Open Source Telephony
 help / color / mirror / Atom feed
From: Andrzej Zaborowski <andrew.zaborowski@intel.com>
To: ofono@ofono.org
Subject: [PATCH 2/2] atmodem: Use +CUAD to list SIM applications.
Date: Wed, 12 Jan 2011 13:12:45 +0100	[thread overview]
Message-ID: <1294834365-11029-2-git-send-email-andrew.zaborowski@intel.com> (raw)
In-Reply-To: <1294834365-11029-1-git-send-email-andrew.zaborowski@intel.com>

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

Note that +CUAD just returns the contents of EFdir and reading
EFdir may be available on more modems than AT+CUAD is.
---
 drivers/atmodem/sim.c |  112 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 112 insertions(+), 0 deletions(-)

diff --git a/drivers/atmodem/sim.c b/drivers/atmodem/sim.c
index 1653ede..2fb97f2 100644
--- a/drivers/atmodem/sim.c
+++ b/drivers/atmodem/sim.c
@@ -38,6 +38,7 @@
 #include "gatresult.h"
 #include "simutil.h"
 #include "vendor.h"
+#include "util.h"
 
 #include "atmodem.h"
 
@@ -53,6 +54,7 @@ struct sim_data {
 static const char *crsm_prefix[] = { "+CRSM:", NULL };
 static const char *cpin_prefix[] = { "+CPIN:", NULL };
 static const char *clck_prefix[] = { "+CLCK:", NULL };
+static const char *cuad_prefix[] = { "+CUAD:", NULL };
 static const char *none_prefix[] = { NULL };
 
 static void at_crsm_info_cb(gboolean ok, GAtResult *result, gpointer user_data)
@@ -827,6 +829,115 @@ error:
 	CALLBACK_WITH_FAILURE(cb, -1, data);
 }
 
+static void at_sim_list_apps_cb(gboolean ok, GAtResult *result,
+				gpointer user_data)
+{
+	struct cb_data *cbd = user_data;
+	GAtResultIter iter;
+	ofono_sim_apps_cb_t cb = cbd->cb;
+	struct ofono_error error;
+	GSList *apps = NULL;
+
+	decode_at_error(&error, g_at_result_final_response(result));
+
+	if (!ok) {
+		cb(&error, NULL, cbd->data);
+		return;
+	}
+
+	g_at_result_iter_init(&iter, result);
+
+	while (g_at_result_iter_next(&iter, "+CUAD:")) {
+		const guint8 *obj_str;
+		gint len;
+		struct ber_tlv_iter dataobj_iter;
+
+		if (!g_at_result_iter_next_hexstring(&iter, &obj_str, &len))
+			goto error;
+
+		ber_tlv_iter_init(&dataobj_iter, obj_str, len);
+
+		/* Find application template entries */
+		while (ber_tlv_iter_next(&dataobj_iter)) {
+			struct ber_tlv_iter value_iter;
+			struct ofono_sim_app_record app;
+
+			if (ber_tlv_iter_get_short_tag(&dataobj_iter) != 0x61)
+				continue;
+
+			ber_tlv_iter_recurse(&dataobj_iter, &value_iter);
+
+			/* Find the aid (mandatory) */
+			if (!ber_tlv_iter_next(&value_iter))
+				goto error;
+			if (ber_tlv_iter_get_short_tag(&value_iter) != 0x4f)
+				goto error;
+
+			app.aid_len = ber_tlv_iter_get_length(&value_iter);
+			if (app.aid_len < 0x01 || app.aid_len > 0x10)
+				goto error;
+
+			memcpy(app.aid,  ber_tlv_iter_get_data(&value_iter),
+					app.aid_len);
+
+			/* Find the label (optional) */
+			while (ber_tlv_iter_next(&value_iter)) {
+				if (ber_tlv_iter_get_short_tag(&value_iter) !=
+						0x50)
+					continue;
+
+				if (ber_tlv_iter_get_length(&value_iter) == 0)
+					break;
+
+				/*
+				 * Label field uses the extra complicated
+				 * encoding in 102.221 Annex A
+				 */
+				app.label = sim_string_to_utf8(
+					ber_tlv_iter_get_data(&value_iter),
+					ber_tlv_iter_get_length(&value_iter));
+				if (app.label == NULL)
+					goto error;
+
+				break;
+			}
+
+			apps = g_slist_prepend(apps,
+						g_memdup(&app, sizeof(app)));
+		}
+	}
+
+	cb(&error, g_slist_reverse(apps), cbd->data);
+	return;
+
+error:
+	CALLBACK_WITH_FAILURE(cb, NULL, cbd->data);
+
+	while (apps) {
+		GSList *t = apps;
+
+		g_free(((struct ofono_sim_app_record *) apps->data)->label);
+
+		apps = apps->next;
+		g_slist_free_1(t);
+	}
+}
+
+static void at_sim_list_apps(struct ofono_sim *sim, ofono_sim_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 (cbd && g_at_chat_send(sd->chat, "AT+CUAD", cuad_prefix,
+					at_sim_list_apps_cb, cbd, g_free) > 0)
+		return;
+
+	g_free(cbd);
+
+	CALLBACK_WITH_FAILURE(cb, NULL, data);
+}
+
 static gboolean at_sim_register(gpointer user)
 {
 	struct ofono_sim *sim = user;
@@ -891,6 +1002,7 @@ static struct ofono_sim_driver driver = {
 	.lock			= at_pin_enable,
 	.change_passwd		= at_change_passwd,
 	.query_locked		= at_pin_query_enabled,
+	.list_apps		= at_sim_list_apps,
 };
 
 void at_sim_init()
-- 
1.7.1.86.g0e460.dirty


  reply	other threads:[~2011-01-12 12:12 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-01-12 12:12 [PATCH 1/2] Add sim driver call for applications discovery Andrzej Zaborowski
2011-01-12 12:12 ` Andrzej Zaborowski [this message]
2011-01-13 16:39 ` Denis Kenzior
2011-01-17 14:42   ` Pekka Pessi

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1294834365-11029-2-git-send-email-andrew.zaborowski@intel.com \
    --to=andrew.zaborowski@intel.com \
    --cc=ofono@ofono.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox