---
 src/gprs-provision.c |    4 +-
 src/gprs.c           |   87 +++++++++++++++++++++++++++++++++++++------------
 src/ofono.h          |    2 +-
 3 files changed, 68 insertions(+), 25 deletions(-)

diff --git a/src/gprs-provision.c b/src/gprs-provision.c
index 3cd84e8..011d5a8 100644
--- a/src/gprs-provision.c
+++ b/src/gprs-provision.c
@@ -48,7 +48,7 @@ void  __ofono_gprs_provision_free_settings(
 }
 
 ofono_bool_t __ofono_gprs_provision_get_settings(const char *mcc,
-                               const char *mnc,
+                               const char *mnc, const char *spn,
                                struct ofono_gprs_provision_data **settings,
                                int *count)
 {
@@ -65,7 +65,7 @@ ofono_bool_t __ofono_gprs_provision_get_settings(const char 
*mcc,
 
                DBG("Calling provisioning plugin '%s'", driver->name);
 
-               if (driver->get_settings(mcc, mnc, settings, count) < 0)
+               if (driver->get_settings(mcc, mnc, spn, settings, count) < 0)
                        continue;
 
                return TRUE;
diff --git a/src/gprs.c b/src/gprs.c
index 5ea864c..bb1b173 100644
--- a/src/gprs.c
+++ b/src/gprs.c
@@ -97,6 +97,7 @@ struct ofono_gprs {
        const struct ofono_gprs_driver *driver;
        void *driver_data;
        struct ofono_atom *atom;
+       struct ofono_sim_context *sim_context;
 };
 
 struct ofono_gprs_context {
@@ -2291,6 +2292,9 @@ static void gprs_remove(struct ofono_atom *atom)
        if (gprs->driver && gprs->driver->remove)
                gprs->driver->remove(gprs);
 
+       if (gprs->sim_context)
+               ofono_sim_context_free(gprs->sim_context);
+
        g_free(gprs);
 }
 
@@ -2627,14 +2631,14 @@ static void provision_context(const struct 
ofono_gprs_provision_data *ap,
        gprs->contexts = g_slist_append(gprs->contexts, context);
 }
 
-static void provision_contexts(struct ofono_gprs *gprs, struct ofono_sim *sim)
+static void provision_contexts(struct ofono_gprs *gprs, const char *mcc,
+                               const char *mnc, const char *spn)
 {
        struct ofono_gprs_provision_data *settings;
        int count;
        int i;
 
-       if (__ofono_gprs_provision_get_settings(ofono_sim_get_mcc(sim),
-                                               ofono_sim_get_mnc(sim),
+       if (__ofono_gprs_provision_get_settings(mcc, mnc, spn,
                                                &settings, &count) == FALSE) {
                ofono_warn("Provisioning failed");
                return;
@@ -2646,13 +2650,15 @@ static void provision_contexts(struct ofono_gprs *gprs, 
struct ofono_sim *sim)
        __ofono_gprs_provision_free_settings(settings, count);
 }
 
-void ofono_gprs_register(struct ofono_gprs *gprs)
+static void ofono_gprs_finish_register(struct ofono_gprs *gprs)
 {
        DBusConnection *conn = ofono_dbus_get_connection();
        struct ofono_modem *modem = __ofono_atom_get_modem(gprs->atom);
        const char *path = __ofono_atom_get_path(gprs->atom);
        struct ofono_atom *netreg_atom;
-       struct ofono_atom *sim_atom;
+
+       if (gprs->contexts == NULL) /* Automatic provisioning failed */
+               add_context(gprs, NULL, OFONO_GPRS_CONTEXT_TYPE_INTERNET);
 
        if (!g_dbus_register_interface(conn, path,
                                        OFONO_CONNECTION_MANAGER_INTERFACE,
@@ -2661,29 +2667,13 @@ void ofono_gprs_register(struct ofono_gprs *gprs)
                ofono_error("Could not create %s interface",
                                OFONO_CONNECTION_MANAGER_INTERFACE);
 
+               gprs_unregister(gprs->atom);
                return;
        }
 
        ofono_modem_add_interface(modem,
                                OFONO_CONNECTION_MANAGER_INTERFACE);
 
-       sim_atom = __ofono_modem_find_atom(modem, OFONO_ATOM_TYPE_SIM);
-
-       if (sim_atom) {
-               const char *imsi;
-               struct ofono_sim *sim = __ofono_atom_get_data(sim_atom);
-
-               imsi = ofono_sim_get_imsi(sim);
-               gprs_load_settings(gprs, imsi);
-
-               if (gprs->contexts == NULL)
-                       provision_contexts(gprs, sim);
-
-       }
-
-       if (gprs->contexts == NULL)
-               add_context(gprs, NULL, OFONO_GPRS_CONTEXT_TYPE_INTERNET);
-
        gprs->netreg_watch = __ofono_modem_add_atom_watch(modem,
                                        OFONO_ATOM_TYPE_NETREG,
                                        netreg_watch, gprs, NULL);
@@ -2697,6 +2687,59 @@ void ofono_gprs_register(struct ofono_gprs *gprs)
        __ofono_atom_register(gprs->atom, gprs_unregister);
 }
 
+static void sim_spn_read_cb(int ok, int length, int record,
+                               const unsigned char *data,
+                               int record_length, void *userdata)
+{
+       struct ofono_gprs *gprs = userdata;
+       char *spn = NULL;
+       struct ofono_atom *sim_atom;
+       struct ofono_sim *sim = NULL;
+
+       if (ok)
+               spn = sim_string_to_utf8(data + 1, length - 1);
+
+       sim_atom = __ofono_modem_find_atom(__ofono_atom_get_modem(gprs->atom),
+                                               OFONO_ATOM_TYPE_SIM);
+       if (sim_atom) {
+               sim = __ofono_atom_get_data(sim_atom);
+               provision_contexts(gprs, ofono_sim_get_mcc(sim),
+                                       ofono_sim_get_mnc(sim), spn);
+       }
+
+       g_free(spn);
+       ofono_gprs_finish_register(gprs);
+}
+
+void ofono_gprs_register(struct ofono_gprs *gprs)
+{
+       struct ofono_modem *modem = __ofono_atom_get_modem(gprs->atom);
+       struct ofono_atom *sim_atom;
+       struct ofono_sim *sim = NULL;
+
+       sim_atom = __ofono_modem_find_atom(modem, OFONO_ATOM_TYPE_SIM);
+
+       if (sim_atom) {
+               const char *imsi;
+               sim = __ofono_atom_get_data(sim_atom);
+
+               imsi = ofono_sim_get_imsi(sim);
+               gprs_load_settings(gprs, imsi);
+       }
+
+       if (gprs->contexts == NULL && sim != NULL) {
+               /* Get Service Provider Name from SIM for provisioning */
+               gprs->sim_context = ofono_sim_context_create(sim);
+
+               if (ofono_sim_read(gprs->sim_context, SIM_EFSPN_FILEID,
+                               OFONO_SIM_FILE_STRUCTURE_TRANSPARENT,
+                                       sim_spn_read_cb, gprs) >= 0)
+                       return;
+       }
+
+       ofono_gprs_finish_register(gprs);
+}
+
 void ofono_gprs_remove(struct ofono_gprs *gprs)
 {
        __ofono_atom_free(gprs->atom);
diff --git a/src/ofono.h b/src/ofono.h
index 6ba0187..0cdebf7 100644
--- a/src/ofono.h
+++ b/src/ofono.h
@@ -424,7 +424,7 @@ void __ofono_nettime_info_received(struct ofono_modem 
*modem,
 
 #include <ofono/gprs-provision.h>
 ofono_bool_t __ofono_gprs_provision_get_settings(const char *mcc,
-                               const char *mnc,
+                               const char *mnc, const char *spn,
                                struct ofono_gprs_provision_data **settings,
                                int *count);
 void __ofono_gprs_provision_free_settings(
-- 
1.7.1

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

Reply via email to