aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--data/qmi-service-uim.json52
-rw-r--r--docs/reference/libqmi-glib/libqmi-glib-common.sections5
-rw-r--r--docs/reference/libqmi-glib/libqmi-glib-docs.xml1
-rw-r--r--src/libqmi-glib/qmi-enums-uim.h21
-rw-r--r--src/qmicli/qmicli-dms.c8
-rw-r--r--src/qmicli/qmicli-helpers.c31
-rw-r--r--src/qmicli/qmicli-helpers.h4
-rw-r--r--src/qmicli/qmicli-uim.c118
8 files changed, 232 insertions, 8 deletions
diff --git a/data/qmi-service-uim.json b/data/qmi-service-uim.json
index 6b38f2a..8ad0cd9 100644
--- a/data/qmi-service-uim.json
+++ b/data/qmi-service-uim.json
@@ -292,6 +292,58 @@
"prerequisites" : [ { "common-ref" : "Success" } ] } ] },
// *********************************************************************************
+ { "name" : "Set PIN Protection",
+ "type" : "Message",
+ "service" : "UIM",
+ "id" : "0x0025",
+ "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 enabled",
+ "format" : "guint8",
+ "public-format" : "gboolean" },
+ { "name" : "PIN Value",
+ "format" : "string" } ] },
+ { "name" : "Response In Indication Token",
+ "id" : "0x11",
+ "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" : "Get Card Status",
"type" : "Message",
"service" : "UIM",
diff --git a/docs/reference/libqmi-glib/libqmi-glib-common.sections b/docs/reference/libqmi-glib/libqmi-glib-common.sections
index d45aeb9..1b0ab6d 100644
--- a/docs/reference/libqmi-glib/libqmi-glib-common.sections
+++ b/docs/reference/libqmi-glib/libqmi-glib-common.sections
@@ -755,6 +755,7 @@ QmiUimCardApplicationType
QmiUimCardApplicationState
QmiUimCardApplicationPersonalizationState
QmiUimCardApplicationPersonalizationFeature
+QmiUimPinId
<SUBSECTION Methods>
qmi_uim_session_type_get_string
qmi_uim_file_type_get_string
@@ -767,6 +768,7 @@ qmi_uim_card_application_type_get_string
qmi_uim_card_application_state_get_string
qmi_uim_card_application_personalization_state_get_string
qmi_uim_card_application_personalization_feature_get_string
+qmi_uim_pin_id_get_string
<SUBSECTION Private>
qmi_uim_session_type_build_string_from_mask
qmi_uim_file_type_build_string_from_mask
@@ -779,6 +781,7 @@ qmi_uim_card_application_type_build_string_from_mask
qmi_uim_card_error_build_string_from_mask
qmi_uim_card_state_build_string_from_mask
qmi_uim_pin_state_build_string_from_mask
+qmi_uim_pin_id_build_string_from_mask
<SUBSECTION Standard>
QMI_TYPE_UIM_SESSION_TYPE
QMI_TYPE_UIM_FILE_TYPE
@@ -791,6 +794,7 @@ QMI_TYPE_UIM_CARD_APPLICATION_TYPE
QMI_TYPE_UIM_CARD_ERROR
QMI_TYPE_UIM_CARD_STATE
QMI_TYPE_UIM_PIN_STATE
+QMI_TYPE_UIM_PIN_ID
qmi_uim_session_type_get_type
qmi_uim_file_type_get_type
qmi_uim_security_attribute_logic_get_type
@@ -802,6 +806,7 @@ qmi_uim_card_application_type_get_type
qmi_uim_card_error_get_type
qmi_uim_card_state_get_type
qmi_uim_pin_state_get_type
+qmi_uim_pin_id_get_type
</SECTION>
<SECTION>
diff --git a/docs/reference/libqmi-glib/libqmi-glib-docs.xml b/docs/reference/libqmi-glib/libqmi-glib-docs.xml
index e753fc2..8159b26 100644
--- a/docs/reference/libqmi-glib/libqmi-glib-docs.xml
+++ b/docs/reference/libqmi-glib/libqmi-glib-docs.xml
@@ -247,6 +247,7 @@
<section>
<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-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/libqmi-glib/qmi-enums-uim.h b/src/libqmi-glib/qmi-enums-uim.h
index 35b8f73..58ea549 100644
--- a/src/libqmi-glib/qmi-enums-uim.h
+++ b/src/libqmi-glib/qmi-enums-uim.h
@@ -122,6 +122,27 @@ typedef enum {
} QmiUimSecurityAttribute;
/*****************************************************************************/
+/* Helper enums for the 'QMI UIM Set PIN Protection' */
+
+/**
+ * QmiUimPinId:
+ * @QMI_UIM_PIN_ID_UNKNOWN: Unknown.
+ * @QMI_UIM_PIN_ID_PIN1: PIN1.
+ * @QMI_UIM_PIN_ID_PIN2: PIN2.
+ * @QMI_UIM_PIN_ID_UPIN: UPIN.
+ * @QMI_UIM_PIN_ID_HIDDEN_KEY: Hidden key.
+ *
+ * PIN ID.
+ */
+typedef enum {
+ QMI_UIM_PIN_ID_UNKNOWN = 0,
+ QMI_UIM_PIN_ID_PIN1 = 1,
+ QMI_UIM_PIN_ID_PIN2 = 2,
+ QMI_UIM_PIN_ID_UPIN = 3,
+ QMI_UIM_PIN_ID_HIDDEN_KEY = 4
+} QmiUimPinId;
+
+/*****************************************************************************/
/* Helper enums for the 'QMI UIM Get Card Status' request/response */
/**
diff --git a/src/qmicli/qmicli-dms.c b/src/qmicli/qmicli-dms.c
index c53aca5..5d080eb 100644
--- a/src/qmicli/qmicli-dms.c
+++ b/src/qmicli/qmicli-dms.c
@@ -685,7 +685,7 @@ uim_set_pin_protection_input_create (const gchar *str)
* "[(PIN|PIN2),(disable|enable),(current PIN)]"
*/
split = g_strsplit (str, ",", -1);
- if (qmicli_read_pin_id_from_string (split[0], &pin_id) &&
+ if (qmicli_read_dms_uim_pin_id_from_string (split[0], &pin_id) &&
qmicli_read_enable_disable_from_string (split[1], &enable_disable) &&
qmicli_read_non_empty_string (split[2], "current PIN", &current_pin)) {
GError *error = NULL;
@@ -769,7 +769,7 @@ uim_verify_pin_input_create (const gchar *str)
* "[(PIN|PIN2),(current PIN)]"
*/
split = g_strsplit (str, ",", -1);
- if (qmicli_read_pin_id_from_string (split[0], &pin_id) &&
+ if (qmicli_read_dms_uim_pin_id_from_string (split[0], &pin_id) &&
qmicli_read_non_empty_string (split[1], "current PIN", &current_pin)) {
GError *error = NULL;
@@ -852,7 +852,7 @@ uim_unblock_pin_input_create (const gchar *str)
* "[(PIN|PIN2),(PUK),(new PIN)]"
*/
split = g_strsplit (str, ",", -1);
- if (qmicli_read_pin_id_from_string (split[0], &pin_id) &&
+ if (qmicli_read_dms_uim_pin_id_from_string (split[0], &pin_id) &&
qmicli_read_non_empty_string (split[1], "PUK", &puk) &&
qmicli_read_non_empty_string (split[2], "new PIN", &new_pin)) {
GError *error = NULL;
@@ -937,7 +937,7 @@ uim_change_pin_input_create (const gchar *str)
* "[(PIN|PIN2),(old PIN),(new PIN)]"
*/
split = g_strsplit (str, ",", -1);
- if (qmicli_read_pin_id_from_string (split[0], &pin_id) &&
+ if (qmicli_read_dms_uim_pin_id_from_string (split[0], &pin_id) &&
qmicli_read_non_empty_string (split[1], "old PIN", &old_pin) &&
qmicli_read_non_empty_string (split[2], "new PIN", &new_pin)) {
GError *error = NULL;
diff --git a/src/qmicli/qmicli-helpers.c b/src/qmicli/qmicli-helpers.c
index 511adf5..205f319 100644
--- a/src/qmicli/qmicli-helpers.c
+++ b/src/qmicli/qmicli-helpers.c
@@ -105,8 +105,8 @@ qmicli_get_raw_data_printable (const GArray *data,
}
gboolean
-qmicli_read_pin_id_from_string (const gchar *str,
- QmiDmsUimPinId *out)
+qmicli_read_dms_uim_pin_id_from_string (const gchar *str,
+ QmiDmsUimPinId *out)
{
if (!str || str[0] == '\0') {
g_printerr ("error: expected 'PIN' or 'PIN2', got: none\n");
@@ -128,6 +128,33 @@ qmicli_read_pin_id_from_string (const gchar *str,
}
gboolean
+qmicli_read_uim_pin_id_from_string (const gchar *str,
+ QmiUimPinId *out)
+{
+ if (!str || str[0] == '\0') {
+ g_printerr ("error: expected 'PIN1', 'PIN2' or 'UPIN', got: none\n");
+ return FALSE;
+ }
+
+ if (g_str_equal (str, "PIN1")) {
+ *out = QMI_UIM_PIN_ID_PIN1;
+ return TRUE;
+ }
+
+ if (g_str_equal (str, "PIN2")) {
+ *out = QMI_UIM_PIN_ID_PIN2;
+ return TRUE;
+ }
+ if (g_str_equal (str, "UPIN")) {
+ *out = QMI_UIM_PIN_ID_UPIN;
+ return TRUE;
+ }
+
+ g_printerr ("error: expected 'PIN1', 'PIN2' or 'UPIN', got: '%s'\n", str);
+ return FALSE;
+}
+
+gboolean
qmicli_read_operating_mode_from_string (const gchar *str,
QmiDmsOperatingMode *out)
{
diff --git a/src/qmicli/qmicli-helpers.h b/src/qmicli/qmicli-helpers.h
index 1dcb95c..1a2a78c 100644
--- a/src/qmicli/qmicli-helpers.h
+++ b/src/qmicli/qmicli-helpers.h
@@ -30,8 +30,10 @@ gchar *qmicli_get_raw_data_printable (const GArray *data,
gsize max_line_length,
const gchar *new_line_prefix);
-gboolean qmicli_read_pin_id_from_string (const gchar *str,
+gboolean qmicli_read_dms_uim_pin_id_from_string (const gchar *str,
QmiDmsUimPinId *out);
+gboolean qmicli_read_uim_pin_id_from_string (const gchar *str,
+ QmiUimPinId *out);
gboolean qmicli_read_operating_mode_from_string (const gchar *str,
QmiDmsOperatingMode *out);
gboolean qmicli_read_rat_mode_pref_from_string (const gchar *str,
diff --git a/src/qmicli/qmicli-uim.c b/src/qmicli/qmicli-uim.c
index c350474..e7276eb 100644
--- a/src/qmicli/qmicli-uim.c
+++ b/src/qmicli/qmicli-uim.c
@@ -43,6 +43,7 @@ static Context *ctx;
/* Options */
static gchar *read_transparent_str;
+static gchar *set_pin_protection_str;
static gchar *get_file_attributes_str;
static gboolean get_card_status_flag;
static gboolean get_supported_messages_flag;
@@ -50,6 +51,10 @@ static gboolean reset_flag;
static gboolean noop_flag;
static GOptionEntry entries[] = {
+ { "uim-set-pin-protection", 0, 0, G_OPTION_ARG_STRING, &set_pin_protection_str,
+ "Set PIN protection",
+ "[(PIN1|PIN2|UPIN),(disable|enable),(current PIN)]"
+ },
{ "uim-read-transparent", 0, 0, G_OPTION_ARG_STRING, &read_transparent_str,
"Read a transparent file given the file path",
"[0xNNNN,0xNNNN,...]"
@@ -101,7 +106,8 @@ qmicli_uim_options_enabled (void)
if (checked)
return !!n_actions;
- n_actions = (!!read_transparent_str +
+ n_actions = (!!set_pin_protection_str +
+ !!read_transparent_str +
!!get_file_attributes_str +
get_card_status_flag +
get_supported_messages_flag +
@@ -138,6 +144,96 @@ operation_shutdown (gboolean operation_status)
qmicli_async_operation_done (operation_status);
}
+static QmiMessageUimSetPinProtectionInput *
+set_pin_protection_input_create (const gchar *str)
+{
+ QmiMessageUimSetPinProtectionInput *input = NULL;
+ gchar **split;
+ QmiUimPinId pin_id;
+ gboolean enable_disable;
+ gchar *current_pin;
+
+ /* Prepare inputs.
+ * Format of the string is:
+ * "[(PIN1|PIN2|UPIN),(disable|enable),(current PIN)]"
+ */
+ split = g_strsplit (str, ",", -1);
+ if (qmicli_read_uim_pin_id_from_string (split[0], &pin_id) &&
+ qmicli_read_enable_disable_from_string (split[1], &enable_disable) &&
+ qmicli_read_non_empty_string (split[2], "current PIN", &current_pin)) {
+ GError *error = NULL;
+
+ input = qmi_message_uim_set_pin_protection_input_new ();
+ if (!qmi_message_uim_set_pin_protection_input_set_info (
+ input,
+ pin_id,
+ enable_disable,
+ current_pin,
+ &error) ||
+ !qmi_message_uim_set_pin_protection_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_set_pin_protection_input_unref (input);
+ input = NULL;
+ }
+ }
+ g_strfreev (split);
+
+ return input;
+}
+
+static void
+set_pin_protection_ready (QmiClientUim *client,
+ GAsyncResult *res)
+{
+ QmiMessageUimSetPinProtectionOutput *output;
+ GError *error = NULL;
+
+ output = qmi_client_uim_set_pin_protection_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_set_pin_protection_output_get_result (output, &error)) {
+ guint8 verify_retries_left;
+ guint8 unblock_retries_left;
+
+ g_printerr ("error: couldn't set PIN protection: %s\n", error->message);
+ g_error_free (error);
+
+ if (qmi_message_uim_set_pin_protection_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_set_pin_protection_output_unref (output);
+ operation_shutdown (FALSE);
+ return;
+ }
+
+ g_print ("[%s] PIN protection updated\n",
+ qmi_device_get_path_display (ctx->device));
+
+ qmi_message_uim_set_pin_protection_output_unref (output);
+ operation_shutdown (TRUE);
+}
+
static void
get_supported_messages_ready (QmiClientUim *client,
GAsyncResult *res)
@@ -690,6 +786,26 @@ qmicli_uim_run (QmiDevice *device,
ctx->client = g_object_ref (client);
ctx->cancellable = g_object_ref (cancellable);
+ /* Set PIN protection */
+ if (set_pin_protection_str) {
+ QmiMessageUimSetPinProtectionInput *input;
+
+ g_debug ("Asynchronously setting PIN protection...");
+ input = set_pin_protection_input_create (set_pin_protection_str);
+ if (!input) {
+ operation_shutdown (FALSE);
+ return;
+ }
+ qmi_client_uim_set_pin_protection (ctx->client,
+ input,
+ 10,
+ ctx->cancellable,
+ (GAsyncReadyCallback)set_pin_protection_ready,
+ NULL);
+ qmi_message_uim_set_pin_protection_input_unref (input);
+ return;
+ }
+
/* Request to read a transparent file? */
if (read_transparent_str) {
QmiMessageUimReadTransparentInput *input;