summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMika Liljeberg <mika.liljeberg@nokia.com>2010-09-10 16:50:57 +0300
committerDenis Kenzior <denkenz@gmail.com>2010-09-10 10:51:53 -0500
commit1e139eb1cedd6cb818c9b32f0d0043507ddc8cf0 (patch)
treeff65be2ace7576fe204c121f5c3bb84dc38d7f07
parentffad43aeb360262b4d1b476b59e382c491fea17f (diff)
downloadofono-1e139eb1cedd6cb818c9b32f0d0043507ddc8cf0.tar.bz2
gprs: add Suspended property
-rw-r--r--doc/connman-api.txt19
-rw-r--r--include/gprs.h10
-rw-r--r--src/gprs.c72
3 files changed, 101 insertions, 0 deletions
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;