telephony-ofono: make use of GetCalls method
diff --git a/audio/telephony-ofono.c b/audio/telephony-ofono.c
index b96c504..e1b6422 100644
--- a/audio/telephony-ofono.c
+++ b/audio/telephony-ofono.c
@@ -65,10 +65,11 @@
#define OFONO_VC_INTERFACE "org.ofono.VoiceCall"
static guint registration_watch = 0;
-static guint voice_watch = 0;
static guint device_watch = 0;
static guint modem_added_watch = 0;
static guint modem_removed_watch = 0;
+static guint call_added_watch = 0;
+static guint call_removed_watch = 0;
/* HAL battery namespace key values */
static int battchg_cur = -1; /* "battery.charge_level.current" */
@@ -456,6 +457,219 @@
return type == DBUS_TYPE_INVALID ? TRUE : FALSE;
}
+static void call_free(struct voice_call *vc)
+{
+ DBG("%s", vc->obj_path);
+
+ g_dbus_remove_watch(connection, vc->watch);
+ g_free(vc->obj_path);
+ g_free(vc->number);
+ g_free(vc);
+}
+
+static gboolean handle_vc_property_changed(DBusConnection *conn,
+ DBusMessage *msg, void *data)
+{
+ struct voice_call *vc = data;
+ const char *obj_path = dbus_message_get_path(msg);
+ DBusMessageIter iter, sub;
+ const char *property, *state;
+
+ DBG("path %s", obj_path);
+
+ dbus_message_iter_init(msg, &iter);
+
+ if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING) {
+ error("Unexpected signature in vc PropertyChanged signal");
+ return TRUE;
+ }
+
+ dbus_message_iter_get_basic(&iter, &property);
+ DBG("property %s", property);
+
+ dbus_message_iter_next(&iter);
+ dbus_message_iter_recurse(&iter, &sub);
+ if (g_str_equal(property, "State")) {
+ dbus_message_iter_get_basic(&sub, &state);
+ DBG("State %s", state);
+ if (g_str_equal(state, "disconnected")) {
+ if (vc->status == CALL_STATUS_ACTIVE)
+ telephony_update_indicator(ofono_indicators,
+ "call", EV_CALL_INACTIVE);
+ else
+ telephony_update_indicator(ofono_indicators,
+ "callsetup", EV_CALLSETUP_INACTIVE);
+ if (vc->status == CALL_STATUS_INCOMING)
+ telephony_calling_stopped_ind();
+ calls = g_slist_remove(calls, vc);
+ call_free(vc);
+ } else if (g_str_equal(state, "active")) {
+ telephony_update_indicator(ofono_indicators,
+ "call", EV_CALL_ACTIVE);
+ telephony_update_indicator(ofono_indicators,
+ "callsetup",
+ EV_CALLSETUP_INACTIVE);
+ if (vc->status == CALL_STATUS_INCOMING)
+ telephony_calling_stopped_ind();
+ vc->status = CALL_STATUS_ACTIVE;
+ } else if (g_str_equal(state, "alerting")) {
+ telephony_update_indicator(ofono_indicators,
+ "callsetup", EV_CALLSETUP_ALERTING);
+ vc->status = CALL_STATUS_ALERTING;
+ vc->originating = TRUE;
+ } else if (g_str_equal(state, "incoming")) {
+ /* state change from waiting to incoming */
+ telephony_update_indicator(ofono_indicators,
+ "callsetup", EV_CALLSETUP_INCOMING);
+ telephony_incoming_call_ind(vc->number,
+ NUMBER_TYPE_TELEPHONY);
+ vc->status = CALL_STATUS_INCOMING;
+ vc->originating = FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+static struct voice_call *call_new(const char *path, DBusMessageIter *properties)
+{
+ struct voice_call *vc;
+
+ DBG("%s", path);
+
+ vc = g_new0(struct voice_call, 1);
+ vc->obj_path = g_strdup(path);
+ vc->watch = g_dbus_add_signal_watch(connection, NULL, path,
+ OFONO_VC_INTERFACE, "PropertyChanged",
+ handle_vc_property_changed, vc, NULL);
+
+ while (dbus_message_iter_get_arg_type(properties)
+ == DBUS_TYPE_DICT_ENTRY) {
+ DBusMessageIter entry, value;
+ const char *property, *cli, *state;
+
+ dbus_message_iter_recurse(properties, &entry);
+ dbus_message_iter_get_basic(&entry, &property);
+
+ dbus_message_iter_next(&entry);
+ dbus_message_iter_recurse(&entry, &value);
+
+ if (g_str_equal(property, "LineIdentification")) {
+ dbus_message_iter_get_basic(&value, &cli);
+ DBG("cli %s", cli);
+ vc->number = g_strdup(cli);
+ } else if (g_str_equal(property, "State")) {
+ dbus_message_iter_get_basic(&value, &state);
+ DBG("state %s", state);
+ if (g_str_equal(state, "incoming"))
+ vc->status = CALL_STATUS_INCOMING;
+ else if (g_str_equal(state, "dialing"))
+ vc->status = CALL_STATUS_DIALING;
+ else if (g_str_equal(state, "alerting"))
+ vc->status = CALL_STATUS_ALERTING;
+ else if (g_str_equal(state, "waiting"))
+ vc->status = CALL_STATUS_WAITING;
+ }
+
+ dbus_message_iter_next(properties);
+ }
+
+ switch (vc->status) {
+ case CALL_STATUS_INCOMING:
+ DBG("CALL_STATUS_INCOMING");
+ vc->originating = FALSE;
+ telephony_update_indicator(ofono_indicators, "callsetup",
+ EV_CALLSETUP_INCOMING);
+ telephony_incoming_call_ind(vc->number, NUMBER_TYPE_TELEPHONY);
+ break;
+ case CALL_STATUS_DIALING:
+ DBG("CALL_STATUS_DIALING");
+ vc->originating = TRUE;
+ g_free(last_dialed_number);
+ last_dialed_number = g_strdup(vc->number);
+ telephony_update_indicator(ofono_indicators, "callsetup",
+ EV_CALLSETUP_OUTGOING);
+ break;
+ case CALL_STATUS_ALERTING:
+ DBG("CALL_STATUS_ALERTING");
+ vc->originating = TRUE;
+ g_free(last_dialed_number);
+ last_dialed_number = g_strdup(vc->number);
+ telephony_update_indicator(ofono_indicators, "callsetup",
+ EV_CALLSETUP_ALERTING);
+ break;
+ case CALL_STATUS_WAITING:
+ DBG("CALL_STATUS_WAITING");
+ vc->originating = FALSE;
+ telephony_update_indicator(ofono_indicators, "callsetup",
+ EV_CALLSETUP_INCOMING);
+ telephony_call_waiting_ind(vc->number, NUMBER_TYPE_TELEPHONY);
+ break;
+ }
+
+ return vc;
+}
+
+static void call_added(const char *path, DBusMessageIter *properties)
+{
+ struct voice_call *vc;
+
+ DBG("%s", path);
+
+ vc = find_vc(path);
+ if (vc)
+ return;
+
+ vc = call_new(path, properties);
+ calls = g_slist_prepend(calls, vc);
+}
+
+static void get_calls_reply(DBusPendingCall *call, void *user_data)
+{
+ DBusError err;
+ DBusMessage *reply;
+ DBusMessageIter iter, entry;
+
+ DBG("");
+ reply = dbus_pending_call_steal_reply(call);
+
+ dbus_error_init(&err);
+ if (dbus_set_error_from_message(&err, reply)) {
+ error("ofono replied with an error: %s, %s",
+ err.name, err.message);
+ dbus_error_free(&err);
+ goto done;
+ }
+
+ dbus_message_iter_init(reply, &iter);
+
+ if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY) {
+ error("Unexpected signature");
+ goto done;
+ }
+
+ dbus_message_iter_recurse(&iter, &entry);
+
+ while (dbus_message_iter_get_arg_type(&entry)
+ == DBUS_TYPE_STRUCT) {
+ const char *path;
+ DBusMessageIter value, properties;
+
+ dbus_message_iter_recurse(&entry, &value);
+ dbus_message_iter_get_basic(&value, &path);
+
+ dbus_message_iter_next(&value);
+ dbus_message_iter_recurse(&value, &properties);
+
+ call_added(path, &properties);
+
+ dbus_message_iter_next(&entry);
+ }
+
+done:
+ dbus_message_unref(reply);
+}
+
static void handle_network_property(const char *property, DBusMessageIter *variant)
{
const char *status, *operator;
@@ -554,9 +768,18 @@
dbus_message_iter_recurse(&iter, &properties);
ret = parse_network_properties(&properties);
- if (ret < 0)
+ if (ret < 0) {
error("Unable to parse %s.GetProperty reply",
OFONO_NETWORKREG_INTERFACE);
+ goto done;
+ }
+
+ ret = send_method_call(OFONO_BUS_NAME, modem_obj_path,
+ OFONO_VCMANAGER_INTERFACE, "GetCalls",
+ get_calls_reply, NULL, DBUS_TYPE_INVALID);
+ if (ret < 0)
+ error("Unable to send %s.GetCalls",
+ OFONO_VCMANAGER_INTERFACE);
done:
dbus_message_unref(reply);
@@ -646,255 +869,68 @@
return TRUE;
}
-static void vc_getproperties_reply(DBusPendingCall *call, void *user_data)
+static gboolean handle_vcmanager_call_added(DBusConnection *conn,
+ DBusMessage *msg, void *data)
{
- DBusMessage *reply;
- DBusError err;
- DBusMessageIter iter, iter_entry;
- const char *path = user_data;
- struct voice_call *vc;
+ DBusMessageIter iter, properties;
+ const char *path = dbus_message_get_path(msg);
- DBG("in vc_getproperties_reply");
-
- reply = dbus_pending_call_steal_reply(call);
- dbus_error_init(&err);
- if (dbus_set_error_from_message(&err, reply)) {
- error("ofono replied with an error: %s, %s",
- err.name, err.message);
- dbus_error_free(&err);
- goto done;
- }
-
- vc = find_vc(path);
- if (!vc) {
- error("in vc_getproperties_reply, vc is NULL");
- goto done;
- }
-
- dbus_message_iter_init(reply, &iter);
-
- if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY) {
- error("Unexpected signature in vc_getproperties_reply()");
- goto done;
- }
-
- dbus_message_iter_recurse(&iter, &iter_entry);
-
- if (dbus_message_iter_get_arg_type(&iter_entry)
- != DBUS_TYPE_DICT_ENTRY) {
- error("Unexpected signature in vc_getproperties_reply()");
- goto done;
- }
-
- while (dbus_message_iter_get_arg_type(&iter_entry)
- != DBUS_TYPE_INVALID) {
- DBusMessageIter iter_property, sub;
- char *property, *cli, *state;
-
- dbus_message_iter_recurse(&iter_entry, &iter_property);
- if (dbus_message_iter_get_arg_type(&iter_property)
- != DBUS_TYPE_STRING) {
- error("Unexpected signature in"
- " vc_getproperties_reply()");
- goto done;
- }
-
- dbus_message_iter_get_basic(&iter_property, &property);
-
- dbus_message_iter_next(&iter_property);
- dbus_message_iter_recurse(&iter_property, &sub);
- if (g_str_equal(property, "LineIdentification")) {
- dbus_message_iter_get_basic(&sub, &cli);
- DBG("in vc_getproperties_reply(), cli is %s", cli);
- vc->number = g_strdup(cli);
- } else if (g_str_equal(property, "State")) {
- dbus_message_iter_get_basic(&sub, &state);
- DBG("in vc_getproperties_reply(),"
- " state is %s", state);
- if (g_str_equal(state, "incoming"))
- vc->status = CALL_STATUS_INCOMING;
- else if (g_str_equal(state, "dialing"))
- vc->status = CALL_STATUS_DIALING;
- else if (g_str_equal(state, "alerting"))
- vc->status = CALL_STATUS_ALERTING;
- else if (g_str_equal(state, "waiting"))
- vc->status = CALL_STATUS_WAITING;
- }
-
- dbus_message_iter_next(&iter_entry);
- }
-
- switch (vc->status) {
- case CALL_STATUS_INCOMING:
- printf("in CALL_STATUS_INCOMING: case\n");
- vc->originating = FALSE;
- telephony_update_indicator(ofono_indicators, "callsetup",
- EV_CALLSETUP_INCOMING);
- telephony_incoming_call_ind(vc->number, NUMBER_TYPE_TELEPHONY);
- break;
- case CALL_STATUS_DIALING:
- printf("in CALL_STATUS_DIALING: case\n");
- vc->originating = TRUE;
- g_free(last_dialed_number);
- last_dialed_number = g_strdup(vc->number);
- telephony_update_indicator(ofono_indicators, "callsetup",
- EV_CALLSETUP_OUTGOING);
- break;
- case CALL_STATUS_ALERTING:
- printf("in CALL_STATUS_ALERTING: case\n");
- vc->originating = TRUE;
- g_free(last_dialed_number);
- last_dialed_number = g_strdup(vc->number);
- telephony_update_indicator(ofono_indicators, "callsetup",
- EV_CALLSETUP_ALERTING);
- break;
- case CALL_STATUS_WAITING:
- DBG("in CALL_STATUS_WAITING: case");
- vc->originating = FALSE;
- telephony_update_indicator(ofono_indicators, "callsetup",
- EV_CALLSETUP_INCOMING);
- telephony_call_waiting_ind(vc->number, NUMBER_TYPE_TELEPHONY);
- break;
- }
-done:
- dbus_message_unref(reply);
-}
-
-static void vc_free(struct voice_call *vc)
-{
- if (!vc)
- return;
-
- g_dbus_remove_watch(connection, vc->watch);
- g_free(vc->obj_path);
- g_free(vc->number);
- g_free(vc);
-}
-
-static gboolean handle_vc_property_changed(DBusConnection *conn,
- DBusMessage *msg, void *data)
-{
- struct voice_call *vc = data;
- const char *obj_path = dbus_message_get_path(msg);
- DBusMessageIter iter, sub;
- const char *property, *state;
-
- DBG("in handle_vc_property_changed, obj_path is %s", obj_path);
+ /* Ignore call if modem path doesn't math */
+ if (g_strcmp0(modem_obj_path, path) != 0)
+ return TRUE;
dbus_message_iter_init(msg, &iter);
- if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING) {
- error("Unexpected signature in vc PropertyChanged signal");
+ if (dbus_message_iter_get_arg_type(&iter)
+ != DBUS_TYPE_OBJECT_PATH) {
+ error("Unexpected signature in %s.%s signal",
+ dbus_message_get_interface(msg),
+ dbus_message_get_member(msg));
return TRUE;
}
- dbus_message_iter_get_basic(&iter, &property);
- DBG("in handle_vc_property_changed(), the property is %s", property);
-
+ dbus_message_iter_get_basic(&iter, &path);
dbus_message_iter_next(&iter);
- dbus_message_iter_recurse(&iter, &sub);
- if (g_str_equal(property, "State")) {
- dbus_message_iter_get_basic(&sub, &state);
- DBG("in handle_vc_property_changed(), State is %s", state);
- if (g_str_equal(state, "disconnected")) {
- printf("in disconnected case\n");
- if (vc->status == CALL_STATUS_ACTIVE)
- telephony_update_indicator(ofono_indicators,
- "call", EV_CALL_INACTIVE);
- else
- telephony_update_indicator(ofono_indicators,
- "callsetup", EV_CALLSETUP_INACTIVE);
- if (vc->status == CALL_STATUS_INCOMING)
- telephony_calling_stopped_ind();
- calls = g_slist_remove(calls, vc);
- vc_free(vc);
- } else if (g_str_equal(state, "active")) {
- telephony_update_indicator(ofono_indicators,
- "call", EV_CALL_ACTIVE);
- telephony_update_indicator(ofono_indicators,
- "callsetup",
- EV_CALLSETUP_INACTIVE);
- if (vc->status == CALL_STATUS_INCOMING)
- telephony_calling_stopped_ind();
- vc->status = CALL_STATUS_ACTIVE;
- DBG("vc status is CALL_STATUS_ACTIVE");
- } else if (g_str_equal(state, "alerting")) {
- telephony_update_indicator(ofono_indicators,
- "callsetup", EV_CALLSETUP_ALERTING);
- vc->status = CALL_STATUS_ALERTING;
- DBG("vc status is CALL_STATUS_ALERTING");
- vc->originating = TRUE;
- } else if (g_str_equal(state, "incoming")) {
- /* state change from waiting to incoming */
- telephony_update_indicator(ofono_indicators,
- "callsetup", EV_CALLSETUP_INCOMING);
- telephony_incoming_call_ind(vc->number,
- NUMBER_TYPE_TELEPHONY);
- vc->status = CALL_STATUS_INCOMING;
- DBG("vc status is CALL_STATUS_INCOMING");
- vc->originating = FALSE;
- }
- }
+ dbus_message_iter_recurse(&iter, &properties);
+
+ call_added(path, &properties);
return TRUE;
}
-static gboolean handle_vcmanager_property_changed(DBusConnection *conn,
+static void call_removed(const char *path)
+{
+ struct voice_call *vc;
+
+ DBG("%s", path);
+
+ vc = find_vc(path);
+ if (vc == NULL)
+ return;
+
+ calls = g_slist_remove(calls, vc);
+ call_free(vc);
+}
+
+static gboolean handle_vcmanager_call_removed(DBusConnection *conn,
DBusMessage *msg, void *data)
{
- DBusMessageIter iter, sub, array;
- const char *property, *vc_obj_path = NULL;
- struct voice_call *vc, *vc_new = NULL;
+ const char *path = dbus_message_get_path(msg);
- DBG("in handle_vcmanager_property_changed");
+ /* Ignore call if modem path doesn't math */
+ if (g_strcmp0(modem_obj_path, path) != 0)
+ return TRUE;
- dbus_message_iter_init(msg, &iter);
-
- if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING) {
- error("Unexpected signature in vcmanager"
- " PropertyChanged signal");
+ if (!dbus_message_get_args(msg, NULL,
+ DBUS_TYPE_OBJECT_PATH, &path,
+ DBUS_TYPE_INVALID)) {
+ error("Unexpected signature in %s.%s signal",
+ dbus_message_get_interface(msg),
+ dbus_message_get_member(msg));
return TRUE;
}
- dbus_message_iter_get_basic(&iter, &property);
- DBG("in handle_vcmanager_property_changed(),"
- " the property is %s", property);
-
- dbus_message_iter_next(&iter);
- dbus_message_iter_recurse(&iter, &sub);
- if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_ARRAY) {
- error("Unexpected signature in vcmanager"
- " PropertyChanged signal");
- return TRUE;
- }
- dbus_message_iter_recurse(&sub, &array);
- while (dbus_message_iter_get_arg_type(&array) != DBUS_TYPE_INVALID) {
- dbus_message_iter_get_basic(&array, &vc_obj_path);
- vc = find_vc(vc_obj_path);
- if (vc) {
- DBG("in handle_vcmanager_property_changed,"
- " found an existing vc");
- } else {
- vc_new = g_new0(struct voice_call, 1);
- vc_new->obj_path = g_strdup(vc_obj_path);
- calls = g_slist_append(calls, vc_new);
- vc_new->watch = g_dbus_add_signal_watch(connection,
- NULL, vc_obj_path,
- OFONO_VC_INTERFACE,
- "PropertyChanged",
- handle_vc_property_changed,
- vc_new, NULL);
- }
- dbus_message_iter_next(&array);
- }
-
- if (!vc_new)
- return TRUE;
-
- send_method_call(OFONO_BUS_NAME, vc_new->obj_path,
- OFONO_VC_INTERFACE,
- "GetProperties", vc_getproperties_reply,
- vc_new->obj_path, DBUS_TYPE_INVALID);
+ call_removed(path);
return TRUE;
}
@@ -933,7 +969,7 @@
DBG("%s", path);
- g_slist_foreach(calls, (GFunc) vc_free, NULL);
+ g_slist_foreach(calls, (GFunc) call_free, NULL);
g_slist_free(calls);
calls = NULL;
@@ -1151,13 +1187,6 @@
handle_network_property_changed,
NULL, NULL);
- voice_watch = g_dbus_add_signal_watch(connection,
- OFONO_BUS_NAME, NULL,
- OFONO_VCMANAGER_INTERFACE,
- "PropertyChanged",
- handle_vcmanager_property_changed,
- NULL, NULL);
-
modem_added_watch = g_dbus_add_signal_watch(connection,
OFONO_BUS_NAME, NULL,
OFONO_MANAGER_INTERFACE,
@@ -1171,6 +1200,19 @@
"ModemRemoved",
handle_manager_modem_removed,
NULL, NULL);
+ call_added_watch = g_dbus_add_signal_watch(connection,
+ OFONO_BUS_NAME, NULL,
+ OFONO_VCMANAGER_INTERFACE,
+ "CallAdded",
+ handle_vcmanager_call_added,
+ NULL, NULL);
+
+ call_removed_watch = g_dbus_add_signal_watch(connection,
+ OFONO_BUS_NAME, NULL,
+ OFONO_VCMANAGER_INTERFACE,
+ "CallRemoved",
+ handle_vcmanager_call_removed,
+ NULL, NULL);
ret = send_method_call(OFONO_BUS_NAME, OFONO_PATH,
OFONO_MANAGER_INTERFACE, "GetModems",
@@ -1204,9 +1246,10 @@
modem_removed(modem_obj_path);
g_dbus_remove_watch(connection, registration_watch);
- g_dbus_remove_watch(connection, voice_watch);
g_dbus_remove_watch(connection, modem_added_watch);
g_dbus_remove_watch(connection, modem_removed_watch);
+ g_dbus_remove_watch(connection, call_added_watch);
+ g_dbus_remove_watch(connection, call_removed_watch);
g_dbus_remove_watch(connection, device_watch);
dbus_connection_unref(connection);