diff options
author | Aleksander Morgado <aleksandermj@chromium.org> | 2022-08-23 12:52:40 +0000 |
---|---|---|
committer | Aleksander Morgado <aleksandermj@chromium.org> | 2022-09-07 20:21:42 +0000 |
commit | 88bb60baa77111e0fa470ab6cfdb004dc13d5116 (patch) | |
tree | 6a034966fb5bb7ffaafcd1a287adbfb075d48210 | |
parent | d22bf20236dca5f93c21e9fc0b6d8d4b5092ac56 (diff) | |
download | libmbim-88bb60baa77111e0fa470ab6cfdb004dc13d5116.tar.gz |
ms-uicc-low-level-access: add support for 'Read Binary' operation
$ sudo mbimcli -p -d /dev/wwan0mbim0 --ms-query-uicc-read-binary="application-id=A0000000871002FF34FF0789312E30FF,file-path=7FFF6F3E"
[/dev/wwan0mbim0] UICC file binary read:
Status word 1: 144
Status word 2: 0
Data: 01
-rw-r--r-- | data/mbim-service-ms-uicc-low-level-access.json | 29 | ||||
-rw-r--r-- | src/libmbim-glib/mbim-cid.c | 3 | ||||
-rw-r--r-- | src/libmbim-glib/mbim-cid.h | 2 | ||||
-rw-r--r-- | src/mbimcli/mbimcli-ms-uicc-low-level-access.c | 198 |
4 files changed, 229 insertions, 3 deletions
diff --git a/data/mbim-service-ms-uicc-low-level-access.json b/data/mbim-service-ms-uicc-low-level-access.json index e249040..32d1a8e 100644 --- a/data/mbim-service-ms-uicc-low-level-access.json +++ b/data/mbim-service-ms-uicc-low-level-access.json @@ -171,5 +171,32 @@ "public-format" : "MbimPinType" }, { "name" : "AccessConditionDeactivate", "format" : "guint32", - "public-format" : "MbimPinType" } ] } + "public-format" : "MbimPinType" } ] }, + + // ********************************************************************************* + { "name" : "Read Binary", + "type" : "Command", + "since" : "1.28", + "query" : [ { "name" : "Version", + "format" : "guint32" }, + { "name" : "ApplicationId", + "format" : "ref-byte-array" }, + { "name" : "FilePath", + "format" : "ref-byte-array" }, + { "name" : "ReadOffset", + "format" : "guint32" }, + { "name" : "ReadSize", + "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 ccdae25..9194c8e 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_FILE_STATUS +#define MBIM_CID_MS_UICC_LOW_LEVEL_ACCESS_LAST MBIM_CID_MS_UICC_LOW_LEVEL_ACCESS_READ_BINARY 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 */ @@ -189,6 +189,7 @@ static const CidConfig cid_ms_uicc_low_level_access_config [MBIM_CID_MS_UICC_LOW { SET, QUERY, NO_NOTIFY }, /* MBIM_CID_MS_UICC_LOW_LEVEL_ACCESS_RESET */ { 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 */ }; /* 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 13b6cae..2e5ce0c 100644 --- a/src/libmbim-glib/mbim-cid.h +++ b/src/libmbim-glib/mbim-cid.h @@ -379,6 +379,7 @@ typedef enum { /*< since=1.18 >*/ * @MBIM_CID_MS_UICC_LOW_LEVEL_ACCESS_RESET: Reset. * @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 commands in the %MBIM_SERVICE_MS_UICC_LOW_LEVEL_ACCESS service. * @@ -394,6 +395,7 @@ typedef enum { /*< since=1.26 >*/ MBIM_CID_MS_UICC_LOW_LEVEL_ACCESS_RESET = 6, 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, } MbimCidMsUiccLowLevelAccess; /** diff --git a/src/mbimcli/mbimcli-ms-uicc-low-level-access.c b/src/mbimcli/mbimcli-ms-uicc-low-level-access.c index 707e83c..b3e4e6d 100644 --- a/src/mbimcli/mbimcli-ms-uicc-low-level-access.c +++ b/src/mbimcli/mbimcli-ms-uicc-low-level-access.c @@ -33,6 +33,7 @@ static Context *ctx; /* Options */ static gboolean query_uicc_application_list_flag; static gchar *query_uicc_file_status_str; +static gchar *query_uicc_read_binary_str; static GOptionEntry entries[] = { { "ms-query-uicc-application-list", 0, 0, G_OPTION_ARG_NONE, &query_uicc_application_list_flag, @@ -43,6 +44,10 @@ static GOptionEntry entries[] = { "Query UICC file status (allowed keys: application-id, file-path)", "[\"key=value,...\"]" }, + { "ms-query-uicc-read-binary", 0, 0, G_OPTION_ARG_STRING, &query_uicc_read_binary_str, + "Read UICC binary file (allowed keys: application-id, file-path, read-offset, read-size, local-pin and data)", + "[\"key=value,...\"]" + }, { NULL } }; @@ -71,7 +76,8 @@ mbimcli_ms_uicc_low_level_access_options_enabled (void) return !!n_actions; n_actions = query_uicc_application_list_flag + - !!query_uicc_file_status_str; + !!query_uicc_file_status_str + + !!query_uicc_read_binary_str; if (n_actions > 1) { g_printerr ("error: too many Microsoft UICC Low Level Access Service actions requested\n"); @@ -104,6 +110,154 @@ shutdown (gboolean operation_status) } static void +read_binary_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_binary_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 binary 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 read_offset; + guint32 read_size; + gchar *local_pin; + gsize data_size; + guint8 *data; +} ReadBinaryQueryProperties; + +static void +read_binary_query_properties_clear (ReadBinaryQueryProperties *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(ReadBinaryQueryProperties, read_binary_query_properties_clear); + +static gboolean +read_binary_query_properties_handle (const gchar *key, + const gchar *value, + GError **error, + gpointer user_data) +{ + ReadBinaryQueryProperties *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, "read-offset") == 0) { + if (!mbimcli_read_uint_from_string (value, &props->read_offset)) { + 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, "read-size") == 0) { + if (!mbimcli_read_uint_from_string (value, &props->read_size)) { + 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_binary_query_input_parse (const gchar *str, + ReadBinaryQueryProperties *props, + GError **error) +{ + + if (!mbimcli_parse_key_value_string (str, + error, + read_binary_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 file_status_query_ready (MbimDevice *device, GAsyncResult *res) { @@ -359,5 +513,47 @@ mbimcli_ms_uicc_low_level_access_run (MbimDevice *device, return; } + /* Request to UICC read binary? */ + if (query_uicc_read_binary_str) { + g_auto(ReadBinaryQueryProperties) props = { + .application_id_size = 0, + .application_id = NULL, + .file_path_size = 0, + .file_path = NULL, + .read_offset = 0, + .read_size = 0, + .local_pin = NULL, + .data_size = 0, + .data = NULL, + }; + + g_debug ("Asynchronously reading from UICC in binary..."); + + if (!read_binary_query_input_parse (query_uicc_read_binary_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_binary_query_new (1, /* version fixed */ + props.application_id_size, + props.application_id, + props.file_path_size, + props.file_path, + props.read_offset, + props.read_size, + props.local_pin, + props.data_size, + props.data, + NULL); + mbim_device_command (ctx->device, + request, + 10, + ctx->cancellable, + (GAsyncReadyCallback)read_binary_query_ready, + NULL); + return; + } + g_warn_if_reached (); } |