From 4cdf56cabe9717853de28ede8bee13f1d91d6bd1 Mon Sep 17 00:00:00 2001 From: Andrzej Zaborowski Date: Sat, 1 Aug 2009 15:48:37 +0200 Subject: [PATCH] Implement ofono_sim_write Writes use sim->simop_q queue together with reads. --- src/sim.c | 116 +++++++++++++++++++++++++++++++++++++++++++++++++++--- src/sim.h | 5 ++- 2 files changed, 114 insertions(+), 7 deletions(-) diff --git a/src/sim.c b/src/sim.c index 6e144f42..bd9dd0f4 100644 --- a/src/sim.c +++ b/src/sim.c @@ -55,7 +55,9 @@ struct sim_file_op { int length; int record_length; int current; - ofono_sim_file_read_cb_t cb; + gconstpointer cb; + int is_read; + void *buffer; void *userdata; }; @@ -288,7 +290,12 @@ static void sim_op_error(struct ofono_modem *modem) struct sim_manager_data *sim = modem->sim_manager; struct sim_file_op *op = g_queue_pop_head(sim->simop_q); - op->cb(modem, 0, 0, 0, 0, 0, 0, op->userdata); + if (op->is_read) + ((ofono_sim_file_read_cb_t) op->cb) + (modem, 0, 0, 0, 0, 0, 0, op->userdata); + else + ((ofono_sim_file_write_cb_t) op->cb) + (modem, 0, op->userdata); sim_file_op_free(op); @@ -308,6 +315,7 @@ static void sim_op_retrieve_cb(const struct ofono_error *error, struct sim_manager_data *sim = modem->sim_manager; struct sim_file_op *op = g_queue_peek_head(sim->simop_q); int total = op->length / op->record_length; + ofono_sim_file_read_cb_t cb = op->cb; char *imsi = sim->imsi; char *path; @@ -318,7 +326,7 @@ static void sim_op_retrieve_cb(const struct ofono_error *error, return; } - op->cb(modem, 1, op->structure, op->length, op->current, + cb(modem, 1, op->structure, op->length, op->current, data, op->record_length, op->userdata); if (op->cache && imsi) { @@ -464,6 +472,26 @@ static void sim_op_info_cb(const struct ofono_error *error, int length, } } +static void sim_op_write_cb(const struct ofono_error *error, void *data) +{ + struct ofono_modem *modem = data; + struct sim_manager_data *sim = modem->sim_manager; + struct sim_file_op *op = g_queue_pop_head(sim->simop_q); + ofono_sim_file_write_cb_t cb = op->cb; + + if (error->type != OFONO_ERROR_TYPE_NO_ERROR) { + sim_op_error(modem); + return; + } + + cb(modem, 1, op->userdata); + + sim_file_op_free(op); + + if (g_queue_get_length(sim->simop_q) > 0) + g_timeout_add(0, sim_op_next, modem); +} + static gboolean sim_op_next(gpointer user_data) { struct ofono_modem *modem = user_data; @@ -475,7 +503,32 @@ static gboolean sim_op_next(gpointer user_data) op = g_queue_peek_head(sim->simop_q); - sim->ops->read_file_info(modem, op->id, sim_op_info_cb, modem); + if (op->is_read) { + sim->ops->read_file_info(modem, op->id, sim_op_info_cb, modem); + } else { + switch (op->structure) { + case OFONO_SIM_FILE_STRUCTURE_TRANSPARENT: + sim->ops->write_file_transparent(modem, op->id, 0, + op->length, op->buffer, + sim_op_write_cb, modem); + break; + case OFONO_SIM_FILE_STRUCTURE_FIXED: + sim->ops->write_file_linear(modem, op->id, op->current, + op->length, op->buffer, + sim_op_write_cb, modem); + break; + case OFONO_SIM_FILE_STRUCTURE_CYCLIC: + sim->ops->write_file_cyclic(modem, op->id, + op->length, op->buffer, + sim_op_write_cb, modem); + break; + default: + ofono_error("Unrecognized file structure, " + "this can't happen"); + } + + g_free(op->buffer); + } return FALSE; } @@ -613,6 +666,7 @@ int ofono_sim_read(struct ofono_modem *modem, int id, op->id = id; op->cb = cb; op->userdata = data; + op->is_read = 1; g_queue_push_tail(sim->simop_q, op); @@ -623,10 +677,60 @@ int ofono_sim_read(struct ofono_modem *modem, int id, } int ofono_sim_write(struct ofono_modem *modem, int id, + ofono_sim_file_write_cb_t cb, enum ofono_sim_file_structure structure, int record, - const unsigned char *data, int length) + const unsigned char *data, int length, void *userdata) { - return -1; + struct sim_manager_data *sim = modem->sim_manager; + struct sim_file_op *op; + gconstpointer fn = NULL; + + if (!cb) + return -1; + + if (sim == NULL) + return -1; + + if (!sim->ops) + return -1; + + switch (structure) { + case OFONO_SIM_FILE_STRUCTURE_TRANSPARENT: + fn = sim->ops->write_file_transparent; + break; + case OFONO_SIM_FILE_STRUCTURE_FIXED: + fn = sim->ops->write_file_linear; + break; + case OFONO_SIM_FILE_STRUCTURE_CYCLIC: + fn = sim->ops->write_file_cyclic; + break; + default: + ofono_error("Unrecognized file structure, this can't happen"); + } + + if (fn == NULL) + return -1; + + if (!sim->simop_q) + sim->simop_q = g_queue_new(); + + op = g_new0(struct sim_file_op, 1); + + op->id = id; + op->cb = cb; + op->userdata = userdata; + op->is_read = 0; + op->buffer = g_memdup(data, length); + op->structure = structure; + op->length = length; + op->current = record; + + g_queue_push_tail(sim->simop_q, op); + + if (g_queue_get_length(sim->simop_q) == 1) + g_timeout_add(0, sim_op_next, modem); + + return 0; } static void initialize_sim_manager(struct ofono_modem *modem) diff --git a/src/sim.h b/src/sim.h index 8e7870d2..88a165cc 100644 --- a/src/sim.h +++ b/src/sim.h @@ -26,6 +26,8 @@ typedef void (*ofono_sim_file_read_cb_t)(struct ofono_modem *modem, int ok, int total_length, int record, const unsigned char *data, int record_length, void *userdata); +typedef void (*ofono_sim_file_write_cb_t)(struct ofono_modem *modem, int ok, + void *userdata); void ofono_sim_manager_init(struct ofono_modem *modem); void ofono_sim_manager_exit(struct ofono_modem *modem); @@ -51,5 +53,6 @@ int ofono_sim_read(struct ofono_modem *modem, int id, ofono_sim_file_read_cb_t cb, void *data); int ofono_sim_write(struct ofono_modem *modem, int id, + ofono_sim_file_write_cb_t cb, enum ofono_sim_file_structure structure, int record, - const unsigned char *data, int length); + const unsigned char *data, int length, void *userdata);