Hi Oleg,
On 01/09/2012 04:30 AM, Oleg Zhurakivskyy wrote:
---
src/gprs.c | 105 ++++++++++++++++++++++++++++++++++++------------------------
1 files changed, 63 insertions(+), 42 deletions(-)
diff --git a/src/gprs.c b/src/gprs.c
index 4e46743..c4ea974 100644
--- a/src/gprs.c
+++ b/src/gprs.c
@@ -94,7 +94,9 @@ struct ofono_gprs {
const struct ofono_gprs_driver *driver;
void *driver_data;
struct ofono_atom *atom;
- struct ofono_sim_context *sim_context;
+ struct ofono_sim *sim;
+ unsigned int sim_watch;
This is actually not necessary, the sim atom is always guaranteed to be
there prior to the gprs atom.
+ unsigned int spn_watch;
};
struct ipv4_settings {
@@ -2502,6 +2504,39 @@ static void free_contexts(struct ofono_gprs *gprs)
g_slist_free(gprs->contexts);
}
+static inline void sim_unregister(struct ofono_gprs *gprs,
+ unsigned int *spn_watch, unsigned int *sim_watch,
+ struct ofono_sim **sim)
+{
+ if (gprs->sim == NULL)
+ return;
+
+ if (*spn_watch)
+ ofono_sim_remove_spn_watch(*sim, spn_watch);
+
+ if (*sim_watch) {
+ __ofono_modem_remove_atom_watch(
+ __ofono_atom_get_modem(gprs->atom), *sim_watch);
+ *sim_watch = 0;
+ }
So all you really need here is this statement moved down to gprs_unregister
+
+ if (*sim)
+ *sim = NULL;
+}
+
+static void sim_watch(struct ofono_atom *atom,
+ enum ofono_atom_watch_condition cond, void *data)
+{
+ struct ofono_gprs *gprs = data;
+
+ if (cond == OFONO_ATOM_WATCH_CONDITION_UNREGISTERED) {
+ sim_unregister(gprs, &gprs->spn_watch, NULL, &gprs->sim);
+ return;
+ }
+
+ gprs->sim = __ofono_atom_get_data(atom);
+}
+
This isn't needed
static void gprs_unregister(struct ofono_atom *atom)
{
DBusConnection *conn = ofono_dbus_get_connection();
@@ -2513,6 +2548,9 @@ static void gprs_unregister(struct ofono_atom *atom)
free_contexts(gprs);
+ if (gprs->sim && gprs->spn_watch)
+ sim_unregister(gprs, &gprs->spn_watch, NULL, NULL);
+
if (gprs->cid_map) {
idmap_free(gprs->cid_map);
gprs->cid_map = NULL;
@@ -2554,6 +2592,10 @@ static void gprs_remove(struct ofono_atom *atom)
gprs->pid_map = NULL;
}
+ if (gprs->sim)
+ sim_unregister(gprs, &gprs->spn_watch, &gprs->sim_watch,
+ &gprs->sim);
Why do you have this here and in gprs_unregister?
+
for (l = gprs->context_drivers; l; l = l->next) {
struct ofono_gprs_context *gc = l->data;
@@ -2565,9 +2607,6 @@ 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);
}
@@ -2605,6 +2644,9 @@ struct ofono_gprs *ofono_gprs_create(struct ofono_modem *modem,
gprs->netreg_status = NETWORK_REGISTRATION_STATUS_UNKNOWN;
gprs->pid_map = idmap_new(MAX_CONTEXTS);
+ gprs->sim_watch = __ofono_modem_add_atom_watch(modem,
+ OFONO_ATOM_TYPE_SIM, sim_watch, gprs, NULL);
+
return gprs;
}
@@ -2955,57 +2997,36 @@ static void ofono_gprs_finish_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)
+static void spn_read_cb(const char *spn, const char *dc, void *data)
{
- struct ofono_gprs *gprs = userdata;
- char *spn = NULL;
- struct ofono_atom *sim_atom;
- struct ofono_sim *sim = NULL;
+ struct ofono_gprs *gprs = data;
+
+ if (gprs->spn_watch == 0)
+ return;
Not sure I follow why you need this?
- if (ok)
- spn = sim_string_to_utf8(data + 1, length - 1);
+ ofono_sim_remove_spn_watch(gprs->sim, &gprs->spn_watch);
- 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);
- }
+ if (gprs->sim != NULL && spn != NULL)
And this might be overly paranoid given that you're getting called by
the sim atom.
I tend to like the philosophy of 'crash early'. This lets you know very
quickly if something is wrong without obfuscating the cause.
+ provision_contexts(gprs, ofono_sim_get_mcc(gprs->sim),
+ ofono_sim_get_mnc(gprs->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->sim == NULL)
+ ofono_gprs_finish_register(gprs);
- if (gprs->contexts == NULL && sim != NULL) {
- /* Get Service Provider Name from SIM for provisioning */
- gprs->sim_context = ofono_sim_context_create(sim);
+ gprs_load_settings(gprs, ofono_sim_get_imsi(gprs->sim));
If sim is null we still try to load the settings? Wouldn't this crash?
- if (ofono_sim_read(gprs->sim_context, SIM_EFSPN_FILEID,
- OFONO_SIM_FILE_STRUCTURE_TRANSPARENT,
- sim_spn_read_cb, gprs) >= 0)
- return;
+ if (gprs->contexts) {
+ ofono_gprs_finish_register(gprs);
+ return;
}
- ofono_gprs_finish_register(gprs);
+ ofono_sim_add_spn_watch(gprs->sim, &gprs->spn_watch, spn_read_cb,
+ gprs, NULL);
And this is probably useless if the sim atom isn't around...
}
void ofono_gprs_remove(struct ofono_gprs *gprs)
Regards,
-Denis