diff options
author | Michal Mazur <mkm@semihalf.com> | 2021-01-07 18:48:37 +0100 |
---|---|---|
committer | Aleksander Morgado <aleksander@aleksander.es> | 2021-03-09 10:16:32 +0000 |
commit | 0a1971899ebfe44ad5b3e690608b2842d5df362a (patch) | |
tree | 2070b8c767f1b25908ca2976421423da774b14f2 | |
parent | e12924547673d4ce5cb797016315582aca84d79b (diff) |
qmicli: new '--get-configuration' and '--depersonalization' actions
Co-authored-by: Aleksander Morgado <aleksander@aleksander.es>
-rw-r--r-- | src/qmicli/qmicli-helpers.h | 48 | ||||
-rw-r--r-- | src/qmicli/qmicli-uim.c | 255 |
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); |