summaryrefslogtreecommitdiffstats
path: root/src/simutil.c
diff options
context:
space:
mode:
authorAndrzej Zaborowski <andrew.zaborowski@intel.com>2011-01-19 09:07:54 +0100
committerDenis Kenzior <denkenz@gmail.com>2011-01-20 11:15:34 -0600
commit1542bf0c597d3251591e02a3c59c47aaac0e22d7 (patch)
tree0a5a2d8d51697e051ce7e3026b1de4599e5b4ca2 /src/simutil.c
parent0ef557e766bddc798ecd00d95b717af52b3fbebe (diff)
downloadofono-1542bf0c597d3251591e02a3c59c47aaac0e22d7.tar.bz2
simutil: SIM applications directory decoding utils
Diffstat (limited to 'src/simutil.c')
-rw-r--r--src/simutil.c57
1 files changed, 57 insertions, 0 deletions
diff --git a/src/simutil.c b/src/simutil.c
index 8abf3d59..3dc47616 100644
--- a/src/simutil.c
+++ b/src/simutil.c
@@ -1465,3 +1465,60 @@ gboolean sim_sst_is_active(unsigned char *efsst, unsigned char len,
return (efsst[index / 4] >> (((index % 4) * 2) + 1)) & 1;
}
+
+GSList *sim_parse_app_template_entries(const unsigned char *buffer, int len)
+{
+ GSList *ret = NULL;
+ const unsigned char *dataobj;
+ int dataobj_len;
+
+ /* Find all the application entries */
+ while ((dataobj = ber_tlv_find_by_tag(buffer, 0x61, len,
+ &dataobj_len)) != NULL) {
+ struct sim_app_record app;
+ const unsigned char *aid, *label;
+ int label_len;
+
+ /* Find the aid (mandatory) */
+ aid = ber_tlv_find_by_tag(dataobj, 0x4f, dataobj_len,
+ &app.aid_len);
+ if (!aid || app.aid_len < 0x01 || app.aid_len > 0x10)
+ goto error;
+
+ memcpy(app.aid, aid, app.aid_len);
+
+ /* Find the label (optional) */
+ label = ber_tlv_find_by_tag(dataobj, 0x50, dataobj_len,
+ &label_len);
+ if (label) {
+ /*
+ * Label field uses the extra complicated
+ * encoding in 102.221 Annex A
+ */
+ app.label = sim_string_to_utf8(label, label_len);
+
+ if (app.label == NULL)
+ goto error;
+ } else
+ app.label = NULL;
+
+ ret = g_slist_prepend(ret, g_memdup(&app, sizeof(app)));
+
+ len -= (dataobj - buffer) + dataobj_len;
+ buffer = dataobj + dataobj_len;
+ }
+
+ return ret;
+
+error:
+ while (ret) {
+ GSList *t = ret;
+
+ g_free(((struct sim_app_record *) ret->data)->label);
+
+ ret = ret->next;
+ g_slist_free_1(t);
+ }
+
+ return NULL;
+}