There seems to be no reason that the fileinfo is cached for file
read or block read requests but not info_only requests, so move
code around to fix this.  O_RDWR is changed to O_WRONLY for the
cache file because the file is not being read in case of cache miss.
---
 src/simfs.c |  140 ++++++++++++++++++++++++++++++++++------------------------
 1 files changed, 82 insertions(+), 58 deletions(-)

diff --git a/src/simfs.c b/src/simfs.c
index 73da80c..37e801a 100644
--- a/src/simfs.c
+++ b/src/simfs.c
@@ -45,12 +45,12 @@
 #define SIM_CACHE_BASEPATH STORAGEDIR "/%s-%i"
 #define SIM_CACHE_VERSION SIM_CACHE_BASEPATH "/version"
 #define SIM_CACHE_PATH SIM_CACHE_BASEPATH "/%04x"
-#define SIM_CACHE_HEADER_SIZE 38
-#define SIM_FILE_INFO_SIZE 6
+#define SIM_CACHE_HEADER_SIZE 39
+#define SIM_FILE_INFO_SIZE 7
 #define SIM_IMAGE_CACHE_BASEPATH STORAGEDIR "/%s-%i/images"
 #define SIM_IMAGE_CACHE_PATH SIM_IMAGE_CACHE_BASEPATH "/%d.xpm"
 
-#define SIM_FS_VERSION 1
+#define SIM_FS_VERSION 2
 
 static gboolean sim_fs_op_next(gpointer user_data);
 static gboolean sim_fs_op_read_record(gpointer user);
@@ -436,14 +436,14 @@ static gboolean sim_fs_op_read_record(gpointer user)
        return FALSE;
 }
 
