* [PATCH 2/2] atmodem: Use +CUAD to list SIM applications.
2011-01-12 12:12 [PATCH 1/2] Add sim driver call for applications discovery Andrzej Zaborowski
@ 2011-01-12 12:12 ` Andrzej Zaborowski
2011-01-13 16:39 ` [PATCH 1/2] Add sim driver call for applications discovery Denis Kenzior
1 sibling, 0 replies; 4+ messages in thread
From: Andrzej Zaborowski @ 2011-01-12 12:12 UTC (permalink / raw)
To: ofono
[-- 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
^ permalink raw reply related [flat|nested] 4+ messages in thread* Re: [PATCH 1/2] Add sim driver call for applications discovery.
2011-01-12 12:12 [PATCH 1/2] Add sim driver call for applications discovery Andrzej Zaborowski
2011-01-12 12:12 ` [PATCH 2/2] atmodem: Use +CUAD to list SIM applications Andrzej Zaborowski
@ 2011-01-13 16:39 ` Denis Kenzior
2011-01-17 14:42 ` Pekka Pessi
1 sibling, 1 reply; 4+ messages in thread
From: Denis Kenzior @ 2011-01-13 16:39 UTC (permalink / raw)
To: ofono
[-- Attachment #1: Type: text/plain, Size: 1632 bytes --]
Hi Andrew,
On 01/12/2011 06:12 AM, Andrzej Zaborowski wrote:
> ---
> include/sim.h | 11 +++++++++++
> 1 files changed, 11 insertions(+), 0 deletions(-)
>
> diff --git a/include/sim.h b/include/sim.h
> index aab981c..e4176e3 100644
> --- a/include/sim.h
> +++ b/include/sim.h
> @@ -77,6 +77,12 @@ enum ofono_sim_state {
> OFONO_SIM_STATE_READY,
> };
>
> +struct ofono_sim_app_record {
> + unsigned char aid[16];
> + unsigned int aid_len;
> + char *label;
> +};
> +
> typedef void (*ofono_sim_file_info_cb_t)(const struct ofono_error *error,
> int filelength,
> enum ofono_sim_file_structure structure,
> @@ -114,6 +120,9 @@ typedef void (*ofono_sim_lock_unlock_cb_t)(const struct ofono_error *error,
> typedef void (*ofono_sim_locked_cb_t)(const struct ofono_error *error,
> int locked, void *data);
>
> +typedef void (*ofono_sim_apps_cb_t)(const struct ofono_error *error,
> + GSList *apps, void *data);
> +
Please remember that we do not use G* types in the ofono public API.
> typedef void (*ofono_sim_file_notify_t)(int id, void *userdata);
>
> struct ofono_sim_driver {
> @@ -159,6 +168,8 @@ struct ofono_sim_driver {
> void (*query_locked)(struct ofono_sim *sim,
> enum ofono_sim_password_type type,
> ofono_sim_locked_cb_t cb, void *data);
> + void (*list_apps)(struct ofono_sim *sim, ofono_sim_apps_cb_t cb,
> + void *data);
> };
Do you think this belongs on a separate atom? E.g. something like
Pekka's SimAuthentication ?
>
> int ofono_sim_driver_register(const struct ofono_sim_driver *d);
Regards,
-Denis
^ permalink raw reply [flat|nested] 4+ messages in thread