simfs: implement ofono_sim_context api

This commit is contained in:
Andrzej Zaborowski 2011-02-03 08:37:37 +01:00 committed by Denis Kenzior
parent 0ecc99973a
commit a7a0cb1ed0
8 changed files with 221 additions and 68 deletions

View File

@ -61,6 +61,7 @@ struct ofono_call_forwarding {
int query_end;
struct cf_ss_request *ss_req;
struct ofono_sim *sim;
struct ofono_sim_context *sim_context;
unsigned char cfis_record_id;
struct ofono_ussd *ussd;
unsigned int ussd_watch;
@ -276,7 +277,7 @@ static void sim_set_cf_indicator(struct ofono_call_forwarding *cf)
data[3] = 128;
}
ofono_sim_write(cf->sim, SIM_EFCFIS_FILEID,
ofono_sim_write(cf->sim_context, SIM_EFCFIS_FILEID,
sim_cfis_update_cb,
OFONO_SIM_FILE_STRUCTURE_FIXED,
cf->cfis_record_id, data,
@ -287,7 +288,7 @@ static void sim_set_cf_indicator(struct ofono_call_forwarding *cf)
if (cf->flags & CALL_FORWARDING_FLAG_CPHS_CFF) {
unsigned char cff_voice = cfu_voice ? 0x0A : 0x05;
ofono_sim_write(cf->sim, SIM_EF_CPHS_CFF_FILEID,
ofono_sim_write(cf->sim_context, SIM_EF_CPHS_CFF_FILEID,
sim_cphs_cff_update_cb,
OFONO_SIM_FILE_STRUCTURE_TRANSPARENT,
0, &cff_voice, sizeof(cff_voice), cf);
@ -1362,11 +1363,11 @@ static void sim_read_cf_indicator(struct ofono_call_forwarding *cf)
if (__ofono_sim_service_available(cf->sim,
SIM_UST_SERVICE_CFIS,
SIM_SST_SERVICE_CFIS) == TRUE)
ofono_sim_read(cf->sim, SIM_EFCFIS_FILEID,
ofono_sim_read(cf->sim_context, SIM_EFCFIS_FILEID,
OFONO_SIM_FILE_STRUCTURE_FIXED,
sim_cfis_read_cb, cf);
else
ofono_sim_read(cf->sim, SIM_EF_CPHS_CFF_FILEID,
ofono_sim_read(cf->sim_context, SIM_EF_CPHS_CFF_FILEID,
OFONO_SIM_FILE_STRUCTURE_TRANSPARENT,
sim_cphs_cff_read_cb, cf);
}
@ -1401,6 +1402,11 @@ static void call_forwarding_unregister(struct ofono_atom *atom)
g_dbus_unregister_interface(conn, path,
OFONO_CALL_FORWARDING_INTERFACE);
if (cf->sim_context) {
ofono_sim_context_free(cf->sim_context);
cf->sim_context = NULL;
}
if (cf->ussd)
cf_unregister_ss_controls(cf);
@ -1499,6 +1505,8 @@ void ofono_call_forwarding_register(struct ofono_call_forwarding *cf)
if (sim_atom) {
cf->sim = __ofono_atom_get_data(sim_atom);
cf->sim_context = ofono_sim_context_create(cf->sim);
sim_read_cf_indicator(cf);
}

View File

@ -57,6 +57,7 @@ struct ofono_cbs {
GSList *topics;
GSList *new_topics;
struct ofono_sim *sim;
struct ofono_sim_context *sim_context;
struct ofono_stk *stk;
struct ofono_netreg *netreg;
unsigned int netreg_watch;
@ -605,6 +606,11 @@ static void cbs_unregister(struct ofono_atom *atom)
cbs->efcbmid_contents = NULL;
}
if (cbs->sim_context) {
ofono_sim_context_free(cbs->sim_context);
cbs->sim_context = NULL;
}
cbs->sim = NULL;
cbs->stk = NULL;
@ -908,10 +914,10 @@ static void cbs_got_imsi(struct ofono_cbs *cbs)
*/
if (topics_str == NULL ||
(cbs->topics == NULL && topics_str[0] != '\0')) {
ofono_sim_read(cbs->sim, SIM_EFCBMI_FILEID,
ofono_sim_read(cbs->sim_context, SIM_EFCBMI_FILEID,
OFONO_SIM_FILE_STRUCTURE_TRANSPARENT,
sim_cbmi_read_cb, cbs);
ofono_sim_read(cbs->sim, SIM_EFCBMIR_FILEID,
ofono_sim_read(cbs->sim_context, SIM_EFCBMIR_FILEID,
OFONO_SIM_FILE_STRUCTURE_TRANSPARENT,
sim_cbmir_read_cb, cbs);
}
@ -919,7 +925,7 @@ static void cbs_got_imsi(struct ofono_cbs *cbs)
if (topics_str)
g_free(topics_str);
ofono_sim_read(cbs->sim, SIM_EFCBMID_FILEID,
ofono_sim_read(cbs->sim_context, SIM_EFCBMID_FILEID,
OFONO_SIM_FILE_STRUCTURE_TRANSPARENT,
sim_cbmid_read_cb, cbs);
}
@ -1067,6 +1073,8 @@ void ofono_cbs_register(struct ofono_cbs *cbs)
if (sim_atom) {
cbs->sim = __ofono_atom_get_data(sim_atom);
cbs->sim_context = ofono_sim_context_create(cbs->sim);
if (ofono_sim_get_state(cbs->sim) == OFONO_SIM_STATE_READY)
cbs_got_imsi(cbs);
}

View File

@ -55,6 +55,7 @@ struct ofono_message_waiting {
gboolean cphs_mbdn_not_provided;
struct ofono_phone_number mailbox_number[5];
struct ofono_sim *sim;
struct ofono_sim_context *sim_context;
struct ofono_atom *atom;
};
@ -202,7 +203,7 @@ static DBusMessage *set_cphs_mbdn(struct ofono_message_waiting *mw,
sim_adn_build(efmbdn, req->mw->ef_cphs_mbdn_length,
&req->number, NULL);
if (ofono_sim_write(mw->sim, SIM_EF_CPHS_MBDN_FILEID,
if (ofono_sim_write(mw->sim_context, SIM_EF_CPHS_MBDN_FILEID,
sync ? cphs_mbdn_sync_cb : mbdn_set_cb,
OFONO_SIM_FILE_STRUCTURE_FIXED,
mw_mailbox_to_cphs_record[mailbox],
@ -300,10 +301,10 @@ static DBusMessage *set_mbdn(struct ofono_message_waiting *mw, int mailbox,
sim_adn_build(efmbdn, req->mw->efmbdn_length, &req->number, NULL);
if (ofono_sim_write(req->mw->sim, SIM_EFMBDN_FILEID, mbdn_set_cb,
OFONO_SIM_FILE_STRUCTURE_FIXED,
req->mw->efmbdn_record_id[mailbox],
efmbdn, req->mw->efmbdn_length, req) == -1) {
if (ofono_sim_write(req->mw->sim_context, SIM_EFMBDN_FILEID,
mbdn_set_cb, OFONO_SIM_FILE_STRUCTURE_FIXED,
req->mw->efmbdn_record_id[mailbox],
efmbdn, req->mw->efmbdn_length, req) == -1) {
g_free(req);
if (msg)
@ -600,7 +601,7 @@ static void mw_mbi_read_cb(int ok, int total_length, int record,
for (i = 0; i < 5 && i < record_length; i++)
mw->efmbdn_record_id[i] = data[i];
err = ofono_sim_read(mw->sim, SIM_EFMBDN_FILEID,
err = ofono_sim_read(mw->sim_context, SIM_EFMBDN_FILEID,
OFONO_SIM_FILE_STRUCTURE_FIXED,
mw_mbdn_read_cb, mw);
@ -615,7 +616,7 @@ out:
st = ofono_sim_get_cphs_service_table(mw->sim);
if (st && bit_field(st[0], 4, 2) == 3)
ofono_sim_read(mw->sim, SIM_EF_CPHS_MBDN_FILEID,
ofono_sim_read(mw->sim_context, SIM_EF_CPHS_MBDN_FILEID,
OFONO_SIM_FILE_STRUCTURE_FIXED,
mw_cphs_mbdn_read_cb, mw);
}
@ -689,7 +690,8 @@ static void mw_set_indicator(struct ofono_message_waiting *mw, int profile,
if (mw->messages[i].indication)
efmwis[0] |= 1 << i;
if (ofono_sim_write(mw->sim, SIM_EFMWIS_FILEID, mw_mwis_write_cb,
if (ofono_sim_write(mw->sim_context, SIM_EFMWIS_FILEID,
mw_mwis_write_cb,
OFONO_SIM_FILE_STRUCTURE_FIXED, 1,
efmwis, mw->efmwis_length, mw) != 0) {
ofono_error("Queuing a EF-MWI write to SIM failed");
@ -707,7 +709,8 @@ try_cphs:
efmwis[1] = mw->messages[1].indication ? 0xa : 0x5 |
mw->messages[3].indication ? 0xa0 : 0x50;
if (ofono_sim_write(mw->sim, SIM_EF_CPHS_MWIS_FILEID, mw_mwis_write_cb,
if (ofono_sim_write(mw->sim_context, SIM_EF_CPHS_MWIS_FILEID,
mw_mwis_write_cb,
OFONO_SIM_FILE_STRUCTURE_TRANSPARENT, 0,
efmwis, mw->ef_cphs_mwis_length, mw) != 0)
ofono_error("Queuing a EF-MWIS write to SIM failed (CPHS)");
@ -918,6 +921,14 @@ static void message_waiting_unregister(struct ofono_atom *atom)
DBusConnection *conn = ofono_dbus_get_connection();
struct ofono_modem *modem = __ofono_atom_get_modem(atom);
const char *path = __ofono_atom_get_path(atom);
struct ofono_message_waiting *mw = __ofono_atom_get_data(atom);
if (mw->sim_context) {
ofono_sim_context_free(mw->sim_context);
mw->sim_context = NULL;
}
mw->sim = NULL;
g_dbus_unregister_interface(conn, path,
OFONO_MESSAGE_WAITING_INTERFACE);
@ -956,16 +967,18 @@ void ofono_message_waiting_register(struct ofono_message_waiting *mw)
/* Assume that if sim atom exists, it is ready */
mw->sim = __ofono_atom_get_data(sim_atom);
mw->sim_context = ofono_sim_context_create(mw->sim);
/* Loads MWI states and MBDN from SIM */
ofono_sim_read(mw->sim, SIM_EFMWIS_FILEID,
ofono_sim_read(mw->sim_context, SIM_EFMWIS_FILEID,
OFONO_SIM_FILE_STRUCTURE_FIXED,
mw_mwis_read_cb, mw);
ofono_sim_read(mw->sim, SIM_EFMBI_FILEID,
ofono_sim_read(mw->sim_context, SIM_EFMBI_FILEID,
OFONO_SIM_FILE_STRUCTURE_FIXED,
mw_mbi_read_cb, mw);
/* Also read CPHS MWIS field */
ofono_sim_read(mw->sim, SIM_EF_CPHS_MWIS_FILEID,
ofono_sim_read(mw->sim_context, SIM_EF_CPHS_MWIS_FILEID,
OFONO_SIM_FILE_STRUCTURE_TRANSPARENT,
mw_cphs_mwis_read_cb, mw);
}

View File

@ -75,6 +75,7 @@ struct ofono_netreg {
struct sim_spdi *spdi;
struct sim_eons *eons;
struct ofono_sim *sim;
struct ofono_sim_context *sim_context;
GKeyFile *settings;
char *imsi;
struct ofono_watchlist *status_watches;
@ -1471,7 +1472,7 @@ check:
* is present.
*/
if (netreg->eons && !sim_eons_pnn_is_empty(netreg->eons))
ofono_sim_read(netreg->sim, SIM_EFOPL_FILEID,
ofono_sim_read(netreg->sim_context, SIM_EFOPL_FILEID,
OFONO_SIM_FILE_STRUCTURE_FIXED,
sim_opl_read_cb, netreg);
}
@ -1550,7 +1551,7 @@ static void sim_spn_read_cb(int ok, int length, int record,
}
netreg->spname = spn;
ofono_sim_read(netreg->sim, SIM_EFSPDI_FILEID,
ofono_sim_read(netreg->sim_context, SIM_EFSPDI_FILEID,
OFONO_SIM_FILE_STRUCTURE_TRANSPARENT,
sim_spdi_read_cb, netreg);
@ -1684,6 +1685,13 @@ static void netreg_unregister(struct ofono_atom *atom)
netreg->settings = NULL;
}
if (netreg->sim_context) {
ofono_sim_context_free(netreg->sim_context);
netreg->sim_context = NULL;
}
netreg->sim = NULL;
g_dbus_unregister_interface(conn, path,
OFONO_NETWORK_REGISTRATION_INTERFACE);
ofono_modem_remove_interface(modem,
@ -1808,12 +1816,14 @@ void ofono_netreg_register(struct ofono_netreg *netreg)
/* Assume that if sim atom exists, it is ready */
netreg->sim = __ofono_atom_get_data(sim_atom);
netreg->sim_context = ofono_sim_context_create(netreg->sim);
netreg_load_settings(netreg);
ofono_sim_read(netreg->sim, SIM_EFPNN_FILEID,
ofono_sim_read(netreg->sim_context, SIM_EFPNN_FILEID,
OFONO_SIM_FILE_STRUCTURE_FIXED,
sim_pnn_read_cb, netreg);
ofono_sim_read(netreg->sim, SIM_EFSPN_FILEID,
ofono_sim_read(netreg->sim_context, SIM_EFSPN_FILEID,
OFONO_SIM_FILE_STRUCTURE_TRANSPARENT,
sim_spn_read_cb, netreg);
}

View File

@ -96,6 +96,7 @@ struct ofono_sim {
struct ofono_watchlist *state_watches;
struct sim_fs *simfs;
struct ofono_sim_context *context;
unsigned char *iidf_image;
@ -495,7 +496,7 @@ static gboolean set_own_numbers(struct ofono_sim *sim,
efmsisdn[sim->efmsisdn_length - 14] = 1;
}
if (ofono_sim_write(req->sim, SIM_EFMSISDN_FILEID,
if (ofono_sim_write(req->sim->context, SIM_EFMSISDN_FILEID,
msisdn_set_cb, OFONO_SIM_FILE_STRUCTURE_FIXED,
record, efmsisdn,
sim->efmsisdn_length, req) == 0)
@ -923,7 +924,7 @@ static void sim_iidf_read_cb(int ok, int length, int record,
sim->iidf_image = g_memdup(data, length);
/* read the clut data */
ofono_sim_read_bytes(sim, iidf_id, offset, clut_len,
ofono_sim_read_bytes(sim->context, iidf_id, offset, clut_len,
sim_iidf_read_clut_cb, sim);
}
@ -955,7 +956,7 @@ static void sim_get_image(struct ofono_sim *sim, unsigned char id,
iidf_len = efimg[7] << 8 | efimg[8];
/* read the image data */
ofono_sim_read_bytes(sim, iidf_id, iidf_offset, iidf_len,
ofono_sim_read_bytes(sim->context, iidf_id, iidf_offset, iidf_len,
sim_iidf_read_cb, sim);
}
@ -1212,8 +1213,9 @@ check:
static void sim_own_numbers_update(struct ofono_sim *sim)
{
ofono_sim_read(sim, SIM_EFMSISDN_FILEID, OFONO_SIM_FILE_STRUCTURE_FIXED,
sim_msisdn_read_cb, sim);
ofono_sim_read(sim->context, SIM_EFMSISDN_FILEID,
OFONO_SIM_FILE_STRUCTURE_FIXED, sim_msisdn_read_cb,
sim);
}
static void sim_efimg_read_cb(int ok, int length, int record,
@ -1266,10 +1268,10 @@ static void sim_ready(enum ofono_sim_state new_state, void *user)
sim_own_numbers_update(sim);
ofono_sim_read(sim, SIM_EFSDN_FILEID, OFONO_SIM_FILE_STRUCTURE_FIXED,
sim_sdn_read_cb, sim);
ofono_sim_read(sim, SIM_EFIMG_FILEID, OFONO_SIM_FILE_STRUCTURE_FIXED,
sim_efimg_read_cb, sim);
ofono_sim_read(sim->context, SIM_EFSDN_FILEID,
OFONO_SIM_FILE_STRUCTURE_FIXED, sim_sdn_read_cb, sim);
ofono_sim_read(sim->context, SIM_EFIMG_FILEID,
OFONO_SIM_FILE_STRUCTURE_FIXED, sim_efimg_read_cb, sim);
}
static void sim_imsi_cb(const struct ofono_error *error, const char *imsi,
@ -1385,7 +1387,7 @@ static gboolean check_bdn_status(struct ofono_sim *sim)
*/
if (sim_sst_is_active(sim->efsst, sim->efsst_length,
SIM_SST_SERVICE_BDN)) {
sim_fs_read_info(sim->simfs, SIM_EFBDN_FILEID,
sim_fs_read_info(sim->context, SIM_EFBDN_FILEID,
OFONO_SIM_FILE_STRUCTURE_FIXED,
sim_efbdn_info_read_cb, sim);
return TRUE;
@ -1439,7 +1441,7 @@ static void sim_efsst_read_cb(int ok, int length, int record,
*/
if (sim_sst_is_active(sim->efsst, sim->efsst_length,
SIM_SST_SERVICE_FDN)) {
sim_fs_read_info(sim->simfs, SIM_EFADN_FILEID,
sim_fs_read_info(sim->context, SIM_EFADN_FILEID,
OFONO_SIM_FILE_STRUCTURE_FIXED,
sim_efadn_info_read_cb, sim);
return;
@ -1529,7 +1531,7 @@ static void sim_efust_read_cb(int ok, int length, int record,
SIM_UST_SERVICE_FDN) ||
sim_ust_is_available(sim->efust, sim->efust_length,
SIM_UST_SERVICE_BDN)) {
ofono_sim_read(sim, SIM_EFEST_FILEID,
ofono_sim_read(sim->context, SIM_EFEST_FILEID,
OFONO_SIM_FILE_STRUCTURE_TRANSPARENT,
sim_efest_read_cb, sim);
@ -1590,7 +1592,7 @@ static void sim_efphase_read_cb(int ok, int length, int record,
if (!ok || length != 1) {
sim->phase = OFONO_SIM_PHASE_3G;
ofono_sim_read(sim, SIM_EFUST_FILEID,
ofono_sim_read(sim->context, SIM_EFUST_FILEID,
OFONO_SIM_FILE_STRUCTURE_TRANSPARENT,
sim_efust_read_cb, sim);
@ -1612,18 +1614,18 @@ static void sim_efphase_read_cb(int ok, int length, int record,
return;
}
ofono_sim_read(sim, SIM_EFSST_FILEID,
ofono_sim_read(sim->context, SIM_EFSST_FILEID,
OFONO_SIM_FILE_STRUCTURE_TRANSPARENT,
sim_efsst_read_cb, sim);
}
static void sim_initialize_after_pin(struct ofono_sim *sim)
{
ofono_sim_read(sim, SIM_EFPHASE_FILEID,
ofono_sim_read(sim->context, SIM_EFPHASE_FILEID,
OFONO_SIM_FILE_STRUCTURE_TRANSPARENT,
sim_efphase_read_cb, sim);
ofono_sim_read(sim, SIM_EFAD_FILEID,
ofono_sim_read(sim->context, SIM_EFAD_FILEID,
OFONO_SIM_FILE_STRUCTURE_TRANSPARENT,
sim_ad_read_cb, sim);
@ -1631,7 +1633,7 @@ static void sim_initialize_after_pin(struct ofono_sim *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_read(sim->context, SIM_EF_CPHS_INFORMATION_FILEID,
OFONO_SIM_FILE_STRUCTURE_TRANSPARENT,
sim_cphs_information_read_cb, sim);
}
@ -1923,7 +1925,7 @@ static void sim_initialize(struct ofono_sim *sim)
*/
/* Grab the EFiccid which is always available */
ofono_sim_read(sim, SIM_EF_ICCID_FILEID,
ofono_sim_read(sim->context, SIM_EF_ICCID_FILEID,
OFONO_SIM_FILE_STRUCTURE_TRANSPARENT,
sim_iccid_read_cb, sim);
@ -1937,47 +1939,51 @@ static void sim_initialize(struct ofono_sim *sim)
* 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_read(sim->context, SIM_EFLI_FILEID,
OFONO_SIM_FILE_STRUCTURE_TRANSPARENT,
sim_efli_read_cb, sim);
ofono_sim_read(sim, SIM_EFPL_FILEID,
ofono_sim_read(sim->context, SIM_EFPL_FILEID,
OFONO_SIM_FILE_STRUCTURE_TRANSPARENT,
sim_efpl_read_cb, sim);
}
int ofono_sim_read_bytes(struct ofono_sim *sim, int id,
struct ofono_sim_context *ofono_sim_context_create(struct ofono_sim *sim)
{
if (sim == NULL || sim->simfs == NULL)
return NULL;
return sim_fs_context_new(sim->simfs);
}
void ofono_sim_context_free(struct ofono_sim_context *context)
{
return sim_fs_context_free(context);
}
int ofono_sim_read_bytes(struct ofono_sim_context *context, int id,
unsigned short offset, unsigned short num_bytes,
ofono_sim_file_read_cb_t cb, void *data)
{
if (sim == NULL)
return -1;
if (num_bytes == 0)
return -1;
return sim_fs_read(sim->simfs, id, OFONO_SIM_FILE_STRUCTURE_TRANSPARENT,
return sim_fs_read(context, id, OFONO_SIM_FILE_STRUCTURE_TRANSPARENT,
offset, num_bytes, cb, data);
}
int ofono_sim_read(struct ofono_sim *sim, int id,
int ofono_sim_read(struct ofono_sim_context *context, int id,
enum ofono_sim_file_structure expected_type,
ofono_sim_file_read_cb_t cb, void *data)
{
if (sim == NULL)
return -1;
return sim_fs_read(sim->simfs, id, expected_type, 0, 0, cb, data);
return sim_fs_read(context, id, expected_type, 0, 0, cb, data);
}
int ofono_sim_write(struct ofono_sim *sim, int id,
int ofono_sim_write(struct ofono_sim_context *context, int id,
ofono_sim_file_write_cb_t cb,
enum ofono_sim_file_structure structure, int record,
const unsigned char *data, int length, void *userdata)
{
if (sim == NULL)
return -1;
return sim_fs_write(sim->simfs, id, cb, structure, record, data, length,
return sim_fs_write(context, id, cb, structure, record, data, length,
userdata);
}
@ -2264,6 +2270,11 @@ static void sim_remove(struct ofono_atom *atom)
sim_free_state(sim);
if (sim->context) {
ofono_sim_context_free(sim->context);
sim->context = NULL;
}
sim_fs_free(sim->simfs);
sim->simfs = NULL;
@ -2329,6 +2340,7 @@ void ofono_sim_register(struct ofono_sim *sim)
ofono_modem_add_interface(modem, OFONO_SIM_MANAGER_INTERFACE);
sim->state_watches = __ofono_watchlist_new(g_free);
sim->simfs = sim_fs_new(sim, sim->driver);
sim->context = ofono_sim_context_create(sim);
__ofono_atom_register(sim->atom, sim_unregister);

View File

@ -69,6 +69,7 @@ struct sim_fs_op {
gconstpointer cb;
gboolean is_read;
void *userdata;
struct ofono_sim_context *context;
};
static void sim_fs_op_free(struct sim_fs_op *node)
@ -108,6 +109,10 @@ void sim_fs_free(struct sim_fs *fs)
g_free(fs);
}
struct ofono_sim_context {
struct sim_fs *fs;
};
struct sim_fs *sim_fs_new(struct ofono_sim *sim,
const struct ofono_sim_driver *driver)
{
@ -124,6 +129,44 @@ struct sim_fs *sim_fs_new(struct ofono_sim *sim,
return fs;
}
struct ofono_sim_context *sim_fs_context_new(struct sim_fs *fs)
{
struct ofono_sim_context *context =
g_try_new0(struct ofono_sim_context, 1);
if (context == NULL)
return NULL;
context->fs = fs;
return context;
}
void sim_fs_context_free(struct ofono_sim_context *context)
{
int n = 0;
struct sim_fs_op *op;
while ((op = g_queue_peek_nth(context->fs->op_q, n)) != NULL) {
if (op->context != context) {
n += 1;
continue;
}
if (n == 0) {
op->cb = NULL;
n += 1;
continue;
}
sim_fs_op_free(op);
g_queue_remove(context->fs->op_q, op);
}
g_free(context);
}
static void sim_fs_end_current(struct sim_fs *fs)
{
struct sim_fs_op *op = g_queue_pop_head(fs->op_q);
@ -145,6 +188,11 @@ static void sim_fs_op_error(struct sim_fs *fs)
{
struct sim_fs_op *op = g_queue_peek_head(fs->op_q);
if (op->cb == NULL) {
sim_fs_end_current(fs);
return;
}
if (op->info_only == TRUE)
((sim_fs_read_info_cb_t) op->cb)
(0, 0, 0, 0, op->userdata);
@ -204,6 +252,11 @@ static void sim_fs_op_write_cb(const struct ofono_error *error, void *data)
struct sim_fs_op *op = g_queue_peek_head(fs->op_q);
ofono_sim_file_write_cb_t cb = op->cb;
if (cb == NULL) {
sim_fs_end_current(fs);
return;
}
if (error->type == OFONO_ERROR_TYPE_NO_ERROR)
cb(1, op->userdata);
else
@ -250,6 +303,11 @@ static void sim_fs_op_read_block_cb(const struct ofono_error *error,
memcpy(op->buffer + bufoff, data + dataoff, tocopy);
cache_block(fs, op->current, 256, data, len);
if (op->cb == NULL) {
sim_fs_end_current(fs);
return;
}
op->current++;
if (op->current > end_block) {
@ -274,6 +332,11 @@ static gboolean sim_fs_op_read_block(gpointer user_data)
fs->op_source = 0;
if (op->cb == NULL) {
sim_fs_end_current(fs);
return FALSE;
}
start_block = op->offset / 256;
end_block = (op->offset + (op->num_bytes - 1)) / 256;
@ -360,11 +423,16 @@ static void sim_fs_op_retrieve_cb(const struct ofono_error *error,
return;
}
cb(1, op->length, op->current, data, op->record_length, op->userdata);
cache_block(fs, op->current - 1, op->record_length,
data, op->record_length);
if (cb == NULL) {
sim_fs_end_current(fs);
return;
}
cb(1, op->length, op->current, data, op->record_length, op->userdata);
if (op->current < total) {
op->current += 1;
fs->op_source = g_idle_add(sim_fs_op_read_record, fs);
@ -383,6 +451,11 @@ static gboolean sim_fs_op_read_record(gpointer user)
fs->op_source = 0;
if (op->cb == NULL) {
sim_fs_end_current(fs);
return FALSE;
}
while (fs->fd != -1 && op->current <= total) {
int offset = (op->current - 1) / 8;
int bit = 1 << ((op->current - 1) % 8);
@ -523,6 +596,11 @@ static void sim_fs_op_info_cb(const struct ofono_error *error, int length,
return;
}
if (op->cb == NULL) {
sim_fs_end_current(fs);
return;
}
op->structure = structure;
op->length = length;
@ -663,6 +741,11 @@ static gboolean sim_fs_op_next(gpointer user_data)
op = g_queue_peek_head(fs->op_q);
if (op->cb == NULL) {
sim_fs_end_current(fs);
return FALSE;
}
if (op->is_read == TRUE) {
if (sim_fs_op_check_cached(fs))
return FALSE;
@ -697,10 +780,11 @@ static gboolean sim_fs_op_next(gpointer user_data)
return FALSE;
}
int sim_fs_read_info(struct sim_fs *fs, int id,
int sim_fs_read_info(struct ofono_sim_context *context, int id,
enum ofono_sim_file_structure expected_type,
sim_fs_read_info_cb_t cb, void *data)
{
struct sim_fs *fs = context->fs;
struct sim_fs_op *op;
if (cb == NULL)
@ -725,6 +809,7 @@ int sim_fs_read_info(struct sim_fs *fs, int id,
op->userdata = data;
op->is_read = TRUE;
op->info_only = TRUE;
op->context = context;
g_queue_push_tail(fs->op_q, op);
@ -734,11 +819,12 @@ int sim_fs_read_info(struct sim_fs *fs, int id,
return 0;
}
int sim_fs_read(struct sim_fs *fs, int id,
int sim_fs_read(struct ofono_sim_context *context, int id,
enum ofono_sim_file_structure expected_type,
unsigned short offset, unsigned short num_bytes,
ofono_sim_file_read_cb_t cb, void *data)
{
struct sim_fs *fs = context->fs;
struct sim_fs_op *op;
if (cb == NULL)
@ -765,6 +851,7 @@ int sim_fs_read(struct sim_fs *fs, int id,
op->offset = offset;
op->num_bytes = num_bytes;
op->info_only = FALSE;
op->context = context;
g_queue_push_tail(fs->op_q, op);
@ -774,10 +861,12 @@ int sim_fs_read(struct sim_fs *fs, int id,
return 0;
}
int sim_fs_write(struct sim_fs *fs, int id, ofono_sim_file_write_cb_t cb,
int sim_fs_write(struct ofono_sim_context *context, int id,
ofono_sim_file_write_cb_t cb,
enum ofono_sim_file_structure structure, int record,
const unsigned char *data, int length, void *userdata)
{
struct sim_fs *fs = context->fs;
struct sim_fs_op *op;
gconstpointer fn = NULL;
@ -819,6 +908,7 @@ int sim_fs_write(struct sim_fs *fs, int id, ofono_sim_file_write_cb_t cb,
op->structure = structure;
op->length = length;
op->current = record;
op->context = context;
g_queue_push_tail(fs->op_q, op);

View File

@ -27,19 +27,21 @@ typedef void (*sim_fs_read_info_cb_t)(int ok, unsigned char file_status,
struct sim_fs *sim_fs_new(struct ofono_sim *sim,
const struct ofono_sim_driver *driver);
struct ofono_sim_context *sim_fs_context_new(struct sim_fs *fs);
int sim_fs_read(struct sim_fs *fs, int id,
int sim_fs_read(struct ofono_sim_context *context, int id,
enum ofono_sim_file_structure expected_type,
unsigned short offset, unsigned short num_bytes,
ofono_sim_file_read_cb_t cb, void *data);
int sim_fs_read_info(struct sim_fs *fs, int id,
int sim_fs_read_info(struct ofono_sim_context *context, int id,
enum ofono_sim_file_structure expected_type,
sim_fs_read_info_cb_t cb, void *data);
void sim_fs_check_version(struct sim_fs *fs);
int sim_fs_write(struct sim_fs *fs, int id, ofono_sim_file_write_cb_t cb,
int sim_fs_write(struct ofono_sim_context *context, int id,
ofono_sim_file_write_cb_t cb,
enum ofono_sim_file_structure structure, int record,
const unsigned char *data, int length, void *userdata);
@ -53,3 +55,4 @@ void sim_fs_image_cache_flush(struct sim_fs *fs);
void sim_fs_image_cache_flush_file(struct sim_fs *fs, int id);
void sim_fs_free(struct sim_fs *fs);
void sim_fs_context_free(struct ofono_sim_context *context);

View File

@ -50,6 +50,7 @@ struct ofono_voicecall {
GSList *new_en_list; /* Emergency numbers being read from SIM */
DBusMessage *pending;
struct ofono_sim *sim;
struct ofono_sim_context *sim_context;
unsigned int sim_watch;
unsigned int sim_state_watch;
const struct ofono_voicecall_driver *driver;
@ -2284,17 +2285,25 @@ static void sim_state_watch(enum ofono_sim_state new_state, void *user)
switch (new_state) {
case OFONO_SIM_STATE_INSERTED:
if (vc->sim_context == NULL)
vc->sim_context = ofono_sim_context_create(vc->sim);
/* Try both formats, only one or none will work */
ofono_sim_read(vc->sim, SIM_EFECC_FILEID,
ofono_sim_read(vc->sim_context, SIM_EFECC_FILEID,
OFONO_SIM_FILE_STRUCTURE_TRANSPARENT,
ecc_g2_read_cb, vc);
ofono_sim_read(vc->sim, SIM_EFECC_FILEID,
ofono_sim_read(vc->sim_context, SIM_EFECC_FILEID,
OFONO_SIM_FILE_STRUCTURE_FIXED,
ecc_g3_read_cb, vc);
break;
case OFONO_SIM_STATE_NOT_PRESENT:
/* TODO: Must release all non-emergency calls */
if (vc->sim_context) {
ofono_sim_context_free(vc->sim_context);
vc->sim_context = NULL;
}
/*
* Free the currently being read EN list, just in case the
* SIM is removed when we're still reading them