sim: Reorder SIM initialization

This commit is contained in:
Denis Kenzior 2010-08-23 13:36:37 -05:00
parent cbf783c334
commit 38300af0da
1 changed files with 95 additions and 98 deletions

193
src/sim.c
View File

@ -872,53 +872,6 @@ check:
sim->new_numbers = NULL;
}
static void sim_ad_read_cb(int ok, int length, int record,
const unsigned char *data,
int record_length, void *userdata)
{
struct ofono_sim *sim = userdata;
DBusConnection *conn = ofono_dbus_get_connection();
const char *path = __ofono_atom_get_path(sim->atom);
int new_mnc_length;
char mcc[OFONO_MAX_MCC_LENGTH + 1];
char mnc[OFONO_MAX_MNC_LENGTH + 1];
const char *str;
if (!ok)
return;
if (length < 4)
return;
new_mnc_length = data[3] & 0xf;
/* sanity check for potential invalid values */
if (new_mnc_length < 2 || new_mnc_length > 3)
return;
if (sim->mnc_length == new_mnc_length)
return;
sim->mnc_length = new_mnc_length;
strncpy(mcc, sim->imsi, OFONO_MAX_MCC_LENGTH);
mcc[OFONO_MAX_MCC_LENGTH] = '\0';
strncpy(mnc, sim->imsi + OFONO_MAX_MCC_LENGTH, sim->mnc_length);
mnc[sim->mnc_length] = '\0';
str = mcc;
ofono_dbus_signal_property_changed(conn, path,
OFONO_SIM_MANAGER_INTERFACE,
"MobileCountryCode",
DBUS_TYPE_STRING, &str);
str = mnc;
ofono_dbus_signal_property_changed(conn, path,
OFONO_SIM_MANAGER_INTERFACE,
"MobileNetworkCode",
DBUS_TYPE_STRING, &str);
}
static gint service_number_compare(gconstpointer a, gconstpointer b)
{
const struct service_number *sdn = a;
@ -1014,35 +967,10 @@ static void sim_ready(void *user, enum ofono_sim_state new_state)
sim_own_numbers_update(sim);
ofono_sim_read(sim, SIM_EFAD_FILEID,
OFONO_SIM_FILE_STRUCTURE_TRANSPARENT,
sim_ad_read_cb, sim);
ofono_sim_read(sim, SIM_EFSDN_FILEID, OFONO_SIM_FILE_STRUCTURE_FIXED,
sim_sdn_read_cb, sim);
}
static void sim_cphs_information_read_cb(int ok, int length, int record,
const unsigned char *data,
int record_length, void *userdata)
{
struct ofono_sim *sim = userdata;
sim->cphs_phase = OFONO_SIM_CPHS_PHASE_NONE;
if (!ok || length < 3)
goto ready;
if (data[0] == 0x01)
sim->cphs_phase = OFONO_SIM_CPHS_PHASE_1G;
else if (data[0] >= 0x02)
sim->cphs_phase = OFONO_SIM_CPHS_PHASE_2G;
memcpy(sim->cphs_service_table, data + 1, 2);
ready:
sim_set_ready(sim);
}
static void sim_imsi_cb(const struct ofono_error *error, const char *imsi,
void *data)
{
@ -1062,11 +990,30 @@ static void sim_imsi_cb(const struct ofono_error *error, const char *imsi,
"SubscriberIdentity",
DBUS_TYPE_STRING, &sim->imsi);
/* Read CPHS-support bits, this is still part of the SIM
* initialisation but no order is specified for it. */
ofono_sim_read(sim, SIM_EF_CPHS_INFORMATION_FILEID,
OFONO_SIM_FILE_STRUCTURE_TRANSPARENT,
sim_cphs_information_read_cb, sim);
if (sim->mnc_length) {
char mcc[OFONO_MAX_MCC_LENGTH + 1];
char mnc[OFONO_MAX_MNC_LENGTH + 1];
const char *str;
strncpy(mcc, sim->imsi, OFONO_MAX_MCC_LENGTH);
mcc[OFONO_MAX_MCC_LENGTH] = '\0';
strncpy(mnc, sim->imsi + OFONO_MAX_MCC_LENGTH, sim->mnc_length);
mnc[sim->mnc_length] = '\0';
str = mcc;
ofono_dbus_signal_property_changed(conn, path,
OFONO_SIM_MANAGER_INTERFACE,
"MobileCountryCode",
DBUS_TYPE_STRING, &str);
str = mnc;
ofono_dbus_signal_property_changed(conn, path,
OFONO_SIM_MANAGER_INTERFACE,
"MobileNetworkCode",
DBUS_TYPE_STRING, &str);
}
sim_set_ready(sim);
}
static void sim_retrieve_imsi(struct ofono_sim *sim)
@ -1128,8 +1075,62 @@ out:
sim_retrieve_imsi(sim);
}
static inline void sim_retrieve_efust(struct ofono_sim *sim)
static void sim_cphs_information_read_cb(int ok, int length, int record,
const unsigned char *data,
int record_length, void *userdata)
{
struct ofono_sim *sim = userdata;
sim->cphs_phase = OFONO_SIM_CPHS_PHASE_NONE;
if (!ok || length < 3)
return;
if (data[0] == 0x01)
sim->cphs_phase = OFONO_SIM_CPHS_PHASE_1G;
else if (data[0] >= 0x02)
sim->cphs_phase = OFONO_SIM_CPHS_PHASE_2G;
memcpy(sim->cphs_service_table, data + 1, 2);
}
static void sim_ad_read_cb(int ok, int length, int record,
const unsigned char *data,
int record_length, void *userdata)
{
struct ofono_sim *sim = userdata;
int new_mnc_length;
if (!ok)
return;
if (length < 4)
return;
new_mnc_length = data[3] & 0xf;
/* sanity check for potential invalid values */
if (new_mnc_length < 2 || new_mnc_length > 3)
return;
sim->mnc_length = new_mnc_length;
}
static void sim_initialize_after_pin(struct ofono_sim *sim)
{
ofono_sim_read(sim, SIM_EFAD_FILEID,
OFONO_SIM_FILE_STRUCTURE_TRANSPARENT,
sim_ad_read_cb, sim);
/*
* Read CPHS-support bits, this is still part of the SIM
* initialisation but no order is specified for it.
*/
ofono_sim_read(sim, SIM_EF_CPHS_INFORMATION_FILEID,
OFONO_SIM_FILE_STRUCTURE_TRANSPARENT,
sim_cphs_information_read_cb, sim);
/* Also retrieve the GSM service table */
ofono_sim_read(sim, SIM_EFUST_FILEID,
OFONO_SIM_FILE_STRUCTURE_TRANSPARENT,
sim_efust_read_cb, sim);
@ -1169,13 +1170,13 @@ static void sim_pin_query_cb(const struct ofono_error *error,
checkdone:
if (pin_type == OFONO_SIM_PASSWORD_NONE)
sim_retrieve_efust(sim);
sim_initialize_after_pin(sim);
}
static void sim_pin_check(struct ofono_sim *sim)
{
if (!sim->driver->query_passwd_state) {
sim_retrieve_efust(sim);
sim_initialize_after_pin(sim);
return;
}
@ -1363,23 +1364,8 @@ skip_efpl:
"PreferredLanguages",
DBUS_TYPE_STRING,
&sim->language_prefs);
}
static void sim_retrieve_efli_and_efpl(struct ofono_sim *sim)
{
/* According to 31.102 the EFli is read first and EFpl is then
* only read if none of the EFli languages are supported by user
* interface. 51.011 mandates the exact opposite, making EFpl/EFelp
* preferred over EFlp (same EFid as EFli, different format).
* However we don't depend on the user interface and so
* need to read both files now.
*/
ofono_sim_read(sim, SIM_EFLI_FILEID,
OFONO_SIM_FILE_STRUCTURE_TRANSPARENT,
sim_efli_read_cb, sim);
ofono_sim_read(sim, SIM_EFPL_FILEID,
OFONO_SIM_FILE_STRUCTURE_TRANSPARENT,
sim_efpl_read_cb, sim);
sim_pin_check(sim);
}
static void sim_iccid_read_cb(int ok, int length, int record,
@ -1420,8 +1406,19 @@ static void sim_efphase_read_cb(const struct ofono_error *error,
OFONO_SIM_FILE_STRUCTURE_TRANSPARENT,
sim_iccid_read_cb, sim);
sim_retrieve_efli_and_efpl(sim);
sim_pin_check(sim);
/* According to 31.102 the EFli is read first and EFpl is then
* only read if none of the EFli languages are supported by user
* interface. 51.011 mandates the exact opposite, making EFpl/EFelp
* preferred over EFlp (same EFid as EFli, different format).
* However we don't depend on the user interface and so
* need to read both files now.
*/
ofono_sim_read(sim, SIM_EFLI_FILEID,
OFONO_SIM_FILE_STRUCTURE_TRANSPARENT,
sim_efli_read_cb, sim);
ofono_sim_read(sim, SIM_EFPL_FILEID,
OFONO_SIM_FILE_STRUCTURE_TRANSPARENT,
sim_efpl_read_cb, sim);
}
static void sim_determine_phase(struct ofono_sim *sim)