Пример #1
0
/* Make sure google knows we want mail notifications. According to
 * Google clients should set 'mailnotifications' to true when needed
 * but never to false, for compatibility reasons:
 * https://code.google.com/apis/talk/jep_extensions/usersettings.html#3 */
static void
ensure_google_settings (GabbleConnection *self)
{
  TpBaseConnection *base_conn = TP_BASE_CONNECTION (self);
  WockyStanza *query;
  WockyPorter *porter;

  if (!self->mail_priv->should_set_google_settings)
    return;

  if (base_conn->status != TP_CONNECTION_STATUS_CONNECTED)
    return;

  porter = wocky_session_get_porter (self->session);
  query = wocky_stanza_build (WOCKY_STANZA_TYPE_IQ,
                              WOCKY_STANZA_SUB_TYPE_SET, NULL, NULL,
                              '@', "id", "user-setting-3",
                              '(', "usersetting",
                                ':', NS_GOOGLE_SETTING,
                                '(', "mailnotifications",
                                  '@', "value", "true",
                                ')',
                              ')',
                              NULL);
  wocky_porter_send_iq_async (porter, query, NULL,
                              set_settings_cb, self);
  self->mail_priv->should_set_google_settings = FALSE;

  g_object_unref (query);
}
Пример #2
0
static void
update_unread_mails (GabbleConnection *conn)
{
  TpBaseConnection *base_conn = TP_BASE_CONNECTION (conn);
  WockyStanza *query;
  WockyPorter *porter = wocky_session_get_porter (conn->session);

  if (base_conn->status != TP_CONNECTION_STATUS_CONNECTED)
    return;

  if (!(conn->features & GABBLE_CONNECTION_FEATURES_GOOGLE_MAIL_NOTIFY))
    return;

  DEBUG ("Updating unread mails information");

  query = wocky_stanza_build (WOCKY_STANZA_TYPE_IQ,
      WOCKY_STANZA_SUB_TYPE_GET, NULL, NULL,
      '(', "query",
        ':', NS_GOOGLE_MAIL_NOTIFY,
      ')',
      NULL);
  wocky_porter_send_iq_async (porter, query, NULL,
      query_unread_mails_cb, conn);
  g_object_unref (query);
}
Пример #3
0
static gboolean
set_own_status (GObject *object,
                const TpPresenceStatus *status,
                GError **error)
{
  ExampleContactListConnection *self =
    EXAMPLE_CONTACT_LIST_CONNECTION (object);
  TpBaseConnection *base = TP_BASE_CONNECTION (object);
  GHashTable *presences;

  if (status->index == EXAMPLE_CONTACT_LIST_PRESENCE_AWAY)
    {
      if (self->priv->away)
        return TRUE;

      self->priv->away = TRUE;
    }
  else
    {
      if (!self->priv->away)
        return TRUE;

      self->priv->away = FALSE;
    }

  presences = g_hash_table_new_full (g_direct_hash, g_direct_equal,
      NULL, NULL);
  g_hash_table_insert (presences, GUINT_TO_POINTER (base->self_handle),
      (gpointer) status);
  tp_presence_mixin_emit_presence_update (object, presences);
  g_hash_table_destroy (presences);
  return TRUE;
}
Пример #4
0
static gboolean
set_own_status (GObject *object,
    const TpPresenceStatus *status,
    GError **error)
{
  ExampleCallConnection *self =
    EXAMPLE_CALL_CONNECTION (object);
  TpBaseConnection *base = TP_BASE_CONNECTION (object);
  GHashTable *presences;
  const gchar *message = "";

  if (status->optional_arguments != NULL)
    {
      GValue *v = g_hash_table_lookup (status->optional_arguments, "message");

      if (v != NULL && G_VALUE_HOLDS_STRING (v))
        {
          message = g_value_get_string (v);

          if (message == NULL)
            message = "";
        }
    }

  if (status->index == EXAMPLE_CALL_PRESENCE_AWAY)
    {
      if (self->priv->away && !tp_strdiff (message,
            self->priv->presence_message))
        return TRUE;

      self->priv->away = TRUE;
    }
  else
    {
      if (!self->priv->away && !tp_strdiff (message,
            self->priv->presence_message))
        return TRUE;

      self->priv->away = FALSE;
    }

  g_free (self->priv->presence_message);
  self->priv->presence_message = g_strdup (message);

  presences = g_hash_table_new_full (g_direct_hash, g_direct_equal,
      NULL, NULL);
  g_hash_table_insert (presences, GUINT_TO_POINTER (base->self_handle),
      (gpointer) status);
  tp_presence_mixin_emit_presence_update (object, presences);
  g_hash_table_destroy (presences);

  if (!self->priv->away)
    {
      g_signal_emit (self, signals[SIGNAL_AVAILABLE], 0, message);
    }

  return TRUE;
}
Пример #5
0
static gboolean
pretend_disconnected (gpointer data)
{
  TpTestsSimpleConnection *self = TP_TESTS_SIMPLE_CONNECTION (data);

  tp_base_connection_finish_shutdown (TP_BASE_CONNECTION (data));
  self->priv->disconnect_source = 0;
  return FALSE;
}
Пример #6
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);
}
Пример #7
0
static void
get_alias_flags (TpSvcConnectionInterfaceAliasing *aliasing,
                 DBusGMethodInvocation *context)
{
  TpBaseConnection *base = TP_BASE_CONNECTION (aliasing);

  TP_BASE_CONNECTION_ERROR_IF_NOT_CONNECTED (base, context);
  tp_svc_connection_interface_aliasing_return_from_get_alias_flags (context,
      TP_CONNECTION_ALIAS_FLAG_USER_SET);
}
static void
conn_power_saving_set_power_saving (
    TpSvcConnectionInterfacePowerSaving *conn,
    gboolean enable,
    DBusGMethodInvocation *context)
{
  GabbleConnection *self = GABBLE_CONNECTION (conn);
  TpBaseConnection *base = TP_BASE_CONNECTION (self);
  gboolean enabled;

  TP_BASE_CONNECTION_ERROR_IF_NOT_CONNECTED (base, context);

  g_object_get (G_OBJECT (self), "power-saving", &enabled, NULL);

  if (enable == enabled)
    {
      /* no-op */
      tp_svc_connection_interface_power_saving_return_from_set_power_saving (
          context);
      return;
    }

  DEBUG ("%sabling presence queueing", enable ? "en" : "dis");

  /* google:queue is loosely described here:
   * <http://mail.jabber.org/pipermail/summit/2010-February/000528.html>. Since
   * April 2011, it is advertised as a stream feature by the Google Talk
   * server; the development version of M-Link, and possibly other servers,
   * also implement the protocol and advertise this stream feature. */
  if (self->features & GABBLE_CONNECTION_FEATURES_GOOGLE_QUEUE)
    {
      ToggleQueueingContext *queueing_context;
      queueing_context = g_slice_new0 (ToggleQueueingContext);
      queueing_context->enabling = enable;
      queueing_context->dbus_context = context;

      google_queueing_send_command (self, enable ? "enable" : "disable",
          toggle_google_queueing_cb, queueing_context);
    }
  else
    {
      /* If the server doesn't support any method of queueing, we can still
       * do it locally by enabling power save mode on Wocky. */
      WockyPorter *porter = gabble_connection_dup_porter (self);

      wocky_c2s_porter_enable_power_saving_mode (WOCKY_C2S_PORTER (porter), enable);
      DEBUG ("%sabled local stanza queueing", enable ? "En" : "Dis");
      g_object_unref (porter);
      maybe_emit_power_saving_changed (self, enable);

      tp_svc_connection_interface_power_saving_return_from_set_power_saving (
          context);
    }
}
Пример #9
0
static gboolean
status_available (GObject *object,
                  guint index_)
{
  TpBaseConnection *base = TP_BASE_CONNECTION (object);

  if (base->status != TP_CONNECTION_STATUS_CONNECTED)
    return FALSE;

  return TRUE;
}
static void
setup (Test *test,
    gconstpointer data)
{
  GError *error = NULL;
  GQuark features[] = { TP_CONNECTION_FEATURE_CONNECTED, 0 };

  tp_debug_set_flags ("all");
  test->dbus = tp_tests_dbus_daemon_dup_or_die ();

  test->mainloop = g_main_loop_new (NULL, FALSE);
  test->error = NULL;

  test->client_libdbus = dbus_bus_get_private (DBUS_BUS_STARTER, NULL);
  g_assert (test->client_libdbus != NULL);
  dbus_connection_setup_with_g_main (test->client_libdbus, NULL);
  dbus_connection_set_exit_on_disconnect (test->client_libdbus, FALSE);
  test->client_dbusglib = dbus_connection_get_g_connection (
      test->client_libdbus);
  dbus_g_connection_ref (test->client_dbusglib);
  test->client_bus = tp_dbus_daemon_new (test->client_dbusglib);
  g_assert (test->client_bus != NULL);

  test->service_conn = tp_tests_object_new_static_class (
        EXAMPLE_TYPE_CONTACT_LIST_CONNECTION,
        "account", "*****@*****.**",
        "protocol", "simple-protocol",
        NULL);
  test->service_conn_as_base = TP_BASE_CONNECTION (test->service_conn);
  g_assert (test->service_conn != NULL);
  g_assert (test->service_conn_as_base != NULL);

  g_assert (tp_base_connection_register (test->service_conn_as_base, "simple",
        &test->conn_name, &test->conn_path, &error));
  g_assert_no_error (error);

  test->cwr_ready = FALSE;
  test->cwr_error = NULL;

  test->conn = tp_connection_new (test->client_bus, test->conn_name,
      test->conn_path, &error);
  g_assert (test->conn != NULL);
  g_assert_no_error (error);

  tp_cli_connection_call_connect (test->conn, -1, NULL, NULL, NULL, NULL);

  g_assert (!tp_proxy_is_prepared (test->conn, TP_CONNECTION_FEATURE_CORE));
  g_assert (!tp_proxy_is_prepared (test->conn,
        TP_CONNECTION_FEATURE_CONNECTED));
  g_assert (!tp_proxy_is_prepared (test->conn, TP_CONNECTION_FEATURE_BALANCE));

  tp_tests_proxy_run_until_prepared (test->conn, features);
}
Пример #11
0
static void
constructed (GObject *object)
{
  TpBaseConnection *base = TP_BASE_CONNECTION (object);
  void (*chain_up) (GObject *) =
    G_OBJECT_CLASS (example_call_connection_parent_class)->constructed;

  if (chain_up != NULL)
    chain_up (object);

  tp_contacts_mixin_init (object,
      G_STRUCT_OFFSET (ExampleCallConnection, contacts_mixin));
  tp_base_connection_register_with_contacts_mixin (base);

  tp_presence_mixin_init (object,
      G_STRUCT_OFFSET (ExampleCallConnection, presence_mixin));
  tp_presence_mixin_simple_presence_register_with_contacts_mixin (object);
}
Пример #12
0
static GHashTable *
get_contact_statuses (GObject *object,
    const GArray *contacts,
    GError **error)
{
  ExampleCallConnection *self =
    EXAMPLE_CALL_CONNECTION (object);
  TpBaseConnection *base = TP_BASE_CONNECTION (object);
  guint i;
  GHashTable *result = g_hash_table_new_full (g_direct_hash, g_direct_equal,
      NULL, (GDestroyNotify) tp_presence_status_free);

  for (i = 0; i < contacts->len; i++)
    {
      TpHandle contact = g_array_index (contacts, guint, i);
      ExampleCallPresence presence;
      GHashTable *parameters;

      parameters = g_hash_table_new_full (g_str_hash,
          g_str_equal, NULL, (GDestroyNotify) tp_g_value_slice_free);

      /* we know our own status from the connection; for this example CM,
       * everyone else's status is assumed to be "available" */
      if (contact == base->self_handle)
        {
          presence = (self->priv->away ? EXAMPLE_CALL_PRESENCE_AWAY
              : EXAMPLE_CALL_PRESENCE_AVAILABLE);

          if (self->priv->presence_message[0] != '\0')
            g_hash_table_insert (parameters, "message",
                tp_g_value_slice_new_string (self->priv->presence_message));
        }
      else
        {
          presence = EXAMPLE_CALL_PRESENCE_AVAILABLE;
        }

      g_hash_table_insert (result, GUINT_TO_POINTER (contact),
          tp_presence_status_new (presence, parameters));
      g_hash_table_destroy (parameters);
    }

  return result;
}
Пример #13
0
static inline gboolean
check_supported_or_dbus_return (GabbleConnection *conn,
    DBusGMethodInvocation *context)
{
  if (TP_BASE_CONNECTION (conn)->status != TP_CONNECTION_STATUS_CONNECTED)
    {
      GError e = { TP_ERRORS, TP_ERROR_DISCONNECTED, "Not connected" };
      dbus_g_method_return_error (context, &e);
      return TRUE;
    }

  if (!(conn->features & GABBLE_CONNECTION_FEATURES_GOOGLE_MAIL_NOTIFY))
    {
      tp_dbus_g_method_return_not_implemented (context);
      return TRUE;
    }

  return FALSE;
}
Пример #14
0
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;
}
Пример #15
0
static void
request_aliases (TpSvcConnectionInterfaceAliasing *aliasing,
                 const GArray *contacts,
                 DBusGMethodInvocation *context)
{
  ExampleContactListConnection *self =
    EXAMPLE_CONTACT_LIST_CONNECTION (aliasing);
  TpBaseConnection *base = TP_BASE_CONNECTION (aliasing);
  TpHandleRepoIface *contact_repo = tp_base_connection_get_handles (base,
      TP_HANDLE_TYPE_CONTACT);
  GPtrArray *result;
  gchar **strings;
  GError *error = NULL;
  guint i;

  TP_BASE_CONNECTION_ERROR_IF_NOT_CONNECTED (base, context);

  if (!tp_handles_are_valid (contact_repo, contacts, FALSE, &error))
    {
      dbus_g_method_return_error (context, error);
      g_error_free (error);
      return;
    }

  result = g_ptr_array_sized_new (contacts->len + 1);

  for (i = 0; i < contacts->len; i++)
    {
      TpHandle contact = g_array_index (contacts, TpHandle, i);
      const gchar *alias = example_contact_list_manager_get_alias (
          self->priv->list_manager, contact);

      g_ptr_array_add (result, (gchar *) alias);
    }

  g_ptr_array_add (result, NULL);
  strings = (gchar **) g_ptr_array_free (result, FALSE);
  tp_svc_connection_interface_aliasing_return_from_request_aliases (context,
      (const gchar **) strings);
  g_free (strings);
}
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;
}
Пример #17
0
static void
tp_contacts_mixin_get_contact_attributes_impl (
  TpSvcConnectionInterfaceContacts *iface,
  const GArray *handles,
  const char **interfaces,
  gboolean hold,
  DBusGMethodInvocation *context)
{
  TpBaseConnection *conn = TP_BASE_CONNECTION (iface);
  GHashTable *result;

  TP_BASE_CONNECTION_ERROR_IF_NOT_CONNECTED (conn, context);

  result = tp_contacts_mixin_get_contact_attributes (G_OBJECT (conn),
      handles, interfaces, always_included_interfaces, NULL);

  tp_svc_connection_interface_contacts_return_from_get_contact_attributes (
      context, result);

  g_hash_table_unref (result);
}
Пример #18
0
static void
constructed (GObject *object)
{
  TpBaseConnection *base = TP_BASE_CONNECTION (object);
  void (*chain_up) (GObject *) =
    G_OBJECT_CLASS (example_contact_list_connection_parent_class)->constructed;

  if (chain_up != NULL)
    chain_up (object);

  tp_contacts_mixin_init (object,
      G_STRUCT_OFFSET (ExampleContactListConnection, contacts_mixin));
  tp_base_connection_register_with_contacts_mixin (base);
  tp_contacts_mixin_add_contact_attributes_iface (object,
      TP_IFACE_CONNECTION_INTERFACE_ALIASING,
      aliasing_fill_contact_attributes);

  tp_presence_mixin_init (object,
      G_STRUCT_OFFSET (ExampleContactListConnection, presence_mixin));
  tp_presence_mixin_simple_presence_register_with_contacts_mixin (object);
}
Пример #19
0
static GHashTable *
get_contact_statuses (GObject *object,
                      const GArray *contacts,
                      GError **error)
{
  ExampleContactListConnection *self =
    EXAMPLE_CONTACT_LIST_CONNECTION (object);
  TpBaseConnection *base = TP_BASE_CONNECTION (object);
  guint i;
  GHashTable *result = g_hash_table_new_full (g_direct_hash, g_direct_equal,
      NULL, (GDestroyNotify) tp_presence_status_free);

  for (i = 0; i < contacts->len; i++)
    {
      TpHandle contact = g_array_index (contacts, guint, i);
      ExampleContactListPresence presence;
      GHashTable *parameters;

      /* we get our own status from the connection, and everyone else's status
       * from the contact lists */
      if (contact == base->self_handle)
        {
          presence = (self->priv->away ? EXAMPLE_CONTACT_LIST_PRESENCE_AWAY
              : EXAMPLE_CONTACT_LIST_PRESENCE_AVAILABLE);
        }
      else
        {
          presence = example_contact_list_manager_get_presence (
              self->priv->list_manager, contact);
        }

      parameters = g_hash_table_new_full (g_str_hash,
          g_str_equal, NULL, (GDestroyNotify) tp_g_value_slice_free);
      g_hash_table_insert (result, GUINT_TO_POINTER (contact),
          tp_presence_status_new (presence, parameters));
      g_hash_table_destroy (parameters);
    }

  return result;
}
Пример #20
0
static void
on_modem_call_emergency_numbers_changed (ModemCallService *call_service,
                                         GParamSpec *dummy,
                                         RingMediaManager *self)
{
  RingMediaManagerPrivate *priv = RING_MEDIA_MANAGER(self)->priv;
  TpBaseConnection *base = TP_BASE_CONNECTION(priv->connection);
  gchar **numbers;
  RingEmergencyServiceInfoList *services;

  if (base->status != TP_CONNECTION_STATUS_CONNECTED)
    return;

  g_object_get (call_service, "emergency-numbers", &numbers, NULL);
  services = ring_emergency_service_info_list_default (numbers);

  METHOD (tp_svc_connection_interface_service_point,
      emit_service_points_changed) (priv->connection, services);

  ring_emergency_service_info_list_free(services);
  g_strfreev (numbers);
}
Пример #21
0
static void
get_aliases (TpSvcConnectionInterfaceAliasing *aliasing,
             const GArray *contacts,
             DBusGMethodInvocation *context)
{
  ExampleContactListConnection *self =
    EXAMPLE_CONTACT_LIST_CONNECTION (aliasing);
  TpBaseConnection *base = TP_BASE_CONNECTION (aliasing);
  TpHandleRepoIface *contact_repo = tp_base_connection_get_handles (base,
      TP_HANDLE_TYPE_CONTACT);
  GHashTable *result;
  GError *error = NULL;
  guint i;

  TP_BASE_CONNECTION_ERROR_IF_NOT_CONNECTED (base, context);

  if (!tp_handles_are_valid (contact_repo, contacts, FALSE, &error))
    {
      dbus_g_method_return_error (context, error);
      g_error_free (error);
      return;
    }

  result = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, NULL);

  for (i = 0; i < contacts->len; i++)
    {
      TpHandle contact = g_array_index (contacts, TpHandle, i);
      const gchar *alias = example_contact_list_manager_get_alias (
          self->priv->list_manager, contact);

      g_hash_table_insert (result, GUINT_TO_POINTER (contact),
          (gchar *) alias);
    }

  tp_svc_connection_interface_aliasing_return_from_get_aliases (context,
      result);
  g_hash_table_destroy (result);
}
Пример #22
0
static void
tp_contacts_mixin_get_contact_by_id_impl (
  TpSvcConnectionInterfaceContacts *iface,
  const gchar *id,
  const gchar **interfaces,
  DBusGMethodInvocation *context)
{
  TpBaseConnection *conn = TP_BASE_CONNECTION (iface);
  TpHandleRepoIface *contact_repo = tp_base_connection_get_handles (conn,
      TP_HANDLE_TYPE_CONTACT);
  GetContactByIdData *data;

  TP_BASE_CONNECTION_ERROR_IF_NOT_CONNECTED (conn, context);

  data = g_slice_new0 (GetContactByIdData);
  data->conn = g_object_ref (conn);
  data->interfaces = g_strdupv ((gchar **) interfaces);
  data->context = context;

  tp_handle_ensure_async (contact_repo, conn, id, NULL,
      ensure_handle_cb, data);
}
Пример #23
0
static void
set_aliases (TpSvcConnectionInterfaceAliasing *aliasing,
             GHashTable *aliases,
             DBusGMethodInvocation *context)
{
  ExampleContactListConnection *self =
    EXAMPLE_CONTACT_LIST_CONNECTION (aliasing);
  TpBaseConnection *base = TP_BASE_CONNECTION (aliasing);
  TpHandleRepoIface *contact_repo = tp_base_connection_get_handles (base,
      TP_HANDLE_TYPE_CONTACT);
  GHashTableIter iter;
  gpointer key, value;

  g_hash_table_iter_init (&iter, aliases);

  while (g_hash_table_iter_next (&iter, &key, &value))
    {
      GError *error = NULL;

      if (!tp_handle_is_valid (contact_repo, GPOINTER_TO_UINT (key),
            &error))
        {
          dbus_g_method_return_error (context, error);
          g_error_free (error);
          return;
        }
    }

  g_hash_table_iter_init (&iter, aliases);

  while (g_hash_table_iter_next (&iter, &key, &value))
    {
      example_contact_list_manager_set_alias (self->priv->list_manager,
          GPOINTER_TO_UINT (key), value);
    }

  tp_svc_connection_interface_aliasing_return_from_set_aliases (context);
}
Пример #24
0
static char *
ring_media_manager_new_object_path(RingMediaManager const *self,
  char const *type)
{
  RingMediaManagerPrivate const *priv = self->priv;
  char const *base_path = TP_BASE_CONNECTION(priv->connection)->object_path;

  static unsigned media_index;
  static unsigned media_index_init;

  if (!media_index_init) {
    media_index = (guint)(time(NULL) - (38 * 365 * 24 * 60 * 60)) * 10;
    media_index_init = 1;
  }

  /* Find an unique D-Bus object_path */
  for (;;) {
    char *path = g_strdup_printf("%s/%s%u", base_path, type, ++media_index);
    if (!g_hash_table_lookup(priv->channels, path)) {
      return path;
    }
    g_free(path);
  }
}
static void _parse_and_forward_one(IdleParser *parser, gchar **tokens, IdleParserMessageCode code, const gchar *format) {
	IdleParserPrivate *priv = IDLE_PARSER_GET_PRIVATE(parser);
	GValueArray *args = g_value_array_new(3);
	GSList *link_ = priv->handlers[code];
	IdleParserHandlerResult result = IDLE_PARSER_HANDLER_RESULT_NOT_HANDLED;
	gboolean success = TRUE;
	gchar **iter = tokens;
	/* We keep a ref to each unique handle in a message so that we can unref them after calling all handlers */
	TpHandleSet *contact_reffed = tp_handle_set_new(tp_base_connection_get_handles(TP_BASE_CONNECTION(priv->conn), TP_HANDLE_TYPE_CONTACT));
	TpHandleSet *room_reffed = tp_handle_set_new(tp_base_connection_get_handles(TP_BASE_CONNECTION(priv->conn), TP_HANDLE_TYPE_ROOM));

	IDLE_DEBUG("message code %u", code);

	while ((*format != '\0') && success && (*iter != NULL)) {
		GValue val = {0};

		if (*format == 'v') {
			format++;
			while (*iter != NULL) {
				if (!_parse_atom(parser, args, *format, iter[0], contact_reffed, room_reffed)) {
					success = FALSE;
					break;
				}

				iter += 2;
			}
		} else if ((*format == ':') || (*format == '.')) {
			/* Assume the happy case of the trailing parameter starting after the :
			 * in the trailing string as the RFC intended */
			const gchar *trailing = iter[1] + 1;

			/* Some IRC proxies *cough* bip *cough* omit the : in the trailing
			 * parameter if that parameter is just one word, to cope with that check
			 * if there are no more tokens after the current one and if so, accept a
			 * trailing string without the : prefix. */
			if (iter[0][0] != ':') {
				if (iter[2] == NULL) {
					trailing = iter[1];
				} else {
					success = FALSE;
					break;
				}
			}

			/*
			 * because of the way things are tokenized, if there is a
			 * space immediately after the the ':', the current token will only be
			 * ":", so we check that the trailing string is non-NULL rather than
			 * checking iter[0][1] (since iter[0] is a NULL-terminated token string
			 * whereas trailing is a pointer into the full message string
			 */
			if (trailing[0] == '\0') {
				success = FALSE;
				break;
			}

			g_value_init(&val, G_TYPE_STRING);
			g_value_set_string(&val, trailing);
			g_value_array_append(args, &val);
			g_value_unset(&val);

			IDLE_DEBUG("set string \"%s\"", trailing);
		} else {
			if (!_parse_atom(parser, args, *format, iter[0], contact_reffed, room_reffed)) {
				success = FALSE;
				break;
			}
		}

		format++;
		iter += 2;
	}

	if (!success && (*format != '.')) {
		IDLE_DEBUG("failed to parse \"%s\"", tokens[1]);

		goto cleanup;
	}

	if (*format && (*format != '.')) {
		IDLE_DEBUG("missing args in message \"%s\"", tokens[1]);

		goto cleanup;
	}

	IDLE_DEBUG("successfully parsed");

	while (link_) {
		MessageHandlerClosure *closure = link_->data;
		result = closure->handler(parser, code, args, closure->user_data);
		if (result == IDLE_PARSER_HANDLER_RESULT_NOT_HANDLED) {
			link_ = link_->next;
		} else if (result == IDLE_PARSER_HANDLER_RESULT_HANDLED) {
			break;
		} else if (result == IDLE_PARSER_HANDLER_RESULT_NO_MORE_PLEASE) {
			GSList *tmp = link_->next;
			g_free(closure);
			priv->handlers[code] = g_slist_remove_link(priv->handlers[code], link_);
			link_ = tmp;
		} else {
			g_assert_not_reached();
		}
	}

cleanup:

	g_value_array_free(args);

	tp_handle_set_destroy(contact_reffed);
	tp_handle_set_destroy(room_reffed);
}
static gboolean _parse_atom(IdleParser *parser, GValueArray *arr, char atom, const gchar *token, TpHandleSet *contact_reffed, TpHandleSet *room_reffed) {
	IdleParserPrivate *priv = IDLE_PARSER_GET_PRIVATE(parser);
	TpHandle handle;
	GValue val = {0};
	TpHandleRepoIface *contact_repo = tp_base_connection_get_handles(TP_BASE_CONNECTION(priv->conn), TP_HANDLE_TYPE_CONTACT);
	TpHandleRepoIface *room_repo = tp_base_connection_get_handles(TP_BASE_CONNECTION(priv->conn), TP_HANDLE_TYPE_ROOM);

	if (token[0] == ':')
		token++;

	IDLE_DEBUG("parsing atom \"%s\" as %c", token, atom);

	switch (atom) {
		case 'I':
			IDLE_DEBUG("ignored token");
			return TRUE;
			break;

		case 'c':
		case 'r':
		case 'C': {
			gchar *id, *bang = NULL;
			gchar modechar = '\0';

			if (idle_muc_channel_is_modechar(token[0])) {
				modechar = token[0];
				token++;
			}

			id = g_strdup(token);

			if (atom != 'r') {
				bang = strchr(id, '!');
				if (bang)
					*bang = '\0';
			}

			if (atom == 'r') {
				if ((handle = tp_handle_ensure(room_repo, id, NULL, NULL))) {
					tp_handle_set_add(room_reffed, handle);
				}
			} else {
				if ((handle = tp_handle_ensure(contact_repo, id, NULL, NULL))) {
					tp_handle_set_add(contact_reffed, handle);

					idle_connection_canon_nick_receive(priv->conn, handle, id);
				}
			}

			g_free(id);

			if (!handle)
				return FALSE;

			g_value_init(&val, G_TYPE_UINT);
			g_value_set_uint(&val, handle);
			g_value_array_append(arr, &val);
			g_value_unset(&val);

			IDLE_DEBUG("set handle %u", handle);

			if (atom == 'C') {
				g_value_init(&val, G_TYPE_CHAR);
				g_value_set_schar(&val, modechar);
				g_value_array_append(arr, &val);
				g_value_unset(&val);

				IDLE_DEBUG("set modechar %c", modechar);
			}

			return TRUE;
		}
		break;

		case 'd': {
			guint dval;

			if (sscanf(token, "%d", &dval)) {
				g_value_init(&val, G_TYPE_UINT);
				g_value_set_uint(&val, dval);
				g_value_array_append(arr, &val);
				g_value_unset(&val);

				IDLE_DEBUG("set int %d", dval);

				return TRUE;
			} else {
				return FALSE;
			}
		}
		break;

		case 's':
			g_value_init(&val, G_TYPE_STRING);
			g_value_set_string(&val, token);
			g_value_array_append(arr, &val);
			g_value_unset(&val);
			IDLE_DEBUG("set string \"%s\"", token);

			return TRUE;
			break;

		default:
			IDLE_DEBUG("unknown atom %c", atom);
			return FALSE;
			break;
	}
}
Пример #27
0
/**
 * tp_contacts_mixin_get_contact_attributes: (skip)
 * @obj: A connection instance that uses this mixin. The connection must be connected.
 * @handles: List of handles to retrieve contacts for. Any invalid handles will be
 * dropped from the returned mapping.
 * @interfaces: A list of interfaces to retrieve attributes from.
 * @assumed_interfaces: A list of additional interfaces to retrieve attributes
 *  from. This can be used for interfaces documented as automatically included,
 *  like %TP_IFACE_CONNECTION for GetContactAttributes,
 *  or %TP_IFACE_CONNECTION and %TP_IFACE_CONNECTION_INTERFACE_CONTACT_LIST for
 *  GetContactListAttributes.
 * @sender: The DBus client's unique name. If this is not NULL, the requested handles
 * will be held on behalf of this client.
 *
 * Get contact attributes for the given contacts. Provide attributes for all requested
 * interfaces. If contact attributes are not immediately known, the behaviour is defined
 * by the interface; the attribute should either be omitted from the result or replaced
 * with a default value.
 *
 * Returns: A dictionary mapping the contact handles to contact attributes.
 *
 */
