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;
}
Example #2
0
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;
}
Example #3
0
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;
}