* [PATCH 01/10] telephony-ofono: notify alerting calls when headset connects
2011-01-05 15:59 [PATCH 00/10] Update telephony-ofono driver Luiz Augusto von Dentz
@ 2011-01-05 15:59 ` Luiz Augusto von Dentz
2011-01-05 15:59 ` [PATCH 02/10] telephony-ofono: fix not being able to answer alerting/waiting calls Luiz Augusto von Dentz
` (9 subsequent siblings)
10 siblings, 0 replies; 12+ messages in thread
From: Luiz Augusto von Dentz @ 2011-01-05 15:59 UTC (permalink / raw)
To: linux-bluetooth
From: Luiz Augusto von Dentz <luiz.dentz-von@nokia.com>
---
audio/telephony-ofono.c | 23 +++++++++++++++++++++++
1 files changed, 23 insertions(+), 0 deletions(-)
diff --git a/audio/telephony-ofono.c b/audio/telephony-ofono.c
index 00c3f6e..babf38f 100644
--- a/audio/telephony-ofono.c
+++ b/audio/telephony-ofono.c
@@ -128,9 +128,32 @@ static struct voice_call *find_vc_with_status(int status)
return NULL;
}
+static int number_type(const char *number)
+{
+ if (number == NULL)
+ return NUMBER_TYPE_TELEPHONY;
+
+ if (number[0] == '+' || strncmp(number, "00", 2) == 0)
+ return NUMBER_TYPE_INTERNATIONAL;
+
+ return NUMBER_TYPE_TELEPHONY;
+}
+
void telephony_device_connected(void *telephony_device)
{
+ struct voice_call *coming;
+
DBG("telephony-ofono: device %p connected", telephony_device);
+
+ coming = find_vc_with_status(CALL_STATUS_ALERTING);
+ if (coming) {
+ if (find_vc_with_status(CALL_STATUS_ACTIVE))
+ telephony_call_waiting_ind(coming->number,
+ number_type(coming->number));
+ else
+ telephony_incoming_call_ind(coming->number,
+ number_type(coming->number));
+ }
}
void telephony_device_disconnected(void *telephony_device)
--
1.7.1
^ permalink raw reply related [flat|nested] 12+ messages in thread* [PATCH 02/10] telephony-ofono: fix not being able to answer alerting/waiting calls
2011-01-05 15:59 [PATCH 00/10] Update telephony-ofono driver Luiz Augusto von Dentz
2011-01-05 15:59 ` [PATCH 01/10] telephony-ofono: notify alerting calls when headset connects Luiz Augusto von Dentz
@ 2011-01-05 15:59 ` Luiz Augusto von Dentz
2011-01-05 15:59 ` [PATCH 03/10] telephony-ofono: fix not setting originating when status property changes Luiz Augusto von Dentz
` (8 subsequent siblings)
10 siblings, 0 replies; 12+ messages in thread
From: Luiz Augusto von Dentz @ 2011-01-05 15:59 UTC (permalink / raw)
To: linux-bluetooth
From: Luiz Augusto von Dentz <luiz.dentz-von@nokia.com>
---
audio/telephony-ofono.c | 9 ++++++++-
1 files changed, 8 insertions(+), 1 deletions(-)
diff --git a/audio/telephony-ofono.c b/audio/telephony-ofono.c
index babf38f..4f69673 100644
--- a/audio/telephony-ofono.c
+++ b/audio/telephony-ofono.c
@@ -263,9 +263,16 @@ void telephony_terminate_call_req(void *telephony_device)
void telephony_answer_call_req(void *telephony_device)
{
- struct voice_call *vc = find_vc_with_status(CALL_STATUS_INCOMING);
+ struct voice_call *vc;
int ret;
+ vc = find_vc_with_status(CALL_STATUS_INCOMING);
+ if (!vc)
+ vc = find_vc_with_status(CALL_STATUS_ALERTING);
+
+ if (!vc)
+ vc = find_vc_with_status(CALL_STATUS_WAITING);
+
if (!vc) {
telephony_answer_call_rsp(telephony_device,
CME_ERROR_NOT_ALLOWED);
--
1.7.1
^ permalink raw reply related [flat|nested] 12+ messages in thread* [PATCH 03/10] telephony-ofono: fix not setting originating when status property changes
2011-01-05 15:59 [PATCH 00/10] Update telephony-ofono driver Luiz Augusto von Dentz
2011-01-05 15:59 ` [PATCH 01/10] telephony-ofono: notify alerting calls when headset connects Luiz Augusto von Dentz
2011-01-05 15:59 ` [PATCH 02/10] telephony-ofono: fix not being able to answer alerting/waiting calls Luiz Augusto von Dentz
@ 2011-01-05 15:59 ` Luiz Augusto von Dentz
2011-01-05 15:59 ` [PATCH 04/10] telephony-ofono: make use of GetModems method Luiz Augusto von Dentz
` (7 subsequent siblings)
10 siblings, 0 replies; 12+ messages in thread
From: Luiz Augusto von Dentz @ 2011-01-05 15:59 UTC (permalink / raw)
To: linux-bluetooth
From: Luiz Augusto von Dentz <luiz.dentz-von@nokia.com>
---
audio/telephony-ofono.c | 2 ++
1 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/audio/telephony-ofono.c b/audio/telephony-ofono.c
index 4f69673..720b32d 100644
--- a/audio/telephony-ofono.c
+++ b/audio/telephony-ofono.c
@@ -834,6 +834,7 @@ static gboolean handle_vc_property_changed(DBusConnection *conn,
"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,
@@ -842,6 +843,7 @@ static gboolean handle_vc_property_changed(DBusConnection *conn,
NUMBER_TYPE_TELEPHONY);
vc->status = CALL_STATUS_INCOMING;
DBG("vc status is CALL_STATUS_INCOMING");
+ vc->originating = FALSE;
}
}
--
1.7.1
^ permalink raw reply related [flat|nested] 12+ messages in thread* [PATCH 04/10] telephony-ofono: make use of GetModems method
2011-01-05 15:59 [PATCH 00/10] Update telephony-ofono driver Luiz Augusto von Dentz
` (2 preceding siblings ...)
2011-01-05 15:59 ` [PATCH 03/10] telephony-ofono: fix not setting originating when status property changes Luiz Augusto von Dentz
@ 2011-01-05 15:59 ` Luiz Augusto von Dentz
2011-01-05 15:59 ` [PATCH 05/10] telephony-ofono: make use of GetCalls method Luiz Augusto von Dentz
` (6 subsequent siblings)
10 siblings, 0 replies; 12+ messages in thread
From: Luiz Augusto von Dentz @ 2011-01-05 15:59 UTC (permalink / raw)
To: linux-bluetooth
From: Luiz Augusto von Dentz <luiz.dentz-von@nokia.com>
Ofono API has changed, modem list is no longer a property
---
audio/telephony-ofono.c | 271 +++++++++++++++++++++++++++++-----------------
1 files changed, 171 insertions(+), 100 deletions(-)
diff --git a/audio/telephony-ofono.c b/audio/telephony-ofono.c
index 720b32d..b96c504 100644
--- a/audio/telephony-ofono.c
+++ b/audio/telephony-ofono.c
@@ -67,6 +67,8 @@ static GSList *calls = NULL;
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;
/* HAL battery namespace key values */
static int battchg_cur = -1; /* "battery.charge_level.current" */
@@ -454,13 +456,13 @@ static gboolean iter_get_basic_args(DBusMessageIter *iter,
return type == DBUS_TYPE_INVALID ? TRUE : FALSE;
}
-static void handle_registration_property(const char *property, DBusMessageIter sub)
+static void handle_network_property(const char *property, DBusMessageIter *variant)
{
const char *status, *operator;
unsigned int signals_bar;
if (g_str_equal(property, "Status")) {
- dbus_message_iter_get_basic(&sub, &status);
+ dbus_message_iter_get_basic(variant, &status);
DBG("Status is %s", status);
if (g_str_equal(status, "registered")) {
net.status = NETWORK_REG_STATUS_HOME;
@@ -481,13 +483,13 @@ static void handle_registration_property(const char *property, DBusMessageIter s
telephony_update_indicator(ofono_indicators,
"service", EV_SERVICE_NONE);
}
- } else if (g_str_equal(property, "Operator")) {
- dbus_message_iter_get_basic(&sub, &operator);
+ } else if (g_str_equal(property, "Name")) {
+ dbus_message_iter_get_basic(variant, &operator);
DBG("Operator is %s", operator);
g_free(net.operator_name);
net.operator_name = g_strdup(operator);
} else if (g_str_equal(property, "SignalStrength")) {
- dbus_message_iter_get_basic(&sub, &signals_bar);
+ dbus_message_iter_get_basic(variant, &signals_bar);
DBG("SignalStrength is %d", signals_bar);
net.signals_bar = signals_bar;
telephony_update_indicator(ofono_indicators, "signal",
@@ -495,16 +497,43 @@ static void handle_registration_property(const char *property, DBusMessageIter s
}
}
-static void get_registration_reply(DBusPendingCall *call, void *user_data)
+static int parse_network_properties(DBusMessageIter *properties)
{
- DBusError err;
- DBusMessage *reply;
- DBusMessageIter iter, iter_entry;
uint32_t features = AG_FEATURE_EC_ANDOR_NR |
AG_FEATURE_REJECT_A_CALL |
AG_FEATURE_ENHANCED_CALL_STATUS |
AG_FEATURE_EXTENDED_ERROR_RESULT_CODES;
+ while (dbus_message_iter_get_arg_type(properties)
+ == DBUS_TYPE_DICT_ENTRY) {
+ const char *key;
+ DBusMessageIter value, entry;
+
+ dbus_message_iter_recurse(properties, &entry);
+ dbus_message_iter_get_basic(&entry, &key);
+
+ dbus_message_iter_next(&entry);
+ dbus_message_iter_recurse(&entry, &value);
+
+ handle_network_property(key, &value);
+
+ dbus_message_iter_next(properties);
+ }
+
+ telephony_ready_ind(features, ofono_indicators, BTRH_NOT_SUPPORTED,
+ chld_str);
+
+ return 0;
+}
+
+static void get_properties_reply(DBusPendingCall *call, void *user_data)
+{
+ DBusError err;
+ DBusMessage *reply;
+ DBusMessageIter iter, properties;
+ int ret = 0;
+
+ DBG("");
reply = dbus_pending_call_steal_reply(call);
dbus_error_init(&err);
@@ -517,67 +546,47 @@ static void get_registration_reply(DBusPendingCall *call, void *user_data)
dbus_message_iter_init(reply, &iter);
- /* ARRAY -> ENTRY -> VARIANT */
if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY) {
- error("Unexpected signature in GetProperties return");
- 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 GetProperties return");
+ error("Unexpected signature");
goto done;
}
- while (dbus_message_iter_get_arg_type(&iter_entry)
- != DBUS_TYPE_INVALID) {
- DBusMessageIter iter_property, sub;
- char *property;
+ dbus_message_iter_recurse(&iter, &properties);
- dbus_message_iter_recurse(&iter_entry, &iter_property);
- if (dbus_message_iter_get_arg_type(&iter_property)
- != DBUS_TYPE_STRING) {
- error("Unexpected signature in GetProperties return");
- goto done;
- }
-
- dbus_message_iter_get_basic(&iter_property, &property);
-
- dbus_message_iter_next(&iter_property);
- dbus_message_iter_recurse(&iter_property, &sub);
-
- handle_registration_property(property, sub);
-
- dbus_message_iter_next(&iter_entry);
- }
-
- telephony_ready_ind(features, ofono_indicators, BTRH_NOT_SUPPORTED,
- chld_str);
+ ret = parse_network_properties(&properties);
+ if (ret < 0)
+ error("Unable to parse %s.GetProperty reply",
+ OFONO_NETWORKREG_INTERFACE);
done:
dbus_message_unref(reply);
}
-static int get_registration_and_signal_status()
+static void modem_added(const char *path)
{
- if (!modem_obj_path)
- return -ENOENT;
+ int ret;
- return send_method_call(OFONO_BUS_NAME, modem_obj_path,
- OFONO_NETWORKREG_INTERFACE,
- "GetProperties", get_registration_reply,
- NULL, DBUS_TYPE_INVALID);
+ DBG("%s", path);
+
+ if (modem_obj_path != NULL)
+ return;
+
+ modem_obj_path = g_strdup(path);
+
+ ret = send_method_call(OFONO_BUS_NAME, path,
+ OFONO_NETWORKREG_INTERFACE, "GetProperties",
+ get_properties_reply, NULL, DBUS_TYPE_INVALID);
+ if (ret < 0)
+ error("Unable to send %s.GetProperties",
+ OFONO_NETWORKREG_INTERFACE);
}
-static void list_modem_reply(DBusPendingCall *call, void *user_data)
+static void get_modems_reply(DBusPendingCall *call, void *user_data)
{
DBusError err;
DBusMessage *reply;
- DBusMessageIter iter, iter_entry, iter_property, iter_arrary, sub;
- char *property, *modem_obj_path_local;
- int ret;
+ DBusMessageIter iter, entry;
+ const char *path;
DBG("list_modem_reply is called\n");
reply = dbus_pending_call_steal_reply(call);
@@ -593,49 +602,29 @@ static void list_modem_reply(DBusPendingCall *call, void *user_data)
dbus_message_iter_init(reply, &iter);
if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY) {
- error("Unexpected signature in ListModems return");
+ error("Unexpected signature");
goto done;
}
- dbus_message_iter_recurse(&iter, &iter_entry);
+ dbus_message_iter_recurse(&iter, &entry);
- if (dbus_message_iter_get_arg_type(&iter_entry)
- != DBUS_TYPE_DICT_ENTRY) {
- error("Unexpected signature in ListModems return 2, %c",
- dbus_message_iter_get_arg_type(&iter_entry));
+ if (dbus_message_iter_get_arg_type(&entry) != DBUS_TYPE_OBJECT_PATH) {
+ error("Unexpected signature");
goto done;
}
- dbus_message_iter_recurse(&iter_entry, &iter_property);
-
- dbus_message_iter_get_basic(&iter_property, &property);
-
- dbus_message_iter_next(&iter_property);
- dbus_message_iter_recurse(&iter_property, &iter_arrary);
- dbus_message_iter_recurse(&iter_arrary, &sub);
- while (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID) {
+ dbus_message_iter_get_basic(&entry, &path);
- dbus_message_iter_get_basic(&sub, &modem_obj_path_local);
- modem_obj_path = g_strdup(modem_obj_path_local);
- if (modem_obj_path != NULL) {
- DBG("modem_obj_path is %p, %s\n", modem_obj_path,
- modem_obj_path);
- break;
- }
- dbus_message_iter_next(&sub);
- }
+ modem_added(path);
- ret = get_registration_and_signal_status();
- if (ret < 0)
- error("get_registration_and_signal_status() failed(%d)", ret);
done:
dbus_message_unref(reply);
}
-static gboolean handle_registration_property_changed(DBusConnection *conn,
+static gboolean handle_network_property_changed(DBusConnection *conn,
DBusMessage *msg, void *data)
{
- DBusMessageIter iter, sub;
+ DBusMessageIter iter, variant;
const char *property;
dbus_message_iter_init(msg, &iter);
@@ -650,9 +639,9 @@ static gboolean handle_registration_property_changed(DBusConnection *conn,
" the property is %s", property);
dbus_message_iter_next(&iter);
- dbus_message_iter_recurse(&iter, &sub);
+ dbus_message_iter_recurse(&iter, &variant);
- handle_registration_property(property, sub);
+ handle_network_property(property, &variant);
return TRUE;
}
@@ -910,6 +899,70 @@ static gboolean handle_vcmanager_property_changed(DBusConnection *conn,
return TRUE;
}
+static gboolean handle_manager_modem_added(DBusConnection *conn,
+ DBusMessage *msg, void *data)
+{
+ DBusMessageIter iter, properties;
+ const char *path;
+
+ if (modem_obj_path != NULL)
+ return TRUE;
+
+ dbus_message_iter_init(msg, &iter);
+
+ 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, &path);
+ dbus_message_iter_recurse(&iter, &properties);
+
+ modem_added(path);
+
+ return TRUE;
+}
+
+static void modem_removed(const char *path)
+{
+ if (g_strcmp0(modem_obj_path, path) != 0)
+ return;
+
+ DBG("%s", path);
+
+ g_slist_foreach(calls, (GFunc) vc_free, NULL);
+ g_slist_free(calls);
+ calls = NULL;
+
+ g_free(net.operator_name);
+ net.operator_name = NULL;
+
+ g_free(modem_obj_path);
+ modem_obj_path = NULL;
+}
+
+static gboolean handle_manager_modem_removed(DBusConnection *conn,
+ DBusMessage *msg, void *data)
+{
+ const char *path;
+
+ 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;
+ }
+
+ modem_removed(path);
+
+ return TRUE;
+}
+
static void hal_battery_level_reply(DBusPendingCall *call, void *user_data)
{
DBusMessage *reply;
@@ -1090,21 +1143,38 @@ int telephony_init(void)
connection = dbus_bus_get(DBUS_BUS_SYSTEM, NULL);
- registration_watch = g_dbus_add_signal_watch(connection, OFONO_BUS_NAME,
- NULL, OFONO_NETWORKREG_INTERFACE,
- "PropertyChanged",
- handle_registration_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);
+ registration_watch = g_dbus_add_signal_watch(connection,
+ OFONO_BUS_NAME, NULL,
+ OFONO_NETWORKREG_INTERFACE,
+ "PropertyChanged",
+ 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,
+ "ModemAdded",
+ handle_manager_modem_added,
+ NULL, NULL);
+
+ modem_removed_watch = g_dbus_add_signal_watch(connection,
+ OFONO_BUS_NAME, NULL,
+ OFONO_MANAGER_INTERFACE,
+ "ModemRemoved",
+ handle_manager_modem_removed,
+ NULL, NULL);
ret = send_method_call(OFONO_BUS_NAME, OFONO_PATH,
- OFONO_MANAGER_INTERFACE, "GetProperties",
- list_modem_reply, NULL, DBUS_TYPE_INVALID);
+ OFONO_MANAGER_INTERFACE, "GetModems",
+ get_modems_reply, NULL, DBUS_TYPE_INVALID);
if (ret < 0)
return ret;
@@ -1125,17 +1195,18 @@ int telephony_init(void)
void telephony_exit(void)
{
- g_free(net.operator_name);
+ DBG("");
- g_free(modem_obj_path);
g_free(last_dialed_number);
+ last_dialed_number = NULL;
- g_slist_foreach(calls, (GFunc) vc_free, NULL);
- g_slist_free(calls);
- calls = NULL;
+ if (modem_obj_path)
+ 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, device_watch);
dbus_connection_unref(connection);
--
1.7.1
^ permalink raw reply related [flat|nested] 12+ messages in thread* [PATCH 05/10] telephony-ofono: make use of GetCalls method
2011-01-05 15:59 [PATCH 00/10] Update telephony-ofono driver Luiz Augusto von Dentz
` (3 preceding siblings ...)
2011-01-05 15:59 ` [PATCH 04/10] telephony-ofono: make use of GetModems method Luiz Augusto von Dentz
@ 2011-01-05 15:59 ` Luiz Augusto von Dentz
2011-01-05 15:59 ` [PATCH 06/10] telephony-ofono: fix not canceling pending calls on exit Luiz Augusto von Dentz
` (5 subsequent siblings)
10 siblings, 0 replies; 12+ messages in thread
From: Luiz Augusto von Dentz @ 2011-01-05 15:59 UTC (permalink / raw)
To: linux-bluetooth
From: Luiz Augusto von Dentz <luiz.dentz-von@nokia.com>
---
audio/telephony-ofono.c | 515 +++++++++++++++++++++++++----------------------
1 files changed, 279 insertions(+), 236 deletions(-)
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 @@ static GSList *calls = NULL;
#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 @@ static gboolean iter_get_basic_args(DBusMessageIter *iter,
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 @@ static void get_properties_reply(DBusPendingCall *call, void *user_data)
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 @@ static gboolean handle_network_property_changed(DBusConnection *conn,
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;
-
- 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;
- }
+ DBusMessageIter iter, properties;
+ const char *path = dbus_message_get_path(msg);
- dbus_message_iter_get_basic(&iter_property, &property);
+ /* Ignore call if modem path doesn't math */
+ if (g_strcmp0(modem_obj_path, path) != 0)
+ return TRUE;
- 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_init(msg, &iter);
- dbus_message_iter_next(&iter_entry);
+ 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;
}
- 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);
-}
+ dbus_message_iter_get_basic(&iter, &path);
+ dbus_message_iter_next(&iter);
+ dbus_message_iter_recurse(&iter, &properties);
-static void vc_free(struct voice_call *vc)
-{
- if (!vc)
- return;
+ call_added(path, &properties);
- g_dbus_remove_watch(connection, vc->watch);
- g_free(vc->obj_path);
- g_free(vc->number);
- g_free(vc);
+ return TRUE;
}
-static gboolean handle_vc_property_changed(DBusConnection *conn,
- DBusMessage *msg, void *data)
+static void call_removed(const char *path)
{
- 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);
-
- 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;
- }
+ struct voice_call *vc;
- dbus_message_iter_get_basic(&iter, &property);
- DBG("in handle_vc_property_changed(), the property is %s", property);
+ DBG("%s", 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;
- }
- }
+ vc = find_vc(path);
+ if (vc == NULL)
+ return;
- return TRUE;
+ calls = g_slist_remove(calls, vc);
+ call_free(vc);
}
-static gboolean handle_vcmanager_property_changed(DBusConnection *conn,
+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;
-
- DBG("in handle_vcmanager_property_changed");
+ const char *path = dbus_message_get_path(msg);
- dbus_message_iter_init(msg, &iter);
-
- if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING) {
- error("Unexpected signature in vcmanager"
- " PropertyChanged signal");
+ /* Ignore call if modem path doesn't math */
+ if (g_strcmp0(modem_obj_path, path) != 0)
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");
+ 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_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 @@ static void modem_removed(const char *path)
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 @@ int telephony_init(void)
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 @@ int telephony_init(void)
"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 @@ void telephony_exit(void)
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);
--
1.7.1
^ permalink raw reply related [flat|nested] 12+ messages in thread* [PATCH 06/10] telephony-ofono: fix not canceling pending calls on exit
2011-01-05 15:59 [PATCH 00/10] Update telephony-ofono driver Luiz Augusto von Dentz
` (4 preceding siblings ...)
2011-01-05 15:59 ` [PATCH 05/10] telephony-ofono: make use of GetCalls method Luiz Augusto von Dentz
@ 2011-01-05 15:59 ` Luiz Augusto von Dentz
2011-01-05 15:59 ` [PATCH 07/10] telephony-ofono: simplify watches handling logic Luiz Augusto von Dentz
` (4 subsequent siblings)
10 siblings, 0 replies; 12+ messages in thread
From: Luiz Augusto von Dentz @ 2011-01-05 15:59 UTC (permalink / raw)
To: linux-bluetooth
From: Luiz Augusto von Dentz <luiz.dentz-von@nokia.com>
---
audio/telephony-ofono.c | 19 ++++++++++++++++++-
1 files changed, 18 insertions(+), 1 deletions(-)
diff --git a/audio/telephony-ofono.c b/audio/telephony-ofono.c
index e1b6422..c554305 100644
--- a/audio/telephony-ofono.c
+++ b/audio/telephony-ofono.c
@@ -56,6 +56,7 @@ static DBusConnection *connection = NULL;
static char *modem_obj_path = NULL;
static char *last_dialed_number = NULL;
static GSList *calls = NULL;
+static GSList *pending = NULL;
#define OFONO_BUS_NAME "org.ofono"
#define OFONO_PATH "/"
@@ -226,7 +227,7 @@ static int send_method_call(const char *dest, const char *path,
}
dbus_pending_call_set_notify(call, cb, user_data, NULL);
- dbus_pending_call_unref(call);
+ pending = g_slist_prepend(pending, call);
dbus_message_unref(msg);
return 0;
@@ -610,6 +611,12 @@ static struct voice_call *call_new(const char *path, DBusMessageIter *properties
return vc;
}
+static void remove_pending(DBusPendingCall *call)
+{
+ pending = g_slist_remove(pending, call);
+ dbus_pending_call_unref(call);
+}
+
static void call_added(const char *path, DBusMessageIter *properties)
{
struct voice_call *vc;
@@ -668,6 +675,7 @@ static void get_calls_reply(DBusPendingCall *call, void *user_data)
done:
dbus_message_unref(reply);
+ remove_pending(call);
}
static void handle_network_property(const char *property, DBusMessageIter *variant)
@@ -783,6 +791,7 @@ static void get_properties_reply(DBusPendingCall *call, void *user_data)
done:
dbus_message_unref(reply);
+ remove_pending(call);
}
static void modem_added(const char *path)
@@ -842,6 +851,7 @@ static void get_modems_reply(DBusPendingCall *call, void *user_data)
done:
dbus_message_unref(reply);
+ remove_pending(call);
}
static gboolean handle_network_property_changed(DBusConnection *conn,
@@ -1052,6 +1062,7 @@ static void hal_battery_level_reply(DBusPendingCall *call, void *user_data)
}
done:
dbus_message_unref(reply);
+ remove_pending(call);
}
static void hal_get_integer(const char *path, const char *key, void *user_data)
@@ -1170,6 +1181,7 @@ static void hal_find_device_reply(DBusPendingCall *call, void *user_data)
hal_get_integer(path, "battery.charge_level.design", &battchg_design);
done:
dbus_message_unref(reply);
+ remove_pending(call);
}
int telephony_init(void)
@@ -1252,6 +1264,11 @@ void telephony_exit(void)
g_dbus_remove_watch(connection, call_removed_watch);
g_dbus_remove_watch(connection, device_watch);
+ g_slist_foreach(pending, (GFunc) dbus_pending_call_cancel, NULL);
+ g_slist_foreach(pending, (GFunc) dbus_pending_call_unref, NULL);
+ g_slist_free(pending);
+ pending = NULL;
+
dbus_connection_unref(connection);
connection = NULL;
--
1.7.1
^ permalink raw reply related [flat|nested] 12+ messages in thread* [PATCH 07/10] telephony-ofono: simplify watches handling logic
2011-01-05 15:59 [PATCH 00/10] Update telephony-ofono driver Luiz Augusto von Dentz
` (5 preceding siblings ...)
2011-01-05 15:59 ` [PATCH 06/10] telephony-ofono: fix not canceling pending calls on exit Luiz Augusto von Dentz
@ 2011-01-05 15:59 ` Luiz Augusto von Dentz
2011-01-05 15:59 ` [PATCH 08/10] telephony-ofono: handle ofono appearing/disappearing from bus Luiz Augusto von Dentz
` (3 subsequent siblings)
10 siblings, 0 replies; 12+ messages in thread
From: Luiz Augusto von Dentz @ 2011-01-05 15:59 UTC (permalink / raw)
To: linux-bluetooth
From: Luiz Augusto von Dentz <luiz.dentz-von@nokia.com>
---
audio/telephony-ofono.c | 85 ++++++++++++++++++----------------------------
1 files changed, 33 insertions(+), 52 deletions(-)
diff --git a/audio/telephony-ofono.c b/audio/telephony-ofono.c
index c554305..00b24f9 100644
--- a/audio/telephony-ofono.c
+++ b/audio/telephony-ofono.c
@@ -56,6 +56,7 @@ static DBusConnection *connection = NULL;
static char *modem_obj_path = NULL;
static char *last_dialed_number = NULL;
static GSList *calls = NULL;
+static GSList *watches = NULL;
static GSList *pending = NULL;
#define OFONO_BUS_NAME "org.ofono"
@@ -65,13 +66,6 @@ static GSList *pending = NULL;
#define OFONO_VCMANAGER_INTERFACE "org.ofono.VoiceCallManager"
#define OFONO_VC_INTERFACE "org.ofono.VoiceCall"
-static guint registration_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" */
static int battchg_last = -1; /* "battery.charge_level.last_full" */
@@ -1130,6 +1124,18 @@ static gboolean handle_hal_property_modified(DBusConnection *conn,
return TRUE;
}
+static void add_watch(const char *sender, const char *path,
+ const char *interface, const char *member,
+ GDBusSignalFunction function)
+{
+ guint watch;
+
+ watch = g_dbus_add_signal_watch(connection, sender, path, interface,
+ member, function, NULL, NULL);
+
+ watches = g_slist_prepend(watches, GUINT_TO_POINTER(watch));
+}
+
static void hal_find_device_reply(DBusPendingCall *call, void *user_data)
{
DBusMessage *reply;
@@ -1170,11 +1176,8 @@ static void hal_find_device_reply(DBusPendingCall *call, void *user_data)
DBG("telephony-ofono: found battery device at %s", path);
- device_watch = g_dbus_add_signal_watch(connection, NULL, path,
- "org.freedesktop.Hal.Device",
- "PropertyModified",
- handle_hal_property_modified,
- NULL, NULL);
+ add_watch(NULL, path, "org.freedesktop.Hal.Device",
+ "PropertyModified", handle_hal_property_modified);
hal_get_integer(path, "battery.charge_level.last_full", &battchg_last);
hal_get_integer(path, "battery.charge_level.current", &battchg_cur);
@@ -1191,40 +1194,16 @@ int telephony_init(void)
connection = dbus_bus_get(DBUS_BUS_SYSTEM, NULL);
-
- registration_watch = g_dbus_add_signal_watch(connection,
- OFONO_BUS_NAME, NULL,
- OFONO_NETWORKREG_INTERFACE,
- "PropertyChanged",
- handle_network_property_changed,
- NULL, NULL);
-
- modem_added_watch = g_dbus_add_signal_watch(connection,
- OFONO_BUS_NAME, NULL,
- OFONO_MANAGER_INTERFACE,
- "ModemAdded",
- handle_manager_modem_added,
- NULL, NULL);
-
- modem_removed_watch = g_dbus_add_signal_watch(connection,
- OFONO_BUS_NAME, NULL,
- OFONO_MANAGER_INTERFACE,
- "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);
+ add_watch(OFONO_BUS_NAME, NULL, OFONO_NETWORKREG_INTERFACE,
+ "PropertyChanged", handle_network_property_changed);
+ add_watch(OFONO_BUS_NAME, NULL, OFONO_MANAGER_INTERFACE,
+ "ModemAdded", handle_manager_modem_added);
+ add_watch(OFONO_BUS_NAME, NULL, OFONO_MANAGER_INTERFACE,
+ "ModemRemoved", handle_manager_modem_removed);
+ add_watch(OFONO_BUS_NAME, NULL, OFONO_VCMANAGER_INTERFACE,
+ "CallAdded", handle_vcmanager_call_added);
+ add_watch(OFONO_BUS_NAME, NULL, OFONO_VCMANAGER_INTERFACE,
+ "CallRemoved", handle_vcmanager_call_removed);
ret = send_method_call(OFONO_BUS_NAME, OFONO_PATH,
OFONO_MANAGER_INTERFACE, "GetModems",
@@ -1247,6 +1226,11 @@ int telephony_init(void)
return ret;
}
+static void remove_watch(gpointer data)
+{
+ g_dbus_remove_watch(connection, GPOINTER_TO_UINT(data));
+}
+
void telephony_exit(void)
{
DBG("");
@@ -1257,12 +1241,9 @@ void telephony_exit(void)
if (modem_obj_path)
modem_removed(modem_obj_path);
- g_dbus_remove_watch(connection, registration_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);
+ g_slist_foreach(watches, (GFunc) remove_watch, NULL);
+ g_slist_free(watches);
+ watches = NULL;
g_slist_foreach(pending, (GFunc) dbus_pending_call_cancel, NULL);
g_slist_foreach(pending, (GFunc) dbus_pending_call_unref, NULL);
--
1.7.1
^ permalink raw reply related [flat|nested] 12+ messages in thread* [PATCH 08/10] telephony-ofono: handle ofono appearing/disappearing from bus
2011-01-05 15:59 [PATCH 00/10] Update telephony-ofono driver Luiz Augusto von Dentz
` (6 preceding siblings ...)
2011-01-05 15:59 ` [PATCH 07/10] telephony-ofono: simplify watches handling logic Luiz Augusto von Dentz
@ 2011-01-05 15:59 ` Luiz Augusto von Dentz
2011-01-05 15:59 ` [PATCH 09/10] telephony-ofono: add handling for Modem.Interfaces property Luiz Augusto von Dentz
` (2 subsequent siblings)
10 siblings, 0 replies; 12+ messages in thread
From: Luiz Augusto von Dentz @ 2011-01-05 15:59 UTC (permalink / raw)
To: linux-bluetooth
From: Luiz Augusto von Dentz <luiz.dentz-von@nokia.com>
---
audio/telephony-ofono.c | 31 ++++++++++++++++++++++++++-----
1 files changed, 26 insertions(+), 5 deletions(-)
diff --git a/audio/telephony-ofono.c b/audio/telephony-ofono.c
index 00b24f9..b6bea91 100644
--- a/audio/telephony-ofono.c
+++ b/audio/telephony-ofono.c
@@ -1187,10 +1187,28 @@ done:
remove_pending(call);
}
+static void handle_service_connect(DBusConnection *conn, void *user_data)
+{
+ DBG("telephony-ofono: %s found", OFONO_BUS_NAME);
+
+ send_method_call(OFONO_BUS_NAME, OFONO_PATH,
+ OFONO_MANAGER_INTERFACE, "GetModems",
+ get_modems_reply, NULL, DBUS_TYPE_INVALID);
+}
+
+static void handle_service_disconnect(DBusConnection *conn, void *user_data)
+{
+ DBG("telephony-ofono: %s exitted", OFONO_BUS_NAME);
+
+ if (modem_obj_path)
+ modem_removed(modem_obj_path);
+}
+
int telephony_init(void)
{
const char *battery_cap = "battery";
int ret;
+ guint watch;
connection = dbus_bus_get(DBUS_BUS_SYSTEM, NULL);
@@ -1205,11 +1223,14 @@ int telephony_init(void)
add_watch(OFONO_BUS_NAME, NULL, OFONO_VCMANAGER_INTERFACE,
"CallRemoved", handle_vcmanager_call_removed);
- ret = send_method_call(OFONO_BUS_NAME, OFONO_PATH,
- OFONO_MANAGER_INTERFACE, "GetModems",
- get_modems_reply, NULL, DBUS_TYPE_INVALID);
- if (ret < 0)
- return ret;
+ watch = g_dbus_add_service_watch(connection, OFONO_BUS_NAME,
+ handle_service_connect,
+ handle_service_disconnect,
+ NULL, NULL);
+ if (watch == 0)
+ return -ENOMEM;
+
+ watches = g_slist_prepend(watches, GUINT_TO_POINTER(watch));
ret = send_method_call("org.freedesktop.Hal",
"/org/freedesktop/Hal/Manager",
--
1.7.1
^ permalink raw reply related [flat|nested] 12+ messages in thread* [PATCH 09/10] telephony-ofono: add handling for Modem.Interfaces property
2011-01-05 15:59 [PATCH 00/10] Update telephony-ofono driver Luiz Augusto von Dentz
` (7 preceding siblings ...)
2011-01-05 15:59 ` [PATCH 08/10] telephony-ofono: handle ofono appearing/disappearing from bus Luiz Augusto von Dentz
@ 2011-01-05 15:59 ` Luiz Augusto von Dentz
2011-01-05 15:59 ` [PATCH 10/10] telephony-ofono: fix not updating indicators when a call is removed Luiz Augusto von Dentz
2011-01-06 22:39 ` [PATCH 00/10] Update telephony-ofono driver Johan Hedberg
10 siblings, 0 replies; 12+ messages in thread
From: Luiz Augusto von Dentz @ 2011-01-05 15:59 UTC (permalink / raw)
To: linux-bluetooth
From: Luiz Augusto von Dentz <luiz.dentz-von@nokia.com>
This should make sure a modem is only used if a network is available
---
audio/telephony-ofono.c | 185 +++++++++++++++++++++++++++++++++++++++--------
1 files changed, 155 insertions(+), 30 deletions(-)
diff --git a/audio/telephony-ofono.c b/audio/telephony-ofono.c
index b6bea91..6492081 100644
--- a/audio/telephony-ofono.c
+++ b/audio/telephony-ofono.c
@@ -61,6 +61,7 @@ static GSList *pending = NULL;
#define OFONO_BUS_NAME "org.ofono"
#define OFONO_PATH "/"
+#define OFONO_MODEM_INTERFACE "org.ofono.Modem"
#define OFONO_MANAGER_INTERFACE "org.ofono.Manager"
#define OFONO_NETWORKREG_INTERFACE "org.ofono.NetworkRegistration"
#define OFONO_VCMANAGER_INTERFACE "org.ofono.VoiceCallManager"
@@ -788,15 +789,12 @@ done:
remove_pending(call);
}
-static void modem_added(const char *path)
+static void network_found(const char *path)
{
int ret;
DBG("%s", path);
- if (modem_obj_path != NULL)
- return;
-
modem_obj_path = g_strdup(path);
ret = send_method_call(OFONO_BUS_NAME, path,
@@ -807,12 +805,90 @@ static void modem_added(const char *path)
OFONO_NETWORKREG_INTERFACE);
}
+static void modem_removed(const char *path)
+{
+ if (g_strcmp0(modem_obj_path, path) != 0)
+ return;
+
+ DBG("%s", path);
+
+ g_slist_foreach(calls, (GFunc) call_free, NULL);
+ g_slist_free(calls);
+ calls = NULL;
+
+ g_free(net.operator_name);
+ net.operator_name = NULL;
+
+ g_free(modem_obj_path);
+ modem_obj_path = NULL;
+}
+
+static void parse_modem_interfaces(const char *path, DBusMessageIter *ifaces)
+{
+ DBG("%s", path);
+
+ while (dbus_message_iter_get_arg_type(ifaces) == DBUS_TYPE_STRING) {
+ const char *iface;
+
+ dbus_message_iter_get_basic(ifaces, &iface);
+
+ if (g_str_equal(iface, OFONO_NETWORKREG_INTERFACE)) {
+ network_found(path);
+ return;
+ }
+
+ dbus_message_iter_next(ifaces);
+ }
+
+ modem_removed(path);
+}
+
+static void modem_added(const char *path, DBusMessageIter *properties)
+{
+ if (modem_obj_path != NULL) {
+ DBG("Ignoring, modem already exist");
+ return;
+ }
+
+ DBG("%s", path);
+
+ while (dbus_message_iter_get_arg_type(properties)
+ == DBUS_TYPE_DICT_ENTRY) {
+ const char *key;
+ DBusMessageIter interfaces, value, entry;
+
+ dbus_message_iter_recurse(properties, &entry);
+ dbus_message_iter_get_basic(&entry, &key);
+
+ dbus_message_iter_next(&entry);
+ dbus_message_iter_recurse(&entry, &value);
+
+ if (strcasecmp(key, "Interfaces") != 0)
+ goto next;
+
+ if (dbus_message_iter_get_arg_type(&value)
+ != DBUS_TYPE_ARRAY) {
+ error("Invalid Signature");
+ return;
+ }
+
+ dbus_message_iter_recurse(&value, &interfaces);
+
+ parse_modem_interfaces(path, &interfaces);
+
+ if (modem_obj_path != NULL)
+ return;
+
+ next:
+ dbus_message_iter_next(properties);
+ }
+}
+
static void get_modems_reply(DBusPendingCall *call, void *user_data)
{
DBusError err;
DBusMessage *reply;
DBusMessageIter iter, entry;
- const char *path;
DBG("list_modem_reply is called\n");
reply = dbus_pending_call_steal_reply(call);
@@ -825,6 +901,10 @@ static void get_modems_reply(DBusPendingCall *call, void *user_data)
goto done;
}
+ /* Skip modem selection if a modem already exist */
+ if (modem_obj_path != NULL)
+ goto done;
+
dbus_message_iter_init(reply, &iter);
if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY) {
@@ -834,14 +914,23 @@ static void get_modems_reply(DBusPendingCall *call, void *user_data)
dbus_message_iter_recurse(&iter, &entry);
- if (dbus_message_iter_get_arg_type(&entry) != DBUS_TYPE_OBJECT_PATH) {
- error("Unexpected signature");
- goto done;
- }
+ while (dbus_message_iter_get_arg_type(&entry)
+ == DBUS_TYPE_STRUCT) {
+ const char *path;
+ DBusMessageIter item, properties;
+
+ dbus_message_iter_recurse(&entry, &item);
+ dbus_message_iter_get_basic(&item, &path);
+
+ dbus_message_iter_next(&item);
+ dbus_message_iter_recurse(&item, &properties);
- dbus_message_iter_get_basic(&entry, &path);
+ modem_added(path, &properties);
+ if (modem_obj_path != NULL)
+ break;
- modem_added(path);
+ dbus_message_iter_next(&entry);
+ }
done:
dbus_message_unref(reply);
@@ -873,6 +962,57 @@ static gboolean handle_network_property_changed(DBusConnection *conn,
return TRUE;
}
+static void handle_modem_property(const char *path, const char *property,
+ DBusMessageIter *variant)
+{
+ DBG("%s", property);
+
+ if (g_str_equal(property, "Interfaces")) {
+ DBusMessageIter interfaces;
+
+ if (dbus_message_iter_get_arg_type(variant)
+ != DBUS_TYPE_ARRAY) {
+ error("Invalid signature");
+ return;
+ }
+
+ dbus_message_iter_recurse(variant, &interfaces);
+ parse_modem_interfaces(path, &interfaces);
+ }
+}
+
+static gboolean handle_modem_property_changed(DBusConnection *conn,
+ DBusMessage *msg, void *data)
+{
+ DBusMessageIter iter, variant;
+ const char *property, *path;
+
+ path = dbus_message_get_path(msg);
+
+ /* Ignore if modem already exist and paths doesn't match */
+ if (modem_obj_path != NULL &&
+ g_str_equal(path, modem_obj_path) == FALSE)
+ return TRUE;
+
+ dbus_message_iter_init(msg, &iter);
+
+ if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING) {
+ error("Unexpected signature in %s.%s PropertyChanged signal",
+ dbus_message_get_interface(msg),
+ dbus_message_get_member(msg));
+ return TRUE;
+ }
+
+ dbus_message_iter_get_basic(&iter, &property);
+
+ dbus_message_iter_next(&iter);
+ dbus_message_iter_recurse(&iter, &variant);
+
+ handle_modem_property(path, property, &variant);
+
+ return TRUE;
+}
+
static gboolean handle_vcmanager_call_added(DBusConnection *conn,
DBusMessage *msg, void *data)
{
@@ -959,31 +1099,14 @@ static gboolean handle_manager_modem_added(DBusConnection *conn,
}
dbus_message_iter_get_basic(&iter, &path);
+ dbus_message_iter_next(&iter);
dbus_message_iter_recurse(&iter, &properties);
- modem_added(path);
+ modem_added(path, &properties);
return TRUE;
}
-static void modem_removed(const char *path)
-{
- if (g_strcmp0(modem_obj_path, path) != 0)
- return;
-
- DBG("%s", path);
-
- g_slist_foreach(calls, (GFunc) call_free, NULL);
- g_slist_free(calls);
- calls = NULL;
-
- g_free(net.operator_name);
- net.operator_name = NULL;
-
- g_free(modem_obj_path);
- modem_obj_path = NULL;
-}
-
static gboolean handle_manager_modem_removed(DBusConnection *conn,
DBusMessage *msg, void *data)
{
@@ -1212,6 +1335,8 @@ int telephony_init(void)
connection = dbus_bus_get(DBUS_BUS_SYSTEM, NULL);
+ add_watch(OFONO_BUS_NAME, NULL, OFONO_MODEM_INTERFACE,
+ "PropertyChanged", handle_modem_property_changed);
add_watch(OFONO_BUS_NAME, NULL, OFONO_NETWORKREG_INTERFACE,
"PropertyChanged", handle_network_property_changed);
add_watch(OFONO_BUS_NAME, NULL, OFONO_MANAGER_INTERFACE,
--
1.7.1
^ permalink raw reply related [flat|nested] 12+ messages in thread* [PATCH 10/10] telephony-ofono: fix not updating indicators when a call is removed
2011-01-05 15:59 [PATCH 00/10] Update telephony-ofono driver Luiz Augusto von Dentz
` (8 preceding siblings ...)
2011-01-05 15:59 ` [PATCH 09/10] telephony-ofono: add handling for Modem.Interfaces property Luiz Augusto von Dentz
@ 2011-01-05 15:59 ` Luiz Augusto von Dentz
2011-01-06 22:39 ` [PATCH 00/10] Update telephony-ofono driver Johan Hedberg
10 siblings, 0 replies; 12+ messages in thread
From: Luiz Augusto von Dentz @ 2011-01-05 15:59 UTC (permalink / raw)
To: linux-bluetooth
From: Luiz Augusto von Dentz <luiz.dentz-von@nokia.com>
In some extreme cases such as modem removal ofono may not have a chance
to set the call to disconnected state so indicators would not be update
properly.
---
audio/telephony-ofono.c | 18 ++++++++++--------
1 files changed, 10 insertions(+), 8 deletions(-)
diff --git a/audio/telephony-ofono.c b/audio/telephony-ofono.c
index 6492081..ae8f56a 100644
--- a/audio/telephony-ofono.c
+++ b/audio/telephony-ofono.c
@@ -457,6 +457,16 @@ static void call_free(struct voice_call *vc)
{
DBG("%s", vc->obj_path);
+ 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();
+
g_dbus_remove_watch(connection, vc->watch);
g_free(vc->obj_path);
g_free(vc->number);
@@ -489,14 +499,6 @@ static gboolean handle_vc_property_changed(DBusConnection *conn,
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")) {
--
1.7.1
^ permalink raw reply related [flat|nested] 12+ messages in thread* Re: [PATCH 00/10] Update telephony-ofono driver
2011-01-05 15:59 [PATCH 00/10] Update telephony-ofono driver Luiz Augusto von Dentz
` (9 preceding siblings ...)
2011-01-05 15:59 ` [PATCH 10/10] telephony-ofono: fix not updating indicators when a call is removed Luiz Augusto von Dentz
@ 2011-01-06 22:39 ` Johan Hedberg
10 siblings, 0 replies; 12+ messages in thread
From: Johan Hedberg @ 2011-01-06 22:39 UTC (permalink / raw)
To: Luiz Augusto von Dentz; +Cc: linux-bluetooth
Hi Luiz,
On Wed, Jan 05, 2011, Luiz Augusto von Dentz wrote:
> This patches update the ofono backend so it can be used with recent
> versions of ofono (> 0.28), it can be tested by compiling bluetoothd with
> --with-telephony=ofono
>
> Since the hfp doesn't really support multiple modems, at least not in the
> same record/connection, the driver will pick the first modem that has
> org.ofono.NetworkRegistration since that is what hfp expect as indicator.
>
> Calls are only picked/indicated if they belong to the modem in use
> otherwise they are ignored.
>
> Note that there is still a plan to integrate hfp inside ofono and this
> changes doesn't change anything, it basically add the possibility to use
> ofono with BlueZ 4.x since 5.x probably will change this entirely.
>
> Luiz Augusto von Dentz (10):
> telephony-ofono: notify alerting calls when headset connects
> telephony-ofono: fix not being able to answer alerting/waiting calls
> telephony-ofono: fix not setting originating when status property
> changes
> telephony-ofono: make use of GetModems method
> telephony-ofono: make use of GetCalls method
> telephony-ofono: fix not canceling pending calls on exit
> telephony-ofono: simplify watches handling logic
> telephony-ofono: handle ofono appearing/disappearing from bus
> telephony-ofono: add handling for Modem.Interfaces property
> telephony-ofono: fix not updating indicators when a call is removed
>
> audio/telephony-ofono.c | 916 +++++++++++++++++++++++++++++++----------------
> 1 files changed, 604 insertions(+), 312 deletions(-)
All 10 patches have been pushed upstream. Thanks.
Johan
^ permalink raw reply [flat|nested] 12+ messages in thread