aboutsummaryrefslogtreecommitdiff
path: root/src/mm-sim-mbim.c
diff options
context:
space:
mode:
authorAleksander Morgado <aleksandermj@chromium.org>2022-09-07 22:31:09 +0000
committerAleksander Morgado <aleksandermj@chromium.org>2022-09-12 08:41:38 +0000
commit9f5a84f777be651524115d82e5a32a0f7d00ad0a (patch)
tree8e8a4f3c503752ff0f24cee5f00e149a4e1a2d97 /src/mm-sim-mbim.c
parent6e04142a96858258223aad88638c3665d59ce35d (diff)
sim-mbim: implement loading GID1 and GID2 of active SIM
Diffstat (limited to 'src/mm-sim-mbim.c')
-rw-r--r--src/mm-sim-mbim.c176
1 files changed, 176 insertions, 0 deletions
diff --git a/src/mm-sim-mbim.c b/src/mm-sim-mbim.c
index c6d417c9..3c274394 100644
--- a/src/mm-sim-mbim.c
+++ b/src/mm-sim-mbim.c
@@ -915,6 +915,178 @@ load_operator_name (MMBaseSim *self,
}
/*****************************************************************************/
+/* Common method to read transparent files */
+
+typedef struct {
+ MbimDevice *device;
+ GByteArray *file_path;
+} CommonReadBinaryContext;
+
+static void
+common_read_binary_context_free (CommonReadBinaryContext *ctx)
+{
+ g_byte_array_unref (ctx->file_path);
+ g_object_unref (ctx->device);
+ g_slice_free (CommonReadBinaryContext, ctx);
+}
+
+static GByteArray *
+common_read_binary_finish (MMBaseSim *self,
+ GAsyncResult *res,
+ GError **error)
+{
+ return g_task_propagate_pointer (G_TASK (res), error);
+}
+
+static void
+read_binary_query_ready (MbimDevice *device,
+ GAsyncResult *res,
+ GTask *task)
+{
+ g_autoptr(MbimMessage) response = NULL;
+ GError *error = NULL;
+ const guint8 *data;
+ guint32 data_size;
+
+ response = mbim_device_command_finish (device, res, &error);
+ if (!response ||
+ !mbim_message_response_get_result (response, MBIM_MESSAGE_TYPE_COMMAND_DONE, &error) ||
+ !mbim_message_ms_uicc_low_level_access_read_binary_response_parse (
+ response,
+ NULL, /* version */
+ NULL, /* status_word_1 */
+ NULL, /* status_word_2 */
+ &data_size,
+ &data,
+ &error))
+ g_task_return_error (task, error);
+ else if (!data_size || !data)
+ g_task_return_new_error (task, MM_CORE_ERROR, MM_CORE_ERROR_FAILED,
+ "data not available");
+ else
+ g_task_return_pointer (task,
+ g_byte_array_append (g_byte_array_sized_new (data_size), data, data_size),
+ (GDestroyNotify)g_byte_array_unref);
+ g_object_unref (task);
+}
+
+static void
+read_binary_subscriber_info_ready (MMSimMbim *self,
+ GAsyncResult *res,
+ GTask *task)
+{
+ g_autoptr(MbimMessage) request = NULL;
+ CommonReadBinaryContext *ctx;
+ GError *error = NULL;
+
+ ctx = (CommonReadBinaryContext *) g_task_get_task_data (task);
+
+ if (!preload_subscriber_info_finish (self, res, &error)) {
+ g_task_return_error (task, error);
+ g_object_unref (task);
+ return;
+ }
+
+ g_assert (self->priv->preload);
+
+ if (self->priv->application_id_error) {
+ g_task_return_error (task, g_error_copy (self->priv->application_id_error));
+ g_object_unref (task);
+ return;
+ }
+
+ if (!self->priv->application_id) {
+ g_task_return_new_error (task, MM_CORE_ERROR, MM_CORE_ERROR_FAILED,
+ "UICC application id not available");
+ g_object_unref (task);
+ return;
+ }
+
+ request = mbim_message_ms_uicc_low_level_access_read_binary_query_new (MS_UICC_LOW_LEVEL_SUPPORTED_VERSION,
+ self->priv->application_id->len,
+ self->priv->application_id->data,
+ ctx->file_path->len,
+ ctx->file_path->data,
+ 0, /* read_offset */
+ 0, /* read_size */
+ NULL, /* local_pin */
+ 0, /* data_size */
+ NULL, /* data */
+ NULL);
+ mbim_device_command (ctx->device,
+ request,
+ 10,
+ NULL,
+ (GAsyncReadyCallback)read_binary_query_ready,
+ task);
+}
+
+static void
+common_read_binary (MMSimMbim *self,
+ const guint8 *file_path,
+ gsize file_path_size,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ g_autoptr(MbimMessage) request = NULL;
+ GTask *task;
+ MbimDevice *device;
+ CommonReadBinaryContext *ctx;
+
+ if (!peek_device (self, &device, callback, user_data))
+ return;
+
+ task = g_task_new (self, NULL, callback, user_data);
+ ctx = g_slice_new0 (CommonReadBinaryContext);
+ ctx->device = g_object_ref (device);
+ ctx->file_path = g_byte_array_append (g_byte_array_sized_new (file_path_size), file_path, file_path_size);
+ g_task_set_task_data (task, ctx, (GDestroyNotify) common_read_binary_context_free);
+
+ preload_subscriber_info (self,
+ (GAsyncReadyCallback) read_binary_subscriber_info_ready,
+ task);
+}
+
+/*****************************************************************************/
+/* Read GID1 and GID2 */
+
+static GByteArray *
+load_gid1_finish (MMBaseSim *self,
+ GAsyncResult *res,
+ GError **error)
+{
+ return common_read_binary_finish (self, res, error);
+}
+
+static void
+load_gid1 (MMBaseSim *self,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ const guint8 file_path[] = { 0x7F, 0xFF, 0x6F, 0x3E };
+
+ common_read_binary (MM_SIM_MBIM (self), file_path, G_N_ELEMENTS (file_path), callback, user_data);
+}
+
+static GByteArray *
+load_gid2_finish (MMBaseSim *self,
+ GAsyncResult *res,
+ GError **error)
+{
+ return common_read_binary_finish (self, res, error);
+}
+
+static void
+load_gid2 (MMBaseSim *self,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ const guint8 file_path[] = { 0x7F, 0xFF, 0x6F, 0x3F };
+
+ common_read_binary (MM_SIM_MBIM (self), file_path, G_N_ELEMENTS (file_path), callback, user_data);
+}
+
+/*****************************************************************************/
/* Send PIN */
static gboolean
@@ -1418,6 +1590,10 @@ mm_sim_mbim_class_init (MMSimMbimClass *klass)
base_sim_class->load_esim_status_finish = load_esim_status_finish;
base_sim_class->load_removability = load_removability;
base_sim_class->load_removability_finish = load_removability_finish;
+ base_sim_class->load_gid1 = load_gid1;
+ base_sim_class->load_gid1_finish = load_gid1_finish;
+ base_sim_class->load_gid2 = load_gid2;
+ base_sim_class->load_gid2_finish = load_gid2_finish;
base_sim_class->send_pin = send_pin;
base_sim_class->send_pin_finish = send_pin_finish;
base_sim_class->send_puk = send_puk;