simutil: SIM applications directory decoding utils
authorAndrzej Zaborowski <andrew.zaborowski@intel.com>
Wed, 19 Jan 2011 08:07:54 +0000 (09:07 +0100)
committerDenis Kenzior <denkenz@gmail.com>
Thu, 20 Jan 2011 17:15:34 +0000 (11:15 -0600)
src/simutil.c
src/simutil.h

index 8abf3d5..3dc4761 100644 (file)
@@ -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;
+}
index 554f798..95bc18f 100644 (file)
@@ -255,6 +255,12 @@ struct sim_ef_info {
        enum sim_file_access perm_update;
 };
 
+struct sim_app_record {
+       unsigned char aid[16];
+       int aid_len;
+       char *label;
+};
+
 struct simple_tlv_iter {
        unsigned int max;
        unsigned int pos;
@@ -446,3 +452,5 @@ gboolean sim_sst_is_available(unsigned char *service_sst, unsigned char len,
                                                enum sim_sst_service index);
 gboolean sim_sst_is_active(unsigned char *service_sst, unsigned char len,
                                                enum sim_sst_service index);
+
+GSList *sim_parse_app_template_entries(const unsigned char *buffer, int len);