Watch GPRS status update to notify DUN client, such as +CGREG
unsolicited result.
---
src/emulator.c | 94 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 94 insertions(+), 0 deletions(-)
diff --git a/src/emulator.c b/src/emulator.c
index 8811f6c..c8f3d65 100644
--- a/src/emulator.c
+++ b/src/emulator.c
@@ -55,6 +55,7 @@ struct modem_settings {
int cgreg;
int cops;
int attached;
+ int gprs_status;
};
struct ofono_emulator {
@@ -68,6 +69,9 @@ struct ofono_emulator {
struct modem_settings settings;
enum ofono_emulator_status status;
struct ofono_watchlist *status_watches;
+ struct ofono_gprs *gprs;
+ unsigned int gprs_watch;
+ unsigned int gprs_status_watch;
};
static unsigned int ofono_emulator_ids;
@@ -294,12 +298,16 @@ static void cgreg_cb(GAtServerRequestType type, GAtResult *result,
gpointer user_data)
{
struct ofono_emulator *e = user_data;
+ char buf[256];
switch (type) {
case G_AT_SERVER_REQUEST_TYPE_SUPPORT:
ofono_emulator_send_final(e, G_AT_SERVER_RESULT_OK);
break;
case G_AT_SERVER_REQUEST_TYPE_QUERY:
+ snprintf(buf, sizeof(buf), "+CGREG: %d, %d", e->settings.cgreg,
+ e->settings.gprs_status);
+ ofono_emulator_send_info(e, buf, TRUE);
ofono_emulator_send_final(e, G_AT_SERVER_RESULT_OK);
break;
case G_AT_SERVER_REQUEST_TYPE_SET:
@@ -720,6 +728,78 @@ static void emulator_remove(struct ofono_atom *atom)
e = NULL;
}
+static void emulator_gprs_update(struct ofono_emulator *e)
+{
+ GAtServer *server = e->server;
+ char buf[256];
+
+ switch (e->settings.cgreg) {
+ case 0:
+ break;
+ case 1:
+ snprintf(buf, sizeof(buf), "+CGREG: %d",
+ e->settings.gprs_status);
+ g_at_server_send_unsolicited(server, buf);
+ break;
+ case 2:
+ snprintf(buf, sizeof(buf), "+CGREG: %d",
+ e->settings.gprs_status);
+ g_at_server_send_unsolicited(server, buf);
+ break;
+ default:
+ break;
+ }
+}
+
+static void gprs_status_changed(int status, void *data)
+{
+ struct ofono_emulator *e = data;
+
+ DBG("%d", status);
+
+ e->settings.gprs_status = status;
+
+ emulator_gprs_update(e);
+}
+
+static void gprs_watch(struct ofono_atom *atom,
+ enum ofono_atom_watch_condition cond,
+ void *data)
+{
+ struct ofono_emulator *e = data;
+ struct ofono_gprs *gprs;
+
+ if (cond == OFONO_ATOM_WATCH_CONDITION_UNREGISTERED) {
+ e->gprs_status_watch = 0;
+ e->gprs = NULL;
+ return;
+ }
+
+ gprs = __ofono_atom_get_data(atom);
+ e->gprs = gprs;
+ e->settings.gprs_status = ofono_gprs_get_status(gprs);
+ e->gprs_status_watch = __ofono_gprs_add_status_watch(e->gprs,
+ gprs_status_changed, e, NULL);
+
+ emulator_gprs_update(e);
+}
+
+static void add_gprs_watches(struct ofono_emulator *e)
+{
+ struct ofono_modem *modem = e->modem;
+ struct ofono_atom *gprs_atom;
+
+ e->gprs_watch = __ofono_modem_add_atom_watch(modem,
+ OFONO_ATOM_TYPE_GPRS,
+ gprs_watch, e, NULL);
+
+ gprs_atom = __ofono_modem_find_atom(modem, OFONO_ATOM_TYPE_GPRS);
+
+ if (gprs_atom && __ofono_atom_get_registered(gprs_atom))
+ gprs_watch(gprs_atom,
+ OFONO_ATOM_WATCH_CONDITION_REGISTERED, e);
+}
+
unsigned int __ofono_emulator_add_status_watch(struct ofono_emulator *e,
ofono_emulator_status_notify_cb_t notify,
void *data, ofono_destroy_func destroy)
@@ -767,6 +847,18 @@ static void emulator_unregister(struct ofono_atom *atom)
g_at_ppp_unref(e->ppp);
e->ppp = NULL;
}
+
+ if (e->gprs_watch) {
+ if (e->gprs_status_watch) {
+ __ofono_gprs_remove_status_watch(e->gprs,
+ e->gprs_status_watch);
+ e->gprs_status_watch = 0;
+ }
+
+ __ofono_modem_remove_atom_watch(e->modem, e->gprs_watch);
+ e->gprs_watch = 0;
+ e->gprs = NULL;
+ }
}
struct ofono_emulator *ofono_emulator_create(struct ofono_modem *modem,
@@ -808,5 +900,7 @@ struct ofono_emulator *ofono_emulator_create(struct ofono_modem
*modem,
g_at_server_register(e->server, "+CGATT", cgatt_cb, e, NULL);
g_at_server_register(e->server, "+CGDCONT", cgdcont_cb, e, NULL);
+ add_gprs_watches(e);
+
return e;
}
--
1.7.0.4