Esempio n. 1
0
void
modem_call_service_resume (ModemCallService *self)
{
  GHashTableIter iter[1];
  ModemCall *ci;

  DEBUG ("enter");
  RETURN_IF_NOT_VALID (self);

  /* XXX/KV: no such signal */
#if 0
  g_signal_emit (self, signals[SIGNAL_EMERGENCY_NUMBERS_CHANGED], 0,
      modem_call_get_emergency_numbers (self));
#endif

  g_hash_table_iter_init (iter, self->priv->instances);
  while (g_hash_table_iter_next (iter, NULL, (gpointer)&ci))
    {
      char *remote;
      gboolean terminating = FALSE;
      ModemCallState state;

      g_object_get (ci,
          "state", &state,
          "remote", &remote,
          "terminating", &terminating,
          NULL);

      if (state != MODEM_CALL_STATE_DISCONNECTED &&
          state != MODEM_CALL_STATE_INVALID)
        {

          /* XXX - atm the value of 'terminating' cannot be trusted.
           * oFono should probably provide the direction as a property
           * since we cannot rely on the call state here. */
          if (terminating)
            {
              modem_message (MODEM_LOG_CALL,
                  "incoming [with state %s] call from \"%s\"",
                  modem_call_get_state_name (state), remote);
              DEBUG ("emit \"incoming\"(%s (%p), %s)",
                  modem_call_get_name (ci), ci, remote);
              g_signal_emit (self, signals[SIGNAL_INCOMING], 0, ci, remote);
            }
          else {
            modem_message (MODEM_LOG_CALL,
                "created [with state %s] call to \"%s\"",
                modem_call_get_state_name (state), remote);
            DEBUG ("emit \"created\"(%s (%p), %s)",
                modem_call_get_name (ci), ci, remote);
            g_signal_emit (self, signals[SIGNAL_CREATED], 0, ci, remote);
          }

          g_signal_emit_by_name (ci, "state", state, 0, 0);
        }

      g_free (remote);
    }
}
static void
on_modem_call_incoming(ModemCallService *call_service,
  ModemCall *modem_call,
  char const *originator,
  RingMediaManager *self)
{
  RingMediaManagerPrivate *priv = self->priv;
  TpHandleRepoIface *repo;
  RingCallChannel *channel;
  TpHandle handle;
  GError *error = NULL;

  if (!ring_media_manager_is_connected (self))
    return;

  channel = modem_call_get_handler(modem_call);
  if (channel) {
    modem_call_set_handler(modem_call, NULL);
    ring_critical("Call instance %s already associated with channel.",
      modem_call_get_name(modem_call));
    ring_critical("Closing old channel %s.", RING_MEDIA_CHANNEL(channel)->nick);
    ring_media_channel_close(RING_MEDIA_CHANNEL(channel));
  }

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

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

  /* Incoming call - pass call and handle ownership to new media channel */
  char *object_path = ring_media_manager_new_object_path(self, "incoming");

  channel = (RingCallChannel *)
    g_object_new(RING_TYPE_CALL_CHANNEL,
      "connection", priv->connection,
      "tones", priv->tones,
      "object-path", object_path,
      "initiator-handle", handle,
      "handle-type", TP_HANDLE_TYPE_CONTACT,
      "handle", handle,
      "peer", handle,
      "requested", FALSE,
      "initial-audio", TRUE,
      "anon-modes", priv->anon_modes,
      "call-instance", modem_call,
      "terminating", TRUE,
      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_INCOMING, 0, 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);
}
Esempio n. 4
0
static ModemCall *
modem_call_service_ensure_instance (ModemCallService *self,
                                    char const *object_path,
                                    GHashTable *properties)
{
  ModemCallServicePrivate *priv = self->priv;
  char *key;
  GValue *value;
  GHashTableIter iter[1];
  gchar const *remote;
  ModemCallState state;
  gboolean incoming = FALSE, originating = FALSE;
  ModemCall *ci;

  DEBUG ("path %s", object_path);

  if (DEBUGGING)
    {
      for (g_hash_table_iter_init (iter, properties);
           g_hash_table_iter_next (iter, (gpointer)&key, (gpointer)&value);)
        {
          char *s = g_strdup_value_contents (value);
          DEBUG ("%s = %s", key, s);
          g_free (s);
        }
    }

  ci = g_hash_table_lookup (priv->instances, object_path);
  if (ci)
    {
      DEBUG ("call already exists %p", (void *)ci);
      return ci;
    }

  value = g_hash_table_lookup (properties, "LineIdentification");
  remote = g_value_get_string (value);

  value = g_hash_table_lookup (properties, "State");
  state = modem_call_state_from_ofono_state (g_value_get_string (value));

  switch (state)
    {
    case MODEM_CALL_STATE_INCOMING:
    case MODEM_CALL_STATE_WAITING:
      incoming = TRUE;
      originating = FALSE;
      break;

    case MODEM_CALL_STATE_DIALING:
    case MODEM_CALL_STATE_ALERTING:
    case MODEM_CALL_STATE_ACTIVE:
    case MODEM_CALL_STATE_HELD:
      incoming = FALSE;
      originating = TRUE;
      break;

    case MODEM_CALL_STATE_INVALID:
    case MODEM_CALL_STATE_DISCONNECTED:
      DEBUG ("call already in invalid state");
      return NULL;
    }

  ci = g_object_new (MODEM_TYPE_CALL,
      "object-path", object_path,
      "call-service", self,
      "state", state,
      "terminating", !originating,
      "originating",  originating,
      NULL);

  modem_oface_update_properties (MODEM_OFACE (ci), properties);
  modem_call_service_connect_to_instance (self, ci);

  if (incoming)
    {
      DEBUG ("emit \"incoming\" (\"%s\" (%p), \"%s\")",
          modem_call_get_name (ci), ci, remote);
      g_signal_emit (self, signals[SIGNAL_INCOMING], 0, ci, remote);
      if (priv->forwarded && !strcmp(priv->forwarded, "incoming"))
        {
          g_signal_emit_by_name (ci, "forwarded");
        }
    }
  else if (g_queue_is_empty (priv->dialing.queue))
    {
      DEBUG ("emit \"created\" (\"%s\" (%p), \"%s\")",
          modem_call_get_name (ci), ci, remote);
      g_signal_emit (self, signals[SIGNAL_CREATED], 0, ci, remote);
      if (priv->forwarded && !strcmp(priv->forwarded, "outgoing"))
        {
          g_signal_emit_by_name (ci, "forwarded");
        }
    }
  else {
    g_queue_push_tail (priv->dialing.created, ci);
  }

  if (priv->forwarded)
    {
      g_free(priv->forwarded);
      priv->forwarded = NULL;
    }

  return ci;
}