GHashTable *
tp_contacts_mixin_get_contact_attributes (GObject *obj,
    const GArray *handles,
    const gchar **interfaces,
    const gchar **assumed_interfaces,
    const gchar *sender)
{
  GHashTable *result;
  guint i;
  TpBaseConnection *conn = TP_BASE_CONNECTION (obj);
  TpContactsMixin *self = TP_CONTACTS_MIXIN (obj);
  TpHandleRepoIface *contact_repo = tp_base_connection_get_handles (conn,
        TP_HANDLE_TYPE_CONTACT);
  GArray *valid_handles;
  TpContactsMixinFillContactAttributesFunc func;

  g_return_val_if_fail (TP_IS_BASE_CONNECTION (obj), NULL);
  g_return_val_if_fail (TP_CONTACTS_MIXIN_OFFSET (obj) != 0, NULL);
  g_return_val_if_fail (tp_base_connection_check_connected (conn, NULL), NULL);

  /* Setup handle array and hash with valid handles, optionally holding them */
  valid_handles = g_array_sized_new (TRUE, TRUE, sizeof (TpHandle),
      handles->len);
  result = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL,
      (GDestroyNotify) g_hash_table_unref);

  for (i = 0 ; i < handles->len ; i++)
    {
      TpHandle h;
      h = g_array_index (handles, TpHandle, i);
      if (tp_handle_is_valid (contact_repo, h, NULL))
        {
          GHashTable *attr_hash = g_hash_table_new_full (g_str_hash,
              g_str_equal, g_free, (GDestroyNotify) tp_g_value_slice_free);
          g_array_append_val (valid_handles, h);
          g_hash_table_insert (result, GUINT_TO_POINTER(h), attr_hash);
        }
    }

  for (i = 0; assumed_interfaces != NULL && assumed_interfaces[i] != NULL; i++)
    {
      func = g_hash_table_lookup (self->priv->interfaces, assumed_interfaces[i]);

      if (func == NULL)
        DEBUG ("non-inspectable assumed interface %s given; ignoring",
            assumed_interfaces[i]);
      else
        func (obj, valid_handles, result);
    }

  for (i = 0; interfaces != NULL && interfaces[i] != NULL; i++)
    {

      func = g_hash_table_lookup (self->priv->interfaces, interfaces[i]);

      if (func == NULL)
        DEBUG ("non-inspectable interface %s given; ignoring", interfaces[i]);
      else
        func (obj, valid_handles, result);
    }

  g_array_unref (valid_handles);

  return result;
}
Пример #28
0
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);
}