static gboolean example_csh_room_manager_request (ExampleCSHRoomManager *self, gpointer request_token, GHashTable *request_properties, gboolean require_new) { TpHandle handle; ExampleCSHRoomChannel *chan; GError *error = NULL; if (tp_strdiff (tp_asv_get_string (request_properties, TP_PROP_CHANNEL_CHANNEL_TYPE), TP_IFACE_CHANNEL_TYPE_TEXT)) { return FALSE; } if (tp_asv_get_uint32 (request_properties, TP_PROP_CHANNEL_TARGET_HANDLE_TYPE, NULL) != TP_HANDLE_TYPE_ROOM) { return FALSE; } handle = tp_asv_get_uint32 (request_properties, TP_PROP_CHANNEL_TARGET_HANDLE, NULL); g_assert (handle != 0); if (tp_channel_manager_asv_has_unknown_properties (request_properties, fixed_properties, allowed_properties, &error)) { goto error; } chan = g_hash_table_lookup (self->priv->channels, GUINT_TO_POINTER (handle)); if (chan == NULL) { new_channel (self, handle, self->priv->conn->self_handle, request_token); } else if (require_new) { g_set_error (&error, TP_ERRORS, TP_ERROR_NOT_AVAILABLE, "A Text channel for room #%u already exists", handle); goto error; } else { tp_channel_manager_emit_request_already_satisfied (self, request_token, TP_EXPORTABLE_CHANNEL (chan)); } return TRUE; error: tp_channel_manager_emit_request_failed (self, request_token, error->domain, error->code, error->message); g_error_free (error); return TRUE; }
static gboolean gabble_im_factory_requestotron (GabbleImFactory *self, gpointer request_token, GHashTable *request_properties, gboolean require_new) { TpHandle handle; GError *error = NULL; TpExportableChannel *channel; if (tp_strdiff (tp_asv_get_string (request_properties, TP_IFACE_CHANNEL ".ChannelType"), TP_IFACE_CHANNEL_TYPE_TEXT)) return FALSE; if (tp_asv_get_uint32 (request_properties, TP_IFACE_CHANNEL ".TargetHandleType", NULL) != TP_HANDLE_TYPE_CONTACT) return FALSE; /* validity already checked by TpBaseConnection */ handle = tp_asv_get_uint32 (request_properties, TP_IFACE_CHANNEL ".TargetHandle", NULL); g_assert (handle != 0); if (tp_channel_manager_asv_has_unknown_properties (request_properties, im_channel_fixed_properties, im_channel_allowed_properties, &error)) goto error; channel = g_hash_table_lookup (self->priv->channels, GUINT_TO_POINTER (handle)); if (channel == NULL) { new_im_channel (self, handle, request_token); return TRUE; } if (require_new) { g_set_error (&error, TP_ERROR, TP_ERROR_NOT_AVAILABLE, "Already chatting with contact #%u in another channel", handle); goto error; } tp_channel_manager_emit_request_already_satisfied (self, request_token, channel); return TRUE; error: tp_channel_manager_emit_request_failed (self, request_token, error->domain, error->code, error->message); g_error_free (error); return TRUE; }
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; }
static gboolean _im_manager_requestotron (IdleIMManager *self, gpointer request_token, GHashTable *request_properties, gboolean require_new) { IdleIMManagerPrivate *priv = IDLE_IM_MANAGER_GET_PRIVATE (self); TpBaseConnection *base_conn = (TpBaseConnection *) priv->conn; TpHandleRepoIface *contact_repo = tp_base_connection_get_handles (base_conn, TP_HANDLE_TYPE_CONTACT); TpHandle handle; GError *error = NULL; TpExportableChannel *channel; if (tp_strdiff (tp_asv_get_string (request_properties, TP_IFACE_CHANNEL ".ChannelType"), TP_IFACE_CHANNEL_TYPE_TEXT)) return FALSE; if (tp_asv_get_uint32 (request_properties, TP_IFACE_CHANNEL ".TargetHandleType", NULL) != TP_HANDLE_TYPE_CONTACT) return FALSE; handle = tp_asv_get_uint32 (request_properties, TP_IFACE_CHANNEL ".TargetHandle", NULL); if (!tp_handle_is_valid (contact_repo, handle, &error)) goto error; /* Check if there are any other properties that we don't understand */ if (tp_channel_manager_asv_has_unknown_properties (request_properties, im_channel_fixed_properties, im_channel_allowed_properties, &error)) { goto error; } /* Don't support opening a channel to our self handle */ if (handle == base_conn->self_handle) { g_set_error (&error, TP_ERROR, TP_ERROR_NOT_IMPLEMENTED, "Can't open a text channel to yourself"); goto error; } channel = g_hash_table_lookup (priv->channels, GUINT_TO_POINTER (handle)); if (channel == NULL) { _im_manager_new_channel (self, handle, base_conn->self_handle, request_token); return TRUE; } if (require_new) { g_set_error (&error, TP_ERROR, TP_ERROR_NOT_AVAILABLE, "Already chatting with contact #%u in another channel", handle); goto error; } tp_channel_manager_emit_request_already_satisfied (self, request_token, channel); return TRUE; error: tp_channel_manager_emit_request_failed (self, request_token, error->domain, error->code, error->message); g_error_free (error); return TRUE; }