Watch netreg status update to notify DUN client, such as +CREG
unsolicited result.
---
src/emulator.c | 106 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 106 insertions(+), 0 deletions(-)
diff --git a/src/emulator.c b/src/emulator.c
index c8f3d65..56edab6 100644
--- a/src/emulator.c
+++ b/src/emulator.c
@@ -56,6 +56,9 @@ struct modem_settings {
int cops;
int attached;
int gprs_status;
+ int netreg_status;
+ int netreg_lac;
+ int netreg_ci;
};
struct ofono_emulator {
@@ -72,6 +75,9 @@ struct ofono_emulator {
struct ofono_gprs *gprs;
unsigned int gprs_watch;
unsigned int gprs_status_watch;
+ struct ofono_netreg *netreg;
+ unsigned int netreg_watch;
+ unsigned int netreg_status_watch;
};
static unsigned int ofono_emulator_ids;
@@ -254,12 +260,19 @@ static void creg_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), "+CREG: %d, %x, %x, %x",
+ e->settings.creg,
+ e->settings.netreg_status,
+ e->settings.netreg_lac,
+ e->settings.netreg_ci);
+ 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:
@@ -800,6 +813,86 @@ static void add_gprs_watches(struct ofono_emulator *e)
OFONO_ATOM_WATCH_CONDITION_REGISTERED, e);
}
+static void emulator_netreg_update(struct ofono_emulator *e)
+{
+ GAtServer *server = e->server;
+ char buf[256];
+
+ switch (e->settings.creg) {
+ case 0:
+ break;
+ case 1:
+ snprintf(buf, sizeof(buf), "+CREG: %d",
+ e->settings.netreg_status);
+ g_at_server_send_unsolicited(server, buf);
+ break;
+ case 2:
+ snprintf(buf, sizeof(buf), "+CREG: %d, %x, %x",
+ e->settings.netreg_status,
+ e->settings.netreg_lac,
+ e->settings.netreg_ci);
+ g_at_server_send_unsolicited(server, buf);
+ break;
+ default:
+ break;
+ }
+}
+
+static void netreg_status_changed(int status, int lac, int ci, int tech,
+ const char *mcc, const char *mnc,
+ void *data)
+{
+ struct ofono_emulator *e = data;
+
+ DBG("%d %d %d", status, lac, ci);
+
+ e->settings.netreg_status = status;
+ e->settings.netreg_lac = lac;
+ e->settings.netreg_ci = ci;
+
+ emulator_netreg_update(e);
+}
+
+static void netreg_watch(struct ofono_atom *atom,
+ enum ofono_atom_watch_condition cond,
+ void *data)
+{
+ struct ofono_emulator *e = data;
+ struct ofono_netreg *netreg;
+
+ if (cond == OFONO_ATOM_WATCH_CONDITION_UNREGISTERED) {
+ e->netreg_status_watch = 0;
+ e->netreg = NULL;
+ return;
+ }
+
+ netreg = __ofono_atom_get_data(atom);
+ e->netreg = netreg;
+ e->settings.netreg_status = ofono_netreg_get_status(netreg);
+ e->settings.netreg_lac = ofono_netreg_get_location(netreg);
+ e->settings.netreg_ci = ofono_netreg_get_cellid(netreg);
+ e->netreg_status_watch = __ofono_netreg_add_status_watch(e->netreg,
+ netreg_status_changed, e, NULL);
+
+ emulator_netreg_update(e);
+}
+
+static void add_netreg_watches(struct ofono_emulator *e)
+{
+ struct ofono_modem *modem = e->modem;
+ struct ofono_atom *netreg_atom;
+
+ e->netreg_watch = __ofono_modem_add_atom_watch(modem,
+ OFONO_ATOM_TYPE_NETREG,
+ netreg_watch, e, NULL);
+
+ netreg_atom = __ofono_modem_find_atom(modem, OFONO_ATOM_TYPE_NETREG);
+
+ if (netreg_atom && __ofono_atom_get_registered(netreg_atom))
+ netreg_watch(netreg_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)
@@ -859,6 +952,18 @@ static void emulator_unregister(struct ofono_atom *atom)
e->gprs_watch = 0;
e->gprs = NULL;
}
+
+ if (e->netreg_watch) {
+ if (e->netreg_status_watch) {
+ __ofono_netreg_remove_status_watch(e->netreg,
+ e->netreg_status_watch);
+ e->netreg_status_watch = 0;
+ }
+
+ __ofono_modem_remove_atom_watch(e->modem, e->netreg_watch);
+ e->netreg_watch = 0;
+ e->netreg = NULL;
+ }
}
struct ofono_emulator *ofono_emulator_create(struct ofono_modem *modem,
@@ -901,6 +1006,7 @@ struct ofono_emulator *ofono_emulator_create(struct ofono_modem
*modem,
g_at_server_register(e->server, "+CGDCONT", cgdcont_cb, e, NULL);
add_gprs_watches(e);
+ add_netreg_watches(e);
return e;
}
--
1.7.0.4