soc.2009.telepathy: 4c9717d5: Implemented connection and disconnection...
sttwister at soc.pidgin.im
sttwister at soc.pidgin.im
Tue May 12 09:15:50 EDT 2009
-----------------------------------------------------------------
Revision: 4c9717d51a5e63b0e733ea7194234e1c222aac0b
Ancestor: 8e40da592d841dc0a9238174da854de8e15ad797
Author: sttwister at soc.pidgin.im
Date: 2009-05-12T13:07:47
Branch: im.pidgin.soc.2009.telepathy
URL: http://d.pidgin.im/viewmtn/revision/info/4c9717d51a5e63b0e733ea7194234e1c222aac0b
Modified files:
libpurple/protocols/telepathy/telepathy.c
ChangeLog:
Implemented connection and disconnection. Fixed some memory leaks.
-------------- next part --------------
============================================================
--- libpurple/protocols/telepathy/telepathy.c dc12b5fd51126a1913d354dd39dd1e5071b3683b
+++ libpurple/protocols/telepathy/telepathy.c 55f1e35cc436a6be4bf2035ec4386a34c3f85e70
@@ -23,6 +23,7 @@
#include <telepathy-glib/connection-manager.h>
#include <telepathy-glib/channel.h>
#include <telepathy-glib/dbus.h>
+#include <telepathy-glib/util.h>
#include "internal.h"
@@ -47,6 +48,8 @@ typedef struct
{
TpConnectionManager *cm;
TpConnectionManagerProtocol *protocol;
+ TpConnection *connection;
+ PurpleConnection *gc;
} telepathy_data;
typedef struct
@@ -108,51 +111,291 @@ telepathy_status_types(PurpleAccount *ac
PurpleStatusType *type;
purple_debug_info("telepathy", "Returning status types for %s: %s, %s, %s\n",
- acct->username,
- TELEPATHY_STATUS_ONLINE, TELEPATHY_STATUS_AWAY, TELEPATHY_STATUS_OFFLINE);
+ acct->username,
+ TELEPATHY_STATUS_ONLINE, TELEPATHY_STATUS_AWAY, TELEPATHY_STATUS_OFFLINE);
type = purple_status_type_new_with_attrs(PURPLE_STATUS_AVAILABLE,
- TELEPATHY_STATUS_ONLINE, NULL, TRUE, TRUE, FALSE,
- "message", _("Message"), purple_value_new(PURPLE_TYPE_STRING),
- NULL);
+ TELEPATHY_STATUS_ONLINE, NULL, TRUE, TRUE, FALSE,
+ "message", _("Message"), purple_value_new(PURPLE_TYPE_STRING),
+ NULL);
types = g_list_prepend(types, type);
type = purple_status_type_new_with_attrs(PURPLE_STATUS_AWAY,
- TELEPATHY_STATUS_AWAY, NULL, TRUE, TRUE, FALSE,
- "message", _("Message"), purple_value_new(PURPLE_TYPE_STRING),
- NULL);
+ TELEPATHY_STATUS_AWAY, NULL, TRUE, TRUE, FALSE,
+ "message", _("Message"), purple_value_new(PURPLE_TYPE_STRING),
+ NULL);
types = g_list_prepend(types, type);
type = purple_status_type_new_with_attrs(PURPLE_STATUS_OFFLINE,
- NULL, NULL, TRUE, TRUE, FALSE,
- "message", _("Message"), purple_value_new(PURPLE_TYPE_STRING),
- NULL);
+ NULL, NULL, TRUE, TRUE, FALSE,
+ "message", _("Message"), purple_value_new(PURPLE_TYPE_STRING),
+ NULL);
types = g_list_prepend(types, type);
return g_list_reverse(types);
}
static void
+connection_ready_cb (TpConnection *connection,
+ const GError *error,
+ gpointer user_data)
+{
+ if (error != NULL)
+ {
+ purple_debug_info("telepathy", "Connection ready error: %s\n", error->message);
+ }
+ else
+ {
+ purple_debug_info("telepathy", "Connection is ready!\n");
+ }
+}
+
+static void
+status_changed_cb (TpConnection *proxy,
+ guint arg_Status,
+ guint arg_Reason,
+ gpointer user_data,
+ GObject *weak_object)
+{
+ PurplePlugin* plugin = user_data;
+ telepathy_data *data = plugin->extra;
+
+ if (arg_Status == TP_CONNECTION_STATUS_CONNECTED)
+ {
+ purple_debug_info("telepathy", "Connected!\n");
+
+ purple_connection_update_progress(data->gc, _("Connected"),
+ 1, /* which connection step this is */
+ 2); /* total number of steps */
+
+ purple_connection_set_state(data->gc, PURPLE_CONNECTED);
+ }
+ else if (arg_Status == TP_CONNECTION_STATUS_DISCONNECTED)
+ {
+ gchar *reason = NULL;
+ purple_debug_info("telepathy", "Disconnected! Reason: %d\n", arg_Reason);
+
+ purple_connection_set_state(data->gc, PURPLE_DISCONNECTED);
+
+ switch (arg_Reason)
+ {
+ case 2:
+ reason = "Network error";
+ break;
+
+ case 3:
+ reason = "Authentication failed";
+ break;
+
+ case 4:
+ reason = "Encryption error";
+ break;
+
+ case 5:
+ reason = "Name in use";
+ break;
+
+ case 6:
+ reason = "SSL Certificate not provided";
+ break;
+
+ case 7:
+ reason = "SSL Certificate is isnged by an untrusted certifying authority";
+ break;
+
+ case 8:
+ reason = "SSL Certificate expired";
+ break;
+
+ case 9:
+ reason = "SSL Certificate is not yet valid";
+ break;
+
+ case 10:
+ reason = "SSL Certificate hostname mismatch";
+ break;
+
+ case 11:
+ reason = "SSL Certificate fingerprint mismatch";
+ break;
+
+ case 12:
+ reason = "SSL Certificate is self-signed";
+ break;
+
+ case 13:
+ reason = "Error while validating the server's SSL Certificate";
+ break;
+ }
+
+ if (reason != NULL)
+ purple_connection_error(data->gc, reason);
+
+ }
+ else if (arg_Status == TP_CONNECTION_STATUS_CONNECTING)
+ {
+ purple_debug_info("telepathy", "Connecting! Reason: %d\n", arg_Reason);
+ purple_connection_set_state(data->gc, PURPLE_CONNECTING);
+ purple_connection_update_progress(data->gc, _("Connecting"),
+ 0, /* which connection step this is */
+ 2); /* total number of steps */
+
+ }
+}
+
+static void
+connection_connect_cb (TpConnection *proxy,
+ const GError *error,
+ gpointer user_data,
+ GObject *weak_object)
+{
+ /* if this fails, something must be broken somewhere */
+ if (error != NULL)
+ {
+ purple_debug_error("telepathy", "Connect error: %s\n", error->message);
+ }
+}
+
+static void
+request_connection_cb (TpConnectionManager *proxy,
+ const gchar *out_Bus_Name,
+ const gchar *out_Object_Path,
+ const GError *error,
+ gpointer user_data,
+ GObject *weak_object)
+{
+ if (error != NULL)
+ {
+ purple_debug_info("telepathy", "RequestConnection error: %s\n", error->message);
+ }
+ else
+ {
+ GError *error = NULL;
+
+ PurplePlugin* plugin = user_data;
+ telepathy_data* data = plugin->extra;
+
+ TpDBusDaemon *daemon = tp_dbus_daemon_dup(&error);
+
+ if (error != NULL)
+ {
+ purple_debug_error("telepathy", "Error creating dbus daemon: %s\n", error->message);
+ g_error_free(error);
+ return;
+ }
+
+ /* get the connection proxy straight out of the dbus interface */
+ data->connection = tp_connection_new(daemon, out_Bus_Name, out_Object_Path, &error);
+
+ if (error != NULL)
+ {
+ purple_debug_error("telepathy", "Error creating TpConenction object: %s\n", error->message);
+ g_error_free(error);
+ return;
+ }
+
+ /* this will indicate that we are actually connected */
+ tp_connection_call_when_ready(data->connection, connection_ready_cb, plugin);
+
+ /* this will indicate any connection status change, also providing a reason */
+ tp_cli_connection_connect_to_status_changed(data->connection, status_changed_cb, plugin, NULL, NULL, &error);
+
+ if (error != NULL)
+ {
+ purple_debug_error("telepathy", "Error conencting to StatusChanged: %s\n", error->message);
+ g_error_free(error);
+ tp_cli_connection_call_disconnect(data->connection, -1, NULL, NULL, NULL, NULL);
+ g_object_unref(data->connection);
+ data->connection = NULL;
+ }
+ else
+ {
+ /* do some magic now :) */
+ tp_cli_connection_call_connect(data->connection, -1, connection_connect_cb, plugin, NULL, NULL);
+ }
+
+ if (daemon != NULL)
+ g_object_unref(daemon);
+ }
+}
+
+static void
telepathy_login(PurpleAccount *acct)
{
PurpleConnection *gc = purple_account_get_connection(acct);
+ PurplePlugin* plugin = gc->prpl;
+ telepathy_data *data = (telepathy_data*)plugin->extra;
+ GHashTable *options = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, (GDestroyNotify) tp_g_value_slice_free);
+ int i;
+
+ data->gc = gc;
+
purple_debug_info("telepathy", "Logging in as %s\n", acct->username);
+ purple_debug_info("telepathy", "Logging in as %s\n", acct->password);
- purple_connection_update_progress(gc, _("Connecting"),
- 0, /* which connection step this is */
- 2); /* total number of steps */
+ /* some protocols might not require username or password, so check them before */
+ if (acct->username != NULL)
+ tp_asv_set_string(options, "account", acct->username);
+ if (acct->password != NULL)
+ tp_asv_set_string(options, "password", acct->password);
- purple_connection_update_progress(gc, _("Connected"),
- 1, /* which connection step this is */
- 2); /* total number of steps */
- purple_connection_set_state(gc, PURPLE_CONNECTED);
+ /* fill in the hash table with the other options, considering the right signatures */
+ for (i = 0; data->protocol->params[i].name != NULL; ++i)
+ {
+ gchar *name;
+ gchar *signature;
+ name = data->protocol->params[i].name;
+ signature = data->protocol->params[i].dbus_signature;
+
+ /* account and password have already been added */
+ if (g_strcmp0(name, "account") != 0 && g_strcmp0(name, "password"))
+ {
+ if (g_strcmp0(signature, "s") == 0)
+ {
+ tp_asv_set_string(options, name, purple_account_get_string(acct, name, ""));
+ }
+ else if (g_strcmp0(signature, "n") == 0)
+ {
+ tp_asv_set_int32(options, name, purple_account_get_int(acct, name, 0));
+ }
+ else if (g_strcmp0(signature, "i") == 0)
+ {
+ tp_asv_set_int32(options, name, purple_account_get_int(acct, name, 0));
+ }
+ else if (g_strcmp0(signature, "q") == 0)
+ {
+ tp_asv_set_uint32(options, name, purple_account_get_int(acct, name, 0));
+ }
+ else if (g_strcmp0(signature, "b") == 0)
+ {
+ tp_asv_set_boolean(options, name, purple_account_get_bool(acct, name, FALSE));
+ }
+ else
+ purple_debug_warning("telepathy", "Unknown signature \"%s\" for \"%s\"\n", signature, name);
+ }
+ }
+
+ /* call RequestConnection with the specified parameters */
+ tp_cli_connection_manager_call_request_connection(data->cm, -1, data->protocol->name, options, request_connection_cb, plugin, NULL, NULL);
}
static void
telepathy_close(PurpleConnection *gc)
{
+ PurplePlugin* plugin = gc->prpl;
+ telepathy_data *data = (telepathy_data*)plugin->extra;
+
purple_debug_info("telepathy", "We're closing, sorry :(\n");
+
+ /* make sure the connection is closed in dbus-land,
+ * or else we won't be able to recreate the connection */
+ if (data->connection)
+ {
+ tp_cli_connection_call_disconnect(data->connection, -1, NULL, NULL, NULL, NULL);
+ g_object_unref(data->connection);
+ data->connection = NULL;
+ }
}
static void
@@ -160,7 +403,13 @@ telepathy_destroy(PurplePlugin *plugin)
{
purple_debug_info("telepathy", "Shutting down\n");
- /* TODO: Free the PurplePluginInfo */
+ /* free everything that we created */
+ if (g_strcmp0(plugin->info->id, "prpl-telepathy") != 0) {
+ g_free(plugin->info->extra_info);
+ g_free(plugin->info);
+ g_object_unref(((telepathy_data*)plugin->extra)->cm);
+ g_free(plugin->extra);
+ }
}
static PurplePluginProtocolInfo telepathy_prpl_info =
@@ -328,7 +577,7 @@ get_human_name(const gchar *telepathy_na
for (i = 0; options[i].telepathy_name != NULL; ++i)
{
if (g_strcmp0(options[i].telepathy_name, telepathy_name) == 0 &&
- g_strcmp0(options[i].dbus_type, dbus_type) == 0)
+ g_strcmp0(options[i].dbus_type, dbus_type) == 0)
return g_strdup(_(options[i].human_name));
}
@@ -342,7 +591,7 @@ get_int_value(const GValue *value,
{
if (g_strcmp0(signature, "q") == 0)
return g_value_get_uint(value);
- else if (g_strcmp0(signature, "i") == 0 && g_strcmp0(signature, "n") == 0)
+ else if (g_strcmp0(signature, "i") == 0 || g_strcmp0(signature, "n") == 0)
return g_value_get_int(value);
else
return 0;
@@ -357,9 +606,9 @@ add_protocol_options(PurplePlugin *plugi
int i;
PurpleAccountOption *option = NULL;
PurplePluginProtocolInfo *protocol_info = plugin->info->extra_info;
- PurplePrefType *type;
TpConnectionManagerParam *param;
gboolean has_default;
+ PurplePrefType type = PURPLE_PREF_NONE;
/* by default, don't prompt for password, we'll unflag this if we get a password parameter */
protocol_info->options = protocol_info->options | OPT_PROTO_NO_PASSWORD;
@@ -389,23 +638,22 @@ add_protocol_options(PurplePlugin *plugi
}
else
{
- type = g_new(PurplePrefType, 1);
- human_name = get_human_name(name, signature, type);
+ human_name = get_human_name(name, signature, &type);
has_default = param->flags & TP_CONN_MGR_PARAM_FLAG_HAS_DEFAULT;
- if (*type == PURPLE_PREF_STRING)
+ if (type == PURPLE_PREF_STRING)
{
option = purple_account_option_string_new(human_name, param->name, NULL);
if (has_default)
purple_account_option_set_default_string(option, g_value_get_string(¶m->default_value));
}
- else if (*type == PURPLE_PREF_INT)
+ else if (type == PURPLE_PREF_INT)
{
option = purple_account_option_int_new(human_name, param->name, 0);
if (has_default)
purple_account_option_set_default_int(option, get_int_value(¶m->default_value, signature));
}
- else if (*type == PURPLE_PREF_BOOLEAN)
+ else if (type == PURPLE_PREF_BOOLEAN)
{
option = purple_account_option_bool_new(human_name, param->name, FALSE);
if (has_default)
@@ -434,6 +682,9 @@ export_prpl(TpConnectionManager *cm,
data->cm = cm;
data->protocol = protocol;
+ data->connection = NULL;
+ data->gc = NULL;
+ g_object_ref(data->cm);
/* correct the plugin id and name, everything else can remain the same */
plugin->info->id = g_strdup_printf("%s-%s-%s", TELEPATHY_ID, tp_connection_manager_get_name(cm), protocol->name);
More information about the Commits
mailing list