summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarlo Lobrano <carlo.lobrano@telit.com>2017-10-03 11:58:44 +0200
committerAleksander Morgado <aleksander@aleksander.es>2017-10-06 10:32:44 +0200
commit6bf1b8cb9e7fc3763c41b3f7ff388c8088a67bf2 (patch)
tree79ae5a00a4c0763905b9a785ea431d6b769b7f10
parentdd76a3523dd7a398197be7ec93df99fb9afcdb6c (diff)
qmicli: Added uim read record function
-rw-r--r--src/qmicli/qmicli-uim.c214
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;