All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/8] simutil: Added ISIM elementary file ID's
@ 2017-11-01 17:33 James Prestwood
  2017-11-01 17:33 ` [PATCH 2/8] sim: header definitions for AID session APIs James Prestwood
                   ` (7 more replies)
  0 siblings, 8 replies; 11+ messages in thread
From: James Prestwood @ 2017-11-01 17:33 UTC (permalink / raw)
  To: ofono

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

---
 src/simutil.h | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/src/simutil.h b/src/simutil.h
index ece5145..e0b9d72 100644
--- a/src/simutil.h
+++ b/src/simutil.h
@@ -65,6 +65,17 @@ enum sim_fileid {
 	SIM_DFGSM_FILEID =			0x7F20,
 };
 
+enum sim_isim_fileid {
+	SIM_ISIM_EFIMPI_FILEID =		0x6F02,
+	SIM_ISIM_EFDOMAIN_FILEID =		0x6F03,
+	SIM_ISIM_EFIMPU_FILEID =		0x6F04,
+	SIM_ISIM_EFARR_FILEID =			0x6F06,
+	SIM_ISIM_EFIST_FILEID =			0x6F07,
+	SIM_ISIM_EFPCSCF_FILEID =		0x6F09,
+	SIM_ISIM_EFSMS_FILEID =			0x6F3C,
+	SIM_ISIM_EFSMSP_FILEID =		0x6F42
+};
+
 /* 51.011 Section 9.3 */
 enum sim_file_access {
 	SIM_FILE_ACCESS_ALWAYS =	0,
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 2/8] sim: header definitions for AID session APIs
  2017-11-01 17:33 [PATCH 1/8] simutil: Added ISIM elementary file ID's James Prestwood
@ 2017-11-01 17:33 ` James Prestwood
  2017-11-02 16:55   ` Denis Kenzior
  2017-11-01 17:33 ` [PATCH 3/8] sim: AID session management James Prestwood
                   ` (6 subsequent siblings)
  7 siblings, 1 reply; 11+ messages in thread
From: James Prestwood @ 2017-11-01 17:33 UTC (permalink / raw)
  To: ofono

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

ISIM and newer AID's require opening a logical channel to read
their EF's. This requires new driver API's to discover AID's,
open/close a channel, and reading the EF's from an opened channel.

This functionality was moved from the simauth module.
---
 include/sim.h | 28 ++++++++++++++++++++++++++++
 1 file changed, 28 insertions(+)

