From 1e139eb1cedd6cb818c9b32f0d0043507ddc8cf0 Mon Sep 17 00:00:00 2001 From: Mika Liljeberg Date: Fri, 10 Sep 2010 16:50:57 +0300 Subject: [PATCH] gprs: add Suspended property --- doc/connman-api.txt | 19 ++++++++++++ include/gprs.h | 10 +++++++ src/gprs.c | 72 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 101 insertions(+) diff --git a/doc/connman-api.txt b/doc/connman-api.txt index 43d8897f..00d5ed75 100644 --- a/doc/connman-api.txt +++ b/doc/connman-api.txt @@ -77,6 +77,25 @@ Properties boolean Attached [readonly] be available, e.g. receiving SMS over packet radio or network initiated PDP activation. + boolean Suspended [readonly, optional] + + Contains whether the GPRS service is suspended. + During suspended state the modem is attached to the + GPRS service and all contexts remain established, + however, data transfer is not possible. + + The suspended state may be entered if the modem is + temporarily out of network coverage. GPRS class B + modems will suspend GPRS whenever a voice call is + active at the same time. GPRS may also be suspended + if the network does not support simultaneous packet + data and voice. Various signalling procedures may + also cause GPRS to be briefly suspended. + + As the suspension may be brief, clients should wait + for an appropriate time for GPRS service to resume + before taking corrective action. + boolean RoamingAllowed [readwrite] Contains whether data roaming is allowed. In the off diff --git a/include/gprs.h b/include/gprs.h index a1cbcd9c..ad7925c3 100644 --- a/include/gprs.h +++ b/include/gprs.h @@ -47,8 +47,18 @@ struct ofono_gprs_driver { ofono_gprs_status_cb_t cb, void *data); }; +enum gprs_suspend_cause { + GPRS_SUSPENDED_DETACHED, + GPRS_SUSPENDED_SIGNALLING, + GPRS_SUSPENDED_CALL, + GPRS_SUSPENDED_NO_COVERAGE, + GPRS_SUSPENDED_UNKNOWN_CAUSE, +}; + void ofono_gprs_status_notify(struct ofono_gprs *gprs, int status); void ofono_gprs_detached_notify(struct ofono_gprs *gprs); +void ofono_gprs_suspend_notify(struct ofono_gprs *gprs, int cause); +void ofono_gprs_resume_notify(struct ofono_gprs *gprs); int ofono_gprs_driver_register(const struct ofono_gprs_driver *d); void ofono_gprs_driver_unregister(const struct ofono_gprs_driver *d); diff --git a/src/gprs.c b/src/gprs.c index d57115b8..d85e70b8 100644 --- a/src/gprs.c +++ b/src/gprs.c @@ -47,6 +47,7 @@ #define SETTINGS_GROUP "Settings" #define MAX_CONTEXT_NAME_LENGTH 127 #define MAX_CONTEXTS 256 +#define SUSPEND_TIMEOUT 8 static GSList *g_drivers = NULL; static GSList *g_context_drivers = NULL; @@ -64,8 +65,10 @@ struct ofono_gprs { ofono_bool_t driver_attached; ofono_bool_t roaming_allowed; ofono_bool_t powered; + ofono_bool_t suspended; int status; int flags; + guint suspend_timeout; struct idmap *pid_map; unsigned int last_context_id; struct idmap *cid_map; @@ -894,6 +897,66 @@ static gboolean context_dbus_unregister(struct pri_context *ctx) OFONO_CONNECTION_CONTEXT_INTERFACE); } +static void update_suspended_property(struct ofono_gprs *gprs, + ofono_bool_t suspended) +{ + DBusConnection *conn = ofono_dbus_get_connection(); + const char *path = __ofono_atom_get_path(gprs->atom); + dbus_bool_t value = suspended; + + if (gprs->suspend_timeout) { + g_source_remove(gprs->suspend_timeout); + gprs->suspend_timeout = 0; + } + + if (gprs->suspended == suspended) + return; + + DBG("%s GPRS service %s", __ofono_atom_get_path(gprs->atom), + suspended ? "suspended" : "resumed"); + + gprs->suspended = suspended; + + if (gprs->attached) + ofono_dbus_signal_property_changed(conn, path, + OFONO_CONNECTION_MANAGER_INTERFACE, + "Suspended", DBUS_TYPE_BOOLEAN, &value); +} + +static gboolean suspend_timeout(gpointer data) +{ + struct ofono_gprs *gprs = data; + + gprs->suspend_timeout = 0; + update_suspended_property(gprs, TRUE); + return FALSE; +} + +void ofono_gprs_suspend_notify(struct ofono_gprs *gprs, int cause) +{ + switch (cause) { + case GPRS_SUSPENDED_DETACHED: + case GPRS_SUSPENDED_CALL: + case GPRS_SUSPENDED_NO_COVERAGE: + update_suspended_property(gprs, TRUE); + break; + + case GPRS_SUSPENDED_SIGNALLING: + case GPRS_SUSPENDED_UNKNOWN_CAUSE: + if (gprs->suspend_timeout) + g_source_remove(gprs->suspend_timeout); + gprs->suspend_timeout = g_timeout_add_seconds(SUSPEND_TIMEOUT, + suspend_timeout, + gprs); + break; + } +} + +void ofono_gprs_resume_notify(struct ofono_gprs *gprs) +{ + update_suspended_property(gprs, FALSE); +} + static void gprs_attached_update(struct ofono_gprs *gprs) { DBusConnection *conn = ofono_dbus_get_connection(); @@ -1052,6 +1115,12 @@ static DBusMessage *gprs_get_properties(DBusConnection *conn, value = gprs->powered; ofono_dbus_dict_append(&dict, "Powered", DBUS_TYPE_BOOLEAN, &value); + if (gprs->attached) { + value = gprs->suspended; + ofono_dbus_dict_append(&dict, "Suspended", + DBUS_TYPE_BOOLEAN, &value); + } + dbus_message_iter_close_container(&iter, &dict); return reply; @@ -1697,6 +1766,9 @@ static void gprs_remove(struct ofono_atom *atom) if (gprs == NULL) return; + if (gprs->suspend_timeout) + g_source_remove(gprs->suspend_timeout); + if (gprs->pid_map) { idmap_free(gprs->pid_map); gprs->pid_map = NULL;