aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichal Mazur <mkm@semihalf.com>2021-01-07 18:48:37 +0100
committerAleksander Morgado <aleksander@aleksander.es>2021-03-09 10:16:32 +0000
commit0a1971899ebfe44ad5b3e690608b2842d5df362a (patch)
tree2070b8c767f1b25908ca2976421423da774b14f2
parente12924547673d4ce5cb797016315582aca84d79b (diff)
qmicli: new '--get-configuration' and '--depersonalization' actions
Co-authored-by: Aleksander Morgado <aleksander@aleksander.es>
-rw-r--r--src/qmicli/qmicli-helpers.h48
-rw-r--r--src/qmicli/qmicli-uim.c255
2 files changed, 280 insertions, 23 deletions
diff --git a/src/qmicli/qmicli-helpers.h b/src/qmicli/qmicli-helpers.h
index 446e4ec..4171856 100644
--- a/src/qmicli/qmicli-helpers.h
+++ b/src/qmicli/qmicli-helpers.h
@@ -27,29 +27,31 @@
#define __QMICLI_HELPERS_H__
/* Common helpers to read enums from strings */
-#define QMICLI_ENUM_LIST \
- QMICLI_ENUM_LIST_ITEM (QmiDmsOperatingMode, dms_operating_mode, "operating mode") \
- QMICLI_ENUM_LIST_ITEM (QmiDmsUimFacility, dms_uim_facility, "facility") \
- QMICLI_ENUM_LIST_ITEM (QmiPdcConfigurationType, pdc_configuration_type, "configuration type") \
- QMICLI_ENUM_LIST_ITEM (QmiNasRadioInterface, nas_radio_interface, "radio interface") \
- QMICLI_ENUM_LIST_ITEM (QmiDeviceExpectedDataFormat, device_expected_data_format, "device expected data format") \
- QMICLI_ENUM_LIST_ITEM (QmiWdaLinkLayerProtocol, wda_link_layer_protocol, "link layer protocol") \
- QMICLI_ENUM_LIST_ITEM (QmiWdaDataAggregationProtocol, wda_data_aggregation_protocol, "data aggregation protocol") \
- QMICLI_ENUM_LIST_ITEM (QmiDataEndpointType, data_endpoint_type, "data endpoint type") \
- QMICLI_ENUM_LIST_ITEM (QmiWdsAutoconnectSetting, wds_autoconnect_setting, "autoconnect setting") \
- QMICLI_ENUM_LIST_ITEM (QmiWdsAutoconnectSettingRoaming, wds_autoconnect_setting_roaming, "autoconnect setting roaming") \
- QMICLI_ENUM_LIST_ITEM (QmiDmsBootImageDownloadMode, dms_boot_image_download_mode, "boot image download mode") \
- QMICLI_ENUM_LIST_ITEM (QmiDmsHpDeviceMode, dms_hp_device_mode, "hp device mode") \
- QMICLI_ENUM_LIST_ITEM (QmiDmsSwiUsbComposition, dms_swi_usb_composition, "swi usb composition") \
- QMICLI_ENUM_LIST_ITEM (QmiDmsFoxconnDeviceMode, dms_foxconn_device_mode, "foxconn device mode") \
- QMICLI_ENUM_LIST_ITEM (QmiDmsFoxconnFirmwareVersionType, dms_foxconn_firmware_version_type, "foxconn firmware version type") \
- QMICLI_ENUM_LIST_ITEM (QmiUimSessionType, uim_session_type, "session type") \
- QMICLI_ENUM_LIST_ITEM (QmiDsdApnType, dsd_apn_type, "apn type") \
- QMICLI_ENUM_LIST_ITEM (QmiDmsMacType, dms_mac_type, "mac address type") \
- QMICLI_ENUM_LIST_ITEM (QmiSarRfState, sar_rf_state, "sar rf state") \
- QMICLI_ENUM_LIST_ITEM (QmiSioPort, sio_port, "sio port") \
- QMICLI_ENUM_LIST_ITEM (QmiLocOperationMode, loc_operation_mode, "operation mode") \
- QMICLI_ENUM_LIST_ITEM (QmiLocLockType, loc_lock_type, "lock type")
+#define QMICLI_ENUM_LIST \
+ QMICLI_ENUM_LIST_ITEM (QmiDmsOperatingMode, dms_operating_mode, "operating mode") \
+ QMICLI_ENUM_LIST_ITEM (QmiDmsUimFacility, dms_uim_facility, "facility") \
+ QMICLI_ENUM_LIST_ITEM (QmiPdcConfigurationType, pdc_configuration_type, "configuration type") \
+ QMICLI_ENUM_LIST_ITEM (QmiNasRadioInterface, nas_radio_interface, "radio interface") \
+ QMICLI_ENUM_LIST_ITEM (QmiDeviceExpectedDataFormat, device_expected_data_format, "device expected data format") \
+ QMICLI_ENUM_LIST_ITEM (QmiWdaLinkLayerProtocol, wda_link_layer_protocol, "link layer protocol") \
+ QMICLI_ENUM_LIST_ITEM (QmiWdaDataAggregationProtocol, wda_data_aggregation_protocol, "data aggregation protocol") \
+ QMICLI_ENUM_LIST_ITEM (QmiDataEndpointType, data_endpoint_type, "data endpoint type") \
+ QMICLI_ENUM_LIST_ITEM (QmiWdsAutoconnectSetting, wds_autoconnect_setting, "autoconnect setting") \
+ QMICLI_ENUM_LIST_ITEM (QmiWdsAutoconnectSettingRoaming, wds_autoconnect_setting_roaming, "autoconnect setting roaming") \
+ QMICLI_ENUM_LIST_ITEM (QmiDmsBootImageDownloadMode, dms_boot_image_download_mode, "boot image download mode") \
+ QMICLI_ENUM_LIST_ITEM (QmiDmsHpDeviceMode, dms_hp_device_mode, "hp device mode") \
+ QMICLI_ENUM_LIST_ITEM (QmiDmsSwiUsbComposition, dms_swi_usb_composition, "swi usb composition") \
+ QMICLI_ENUM_LIST_ITEM (QmiDmsFoxconnDeviceMode, dms_foxconn_device_mode, "foxconn device mode") \
+ QMICLI_ENUM_LIST_ITEM (QmiDmsFoxconnFirmwareVersionType, dms_foxconn_firmware_version_type, "foxconn firmware version type") \
+ QMICLI_ENUM_LIST_ITEM (QmiUimSessionType, uim_session_type, "session type") \
+ QMICLI_ENUM_LIST_ITEM (QmiDsdApnType, dsd_apn_type, "apn type") \
+ QMICLI_ENUM_LIST_ITEM (QmiDmsMacType, dms_mac_type, "mac address type") \
+ QMICLI_ENUM_LIST_ITEM (QmiSarRfState, sar_rf_state, "sar rf state") \
+ QMICLI_ENUM_LIST_ITEM (QmiSioPort, sio_port, "sio port") \
+ QMICLI_ENUM_LIST_ITEM (QmiLocOperationMode, loc_operation_mode, "operation mode") \
+ QMICLI_ENUM_LIST_ITEM (QmiLocLockType, loc_lock_type, "lock type") \
+ QMICLI_ENUM_LIST_ITEM (QmiUimCardApplicationPersonalizationFeature, uim_card_application_personalization_feature, "personalization feature" ) \
+ QMICLI_ENUM_LIST_ITEM (QmiUimDepersonalizationOperation, uim_depersonalization_operation, "depersonalization operation" )
#define QMICLI_ENUM_LIST_ITEM(TYPE,TYPE_UNDERSCORE,DESCR) \
gboolean qmicli_read_## TYPE_UNDERSCORE ##_from_string (const gchar *str, TYPE *out);
diff --git a/src/qmicli/qmicli-uim.c b/src/qmicli/qmicli-uim.c
index a8e1810..4c2fef3 100644
--- a/src/qmicli/qmicli-uim.c
+++ b/src/qmicli/qmicli-uim.c
@@ -59,6 +59,7 @@ static gchar *sim_power_on_str;
static gchar *sim_power_off_str;
static gchar *change_provisioning_session_str;
static gchar *switch_slot_str;
+static gchar *depersonalization_str;
static gchar **monitor_refresh_file_array;
static gboolean get_card_status_flag;
static gboolean get_supported_messages_flag;
@@ -67,6 +68,7 @@ static gboolean monitor_slot_status_flag;
static gboolean reset_flag;
static gboolean monitor_refresh_all_flag;
static gboolean noop_flag;
+static gboolean get_configuration_flag;
#undef VALIDATE_UNKNOWN
#define VALIDATE_UNKNOWN(str) (str ? str : "unknown")
@@ -180,6 +182,19 @@ static GOptionEntry entries[] = {
NULL
},
#endif
+#if defined HAVE_QMI_MESSAGE_UIM_GET_CONFIGURATION
+ { "uim-get-configuration", 0, 0, G_OPTION_ARG_NONE, &get_configuration_flag,
+ "Get personalization status of the modem",
+ NULL
+ },
+#endif
+#if defined HAVE_QMI_MESSAGE_UIM_DEPERSONALIZATION
+ { "uim-depersonalization", 0, 0, G_OPTION_ARG_STRING, &depersonalization_str,
+ "Deactivates or unblocks personalization feature",
+ "[(feature),(operation),(control key)[,(slot number)]]"
+ },
+#endif
+
{ "uim-noop", 0, 0, G_OPTION_ARG_NONE, &noop_flag,
"Just allocate or release a UIM client. Use with `--client-no-release-cid' and/or `--client-cid'",
NULL
@@ -223,12 +238,14 @@ qmicli_uim_options_enabled (void)
!!change_provisioning_session_str +
!!switch_slot_str +
!!monitor_refresh_file_array +
+ !!depersonalization_str +
get_card_status_flag +
get_supported_messages_flag +
get_slot_status_flag +
monitor_slot_status_flag +
reset_flag +
monitor_refresh_all_flag +
+ get_configuration_flag +
noop_flag);
if (n_actions > 1) {
@@ -2382,6 +2399,200 @@ register_refresh_all_events (void)
#endif /* HAVE_QMI_MESSAGE_UIM_REFRESH_REGISTER_ALL */
+#if defined HAVE_QMI_MESSAGE_UIM_GET_CONFIGURATION
+
+static QmiMessageUimGetConfigurationInput *
+get_configuration_input_create (void)
+{
+ QmiMessageUimGetConfigurationInput *input;
+
+ input = qmi_message_uim_get_configuration_input_new ();
+
+ qmi_message_uim_get_configuration_input_set_configuration_mask (
+ input,
+ QMI_UIM_CONFIGURATION_PERSONALIZATION_STATUS,
+ NULL);
+
+ return input;
+}
+
+static void
+get_configuration_ready (QmiClientUim *client,
+ GAsyncResult *res)
+{
+ g_autoptr(QmiMessageUimGetConfigurationOutput) output = NULL;
+ g_autoptr(GError) error = NULL;
+ GArray *elements = NULL;
+ GArray *other_slots = NULL;
+
+ output = qmi_client_uim_get_configuration_finish (client, res, &error);
+ if (!output) {
+ g_printerr ("error: operation failed: %s\n", error->message);
+ operation_shutdown (FALSE);
+ return;
+ }
+
+ if (!qmi_message_uim_get_configuration_output_get_result (output, &error)) {
+ g_printerr ("error: get configuration failed: %s\n", error->message);
+ operation_shutdown (FALSE);
+ return;
+ }
+
+ g_print ("Configuration successfully retrieved\n");
+
+ /* Other slots TLV contains info for slots > 1 */
+ qmi_message_uim_get_configuration_output_get_personalization_status_other_slots (output, &other_slots, NULL);
+
+ if (qmi_message_uim_get_configuration_output_get_personalization_status (output, &elements, NULL)) {
+ if (elements->len == 0)
+ g_print ("Personalization features%s: all disabled\n",
+ other_slots ? " in slot 1" : "");
+ else {
+ QmiMessageUimGetConfigurationOutputPersonalizationStatusElement *element;
+ guint i;
+
+ g_print ("Personalization features%s:\n",
+ other_slots ? " in slot 1" : "");
+ for (i = 0; i < elements->len; i++) {
+ element = &g_array_index (elements,
+ QmiMessageUimGetConfigurationOutputPersonalizationStatusElement,
+ i);
+ g_print ("\tPersonalization: %s\n"
+ "\t\tVerify left: %u\n"
+ "\t\tUnblock left: %u\n",
+ qmi_uim_card_application_personalization_feature_get_string (element->feature),
+ element->verify_left,
+ element->unblock_left);
+ }
+ }
+ }
+
+ if (other_slots) {
+ if (other_slots->len == 0)
+ g_print ("Personalization features in other slots: all disabled\n");
+ else {
+ guint slot;
+
+ for (slot = 0; slot < other_slots->len; slot++) {
+ QmiMessageUimGetConfigurationOutputPersonalizationStatusElement *element;
+ guint i;
+
+ elements = g_array_index (other_slots, GArray *, slot);
+ if (!elements)
+ continue;
+
+ g_print ("Personalization features in slot %u:\n", slot + 2);
+ for (i = 0; i < elements->len; i++) {
+ element = &g_array_index (elements,
+ QmiMessageUimGetConfigurationOutputPersonalizationStatusElement,
+ i);
+ g_print ("\tPersonalization: %s\n"
+ "\t\tVerify left: %u\n"
+ "\t\tUnblock left: %u\n",
+ qmi_uim_card_application_personalization_feature_get_string (element->feature),
+ element->verify_left,
+ element->unblock_left);
+ }
+ }
+ }
+ }
+
+ operation_shutdown (TRUE);
+}
+
+#endif /* HAVE_QMI_MESSAGE_UIM_GET_CONFIGURATION */
+
+#if defined HAVE_QMI_MESSAGE_UIM_DEPERSONALIZATION
+
+static QmiMessageUimDepersonalizationInput *
+depersonalization_input_create (const gchar *str)
+{
+ g_auto(GStrv) split = NULL;
+ QmiMessageUimDepersonalizationInput *input = NULL;
+ QmiUimCardApplicationPersonalizationFeature feature;
+ QmiUimDepersonalizationOperation operation;
+ const gchar *control_key;
+ guint slot = 0;
+
+ /* Prepare inputs.
+ * Format of the string is:
+ * "[(feature),(operation),(control key)[,(slot number)]]"
+ */
+ split = g_strsplit (str, ",", -1);
+
+ if (!split[0] || !qmicli_read_uim_card_application_personalization_feature_from_string (split[0], &feature)) {
+ g_printerr ("error: invalid personalization feature\n");
+ return NULL;
+ }
+
+ if (!split[1] || !qmicli_read_uim_depersonalization_operation_from_string (split[1], &operation)) {
+ g_printerr ("error: invalid depersonalization operation\n");
+ return NULL;
+ }
+
+ if (!split[2]) {
+ g_printerr ("error: missing control key\n");
+ return NULL;
+ }
+ control_key = split[2];
+
+ if (g_strv_length (split) > 3) {
+ if (!qmicli_read_uint_from_string (split[3], &slot) || (slot < 1) || (slot > 5)) {
+ g_printerr ("error: invalid slot number\n");
+ return NULL;
+ }
+ }
+
+ input = qmi_message_uim_depersonalization_input_new ();
+ qmi_message_uim_depersonalization_input_set_info (input, feature, operation, control_key, NULL);
+
+ /* skip setting slot if not given by the user */
+ if (slot > 0)
+ qmi_message_uim_depersonalization_input_set_slot (input, slot, NULL);
+
+ return input;
+}
+
+static void
+depersonalization_ready (QmiClientUim *client,
+ GAsyncResult *res)
+{
+ g_autoptr(QmiMessageUimDepersonalizationOutput) output = NULL;
+ g_autoptr(GError) error = NULL;
+ guint8 unblock_left;
+ guint8 verify_left;
+
+ output = qmi_client_uim_depersonalization_finish (client, res, &error);
+ if (!output) {
+ g_printerr ("error: operation failed: %s\n", error->message);
+ operation_shutdown (FALSE);
+ return;
+ }
+
+ if (qmi_message_uim_depersonalization_output_get_result (output, &error)) {
+ g_print ("Modem was unlocked successfully\n");
+ operation_shutdown (TRUE);
+ return;
+ }
+
+ g_printerr ("error: depersonalization failed: %s\n", error->message);
+ if (qmi_message_uim_depersonalization_output_get_retries_remaining (
+ output,
+ &verify_left,
+ &unblock_left,
+ NULL)) {
+ g_printerr ("Retries left:\n"
+ "\tVerify: %u\n"
+ "\tUnblock: %u\n",
+ verify_left,
+ unblock_left);
+ }
+
+ operation_shutdown (FALSE);
+}
+
+#endif /* HAVE_QMI_MESSAGE_UIM_DEPERSONALIZATION */
+
void
qmicli_uim_run (QmiDevice *device,
QmiClientUim *client,
@@ -2714,6 +2925,50 @@ qmicli_uim_run (QmiDevice *device,
}
#endif
+#if defined HAVE_QMI_MESSAGE_UIM_GET_CONFIGURATION
+ /* Request to get personalization status? */
+ if (get_configuration_flag) {
+ g_autoptr(QmiMessageUimGetConfigurationInput) input = NULL;
+
+ g_debug ("Asynchronously getting UIM configuration...");
+ input = get_configuration_input_create ();
+ if (!input) {
+ operation_shutdown (FALSE);
+ return;
+ }
+
+ qmi_client_uim_get_configuration (ctx->client,
+ input,
+ 10,
+ ctx->cancellable,
+ (GAsyncReadyCallback)get_configuration_ready,
+ NULL);
+ return;
+ }
+#endif
+
+#if defined HAVE_QMI_MESSAGE_UIM_DEPERSONALIZATION
+ /* Request to depersonalize the modem? */
+ if (depersonalization_str) {
+ g_autoptr(QmiMessageUimDepersonalizationInput) input = NULL;
+
+ g_debug ("Asynchronously removing personalization...");
+ input = depersonalization_input_create (depersonalization_str);
+ if (!input) {
+ operation_shutdown (FALSE);
+ return;
+ }
+
+ qmi_client_uim_depersonalization (ctx->client,
+ input,
+ 10,
+ ctx->cancellable,
+ (GAsyncReadyCallback)depersonalization_ready,
+ NULL);
+ return;
+ }
+#endif
+
/* Just client allocate/release? */
if (noop_flag) {
g_idle_add (noop_cb, NULL);