summaryrefslogtreecommitdiffstats
path: root/drivers/mbmmodem
diff options
context:
space:
mode:
authorDenis Kenzior <denkenz@gmail.com>2009-12-01 19:38:44 -0600
committerDenis Kenzior <denkenz@gmail.com>2009-12-01 19:38:44 -0600
commit8cd0990c66be67b372fb4a3de67aa94ea2e5214a (patch)
tree59b63e1bf4369f666b6569771ab1c1f1481e4a5b /drivers/mbmmodem
parent6389552fd52e592018fa9c253f7303e500c85044 (diff)
downloadofono-8cd0990c66be67b372fb4a3de67aa94ea2e5214a.tar.bz2
Fix: Poll ENAP on older mbm hardware
Diffstat (limited to 'drivers/mbmmodem')
-rw-r--r--drivers/mbmmodem/gprs-context.c311
1 files changed, 186 insertions, 125 deletions
diff --git a/drivers/mbmmodem/gprs-context.c b/drivers/mbmmodem/gprs-context.c
index 63022074..548d3f09 100644
--- a/drivers/mbmmodem/gprs-context.c
+++ b/drivers/mbmmodem/gprs-context.c
@@ -48,6 +48,9 @@
static const char *none_prefix[] = { NULL };
static const char *e2ipcfg_prefix[] = { "*E2IPCFG:", NULL };
+static const char *enap_prefix[] = { "*ENAP:", NULL };
+
+static gboolean mbm_enap_poll(gpointer user_data);
enum mbm_state {
MBM_NONE = 0,
@@ -60,6 +63,7 @@ struct gprs_context_data {
unsigned int active_context;
gboolean have_e2nap;
gboolean have_e2ipcfg;
+ unsigned int enap_source;
enum mbm_state mbm_state;
union {
ofono_gprs_context_cb_t down_cb; /* Down callback */
@@ -69,6 +73,172 @@ struct gprs_context_data {
int enap; /* State of the call */
};
+static void mbm_e2ipcfg_cb(gboolean ok, GAtResult *result, gpointer user_data)
+{
+ struct ofono_gprs_context *gc = user_data;
+ struct gprs_context_data *gcd = ofono_gprs_context_get_data(gc);
+ GAtResultIter iter;
+ int numdns = 0;
+ int type;
+ const char *str;
+ const char *ip = NULL;
+ const char *gateway = NULL;
+ const char *dns[5];
+ struct ofono_modem *modem;
+ const char *interface;
+ gboolean success = FALSE;
+
+ if (!ok)
+ goto out;
+
+ g_at_result_iter_init(&iter, result);
+
+ if (g_at_result_iter_next(&iter, "*E2IPCFG:") == FALSE)
+ return;
+
+ while (g_at_result_iter_open_list(&iter)) {
+ if (g_at_result_iter_next_number(&iter, &type) == FALSE)
+ break;
+
+ if (g_at_result_iter_next_string(&iter, &str) == FALSE)
+ break;
+
+ switch (type) {
+ case 1:
+ ip = str;
+ break;
+ case 2:
+ gateway = str;
+ break;
+ case 3:
+ dns[numdns++] = str;
+ break;
+ default:
+ break;
+ }
+
+ if (g_at_result_iter_close_list(&iter) == FALSE)
+ break;
+ }
+
+ dns[numdns] = NULL;
+
+ if (ip && gateway && numdns)
+ success = TRUE;
+
+out:
+ modem = ofono_gprs_context_get_modem(gc);
+ interface = ofono_modem_get_string(modem, "NetworkInterface");
+
+ CALLBACK_WITH_SUCCESS(gcd->up_cb, interface, success, ip, NULL,
+ gateway, success ? dns : NULL, gcd->cb_data);
+ gcd->mbm_state = MBM_NONE;
+ gcd->up_cb = NULL;
+ gcd->cb_data = NULL;
+}
+
+static void mbm_get_ip_details(struct ofono_gprs_context *gc)
+{
+ struct gprs_context_data *gcd = ofono_gprs_context_get_data(gc);
+ struct ofono_modem *modem;
+ const char *interface;
+
+ if (gcd->have_e2ipcfg) {
+ g_at_chat_send(gcd->chat, "AT*E2IPCFG?", e2ipcfg_prefix,
+ mbm_e2ipcfg_cb, gc, NULL);
+ return;
+ }
+
+ modem = ofono_gprs_context_get_modem(gc);
+ interface = ofono_modem_get_string(modem, "NetworkInterface");
+ CALLBACK_WITH_SUCCESS(gcd->up_cb, interface, FALSE, NULL, NULL,
+ NULL, NULL, gcd->cb_data);
+
+ gcd->mbm_state = MBM_NONE;
+ gcd->up_cb = NULL;
+ gcd->cb_data = NULL;
+}
+
+static void mbm_state_changed(struct ofono_gprs_context *gc, int state)
+{
+ struct gprs_context_data *gcd = ofono_gprs_context_get_data(gc);
+
+ if (gcd->active_context == 0)
+ return;
+
+ switch (state) {
+ case MBM_E2NAP_DISCONNECTED:
+ ofono_debug("MBM Context: disconnected");
+
+ if (gcd->mbm_state == MBM_DISABLING) {
+ CALLBACK_WITH_SUCCESS(gcd->down_cb, gcd->cb_data);
+ gcd->down_cb = NULL;
+ } else if (gcd->mbm_state == MBM_ENABLING) {
+ CALLBACK_WITH_FAILURE(gcd->up_cb, NULL, 0, NULL, NULL,
+ NULL, NULL, gcd->cb_data);
+ gcd->up_cb = NULL;
+ } else
+ ofono_gprs_context_deactivated(gc, gcd->active_context);
+
+ gcd->mbm_state = MBM_NONE;
+ gcd->cb_data = NULL;
+ gcd->active_context = 0;
+
+ break;
+
+ case MBM_E2NAP_CONNECTED:
+ ofono_debug("MBM Context: connected");
+
+ if (gcd->mbm_state == MBM_ENABLING)
+ mbm_get_ip_details(gc);
+
+ break;
+
+ case MBM_E2NAP_CONNECTING:
+ ofono_debug("MBM Context: connecting");
+ break;
+
+ default:
+ break;
+ };
+
+ gcd->enap = state;
+}
+
+static void mbm_enap_poll_cb(gboolean ok, GAtResult *result, gpointer user_data)
+{
+ struct ofono_gprs_context *gc = user_data;
+ struct gprs_context_data *gcd = ofono_gprs_context_get_data(gc);
+ GAtResultIter iter;
+ int state;
+
+ g_at_result_iter_init(&iter, result);
+
+ if (g_at_result_iter_next(&iter, "*ENAP:") == FALSE)
+ return;
+
+ g_at_result_iter_next_number(&iter, &state);
+
+ mbm_state_changed(gc, state);
+
+ if ((state == MBM_E2NAP_CONNECTED && gcd->mbm_state == MBM_DISABLING) ||
+ state == MBM_E2NAP_CONNECTING)
+ gcd->enap_source = g_timeout_add_seconds(1, mbm_enap_poll, gc);
+}
+
+static gboolean mbm_enap_poll(gpointer user_data)
+{
+ struct ofono_gprs_context *gc = user_data;
+ struct gprs_context_data *gcd = ofono_gprs_context_get_data(gc);
+
+ g_at_chat_send(gcd->chat, "AT*ENAP?", enap_prefix,
+ mbm_enap_poll_cb, gc, NULL);
+
+ gcd->enap_source = 0;
+
+ return FALSE;
+}
+
static void at_enap_down_cb(gboolean ok, GAtResult *result, gpointer user_data)
{
struct cb_data *cbd = user_data;
@@ -82,6 +252,11 @@ static void at_enap_down_cb(gboolean ok, GAtResult *result, gpointer user_data)
gcd->mbm_state = MBM_DISABLING;
gcd->down_cb = cb;
gcd->cb_data = cbd->data;
+
+ if (gcd->have_e2nap == FALSE)
+ g_at_chat_send(gcd->chat, "AT*ENAP?", enap_prefix,
+ mbm_enap_poll_cb, gc, NULL);
+
return;
}
@@ -101,6 +276,11 @@ static void mbm_enap_up_cb(gboolean ok, GAtResult *result, gpointer user_data)
gcd->mbm_state = MBM_ENABLING;
gcd->up_cb = cb;
gcd->cb_data = cbd->data;
+
+ if (gcd->have_e2nap == FALSE)
+ g_at_chat_send(gcd->chat, "AT*ENAP?", enap_prefix,
+ mbm_enap_poll_cb, gc, NULL);
+
return;
}
@@ -209,102 +389,12 @@ error:
CALLBACK_WITH_FAILURE(cb, data);
}
-static void mbm_e2ipcfg_cb(gboolean ok, GAtResult *result, gpointer user_data)
-{
- struct ofono_gprs_context *gc = user_data;
- struct gprs_context_data *gcd = ofono_gprs_context_get_data(gc);
- GAtResultIter iter;
- int numdns = 0;
- int type;
- const char *str;
- const char *ip = NULL;
- const char *gateway = NULL;
- const char *dns[5];
- struct ofono_modem *modem;
- const char *interface;
- gboolean success = FALSE;
-
- if (!ok)
- goto out;
-
- g_at_result_iter_init(&iter, result);
-
- if (g_at_result_iter_next(&iter, "*E2IPCFG:") == FALSE)
- return;
-
- while (g_at_result_iter_open_list(&iter)) {
- if (g_at_result_iter_next_number(&iter, &type) == FALSE)
- break;
-
- if (g_at_result_iter_next_string(&iter, &str) == FALSE)
- break;
-
- switch (type) {
- case 1:
- ip = str;
- break;
- case 2:
- gateway = str;
- break;
- case 3:
- dns[numdns++] = str;
- break;
- default:
- break;
- }
-
- if (g_at_result_iter_close_list(&iter) == FALSE)
- break;
- }
-
- dns[numdns] = NULL;
-
- if (ip && gateway && numdns)
- success = TRUE;
-
-out:
- modem = ofono_gprs_context_get_modem(gc);
- interface = ofono_modem_get_string(modem, "NetworkInterface");
-
- CALLBACK_WITH_SUCCESS(gcd->up_cb, interface, success, ip, NULL,
- gateway, success ? dns : NULL, gcd->cb_data);
- gcd->mbm_state = MBM_NONE;
- gcd->up_cb = NULL;
- gcd->cb_data = NULL;
-}
-
-static void mbm_get_ip_details(struct ofono_gprs_context *gc)
-{
- struct gprs_context_data *gcd = ofono_gprs_context_get_data(gc);
- struct ofono_modem *modem;
- const char *interface;
-
- if (gcd->have_e2ipcfg) {
- g_at_chat_send(gcd->chat, "AT*E2IPCFG?", e2ipcfg_prefix,
- mbm_e2ipcfg_cb, gc, NULL);
- return;
- }
-
- modem = ofono_gprs_context_get_modem(gc);
- interface = ofono_modem_get_string(modem, "NetworkInterface");
- CALLBACK_WITH_SUCCESS(gcd->up_cb, interface, FALSE, NULL, NULL,
- NULL, NULL, gcd->cb_data);
-
- gcd->mbm_state = MBM_NONE;
- gcd->up_cb = NULL;
- gcd->cb_data = NULL;
-}
-
static void e2nap_notifier(GAtResult *result, gpointer user_data)
{
struct ofono_gprs_context *gc = user_data;
- struct gprs_context_data *gcd = ofono_gprs_context_get_data(gc);
GAtResultIter iter;
int state;
- if (gcd->active_context == 0)
- return;
-
g_at_result_iter_init(&iter, result);
if (g_at_result_iter_next(&iter, "*E2NAP:") == FALSE)
@@ -312,41 +402,7 @@ static void e2nap_notifier(GAtResult *result, gpointer user_data)
g_at_result_iter_next_number(&iter, &state);
- switch (state) {
- case MBM_E2NAP_DISCONNECTED:
- if (gcd->mbm_state == MBM_DISABLING) {
- CALLBACK_WITH_SUCCESS(gcd->down_cb, gcd->cb_data);
- gcd->down_cb = NULL;
- } else if (gcd->mbm_state == MBM_ENABLING) {
- CALLBACK_WITH_FAILURE(gcd->up_cb, NULL, 0, NULL, NULL,
- NULL, NULL, gcd->cb_data);
- gcd->up_cb = NULL;
- } else
- ofono_gprs_context_deactivated(gc, gcd->active_context);
-
- gcd->mbm_state = MBM_NONE;
- gcd->cb_data = NULL;
- gcd->active_context = 0;
-
- break;
-
- case MBM_E2NAP_CONNECTED:
- ofono_debug("MBM Context: connected");
-
- if (gcd->mbm_state == MBM_ENABLING)
- mbm_get_ip_details(gc);
-
- break;
-
- case MBM_E2NAP_CONNECTING:
- ofono_debug("MBM Context: connecting");
- break;
-
- default:
- break;
- };
-
- gcd->enap = state;
+ mbm_state_changed(gc, state);
}
static void mbm_e2nap_cb(gboolean ok, GAtResult *result, gpointer user_data)
@@ -392,6 +448,11 @@ static void mbm_gprs_context_remove(struct ofono_gprs_context *gc)
{
struct gprs_context_data *gcd = ofono_gprs_context_get_data(gc);
+ if (gcd->enap_source) {
+ g_source_remove(gcd->enap_source);
+ gcd->enap_source = 0;
+ }
+
ofono_gprs_context_set_data(gc, NULL);
g_free(gcd);
}