summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAleksander Morgado <aleksandermj@chromium.org>2022-08-23 12:52:59 +0000
committerAleksander Morgado <aleksandermj@chromium.org>2022-09-07 20:21:42 +0000
commitf9ea6778de5a2339a935a40a27f110e92af01e2c (patch)
treec81456af84e6d8c35ea244ee771811f1516d3872
parent88bb60baa77111e0fa470ab6cfdb004dc13d5116 (diff)
downloadlibmbim-f9ea6778de5a2339a935a40a27f110e92af01e2c.tar.gz
ms-uicc-low-level-access: add support for 'Read Record' operation
$ sudo mbimcli -p -d /dev/wwan0mbim0 --ms-query-uicc-read-record="application-id=A0000000871002FF34FF0789312E30FF,file-path=3F002FE2" [/dev/wwan0mbim0] UICC file record read: Status word 1: 144 Status word 2: 0 Data: 98:43:70:77:00:10:85:84:36:F8
-rw-r--r--data/mbim-service-ms-uicc-low-level-access.json25
-rw-r--r--src/libmbim-glib/mbim-cid.c3
-rw-r--r--src/libmbim-glib/mbim-cid.h2
-rw-r--r--src/mbimcli/mbimcli-ms-uicc-low-level-access.c189
4 files changed, 217 insertions, 2 deletions
diff --git a/data/mbim-service-ms-uicc-low-level-access.json b/data/mbim-service-ms-uicc-low-level-access.json
index 32d1a8e..212f44b 100644
--- a/data/mbim-service-ms-uicc-low-level-access.json
+++ b/data/mbim-service-ms-uicc-low-level-access.json
@@ -198,5 +198,30 @@
{ "name" : "StatusWord2",
"format" : "guint32" },
{ "name" : "Data",
+ "format" : "ref-byte-array" } ] },
+
+ // *********************************************************************************
+ { "name" : "Read Record",
+ "type" : "Command",
+ "since" : "1.28",
+ "query" : [ { "name" : "Version",
+ "format" : "guint32" },
+ { "name" : "ApplicationId",
+ "format" : "ref-byte-array" },
+ { "name" : "FilePath",
+ "format" : "ref-byte-array" },
+ { "name" : "RecordNumber",
+ "format" : "guint32" },
+ { "name" : "LocalPin",
+ "format" : "string" },
+ { "name" : "Data",
+ "format" : "ref-byte-array" } ],
+ "response" : [ { "name" : "Version",
+ "format" : "guint32" },
+ { "name" : "StatusWord1",
+ "format" : "guint32" },
+ { "name" : "StatusWord2",
+ "format" : "guint32" },
+ { "name" : "Data",
"format" : "ref-byte-array" } ] }
]
diff --git a/src/libmbim-glib/mbim-cid.c b/src/libmbim-glib/mbim-cid.c
index 9194c8e..d8aa377 100644
--- a/src/libmbim-glib/mbim-cid.c
+++ b/src/libmbim-glib/mbim-cid.c
@@ -179,7 +179,7 @@ static const CidConfig cid_qdu_config [MBIM_CID_QDU_LAST] = {
};
/* Note: index of the array is CID-1 */
-#define MBIM_CID_MS_UICC_LOW_LEVEL_ACCESS_LAST MBIM_CID_MS_UICC_LOW_LEVEL_ACCESS_READ_BINARY
+#define MBIM_CID_MS_UICC_LOW_LEVEL_ACCESS_LAST MBIM_CID_MS_UICC_LOW_LEVEL_ACCESS_READ_RECORD
static const CidConfig cid_ms_uicc_low_level_access_config [MBIM_CID_MS_UICC_LOW_LEVEL_ACCESS_LAST] = {
{ NO_SET, QUERY, NO_NOTIFY }, /* MBIM_CID_MS_UICC_LOW_LEVEL_ACCESS_ATR */
{ SET, NO_QUERY, NO_NOTIFY }, /* MBIM_CID_MS_UICC_LOW_LEVEL_ACCESS_OPEN_CHANNEL */
@@ -190,6 +190,7 @@ static const CidConfig cid_ms_uicc_low_level_access_config [MBIM_CID_MS_UICC_LOW
{ NO_SET, QUERY, NO_NOTIFY }, /* MBIM_CID_MS_UICC_LOW_LEVEL_ACCESS_APPLICATION_LIST */
{ NO_SET, QUERY, NO_NOTIFY }, /* MBIM_CID_MS_UICC_LOW_LEVEL_ACCESS_FILE_STATUS */
{ SET, QUERY, NO_NOTIFY }, /* MBIM_CID_MS_UICC_LOW_LEVEL_ACCESS_READ_BINARY */
+ { SET, QUERY, NO_NOTIFY }, /* MBIM_CID_MS_UICC_LOW_LEVEL_ACCESS_READ_RECORD */
};
/* Note: index of the array is CID-1 */
diff --git a/src/libmbim-glib/mbim-cid.h b/src/libmbim-glib/mbim-cid.h
index 2e5ce0c..c404271 100644
--- a/src/libmbim-glib/mbim-cid.h
+++ b/src/libmbim-glib/mbim-cid.h
@@ -380,6 +380,7 @@ typedef enum { /*< since=1.18 >*/
* @MBIM_CID_MS_UICC_LOW_LEVEL_ACCESS_APPLICATION_LIST: Retrieve application list. Since 1.28.
* @MBIM_CID_MS_UICC_LOW_LEVEL_ACCESS_FILE_STATUS: Retrieve information about a specific UICC file. Since 1.28.
* @MBIM_CID_MS_UICC_LOW_LEVEL_ACCESS_READ_BINARY: Read a UICC binary file. Since 1.28.
+ * @MBIM_CID_MS_UICC_LOW_LEVEL_ACCESS_READ_RECORD: Read a UICC linear fixed or cyclic file. Since 1.28.
*
* MBIM commands in the %MBIM_SERVICE_MS_UICC_LOW_LEVEL_ACCESS service.
*
@@ -396,6 +397,7 @@ typedef enum { /*< since=1.26 >*/
MBIM_CID_MS_UICC_LOW_LEVEL_ACCESS_APPLICATION_LIST = 7,
MBIM_CID_MS_UICC_LOW_LEVEL_ACCESS_FILE_STATUS = 8,
MBIM_CID_MS_UICC_LOW_LEVEL_ACCESS_READ_BINARY = 9,
+ MBIM_CID_MS_UICC_LOW_LEVEL_ACCESS_READ_RECORD = 10,
} MbimCidMsUiccLowLevelAccess;
/**
diff --git a/src/mbimcli/mbimcli-ms-uicc-low-level-access.c b/src/mbimcli/mbimcli-ms-uicc-low-level-access.c
index b3e4e6d..9f0ea05 100644
--- a/src/mbimcli/mbimcli-ms-uicc-low-level-access.c
+++ b/src/mbimcli/mbimcli-ms-uicc-low-level-access.c
@@ -34,6 +34,7 @@ static Context *ctx;
static gboolean query_uicc_application_list_flag;
static gchar *query_uicc_file_status_str;
static gchar *query_uicc_read_binary_str;
+static gchar *query_uicc_read_record_str;
static GOptionEntry entries[] = {
{ "ms-query-uicc-application-list", 0, 0, G_OPTION_ARG_NONE, &query_uicc_application_list_flag,
@@ -48,6 +49,10 @@ static GOptionEntry entries[] = {
"Read UICC binary file (allowed keys: application-id, file-path, read-offset, read-size, local-pin and data)",
"[\"key=value,...\"]"
},
+ { "ms-query-uicc-read-record", 0, 0, G_OPTION_ARG_STRING, &query_uicc_read_record_str,
+ "Read UICC record file (allowed keys: application-id, file-path, record-number, local-pin and data)",
+ "[\"key=value,...\"]"
+ },
{ NULL }
};
@@ -77,7 +82,8 @@ mbimcli_ms_uicc_low_level_access_options_enabled (void)
n_actions = query_uicc_application_list_flag +
!!query_uicc_file_status_str +
- !!query_uicc_read_binary_str;
+ !!query_uicc_read_binary_str +
+ !!query_uicc_read_record_str;
if (n_actions > 1) {
g_printerr ("error: too many Microsoft UICC Low Level Access Service actions requested\n");
@@ -110,6 +116,147 @@ shutdown (gboolean operation_status)
}
static void
+read_record_query_ready (MbimDevice *device,
+ GAsyncResult *res)
+{
+ g_autoptr(MbimMessage) response = NULL;
+ g_autoptr(GError) error = NULL;
+ guint32 status_word_1;
+ guint32 status_word_2;
+ const guint8 *data;
+ guint32 data_size;
+ g_autofree gchar *data_str = NULL;
+
+ response = mbim_device_command_finish (device, res, &error);
+ if (!response || !mbim_message_response_get_result (response, MBIM_MESSAGE_TYPE_COMMAND_DONE, &error)) {
+ g_printerr ("error: operation failed: %s\n", error->message);
+ shutdown (FALSE);
+ return;
+ }
+
+ if (!mbim_message_ms_uicc_low_level_access_read_record_response_parse (
+ response,
+ NULL, /* version */
+ &status_word_1,
+ &status_word_2,
+ &data_size,
+ &data,
+ &error)) {
+ g_printerr ("error: couldn't parse response message: %s\n", error->message);
+ shutdown (FALSE);
+ return;
+ }
+
+ data_str = mbim_common_str_hex (data, data_size, ':');
+
+ g_print ("[%s] UICC file record read:\n"
+ "\tStatus word 1: %u\n"
+ "\tStatus word 2: %u\n"
+ "\t Data: %s\n",
+ mbim_device_get_path_display (device),
+ status_word_1,
+ status_word_2,
+ data_str);
+
+ shutdown (TRUE);
+}
+
+typedef struct {
+ gsize application_id_size;
+ guint8 *application_id;
+ gsize file_path_size;
+ guint8 *file_path;
+ guint32 record_number;
+ gchar *local_pin;
+ gsize data_size;
+ guint8 *data;
+} ReadRecordQueryProperties;
+
+static void
+read_record_query_properties_clear (ReadRecordQueryProperties *props)
+{
+ g_clear_pointer (&props->application_id, g_free);
+ g_clear_pointer (&props->file_path, g_free);
+ g_clear_pointer (&props->local_pin, g_free);
+ g_clear_pointer (&props->data, g_free);
+}
+
+G_DEFINE_AUTO_CLEANUP_CLEAR_FUNC(ReadRecordQueryProperties, read_record_query_properties_clear);
+
+static gboolean
+read_record_query_properties_handle (const gchar *key,
+ const gchar *value,
+ GError **error,
+ gpointer user_data)
+{
+ ReadRecordQueryProperties *props = user_data;
+
+ if (g_ascii_strcasecmp (key, "application-id") == 0) {
+ g_clear_pointer (&props->application_id, g_free);
+ props->application_id_size = 0;
+ props->application_id = mbimcli_read_buffer_from_string (value, -1, &props->application_id_size, error);
+ if (!props->application_id)
+ return FALSE;
+ } else if (g_ascii_strcasecmp (key, "file-path") == 0) {
+ g_clear_pointer (&props->file_path, g_free);
+ props->file_path_size = 0;
+ props->file_path = mbimcli_read_buffer_from_string (value, -1, &props->file_path_size, error);
+ if (!props->file_path)
+ return FALSE;
+ } else if (g_ascii_strcasecmp (key, "record-number") == 0) {
+ if (!mbimcli_read_uint_from_string (value, &props->record_number)) {
+ g_set_error (error, MBIM_CORE_ERROR, MBIM_CORE_ERROR_FAILED,
+ "Failed to parse field as an integer");
+ return FALSE;
+ }
+ } else if (g_ascii_strcasecmp (key, "local-pin") == 0) {
+ g_clear_pointer (&props->local_pin, g_free);
+ props->local_pin = g_strdup (value);
+ } else if (g_ascii_strcasecmp (key, "data") == 0) {
+ g_clear_pointer (&props->data, g_free);
+ props->data_size = 0;
+ props->data = mbimcli_read_buffer_from_string (value, -1, &props->data_size, error);
+ if (!props->data)
+ return FALSE;
+ } else {
+ g_set_error (error, MBIM_CORE_ERROR, MBIM_CORE_ERROR_FAILED,
+ "unrecognized option '%s'", key);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static gboolean
+read_record_query_input_parse (const gchar *str,
+ ReadRecordQueryProperties *props,
+ GError **error)
+{
+
+ if (!mbimcli_parse_key_value_string (str,
+ error,
+ read_record_query_properties_handle,
+ props))
+ return FALSE;
+
+ if (!props->application_id_size || !props->application_id) {
+ g_set_error (error, MBIM_CORE_ERROR, MBIM_CORE_ERROR_FAILED,
+ "Option 'application-id' is missing");
+ return FALSE;
+ }
+
+ if (!props->file_path_size || !props->file_path) {
+ g_set_error (error, MBIM_CORE_ERROR, MBIM_CORE_ERROR_FAILED,
+ "Option 'file-path' is missing");
+ return FALSE;
+ }
+
+ /* all the other fields are optional */
+
+ return TRUE;
+}
+
+static void
read_binary_query_ready (MbimDevice *device,
GAsyncResult *res)
{
@@ -555,5 +702,45 @@ mbimcli_ms_uicc_low_level_access_run (MbimDevice *device,
return;
}
+ /* Request to UICC read record? */
+ if (query_uicc_read_record_str) {
+ g_auto(ReadRecordQueryProperties) props = {
+ .application_id_size = 0,
+ .application_id = NULL,
+ .file_path_size = 0,
+ .file_path = NULL,
+ .record_number = 0,
+ .local_pin = NULL,
+ .data_size = 0,
+ .data = NULL,
+ };
+
+ g_debug ("Asynchronously reading from UICC record...");
+
+ if (!read_record_query_input_parse (query_uicc_read_record_str, &props, &error)) {
+ g_printerr ("error: couldn't parse input arguments: %s\n", error->message);
+ shutdown (FALSE);
+ return;
+ }
+
+ request = mbim_message_ms_uicc_low_level_access_read_record_query_new (1, /* version fixed */
+ props.application_id_size,
+ props.application_id,
+ props.file_path_size,
+ props.file_path,
+ props.record_number,
+ props.local_pin,
+ props.data_size,
+ props.data,
+ NULL);
+ mbim_device_command (ctx->device,
+ request,
+ 10,
+ ctx->cancellable,
+ (GAsyncReadyCallback)read_record_query_ready,
+ NULL);
+ return;
+ }
+
g_warn_if_reached ();
}