示例#1
0
static void
location_pep_node_changed (WockyPepService *pep,
    WockyBareContact *contact,
    WockyStanza *stanza,
    WockyNode *item_node,
    GabbleConnection *conn)
{
  TpHandleRepoIface *contact_repo = tp_base_connection_get_handles (
      (TpBaseConnection *) conn, TP_HANDLE_TYPE_CONTACT);
  TpBaseConnection *base = (TpBaseConnection *) conn;
  TpHandle handle;
  const gchar *jid;

  jid = wocky_bare_contact_get_jid (contact);
  handle = tp_handle_ensure (contact_repo, jid, NULL, NULL);
  if (handle == 0)
    {
      DEBUG ("Invalid from: %s", jid);
      return;
    }

  if (handle == tp_base_connection_get_self_handle (base))
    /* Ignore echoed pubsub notifications */
    return;

  update_location_from_item (conn, handle, item_node);
}
示例#2
0
void
example_call_stream_accept_proposed_direction (ExampleCallStream *self)
{
  GHashTable *updated_senders;
  GArray *removed_senders;

  if (self->priv->removed ||
      self->priv->local_sending_state != FUTURE_SENDING_STATE_PENDING_SEND)
    return;

  g_message ("%s: SIGNALLING: Sending to server: OK, I'll send you media",
      self->priv->object_path);

  self->priv->local_sending_state = FUTURE_SENDING_STATE_SENDING;

  updated_senders = g_hash_table_new (NULL, NULL);
  removed_senders = g_array_sized_new (FALSE, FALSE, sizeof (guint), 0);
  g_hash_table_insert (updated_senders,
      GUINT_TO_POINTER (tp_base_connection_get_self_handle (self->priv->conn)),
      GUINT_TO_POINTER (FUTURE_SENDING_STATE_SENDING));
  future_svc_call_stream_emit_senders_changed (self, updated_senders,
      removed_senders);
  g_hash_table_unref (updated_senders);
  g_array_free (removed_senders, TRUE);
}
void
ring_text_manager_add_capabilities(RingTextManager *self,
  guint handle,
  GPtrArray *returns)
{
  RingTextManagerPrivate *priv = RING_TEXT_MANAGER(self)->priv;
  char const *id = ring_connection_inspect_contact(priv->connection, handle);
  guint selfhandle = tp_base_connection_get_self_handle(
    (TpBaseConnection *)priv->connection);
  char *destination;

  if (id == NULL)
    return;

  /* Some UIs create channels even if they do not intend to send anything */
  /* Allow them to do so */

  destination = ring_text_channel_destination(id);

  if (handle == selfhandle || modem_sms_is_valid_address (destination)) {
    g_ptr_array_add(returns,
      ring_contact_capability_new(handle,
        TP_IFACE_CHANNEL_TYPE_TEXT,
        TP_CONNECTION_CAPABILITY_FLAG_CREATE,
        RING_TEXT_CHANNEL_CAPABILITY_FLAGS));
  }

  g_free(destination);
}
示例#4
0
const gchar *
conn_util_get_bare_self_jid (GabbleConnection *conn)
{
  TpBaseConnection *base = TP_BASE_CONNECTION (conn);
  TpHandleRepoIface *contact_handles = tp_base_connection_get_handles (base,
      TP_HANDLE_TYPE_CONTACT);
  TpHandle self = tp_base_connection_get_self_handle (base);

  return tp_handle_inspect (contact_handles, self);
}
示例#5
0
static void
get_property (GObject *object,
    guint property_id,
    GValue *value,
    GParamSpec *pspec)
{
  ExampleCallStream *self = EXAMPLE_CALL_STREAM (object);

  switch (property_id)
    {
    case PROP_OBJECT_PATH:
      g_value_set_string (value, self->priv->object_path);
      break;

    case PROP_INTERFACES:
      g_value_set_static_boxed (value, empty_strv);
      break;

    case PROP_HANDLE:
      g_value_set_uint (value, self->priv->handle);
      break;

    case PROP_CONNECTION:
      g_value_set_object (value, self->priv->conn);
      break;

    case PROP_SIMULATION_DELAY:
      g_value_set_uint (value, self->priv->simulation_delay);
      break;

    case PROP_LOCALLY_REQUESTED:
      g_value_set_boolean (value, self->priv->locally_requested);
      break;

    case PROP_SENDERS:
        {
          GHashTable *senders = g_hash_table_new (NULL, NULL);

          g_hash_table_insert (senders, GUINT_TO_POINTER (self->priv->handle),
              GUINT_TO_POINTER (self->priv->remote_sending_state));

          g_hash_table_insert (senders,
              GUINT_TO_POINTER (tp_base_connection_get_self_handle (
                  self->priv->conn)),
              GUINT_TO_POINTER (self->priv->local_sending_state));

          g_value_take_boxed (value, senders);
        }
      break;

    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
      break;
    }
}
static gboolean
rakia_nua_i_invite_cb (TpBaseConnection    *conn,
                       const RakiaNuaEvent *ev,
                       tagi_t               tags[],
                       RakiaMediaManager   *fac)
{
  TpHandle handle;
  RakiaSipSession *session;
  struct InviteData *idata;

  /* figure out a handle for the identity */

  handle = rakia_handle_by_requestor (conn, ev->sip);
  if (!handle)
    {
      MESSAGE ("incoming INVITE with invalid sender information");
      nua_respond (ev->nua_handle, 400, "Invalid From address", TAG_END());
      return TRUE;
    }

  DEBUG("Got incoming invite from <%s>",
        rakia_handle_inspect (conn, handle));

  if (handle == tp_base_connection_get_self_handle (conn))
    {
      DEBUG("cannot handle calls from self");
      nua_respond (ev->nua_handle, 501, "Calls from self are not supported", TAG_END());
      /* FIXME: Possible handle leak.. needs double checking ? */
      return TRUE;
    }

  session = new_session (fac, ev->nua_handle, 0);

  /* We delay emission of NewChannel(s) until we have the data on
   * initial media */
  idata = g_slice_new (struct InviteData);
  idata->fac = fac;
  idata->handle = handle;

  g_signal_connect (session, "incoming-call",
      G_CALLBACK (incoming_call_cb), idata);

  return TRUE;
}
static gboolean
ring_media_manager_outgoing_call(RingMediaManager *self,
  gpointer request,
  TpHandle target,
  TpHandle initial_remote,
  char const *emergency,
  gboolean initial_audio)
{
  RingMediaManagerPrivate *priv = self->priv;
  TpHandleType htype = target ? TP_HANDLE_TYPE_CONTACT : TP_HANDLE_TYPE_NONE;
  char *object_path = ring_media_manager_new_object_path(self, "outgoing");
  RingCallChannel *channel;
  TpHandle initiator;

  initiator = tp_base_connection_get_self_handle(
    TP_BASE_CONNECTION(priv->connection));

  channel = (RingCallChannel *)
    g_object_new(RING_TYPE_CALL_CHANNEL,
      "connection", priv->connection,
      "tones", priv->tones,
      "object-path", object_path,
      "initiator-handle", initiator,
      "handle-type", htype,
      "handle", target,
      "peer", target,
      "initial-remote", initial_remote,
      "requested", TRUE,
      "initial-audio", initial_audio,
      "anon-modes", priv->anon_modes,
      "initial-emergency-service", emergency,
      NULL);

  g_free(object_path);

  if (initial_audio)
    ring_call_channel_initial_audio(channel, self, request);
  else
    ring_media_manager_emit_new_channel(self, request, channel, NULL);

  return TRUE;
}
示例#8
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;
}
void
ring_media_manager_add_capabilities(RingMediaManager *self,
  guint handle,
  GPtrArray *returns)
{
  RingMediaManagerPrivate *priv = RING_MEDIA_MANAGER(self)->priv;
  char const *id = ring_connection_inspect_contact(priv->connection, handle);
  guint selfhandle = tp_base_connection_get_self_handle(
    (TpBaseConnection *)priv->connection);

  if (id == NULL)
    return;

  if (!ring_media_manager_is_connected (self))
    return;

  /* XXX - should check if we are in emergency call mode only status */

  if (handle == selfhandle) {
    if (priv->capability_flags)
      g_ptr_array_add(returns,
        ring_contact_capability_new(handle,
          TP_IFACE_CHANNEL_TYPE_STREAMED_MEDIA,
          TP_CONNECTION_CAPABILITY_FLAG_CREATE |
          TP_CONNECTION_CAPABILITY_FLAG_INVITE,
          RING_MEDIA_CHANNEL_CAPABILITY_FLAGS));
  }
  else if (modem_call_is_valid_address (id)) {
    g_ptr_array_add(returns,
      ring_contact_capability_new(handle,
        TP_IFACE_CHANNEL_TYPE_STREAMED_MEDIA,
        TP_CONNECTION_CAPABILITY_FLAG_CREATE |
        TP_CONNECTION_CAPABILITY_FLAG_INVITE,
        RING_MEDIA_CHANNEL_CAPABILITY_FLAGS));
  }
}
static void
on_modem_call_created(ModemCallService *call_service,
  ModemCall *modem_call,
  char const *destination,
  RingMediaManager *self)
{
  RingMediaManagerPrivate *priv = self->priv;
  TpHandleRepoIface *repo;
  RingCallChannel *channel;
  TpHandle handle;
  char const *sos;
  GError *error = NULL;

  if (!ring_media_manager_is_connected (self))
    return;

  channel = modem_call_get_handler(modem_call);
  if (channel)
    return; /* Call created by ring, nothing to do */

  /* This is a call created outside ring, create a channel for it */
  DEBUG("Freshly created call instance %s not associated with channel.",
    modem_call_get_name(modem_call));

  repo = tp_base_connection_get_handles(
    (TpBaseConnection *)(self->priv->connection), TP_HANDLE_TYPE_CONTACT);
  error = NULL;
  handle = tp_handle_ensure(repo, destination,
           ring_network_normalization_context(), &error);

  if (handle == 0) {
    ring_warning("tp_handle_ensure:" GERROR_MSG_FMT, GERROR_MSG_CODE(error));
    if (error) g_error_free(error);
    /* Xyzzy - modem_call_request_release() ?? */
    return;
  }

  sos = modem_call_get_emergency_service(priv->call_service, destination);

  char *object_path = ring_media_manager_new_object_path(self, "created");

  channel = (RingCallChannel *)
    g_object_new(RING_TYPE_CALL_CHANNEL,
      "connection", priv->connection,
      "tones", priv->tones,
      "object-path", object_path,
      "initiator-handle", tp_base_connection_get_self_handle(
        TP_BASE_CONNECTION(priv->connection)),
      "handle-type", TP_HANDLE_TYPE_CONTACT,
      "handle", handle,
      "peer", handle,
      "requested", TRUE,
      "initial-remote", handle,
      "initial-audio", TRUE,
      "anon-modes", priv->anon_modes,
      "call-instance", modem_call,
      "originating", TRUE,
      sos ? "initial-emergency-service" : NULL, sos,
      NULL);

  g_free(object_path);

  ring_media_manager_emit_new_channel(self, NULL, channel, NULL);
  ring_media_channel_set_state(RING_MEDIA_CHANNEL(channel),
    MODEM_CALL_STATE_DIALING, 0, 0);
}
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;
}
/**
 * new_call_channel
 *
 * Creates a new empty RakiaCallChannel.
 */
