diff options
-rw-r--r-- | data/qmi-service-uim.json | 58 | ||||
-rw-r--r-- | docs/reference/libqmi-glib/libqmi-glib-docs.xml | 1 | ||||
-rw-r--r-- | src/qmicli/qmicli-uim.c | 113 |
3 files changed, 172 insertions, 0 deletions
diff --git a/data/qmi-service-uim.json b/data/qmi-service-uim.json index 8ad0cd90..02620dd5 100644 --- a/data/qmi-service-uim.json +++ b/data/qmi-service-uim.json @@ -344,6 +344,64 @@ "prerequisites" : [ { "common-ref" : "Success" } ] } ] }, // ********************************************************************************* + { "name" : "Verify PIN", + "type" : "Message", + "service" : "UIM", + "id" : "0x0026", + "version" : "1.0", + "input" : [ { "name" : "Session Information", + "id" : "0x01", + "mandatory" : "yes", + "type" : "TLV", + "format" : "sequence", + "contents" : [ { "name" : "Session Type", + "format" : "guint8", + "public-format" : "QmiUimSessionType" }, + { "name" : "Application Identifier", + "format" : "string" } ] }, + { "name" : "Info", + "id" : "0x02", + "mandatory" : "yes", + "type" : "TLV", + "format" : "sequence", + "contents" : [ { "name" : "PIN ID", + "format" : "guint8", + "public-format" : "QmiUimPinId" }, + { "name" : "PIN Value", + "format" : "string" } ] }, + { "name" : "Response In Indication Token", + "id" : "0x12", + "mandatory" : "no", + "type" : "TLV", + "format" : "guint32" } ], + "output" : [ { "common-ref" : "Operation Result" }, + { "name" : "Retries Remaining", + "id" : "0x10", + "mandatory" : "no", + "type" : "TLV", + "format" : "sequence", + "contents" : [ { "name" : "Verify Retries Left", + "format" : "guint8" }, + { "name" : "Unblock Retries Left", + "format" : "guint8" } ], + "prerequisites": [ { "common-ref" : "No Success" } ] }, + { "name" : "Response In Indication Token", + "id" : "0x12", + "mandatory" : "no", + "type" : "TLV", + "format" : "guint32", + "prerequisites" : [ { "common-ref" : "Success" } ] }, + { "name" : "Card Result", + "id" : "0x13", + "mandatory" : "no", + "type" : "TLV", + "format" : "sequence", + "contents" : [ { "name" : "SW1", + "format" : "guint8" }, + { "name" : "SW2", + "format" : "guint8" } ] } ] }, + + // ********************************************************************************* { "name" : "Get Card Status", "type" : "Message", "service" : "UIM", diff --git a/docs/reference/libqmi-glib/libqmi-glib-docs.xml b/docs/reference/libqmi-glib/libqmi-glib-docs.xml index 8159b263..73af0f42 100644 --- a/docs/reference/libqmi-glib/libqmi-glib-docs.xml +++ b/docs/reference/libqmi-glib/libqmi-glib-docs.xml @@ -248,6 +248,7 @@ <title>UIM Requests</title> <xi:include href="xml/qmi-message-uim-reset.xml"/> <xi:include href="xml/qmi-message-uim-set-pin-protection.xml"/> + <xi:include href="xml/qmi-message-uim-verify-pin.xml"/> <xi:include href="xml/qmi-message-uim-read-transparent.xml"/> <xi:include href="xml/qmi-message-uim-read-record.xml"/> <xi:include href="xml/qmi-message-uim-get-file-attributes.xml"/> diff --git a/src/qmicli/qmicli-uim.c b/src/qmicli/qmicli-uim.c index e7276ebf..feb23549 100644 --- a/src/qmicli/qmicli-uim.c +++ b/src/qmicli/qmicli-uim.c @@ -44,6 +44,7 @@ static Context *ctx; /* Options */ static gchar *read_transparent_str; static gchar *set_pin_protection_str; +static gchar *verify_pin_str; static gchar *get_file_attributes_str; static gboolean get_card_status_flag; static gboolean get_supported_messages_flag; @@ -55,6 +56,10 @@ static GOptionEntry entries[] = { "Set PIN protection", "[(PIN1|PIN2|UPIN),(disable|enable),(current PIN)]" }, + { "uim-verify-pin", 0, 0, G_OPTION_ARG_STRING, &verify_pin_str, + "Verify PIN", + "[(PIN1|PIN2|UPIN),(current PIN)]", + }, { "uim-read-transparent", 0, 0, G_OPTION_ARG_STRING, &read_transparent_str, "Read a transparent file given the file path", "[0xNNNN,0xNNNN,...]" @@ -107,6 +112,7 @@ qmicli_uim_options_enabled (void) return !!n_actions; n_actions = (!!set_pin_protection_str + + !!verify_pin_str + !!read_transparent_str + !!get_file_attributes_str + get_card_status_flag + @@ -234,6 +240,93 @@ set_pin_protection_ready (QmiClientUim *client, operation_shutdown (TRUE); } +static QmiMessageUimVerifyPinInput * +verify_pin_input_create (const gchar *str) +{ + QmiMessageUimVerifyPinInput *input = NULL; + gchar **split; + QmiUimPinId pin_id; + gchar *current_pin; + + /* Prepare inputs. + * Format of the string is: + * "[(PIN1|PIN2),(current PIN)]" + */ + split = g_strsplit (str, ",", -1); + if (qmicli_read_uim_pin_id_from_string (split[0], &pin_id) && + qmicli_read_non_empty_string (split[1], "current PIN", ¤t_pin)) { + GError *error = NULL; + + input = qmi_message_uim_verify_pin_input_new (); + if (!qmi_message_uim_verify_pin_input_set_info ( + input, + pin_id, + current_pin, + &error) || + !qmi_message_uim_verify_pin_input_set_session_information ( + input, + QMI_UIM_SESSION_TYPE_CARD_SLOT_1, + "", /* ignored */ + &error)) { + g_printerr ("error: couldn't create input data bundle: '%s'\n", + error->message); + g_error_free (error); + qmi_message_uim_verify_pin_input_unref (input); + input = NULL; + } + } + g_strfreev (split); + + return input; +} + +static void +verify_pin_ready (QmiClientUim *client, + GAsyncResult *res) +{ + QmiMessageUimVerifyPinOutput *output; + GError *error = NULL; + + output = qmi_client_uim_verify_pin_finish (client, res, &error); + if (!output) { + g_printerr ("error: operation failed: %s\n", error->message); + g_error_free (error); + operation_shutdown (FALSE); + return; + } + + if (!qmi_message_uim_verify_pin_output_get_result (output, &error)) { + guint8 verify_retries_left; + guint8 unblock_retries_left; + + g_printerr ("error: couldn't verify PIN: %s\n", error->message); + g_error_free (error); + + if (qmi_message_uim_verify_pin_output_get_retries_remaining ( + output, + &verify_retries_left, + &unblock_retries_left, + NULL)) { + g_printerr ("[%s] Retries left:\n" + "\tVerify: %u\n" + "\tUnblock: %u\n", + qmi_device_get_path_display (ctx->device), + verify_retries_left, + unblock_retries_left); + } + + qmi_message_uim_verify_pin_output_unref (output); + operation_shutdown (FALSE); + return; + } + + g_print ("[%s] PIN verified successfully\n", + qmi_device_get_path_display (ctx->device)); + + qmi_message_uim_verify_pin_output_unref (output); + operation_shutdown (TRUE); +} + static void get_supported_messages_ready (QmiClientUim *client, GAsyncResult *res) @@ -806,6 +899,26 @@ qmicli_uim_run (QmiDevice *device, return; } + /* Request to verify PIN? */ + if (verify_pin_str) { + QmiMessageUimVerifyPinInput *input; + + g_debug ("Asynchronously verifying PIN..."); + input = verify_pin_input_create (verify_pin_str); + if (!input) { + operation_shutdown (FALSE); + return; + } + qmi_client_uim_verify_pin (ctx->client, + input, + 10, + ctx->cancellable, + (GAsyncReadyCallback)verify_pin_ready, + NULL); + qmi_message_uim_verify_pin_input_unref (input); + return; + } + /* Request to read a transparent file? */ if (read_transparent_str) { QmiMessageUimReadTransparentInput *input; |