ModemRequest * modem_call_request_answer (ModemCall *self, ModemCallReply callback, gpointer user_data) { DEBUG ("enter"); RETURN_NULL_IF_NOT_VALID (self); if (self->priv->state != MODEM_CALL_STATE_WAITING) { DEBUG ("%s.%s (%s)", MODEM_OFACE_CALL, "Answer", modem_call_get_path (self)); return modem_request (MODEM_CALL (self), modem_oface_dbus_proxy (MODEM_OFACE (self)), "Answer", reply_to_instance_request, G_CALLBACK (callback), user_data, G_TYPE_INVALID); } else { DEBUG ("%s.%s (%s)", MODEM_OFACE_CALL_MANAGER, "HoldAndAnswer", modem_call_get_path (self)); return modem_request (MODEM_CALL (self), modem_oface_dbus_proxy (MODEM_OFACE (self->priv->service)), "HoldAndAnswer", reply_to_instance_request, G_CALLBACK (callback), user_data, G_TYPE_INVALID); } }
ModemRequest * modem_call_request_hold (ModemCall *self, int hold, ModemCallReply callback, gpointer user_data) { ModemCallPrivate *priv = self->priv; DEBUG (""); RETURN_NULL_IF_NOT_VALID (self); if (!((priv->state == MODEM_CALL_STATE_HELD && !hold) || (priv->state == MODEM_CALL_STATE_ACTIVE && hold))) { DEBUG ("invalid hold request %d in %s state\n", hold, priv->state_str); return NULL; } DEBUG ("%s.%s", MODEM_OFACE_CALL_MANAGER, "SwapCalls"); return modem_request (MODEM_CALL (self), modem_oface_dbus_proxy (MODEM_OFACE (self->priv->service)), "SwapCalls", reply_to_instance_request, G_CALLBACK (callback), user_data, G_TYPE_INVALID); }
gboolean modem_call_has_path (ModemCall const *self, char const *object_path) { gchar const *my_path = modem_oface_object_path (MODEM_OFACE (self)); return object_path && my_path && strcmp (my_path, object_path) == 0; }
static void modem_sim_service_constructed (GObject *object) { if (G_OBJECT_CLASS (modem_sim_service_parent_class)->constructed) G_OBJECT_CLASS (modem_sim_service_parent_class)->constructed (object); if (modem_oface_dbus_proxy (MODEM_OFACE (object)) == NULL) g_warning("object created without dbus-proxy set"); }
static void modem_call_constructed (GObject *object) { if (G_OBJECT_CLASS (modem_call_parent_class)->constructed) G_OBJECT_CLASS (modem_call_parent_class)->constructed (object); DEBUG ("ModemCall for %s on %s", modem_oface_object_path (MODEM_OFACE (object)), MODEM_OFACE_CALL); }
ModemRequest * modem_call_send_dtmf (ModemCall *self, char const *dialstring, ModemCallReply *callback, gpointer user_data) { int i; char modemstring[256]; RETURN_NULL_IF_NOT_VALID (self); g_return_val_if_fail (dialstring != NULL, NULL); for (i = 0; dialstring[i]; i++) { if (i == 255) return NULL; /* Too long */ switch (dialstring[i]) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': case '#': case '*': modemstring[i] = dialstring[i]; break; case 'p': case 'P': modemstring[i] = 'p'; break; case 'w': case 'W': modemstring[i] = 'w'; break; case 'a': case 'A': modemstring[i] = 'a'; break; case 'b': case 'B': modemstring[i] = 'b'; break; case 'c': case 'C': modemstring[i] = 'c'; break; case 'd': case 'D': modemstring[i] = 'd'; break; default: return NULL; } } modemstring[i] = '\0'; return modem_request (self, modem_oface_dbus_proxy (MODEM_OFACE (self->priv->service)), "SendTones", reply_to_instance_request, G_CALLBACK (callback), user_data, G_TYPE_STRING, modemstring, G_TYPE_INVALID); }
ModemRequest * modem_call_stop_dtmf (ModemCall *self, ModemCallReply *callback, gpointer user_data) { RETURN_NULL_IF_NOT_VALID (self); return modem_request (MODEM_CALL (self), modem_oface_dbus_proxy (MODEM_OFACE (self->priv->service)), "StopTones", reply_to_stop_dtmf, G_CALLBACK (callback), user_data, G_TYPE_INVALID); }
ModemRequest * modem_sms_set_sc_address (ModemSMSService *self, char const *address, ModemSMSServiceReply *callback, gpointer user_data) { GValue value[1]; g_value_init (memset (value, 0, sizeof value), G_TYPE_STRING); g_value_set_string (value, address); return modem_oface_set_property_req (MODEM_OFACE (self), "ServiceCenterAddress", value, (void *)callback, user_data); }
ModemRequest * modem_call_request_release (ModemCall *self, ModemCallReply callback, gpointer user_data) { DEBUG ("%s.%s (%s)", MODEM_OFACE_CALL, "Hangup", modem_call_get_path (self)); RETURN_NULL_IF_NOT_VALID (self); return modem_request (MODEM_CALL (self), modem_oface_dbus_proxy (MODEM_OFACE (self)), "Hangup", reply_to_instance_request, G_CALLBACK (callback), user_data, G_TYPE_INVALID); }
ModemRequest * modem_sms_set_srr (ModemSMSService *self, gboolean srr, ModemSMSServiceReply *callback, gpointer user_data) { GValue value[1]; g_value_init (memset (value, 0, sizeof value), G_TYPE_BOOLEAN); g_value_set_boolean (value, srr); return modem_oface_set_property_req (MODEM_OFACE (self), "UseDeliveryReports", value, (void *)callback, user_data); }
char const * modem_call_get_name (ModemCall const *self) { if (self == NULL) return "<nil>"; char const *path = modem_oface_object_path (MODEM_OFACE (self)); char const *last = strrchr (path, '/'); if (last) return last + 1; return "<invalid>"; }
ModemRequest * modem_call_request_split (ModemCall *self, ModemCallReply callback, gpointer user_data) { DEBUG ("%s.%s (%s)", MODEM_OFACE_CALL_MANAGER, "PrivateChat", modem_call_get_path (self)); RETURN_NULL_IF_NOT_VALID (self); return modem_request (MODEM_CALL (self), modem_oface_dbus_proxy (MODEM_OFACE (self->priv->service)), "PrivateChat", reply_to_private_chat_request, G_CALLBACK (callback), user_data, DBUS_TYPE_G_OBJECT_PATH, modem_call_get_path (self), G_TYPE_INVALID); }
/* XXX: Ofono at the moment supports only fixed-duration tones */ ModemRequest * modem_call_start_dtmf (ModemCall *self, char const tone, ModemCallReply *callback, gpointer user_data) { char tones[2] = { tone }; RETURN_NULL_IF_NOT_VALID (self); return modem_request (MODEM_CALL (self), modem_oface_dbus_proxy (MODEM_OFACE (self->priv->service)), "SendTones", reply_to_instance_request, G_CALLBACK (callback), user_data, G_TYPE_STRING, tones, G_TYPE_INVALID); }
static void modem_call_service_connect_to_instance (ModemCallService *self, ModemCall *instance) { ModemCallServicePrivate *priv = self->priv; gchar const *object_path; if (!instance) return; g_signal_connect (instance, "state", G_CALLBACK (on_modem_call_state), self); modem_oface_connect (MODEM_OFACE (instance)); object_path = modem_call_get_path (instance); g_hash_table_insert (priv->instances, (gpointer) object_path, instance); }
static void modem_call_service_disconnect_instance (ModemCallService *self, ModemCall *instance) { ModemCallServicePrivate *priv = self->priv; if (!instance) return; g_hash_table_steal (priv->instances, modem_call_get_path (instance)); g_signal_handlers_disconnect_by_func (instance, on_modem_call_state, self); g_signal_emit (self, signals[SIGNAL_REMOVED], 0, instance); modem_oface_disconnect (MODEM_OFACE (instance)); g_object_unref (instance); }
static void on_sim_notify_imsi (ModemSIMService *sim, GParamSpec *dummy, Modem *self) { gchar *imsi = NULL; DEBUG ("enter"); g_object_get (sim, "imsi", &imsi, NULL); if (imsi == NULL) return; if (strlen (imsi)) { DEBUG ("emitting imsi-added \"%s\" for %s", imsi, modem_oface_object_path (MODEM_OFACE (sim))); g_signal_emit (self, signals[SIGNAL_IMSI_ADDED], 0, imsi); } g_free (imsi); }
ModemRequest * modem_sms_request_send (ModemSMSService *self, char const *to, char const *message, ModemSMSServiceSendReply *reply, gpointer user_data) { ModemRequest *request; DEBUG (MODEM_OFACE_SMS ".SendMessage (%s,%s)", to, message); request = modem_request (self, modem_oface_dbus_proxy (MODEM_OFACE (self)), "SendMessage", reply_to_send_message, G_CALLBACK (reply), user_data, G_TYPE_STRING, to, G_TYPE_STRING, message, G_TYPE_INVALID); if (request) modem_request_add_data_full (request, "destination", g_strdup (to), g_free); return request; }
char const * modem_get_modem_path (Modem const *self) { return modem_oface_object_path (MODEM_OFACE (self)); }
static void modem_update_interfaces (Modem *self) { ModemPrivate *priv = self->priv; ModemOface *oface; ModemOface *already; GHashTableIter iter[1]; char const *object_path; GHashTable *prev_ifhash; char *interface; guint i; DEBUG ("enter"); prev_ifhash = priv->ifhash; priv->ifhash = g_hash_table_new (g_str_hash, g_str_equal); for (i = 0; priv->interfaces[i]; i++) { interface = g_strdup (priv->interfaces[i]); g_hash_table_insert (priv->ifhash, interface, GUINT_TO_POINTER(1)); } object_path = modem_oface_object_path (MODEM_OFACE (self)); for (i = 0; priv->interfaces[i]; i++) { interface = priv->interfaces[i]; if (g_hash_table_lookup (priv->ofaces, interface)) continue; if (g_hash_table_lookup (prev_ifhash, interface)) continue; oface = modem_oface_new (interface, object_path); if (oface == NULL) { DEBUG("Modem %s ignoring interface %s", object_path, interface); continue; } DEBUG("Modem %s adding interface %s", object_path, interface); already = g_hash_table_lookup (priv->connecting, interface); if (already) { /* interface was added, removed and added before it got connected */ g_signal_handlers_disconnect_by_func (already, on_oface_connected, self); } g_hash_table_insert (priv->connecting, g_strdup (interface), oface); g_signal_connect (oface, "connected", G_CALLBACK (on_oface_connected), self); modem_oface_connect (oface); } g_hash_table_unref (prev_ifhash); DEBUG("All modem %s interfaces added", object_path); redo_connecting: for (g_hash_table_iter_init (iter, priv->connecting); g_hash_table_iter_next (iter, (gpointer)&interface, (gpointer)&oface);) { if (g_hash_table_lookup (priv->ifhash, interface) == NULL) { modem_oface_disconnect (oface); goto redo_connecting; } } redo_ofaces: for (g_hash_table_iter_init (iter, priv->ofaces); g_hash_table_iter_next (iter, (gpointer)&interface, (gpointer)&oface);) { if (g_hash_table_lookup (priv->ifhash, interface) == NULL) { modem_oface_disconnect (oface); goto redo_ofaces; } } }
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; }