static void _im_channel_closed_cb (IdleIMChannel *chan, gpointer user_data) { IdleIMManager *self = IDLE_IM_MANAGER (user_data); IdleIMManagerPrivate *priv = IDLE_IM_MANAGER_GET_PRIVATE (self); TpBaseChannel *base = TP_BASE_CHANNEL (chan); tp_channel_manager_emit_channel_closed_for_object (self, TP_EXPORTABLE_CHANNEL (chan)); if (priv->channels) { TpHandle handle = tp_base_channel_get_target_handle (base); if (tp_base_channel_is_destroyed (base)) { IDLE_DEBUG ("removing channel with handle %u", handle); g_hash_table_remove (priv->channels, GUINT_TO_POINTER (handle)); } else { IDLE_DEBUG ("reopening channel with handle %u due to pending messages", handle); tp_channel_manager_emit_new_channel (self, (TpExportableChannel *) chan, NULL); } } }
static gboolean kindling_roomlist_manager_get_channel(TpChannelManager *manager, gpointer request_token, GHashTable *request_properties, gboolean require_new) { KindlingRoomlistManagerPrivate *priv = KINDLING_ROOMLIST_MANAGER_GET_PRIVATE(manager); TpExportableChannel *channel; g_printf("get channel %s\n", tp_asv_get_string (request_properties,TP_IFACE_CHANNEL ".ChannelType")); if (tp_strdiff (tp_asv_get_string (request_properties, TP_IFACE_CHANNEL".ChannelType"), TP_IFACE_CHANNEL_TYPE_ROOM_LIST)) { return FALSE; } if (priv->channels->len > 0 && !require_new) { tp_channel_manager_emit_request_already_satisfied (manager, request_token, TP_EXPORTABLE_CHANNEL(g_ptr_array_index (priv->channels,0))); return TRUE; } channel = g_object_new(KINDLING_TYPE_ROOMLIST_CHANNEL, "connection", priv->conn, NULL); g_signal_connect (channel, "closed", (GCallback) roomlist_channel_closed_cb, manager); g_ptr_array_add(priv->channels, channel); GSList *request_tokens = g_slist_prepend (NULL, request_token); tp_channel_manager_emit_new_channel (manager, TP_EXPORTABLE_CHANNEL(channel), request_tokens); g_slist_free (request_tokens); return TRUE; }
static void new_channel (ExampleCSHRoomManager *self, TpHandle handle, TpHandle initiator, gpointer request_token) { ExampleCSHRoomChannel *chan; gchar *object_path; GSList *requests = NULL; object_path = g_strdup_printf ("%s/CSHRoomChannel%u", self->priv->conn->object_path, handle); chan = g_object_new (EXAMPLE_TYPE_CSH_ROOM_CHANNEL, "connection", self->priv->conn, "object-path", object_path, "handle", handle, /* FIXME: initiator */ NULL); g_free (object_path); g_signal_connect (chan, "closed", (GCallback) channel_closed_cb, self); g_hash_table_insert (self->priv->channels, GUINT_TO_POINTER (handle), chan); if (request_token != NULL) requests = g_slist_prepend (requests, request_token); tp_channel_manager_emit_new_channel (self, TP_EXPORTABLE_CHANNEL (chan), requests); g_slist_free (requests); }
static void channel_closed_cb (ExampleEcho2Channel *chan, ExampleEcho2ImManager *self) { tp_channel_manager_emit_channel_closed_for_object (self, TP_EXPORTABLE_CHANNEL (chan)); if (self->priv->channels != NULL) { TpHandle handle; gboolean really_destroyed; g_object_get (chan, "handle", &handle, "channel-destroyed", &really_destroyed, NULL); /* Re-announce the channel if it's not yet ready to go away (pending * messages) */ if (really_destroyed) { g_hash_table_remove (self->priv->channels, GUINT_TO_POINTER (handle)); } else { tp_channel_manager_emit_new_channel (self, TP_EXPORTABLE_CHANNEL (chan), NULL); } } }
void ring_media_manager_emit_new_channel(RingMediaManager *self, gpointer request, gpointer _channel, GError *error) { DEBUG("%s(%p, %p, %p, %p) called", __func__, self, request, _channel, error); RingMediaManagerPrivate *priv = RING_MEDIA_MANAGER(self)->priv; TpBaseChannel *channel = _channel ? TP_BASE_CHANNEL (_channel) : NULL; GSList *requests = request ? g_slist_prepend(NULL, request) : NULL; if (error == NULL) { char *object_path = NULL; g_signal_connect( channel, "closed", G_CALLBACK(on_media_channel_closed), self); g_object_get(channel, "object-path", &object_path, NULL); DEBUG("got new channel %p nick %s type %s", channel, get_nick (channel), G_OBJECT_TYPE_NAME (channel)); g_hash_table_insert(priv->channels, object_path, channel); tp_channel_manager_emit_new_channel(self, TP_EXPORTABLE_CHANNEL(channel), requests); /* Emit Group and StreamedMedia signals */ ring_media_channel_emit_initial(RING_MEDIA_CHANNEL (channel)); } else { DEBUG("new channel %p nick %s type %s failed with " GERROR_MSG_FMT, channel, get_nick (channel), G_OBJECT_TYPE_NAME (channel), GERROR_MSG_CODE(error)); if (request) { tp_channel_manager_emit_request_failed(self, request, error->domain, error->code, error->message); } if (_channel) g_object_unref(_channel); } g_slist_free(requests); }
static void incoming_call_cb (RakiaSipSession *session, struct InviteData *idata) { RakiaCallChannel *channel; g_signal_handlers_disconnect_by_func (session, G_CALLBACK (incoming_call_cb), idata); channel = new_call_channel (idata->fac, idata->handle, idata->handle, NULL, session); tp_channel_manager_emit_new_channel (idata->fac, TP_EXPORTABLE_CHANNEL (channel), NULL); g_object_unref (session); g_slice_free (struct InviteData, idata); }
/* * new_im_channel: * @fac: the factory * @handle: a contact handle, for whom a channel must not yet exist * @request_token: if the channel is being created in response to a channel * request, the associated request token; otherwise, NULL. * * Creates a new 1-1 text channel to a contact. Must only be called when no 1-1 * text channel is already open to that contact. * * Returns: (transfer none): a freshly-constructed channel */ static GabbleIMChannel * new_im_channel (GabbleImFactory *fac, TpHandle handle, gpointer request_token) { GabbleImFactoryPrivate *priv = fac->priv; TpBaseConnection *conn = (TpBaseConnection *) priv->conn; GabbleIMChannel *chan; GSList *request_tokens; TpHandle initiator; g_return_val_if_fail (handle != 0, NULL); if (request_token != NULL) initiator = tp_base_connection_get_self_handle (conn); else initiator = handle; chan = g_object_new (GABBLE_TYPE_IM_CHANNEL, "connection", priv->conn, "handle", handle, "initiator-handle", initiator, "requested", (handle != initiator), NULL); tp_base_channel_register ((TpBaseChannel *) chan); g_signal_connect (chan, "closed", (GCallback) im_channel_closed_cb, fac); g_hash_table_insert (priv->channels, GUINT_TO_POINTER (handle), chan); if (request_token != NULL) request_tokens = g_slist_prepend (NULL, request_token); else request_tokens = NULL; tp_channel_manager_emit_new_channel (fac, (TpExportableChannel *) chan, request_tokens); g_slist_free (request_tokens); return chan; }
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; }
/** * im_channel_closed_cb: * * Signal callback for when an IM channel is closed. Removes the references * that #GabbleConnection holds to them - unless the channel has pending * messages, in which case it is re-announced (so from the perspective of the * D-Bus API, it was replaced by an identical channel). */ static void im_channel_closed_cb (GabbleIMChannel *chan, gpointer user_data) { GabbleImFactory *self = GABBLE_IM_FACTORY (user_data); GabbleImFactoryPrivate *priv = self->priv; TpBaseChannel *base = TP_BASE_CHANNEL (chan); TpHandle contact_handle = tp_base_channel_get_target_handle (base); DEBUG ("%p, channel %p", self, chan); if (tp_base_channel_is_registered (base)) { tp_channel_manager_emit_channel_closed_for_object (self, (TpExportableChannel *) chan); } if (priv->channels != NULL) { if (tp_base_channel_is_destroyed (base)) { DEBUG ("removing channel with handle %u", contact_handle); g_hash_table_remove (priv->channels, GUINT_TO_POINTER (contact_handle)); } else if (tp_base_channel_is_respawning (base)) { DEBUG ("reopening channel with handle %u due to pending messages", contact_handle); tp_channel_manager_emit_new_channel (self, (TpExportableChannel *) chan, NULL); } else { /* this basically means tp_base_channel_disappear() must * have been called; this doesn't have any meaning in this * channel manager. */ g_assert_not_reached (); } } }
static void on_text_channel_closed(RingTextChannel *channel, RingTextManager *self) { char *object_path; gboolean really_destroyed; guint handle; g_object_get(channel, "object-path", &object_path, "channel-destroyed", &really_destroyed, "handle", &handle, NULL); if (self->priv->channels == NULL) really_destroyed = TRUE; DEBUG(": %s is %s", object_path, really_destroyed ? "destroyed" : "about to be recycled"); tp_channel_manager_emit_channel_closed(self, object_path); if (self->priv->channels == NULL) ; else if (really_destroyed) { g_hash_table_remove(self->priv->channels, object_path); } else { g_object_set(channel, "initiator", handle, "requested", FALSE, NULL); tp_channel_manager_emit_new_channel(self, (TpExportableChannel *)channel, NULL); } g_free(object_path); }
static void gabble_auth_manager_start_auth_async (WockyAuthRegistry *registry, const GSList *mechanisms, gboolean allow_plain, gboolean is_secure_channel, const gchar *username, const gchar *password, const gchar *server, const gchar *session_id, GAsyncReadyCallback callback, gpointer user_data) { GabbleAuthManager *self = GABBLE_AUTH_MANAGER (registry); /* assumption: Wocky's API guarantees that we never have more than one * auth request outstanding */ g_assert (self->priv->channel == NULL); if (password == NULL || username == NULL) { GPtrArray *mech_array = g_ptr_array_new (); const GSList *iter; for (iter = mechanisms; iter != NULL; iter = iter->next) { self->priv->mechanisms = g_slist_prepend (self->priv->mechanisms, g_strdup (iter->data)); /* skip Wocky-specific pseudo-mechanisms for the D-Bus API */ if (!g_str_has_prefix (iter->data, "X-WOCKY-JABBER-")) g_ptr_array_add (mech_array, iter->data); } if (wocky_auth_registry_supports_one_of (registry, mechanisms, allow_plain)) g_ptr_array_add (mech_array, X_TELEPATHY_PASSWORD); g_ptr_array_add (mech_array, NULL); /* we'll use these if we fall back to the base class to use * X-TELEPATHY-PASSWORD */ self->priv->mechanisms = g_slist_reverse (self->priv->mechanisms); self->priv->allow_plain = allow_plain; self->priv->is_secure_channel = is_secure_channel; self->priv->server = g_strdup (server); self->priv->session_id = g_strdup (session_id); if (username == NULL) { g_object_get (self->priv->conn, "username", &self->priv->username, NULL); } else { self->priv->username = g_strdup (username); } self->priv->channel = gabble_server_sasl_channel_new (self->priv->conn, (GStrv) mech_array->pdata, is_secure_channel, session_id); g_ptr_array_unref (mech_array); self->priv->closed_id = tp_g_signal_connect_object (self->priv->channel, "closed", G_CALLBACK (auth_channel_closed_cb), self, 0); gabble_server_sasl_channel_start_auth_async (self->priv->channel, gabble_auth_manager_start_auth_cb, g_simple_async_result_new ((GObject *) self, callback, user_data, gabble_auth_manager_start_auth_async)); g_assert (!tp_base_channel_is_destroyed ( (TpBaseChannel *) self->priv->channel)); g_assert (tp_base_channel_is_registered ( (TpBaseChannel *) self->priv->channel)); tp_channel_manager_emit_new_channel (self, TP_EXPORTABLE_CHANNEL (self->priv->channel), NULL); } else { WOCKY_AUTH_REGISTRY_CLASS ( gabble_auth_manager_parent_class)->start_auth_async_func ( registry, mechanisms, allow_plain, is_secure_channel, username, password, server, session_id, callback, user_data); } }
static RingTextChannel * ring_text_manager_request(RingTextManager *self, gpointer request, TpHandle initiator, TpHandle handle, gboolean require_mine, gboolean class0) { RingTextManagerPrivate *priv = self->priv; RingTextChannel *channel; char *object_path; object_path = g_strdup_printf("%s/%s%u", priv->connection->parent.object_path, class0 ? "flash" : "text", (unsigned)handle); channel = ring_text_manager_lookup(self, object_path); if (channel) { g_free(object_path); if (require_mine) { char *message; channel = NULL; message = g_strdup_printf("Cannot create: " "channel with target '%s' already exists", ring_connection_inspect_contact(priv->connection, handle)); DEBUG("%s", message); if (request) tp_channel_manager_emit_request_failed(self, request, TP_ERROR, TP_ERROR_NOT_AVAILABLE, message); g_assert(request); g_free(message); return NULL; } else { if (request) tp_channel_manager_emit_request_already_satisfied( self, request, TP_EXPORTABLE_CHANNEL(channel)); return channel; } } channel = g_object_new (RING_TYPE_TEXT_CHANNEL, "connection", self->priv->connection, "object-path", object_path, "handle-type", TP_HANDLE_TYPE_CONTACT, "handle", handle, "initiator-handle", initiator, "requested", request != NULL, "sms-flash", class0, NULL); g_free(object_path); g_object_get(channel, "object_path", &object_path, NULL); g_hash_table_insert(priv->channels, object_path, channel); g_signal_connect(channel, "closed", (GCallback)on_text_channel_closed, self); GSList *requests = request ? g_slist_prepend(NULL, request) : NULL; tp_channel_manager_emit_new_channel( self, TP_EXPORTABLE_CHANNEL(channel), requests); DEBUG("New channel emitted"); g_slist_free(requests); return channel; }
static gboolean rakia_media_manager_requestotron (TpChannelManager *manager, gpointer request_token, GHashTable *request_properties, RequestMethod method) { RakiaMediaManager *self = RAKIA_MEDIA_MANAGER (manager); RakiaMediaManagerPrivate *priv = RAKIA_MEDIA_MANAGER_GET_PRIVATE (self); TpBaseConnection *conn = (TpBaseConnection *) priv->conn; TpHandleType handle_type; TpHandle handle; RakiaSipSession *session; RakiaCallChannel *channel = NULL; GError *error = NULL; GSList *request_tokens; gboolean valid = FALSE; gboolean initial_audio = FALSE; gboolean initial_video = FALSE; TpHandle self_handle = tp_base_connection_get_self_handle (conn); /* Supported modes of operation: * - RequestChannel(Contact, n) where n != 0: * channel has TargetHandle=n; * n is in remote pending; * call is started when caller calls RequestStreams. * - CreateChannel({THT: Contact, TH: n}): * channel has TargetHandle=n * n is not in the group interface at all * call is started when caller calls RequestStreams. * - EnsureChannel({THT: Contact, TH: n}): * look for a channel whose peer is n, and return that if found with * whatever properties and group membership it has; * otherwise the same as into CreateChannel */ if (tp_strdiff (tp_asv_get_string (request_properties, TP_PROP_CHANNEL_CHANNEL_TYPE), TP_IFACE_CHANNEL_TYPE_CALL)) return FALSE; if (tp_asv_get_boolean (request_properties, TP_PROP_CHANNEL_TYPE_CALL_INITIAL_AUDIO, &valid) && valid) initial_audio = TRUE; if (tp_asv_get_boolean (request_properties, TP_PROP_CHANNEL_TYPE_CALL_INITIAL_VIDEO, &valid) && valid) initial_audio = TRUE; if (!initial_audio && !initial_video) return FALSE; handle_type = tp_asv_get_uint32 (request_properties, TP_IFACE_CHANNEL ".TargetHandleType", NULL); handle = tp_asv_get_uint32 (request_properties, TP_IFACE_CHANNEL ".TargetHandle", NULL); if (handle_type != TP_HANDLE_TYPE_CONTACT) return FALSE; g_assert (handle != 0); if (tp_channel_manager_asv_has_unknown_properties (request_properties, media_channel_fixed_properties, named_channel_allowed_properties, &error)) goto error; /* Calls to self are problematic in terms of StreamedMedia channel * interface and its semantically required Group member changes; * we disable them until a better API is available through * Call channel type */ if (handle == self_handle) { g_set_error (&error, TP_ERROR, TP_ERROR_NOT_IMPLEMENTED, "Cannot call self"); goto error; } if (method == METHOD_ENSURE) { guint i; TpHandle peer = 0; for (i = 0; i < priv->channels->len; i++) { channel = g_ptr_array_index (priv->channels, i); g_object_get (channel, "peer", &peer, NULL); if (peer == handle) { tp_channel_manager_emit_request_already_satisfied (self, request_token, TP_EXPORTABLE_CHANNEL (channel)); return TRUE; } } } session = new_session (self, NULL, handle); channel = new_call_channel (self, self_handle, handle, request_properties, session); g_object_unref (session); request_tokens = g_slist_prepend (NULL, request_token); tp_channel_manager_emit_new_channel (self, TP_EXPORTABLE_CHANNEL (channel), request_tokens); g_slist_free (request_tokens); return TRUE; error: tp_channel_manager_emit_request_failed (self, request_token, error->domain, error->code, error->message); g_error_free (error); return TRUE; }