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.
This commit is contained in:
Denis Kenzior 2011-04-14 13:20:07 -05:00
parent 49928bece3
commit e4fda1e36d
1 changed files with 42 additions and 42 deletions

View File

@ -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);