/* Make sure google knows we want mail notifications. According to * Google clients should set 'mailnotifications' to true when needed * but never to false, for compatibility reasons: * https://code.google.com/apis/talk/jep_extensions/usersettings.html#3 */ static void ensure_google_settings (GabbleConnection *self) { TpBaseConnection *base_conn = TP_BASE_CONNECTION (self); WockyStanza *query; WockyPorter *porter; if (!self->mail_priv->should_set_google_settings) return; if (base_conn->status != TP_CONNECTION_STATUS_CONNECTED) return; porter = wocky_session_get_porter (self->session); query = wocky_stanza_build (WOCKY_STANZA_TYPE_IQ, WOCKY_STANZA_SUB_TYPE_SET, NULL, NULL, '@', "id", "user-setting-3", '(', "usersetting", ':', NS_GOOGLE_SETTING, '(', "mailnotifications", '@', "value", "true", ')', ')', NULL); wocky_porter_send_iq_async (porter, query, NULL, set_settings_cb, self); self->mail_priv->should_set_google_settings = FALSE; g_object_unref (query); }
static void update_unread_mails (GabbleConnection *conn) { TpBaseConnection *base_conn = TP_BASE_CONNECTION (conn); WockyStanza *query; WockyPorter *porter = wocky_session_get_porter (conn->session); if (base_conn->status != TP_CONNECTION_STATUS_CONNECTED) return; if (!(conn->features & GABBLE_CONNECTION_FEATURES_GOOGLE_MAIL_NOTIFY)) return; DEBUG ("Updating unread mails information"); query = wocky_stanza_build (WOCKY_STANZA_TYPE_IQ, WOCKY_STANZA_SUB_TYPE_GET, NULL, NULL, '(', "query", ':', NS_GOOGLE_MAIL_NOTIFY, ')', NULL); wocky_porter_send_iq_async (porter, query, NULL, query_unread_mails_cb, conn); g_object_unref (query); }
static gboolean set_own_status (GObject *object, const TpPresenceStatus *status, GError **error) { ExampleContactListConnection *self = EXAMPLE_CONTACT_LIST_CONNECTION (object); TpBaseConnection *base = TP_BASE_CONNECTION (object); GHashTable *presences; if (status->index == EXAMPLE_CONTACT_LIST_PRESENCE_AWAY) { if (self->priv->away) return TRUE; self->priv->away = TRUE; } else { if (!self->priv->away) return TRUE; self->priv->away = FALSE; } presences = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, NULL); g_hash_table_insert (presences, GUINT_TO_POINTER (base->self_handle), (gpointer) status); tp_presence_mixin_emit_presence_update (object, presences); g_hash_table_destroy (presences); return TRUE; }
static gboolean set_own_status (GObject *object, const TpPresenceStatus *status, GError **error) { ExampleCallConnection *self = EXAMPLE_CALL_CONNECTION (object); TpBaseConnection *base = TP_BASE_CONNECTION (object); GHashTable *presences; const gchar *message = ""; if (status->optional_arguments != NULL) { GValue *v = g_hash_table_lookup (status->optional_arguments, "message"); if (v != NULL && G_VALUE_HOLDS_STRING (v)) { message = g_value_get_string (v); if (message == NULL) message = ""; } } if (status->index == EXAMPLE_CALL_PRESENCE_AWAY) { if (self->priv->away && !tp_strdiff (message, self->priv->presence_message)) return TRUE; self->priv->away = TRUE; } else { if (!self->priv->away && !tp_strdiff (message, self->priv->presence_message)) return TRUE; self->priv->away = FALSE; } g_free (self->priv->presence_message); self->priv->presence_message = g_strdup (message); presences = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, NULL); g_hash_table_insert (presences, GUINT_TO_POINTER (base->self_handle), (gpointer) status); tp_presence_mixin_emit_presence_update (object, presences); g_hash_table_destroy (presences); if (!self->priv->away) { g_signal_emit (self, signals[SIGNAL_AVAILABLE], 0, message); } return TRUE; }
static gboolean pretend_disconnected (gpointer data) { TpTestsSimpleConnection *self = TP_TESTS_SIMPLE_CONNECTION (data); tp_base_connection_finish_shutdown (TP_BASE_CONNECTION (data)); self->priv->disconnect_source = 0; return FALSE; }
const gchar * conn_util_get_bare_self_jid (GabbleConnection *conn) { TpBaseConnection *base = TP_BASE_CONNECTION (conn); TpHandleRepoIface *contact_handles = tp_base_connection_get_handles (base, TP_HANDLE_TYPE_CONTACT); TpHandle self = tp_base_connection_get_self_handle (base); return tp_handle_inspect (contact_handles, self); }
static void get_alias_flags (TpSvcConnectionInterfaceAliasing *aliasing, DBusGMethodInvocation *context) { TpBaseConnection *base = TP_BASE_CONNECTION (aliasing); TP_BASE_CONNECTION_ERROR_IF_NOT_CONNECTED (base, context); tp_svc_connection_interface_aliasing_return_from_get_alias_flags (context, TP_CONNECTION_ALIAS_FLAG_USER_SET); }
static void conn_power_saving_set_power_saving ( TpSvcConnectionInterfacePowerSaving *conn, gboolean enable, DBusGMethodInvocation *context) { GabbleConnection *self = GABBLE_CONNECTION (conn); TpBaseConnection *base = TP_BASE_CONNECTION (self); gboolean enabled; TP_BASE_CONNECTION_ERROR_IF_NOT_CONNECTED (base, context); g_object_get (G_OBJECT (self), "power-saving", &enabled, NULL); if (enable == enabled) { /* no-op */ tp_svc_connection_interface_power_saving_return_from_set_power_saving ( context); return; } DEBUG ("%sabling presence queueing", enable ? "en" : "dis"); /* google:queue is loosely described here: * <http://mail.jabber.org/pipermail/summit/2010-February/000528.html>. Since * April 2011, it is advertised as a stream feature by the Google Talk * server; the development version of M-Link, and possibly other servers, * also implement the protocol and advertise this stream feature. */ if (self->features & GABBLE_CONNECTION_FEATURES_GOOGLE_QUEUE) { ToggleQueueingContext *queueing_context; queueing_context = g_slice_new0 (ToggleQueueingContext); queueing_context->enabling = enable; queueing_context->dbus_context = context; google_queueing_send_command (self, enable ? "enable" : "disable", toggle_google_queueing_cb, queueing_context); } else { /* If the server doesn't support any method of queueing, we can still * do it locally by enabling power save mode on Wocky. */ WockyPorter *porter = gabble_connection_dup_porter (self); wocky_c2s_porter_enable_power_saving_mode (WOCKY_C2S_PORTER (porter), enable); DEBUG ("%sabled local stanza queueing", enable ? "En" : "Dis"); g_object_unref (porter); maybe_emit_power_saving_changed (self, enable); tp_svc_connection_interface_power_saving_return_from_set_power_saving ( context); } }
static gboolean status_available (GObject *object, guint index_) { TpBaseConnection *base = TP_BASE_CONNECTION (object); if (base->status != TP_CONNECTION_STATUS_CONNECTED) return FALSE; return TRUE; }
static void setup (Test *test, gconstpointer data) { GError *error = NULL; GQuark features[] = { TP_CONNECTION_FEATURE_CONNECTED, 0 }; tp_debug_set_flags ("all"); test->dbus = tp_tests_dbus_daemon_dup_or_die (); test->mainloop = g_main_loop_new (NULL, FALSE); test->error = NULL; test->client_libdbus = dbus_bus_get_private (DBUS_BUS_STARTER, NULL); g_assert (test->client_libdbus != NULL); dbus_connection_setup_with_g_main (test->client_libdbus, NULL); dbus_connection_set_exit_on_disconnect (test->client_libdbus, FALSE); test->client_dbusglib = dbus_connection_get_g_connection ( test->client_libdbus); dbus_g_connection_ref (test->client_dbusglib); test->client_bus = tp_dbus_daemon_new (test->client_dbusglib); g_assert (test->client_bus != NULL); test->service_conn = tp_tests_object_new_static_class ( EXAMPLE_TYPE_CONTACT_LIST_CONNECTION, "account", "*****@*****.**", "protocol", "simple-protocol", NULL); test->service_conn_as_base = TP_BASE_CONNECTION (test->service_conn); g_assert (test->service_conn != NULL); g_assert (test->service_conn_as_base != NULL); g_assert (tp_base_connection_register (test->service_conn_as_base, "simple", &test->conn_name, &test->conn_path, &error)); g_assert_no_error (error); test->cwr_ready = FALSE; test->cwr_error = NULL; test->conn = tp_connection_new (test->client_bus, test->conn_name, test->conn_path, &error); g_assert (test->conn != NULL); g_assert_no_error (error); tp_cli_connection_call_connect (test->conn, -1, NULL, NULL, NULL, NULL); g_assert (!tp_proxy_is_prepared (test->conn, TP_CONNECTION_FEATURE_CORE)); g_assert (!tp_proxy_is_prepared (test->conn, TP_CONNECTION_FEATURE_CONNECTED)); g_assert (!tp_proxy_is_prepared (test->conn, TP_CONNECTION_FEATURE_BALANCE)); tp_tests_proxy_run_until_prepared (test->conn, features); }
static void constructed (GObject *object) { TpBaseConnection *base = TP_BASE_CONNECTION (object); void (*chain_up) (GObject *) = G_OBJECT_CLASS (example_call_connection_parent_class)->constructed; if (chain_up != NULL) chain_up (object); tp_contacts_mixin_init (object, G_STRUCT_OFFSET (ExampleCallConnection, contacts_mixin)); tp_base_connection_register_with_contacts_mixin (base); tp_presence_mixin_init (object, G_STRUCT_OFFSET (ExampleCallConnection, presence_mixin)); tp_presence_mixin_simple_presence_register_with_contacts_mixin (object); }
static GHashTable * get_contact_statuses (GObject *object, const GArray *contacts, GError **error) { ExampleCallConnection *self = EXAMPLE_CALL_CONNECTION (object); TpBaseConnection *base = TP_BASE_CONNECTION (object); guint i; GHashTable *result = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, (GDestroyNotify) tp_presence_status_free); for (i = 0; i < contacts->len; i++) { TpHandle contact = g_array_index (contacts, guint, i); ExampleCallPresence presence; GHashTable *parameters; parameters = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, (GDestroyNotify) tp_g_value_slice_free); /* we know our own status from the connection; for this example CM, * everyone else's status is assumed to be "available" */ if (contact == base->self_handle) { presence = (self->priv->away ? EXAMPLE_CALL_PRESENCE_AWAY : EXAMPLE_CALL_PRESENCE_AVAILABLE); if (self->priv->presence_message[0] != '\0') g_hash_table_insert (parameters, "message", tp_g_value_slice_new_string (self->priv->presence_message)); } else { presence = EXAMPLE_CALL_PRESENCE_AVAILABLE; } g_hash_table_insert (result, GUINT_TO_POINTER (contact), tp_presence_status_new (presence, parameters)); g_hash_table_destroy (parameters); } return result; }
static inline gboolean check_supported_or_dbus_return (GabbleConnection *conn, DBusGMethodInvocation *context) { if (TP_BASE_CONNECTION (conn)->status != TP_CONNECTION_STATUS_CONNECTED) { GError e = { TP_ERRORS, TP_ERROR_DISCONNECTED, "Not connected" }; dbus_g_method_return_error (context, &e); return TRUE; } if (!(conn->features & GABBLE_CONNECTION_FEATURES_GOOGLE_MAIL_NOTIFY)) { tp_dbus_g_method_return_not_implemented (context); return TRUE; } return FALSE; }
static gboolean ring_media_manager_outgoing_call(RingMediaManager *self, gpointer request, TpHandle target, TpHandle initial_remote, char const *emergency, gboolean initial_audio) { RingMediaManagerPrivate *priv = self->priv; TpHandleType htype = target ? TP_HANDLE_TYPE_CONTACT : TP_HANDLE_TYPE_NONE; char *object_path = ring_media_manager_new_object_path(self, "outgoing"); RingCallChannel *channel; TpHandle initiator; initiator = tp_base_connection_get_self_handle( TP_BASE_CONNECTION(priv->connection)); channel = (RingCallChannel *) g_object_new(RING_TYPE_CALL_CHANNEL, "connection", priv->connection, "tones", priv->tones, "object-path", object_path, "initiator-handle", initiator, "handle-type", htype, "handle", target, "peer", target, "initial-remote", initial_remote, "requested", TRUE, "initial-audio", initial_audio, "anon-modes", priv->anon_modes, "initial-emergency-service", emergency, NULL); g_free(object_path); if (initial_audio) ring_call_channel_initial_audio(channel, self, request); else ring_media_manager_emit_new_channel(self, request, channel, NULL); return TRUE; }
static void request_aliases (TpSvcConnectionInterfaceAliasing *aliasing, const GArray *contacts, DBusGMethodInvocation *context) { ExampleContactListConnection *self = EXAMPLE_CONTACT_LIST_CONNECTION (aliasing); TpBaseConnection *base = TP_BASE_CONNECTION (aliasing); TpHandleRepoIface *contact_repo = tp_base_connection_get_handles (base, TP_HANDLE_TYPE_CONTACT); GPtrArray *result; gchar **strings; GError *error = NULL; guint i; TP_BASE_CONNECTION_ERROR_IF_NOT_CONNECTED (base, context); if (!tp_handles_are_valid (contact_repo, contacts, FALSE, &error)) { dbus_g_method_return_error (context, error); g_error_free (error); return; } result = g_ptr_array_sized_new (contacts->len + 1); for (i = 0; i < contacts->len; i++) { TpHandle contact = g_array_index (contacts, TpHandle, i); const gchar *alias = example_contact_list_manager_get_alias ( self->priv->list_manager, contact); g_ptr_array_add (result, (gchar *) alias); } g_ptr_array_add (result, NULL); strings = (gchar **) g_ptr_array_free (result, FALSE); tp_svc_connection_interface_aliasing_return_from_request_aliases (context, (const gchar **) strings); g_free (strings); }
static IdleIMChannel * _im_manager_new_channel (IdleIMManager *mgr, TpHandle handle, TpHandle initiator, gpointer request) { IdleIMManagerPrivate *priv = IDLE_IM_MANAGER_GET_PRIVATE (mgr); TpBaseConnection *base_connection = TP_BASE_CONNECTION (priv->conn); TpHandleRepoIface *handle_repo = tp_base_connection_get_handles (base_connection, TP_HANDLE_TYPE_CONTACT); IdleIMChannel *chan; const gchar *name; GSList *requests = NULL; g_assert (g_hash_table_lookup (priv->channels, GUINT_TO_POINTER (handle)) == NULL); name = tp_handle_inspect (handle_repo, handle); IDLE_DEBUG ("Requested channel for handle: %u (%s)", handle, name); chan = g_object_new (IDLE_TYPE_IM_CHANNEL, "connection", priv->conn, "handle", handle, "initiator-handle", initiator, "requested", handle != initiator, NULL); tp_base_channel_register (TP_BASE_CHANNEL (chan)); g_hash_table_insert (priv->channels, GUINT_TO_POINTER (handle), chan); if (request != NULL) requests = g_slist_prepend (requests, request); tp_channel_manager_emit_new_channel (mgr, TP_EXPORTABLE_CHANNEL (chan), requests); g_slist_free (requests); g_signal_connect (chan, "closed", G_CALLBACK (_im_channel_closed_cb), mgr); return chan; }
static void tp_contacts_mixin_get_contact_attributes_impl ( TpSvcConnectionInterfaceContacts *iface, const GArray *handles, const char **interfaces, gboolean hold, DBusGMethodInvocation *context) { TpBaseConnection *conn = TP_BASE_CONNECTION (iface); GHashTable *result; TP_BASE_CONNECTION_ERROR_IF_NOT_CONNECTED (conn, context); result = tp_contacts_mixin_get_contact_attributes (G_OBJECT (conn), handles, interfaces, always_included_interfaces, NULL); tp_svc_connection_interface_contacts_return_from_get_contact_attributes ( context, result); g_hash_table_unref (result); }
static void constructed (GObject *object) { TpBaseConnection *base = TP_BASE_CONNECTION (object); void (*chain_up) (GObject *) = G_OBJECT_CLASS (example_contact_list_connection_parent_class)->constructed; if (chain_up != NULL) chain_up (object); tp_contacts_mixin_init (object, G_STRUCT_OFFSET (ExampleContactListConnection, contacts_mixin)); tp_base_connection_register_with_contacts_mixin (base); tp_contacts_mixin_add_contact_attributes_iface (object, TP_IFACE_CONNECTION_INTERFACE_ALIASING, aliasing_fill_contact_attributes); tp_presence_mixin_init (object, G_STRUCT_OFFSET (ExampleContactListConnection, presence_mixin)); tp_presence_mixin_simple_presence_register_with_contacts_mixin (object); }
static GHashTable * get_contact_statuses (GObject *object, const GArray *contacts, GError **error) { ExampleContactListConnection *self = EXAMPLE_CONTACT_LIST_CONNECTION (object); TpBaseConnection *base = TP_BASE_CONNECTION (object); guint i; GHashTable *result = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, (GDestroyNotify) tp_presence_status_free); for (i = 0; i < contacts->len; i++) { TpHandle contact = g_array_index (contacts, guint, i); ExampleContactListPresence presence; GHashTable *parameters; /* we get our own status from the connection, and everyone else's status * from the contact lists */ if (contact == base->self_handle) { presence = (self->priv->away ? EXAMPLE_CONTACT_LIST_PRESENCE_AWAY : EXAMPLE_CONTACT_LIST_PRESENCE_AVAILABLE); } else { presence = example_contact_list_manager_get_presence ( self->priv->list_manager, contact); } parameters = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, (GDestroyNotify) tp_g_value_slice_free); g_hash_table_insert (result, GUINT_TO_POINTER (contact), tp_presence_status_new (presence, parameters)); g_hash_table_destroy (parameters); } return result; }
static void on_modem_call_emergency_numbers_changed (ModemCallService *call_service, GParamSpec *dummy, RingMediaManager *self) { RingMediaManagerPrivate *priv = RING_MEDIA_MANAGER(self)->priv; TpBaseConnection *base = TP_BASE_CONNECTION(priv->connection); gchar **numbers; RingEmergencyServiceInfoList *services; if (base->status != TP_CONNECTION_STATUS_CONNECTED) return; g_object_get (call_service, "emergency-numbers", &numbers, NULL); services = ring_emergency_service_info_list_default (numbers); METHOD (tp_svc_connection_interface_service_point, emit_service_points_changed) (priv->connection, services); ring_emergency_service_info_list_free(services); g_strfreev (numbers); }
static void get_aliases (TpSvcConnectionInterfaceAliasing *aliasing, const GArray *contacts, DBusGMethodInvocation *context) { ExampleContactListConnection *self = EXAMPLE_CONTACT_LIST_CONNECTION (aliasing); TpBaseConnection *base = TP_BASE_CONNECTION (aliasing); TpHandleRepoIface *contact_repo = tp_base_connection_get_handles (base, TP_HANDLE_TYPE_CONTACT); GHashTable *result; GError *error = NULL; guint i; TP_BASE_CONNECTION_ERROR_IF_NOT_CONNECTED (base, context); if (!tp_handles_are_valid (contact_repo, contacts, FALSE, &error)) { dbus_g_method_return_error (context, error); g_error_free (error); return; } result = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, NULL); for (i = 0; i < contacts->len; i++) { TpHandle contact = g_array_index (contacts, TpHandle, i); const gchar *alias = example_contact_list_manager_get_alias ( self->priv->list_manager, contact); g_hash_table_insert (result, GUINT_TO_POINTER (contact), (gchar *) alias); } tp_svc_connection_interface_aliasing_return_from_get_aliases (context, result); g_hash_table_destroy (result); }
static void tp_contacts_mixin_get_contact_by_id_impl ( TpSvcConnectionInterfaceContacts *iface, const gchar *id, const gchar **interfaces, DBusGMethodInvocation *context) { TpBaseConnection *conn = TP_BASE_CONNECTION (iface); TpHandleRepoIface *contact_repo = tp_base_connection_get_handles (conn, TP_HANDLE_TYPE_CONTACT); GetContactByIdData *data; TP_BASE_CONNECTION_ERROR_IF_NOT_CONNECTED (conn, context); data = g_slice_new0 (GetContactByIdData); data->conn = g_object_ref (conn); data->interfaces = g_strdupv ((gchar **) interfaces); data->context = context; tp_handle_ensure_async (contact_repo, conn, id, NULL, ensure_handle_cb, data); }
static void set_aliases (TpSvcConnectionInterfaceAliasing *aliasing, GHashTable *aliases, DBusGMethodInvocation *context) { ExampleContactListConnection *self = EXAMPLE_CONTACT_LIST_CONNECTION (aliasing); TpBaseConnection *base = TP_BASE_CONNECTION (aliasing); TpHandleRepoIface *contact_repo = tp_base_connection_get_handles (base, TP_HANDLE_TYPE_CONTACT); GHashTableIter iter; gpointer key, value; g_hash_table_iter_init (&iter, aliases); while (g_hash_table_iter_next (&iter, &key, &value)) { GError *error = NULL; if (!tp_handle_is_valid (contact_repo, GPOINTER_TO_UINT (key), &error)) { dbus_g_method_return_error (context, error); g_error_free (error); return; } } g_hash_table_iter_init (&iter, aliases); while (g_hash_table_iter_next (&iter, &key, &value)) { example_contact_list_manager_set_alias (self->priv->list_manager, GPOINTER_TO_UINT (key), value); } tp_svc_connection_interface_aliasing_return_from_set_aliases (context); }
static char * ring_media_manager_new_object_path(RingMediaManager const *self, char const *type) { RingMediaManagerPrivate const *priv = self->priv; char const *base_path = TP_BASE_CONNECTION(priv->connection)->object_path; static unsigned media_index; static unsigned media_index_init; if (!media_index_init) { media_index = (guint)(time(NULL) - (38 * 365 * 24 * 60 * 60)) * 10; media_index_init = 1; } /* Find an unique D-Bus object_path */ for (;;) { char *path = g_strdup_printf("%s/%s%u", base_path, type, ++media_index); if (!g_hash_table_lookup(priv->channels, path)) { return path; } g_free(path); } }
static void _parse_and_forward_one(IdleParser *parser, gchar **tokens, IdleParserMessageCode code, const gchar *format) { IdleParserPrivate *priv = IDLE_PARSER_GET_PRIVATE(parser); GValueArray *args = g_value_array_new(3); GSList *link_ = priv->handlers[code]; IdleParserHandlerResult result = IDLE_PARSER_HANDLER_RESULT_NOT_HANDLED; gboolean success = TRUE; gchar **iter = tokens; /* We keep a ref to each unique handle in a message so that we can unref them after calling all handlers */ TpHandleSet *contact_reffed = tp_handle_set_new(tp_base_connection_get_handles(TP_BASE_CONNECTION(priv->conn), TP_HANDLE_TYPE_CONTACT)); TpHandleSet *room_reffed = tp_handle_set_new(tp_base_connection_get_handles(TP_BASE_CONNECTION(priv->conn), TP_HANDLE_TYPE_ROOM)); IDLE_DEBUG("message code %u", code); while ((*format != '\0') && success && (*iter != NULL)) { GValue val = {0}; if (*format == 'v') { format++; while (*iter != NULL) { if (!_parse_atom(parser, args, *format, iter[0], contact_reffed, room_reffed)) { success = FALSE; break; } iter += 2; } } else if ((*format == ':') || (*format == '.')) { /* Assume the happy case of the trailing parameter starting after the : * in the trailing string as the RFC intended */ const gchar *trailing = iter[1] + 1; /* Some IRC proxies *cough* bip *cough* omit the : in the trailing * parameter if that parameter is just one word, to cope with that check * if there are no more tokens after the current one and if so, accept a * trailing string without the : prefix. */ if (iter[0][0] != ':') { if (iter[2] == NULL) { trailing = iter[1]; } else { success = FALSE; break; } } /* * because of the way things are tokenized, if there is a * space immediately after the the ':', the current token will only be * ":", so we check that the trailing string is non-NULL rather than * checking iter[0][1] (since iter[0] is a NULL-terminated token string * whereas trailing is a pointer into the full message string */ if (trailing[0] == '\0') { success = FALSE; break; } g_value_init(&val, G_TYPE_STRING); g_value_set_string(&val, trailing); g_value_array_append(args, &val); g_value_unset(&val); IDLE_DEBUG("set string \"%s\"", trailing); } else { if (!_parse_atom(parser, args, *format, iter[0], contact_reffed, room_reffed)) { success = FALSE; break; } } format++; iter += 2; } if (!success && (*format != '.')) { IDLE_DEBUG("failed to parse \"%s\"", tokens[1]); goto cleanup; } if (*format && (*format != '.')) { IDLE_DEBUG("missing args in message \"%s\"", tokens[1]); goto cleanup; } IDLE_DEBUG("successfully parsed"); while (link_) { MessageHandlerClosure *closure = link_->data; result = closure->handler(parser, code, args, closure->user_data); if (result == IDLE_PARSER_HANDLER_RESULT_NOT_HANDLED) { link_ = link_->next; } else if (result == IDLE_PARSER_HANDLER_RESULT_HANDLED) { break; } else if (result == IDLE_PARSER_HANDLER_RESULT_NO_MORE_PLEASE) { GSList *tmp = link_->next; g_free(closure); priv->handlers[code] = g_slist_remove_link(priv->handlers[code], link_); link_ = tmp; } else { g_assert_not_reached(); } } cleanup: g_value_array_free(args); tp_handle_set_destroy(contact_reffed); tp_handle_set_destroy(room_reffed); }
static gboolean _parse_atom(IdleParser *parser, GValueArray *arr, char atom, const gchar *token, TpHandleSet *contact_reffed, TpHandleSet *room_reffed) { IdleParserPrivate *priv = IDLE_PARSER_GET_PRIVATE(parser); TpHandle handle; GValue val = {0}; TpHandleRepoIface *contact_repo = tp_base_connection_get_handles(TP_BASE_CONNECTION(priv->conn), TP_HANDLE_TYPE_CONTACT); TpHandleRepoIface *room_repo = tp_base_connection_get_handles(TP_BASE_CONNECTION(priv->conn), TP_HANDLE_TYPE_ROOM); if (token[0] == ':') token++; IDLE_DEBUG("parsing atom \"%s\" as %c", token, atom); switch (atom) { case 'I': IDLE_DEBUG("ignored token"); return TRUE; break; case 'c': case 'r': case 'C': { gchar *id, *bang = NULL; gchar modechar = '\0'; if (idle_muc_channel_is_modechar(token[0])) { modechar = token[0]; token++; } id = g_strdup(token); if (atom != 'r') { bang = strchr(id, '!'); if (bang) *bang = '\0'; } if (atom == 'r') { if ((handle = tp_handle_ensure(room_repo, id, NULL, NULL))) { tp_handle_set_add(room_reffed, handle); } } else { if ((handle = tp_handle_ensure(contact_repo, id, NULL, NULL))) { tp_handle_set_add(contact_reffed, handle); idle_connection_canon_nick_receive(priv->conn, handle, id); } } g_free(id); if (!handle) return FALSE; g_value_init(&val, G_TYPE_UINT); g_value_set_uint(&val, handle); g_value_array_append(arr, &val); g_value_unset(&val); IDLE_DEBUG("set handle %u", handle); if (atom == 'C') { g_value_init(&val, G_TYPE_CHAR); g_value_set_schar(&val, modechar); g_value_array_append(arr, &val); g_value_unset(&val); IDLE_DEBUG("set modechar %c", modechar); } return TRUE; } break; case 'd': { guint dval; if (sscanf(token, "%d", &dval)) { g_value_init(&val, G_TYPE_UINT); g_value_set_uint(&val, dval); g_value_array_append(arr, &val); g_value_unset(&val); IDLE_DEBUG("set int %d", dval); return TRUE; } else { return FALSE; } } break; case 's': g_value_init(&val, G_TYPE_STRING); g_value_set_string(&val, token); g_value_array_append(arr, &val); g_value_unset(&val); IDLE_DEBUG("set string \"%s\"", token); return TRUE; break; default: IDLE_DEBUG("unknown atom %c", atom); return FALSE; break; } }
/** * tp_contacts_mixin_get_contact_attributes: (skip) * @obj: A connection instance that uses this mixin. The connection must be connected. * @handles: List of handles to retrieve contacts for. Any invalid handles will be * dropped from the returned mapping. * @interfaces: A list of interfaces to retrieve attributes from. * @assumed_interfaces: A list of additional interfaces to retrieve attributes * from. This can be used for interfaces documented as automatically included, * like %TP_IFACE_CONNECTION for GetContactAttributes, * or %TP_IFACE_CONNECTION and %TP_IFACE_CONNECTION_INTERFACE_CONTACT_LIST for * GetContactListAttributes. * @sender: The DBus client's unique name. If this is not NULL, the requested handles * will be held on behalf of this client. * * Get contact attributes for the given contacts. Provide attributes for all requested * interfaces. If contact attributes are not immediately known, the behaviour is defined * by the interface; the attribute should either be omitted from the result or replaced * with a default value. * * Returns: A dictionary mapping the contact handles to contact attributes. * */ GHashTable * tp_contacts_mixin_get_contact_attributes (GObject *obj, const GArray *handles, const gchar **interfaces, const gchar **assumed_interfaces, const gchar *sender) { GHashTable *result; guint i; TpBaseConnection *conn = TP_BASE_CONNECTION (obj); TpContactsMixin *self = TP_CONTACTS_MIXIN (obj); TpHandleRepoIface *contact_repo = tp_base_connection_get_handles (conn, TP_HANDLE_TYPE_CONTACT); GArray *valid_handles; TpContactsMixinFillContactAttributesFunc func; g_return_val_if_fail (TP_IS_BASE_CONNECTION (obj), NULL); g_return_val_if_fail (TP_CONTACTS_MIXIN_OFFSET (obj) != 0, NULL); g_return_val_if_fail (tp_base_connection_check_connected (conn, NULL), NULL); /* Setup handle array and hash with valid handles, optionally holding them */ valid_handles = g_array_sized_new (TRUE, TRUE, sizeof (TpHandle), handles->len); result = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, (GDestroyNotify) g_hash_table_unref); for (i = 0 ; i < handles->len ; i++) { TpHandle h; h = g_array_index (handles, TpHandle, i); if (tp_handle_is_valid (contact_repo, h, NULL)) { GHashTable *attr_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) tp_g_value_slice_free); g_array_append_val (valid_handles, h); g_hash_table_insert (result, GUINT_TO_POINTER(h), attr_hash); } } for (i = 0; assumed_interfaces != NULL && assumed_interfaces[i] != NULL; i++) { func = g_hash_table_lookup (self->priv->interfaces, assumed_interfaces[i]); if (func == NULL) DEBUG ("non-inspectable assumed interface %s given; ignoring", assumed_interfaces[i]); else func (obj, valid_handles, result); } for (i = 0; interfaces != NULL && interfaces[i] != NULL; i++) { func = g_hash_table_lookup (self->priv->interfaces, interfaces[i]); if (func == NULL) DEBUG ("non-inspectable interface %s given; ignoring", interfaces[i]); else func (obj, valid_handles, result); } g_array_unref (valid_handles); return result; }
static void on_modem_call_created(ModemCallService *call_service, ModemCall *modem_call, char const *destination, RingMediaManager *self) { RingMediaManagerPrivate *priv = self->priv; TpHandleRepoIface *repo; RingCallChannel *channel; TpHandle handle; char const *sos; GError *error = NULL; if (!ring_media_manager_is_connected (self)) return; channel = modem_call_get_handler(modem_call); if (channel) return; /* Call created by ring, nothing to do */ /* This is a call created outside ring, create a channel for it */ DEBUG("Freshly created call instance %s not associated with channel.", modem_call_get_name(modem_call)); repo = tp_base_connection_get_handles( (TpBaseConnection *)(self->priv->connection), TP_HANDLE_TYPE_CONTACT); error = NULL; handle = tp_handle_ensure(repo, destination, ring_network_normalization_context(), &error); if (handle == 0) { ring_warning("tp_handle_ensure:" GERROR_MSG_FMT, GERROR_MSG_CODE(error)); if (error) g_error_free(error); /* Xyzzy - modem_call_request_release() ?? */ return; } sos = modem_call_get_emergency_service(priv->call_service, destination); char *object_path = ring_media_manager_new_object_path(self, "created"); channel = (RingCallChannel *) g_object_new(RING_TYPE_CALL_CHANNEL, "connection", priv->connection, "tones", priv->tones, "object-path", object_path, "initiator-handle", tp_base_connection_get_self_handle( TP_BASE_CONNECTION(priv->connection)), "handle-type", TP_HANDLE_TYPE_CONTACT, "handle", handle, "peer", handle, "requested", TRUE, "initial-remote", handle, "initial-audio", TRUE, "anon-modes", priv->anon_modes, "call-instance", modem_call, "originating", TRUE, sos ? "initial-emergency-service" : NULL, sos, NULL); g_free(object_path); ring_media_manager_emit_new_channel(self, NULL, channel, NULL); ring_media_channel_set_state(RING_MEDIA_CHANNEL(channel), MODEM_CALL_STATE_DIALING, 0, 0); }