From 88a2c660f42d41ab24ce0e5cd2432890a70cfc12 Mon Sep 17 00:00:00 2001 From: Pekka Pessi Date: Thu, 4 Nov 2010 21:51:51 +0200 Subject: modem/call: derive ModemCallService and ModemCall from ModemOface --- modem/call-service.c | 633 ++++++++++++++++++++------------------------------- modem/call.c | 295 +++++++++++++----------- modem/call.h | 23 +- 3 files changed, 413 insertions(+), 538 deletions(-) diff --git a/modem/call-service.c b/modem/call-service.c index 89c3a0a..96529af 100644 --- a/modem/call-service.c +++ b/modem/call-service.c @@ -41,7 +41,7 @@ /* ---------------------------------------------------------------------- */ -G_DEFINE_TYPE (ModemCallService, modem_call_service, G_TYPE_OBJECT); +G_DEFINE_TYPE (ModemCallService, modem_call_service, MODEM_TYPE_OFACE); /* Properties */ enum @@ -54,11 +54,10 @@ enum /* Signals */ enum { - SIGNAL_CONNECTED, SIGNAL_INCOMING, SIGNAL_CREATED, SIGNAL_USER_CONNECTION, - SIGNAL_EMERGENCY_NUMBERS_CHANGED, + SIGNAL_REMOVED, N_SIGNALS }; @@ -66,8 +65,6 @@ static guint signals[N_SIGNALS]; struct _ModemCallServicePrivate { - DBusGProxy *proxy; /* D-Bus proxy to call server */ - /* < object_path, call instance > */ GHashTable *instances; @@ -85,44 +82,50 @@ struct _ModemCallServicePrivate ModemCall *active, *hold; - struct { - GQueue queue[1]; - GError *error; - } connecting; - unsigned user_connection:1; /* Do we have in-band connection? */ - unsigned connected:1, disconnected:1, signals :1, dispose_has_run:1; + unsigned signals :1; unsigned :0; }; /* ---------------------------------------------------------------------- */ -static ModemOfonoPropsReply reply_to_call_manager_get_properties; -static ModemOfonoPropChangedCb on_manager_property_changed; - static void modem_call_service_connect_to_instance (ModemCallService *self, ModemCall *ci); static void modem_call_service_disconnect_instance (ModemCallService *self, ModemCall *ci); +static ModemCall *modem_call_service_ensure_instance (ModemCallService *self, + char const *object_path, + GHashTable *properties); + static ModemRequestCallNotify modem_call_request_dial_reply; static ModemRequestCallNotify modem_call_conference_request_reply; -static void modem_call_service_check_connected (ModemCallService *self, - ModemRequest *request, - GError const *error); - #if nomore static void on_user_connection (DBusGProxy *proxy, gboolean attached, ModemCallService *self); #endif + static void on_modem_call_state (ModemCall *, ModemCallState, ModemCallService *); -static void on_modem_call_terminated (ModemCall *, ModemCallService *); + +/* ---------------------------------------------------------------------- */ + +#define RETURN_IF_NOT_VALID(self) \ + g_return_if_fail (self != NULL && \ + modem_oface_is_connected (MODEM_OFACE (self))) + +#define RETURN_VAL_IF_NOT_VALID(self, val) \ + g_return_val_if_fail (self != NULL && \ + modem_oface_is_connected (MODEM_OFACE (self)), (val)) + +#define RETURN_NULL_IF_NOT_VALID(self) RETURN_VAL_IF_NOT_VALID (self, NULL) + +#define DBUS_PROXY(x) modem_oface_dbus_proxy (MODEM_OFACE (x)) /* ---------------------------------------------------------------------- */ @@ -136,14 +139,14 @@ modem_call_service_constructed (GObject *object) static void modem_call_service_init (ModemCallService *self) { + DEBUG ("enter"); + self->priv = G_TYPE_INSTANCE_GET_PRIVATE(self, MODEM_TYPE_CALL_SERVICE, ModemCallServicePrivate); g_queue_init (self->priv->dialing.queue); g_queue_init (self->priv->dialing.created); - g_queue_init (self->priv->connecting.queue); - self->priv->instances = g_hash_table_new_full ( g_str_hash, g_str_equal, g_free, g_object_unref); } @@ -198,61 +201,161 @@ modem_call_service_dispose (GObject *object) { DEBUG ("enter"); - ModemCall *ci; - GHashTableIter iter[1]; + if (G_OBJECT_CLASS (modem_call_service_parent_class)->dispose) + G_OBJECT_CLASS (modem_call_service_parent_class)->dispose (object); +} + + +static void +modem_call_service_finalize (GObject *object) +{ + DEBUG ("enter"); + ModemCallService *self = MODEM_CALL_SERVICE (object); ModemCallServicePrivate *priv = self->priv; - if (priv->dispose_has_run) - return; + g_strfreev (priv->emergency_numbers), priv->emergency_numbers = NULL; - modem_call_service_disconnect (self); + g_hash_table_destroy (priv->instances); - priv->dispose_has_run = TRUE; + G_OBJECT_CLASS (modem_call_service_parent_class)->finalize (object); - g_hash_table_iter_init (iter, priv->instances); - while (g_hash_table_iter_next (iter, NULL, (gpointer)&ci)) + DEBUG ("leave"); +} + +/* ---------------------------------------------------------------------- */ + +static ModemOfaceManagedReply reply_to_call_manager_get_calls; + +static void on_manager_call_added (DBusGProxy *proxy, + char const *path, GHashTable *properties, + gpointer user_data); + +static void on_manager_call_removed (DBusGProxy *proxy, + char const *path, + gpointer user_data); + +static char const * +modem_call_service_property_mapper (char const *name) +{ + if (!strcmp (name, "EmergencyNumbers")) + return "emergency-numbers"; + return NULL; +} + +static void +reply_to_call_manager_get_calls (ModemOface *_self, + ModemRequest *request, + GPtrArray *array, + GError const *error, + gpointer user_data) +{ + ModemCallService *self = MODEM_CALL_SERVICE (_self); + + DEBUG ("enter"); + + if (!error) { - modem_call_service_disconnect_instance (self, ci); + guint i; + + for (i = 0; i < array->len; i++) + { + GValueArray *va = g_ptr_array_index (array, i); + char const *path = g_value_get_boxed (va->values + 0); + GHashTable *properties = g_value_get_boxed (va->values + 1); + + modem_call_service_ensure_instance (self, path, properties); + } } - ci = priv->conference.instance; - modem_call_service_disconnect_instance (self, ci); + modem_oface_check_connected (_self, request, error); +} + +/** Connect to call service */ +static void +modem_call_service_connect (ModemOface *_self) +{ + DEBUG ("(%p): enter", _self); - if (priv->proxy) - g_object_run_dispose (G_OBJECT (priv->proxy)); + ModemCallService *self = MODEM_CALL_SERVICE (_self); + ModemCallServicePrivate *priv = self->priv; - if (G_OBJECT_CLASS (modem_call_service_parent_class)->dispose) - G_OBJECT_CLASS (modem_call_service_parent_class)->dispose (object); + if (!priv->signals) + { + DBusGProxy *proxy = DBUS_PROXY (_self); - DEBUG ("leave"); + priv->signals = TRUE; + +#define CONNECT(p, handler, name, signature...) \ + dbus_g_proxy_add_signal (p, (name), ##signature); \ + dbus_g_proxy_connect_signal (p, (name), G_CALLBACK (handler), self, NULL) + + CONNECT (proxy, on_manager_call_added, "CallAdded", + DBUS_TYPE_G_OBJECT_PATH, MODEM_TYPE_DBUS_DICT, G_TYPE_INVALID); + + CONNECT (proxy, on_manager_call_removed, "CallRemoved", + DBUS_TYPE_G_OBJECT_PATH, G_TYPE_INVALID); + +#undef CONNECT + } + + modem_oface_connect_properties (_self, TRUE); + + modem_oface_add_connect_request (_self, + modem_oface_request_managed (_self, "GetCalls", + reply_to_call_manager_get_calls, NULL)); } +/** Disconnect from call service */ static void -modem_call_service_finalize (GObject *object) +modem_call_service_disconnect (ModemOface *_self) { - DEBUG ("enter"); + DEBUG ("(%p): enter", _self); - ModemCallService *self = MODEM_CALL_SERVICE (object); + ModemCallService *self = MODEM_CALL_SERVICE (_self); ModemCallServicePrivate *priv = self->priv; + GHashTableIter iter[1]; + ModemCall *ci; - if (priv->proxy) g_object_unref (priv->proxy), priv->proxy = NULL; - g_strfreev (priv->emergency_numbers), priv->emergency_numbers = NULL; - g_clear_error (&priv->connecting.error); + while (!g_queue_is_empty (priv->dialing.queue)) + { + ModemRequest *request = g_queue_pop_head (priv->dialing.queue); + modem_request_cancel (request); + } - g_hash_table_destroy (priv->instances); + if (priv->signals) + { + priv->signals = FALSE; - G_OBJECT_CLASS (modem_call_service_parent_class)->finalize (object); + dbus_g_proxy_disconnect_signal (DBUS_PROXY (self), "CallAdded", + G_CALLBACK (on_manager_call_added), self); + dbus_g_proxy_disconnect_signal (DBUS_PROXY (self), "CallRemoved", + G_CALLBACK (on_manager_call_removed), self); + } - DEBUG ("leave"); + for (g_hash_table_iter_init (iter, priv->instances); + g_hash_table_iter_next (iter, NULL, (gpointer)&ci); + g_hash_table_iter_init (iter, priv->instances)) + { + modem_call_service_disconnect_instance (self, ci); + } + + ci = priv->conference.instance; + modem_call_service_disconnect_instance (self, ci); + + modem_oface_disconnect_properties (_self); } +/* ---------------------------------------------------------------------- */ static void modem_call_service_class_init (ModemCallServiceClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); + ModemOfaceClass *oface_class = MODEM_OFACE_CLASS (klass); + + DEBUG ("enter"); g_type_class_add_private (klass, sizeof (ModemCallServicePrivate)); @@ -262,6 +365,10 @@ modem_call_service_class_init (ModemCallServiceClass *klass) object_class->dispose = modem_call_service_dispose; object_class->finalize = modem_call_service_finalize; + oface_class->property_mapper = modem_call_service_property_mapper; + oface_class->connect = modem_call_service_connect; + oface_class->disconnect = modem_call_service_disconnect; + /* Properties */ g_object_class_install_property (object_class, PROP_EMERGENCY_NUMBERS, g_param_spec_boxed ("emergency-numbers", @@ -272,14 +379,6 @@ modem_call_service_class_init (ModemCallServiceClass *klass) G_PARAM_STATIC_STRINGS)); /* Signals to emit */ - signals[SIGNAL_CONNECTED] = - g_signal_new ("connected", G_OBJECT_CLASS_TYPE (klass), - G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED, - 0, - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - signals[SIGNAL_INCOMING] = g_signal_new ("incoming", G_OBJECT_CLASS_TYPE (klass), G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED, @@ -298,69 +397,64 @@ modem_call_service_class_init (ModemCallServiceClass *klass) G_TYPE_NONE, 2, MODEM_TYPE_CALL, G_TYPE_STRING); - signals[SIGNAL_USER_CONNECTION] = - g_signal_new ("user-connection", G_OBJECT_CLASS_TYPE (klass), + signals[SIGNAL_REMOVED] = + g_signal_new ("removed", G_OBJECT_CLASS_TYPE (klass), G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED, 0, NULL, NULL, - g_cclosure_marshal_VOID__BOOLEAN, + _modem__marshal_VOID__OBJECT, G_TYPE_NONE, 1, - G_TYPE_BOOLEAN); + MODEM_TYPE_CALL); - signals[SIGNAL_EMERGENCY_NUMBERS_CHANGED] = - g_signal_new ("emergency-numbers-changed", G_OBJECT_CLASS_TYPE (klass), + signals[SIGNAL_USER_CONNECTION] = + g_signal_new ("user-connection", G_OBJECT_CLASS_TYPE (klass), G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED, 0, NULL, NULL, - g_cclosure_marshal_VOID__BOXED, + g_cclosure_marshal_VOID__BOOLEAN, G_TYPE_NONE, 1, - G_TYPE_STRV); - + G_TYPE_BOOLEAN); - modem_error_domain_prefix (0); /* Init errors */ + DEBUG ("leave"); } /* ---------------------------------------------------------------------- */ -#define RETURN_NULL_IF_NOT_VALID(self) \ - g_return_val_if_fail (self != NULL && self->priv->proxy != NULL && \ - !self->priv->dispose_has_run, NULL) +static void +modem_call_service_connect_to_instance (ModemCallService *self, + ModemCall *instance) +{ + ModemCallServicePrivate *priv = self->priv; + gchar const *object_path; -/* ---------------------------------------------------------------------- */ + if (!instance) + return; -static ModemOfonoGetDescsReply reply_to_call_manager_get_calls; + g_signal_connect (instance, "state", G_CALLBACK (on_modem_call_state), self); -static void on_manager_call_added (DBusGProxy *proxy, - char const *path, - GHashTable *properties, - gpointer user_data); + modem_oface_connect (MODEM_OFACE (instance)); -/* ---------------------------------------------------------------------- */ + object_path = modem_call_get_path (instance); -static void -modem_call_service_connect_to_instance (ModemCallService *self, - ModemCall *instance) -{ - if (instance) - { - g_signal_connect (instance, "state", - G_CALLBACK (on_modem_call_state), self); - g_signal_connect_after (instance, "terminated", - G_CALLBACK (on_modem_call_terminated), self); - } + g_hash_table_insert (priv->instances, g_strdup (object_path), instance); } static void modem_call_service_disconnect_instance (ModemCallService *self, ModemCall *instance) { - if (instance) - { - g_signal_handlers_disconnect_by_func (instance, - on_modem_call_state, self); - g_signal_handlers_disconnect_by_func (instance, - on_modem_call_terminated, self); - } + ModemCallServicePrivate *priv = self->priv; + + if (!instance) + return; + + g_hash_table_remove (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)); } static ModemCall * @@ -372,9 +466,10 @@ modem_call_service_ensure_instance (ModemCallService *self, char *key; GValue *value; GHashTableIter iter[1]; - char const *remote; + gchar const *remote; ModemCallState state; gboolean incoming = FALSE, originating = FALSE; + DBusGProxy *proxy; ModemCall *ci; DEBUG ("path %s", object_path); @@ -425,27 +520,28 @@ modem_call_service_ensure_instance (ModemCallService *self, return NULL; } + proxy = modem_ofono_proxy (object_path, OFONO_IFACE_CALL); + ci = g_object_new (MODEM_TYPE_CALL, + "dbus-proxy", proxy, "call-service", self, - "object-path", object_path, - "remote", remote, "state", state, "terminating", !originating, "originating", originating, NULL); + modem_oface_update_properties (MODEM_OFACE (ci), properties); modem_call_service_connect_to_instance (self, ci); - g_hash_table_insert (priv->instances, g_strdup (object_path), ci); if (incoming) { - DEBUG ("emit \"incoming\"(%s (%p), %s)", + DEBUG ("emit \"incoming\" (\"%s\" (%p), \"%s\")", modem_call_get_name (ci), ci, remote); g_signal_emit (self, signals[SIGNAL_INCOMING], 0, ci, remote); } else if (g_queue_is_empty (priv->dialing.queue)) { - DEBUG ("emit \"created\"(%s (%p), %s)", + DEBUG ("emit \"created\" (\"%s\" (%p), \"%s\")", modem_call_get_name (ci), ci, remote); g_signal_emit (self, signals[SIGNAL_CREATED], 0, ci, remote); } @@ -463,6 +559,7 @@ modem_call_service_get_dialed (ModemCallService *self, { ModemCallServicePrivate *priv = self->priv; ModemCall *ci; + DBusGProxy *proxy; ci = g_hash_table_lookup (priv->instances, object_path); if (ci) @@ -475,89 +572,26 @@ modem_call_service_get_dialed (ModemCallService *self, return ci; } + proxy = modem_ofono_proxy (object_path, OFONO_IFACE_CALL); + ci = g_object_new (MODEM_TYPE_CALL, + "dbus-proxy", proxy, "call-service", self, - "object-path", object_path, "remote", remote, "state", MODEM_CALL_STATE_DIALING, + "ofono-state", "dialing", "terminating", FALSE, "originating", TRUE, NULL); modem_call_service_connect_to_instance (self, ci); - g_hash_table_insert (priv->instances, g_strdup (object_path), ci); return ci; } -/* ---------------------------------------------------------------------- */ - -DBusGProxy * -_modem_call_service_proxy (ModemCallService *self) -{ - RETURN_NULL_IF_NOT_VALID (self); - - return self->priv->proxy; -} - /* ---------------------------------------------------------------------- */ /* ModemCallService interface */ -gboolean -modem_call_service_connect (ModemCallService *self, - char const *object_path) -{ - ModemCallServicePrivate *priv = self->priv; - - if (priv->dispose_has_run) - return FALSE; - - if (priv->disconnected) - return FALSE; - - if (priv->connected) - return TRUE; - - if (!g_queue_is_empty (priv->connecting.queue)) - return TRUE; - - g_clear_error (&priv->connecting.error); - - if (!priv->proxy) - priv->proxy = modem_ofono_proxy (object_path, - OFONO_IFACE_CALL_MANAGER); - - if (!priv->proxy) - { - g_error ("Failed to proxy the call service"); - return FALSE; - } - - if (!priv->signals) - { - priv->signals = TRUE; - - modem_ofono_proxy_connect_to_property_changed ( - priv->proxy, on_manager_property_changed, self); - - dbus_g_proxy_add_signal (priv->proxy, "CallAdded", - DBUS_TYPE_G_OBJECT_PATH, MODEM_TYPE_DBUS_DICT, G_TYPE_INVALID); - - dbus_g_proxy_connect_signal (priv->proxy, "CallAdded", - G_CALLBACK (on_manager_call_added), self, NULL); - } - - g_queue_push_tail (priv->connecting.queue, - modem_ofono_proxy_request_properties (priv->proxy, - reply_to_call_manager_get_properties, self, NULL)); - - g_queue_push_tail (priv->connecting.queue, - modem_ofono_request_descs (self, priv->proxy, - "GetCalls", reply_to_call_manager_get_calls, NULL)); - - return TRUE; -} - #if 0 static void refresh_conference_memberships (ModemCallService *self, @@ -597,76 +631,6 @@ refresh_conference_memberships (ModemCallService *self, } #endif -static void -on_manager_property_changed (DBusGProxy *proxy, - char const *property, - GValue const *value, - gpointer user_data) -{ - ModemCallService *self = MODEM_CALL_SERVICE (user_data); - - if (DEBUGGING) - { - char *s; - DEBUG ("enter"); - s = g_strdup_value_contents (value); - DEBUG ("%s = %s", property, s); - g_free (s); - } - - if (!strcmp (property, "EmergencyNumbers")) - { - g_object_set_property (G_OBJECT (self), "emergency-numbers", value); - g_signal_emit (self, signals[SIGNAL_EMERGENCY_NUMBERS_CHANGED], 0, - modem_call_get_emergency_numbers (self)); - } -#if 0 - else if (!strcmp (property, "MultipartyCalls")) - { - refresh_conference_memberships (self, g_value_get_boxed (value)); - } -#endif -} - -static void -reply_to_call_manager_get_properties (gpointer _self, - ModemRequest *request, - GHashTable *properties, - GError const *error, - gpointer user_data) -{ - ModemCallService *self = MODEM_CALL_SERVICE (_self); - - DEBUG ("enter"); - - if (!error) - { - GValue *value; - - value = g_hash_table_lookup (properties, "EmergencyNumbers"); - if (value) - { - g_object_set_property (G_OBJECT (self), "emergency-numbers", value); - } - - if (DEBUGGING) - { - char *key; - GHashTableIter iter[1]; - - 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); - } - } - } - - modem_call_service_check_connected (self, request, error); -} - static void on_manager_call_added (DBusGProxy *proxy, char const *path, @@ -681,133 +645,25 @@ on_manager_call_added (DBusGProxy *proxy, } static void -reply_to_call_manager_get_calls (gpointer _self, - ModemRequest *request, - GPtrArray *array, - GError const *error, - gpointer user_data) -{ - ModemCallService *self = _self; - - DEBUG ("enter"); - - if (!error) - { - guint i; - - for (i = 0; i < array->len; i++) - { - GValueArray *va = g_ptr_array_index (array, i); - char const *path = g_value_get_boxed (va->values + 0); - GHashTable *properties = g_value_get_boxed (va->values + 1); - - modem_call_service_ensure_instance (self, path, properties); - } - } - - modem_call_service_check_connected (self, request, error); -} - -static void -modem_call_service_check_connected (ModemCallService *self, - ModemRequest *request, - GError const *error) -{ - ModemCallServicePrivate *priv = self->priv; - - if (g_queue_find (priv->connecting.queue, request)) - { - g_queue_remove (priv->connecting.queue, request); - - if (error) - { - if (!priv->connecting.error || - priv->connecting.error->domain == DBUS_GERROR) - { - g_clear_error (&priv->connecting.error); - g_set_error (&priv->connecting.error, - error->domain, error->code, - "%s", error->message); - } - - modem_critical (MODEM_SERVICE_CALL, GERROR_MSG_FMT, - GERROR_MSG_CODE (priv->connecting.error)); - } - - if (g_queue_is_empty (priv->connecting.queue)) - { - priv->connected = priv->connecting.error == NULL; - DEBUG ("emit \"connected\"(%s)", priv->connected ? "TRUE" : "FALSE"); - g_signal_emit (self, signals[SIGNAL_CONNECTED], 0); - } - } -} - -/** Disconnect from call service */ -void -modem_call_service_disconnect (ModemCallService *self) +on_manager_call_removed (DBusGProxy *proxy, + char const *path, + gpointer user_data) { - DEBUG ("(%p): enter", self); + DEBUG ("%s", path); + ModemCallService *self = MODEM_CALL_SERVICE (user_data); ModemCallServicePrivate *priv = self->priv; - unsigned was_connected = priv->connected; - - g_return_if_fail (!priv->dispose_has_run); - - if (priv->disconnected) - return; + ModemCall *ci = g_hash_table_lookup (priv->instances, path); - priv->connected = FALSE; - priv->disconnected = TRUE; - - while (!g_queue_is_empty (priv->connecting.queue)) - { - ModemRequest *request = g_queue_pop_head (priv->connecting.queue); - modem_request_cancel (request); - } - - while (!g_queue_is_empty (priv->dialing.queue)) - { - ModemRequest *request = g_queue_pop_head (priv->connecting.queue); - modem_request_cancel (request); - } - - if (priv->signals) + if (ci) { - priv->signals = FALSE; - - modem_ofono_proxy_disconnect_from_property_changed ( - priv->proxy, on_manager_property_changed, self); - - dbus_g_proxy_disconnect_signal (priv->proxy, "CallAdded", - G_CALLBACK (on_manager_call_added), self); + modem_call_service_disconnect_instance (self, ci); } - - g_clear_error (&priv->connecting.error); - - if (was_connected) - g_signal_emit (self, signals[SIGNAL_CONNECTED], 0); } -gboolean -modem_call_service_is_connected (ModemCallService const *self) -{ - return MODEM_IS_CALL_SERVICE (self) && self->priv->connected; -} - -gboolean -modem_call_service_is_connecting (ModemCallService const *self) -{ - return MODEM_IS_CALL_SERVICE (self) - && !g_queue_is_empty (self->priv->connecting.queue); -} - - void modem_call_service_resume (ModemCallService *self) { - DEBUG ("enter"); - GHashTableIter iter[1]; ModemCall *membercall = NULL; ModemCall *ci; @@ -815,11 +671,14 @@ modem_call_service_resume (ModemCallService *self) ModemCallConference *mcc; #endif - if (!self->priv->connected) - return; + 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)) @@ -1038,11 +897,9 @@ modem_call_request_dial (ModemCallService *self, ModemRequest *request; ModemCallServicePrivate *priv = self->priv; - RETURN_NULL_IF_NOT_VALID (self); - DEBUG ("called"); - g_return_val_if_fail (priv->connected, NULL); + RETURN_NULL_IF_NOT_VALID (self); g_return_val_if_fail (destination != NULL, NULL); g_return_val_if_fail (callback != NULL, NULL); @@ -1057,7 +914,7 @@ modem_call_request_dial (ModemCallService *self, else clir_str = ""; - request = modem_request_begin (self, priv->proxy, + request = modem_request_begin (self, DBUS_PROXY (self), "Dial", modem_call_request_dial_reply, G_CALLBACK (callback), user_data, G_TYPE_STRING, destination, @@ -1108,10 +965,11 @@ modem_call_request_dial_reply (DBusGProxy *proxy, { ci = modem_call_service_get_dialed (self, object_path, destination); } - else { - object_path = NULL; - modem_error_fix (&error); - } + else + { + object_path = NULL; + modem_error_fix (&error); + } if (ci) { @@ -1122,29 +980,31 @@ modem_call_request_dial_reply (DBusGProxy *proxy, "call create request to \"%s\" successful", destination); } - else { - char ebuffer[32]; + else + { + char ebuffer[32]; - modem_message (MODEM_SERVICE_CALL, - "call create request to \"%s\" failed: %s.%s: %s", - destination, - modem_error_domain_prefix (error->domain), - modem_error_name (error, ebuffer, sizeof ebuffer), - error->message); + modem_message (MODEM_SERVICE_CALL, + "call create request to \"%s\" failed: %s.%s: %s", + destination, + modem_error_domain_prefix (error->domain), + modem_error_name (error, ebuffer, sizeof ebuffer), + error->message); - DEBUG ("%s: " GERROR_MSG_FMT, OFONO_IFACE_CALL_MANAGER ".Dial", - GERROR_MSG_CODE (error)); - } + DEBUG ("%s: " GERROR_MSG_FMT, OFONO_IFACE_CALL_MANAGER ".Dial", + GERROR_MSG_CODE (error)); + } if (modem_request_get_data (request, "call-canceled")) { if (ci) modem_call_request_release (ci, NULL, NULL); } - else { - g_assert (ci || error); - callback (self, request, ci, error, user_data); - } + else + { + g_assert (ci || error); + callback (self, request, ci, error, user_data); + } if (g_queue_find (priv->dialing.queue, request)) g_queue_remove (priv->dialing.queue, request); @@ -1172,11 +1032,12 @@ on_modem_call_state (ModemCall *ci, ModemCallState state, ModemCallService *self) { - ModemCallServicePrivate *priv = MODEM_CALL_SERVICE (self)->priv; + ModemCallServicePrivate *priv; gboolean releasing = FALSE; - if (priv->disconnected) - return; + RETURN_IF_NOT_VALID (self); + + priv = self->priv; switch (state) { @@ -1254,18 +1115,6 @@ on_modem_call_state (ModemCall *ci, #endif } -static void -on_modem_call_terminated (ModemCall *ci, - ModemCallService *self) -{ - char const *path; - ModemCallServicePrivate *priv = self->priv; - - path = modem_call_get_path (ci); - if (path) - g_hash_table_remove (priv->instances, path); -} - ModemRequest * modem_call_request_conference (ModemCallService *self, ModemCallServiceReply *callback, @@ -1273,7 +1122,7 @@ modem_call_request_conference (ModemCallService *self, { RETURN_NULL_IF_NOT_VALID (self); - return modem_request (MODEM_CALL_SERVICE (self), self->priv->proxy, + return modem_request (MODEM_CALL_SERVICE (self), DBUS_PROXY (self), "CreateMultiparty", modem_call_conference_request_reply, G_CALLBACK (callback), user_data, diff --git a/modem/call.c b/modem/call.c index 75db1dd..14808b9 100644 --- a/modem/call.c +++ b/modem/call.c @@ -40,24 +40,25 @@ #include #include -G_DEFINE_TYPE (ModemCall, modem_call, G_TYPE_OBJECT); +G_DEFINE_TYPE (ModemCall, modem_call, MODEM_TYPE_OFACE); struct _ModemCallPrivate { - char *object_path; ModemCallService *service; - - DBusGProxy *proxy; gpointer handler; - char *remote, *emergency; + gchar *state_str; + gchar *remote; + gchar *emergency; unsigned char state; unsigned char causetype, cause; - unsigned originating:1, terminating:1, onhold:1, member:1; - - unsigned dispose_has_run:1, :0; + unsigned originating:1; + unsigned terminating:1; + unsigned onhold:1; + unsigned member:1; + unsigned :0; }; /* Properties */ @@ -65,7 +66,7 @@ enum { PROP_NONE, PROP_SERVICE, - PROP_OBJECT_PATH, + PROP_OFONO_STATE, PROP_STATE, PROP_CAUSETYPE, PROP_CAUSE, @@ -97,12 +98,9 @@ static guint call_signals[N_SIGNALS]; /* ---------------------------------------------------------------------- */ -extern DBusGProxy *_modem_call_service_proxy (ModemCallService *self); -static void -reply_to_instance_request (DBusGProxy *proxy, - DBusGProxyCall *call, - void *_request); +static void on_notify_ofono_state (ModemCall *, GParamSpec *, gpointer); +static void reply_to_instance_request (DBusGProxy *, DBusGProxyCall *, void *); #if nomore /* Ofono does not provide this information */ static void on_on_hold (DBusGProxy *, gboolean onhold, ModemCall*); @@ -117,14 +115,19 @@ static void on_sending_dtmf (DBusGProxy *proxy, static void on_stopped_dtmf (DBusGProxy *proxy, ModemCall *); #endif -static void reply_to_stop_dtmf (DBusGProxy *proxy, - DBusGProxyCall *call, - void *_request); +static void reply_to_stop_dtmf (DBusGProxy *, DBusGProxyCall *, void *); -static void on_call_property_changed (DBusGProxy *proxy, - char const *property, - GValue const *value, - gpointer user_data); +/* ---------------------------------------------------------------------- */ + +#define RETURN_IF_NOT_VALID(self) \ + g_return_if_fail (self != NULL && \ + modem_oface_is_connected (MODEM_OFACE (self))) + +#define RETURN_VAL_IF_NOT_VALID(self, val) \ + g_return_val_if_fail (self != NULL && \ + modem_oface_is_connected (MODEM_OFACE (self)), (val)) + +#define RETURN_NULL_IF_NOT_VALID(self) RETURN_VAL_IF_NOT_VALID (self, NULL) /* ---------------------------------------------------------------------- */ @@ -138,35 +141,17 @@ modem_call_init (ModemCall *self) static void modem_call_constructed (GObject *object) { - ModemCall *self = MODEM_CALL (object); - ModemCallPrivate *priv = self->priv; - if (G_OBJECT_CLASS (modem_call_parent_class)->constructed) G_OBJECT_CLASS (modem_call_parent_class)->constructed (object); - priv->proxy = modem_ofono_proxy (priv->object_path, OFONO_IFACE_CALL); - - modem_ofono_proxy_connect_to_property_changed (priv->proxy, - on_call_property_changed, self); - DEBUG ("ModemCall for %s on %s", - self->priv->object_path, OFONO_IFACE_CALL); + modem_oface_object_path (MODEM_OFACE (object)), OFONO_IFACE_CALL); } static void modem_call_dispose (GObject *object) { - ModemCall *self = MODEM_CALL (object); - ModemCallPrivate *priv = self->priv; - - if (priv->dispose_has_run) - return; - priv->dispose_has_run = TRUE; - - modem_ofono_proxy_disconnect_from_property_changed (priv->proxy, - on_call_property_changed, self); - - g_object_run_dispose (G_OBJECT (priv->proxy)); + DEBUG ("enter"); if (G_OBJECT_CLASS (modem_call_parent_class)->dispose) G_OBJECT_CLASS (modem_call_parent_class)->dispose (object); @@ -178,10 +163,7 @@ modem_call_finalize (GObject *object) ModemCall *self = MODEM_CALL (object); ModemCallPrivate *priv = self->priv; - g_free (priv->object_path), priv->object_path = NULL; priv->service = NULL; - if (priv->proxy) - g_object_unref (priv->proxy), priv->proxy = NULL; g_free (priv->remote), priv->remote = NULL; g_free (priv->emergency), priv->emergency = NULL; @@ -199,14 +181,14 @@ modem_call_get_property (GObject *object, switch (property_id) { - case PROP_OBJECT_PATH: - g_value_set_string (value, priv->object_path); - break; - case PROP_SERVICE: g_value_set_object (value, priv->service); break; + case PROP_OFONO_STATE: + g_value_set_string (value, priv->state_str); + break; + case PROP_STATE: g_value_set_uint (value, priv->state); break; @@ -261,14 +243,16 @@ modem_call_set_property (GObject *obj, switch (property_id) { - case PROP_OBJECT_PATH: - priv->object_path = g_value_dup_string (value); - break; - case PROP_SERVICE: priv->service = g_value_get_object (value); break; + /* XXX/KV: ugly hack until usage of state is harmonized */ + case PROP_OFONO_STATE: + g_free (priv->state_str); + priv->state_str = g_value_dup_string (value); + break; + case PROP_STATE: priv->state = g_value_get_uint (value); break; @@ -319,10 +303,63 @@ modem_call_set_property (GObject *obj, } } +/* ------------------------------------------------------------------------- */ + +/** Maps properties of org.ofono.VoiceCall to matching ModemCall properties */ +char const * +modem_call_property_mapper (char const *name) +{ + if (!strcmp (name, "LineIdentification")) + return "remote"; + if (!strcmp (name, "Multiparty")) + return "member"; + if (!strcmp (name, "State")) + return "ofono-state"; + if (!strcmp (name, "StartTime")) + return "start-time"; + if (!strcmp (name, "Information")) + return NULL; + if (!strcmp (name, "Icon")) + return NULL; + return NULL; +} + +static void +modem_call_connect (ModemOface *_self) +{ + DEBUG ("(%p): enter", _self); + + /* CallAdded gives us initial properties */ + modem_oface_connect_properties (_self, FALSE); + + g_signal_connect (_self, "notify::ofono-state", + G_CALLBACK(on_notify_ofono_state), _self); +} + +static void +modem_call_connected (ModemOface *_self) +{ + DEBUG ("(%p): enter", _self); + + on_notify_ofono_state (MODEM_CALL (_self), NULL, _self); +} + +static void +modem_call_disconnect (ModemOface *_self) +{ + DEBUG ("(%p): enter", _self); + + g_signal_handlers_disconnect_by_func (_self, + G_CALLBACK(on_notify_ofono_state), _self); + + modem_oface_disconnect_properties (_self); +} + static void modem_call_class_init (ModemCallClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); + ModemOfaceClass *oface_class = MODEM_OFACE_CLASS (klass); g_type_class_add_private (klass, sizeof (ModemCallPrivate)); @@ -332,15 +369,12 @@ modem_call_class_init (ModemCallClass *klass) object_class->get_property = modem_call_get_property; object_class->set_property = modem_call_set_property; - /* Properties */ - g_object_class_install_property (object_class, PROP_OBJECT_PATH, - g_param_spec_string ("object-path", - "Object Path", - "Unique identifier for this object", - "", /* default value */ - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS)); + oface_class->property_mapper = modem_call_property_mapper; + oface_class->connect = modem_call_connect; + oface_class->connected = modem_call_connected; + oface_class->disconnect = modem_call_disconnect; + /* Properties */ g_object_class_install_property (object_class, PROP_SERVICE, g_param_spec_object ("call-service", "Call service", @@ -350,6 +384,14 @@ modem_call_class_init (ModemCallClass *klass) G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS)); + g_object_class_install_property (object_class, PROP_OFONO_STATE, + g_param_spec_string ("ofono-state", + "Call State String", + "State name of the call instance", + NULL, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + g_object_class_install_property (object_class, PROP_STATE, g_param_spec_uint ("state", "Call state", @@ -511,7 +553,9 @@ modem_call_get_name (ModemCall const *self) if (self == NULL) return ""; - char *last = strrchr (self->priv->object_path, '/'); + char const *path = modem_oface_object_path (MODEM_OFACE (self)); + char const *last = strrchr (path, '/'); + if (last) return last + 1; @@ -521,7 +565,7 @@ modem_call_get_name (ModemCall const *self) char const * modem_call_get_path (ModemCall const *self) { - return self->priv->object_path; + return modem_oface_object_path (MODEM_OFACE (self)); } char const * @@ -551,7 +595,9 @@ gboolean modem_call_has_path (ModemCall const *self, char const *object_path) { - return object_path && strcmp (self->priv->object_path, object_path) == 0; + gchar const *my_path = modem_oface_object_path (MODEM_OFACE (self)); + + return object_path && my_path && strcmp (my_path, object_path) == 0; } gboolean @@ -644,38 +690,21 @@ modem_call_state_from_ofono_state (const char *state) } static void -on_call_property_changed (DBusGProxy *proxy, - char const *property, - GValue const *value, - gpointer user_data) +on_notify_ofono_state (ModemCall *self, + GParamSpec *pspec, + gpointer user_data) { - char *s; - ModemCall *self = MODEM_CALL (user_data); - - DEBUG ("enter"); - - s = g_strdup_value_contents (value); - DEBUG ("%s = %s", property, s); - g_free (s); - - if (!strcmp (property, "State")) - { - ModemCallState state; + ModemCallPrivate *priv = self->priv; + ModemCallState state; - state = modem_call_state_from_ofono_state ( - g_value_get_string (value)); + DEBUG ("enter with \"%s\"", priv->state_str); - if (state != self->priv->state) - { - g_object_set (self, "state", state, NULL); - g_signal_emit (self, call_signals[SIGNAL_STATE], 0, state); + state = modem_call_state_from_ofono_state (priv->state_str); + if (state == priv->state) + return; - /* Ofono does not have a separate 'terminated' state, so - * we fake it here for now */ - if (state == MODEM_CALL_STATE_DISCONNECTED) - g_signal_emit (self, call_signals[SIGNAL_TERMINATED], 0); - } - } + g_object_set (self, "state", state, NULL); + g_signal_emit (self, call_signals[SIGNAL_STATE], 0, state); } #if nomore @@ -769,23 +798,24 @@ modem_call_request_answer (ModemCall *self, gpointer user_data) { DEBUG ("enter"); - g_return_val_if_fail (self != NULL, NULL); - g_return_val_if_fail (!MODEM_CALL (self)->priv->dispose_has_run, NULL); + + RETURN_NULL_IF_NOT_VALID (self); if (self->priv->state != MODEM_CALL_STATE_WAITING) { DEBUG ("%s.%s (%s)", OFONO_IFACE_CALL, "Answer", - self ? self->priv->object_path : "NULL"); - return modem_request (MODEM_CALL (self), self->priv->proxy, + 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)", OFONO_IFACE_CALL_MANAGER, "HoldAndAnswer", - self ? self->priv->object_path : "NULL"); + modem_call_get_path (self)); return modem_request (MODEM_CALL (self), - _modem_call_service_proxy (self->priv->service), + modem_oface_dbus_proxy (MODEM_OFACE (self->priv->service)), "HoldAndAnswer", reply_to_instance_request, G_CALLBACK (callback), user_data, G_TYPE_INVALID); @@ -797,11 +827,11 @@ modem_call_request_release (ModemCall *self, ModemCallReply callback, gpointer user_data) { - DEBUG ("%s.%s (%s)", OFONO_IFACE_CALL, "Hangup", - self ? self->priv->object_path : "NULL"); - g_return_val_if_fail (self != NULL, NULL); - g_return_val_if_fail (!MODEM_CALL (self)->priv->dispose_has_run, NULL); - return modem_request (MODEM_CALL (self), self->priv->proxy, + DEBUG ("%s.%s (%s)", OFONO_IFACE_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); @@ -814,14 +844,14 @@ modem_call_request_split (ModemCall *self, gpointer user_data) { DEBUG ("%s.%s (%s)", OFONO_IFACE_CALL_MANAGER, "PrivateChat", - self ? self->priv->object_path : "NULL"); - g_return_val_if_fail (self != NULL, NULL); - g_return_val_if_fail (!MODEM_CALL (self)->priv->dispose_has_run, NULL); + modem_call_get_path (self)); + RETURN_NULL_IF_NOT_VALID (self); + return modem_request (MODEM_CALL (self), - _modem_call_service_proxy (self->priv->service), + modem_oface_dbus_proxy (MODEM_OFACE (self->priv->service)), "PrivateChat", reply_to_instance_request, G_CALLBACK (callback), user_data, - DBUS_TYPE_G_OBJECT_PATH, self->priv->object_path, + DBUS_TYPE_G_OBJECT_PATH, modem_call_get_path (self), G_TYPE_INVALID); } @@ -835,10 +865,10 @@ modem_call_request_hold (ModemCall *self, (void)hold; DEBUG ("%s.%s", OFONO_IFACE_CALL_MANAGER, "SwapCalls"); - g_return_val_if_fail (self != NULL, NULL); - g_return_val_if_fail (!MODEM_CALL (self)->priv->dispose_has_run, NULL); + RETURN_NULL_IF_NOT_VALID (self); + return modem_request (MODEM_CALL (self), - _modem_call_service_proxy (self->priv->service), + modem_oface_dbus_proxy (MODEM_OFACE (self->priv->service)), "SwapCalls", reply_to_instance_request, G_CALLBACK (callback), user_data, G_TYPE_INVALID); @@ -858,20 +888,23 @@ reply_to_instance_request (DBusGProxy *proxy, GError *error = NULL; if (dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_INVALID)) - { - } - else { + ; + else modem_error_fix (&error); - } - if (callback) callback (self, request, error, user_data); + + if (callback) + callback (self, request, error, user_data); + g_clear_error (&error); } gboolean modem_call_can_join (ModemCall const *self) { +#if 0 if (!self || MODEM_IS_CALL_CONFERENCE (self)) return FALSE; +#endif return (self->priv->state == MODEM_CALL_STATE_ACTIVE || self->priv->state == MODEM_CALL_STATE_HELD); @@ -884,11 +917,9 @@ modem_call_send_dtmf (ModemCall *self, char const *dialstring, { int i; char modemstring[256]; - ModemCallPrivate *priv = self->priv; + RETURN_NULL_IF_NOT_VALID (self); g_return_val_if_fail (dialstring != NULL, NULL); - g_return_val_if_fail (!priv->dispose_has_run, NULL); - g_return_val_if_fail (priv->service != NULL, NULL); for (i = 0; dialstring[i]; i++) { @@ -927,7 +958,7 @@ modem_call_send_dtmf (ModemCall *self, char const *dialstring, modemstring[i] = '\0'; return modem_request (self, - _modem_call_service_proxy (self->priv->service), + modem_oface_dbus_proxy (MODEM_OFACE (self->priv->service)), "SendTones", reply_to_instance_request, G_CALLBACK (callback), user_data, G_TYPE_STRING, modemstring, @@ -940,14 +971,12 @@ modem_call_start_dtmf (ModemCall *self, char const tone, ModemCallReply *callback, gpointer user_data) { - char tones[2]; - g_return_val_if_fail (self != NULL, NULL); - g_return_val_if_fail (!MODEM_CALL (self)->priv->dispose_has_run, NULL); + char tones[2] = { tone }; - tones[0] = tone, tones[1] = '\0'; + RETURN_NULL_IF_NOT_VALID (self); return modem_request (MODEM_CALL (self), - _modem_call_service_proxy (self->priv->service), + modem_oface_dbus_proxy (MODEM_OFACE (self->priv->service)), "SendTones", reply_to_instance_request, G_CALLBACK (callback), user_data, G_TYPE_STRING, tones, @@ -959,11 +988,10 @@ modem_call_stop_dtmf (ModemCall *self, ModemCallReply *callback, gpointer user_data) { - g_return_val_if_fail (self != NULL, NULL); - g_return_val_if_fail (!MODEM_CALL (self)->priv->dispose_has_run, NULL); + RETURN_NULL_IF_NOT_VALID (self); return modem_request (MODEM_CALL (self), - _modem_call_service_proxy (self->priv->service), + modem_oface_dbus_proxy (MODEM_OFACE (self->priv->service)), "StopTones", reply_to_stop_dtmf, G_CALLBACK (callback), user_data, G_TYPE_INVALID); @@ -989,16 +1017,19 @@ reply_to_stop_dtmf (DBusGProxy *proxy, { g_free (stopped); } - else { - modem_error_fix (&error); - DEBUG ("got " GERROR_MSG_FMT, GERROR_MSG_CODE (error)); - } + else + { + modem_error_fix (&error); + DEBUG ("got " GERROR_MSG_FMT, GERROR_MSG_CODE (error)); + } if (callback) callback (self, request, error, user_data); + g_clear_error (&error); } +#if 0 /* ---------------------------------------------------------------------- */ /* * ModemCallConference - Interface towards Ofono Multiparty calls @@ -1088,6 +1119,8 @@ modem_call_conference_class_init (ModemCallConferenceClass *klass) MODEM_TYPE_CALL); } +#endif + GError * modem_call_new_error (guint causetype, guint cause, char const *prefixed) { diff --git a/modem/call.h b/modem/call.h index 612c1e6..862d54f 100644 --- a/modem/call.h +++ b/modem/call.h @@ -26,6 +26,7 @@ #include #include +#include G_BEGIN_DECLS @@ -35,12 +36,12 @@ typedef struct _ModemCallServicePrivate ModemCallServicePrivate; struct _ModemCallServiceClass { - GObjectClass parent_class; + ModemOfaceClass parent_class; }; struct _ModemCallService { - GObject parent; + ModemOface parent; ModemCallServicePrivate *priv; }; @@ -62,7 +63,7 @@ GType modem_call_service_get_type (void); (G_TYPE_CHECK_CLASS_TYPE ((klass), MODEM_TYPE_CALL_SERVICE)) #define MODEM_CALL_SERVICE_GET_CLASS(obj) \ (G_TYPE_INSTANCE_GET_CLASS ((obj), \ - MODEM_TYPE_CALL_SERVICE, \ModemCallServiceClass)) + MODEM_TYPE_CALL_SERVICE, ModemCallServiceClass)) typedef struct _ModemCall ModemCall; typedef struct _ModemCallClass ModemCallClass; @@ -73,11 +74,11 @@ typedef enum _ModemCallCauseType ModemCallCauseType; typedef enum _ModemClirOverride ModemClirOverride; struct _ModemCallClass { - GObjectClass parent_class; + ModemOfaceClass parent_class; }; struct _ModemCall { - GObject parent; + ModemOface parent; ModemCallPrivate *priv; }; @@ -169,16 +170,12 @@ enum MODEM_MAX_CALLS = 7 }; +char const *modem_call_service_property_name_by_ofono_name (char const *); + char const *modem_call_get_state_name (int state); GError *modem_call_new_error (guint causetype, guint cause, char const *prefixed); -/* Call service */ -gboolean modem_call_service_connect (ModemCallService *, char const *); -void modem_call_service_disconnect (ModemCallService *); -gboolean modem_call_service_is_connected (ModemCallService const *); -gboolean modem_call_service_is_connecting (ModemCallService const *); - void modem_call_service_resume (ModemCallService *); /* Validate addresses */ @@ -223,10 +220,6 @@ ModemRequest *modem_call_request_conference (ModemCallService *, ModemCallServiceReply *callback, gpointer user_data); -/* ModemCall service */ -void modem_call_connect (ModemCall *); -void modem_call_disconnect (ModemCall *); - char const *modem_call_get_name (ModemCall const *); char const *modem_call_get_path (ModemCall const *); gboolean modem_call_has_path (ModemCall const *, char const *object_path); -- cgit v1.2.3