Signed-off-by: Mika Liljeberg <mika.liljeb...@nokia.com> --- drivers/isimodem/debug.c | 25 +++++++++++++++ drivers/isimodem/debug.h | 2 + drivers/isimodem/gpds.h | 17 ++++++++++ drivers/isimodem/gprs.c | 74 +++++++++++++++++++++++++++++++++++++++++++++- 4 files changed, 117 insertions(+), 1 deletions(-)
diff --git a/drivers/isimodem/debug.c b/drivers/isimodem/debug.c index 86530fd..b398797 100644 --- a/drivers/isimodem/debug.c +++ b/drivers/isimodem/debug.c @@ -979,6 +979,31 @@ const char *gpds_isi_cause_name(enum gpds_isi_cause value) return "GPDS_<UNKNOWN>"; } +const char *gpds_transfer_status_name(enum gpds_transfer_status value) +{ + switch (value) { + _(GPDS_TRANSFER_NOT_AVAIL); + _(GPDS_TRANSFER_AVAIL); + } + return "GPDS_<UNKNOWN>"; +} + +const char *gpds_transfer_cause_name(enum gpds_transfer_cause value) +{ + switch (value) { + _(GPDS_TRANSFER_CAUSE_ATTACHED); + _(GPDS_TRANSFER_CAUSE_DETACHED); + _(GPDS_TRANSFER_CAUSE_RESUMED); + _(GPDS_TRANSFER_CAUSE_SUSPENDED_NO_COVERAGE); + _(GPDS_TRANSFER_CAUSE_SUSPENDED_CALL_SMS); + _(GPDS_TRANSFER_CAUSE_SUSPENDED_CALL); + _(GPDS_TRANSFER_CAUSE_SUSPENDED_RAU); + _(GPDS_TRANSFER_CAUSE_SUSPENDED_LU); + _(GPDS_TRANSFER_CAUSE_DSAC_RESTRICTION); + } + return "GPDS_<UNKNOWN>"; +} + #undef _ static void hex_dump(const char *name, const uint8_t m[], size_t len) diff --git a/drivers/isimodem/debug.h b/drivers/isimodem/debug.h index d507991..1ad5547 100644 --- a/drivers/isimodem/debug.h +++ b/drivers/isimodem/debug.h @@ -70,6 +70,8 @@ const char *gpds_message_id_name(enum gpds_message_id value); const char *gpds_subblock_name(enum gpds_subblock value); const char *gpds_status_name(enum gpds_status value); const char *gpds_isi_cause_name(enum gpds_isi_cause value); +const char *gpds_transfer_status_name(enum gpds_transfer_status value); +const char *gpds_transfer_cause_name(enum gpds_transfer_cause value); void ss_debug(const void *restrict buf, size_t len, void *data); void mtc_debug(const void *restrict buf, size_t len, void *data); diff --git a/drivers/isimodem/gpds.h b/drivers/isimodem/gpds.h index 86d4d95..9bb60e6 100644 --- a/drivers/isimodem/gpds.h +++ b/drivers/isimodem/gpds.h @@ -202,6 +202,23 @@ enum gpds_isi_cause { GPDS_CAUSE_AUT_FAILURE = 0xFF, }; +enum gpds_transfer_status { + GPDS_TRANSFER_NOT_AVAIL = 0x00, + GPDS_TRANSFER_AVAIL = 0x01, +}; + +enum gpds_transfer_cause { + GPDS_TRANSFER_CAUSE_ATTACHED = 0x02, + GPDS_TRANSFER_CAUSE_DETACHED = 0x03, + GPDS_TRANSFER_CAUSE_RESUMED = 0x04, + GPDS_TRANSFER_CAUSE_SUSPENDED_NO_COVERAGE = 0x05, + GPDS_TRANSFER_CAUSE_SUSPENDED_CALL_SMS = 0x07, + GPDS_TRANSFER_CAUSE_SUSPENDED_CALL = 0x08, + GPDS_TRANSFER_CAUSE_SUSPENDED_RAU = 0x09, + GPDS_TRANSFER_CAUSE_SUSPENDED_LU = 0x0A, + GPDS_TRANSFER_CAUSE_DSAC_RESTRICTION = 0x0B, +}; + enum gpds_context_type { GPDS_CONT_TYPE_NORMAL = 0x00, GPDS_CONT_TYPE_NWI = 0x01, diff --git a/drivers/isimodem/gprs.c b/drivers/isimodem/gprs.c index 6f4f686..573dbb5 100644 --- a/drivers/isimodem/gprs.c +++ b/drivers/isimodem/gprs.c @@ -41,6 +41,8 @@ #include "gpds.h" #include "debug.h" +#define SUSPEND_TIMEOUT 8 /* s */ + /* 27.007 Section 10.1.20 <stat> */ enum network_registration_status { GPRS_STAT_NOT_REGISTERED = 0, @@ -53,6 +55,7 @@ enum network_registration_status { struct gprs_data { GIsiClient *client; + guint timeout; }; static void detach_ind_cb(GIsiClient *client, @@ -72,6 +75,70 @@ static void detach_ind_cb(GIsiClient *client, /*ofono_gprs_detached_notify(gprs);*/ } +static gboolean suspend_timeout(gpointer data) +{ + struct ofono_gprs *gprs = data; + struct gprs_data *gd = ofono_gprs_get_data(gprs); + + ofono_gprs_suspend_notify(gprs, TRUE); + gd->timeout = 0; + return FALSE; +} + +static void suspend_notify(struct ofono_gprs *gprs, + uint8_t suspend_status, + uint8_t suspend_cause) +{ + struct gprs_data *gd = ofono_gprs_get_data(gprs); + ofono_bool_t status = FALSE; + + DBG("transfer status: %s (0x%02"PRIx8") cause %s (0x%02"PRIx8")", + gpds_transfer_status_name(suspend_status), suspend_status, + gpds_transfer_cause_name(suspend_cause), suspend_cause); + + if (suspend_status == GPDS_TRANSFER_NOT_AVAIL) { + switch (suspend_cause) { + case GPDS_TRANSFER_CAUSE_SUSPENDED_NO_COVERAGE: + case GPDS_TRANSFER_CAUSE_SUSPENDED_CALL: + status = TRUE; + break; + + case GPDS_TRANSFER_CAUSE_SUSPENDED_CALL_SMS: + case GPDS_TRANSFER_CAUSE_SUSPENDED_RAU: + case GPDS_TRANSFER_CAUSE_SUSPENDED_LU: + if (gd->timeout) + return; + gd->timeout = g_timeout_add_seconds(SUSPEND_TIMEOUT, + suspend_timeout, + gprs); + return; + + default: + return; + } + } + + if (gd->timeout) { + g_source_remove(gd->timeout); + gd->timeout = 0; + } + + ofono_gprs_suspend_notify(gprs, status); +} + +static void transfer_status_ind_cb(GIsiClient *client, + const void *restrict data, size_t len, + uint16_t object, void *opaque) +{ + struct ofono_gprs *gprs = opaque; + const unsigned char *msg = data; + + if (!msg || len < 3 || msg[0] != GPDS_TRANSFER_STATUS_IND) + return; + + suspend_notify(gprs, msg[1], msg[2]); +} + static gboolean isi_gprs_register(gpointer user) { struct ofono_gprs *gprs = user; @@ -83,6 +150,8 @@ static gboolean isi_gprs_register(gpointer user) g_isi_client_set_debug(gd->client, gpds_debug, NULL); g_isi_subscribe(gd->client, GPDS_DETACH_IND, detach_ind_cb, gprs); + g_isi_subscribe(gd->client, GPDS_TRANSFER_STATUS_IND, + transfer_status_ind_cb, gprs); ofono_gprs_register(user); @@ -258,6 +327,7 @@ static gboolean status_resp_cb(GIsiClient *client, const unsigned char *msg = data; struct isi_cb_data *cbd = opaque; ofono_gprs_status_cb_t cb = cbd->cb; + struct ofono_gprs *gprs = cbd->data; int status; if (!msg) { @@ -265,7 +335,7 @@ static gboolean status_resp_cb(GIsiClient *client, goto error; } - if (len < 2 || msg[0] != GPDS_STATUS_RESP) + if (len < 13 || msg[0] != GPDS_STATUS_RESP) return FALSE; /* FIXME: the core still expects reg status, and not a boolean @@ -281,6 +351,8 @@ static gboolean status_resp_cb(GIsiClient *client, status = GPRS_STAT_UNKNOWN; } + suspend_notify(gprs, msg[11], msg[12]); + CALLBACK_WITH_SUCCESS(cb, status, cbd->data); return TRUE; -- 1.7.0.4 _______________________________________________ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono