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

_______________________________________________
ofono mailing list
ofono@ofono.org
http://lists.ofono.org/listinfo/ofono

Reply via email to