diff --git a/include/sim.h b/include/sim.h
index 0c91ce2..aeceef6 100644
--- a/include/sim.h
+++ b/include/sim.h
@@ -121,6 +121,17 @@ typedef void (*ofono_sim_lock_unlock_cb_t)(const struct ofono_error *error,
 typedef void (*ofono_query_facility_lock_cb_t)(const struct ofono_error *error,
 					ofono_bool_t status, void *data);
 
+typedef void (*ofono_sim_list_apps_cb_t)(const struct ofono_error *error,
+					const unsigned char *dataobj,
+					int len, void *data);
+typedef void (*ofono_sim_open_channel_cb_t)(const struct ofono_error *error,
+					int session_id, void *data);
+
+typedef void (*ofono_sim_close_channel_cb_t)(const struct ofono_error *error,
+					void *data);
+
+typedef void (*ofono_sim_get_session_cb_t)(int session, void *data);
+
 struct ofono_sim_driver {
 	const char *name;
 	int (*probe)(struct ofono_sim *sim, unsigned int vendor, void *data);
@@ -173,6 +184,16 @@ struct ofono_sim_driver {
 	void (*query_facility_lock)(struct ofono_sim *sim,
 			enum ofono_sim_password_type lock,
 			ofono_query_facility_lock_cb_t cb, void *data);
+	void (*list_apps)(struct ofono_sim *sim,
+			ofono_sim_list_apps_cb_t cb, void *data);
+	void (*open_channel)(struct ofono_sim *sim, const unsigned char *aid,
+			ofono_sim_open_channel_cb_t cb, void *data);
+	void (*close_channel)(struct ofono_sim *sim, int session_id,
+			ofono_sim_close_channel_cb_t cb, void *data);
+	void (*read_file_session)(struct ofono_sim *sim, int session,
+			int fileid, int start, int length,
+			const unsigned char *path, unsigned int path_len,
+			ofono_sim_read_cb_t cb, void *data);
 };
 
 int ofono_sim_driver_register(const struct ofono_sim_driver *d);
@@ -248,6 +269,13 @@ unsigned int ofono_sim_add_file_watch(struct ofono_sim_context *context,
 void ofono_sim_remove_file_watch(struct ofono_sim_context *context,
 					unsigned int id);
 
+struct sim_app_record **ofono_sim_get_aid_list(struct ofono_sim *sim);
+
+int ofono_sim_get_session(struct ofono_sim *sim, unsigned char *aid,
+		ofono_sim_get_session_cb_t cb, void *data);
+
+int ofono_sim_release_session(struct ofono_sim *sim, int session_id);
+
 #ifdef __cplusplus
 }
 #endif
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 3/8] sim: AID session management
  2017-11-01 17:33 [PATCH 1/8] simutil: Added ISIM elementary file ID's James Prestwood
  2017-11-01 17:33 ` [PATCH 2/8] sim: header definitions for AID session APIs James Prestwood
@ 2017-11-01 17:33 ` James Prestwood
  2017-11-02 17:10   ` Denis Kenzior
  2017-11-01 17:33 ` [PATCH 4/8] atmodem: implement new driver APIs for AID sessions James Prestwood
                   ` (5 subsequent siblings)
  7 siblings, 1 reply; 11+ messages in thread
From: James Prestwood @ 2017-11-01 17:33 UTC (permalink / raw)
  To: ofono

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

Accessing an AID requires opening a channel to that application.
This patch implements session management API's so that other atoms
can access a given AID. Now any atom can get a session ID from the
sim atom. This will either reuse an existing session or open a new
channel. Once done, the atom should release the session which will
automatically close the channel when no atoms are using it.

The major functional change to the sim atom is the AID discovery
phase of initialization. Now, the sim atom is not 'ready' until AID
discovery finishes where before, the sim was 'ready' after the IMSI
had been obtained. If application discovery is not supported then
the the sim atom behaves as it did before.
---
 src/sim.c | 204 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 204 insertions(+)

diff --git a/src/sim.c b/src/sim.c
index 88c0421..53eb048 100644
--- a/src/sim.c
+++ b/src/sim.c
@@ -48,6 +48,25 @@
 
 #define SIM_FLAG_READING_SPN	0x1
 
+/*
+ * A new session object will be created if a USim/ISim applications are
+ * found during app discovery. Any concurrent file/logical access to
+ * these applications will share the same session ID.
+ */
+struct ofono_aid_session {
+	struct sim_app_record record;
+	struct ofono_sim_context *context;
+	int session_id;
+	int ref;
+};
+
+/* callback data for opening a new session */
+struct sdata {
+	void *data;
+	ofono_sim_get_session_cb_t cb;
+	struct ofono_aid_session *session;
+};
+
 struct ofono_sim {
 	int flags;
 
@@ -114,6 +133,8 @@ struct ofono_sim {
 	void *driver_data;
 	struct ofono_atom *atom;
 	unsigned int hfp_watch;
+
+	GSList *aid_sessions;
 };
 
 struct msisdn_set_request {
@@ -1434,6 +1455,36 @@ static void sim_set_ready(struct ofono_sim *sim)
 	call_state_watches(sim);
 }
 
+static void discover_apps_cb(const struct ofono_error *error,
+		const unsigned char *dataobj,
+		int len, void *data)
+{
+	GSList *list;
+	GSList *iter;
+	struct ofono_sim *sim = data;
+
+	if (error->type != OFONO_ERROR_TYPE_NO_ERROR)
+		return;
+
+	list = sim_parse_app_template_entries(dataobj, len);
+	iter = list;
+
+	while (iter) {
+		struct sim_app_record *app = iter->data;
+		struct ofono_aid_session *s = g_try_new0(
+				struct ofono_aid_session, 1);
+
+		memcpy(&s->record, app, sizeof(struct sim_app_record));
+		sim->aid_sessions = g_slist_prepend(sim->aid_sessions, s);
+
+		g_free(app);
+
+		iter = g_slist_next(iter);
+	}
+
+	g_slist_free(list);
+}
+
 static void sim_imsi_obtained(struct ofono_sim *sim, const char *imsi)
 {
 	DBusConnection *conn = ofono_dbus_get_connection();
@@ -1844,6 +1895,12 @@ static void sim_initialize_after_pin(struct ofono_sim *sim)
 {
 	sim->context = ofono_sim_context_create(sim);
 
+	/*
+	 * Discover applications on SIM
+	 */
+	if (sim->driver->list_apps)
+		sim->driver->list_apps(sim, discover_apps_cb, sim);
+
 	ofono_sim_read(sim->context, SIM_EFPHASE_FILEID,
 			OFONO_SIM_FILE_STRUCTURE_TRANSPARENT,
 			sim_efphase_read_cb, sim);
@@ -2450,6 +2507,9 @@ static void sim_free_main_state(struct ofono_sim *sim)
 		ofono_sim_context_free(sim->context);
 		sim->context = NULL;
 	}
+
+	if (sim->aid_sessions)
+		g_slist_free(sim->aid_sessions);
 }
 
 static void sim_free_state(struct ofono_sim *sim)
@@ -3304,3 +3364,147 @@ void __ofono_sim_refresh(struct ofono_sim *sim, GSList *file_list,
 		}
 	}
 }
+
+struct sim_app_record **ofono_sim_get_aid_list(struct ofono_sim *sim)
+{
+	GSList *iter = sim->aid_sessions;
+	int len;
+	struct sim_app_record **ret;
+	int i = 0;
+
+	if (!iter) {
+		DBG("AID list not found");
+		return NULL;
+	}
+
+	len = g_slist_length(iter);
+	ret = g_try_new0(struct sim_app_record *,
+			len + 1);
+
+	while (iter) {
+		struct ofono_aid_session *s = iter->data;
+
+		ret[i++] = &s->record;
+
+		iter = g_slist_next(iter);
+	}
+
+	return ret;
+}
+
+static struct ofono_aid_session *find_session_by_aid(struct ofono_sim *sim,
+		unsigned char *aid)
+{
+	GSList *iter = sim->aid_sessions;
+
+	while (iter) {
+		struct ofono_aid_session *session = iter->data;
+
+		if (!memcmp(session->record.aid, aid, 16))
+			return session;
+
+		iter = g_slist_next(iter);
+	}
+
+	return NULL;
+}
+
+static struct ofono_aid_session *find_session_by_id(struct ofono_sim *sim,
+		int session_id)
+{
+	GSList *iter = sim->aid_sessions;
+
+	while (iter) {
+		struct ofono_aid_session *session = iter->data;
+
+		if (session->session_id == session_id)
+			return session;
+
+		iter = g_slist_next(iter);
+	}
+
+	return NULL;
+}
+
+static struct sdata *cb_data_new(ofono_sim_get_session_cb_t cb, void *data,
+		struct ofono_aid_session *session)
+{
+	struct sdata *cbd = g_try_new0(struct sdata, 1);
+
+	cbd->cb = cb;
+	cbd->data = data;
+	cbd->session = session;
+
+	return cbd;
+}
+
+static void open_channel_cb(const struct ofono_error *error, int session_id,
+		void *data)
+{
+	struct sdata *cbd = data;
+	struct ofono_aid_session *session = cbd->session;
+
+	if (error->type != OFONO_ERROR_TYPE_NO_ERROR) {
+		session->ref = 0;
+		session->session_id = -1;
+		goto end;
+	}
+
+	session->session_id = session_id;
+
+end:
+	cbd->cb(session->session_id, cbd->data);
+
+	g_free(cbd);
+}
+
+int ofono_sim_get_session(struct ofono_sim *sim, unsigned char *aid,
+		ofono_sim_get_session_cb_t cb, void *data)
+{
+	struct sdata *cbd;
+	struct ofono_aid_session *session = find_session_by_aid(sim, aid);
+
+	if (!session) {
+		DBG("AID not found");
+		return 0;
+	}
+
+	if (!sim->driver->open_channel || !sim->driver->close_channel) {
+		DBG("sim driver does not support opening logical channels");
+		return 0;
+	}
+
+	/* increase ref to ensure the session doesn't get cleaned up */
+	session->ref++;
+
+	if (session->session_id == 0) {
+		/* AID found but no session has been opened */
+		cbd = cb_data_new(cb, data, session);
+		sim->driver->open_channel(sim, aid, open_channel_cb, cbd);
+	} else {
+		cb(session->session_id, data);
+	}
+
+	return 1;
+}
+
+int ofono_sim_release_session(struct ofono_sim *sim, int session_id)
+{
+	struct ofono_aid_session *session = find_session_by_id(sim, session_id);
+
+	if (!session) {
+		DBG("Session %d not found", session_id);
+		return 0;
+	}
+
+	session->ref--;
+
+	/* if nobody is using this session, close the channel */
+	if (session->ref <= 0) {
+		sim->driver->close_channel(sim, session_id, NULL, NULL);
+		session->session_id = 0;
+		session->ref = 0;
+	}
+
+	return 1;
+}
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 4/8] atmodem: implement new driver APIs for AID sessions
  2017-11-01 17:33 [PATCH 1/8] simutil: Added ISIM elementary file ID's James Prestwood
  2017-11-01 17:33 ` [PATCH 2/8] sim: header definitions for AID session APIs James Prestwood
  2017-11-01 17:33 ` [PATCH 3/8] sim: AID session management James Prestwood
@ 2017-11-01 17:33 ` James Prestwood
  2017-11-01 17:33 ` [PATCH 5/8] simfs: read files from specific AID's James Prestwood
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 11+ messages in thread
From: James Prestwood @ 2017-11-01 17:33 UTC (permalink / raw)
  To: ofono

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

Implementation for open/close channel, list applications,
and session based file read.
---
 drivers/atmodem/sim.c | 236 ++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 236 insertions(+)

diff --git a/drivers/atmodem/sim.c b/drivers/atmodem/sim.c
index 6395a04..ee03fc8 100644
--- a/drivers/atmodem/sim.c
+++ b/drivers/atmodem/sim.c
@@ -39,6 +39,7 @@
 #include "gatresult.h"
 #include "simutil.h"
 #include "vendor.h"
+#include "util.h"
 
 #include "atmodem.h"
 
@@ -69,6 +70,9 @@ static const char *pct_prefix[] = { "#PCT:", NULL };
 static const char *pnnm_prefix[] = { "+PNNM:", NULL };
 static const char *qpinc_prefix[] = { "+QPINC:", NULL };
 static const char *upincnt_prefix[] = { "+UPINCNT:", NULL };
+static const char *cuad_prefix[] = { "+CUAD:", NULL };
+static const char *ccho_prefix[] = { "+CCHO:", NULL };
+static const char *crla_prefix[] = { "+CRLA:", NULL };
 static const char *none_prefix[] = { NULL };
 
 static void at_crsm_info_cb(gboolean ok, GAtResult *result, gpointer user_data)
@@ -1568,6 +1572,234 @@ error:
 	CALLBACK_WITH_FAILURE(cb, -1, data);
 }
 
+static void at_discover_apps_cb(gboolean ok, GAtResult *result,
+				gpointer user_data)
+{
+	struct cb_data *cbd = user_data;
+	GAtResultIter iter;
+	ofono_sim_list_apps_cb_t cb = cbd->cb;
+	struct ofono_error error;
+	const unsigned char *dataobj;
+	gint linelen;
+	unsigned char *buffer;
+	int len;
+
+	decode_at_error(&error, g_at_result_final_response(result));
+
+	if (!ok) {
+		cb(&error, NULL, 0, cbd->data);
+		return;
+	}
+
+	g_at_result_iter_init(&iter, result);
+
+	len = 0;
+	while (g_at_result_iter_next(&iter, "+CUAD:")) {
+		if (!g_at_result_iter_next_hexstring(&iter, NULL, &linelen))
+			goto error;
+
+		len += linelen;
+	}
+
+	g_at_result_iter_init(&iter, result);
+
+	buffer = g_malloc(len);
+	len = 0;
+
+	while (g_at_result_iter_next(&iter, "+CUAD:")) {
+		g_at_result_iter_next_hexstring(&iter, &dataobj, &linelen);
+		memcpy(buffer + len, dataobj, linelen);
+		len += linelen;
+	}
+
+	cb(&error, buffer, len, cbd->data);
+
+	g_free(buffer);
+	return;
+
+error:
+	CALLBACK_WITH_FAILURE(cb, NULL, 0, cbd->data);
+}
+
+static void at_discover_apps(struct ofono_sim *sim,
+				ofono_sim_list_apps_cb_t cb,
+				void *data)
+{
+	struct sim_data *sd = ofono_sim_get_data(sim);
+	struct cb_data *cbd = cb_data_new(cb, data);
+
+	if (g_at_chat_send(sd->chat, "AT+CUAD", cuad_prefix,
+			at_discover_apps_cb, cbd, g_free) > 0)
+		return;
+
+	g_free(cbd);
+
+	CALLBACK_WITH_FAILURE(cb, NULL, 0, data);
+}
+
+static void at_open_channel_cb(gboolean ok, GAtResult *result,
+		gpointer user_data)
+{
+	struct cb_data *cbd = user_data;
+	GAtResultIter iter;
+	ofono_sim_open_channel_cb_t cb = cbd->cb;
+	struct ofono_error error;
+	int session_id = -1;
+
+	decode_at_error(&error, g_at_result_final_response(result));
+
+	if (!ok)
+		goto error;
+
+	g_at_result_iter_init(&iter, result);
+
+	if (!g_at_result_iter_next(&iter, "+CCHO:"))
+		goto error;
+
+	if (!g_at_result_iter_next_number(&iter, &session_id))
+		goto error;
+
+	cb(&error, session_id, cbd->data);
+
+	return;
+
+error:
+	cb(&error, -1, cbd->data);
+}
+
+static void at_open_channel(struct ofono_sim *sim, const unsigned char *aid,
+		ofono_sim_open_channel_cb_t cb, void *data)
+{
+	struct sim_data *sd = ofono_sim_get_data(sim);
+	struct cb_data *cbd = cb_data_new(cb, data);
+	char cmd[43];
+	int ret = 0;
+
+	strcpy(cmd, "AT+CCHO=\"");
+	ret += 9;
+
+	encode_hex_own_buf(aid, 16, 0, cmd + ret);
+	ret += 32;
+
+	strcpy(cmd + ret, "\"");
+
+	if (g_at_chat_send(sd->chat, cmd, ccho_prefix, at_open_channel_cb,
+			cbd, g_free) > 0)
+		return;
+
+	g_free(cbd);
+
+	CALLBACK_WITH_FAILURE(cb, -1, data);
+}
+
+static void at_close_channel_cb(gboolean ok, GAtResult *result,
+		gpointer user_data)
+{
+	struct cb_data *cbd = user_data;
+	ofono_sim_close_channel_cb_t cb = cbd->cb;
+	struct ofono_error error;
+
+	decode_at_error(&error, g_at_result_final_response(result));
+
+	if (cb)
+		cb(&error, cbd->data);
+}
+
+static void at_close_channel(struct ofono_sim *sim, int session_id,
+		ofono_sim_close_channel_cb_t cb, void *data)
+{
+	struct sim_data *sd = ofono_sim_get_data(sim);
+	struct cb_data *cbd = cb_data_new(cb, data);
+	char cmd[15];
+
+	sprintf(cmd, "AT+CCHC=%d", session_id);
+
+	g_at_chat_send(sd->chat, cmd, NULL, at_close_channel_cb, cbd, g_free);
+}
+
+static void at_crla_read_cb(gboolean ok, GAtResult *result,
+				gpointer user_data)
+{
+	struct cb_data *cbd = user_data;
+	GAtResultIter iter;
+	ofono_sim_read_cb_t cb = cbd->cb;
+	struct ofono_error error;
+	const guint8 *response;
+	gint sw1, sw2, len;
+
+	decode_at_error(&error, g_at_result_final_response(result));
+
+	if (!ok) {
+		cb(&error, NULL, 0, cbd->data);
+		return;
+	}
+
+	g_at_result_iter_init(&iter, result);
+
+	if (!g_at_result_iter_next(&iter, "+CRLA:")) {
+		CALLBACK_WITH_FAILURE(cb, NULL, 0, cbd->data);
+		return;
+	}
+
+	g_at_result_iter_next_number(&iter, &sw1);
+	g_at_result_iter_next_number(&iter, &sw2);
+
+	if ((sw1 != 0x90 && sw1 != 0x91 && sw1 != 0x92 && sw1 != 0x9f) ||
+			(sw1 == 0x90 && sw2 != 0x00)) {
+		memset(&error, 0, sizeof(error));
+
+		error.type = OFONO_ERROR_TYPE_SIM;
+		error.error = (sw1 << 8) | sw2;
+
+		cb(&error, NULL, 0, cbd->data);
+		return;
+	}
+
+	if (!g_at_result_iter_next_hexstring(&iter, &response, &len)) {
+		CALLBACK_WITH_FAILURE(cb, NULL, 0, cbd->data);
+		return;
+	}
+
+	DBG("crla_read_cb: %02x, %02x, %d", sw1, sw2, len);
+
+	cb(&error, response, len, cbd->data);
+}
+
+static void at_read_file_session(struct ofono_sim *sim, int session,
+				int fileid, int start, int length,
+				const unsigned char *path,
+				unsigned int path_len,
+				ofono_sim_read_cb_t cb, void *data)
+{
+	struct sim_data *sd = ofono_sim_get_data(sim);
+	struct cb_data *cbd = cb_data_new(cb, data);
+	char buf[64];
+	unsigned int len;
+
+	len = snprintf(buf, sizeof(buf), "AT+CRLA=%i,176,%i,%i,%i,%i,,",
+			session, fileid, start >> 8, start & 0xff, length);
+
+	if (path_len > 0) {
+		buf[len++] = ',';
+		buf[len++] = ',';
+		buf[len++] = '\"';
+
+		for (; path_len; path_len--)
+			len += sprintf(buf + len, "%02hhX", *path++);
+
+		buf[len++] = '\"';
+		buf[len] = '\0';
+	}
+
+	if (g_at_chat_send(sd->chat, buf, crla_prefix,
+			at_crla_read_cb, cbd, g_free) > 0)
+		return;
+
+	g_free(cbd);
+
+	CALLBACK_WITH_FAILURE(cb, NULL, 0, data);
+}
+
 static gboolean at_sim_register(gpointer user)
 {
 	struct ofono_sim *sim = user;
@@ -1629,6 +1861,10 @@ static struct ofono_sim_driver driver = {
 	.lock			= at_pin_enable,
 	.change_passwd		= at_change_passwd,
 	.query_facility_lock	= at_query_clck,
+	.list_apps		= at_discover_apps,
+	.open_channel		= at_open_channel,
+	.close_channel		= at_close_channel,
+	.read_file_session	= at_read_file_session
 };
 
 static struct ofono_sim_driver driver_noef = {
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 5/8] simfs: read files from specific AID's
  2017-11-01 17:33 [PATCH 1/8] simutil: Added ISIM elementary file ID's James Prestwood
                   ` (2 preceding siblings ...)
  2017-11-01 17:33 ` [PATCH 4/8] atmodem: implement new driver APIs for AID sessions James Prestwood
@ 2017-11-01 17:33 ` James Prestwood
  2017-11-01 17:33 ` [PATCH 6/8] sim: header definitions for AID sim context API James Prestwood
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 11+ messages in thread
From: James Prestwood @ 2017-11-01 17:33 UTC (permalink / raw)
  To: ofono

[-- Attachment #1: Type: text/plain, Size: 3901 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 | 72 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++----
 src/simfs.h |  3 +++
 2 files changed, 71 insertions(+), 4 deletions(-)

diff --git a/src/simfs.c b/src/simfs.c
index 37a232a..6b70df0 100644
--- a/src/simfs.c
+++ b/src/simfs.c
@@ -124,6 +124,7 @@ struct file_watch {
 struct ofono_sim_context {
 	struct sim_fs *fs;
 	struct ofono_watchlist *file_watches;
+	unsigned char *aid;
 };
 
 struct sim_fs *sim_fs_new(struct ofono_sim *sim,
@@ -156,6 +157,19 @@ 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->aid = g_memdup(aid, 16);
+
+	return context;
+}
+
 void sim_fs_context_free(struct ofono_sim_context *context)
 {
 	struct sim_fs *fs = context->fs;
@@ -181,6 +195,9 @@ void sim_fs_context_free(struct ofono_sim_context *context)
 		}
 	}
 
+	if (context->aid)
+		g_free(context->aid);
+
 	if (context->file_watches)
 		__ofono_watchlist_free(context->file_watches);
 
@@ -805,6 +822,43 @@ 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);
+}
+
+static void get_session_cb(int session_id, void *data)
+{
+	struct sim_fs *fs = data;
+	struct sim_fs_op *op;
+
+	if (session_id == -1) {
+		sim_fs_op_error(fs);
+		return;
+	}
+
+	fs->op_source = 0;
+
+	op = g_queue_peek_head(fs->op_q);
+
+	fs->driver->read_file_session(fs->sim, session_id, op->id, op->offset,
+			op->num_bytes, op->path, op->path_len,
+			sim_fs_read_session_cb, fs);
+
+	ofono_sim_release_session(fs->sim, session_id);
+}
+
 static gboolean sim_fs_op_next(gpointer user_data)
 {
 	struct sim_fs *fs = user_data;
@@ -827,10 +881,20 @@ 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->aid == NULL) {
+			driver->read_file_info(fs->sim, op->id,
+						op->path_len ? op->path : NULL,
+						op->path_len,
+						sim_fs_op_info_cb, fs);
+		} else {
+			if (!ofono_sim_get_session(fs->sim, op->context->aid,
+					get_session_cb, fs)) {
+				ofono_sim_file_read_cb_t cb = op->cb;
+
+				DBG("Could not get session for AID");
+				cb(FALSE, 0, 0, NULL, 0, op->userdata);
+			}
+		}
 	} 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] 11+ messages in thread

* [PATCH 6/8] sim: header definitions for AID sim context API
  2017-11-01 17:33 [PATCH 1/8] simutil: Added ISIM elementary file ID's James Prestwood
                   ` (3 preceding siblings ...)
  2017-11-01 17:33 ` [PATCH 5/8] simfs: read files from specific AID's James Prestwood
@ 2017-11-01 17:33 ` James Prestwood
  2017-11-01 17:33 ` [PATCH 7/8] sim: implement create context with AID James Prestwood
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 11+ messages in thread
From: James Prestwood @ 2017-11-01 17:33 UTC (permalink / raw)
  To: ofono

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

This will allow an atom to create a SIM context to a specific
AID on the sim, which it can then access EF's on through the
context.
---
 include/sim.h | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/include/sim.h b/include/sim.h
index aeceef6..30f6c2d 100644
--- a/include/sim.h
+++ b/include/sim.h
@@ -239,6 +239,10 @@ ofono_bool_t ofono_sim_remove_spn_watch(struct ofono_sim *sim, unsigned int *id)
 void ofono_sim_inserted_notify(struct ofono_sim *sim, ofono_bool_t inserted);
 
 struct ofono_sim_context *ofono_sim_context_create(struct ofono_sim *sim);
+
+struct ofono_sim_context *ofono_sim_context_create_isim(
+		struct ofono_sim *sim);
+
 void ofono_sim_context_free(struct ofono_sim_context *context);
 
 /* This will queue an operation to read all available records with id from the
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 7/8] sim: implement create context with AID
  2017-11-01 17:33 [PATCH 1/8] simutil: Added ISIM elementary file ID's James Prestwood
                   ` (4 preceding siblings ...)
  2017-11-01 17:33 ` [PATCH 6/8] sim: header definitions for AID sim context API James Prestwood
@ 2017-11-01 17:33 ` James Prestwood
  2017-11-01 17:33 ` [PATCH 8/8] sim: added NetworkAccessIdentifier to SimManager James Prestwood
  2017-11-02 16:40 ` [PATCH 1/8] simutil: Added ISIM elementary file ID's Denis Kenzior
  7 siblings, 0 replies; 11+ messages in thread
From: James Prestwood @ 2017-11-01 17:33 UTC (permalink / raw)
  To: ofono

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

API to create a sim context for a given AID. This AID based
context is only relevant for an ISIM application, so during
AID discovery, if an ISIM is found, a new fs object is
initialized for the ISIM. If any atom wants to create an
AID based context for the ISIM AID, the ISIM fs object will
be used.
---
 src/sim.c | 41 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 41 insertions(+)

diff --git a/src/sim.c b/src/sim.c
index 53eb048..8b466c9 100644
--- a/src/sim.c
+++ b/src/sim.c
@@ -122,6 +122,7 @@ struct ofono_sim {
 	unsigned int cphs_spn_short_watch;
 
 	struct sim_fs *simfs;
+	struct sim_fs *simfs_isim;
 	struct ofono_sim_context *context;
 	struct ofono_sim_context *early_context;
 
@@ -1477,6 +1478,14 @@ static void discover_apps_cb(const struct ofono_error *error,
 		memcpy(&s->record, app, sizeof(struct sim_app_record));
 		sim->aid_sessions = g_slist_prepend(sim->aid_sessions, s);
 
+		if (app->type == SIM_APP_TYPE_ISIM) {
+			/*
+			 * If an ISIM application is found, we should init
+			 * the FS structure so the ISIM EF's can be accessed.
+			 */
+			sim->simfs_isim = sim_fs_new(sim, sim->driver);
+		}
+
 		g_free(app);
 
 		iter = g_slist_next(iter);
@@ -2235,6 +2244,36 @@ struct ofono_sim_context *ofono_sim_context_create(struct ofono_sim *sim)
 	return sim_fs_context_new(sim->simfs);
 }
 
+struct ofono_sim_context *ofono_sim_context_create_isim(
+		struct ofono_sim *sim)
+{
+	GSList *iter = sim->aid_sessions;
+
+	if (sim == NULL || sim->simfs_isim == NULL)
+		return NULL;
+
+	/*
+	 * Check if the AID is even valid
+	 */
+	while (iter) {
+		struct sim_app_record *app = iter->data;
+
+		/*
+		 * This AID based context is only relevant for an ISIM AID. A
+		 * USIM application can be accessed with the 'default' FS
+		 * context API's.
+		 */
+		if (app->type == SIM_APP_TYPE_ISIM) {
+			return sim_fs_context_new_with_aid(sim->simfs_isim,
+					app->aid);
+		}
+
+		iter = g_slist_next(iter);
+	}
+
+	return NULL;
+}
+
 void ofono_sim_context_free(struct ofono_sim_context *context)
 {
 	return sim_fs_context_free(context);
@@ -3056,6 +3095,8 @@ static void sim_remove(struct ofono_atom *atom)
 
 	sim_fs_free(sim->simfs);
 	sim->simfs = NULL;
+	sim_fs_free(sim->simfs_isim);
+	sim->simfs_isim = NULL;
 
 	g_free(sim);
 }
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 8/8] sim: added NetworkAccessIdentifier to SimManager
  2017-11-01 17:33 [PATCH 1/8] simutil: Added ISIM elementary file ID's James Prestwood
                   ` (5 preceding siblings ...)
  2017-11-01 17:33 ` [PATCH 7/8] sim: implement create context with AID James Prestwood
@ 2017-11-01 17:33 ` James Prestwood
  2017-11-02 16:40 ` [PATCH 1/8] simutil: Added ISIM elementary file ID's Denis Kenzior
  7 siblings, 0 replies; 11+ messages in thread
From: James Prestwood @ 2017-11-01 17:33 UTC (permalink / raw)
  To: ofono

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

EAP-SIM/AKA/AKA' requires the SIM's NAI to authenticate.
If available, this can be obtained from the ISIM AID.

If the ISIM AID is found a new AID based context will be
created and the EFIMPI file will be read from the SIM
which contains the NAI.
---
 src/sim.c | 39 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 39 insertions(+)

diff --git a/src/sim.c b/src/sim.c
index 8b466c9..f09c550 100644
--- a/src/sim.c
+++ b/src/sim.c
@@ -125,6 +125,7 @@ struct ofono_sim {
 	struct sim_fs *simfs_isim;
 	struct ofono_sim_context *context;
 	struct ofono_sim_context *early_context;
+	struct ofono_sim_context *isim_context;
 
 	unsigned char *iidf_image;
 	unsigned int *iidf_watch_ids;
@@ -136,6 +137,7 @@ struct ofono_sim {
 	unsigned int hfp_watch;
 
 	GSList *aid_sessions;
+	char *nai;
 };
 
 struct msisdn_set_request {
@@ -407,6 +409,10 @@ static DBusMessage *sim_get_properties(DBusConnection *conn,
 		ofono_dbus_dict_append(&dict, "ServiceProviderName",
 					DBUS_TYPE_STRING, &sim->spn);
 
+	if (sim->nai)
+		ofono_dbus_dict_append(&dict, "NetworkAccessIdentifier",
+					DBUS_TYPE_STRING, &sim->nai);
+
 	fdn = sim->fixed_dialing;
 	ofono_dbus_dict_append(&dict, "FixedDialing", DBUS_TYPE_BOOLEAN, &fdn);
 
@@ -1456,6 +1462,25 @@ static void sim_set_ready(struct ofono_sim *sim)
 	call_state_watches(sim);
 }
 
+static void impi_read_cb(int ok, int total_length, int record,
+		const unsigned char *data,
+		int record_length, void *userdata)
+{
+	struct ofono_sim *sim = userdata;
+
+	if (!ok) {
+		DBG("error reading IMPI");
+		return;
+	}
+
+	if (data[0] != 0x80) {
+		DBG("invalid TLV tag 0x%02x", data[0]);
+		return;
+	}
+
+	sim->nai = g_strndup((const char *)data + 2, data[1]);
+}
+
 static void discover_apps_cb(const struct ofono_error *error,
 		const unsigned char *dataobj,
 		int len, void *data)
@@ -1484,6 +1509,12 @@ static void discover_apps_cb(const struct ofono_error *error,
 			 * the FS structure so the ISIM EF's can be accessed.
 			 */
 			sim->simfs_isim = sim_fs_new(sim, sim->driver);
+			sim->isim_context = ofono_sim_context_create_isim(
+					sim);
+			/* attempt to get the NAI from EFimpi */
+			ofono_sim_read_bytes(sim->isim_context,
+					SIM_ISIM_EFIMPI_FILEID, 0, 255, NULL,
+					0, impi_read_cb, sim);
 		}
 
 		g_free(app);
@@ -2547,6 +2578,14 @@ static void sim_free_main_state(struct ofono_sim *sim)
 		sim->context = NULL;
 	}
 
+	if (sim->isim_context) {
+		ofono_sim_context_free(sim->isim_context);
+		sim->isim_context = NULL;
+	}
+
+	if (sim->nai)
+		g_free(sim->nai);
+
 	if (sim->aid_sessions)
 		g_slist_free(sim->aid_sessions);
 }
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* Re: [PATCH 1/8] simutil: Added ISIM elementary file ID's
  2017-11-01 17:33 [PATCH 1/8] simutil: Added ISIM elementary file ID's James Prestwood
                   ` (6 preceding siblings ...)
  2017-11-01 17:33 ` [PATCH 8/8] sim: added NetworkAccessIdentifier to SimManager James Prestwood
@ 2017-11-02 16:40 ` Denis Kenzior
  7 siblings, 0 replies; 11+ messages in thread
From: Denis Kenzior @ 2017-11-02 16:40 UTC (permalink / raw)
  To: ofono

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

Hi James,

On 11/01/2017 12:33 PM, James Prestwood wrote:
> ---
>   src/simutil.h | 11 +++++++++++
>   1 file changed, 11 insertions(+)
> 

Applied, thanks.

Regards,
-Denis


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 2/8] sim: header definitions for AID session APIs
  2017-11-01 17:33 ` [PATCH 2/8] sim: header definitions for AID session APIs James Prestwood
@ 2017-11-02 16:55   ` Denis Kenzior
  0 siblings, 0 replies; 11+ messages in thread
From: Denis Kenzior @ 2017-11-02 16:55 UTC (permalink / raw)
  To: ofono

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

Hi James,

On 11/01/2017 12:33 PM, James Prestwood wrote:
> ISIM and newer AID's require opening a logical channel to read
> their EF's. This requires new driver API's to discover AID's,
> open/close a channel, and reading the EF's from an opened channel.
> 
> This functionality was moved from the simauth module.
> ---
>   include/sim.h | 28 ++++++++++++++++++++++++++++
>   1 file changed, 28 insertions(+)
> 
> diff --git a/include/sim.h b/include/sim.h
> index 0c91ce2..aeceef6 100644
> --- a/include/sim.h
> +++ b/include/sim.h
> @@ -121,6 +121,17 @@ typedef void (*ofono_sim_lock_unlock_cb_t)(const struct ofono_error *error,
>   typedef void (*ofono_query_facility_lock_cb_t)(const struct ofono_error *error,
>   					ofono_bool_t status, void *data);
>   
> +typedef void (*ofono_sim_list_apps_cb_t)(const struct ofono_error *error,
> +					const unsigned char *dataobj,
> +					int len, void *data);
> +typedef void (*ofono_sim_open_channel_cb_t)(const struct ofono_error *error,
> +					int session_id, void *data);
> +
> +typedef void (*ofono_sim_close_channel_cb_t)(const struct ofono_error *error,
> +					void *data);
> +
> +typedef void (*ofono_sim_get_session_cb_t)(int session, void *data);
> +
>   struct ofono_sim_driver {
>   	const char *name;
>   	int (*probe)(struct ofono_sim *sim, unsigned int vendor, void *data);
> @@ -173,6 +184,16 @@ struct ofono_sim_driver {
>   	void (*query_facility_lock)(struct ofono_sim *sim,
>   			enum ofono_sim_password_type lock,
>   			ofono_query_facility_lock_cb_t cb, void *data);
> +	void (*list_apps)(struct ofono_sim *sim,
> +			ofono_sim_list_apps_cb_t cb, void *data);
> +	void (*open_channel)(struct ofono_sim *sim, const unsigned char *aid,
> +			ofono_sim_open_channel_cb_t cb, void *data);
> +	void (*close_channel)(struct ofono_sim *sim, int session_id,
> +			ofono_sim_close_channel_cb_t cb, void *data);
> +	void (*read_file_session)(struct ofono_sim *sim, int session,
> +			int fileid, int start, int length,
> +			const unsigned char *path, unsigned int path_len,
> +			ofono_sim_read_cb_t cb, void *data);

Hmm, we still would need read_file_info, read_file_record equivalents 
no?  E.g. +CRLA 176, 178 and 192 equivalents to +CRSM 176, 178 and 192.

Perhaps session_read_binary, session_read_record, session_get_response?

>   };
>   
>   int ofono_sim_driver_register(const struct ofono_sim_driver *d);
> @@ -248,6 +269,13 @@ unsigned int ofono_sim_add_file_watch(struct ofono_sim_context *context,
>   void ofono_sim_remove_file_watch(struct ofono_sim_context *context,
>   					unsigned int id);
>   
> +struct sim_app_record **ofono_sim_get_aid_list(struct ofono_sim *sim);
> +

I would just make it easy and hide this in ofono.h for now.  I'm not 
sure the drivers need access to this...  Maybe even make it return the 
corresponding ofono_sim member directly...

> +int ofono_sim_get_session(struct ofono_sim *sim, unsigned char *aid,
> +		ofono_sim_get_session_cb_t cb, void *data);
> +
> +int ofono_sim_release_session(struct ofono_sim *sim, int session_id);
> +

Same here, keep this API private for now.

>   #ifdef __cplusplus
>   }
>   #endif
> 

Regards,
-Denis

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 3/8] sim: AID session management
  2017-11-01 17:33 ` [PATCH 3/8] sim: AID session management James Prestwood
@ 2017-11-02 17:10   ` Denis Kenzior
  0 siblings, 0 replies; 11+ messages in thread
From: Denis Kenzior @ 2017-11-02 17:10 UTC (permalink / raw)
  To: ofono

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

Hi James,

On 11/01/2017 12:33 PM, James Prestwood wrote:
> Accessing an AID requires opening a channel to that application.
> This patch implements session management API's so that other atoms
> can access a given AID. Now any atom can get a session ID from the
> sim atom. This will either reuse an existing session or open a new
> channel. Once done, the atom should release the session which will
> automatically close the channel when no atoms are using it.
> 
> The major functional change to the sim atom is the AID discovery
> phase of initialization. Now, the sim atom is not 'ready' until AID
> discovery finishes where before, the sim was 'ready' after the IMSI
> had been obtained. If application discovery is not supported then
> the the sim atom behaves as it did before.
> ---
>   src/sim.c | 204 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>   1 file changed, 204 insertions(+)
> 
> diff --git a/src/sim.c b/src/sim.c
> index 88c0421..53eb048 100644
> --- a/src/sim.c
> +++ b/src/sim.c
> @@ -48,6 +48,25 @@
>   
>   #define SIM_FLAG_READING_SPN	0x1
>   
> +/*
> + * A new session object will be created if a USim/ISim applications are
> + * found during app discovery. Any concurrent file/logical access to
> + * these applications will share the same session ID.
> + */
> +struct ofono_aid_session {
> +	struct sim_app_record record;
> +	struct ofono_sim_context *context;
> +	int session_id;
> +	int ref;
> +};
> +
> +/* callback data for opening a new session */
> +struct sdata {
> +	void *data;
> +	ofono_sim_get_session_cb_t cb;
> +	struct ofono_aid_session *session;
> +};
> +

You have to be careful here because sdata objects are not tracked 
anywhere.  So if the SIM atom is removed (e.g. due to USB hot-unplug or 
whatever) then there is potential for memory leaks.

>   struct ofono_sim {
>   	int flags;
>   
> @@ -114,6 +133,8 @@ struct ofono_sim {
>   	void *driver_data;
>   	struct ofono_atom *atom;
>   	unsigned int hfp_watch;
> +
> +	GSList *aid_sessions;

It may be easier to keep a GSList of sim_app_records directly and have 
ofono_aid_session reference that list.

>   };
>   
>   struct msisdn_set_request {
> @@ -1434,6 +1455,36 @@ static void sim_set_ready(struct ofono_sim *sim)
>   	call_state_watches(sim);
>   }
>   
> +static void discover_apps_cb(const struct ofono_error *error,
> +		const unsigned char *dataobj,
> +		int len, void *data)
> +{
> +	GSList *list;
> +	GSList *iter;
> +	struct ofono_sim *sim = data;
> +
> +	if (error->type != OFONO_ERROR_TYPE_NO_ERROR)
> +		return;
> +
> +	list = sim_parse_app_template_entries(dataobj, len);
> +	iter = list;
> + > +	while (iter) {
> +		struct sim_app_record *app = iter->data;
> +		struct ofono_aid_session *s = g_try_new0(
> +				struct ofono_aid_session, 1);
> +
> +		memcpy(&s->record, app, sizeof(struct sim_app_record));
> +		sim->aid_sessions = g_slist_prepend(sim->aid_sessions, s);
> +
> +		g_free(app);
> +
> +		iter = g_slist_next(iter);
> +	}
> +
> +	g_slist_free(list);
> +}
> +
>   static void sim_imsi_obtained(struct ofono_sim *sim, const char *imsi)
>   {
>   	DBusConnection *conn = ofono_dbus_get_connection();
> @@ -1844,6 +1895,12 @@ static void sim_initialize_after_pin(struct ofono_sim *sim)
>   {
>   	sim->context = ofono_sim_context_create(sim);
>   
> +	/*
> +	 * Discover applications on SIM
> +	 */
> +	if (sim->driver->list_apps)
> +		sim->driver->list_apps(sim, discover_apps_cb, sim);
> +
>   	ofono_sim_read(sim->context, SIM_EFPHASE_FILEID,
>   			OFONO_SIM_FILE_STRUCTURE_TRANSPARENT,
>   			sim_efphase_read_cb, sim);
> @@ -2450,6 +2507,9 @@ static void sim_free_main_state(struct ofono_sim *sim)
>   		ofono_sim_context_free(sim->context);
>   		sim->context = NULL;
>   	}
> +
> +	if (sim->aid_sessions)
> +		g_slist_free(sim->aid_sessions);
>   }
>   
>   static void sim_free_state(struct ofono_sim *sim)
> @@ -3304,3 +3364,147 @@ void __ofono_sim_refresh(struct ofono_sim *sim, GSList *file_list,
>   		}
>   	}
>   }
> +
> +struct sim_app_record **ofono_sim_get_aid_list(struct ofono_sim *sim)

That way you can make this private API (__ofono_sim_get_aid_list) and 
simply return a GSList.  E.g. sim->aid_list or something.

> +{
> +	GSList *iter = sim->aid_sessions;
> +	int len;
> +	struct sim_app_record **ret;
> +	int i = 0;
> +
> +	if (!iter) {
> +		DBG("AID list not found");
> +		return NULL;
> +	}
> +
> +	len = g_slist_length(iter);
> +	ret = g_try_new0(struct sim_app_record *,
> +			len + 1);
> +
> +	while (iter) {
> +		struct ofono_aid_session *s = iter->data;
> +
> +		ret[i++] = &s->record;
> +
> +		iter = g_slist_next(iter);
> +	}
> +
> +	return ret;
> +}
> +
> +static struct ofono_aid_session *find_session_by_aid(struct ofono_sim *sim,
> +		unsigned char *aid)
> +{
> +	GSList *iter = sim->aid_sessions;
> +
> +	while (iter) {
> +		struct ofono_aid_session *session = iter->data;
> +
> +		if (!memcmp(session->record.aid, aid, 16))
> +			return session;
> +
> +		iter = g_slist_next(iter);
> +	}
> +
> +	return NULL;
> +}
> +
> +static struct ofono_aid_session *find_session_by_id(struct ofono_sim *sim,
> +		int session_id)
> +{
> +	GSList *iter = sim->aid_sessions;
> +
> +	while (iter) {
> +		struct ofono_aid_session *session = iter->data;
> +
> +		if (session->session_id == session_id)
> +			return session;
> +
> +		iter = g_slist_next(iter);
> +	}
> +
> +	return NULL;
> +}
> +
> +static struct sdata *cb_data_new(ofono_sim_get_session_cb_t cb, void *data,
> +		struct ofono_aid_session *session)
> +{
> +	struct sdata *cbd = g_try_new0(struct sdata, 1);
> +
> +	cbd->cb = cb;
> +	cbd->data = data;
> +	cbd->session = session;
> +
> +	return cbd;
> +}
> +
> +static void open_channel_cb(const struct ofono_error *error, int session_id,
> +		void *data)
> +{
> +	struct sdata *cbd = data;
> +	struct ofono_aid_session *session = cbd->session;
> +
> +	if (error->type != OFONO_ERROR_TYPE_NO_ERROR) {
> +		session->ref = 0;
> +		session->session_id = -1;
> +		goto end;
> +	}
> +
> +	session->session_id = session_id;
> +
> +end:
> +	cbd->cb(session->session_id, cbd->data);
> +
> +	g_free(cbd);
> +}
> +
> +int ofono_sim_get_session(struct ofono_sim *sim, unsigned char *aid,
> +		ofono_sim_get_session_cb_t cb, void *data)
> +{
> +	struct sdata *cbd;
> +	struct ofono_aid_session *session = find_session_by_aid(sim, aid);
> +
> +	if (!session) {
> +		DBG("AID not found");
> +		return 0;

So in general we make a function return either true/false or if it 
returns an int, then it should return -errno or 0 on success.  So in 
this case return -ENOENT.

> +	}
> +
> +	if (!sim->driver->open_channel || !sim->driver->close_channel) {
> +		DBG("sim driver does not support opening logical channels");
> +		return 0;

return -ENOTSUP

> +	}
> +
> +	/* increase ref to ensure the session doesn't get cleaned up */
> +	session->ref++;
s> +
> +	if (session->session_id == 0) {
> +		/* AID found but no session has been opened */
> +		cbd = cb_data_new(cb, data, session);
> +		sim->driver->open_channel(sim, aid, open_channel_cb, cbd);

So what happens if two atoms call this one after the other?  Eg. before 
the open_channel_cb was called?

> +	} else {
> +		cb(session->session_id, data);
> +	}
> +
> +	return 1;
> +}
> +
> +int ofono_sim_release_session(struct ofono_sim *sim, int session_id)
> +{
> +	struct ofono_aid_session *session = find_session_by_id(sim, session_id);
> +
> +	if (!session) {
> +		DBG("Session %d not found", session_id);
> +		return 0;
> +	}
> +
> +	session->ref--;
> +
> +	/* if nobody is using this session, close the channel */
> +	if (session->ref <= 0) {
> +		sim->driver->close_channel(sim, session_id, NULL, NULL);
> +		session->session_id = 0;
> +		session->ref = 0;
> +	}
> +
> +	return 1;
> +}
> 

Regards,
-Denis

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2017-11-02 17:10 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-11-01 17:33 [PATCH 1/8] simutil: Added ISIM elementary file ID's James Prestwood
2017-11-01 17:33 ` [PATCH 2/8] sim: header definitions for AID session APIs James Prestwood
2017-11-02 16:55   ` Denis Kenzior
2017-11-01 17:33 ` [PATCH 3/8] sim: AID session management James Prestwood
2017-11-02 17:10   ` Denis Kenzior
2017-11-01 17:33 ` [PATCH 4/8] atmodem: implement new driver APIs for AID sessions James Prestwood
2017-11-01 17:33 ` [PATCH 5/8] simfs: read files from specific AID's James Prestwood
2017-11-01 17:33 ` [PATCH 6/8] sim: header definitions for AID sim context API James Prestwood
2017-11-01 17:33 ` [PATCH 7/8] sim: implement create context with AID James Prestwood
2017-11-01 17:33 ` [PATCH 8/8] sim: added NetworkAccessIdentifier to SimManager James Prestwood
2017-11-02 16:40 ` [PATCH 1/8] simutil: Added ISIM elementary file ID's Denis Kenzior

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.