Hi Kristen,
On 07/27/2010 06:22 PM, Kristen Carlson Accardi wrote:
Implement ofono_sim_read_bytes(). For transparent files, this
will read num_bytes from a specified offset of a given fileid.
---
include/sim.h | 5 +++++
src/sim.c | 27 ++++++++++++++++++++++++---
2 files changed, 29 insertions(+), 3 deletions(-)
diff --git a/include/sim.h b/include/sim.h
index 36a99b9..15cd6b8 100644
--- a/include/sim.h
+++ b/include/sim.h
@@ -198,6 +198,11 @@ int ofono_sim_read(struct ofono_sim *sim, int id,
enum ofono_sim_file_structure expected,
ofono_sim_file_read_cb_t cb, void *data);
+int ofono_sim_read_bytes(struct ofono_sim *sim, int id,
+ enum ofono_sim_file_structure expected,
+ unsigned short offset, int num_bytes,
+ ofono_sim_file_read_cb_t cb, void *data);
+
The read_bytes function has a slightly different audience than the
sim_read function. Namely, ofono_sim_read stats the file first for
structure / length / record size and then reads it.
For EFiidf files you will need to initiate multiple reads, so 'stat'ing
the file first every time is inefficient. Maybe a more low-level
semantic is in order, i.e one that attempts to read directly.
int ofono_sim_write(struct ofono_sim *sim, int id,
ofono_sim_file_write_cb_t cb,
enum ofono_sim_file_structure structure, int record,
diff --git a/src/sim.c b/src/sim.c
index 2514e7b..63dea19 100644
--- a/src/sim.c
+++ b/src/sim.c
@@ -60,6 +60,8 @@ struct sim_file_op {
int id;
gboolean cache;
enum ofono_sim_file_structure structure;
+ unsigned short offset;
+ int num_bytes;
int length;
int record_length;
int current;
@@ -1434,7 +1436,7 @@ static void sim_op_retrieve_cb(const struct ofono_error *error,
return;
}
- cb(1, op->length, op->current, data, op->record_length, op->userdata);
+ cb(1, len, op->current, data, op->record_length, op->userdata);
if (op->cache && imsi) {
char *path = g_strdup_printf(SIM_CACHE_PATH,
@@ -1472,7 +1474,16 @@ static gboolean sim_op_retrieve_next(gpointer user)
return FALSE;
}
- sim->driver->read_file_transparent(sim, op->id, 0, op->length,
+ if (op->num_bytes < 0)
+ op->num_bytes = op->length;
+
+ if (op->offset + op->num_bytes > op->length) {
+ sim_op_error(sim);
+ return FALSE;
+ }
+
+ sim->driver->read_file_transparent(sim, op->id, op->offset,
+ op->num_bytes,
sim_op_retrieve_cb, sim);
Unfortunately you cannot read large files in one go. You must separate
the reads into 256 byte chunks. See 3GPP 11.11 for more details.
My rough thinking is as follows:
- Read EFimg
- Cleverly read chunks of EFiidf 1..n, caching the needed chunks and
minimizing the # of reads. Perhaps using some sort of a bitmap of 256
byte chunks.
- Generate icons and write to a cache on the filesystem
- Free memory resources
- Use memmap to return icons to the user in GetIcon
Regards,
-Denis