From e4fda1e36d241a8dba5088edc9debe54539e4cd3 Mon Sep 17 00:00:00 2001 From: Denis Kenzior Date: Thu, 14 Apr 2011 13:20:07 -0500 Subject: [PATCH] network: Read EFcsp after initializing reg state This is to avoid some benign race conditions when EFcsp might be read before the registration state has been established. --- src/network.c | 84 +++++++++++++++++++++++++-------------------------- 1 file changed, 42 insertions(+), 42 deletions(-) diff --git a/src/network.c b/src/network.c index 2865b165..19e2bcac 100644 --- a/src/network.c +++ b/src/network.c @@ -1390,6 +1390,43 @@ void ofono_netreg_time_notify(struct ofono_netreg *netreg, __ofono_nettime_info_received(modem, info); } +static void sim_csp_read_cb(int ok, int length, int record, + const unsigned char *data, + int record_length, void *user_data) +{ + struct ofono_netreg *netreg = user_data; + int i; + + if (!ok) + return; + + if (length < 18 || record_length < 18 || length < record_length) + return; + + /* + * According to CPHS 4.2, EFcsp is an array of two-byte service + * entries, each consisting of a one byte service group + * identifier followed by 8 bits; each bit is indicating + * availability of a specific service or feature. + * + * The PLMN mode bit, if present, indicates whether manual + * operator selection should be disabled or enabled. When + * unset, the device is forced to automatic mode; when set, + * manual selection is to be enabled. The latter is also the + * default. + */ + for (i = 0; i < record_length / 2; i++) { + + if (data[i * 2] != SIM_CSP_ENTRY_VALUE_ADDED_SERVICES) + continue; + + if ((data[i * 2 + 1] & 0x80) != 0) + return; + + set_registration_mode(netreg, + NETWORK_REGISTRATION_MODE_AUTO_ONLY); + } +} static void init_registration_status(const struct ofono_error *error, int status, int lac, int ci, int tech, @@ -1423,6 +1460,11 @@ static void init_registration_status(const struct ofono_error *error, netreg->driver->register_auto(netreg, init_register, netreg); } + + if (netreg->sim_context) + ofono_sim_read(netreg->sim_context, SIM_EF_CPHS_CSP_FILEID, + OFONO_SIM_FILE_STRUCTURE_TRANSPARENT, + sim_csp_read_cb, netreg); } static void notify_emulator_strength(struct ofono_atom *atom, void *data) @@ -1643,44 +1685,6 @@ static void sim_spn_read_cb(int ok, int length, int record, } } -static void sim_csp_read_cb(int ok, int length, int record, - const unsigned char *data, - int record_length, void *user_data) -{ - struct ofono_netreg *netreg = user_data; - int i; - - if (!ok) - return; - - if (length < 18 || record_length < 18 || length < record_length) - return; - - /* - * According to CPHS 4.2, EFcsp is an array of two-byte service - * entries, each consisting of a one byte service group - * identifier followed by 8 bits; each bit is indicating - * availability of a specific service or feature. - * - * The PLMN mode bit, if present, indicates whether manual - * operator selection should be disabled or enabled. When - * unset, the device is forced to automatic mode; when set, - * manual selection is to be enabled. The latter is also the - * default. - */ - for (i = 0; i < record_length / 2; i++) { - - if (data[i * 2] != SIM_CSP_ENTRY_VALUE_ADDED_SERVICES) - continue; - - if ((data[i * 2 + 1] & 0x80) != 0) - return; - - set_registration_mode(netreg, - NETWORK_REGISTRATION_MODE_AUTO_ONLY); - } -} - int ofono_netreg_get_location(struct ofono_netreg *netreg) { if (netreg == NULL) @@ -2082,10 +2086,6 @@ void ofono_netreg_register(struct ofono_netreg *netreg) ofono_sim_add_file_watch(netreg->sim_context, SIM_EFSPDI_FILEID, sim_spn_spdi_changed, netreg, NULL); - - ofono_sim_read(netreg->sim_context, SIM_EF_CPHS_CSP_FILEID, - OFONO_SIM_FILE_STRUCTURE_TRANSPARENT, - sim_csp_read_cb, netreg); } __ofono_atom_register(netreg->atom, netreg_unregister);