diff options
author | Andrzej Zaborowski <andrew.zaborowski@intel.com> | 2011-01-19 09:07:54 +0100 |
---|---|---|
committer | Denis Kenzior <denkenz@gmail.com> | 2011-01-20 11:15:34 -0600 |
commit | 1542bf0c597d3251591e02a3c59c47aaac0e22d7 (patch) | |
tree | 0a5a2d8d51697e051ce7e3026b1de4599e5b4ca2 /src/simutil.c | |
parent | 0ef557e766bddc798ecd00d95b717af52b3fbebe (diff) | |
download | ofono-1542bf0c597d3251591e02a3c59c47aaac0e22d7.tar.bz2 |
simutil: SIM applications directory decoding utils
Diffstat (limited to 'src/simutil.c')
-rw-r--r-- | src/simutil.c | 57 |
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; +} |