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 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 ring_media_requestotron(RingMediaManager *self, gpointer request, GHashTable *properties, RequestotronMethod kind) { RingMediaManagerPrivate *priv = self->priv; TpHandle handle; /* If we're not connected, calls aren't supported. */ if (self->priv->call_service == NULL) return FALSE; handle = tp_asv_get_uint32 (properties, TP_IFACE_CHANNEL ".TargetHandle", NULL); if (kind == METHOD_COMPATIBLE && handle == 0 && ring_properties_satisfy(properties, ring_anon_channel_fixed_properties(), ring_anon_channel_allowed_properties)) { return ring_media_manager_outgoing_call(self, request, 0, 0, NULL, FALSE); } if (tp_asv_get_initial_video (properties, FALSE)) { tp_channel_manager_emit_request_failed (self, request, TP_ERRORS, TP_ERROR_NOT_IMPLEMENTED, "Video calls are not supported"); return TRUE; } if (handle != 0 && ring_properties_satisfy(properties, ring_call_channel_fixed_properties(), ring_call_channel_allowed_properties)) { RingCallChannel *channel; char const *target_id; GError *error = NULL; target_id = ring_connection_inspect_contact(priv->connection, handle); if (!modem_call_validate_address(target_id, &error)) { tp_channel_manager_emit_request_failed( self, request, TP_ERRORS, TP_ERROR_INVALID_HANDLE, error->message); g_error_free(error); return TRUE; } /* We do not yet support 'w' */ else if (strchr(target_id, 'w')) { tp_channel_manager_emit_request_failed( self, request, TP_ERRORS, TP_ERROR_NOT_IMPLEMENTED, "Dial strings containing 'w' are not supported"); return TRUE; } if (kind == METHOD_ENSURE) { channel = ring_media_manager_lookup_by_peer(self, handle); if (channel) { tp_channel_manager_emit_request_already_satisfied( self, request, TP_EXPORTABLE_CHANNEL(channel)); return TRUE; } } return ring_media_manager_outgoing_call(self, request, handle, kind == METHOD_COMPATIBLE ? handle : 0, modem_call_get_emergency_service(priv->call_service, target_id), tp_asv_get_initial_audio(properties, FALSE)); } return FALSE; }
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; }
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; }