-static void sim_fs_op_info_cb(const struct ofono_error *error, int length,
-                               enum ofono_sim_file_structure structure,
-                               int record_length,
-                               const unsigned char access[3],
-                               unsigned char file_status,
-                               void *data)
+static void sim_fs_op_cache_fileinfo(struct sim_fs *fs,
+                                       const struct ofono_error *error,
+                                       int length,
+                                       enum ofono_sim_file_structure structure,
+                                       int record_length,
+                                       const unsigned char access[3],
+                                       unsigned char file_status)
 {
-       struct sim_fs *fs = data;
        struct sim_fs_op *op = g_queue_peek_head(fs->op_q);
        const char *imsi = ofono_sim_get_imsi(fs->sim);
        enum ofono_sim_phase phase = ofono_sim_get_phase(fs->sim);
@@ -454,11 +454,65 @@ static void sim_fs_op_info_cb(const struct ofono_error 
*error, int length,
        gboolean cache;
        char *path;
 
+       /* TS 11.11, Section 9.3 */
+       update = file_access_condition_decode(access[0] & 0xf);
+       rehabilitate = file_access_condition_decode((access[2] >> 4) & 0xf);
+       invalidate = file_access_condition_decode(access[2] & 0xf);
+
+       /* Never cache card holder writable files */
+       cache = (update == SIM_FILE_ACCESS_ADM ||
+                       update == SIM_FILE_ACCESS_NEVER) &&
+                       (invalidate == SIM_FILE_ACCESS_ADM ||
+                               invalidate == SIM_FILE_ACCESS_NEVER) &&
+                       (rehabilitate == SIM_FILE_ACCESS_ADM ||
+                               rehabilitate == SIM_FILE_ACCESS_NEVER);
+
+       if (imsi == NULL || phase == OFONO_SIM_PHASE_UNKNOWN || cache == FALSE)
+               return;
+
+       memset(fileinfo, 0, SIM_CACHE_HEADER_SIZE);
+
+       fileinfo[0] = error->type;
+       fileinfo[1] = length >> 8;
+       fileinfo[2] = length & 0xff;
+       fileinfo[3] = structure;
+       fileinfo[4] = record_length >> 8;
+       fileinfo[5] = record_length & 0xff;
+       fileinfo[6] = file_status;
+
+       path = g_strdup_printf(SIM_CACHE_PATH, imsi, phase, op->id);
+       fs->fd = TFR(open(path, O_WRONLY | O_CREAT | O_TRUNC, SIM_CACHE_MODE));
+       g_free(path);
+
+       if (fs->fd == -1)
+               return;
+
+       if (TFR(write(fs->fd, fileinfo, SIM_CACHE_HEADER_SIZE)) ==
+                       SIM_CACHE_HEADER_SIZE)
+               return;
+
+       TFR(close(fs->fd));
+       fs->fd = -1;
+}
+
+static void sim_fs_op_info_cb(const struct ofono_error *error, int length,
+                               enum ofono_sim_file_structure structure,
+                               int record_length,
+                               const unsigned char access[3],
+                               unsigned char file_status,
+                               void *data)
+{
+       struct sim_fs *fs = data;
+       struct sim_fs_op *op = g_queue_peek_head(fs->op_q);
+
        if (error->type != OFONO_ERROR_TYPE_NO_ERROR) {
                sim_fs_op_error(fs);
                return;
        }
 
+       sim_fs_op_cache_fileinfo(fs, error, length, structure, record_length,
+                                       access, file_status);
+
        if (structure != op->structure) {
                ofono_error("Requested file structure differs from SIM: %x",
                                op->id);
@@ -466,22 +520,9 @@ static void sim_fs_op_info_cb(const struct ofono_error 
*error, int length,
                return;
        }
 
-       /* TS 11.11, Section 9.3 */
-       update = file_access_condition_decode(access[0] & 0xf);
-       rehabilitate = file_access_condition_decode((access[2] >> 4) & 0xf);
-       invalidate = file_access_condition_decode(access[2] & 0xf);
-
        op->structure = structure;
        op->length = length;
 
-       /* Never cache card holder writable files */
-       cache = (update == SIM_FILE_ACCESS_ADM ||
-                       update == SIM_FILE_ACCESS_NEVER) &&
-                       (invalidate == SIM_FILE_ACCESS_ADM ||
-                               invalidate == SIM_FILE_ACCESS_NEVER) &&
-                       (rehabilitate == SIM_FILE_ACCESS_ADM ||
-                               rehabilitate == SIM_FILE_ACCESS_NEVER);
-
        if (structure == OFONO_SIM_FILE_STRUCTURE_TRANSPARENT) {
                if (op->num_bytes == 0)
                        op->num_bytes = op->length;
@@ -501,8 +542,8 @@ static void sim_fs_op_info_cb(const struct ofono_error 
*error, int length,
 
        if (op->info_only == TRUE) {
                /*
-                * It's info-only request. So there is no need to request
-                * actual contents of the EF-files. Just return the EF-info.
+                * It's an info-only request, so there is no need to request
+                * actual contents of the EF. Just return the EF-info.
                 */
                sim_fs_read_info_cb_t cb = op->cb;
 
@@ -510,35 +551,7 @@ static void sim_fs_op_info_cb(const struct ofono_error 
*error, int length,
                        op->record_length, op->userdata);
 
                sim_fs_end_current(fs);
-
-               return;
        }
-
-       if (imsi == NULL || phase == OFONO_SIM_PHASE_UNKNOWN || cache == FALSE)
-               return;
-
-       memset(fileinfo, 0, SIM_CACHE_HEADER_SIZE);
-
-       fileinfo[0] = error->type;
-       fileinfo[1] = length >> 8;
-       fileinfo[2] = length & 0xff;
-       fileinfo[3] = structure;
-       fileinfo[4] = record_length >> 8;
-       fileinfo[5] = record_length & 0xff;
-
-       path = g_strdup_printf(SIM_CACHE_PATH, imsi, phase, op->id);
-       fs->fd = TFR(open(path, O_RDWR | O_CREAT | O_TRUNC, SIM_CACHE_MODE));
-       g_free(path);
-
-       if (fs->fd == -1)
-               return;
-
-       if (TFR(write(fs->fd, fileinfo, SIM_CACHE_HEADER_SIZE)) ==
-                       SIM_CACHE_HEADER_SIZE)
-               return;
-
-       TFR(close(fs->fd));
-       fs->fd = -1;
 }
 
 static gboolean sim_fs_op_check_cached(struct sim_fs *fs)
@@ -546,7 +559,6 @@ static gboolean sim_fs_op_check_cached(struct sim_fs *fs)
        const char *imsi = ofono_sim_get_imsi(fs->sim);
        enum ofono_sim_phase phase = ofono_sim_get_phase(fs->sim);
        struct sim_fs_op *op = g_queue_peek_head(fs->op_q);
-       gboolean ret = FALSE;
        char *path;
        int fd;
        ssize_t len;
@@ -555,9 +567,9 @@ static gboolean sim_fs_op_check_cached(struct sim_fs *fs)
        int file_length;
        enum ofono_sim_file_structure structure;
        int record_length;
+       unsigned char file_status;
 
-       if (imsi == NULL || phase == OFONO_SIM_PHASE_UNKNOWN ||
-                       op->info_only == TRUE)
+       if (imsi == NULL || phase == OFONO_SIM_PHASE_UNKNOWN)
                return FALSE;
 
        path = g_strdup_printf(SIM_CACHE_PATH, imsi, phase, op->id);
@@ -586,6 +598,7 @@ static gboolean sim_fs_op_check_cached(struct sim_fs *fs)
        file_length = (fileinfo[1] << 8) | fileinfo[2];
        structure = fileinfo[3];
        record_length = (fileinfo[4] << 8) | fileinfo[5];
+       file_status = fileinfo[6];
 
        if (structure == OFONO_SIM_FILE_STRUCTURE_TRANSPARENT)
                record_length = file_length;
@@ -605,7 +618,18 @@ static gboolean sim_fs_op_check_cached(struct sim_fs *fs)
                return TRUE;
        }
 
-       if (structure == OFONO_SIM_FILE_STRUCTURE_TRANSPARENT) {
+       if (op->info_only == TRUE) {
+               /*
+                * It's an info-only request, so there is no need to request
+                * actual contents of the EF. Just return the EF-info.
+                */
+               sim_fs_read_info_cb_t cb = op->cb;
+
+               cb(1, file_status, op->length,
+                       op->record_length, op->userdata);
+
+               sim_fs_end_current(fs);
+       } else if (structure == OFONO_SIM_FILE_STRUCTURE_TRANSPARENT) {
                if (op->num_bytes == 0)
                        op->num_bytes = op->length;
 
@@ -620,7 +644,7 @@ static gboolean sim_fs_op_check_cached(struct sim_fs *fs)
 
 error:
        TFR(close(fd));
-       return ret;
+       return FALSE;
 }
 
 static gboolean sim_fs_op_next(gpointer user_data)
-- 
1.7.1.86.g0e460.dirty

_______________________________________________
ofono mailing list
ofono@ofono.org
http://lists.ofono.org/listinfo/ofono

Reply via email to