diff options
author | Carlo Lobrano <carlo.lobrano@telit.com> | 2017-10-03 11:58:44 +0200 |
---|---|---|
committer | Aleksander Morgado <aleksander@aleksander.es> | 2017-10-06 10:32:44 +0200 |
commit | 6bf1b8cb9e7fc3763c41b3f7ff388c8088a67bf2 (patch) | |
tree | 79ae5a00a4c0763905b9a785ea431d6b769b7f10 | |
parent | dd76a3523dd7a398197be7ec93df99fb9afcdb6c (diff) |
qmicli: Added uim read record function
-rw-r--r-- | src/qmicli/qmicli-uim.c | 214 |
1 files changed, 210 insertions, 4 deletions
diff --git a/src/qmicli/qmicli-uim.c b/src/qmicli/qmicli-uim.c index 84df534..ce39e2d 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 *read_record_str; static gchar *set_pin_protection_str; static gchar *verify_pin_str; static gchar *unblock_pin_str; @@ -80,6 +81,10 @@ static GOptionEntry entries[] = { "Get the attributes of a given file", "[0xNNNN,0xNNNN,...]" }, + { "uim-read-record", 0, 0, G_OPTION_ARG_STRING, &read_record_str, + "Read a record from given file (allowed keys: record-number, record-length, file ([0xNNNN-0xNNNN,...])", + "[\"key=value,...\"]" + }, { "uim-get-card-status", 0, 0, G_OPTION_ARG_NONE, &get_card_status_flag, "Get card status", NULL @@ -136,6 +141,7 @@ qmicli_uim_options_enabled (void) !!unblock_pin_str + !!change_pin_str + !!read_transparent_str + + !!read_record_str + !!get_file_attributes_str + !!sim_power_on_str + !!sim_power_off_str + @@ -865,14 +871,15 @@ get_card_status_ready (QmiClientUim *client, } static gboolean -get_sim_file_id_and_path (const gchar *file_path_str, - guint16 *file_id, - GArray **file_path) +get_sim_file_id_and_path_with_separator (const gchar *file_path_str, + guint16 *file_id, + GArray **file_path, + const gchar *separator) { guint i; gchar **split; - split = g_strsplit (file_path_str, ",", -1); + split = g_strsplit (file_path_str, separator, -1); if (!split) { g_printerr ("error: invalid file path given: '%s'\n", file_path_str); return FALSE; @@ -914,6 +921,14 @@ get_sim_file_id_and_path (const gchar *file_path_str, return TRUE; } +static gboolean +get_sim_file_id_and_path (const gchar *file_path_str, + guint16 *file_id, + GArray **file_path) +{ + return get_sim_file_id_and_path_with_separator (file_path_str, file_id, file_path, ","); +} + static void read_transparent_ready (QmiClientUim *client, GAsyncResult *res) @@ -1013,6 +1028,175 @@ read_transparent_build_input (const gchar *file_path_str) } static void +read_record_ready (QmiClientUim *client, + GAsyncResult *res) +{ + QmiMessageUimReadRecordOutput *output; + GError *error = NULL; + guint8 sw1 = 0; + guint8 sw2 = 0; + GArray *read_result = NULL; + + output = qmi_client_uim_read_record_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_read_record_output_get_result (output, &error)) { + g_printerr ("error: couldn't read record file from the UIM: %s\n", error->message); + g_error_free (error); + + /* Card result */ + if (qmi_message_uim_read_record_output_get_card_result ( + output, + &sw1, + &sw2, + NULL)) { + g_print ("Card result:\n" + "\tSW1: '0x%02x'\n" + "\tSW2: '0x%02x'\n", + sw1, sw2); + } + + qmi_message_uim_read_record_output_unref (output); + operation_shutdown (FALSE); + return; + } + + g_print ("[%s] Successfully read information from the UIM:\n", + qmi_device_get_path_display (ctx->device)); + + /* Card result */ + if (qmi_message_uim_read_record_output_get_card_result ( + output, + &sw1, + &sw2, + NULL)) { + g_print ("Card result:\n" + "\tSW1: '0x%02x'\n" + "\tSW2: '0x%02x'\n", + sw1, sw2); + } + + /* Read result */ + if (qmi_message_uim_read_record_output_get_read_result ( + output, + &read_result, + NULL)) { + gchar *str; + + str = qmicli_get_raw_data_printable (read_result, 80, "\t"); + g_print ("Read result:\n" + "%s\n", + str); + g_free (str); + } + + qmi_message_uim_read_record_output_unref (output); + operation_shutdown (TRUE); +} + +typedef struct { + char *file; + guint16 record_number; + guint16 record_length; +} SetReadRecordProperties; + +static gboolean +set_read_record_properties_handle (const gchar *key, + const gchar *value, + GError **error, + gpointer user_data) +{ + SetReadRecordProperties *props = (SetReadRecordProperties *) user_data; + + if (!value || !value[0]) { + g_set_error (error, + QMI_CORE_ERROR, + QMI_CORE_ERROR_FAILED, + "key '%s' requires a value", + key); + return FALSE; + } + + if (g_ascii_strcasecmp (key, "file") == 0) { + props->file = strdup(value); + return TRUE; + } + + if (g_ascii_strcasecmp (key, "record-number") == 0) { + props->record_number = (guint16) atoi(value); + return TRUE; + } + + if (g_ascii_strcasecmp (key, "record-length") == 0) { + props->record_length = (guint16) atoi(value); + return TRUE; + } + + g_set_error (error, + QMI_CORE_ERROR, + QMI_CORE_ERROR_FAILED, + "Unrecognized option '%s'", + key); + return FALSE; +} + +static QmiMessageUimReadRecordInput * +read_record_input_create (const gchar *str) +{ + GError *error = NULL; + QmiMessageUimReadRecordInput *input = NULL; + SetReadRecordProperties props = { + .file = NULL, + .record_number = 0, + .record_length = 0, + }; + guint16 file_id = 0; + GArray *file_path = NULL; + + if (!qmicli_parse_key_value_string (str, + &error, + set_read_record_properties_handle, + &props)) { + g_printerr ("error: could not parse input string '%s': %s\n", + str, + error->message); + g_error_free (error); + goto out; + } + + if (!get_sim_file_id_and_path_with_separator (props.file, &file_id, &file_path, "-")) + goto out; + + input = qmi_message_uim_read_record_input_new (); + + qmi_message_uim_read_record_input_set_session_information ( + input, + QMI_UIM_SESSION_TYPE_PRIMARY_GW_PROVISIONING, + "", + NULL); + qmi_message_uim_read_record_input_set_file ( + input, + file_id, + file_path, + NULL); + qmi_message_uim_read_record_input_set_record ( + input, + props.record_number, + props.record_length, + NULL); + +out: + free (props.file); + g_array_unref (file_path); + return input; +} + +static void get_file_attributes_ready (QmiClientUim *client, GAsyncResult *res, gchar *file_name) @@ -1293,6 +1477,28 @@ qmicli_uim_run (QmiDevice *device, return; } + /* Request to read a transparent file? */ + if (read_record_str) { + QmiMessageUimReadRecordInput *input; + + input = read_record_input_create (read_record_str); + if (!input) { + operation_shutdown (FALSE); + return; + } + + g_debug ("Asynchronously reading record file at '%s'...", + read_record_str); + qmi_client_uim_read_record (ctx->client, + input, + 10, + ctx->cancellable, + (GAsyncReadyCallback)read_record_ready, + NULL); + qmi_message_uim_read_record_input_unref (input); + return; + } + /* Request to get file attributes? */ if (get_file_attributes_str) { QmiMessageUimGetFileAttributesInput *input; |