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;
}
Beispiel #3
0
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);
}
Beispiel #4
0
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);
}
Beispiel #7
0
/*
 * 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;
}
Beispiel #9
0
/**
 * 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;
}