All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCHv2] simfs: read files from specific AID's
@ 2017-11-06 19:03 James Prestwood
  0 siblings, 0 replies; only message in thread
From: James Prestwood @ 2017-11-06 19:03 UTC (permalink / raw)
  To: ofono

[-- Attachment #1: Type: text/plain, Size: 6121 bytes --]

The simfs atom could not read EF's that did not exist on the
'default' ADF directory. This implements a new way to read EF's
that exist on a given AID. A new fs object/context can be
initialized for a given AID. Using this fs context with
the existing read file API will read from that AID rather than
the default ADF.
---
 src/simfs.c | 154 ++++++++++++++++++++++++++++++++++++++++++++++++++++++------
 src/simfs.h |   3 ++
 2 files changed, 142 insertions(+), 15 deletions(-)

diff --git a/src/simfs.c b/src/simfs.c
index 37a232a..f1b33b5 100644
--- a/src/simfs.c
+++ b/src/simfs.c
@@ -70,16 +70,17 @@ struct sim_fs_op {
 	unsigned char path_len;
 	gconstpointer cb;
 	gboolean is_read;
+	int session_id;
+	unsigned int watch_id;
 	void *userdata;
 	struct ofono_sim_context *context;
 };
 
-static void sim_fs_op_free(gpointer pointer)
-{
-	struct sim_fs_op *node = pointer;
-	g_free(node->buffer);
-	g_free(node);
-}
+struct ofono_sim_context {
+	struct sim_fs *fs;
+	struct ofono_watchlist *file_watches;
+	struct ofono_sim_aid_session *session;
+};
 
 struct sim_fs {
 	GQueue *op_q;
@@ -91,6 +92,20 @@ struct sim_fs {
 	GSList *contexts;
 };
 
+static void sim_fs_op_free(gpointer pointer)
+{
+	struct sim_fs_op *node = pointer;
+
+	/* only release the session if there are no pending reads */
+	if (node->context->session &&
+			g_queue_get_length(node->context->fs->op_q) == 0)
+		__ofono_sim_remove_session_watch(node->context->session,
+				node->watch_id);
+
+	g_free(node->buffer);
+	g_free(node);
+}
+
 void sim_fs_free(struct sim_fs *fs)
 {
 	if (fs == NULL)
@@ -121,11 +136,6 @@ struct file_watch {
 	int ef;
 };
 
-struct ofono_sim_context {
-	struct sim_fs *fs;
-	struct ofono_watchlist *file_watches;
-};
-
 struct sim_fs *sim_fs_new(struct ofono_sim *sim,
 				const struct ofono_sim_driver *driver)
 {
@@ -156,6 +166,23 @@ struct ofono_sim_context *sim_fs_context_new(struct sim_fs *fs)
 	return context;
 }
 
+struct ofono_sim_context *sim_fs_context_new_with_aid(struct sim_fs *fs,
+		unsigned char *aid)
+{
+	struct ofono_sim_context *context = sim_fs_context_new(fs);
+
+	if (context == NULL)
+		return NULL;
+
+	context->session = __ofono_sim_get_session_by_aid(fs->sim, aid);
+	if (!context->session) {
+		sim_fs_context_free(context);
+		return NULL;
+	}
+
+	return context;
+}
+
 void sim_fs_context_free(struct ofono_sim_context *context)
 {
 	struct sim_fs *fs = context->fs;
@@ -805,6 +832,97 @@ error:
 	return FALSE;
 }
 
+static void sim_fs_read_session_cb(const struct ofono_error *error,
+		const unsigned char *sdata, int length, void *data)
+{
+	struct sim_fs *fs = data;
+	struct sim_fs_op *op = g_queue_peek_head(fs->op_q);
+	ofono_sim_file_read_cb_t cb;
+
+	if (error->type != OFONO_ERROR_TYPE_NO_ERROR) {
+		sim_fs_op_error(fs);
+		return;
+	}
+
+	cb = op->cb;
+	cb(TRUE, length, 0, sdata, length, op->userdata);
+
+	sim_fs_end_current(fs);
+}
+
+static void session_read_info_cb(const struct ofono_error *error,
+					int filelength,
+					enum ofono_sim_file_structure structure,
+					int recordlength,
+					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, filelength, structure, recordlength,
+			access, file_status);
+
+	if (op->info_only) {
+		sim_fs_read_info_cb_t cb = op->cb;
+
+		cb(1, file_status, filelength, recordlength, op->userdata);
+
+		sim_fs_end_current(fs);
+		return;
+	}
+
+	if (op->structure == OFONO_SIM_FILE_STRUCTURE_TRANSPARENT) {
+		if (!fs->driver->session_read_binary) {
+			sim_fs_op_error(fs);
+			return;
+		}
+
+		fs->driver->session_read_binary(fs->sim, op->session_id,
+				op->id, op->offset, filelength, op->path,
+				op->path_len, sim_fs_read_session_cb, fs);
+	} else {
+		if (!fs->driver->session_read_record) {
+			sim_fs_op_error(fs);
+			return;
+		}
+
+		fs->driver->session_read_record(fs->sim, op->session_id,
+				op->id, op->offset, recordlength, op->path,
+				op->path_len, sim_fs_read_session_cb, fs);
+	}
+}
+
+static void get_session_cb(ofono_bool_t active, int session_id,
+		void *data)
+{
+	struct sim_fs *fs = data;
+	struct sim_fs_op *op;
+
+	if (!active) {
+		sim_fs_op_error(fs);
+		return;
+	}
+
+	op = g_queue_peek_head(fs->op_q);
+
+	op->session_id = session_id;
+
+	if (!fs->driver->session_read_info) {
+		sim_fs_op_error(fs);
+		return;
+	}
+
+	fs->driver->session_read_info(fs->sim, session_id, op->id, op->path,
+			op->path_len, session_read_info_cb, fs);
+}
+
 static gboolean sim_fs_op_next(gpointer user_data)
 {
 	struct sim_fs *fs = user_data;
@@ -827,10 +945,16 @@ static gboolean sim_fs_op_next(gpointer user_data)
 		if (sim_fs_op_check_cached(fs))
 			return FALSE;
 
-		driver->read_file_info(fs->sim, op->id,
-					op->path_len ? op->path : NULL,
-					op->path_len,
-					sim_fs_op_info_cb, fs);
+		if (!op->context->session) {
+			driver->read_file_info(fs->sim, op->id,
+						op->path_len ? op->path : NULL,
+						op->path_len,
+						sim_fs_op_info_cb, fs);
+		} else {
+			op->watch_id = __ofono_sim_add_session_watch(
+					op->context->session, get_session_cb,
+					fs, NULL);
+		}
 	} else {
 		switch (op->structure) {
 		case OFONO_SIM_FILE_STRUCTURE_TRANSPARENT:
diff --git a/src/simfs.h b/src/simfs.h
index bb3ab0f..39af6a3 100644
--- a/src/simfs.h
+++ b/src/simfs.h
@@ -29,6 +29,9 @@ 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);
 
+struct ofono_sim_context *sim_fs_context_new_with_aid(struct sim_fs *fs,
+		unsigned char *aid);
+
 unsigned int sim_fs_file_watch_add(struct ofono_sim_context *context,
 					int id, ofono_sim_file_changed_cb_t cb,
 					void *userdata,
-- 
2.7.4


^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2017-11-06 19:03 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-11-06 19:03 [PATCHv2] simfs: read files from specific AID's James Prestwood

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.