static RakiaCallChannel *
new_call_channel (RakiaMediaManager *fac,
                   TpHandle initiator,
                   TpHandle maybe_peer,
                   GHashTable *request_properties,
                   RakiaSipSession *session)
{
  RakiaMediaManagerPrivate *priv = RAKIA_MEDIA_MANAGER_GET_PRIVATE (fac);
  RakiaCallChannel *chan = NULL;
  gchar *object_path;
  gboolean initial_audio = FALSE;
  gboolean initial_video = FALSE;
  gboolean immutable_streams = FALSE;
  const gchar *dtmf_initial_tones = NULL;
  const gchar *initial_audio_name = NULL;
  const gchar *initial_video_name = NULL;
  TpHandle self_handle = tp_base_connection_get_self_handle (priv->conn);

  g_assert (initiator != 0);

  object_path = g_strdup_printf ("%s/CallChannel%u",
      tp_base_connection_get_object_path (priv->conn), priv->channel_index++);

  DEBUG("channel object path %s", object_path);

  if (request_properties != NULL)
    {
      initial_audio = tp_asv_get_boolean (request_properties,
          TP_PROP_CHANNEL_TYPE_CALL_INITIAL_AUDIO, NULL);
      initial_video = tp_asv_get_boolean (request_properties,
          TP_PROP_CHANNEL_TYPE_CALL_INITIAL_VIDEO, NULL);
      initial_audio_name = tp_asv_get_string (request_properties,
          TP_PROP_CHANNEL_TYPE_CALL_INITIAL_AUDIO_NAME);
      initial_video_name = tp_asv_get_string (request_properties,
          TP_PROP_CHANNEL_TYPE_CALL_INITIAL_VIDEO_NAME);
      dtmf_initial_tones = tp_asv_get_string (request_properties,
          TP_PROP_CHANNEL_INTERFACE_DTMF_INITIAL_TONES);
    }

  g_object_get (priv->conn,
      "immutable-streams", &immutable_streams,
      NULL);

  chan = g_object_new (RAKIA_TYPE_CALL_CHANNEL,
                       "connection", priv->conn,
                       "object-path", object_path,
                       "handle", maybe_peer,
                       "initiator-handle", initiator,
                       "initial-audio", initial_audio,
                       "initial-video", initial_video,
                       "initial-audio-name", initial_audio_name,
                       "initial-video-name", initial_video_name,
                       "initial-transport", TP_STREAM_TRANSPORT_TYPE_RAW_UDP,
                       "mutable-contents", !immutable_streams,
                       "initial-tones", dtmf_initial_tones,
                       "sip-session", session,
                       "stun-server", priv->stun_server ? priv->stun_server :
                       "",
                       "stun-port", priv->stun_port,
                       "requested", (initiator == self_handle),
                       NULL);

  g_free (object_path);


  g_signal_connect (chan, "closed", G_CALLBACK (call_channel_closed_cb), fac);

  g_ptr_array_add (priv->channels, chan);

  tp_base_channel_register (TP_BASE_CHANNEL (chan));

  return chan;
}
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 == tp_base_connection_get_self_handle (base_conn))
	{
		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, tp_base_connection_get_self_handle (base_conn), 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;
}
示例#14
0
static gboolean
example_echo_2_im_manager_request (ExampleEcho2ImManager *self,
                                   gpointer request_token,
                                   GHashTable *request_properties,
                                   gboolean require_new)
{
  TpHandle handle;
  ExampleEcho2Channel *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_CONTACT)
    {
      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,
          tp_base_connection_get_self_handle (self->priv->conn),
          request_token);
    }
  else if (require_new)
    {
      g_set_error (&error, TP_ERROR, TP_ERROR_NOT_AVAILABLE,
          "An echo2 channel to contact #%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;
}
示例#15
0
/* The remote user wants to change the direction of this stream according
 * to @local_send and @remote_send. Shall we let him? */
static void
example_call_stream_receive_direction_request (ExampleCallStream *self,
    gboolean local_send,
    gboolean remote_send)
{
  GHashTable *updated_senders = g_hash_table_new (NULL, NULL);

  /* In some protocols, streams cannot be neither sending nor receiving, so
   * if a stream is set to TP_MEDIA_STREAM_DIRECTION_NONE, this is equivalent
   * to removing it. (This is true in XMPP, for instance.)
   *
   * However, for this example we'll emulate a protocol where streams can be
   * directionless.
   */

  if (local_send)
    {
      g_message ("%s: SIGNALLING: send: Please start sending me media",
          self->priv->object_path);

      if (self->priv->local_sending_state == FUTURE_SENDING_STATE_NONE)
        {
          /* ask the user for permission */
          self->priv->local_sending_state = FUTURE_SENDING_STATE_PENDING_SEND;

          g_hash_table_insert (updated_senders,
              GUINT_TO_POINTER (tp_base_connection_get_self_handle (
                  self->priv->conn)),
              GUINT_TO_POINTER (FUTURE_SENDING_STATE_PENDING_SEND));
        }
      else
        {
          /* nothing to do, we're already sending (or asking the user for
           * permission to do so) on that stream */
        }
    }
  else
    {
      g_message ("%s: SIGNALLING: receive: Please stop sending me media",
          self->priv->object_path);
      g_message ("%s: SIGNALLING: reply: OK!",
          self->priv->object_path);

      if (self->priv->local_sending_state == FUTURE_SENDING_STATE_SENDING)
        {
          g_message ("%s: MEDIA: no longer sending media to peer",
              self->priv->object_path);
          self->priv->local_sending_state = FUTURE_SENDING_STATE_NONE;

          g_hash_table_insert (updated_senders,
              GUINT_TO_POINTER (tp_base_connection_get_self_handle (
                  self->priv->conn)),
              GUINT_TO_POINTER (FUTURE_SENDING_STATE_NONE));
        }
      else if (self->priv->local_sending_state ==
          FUTURE_SENDING_STATE_PENDING_SEND)
        {
          self->priv->local_sending_state = FUTURE_SENDING_STATE_NONE;

          g_hash_table_insert (updated_senders,
              GUINT_TO_POINTER (tp_base_connection_get_self_handle (
                  self->priv->conn)),
              GUINT_TO_POINTER (FUTURE_SENDING_STATE_NONE));
        }
      else
        {
          /* nothing to do, we're not sending on that stream anyway */
        }
    }

  if (remote_send)
    {
      g_message ("%s: SIGNALLING: receive: I will now send you media",
          self->priv->object_path);

      if (self->priv->remote_sending_state != FUTURE_SENDING_STATE_SENDING)
        {
          self->priv->remote_sending_state = FUTURE_SENDING_STATE_SENDING;

          g_hash_table_insert (updated_senders,
              GUINT_TO_POINTER (self->priv->handle),
              GUINT_TO_POINTER (FUTURE_SENDING_STATE_SENDING));
        }
    }
  else
    {
      if (self->priv->remote_sending_state ==
          FUTURE_SENDING_STATE_PENDING_SEND)
        {
          g_message ("%s: SIGNALLING: receive: No, I refuse to send you media",
              self->priv->object_path);
          self->priv->remote_sending_state = FUTURE_SENDING_STATE_NONE;

          g_hash_table_insert (updated_senders,
              GUINT_TO_POINTER (self->priv->handle),
              GUINT_TO_POINTER (FUTURE_SENDING_STATE_NONE));
        }
      else if (self->priv->remote_sending_state ==
          FUTURE_SENDING_STATE_SENDING)
        {
          g_message ("%s: SIGNALLING: receive: I will no longer send media",
              self->priv->object_path);
          self->priv->remote_sending_state = FUTURE_SENDING_STATE_NONE;

          g_hash_table_insert (updated_senders,
              GUINT_TO_POINTER (self->priv->handle),
              GUINT_TO_POINTER (FUTURE_SENDING_STATE_NONE));
        }
    }

  if (g_hash_table_size (updated_senders) != 0)
    {
      GArray *removed_senders = g_array_sized_new (FALSE, FALSE,
          sizeof (guint), 0);

      future_svc_call_stream_emit_senders_changed (self, updated_senders,
          removed_senders);

      g_array_free (removed_senders, TRUE);
    }

  g_hash_table_unref (updated_senders);
}
示例#16
0
static void
example_call_stream_change_direction (ExampleCallStream *self,
    gboolean want_to_send, gboolean want_to_receive)
{
  GHashTable *updated_senders = g_hash_table_new (NULL, NULL);

  if (want_to_send)
    {
      if (self->priv->local_sending_state != FUTURE_SENDING_STATE_SENDING)
        {
          if (self->priv->local_sending_state ==
              FUTURE_SENDING_STATE_PENDING_SEND)
            {
              g_message ("%s: SIGNALLING: send: I will now send you media",
                  self->priv->object_path);
            }

          g_message ("%s: MEDIA: sending media to peer",
              self->priv->object_path);
          self->priv->local_sending_state = FUTURE_SENDING_STATE_SENDING;

          g_hash_table_insert (updated_senders,
              GUINT_TO_POINTER (tp_base_connection_get_self_handle (
                  self->priv->conn)),
              GUINT_TO_POINTER (FUTURE_SENDING_STATE_SENDING));
        }
    }
  else
    {
      if (self->priv->local_sending_state == FUTURE_SENDING_STATE_SENDING)
        {
          g_message ("%s: SIGNALLING: send: I will no longer send you media",
              self->priv->object_path);
          g_message ("%s: MEDIA: no longer sending media to peer",
              self->priv->object_path);
          self->priv->local_sending_state = FUTURE_SENDING_STATE_NONE;

          g_hash_table_insert (updated_senders,
              GUINT_TO_POINTER (tp_base_connection_get_self_handle (
                  self->priv->conn)),
              GUINT_TO_POINTER (FUTURE_SENDING_STATE_NONE));
        }
      else if (self->priv->local_sending_state ==
          FUTURE_SENDING_STATE_PENDING_SEND)
        {
          g_message ("%s: SIGNALLING: send: refusing to send you media",
              self->priv->object_path);
          self->priv->local_sending_state = FUTURE_SENDING_STATE_NONE;

          g_hash_table_insert (updated_senders,
              GUINT_TO_POINTER (tp_base_connection_get_self_handle (
                  self->priv->conn)),
              GUINT_TO_POINTER (FUTURE_SENDING_STATE_NONE));
        }
    }

  if (want_to_receive)
    {
      if (self->priv->remote_sending_state == FUTURE_SENDING_STATE_NONE)
        {
          g_message ("%s: SIGNALLING: send: send me media, please?",
              self->priv->object_path);
          self->priv->remote_sending_state = FUTURE_SENDING_STATE_PENDING_SEND;
          g_timeout_add_full (G_PRIORITY_DEFAULT, self->priv->simulation_delay,
              simulate_contact_agreed_to_send_cb, g_object_ref (self),
              g_object_unref);

          g_hash_table_insert (updated_senders,
              GUINT_TO_POINTER (self->priv->handle),
              GUINT_TO_POINTER (FUTURE_SENDING_STATE_PENDING_SEND));
        }
    }
  else
    {
      if (self->priv->remote_sending_state != FUTURE_SENDING_STATE_NONE)
        {
          g_message ("%s: SIGNALLING: send: Please stop sending me media",
              self->priv->object_path);
          g_message ("%s: MEDIA: suppressing output of stream",
              self->priv->object_path);
          self->priv->remote_sending_state = FUTURE_SENDING_STATE_NONE;

          g_hash_table_insert (updated_senders,
              GUINT_TO_POINTER (self->priv->handle),
              GUINT_TO_POINTER (FUTURE_SENDING_STATE_NONE));
        }
    }

  if (g_hash_table_size (updated_senders) != 0)
    {
      GArray *removed_senders = g_array_sized_new (FALSE, FALSE,
          sizeof (guint), 0);

      future_svc_call_stream_emit_senders_changed (self, updated_senders,
          removed_senders);

      g_array_free (removed_senders, TRUE);
    }

  g_hash_table_unref (updated_senders);
}