aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/mm-sim-mbim.c289
1 files changed, 167 insertions, 122 deletions
diff --git a/src/mm-sim-mbim.c b/src/mm-sim-mbim.c
index 348a6017..6655ff13 100644
--- a/src/mm-sim-mbim.c
+++ b/src/mm-sim-mbim.c
@@ -823,128 +823,6 @@ load_eid (MMBaseSim *self,
}
/*****************************************************************************/
-/* Load operator identifier */
-
-static gchar *
-load_operator_identifier_finish (MMBaseSim *self,
- GAsyncResult *res,
- GError **error)
-{
- return g_task_propagate_pointer (G_TASK (res), error);
-}
-
-static void
-load_operator_identifier_ready (MbimDevice *device,
- GAsyncResult *res,
- GTask *task)
-{
- MbimMessage *response;
- GError *error = NULL;
- MbimProvider *provider;
-
- response = mbim_device_command_finish (device, res, &error);
- if (response &&
- mbim_message_response_get_result (response, MBIM_MESSAGE_TYPE_COMMAND_DONE, &error) &&
- mbim_message_home_provider_response_parse (
- response,
- &provider,
- &error)) {
- g_task_return_pointer (task, g_strdup (provider->provider_id), g_free);
- mbim_provider_free (provider);
- } else
- g_task_return_error (task, error);
- g_object_unref (task);
-
- if (response)
- mbim_message_unref (response);
-}
-
-static void
-load_operator_identifier (MMBaseSim *self,
- GAsyncReadyCallback callback,
- gpointer user_data)
-{
- MbimDevice *device;
- MbimMessage *message;
- GTask *task;
-
- if (!peek_device (self, &device, callback, user_data))
- return;
-
- task = g_task_new (self, NULL, callback, user_data);
-
- message = mbim_message_home_provider_query_new (NULL);
- mbim_device_command (device,
- message,
- 30,
- NULL,
- (GAsyncReadyCallback)load_operator_identifier_ready,
- task);
- mbim_message_unref (message);
-}
-
-/*****************************************************************************/
-/* Load operator name */
-
-static gchar *
-load_operator_name_finish (MMBaseSim *self,
- GAsyncResult *res,
- GError **error)
-{
- return g_task_propagate_pointer (G_TASK (res), error);
-}
-
-static void
-load_operator_name_ready (MbimDevice *device,
- GAsyncResult *res,
- GTask *task)
-{
- MbimMessage *response;
- GError *error = NULL;
- MbimProvider *provider;
-
- response = mbim_device_command_finish (device, res, &error);
- if (response &&
- mbim_message_response_get_result (response, MBIM_MESSAGE_TYPE_COMMAND_DONE, &error) &&
- mbim_message_home_provider_response_parse (
- response,
- &provider,
- &error)) {
- g_task_return_pointer (task, g_strdup (provider->provider_name), g_free);
- mbim_provider_free (provider);
- } else
- g_task_return_error (task, error);
- g_object_unref (task);
-
- if (response)
- mbim_message_unref (response);
-}
-
-static void
-load_operator_name (MMBaseSim *self,
- GAsyncReadyCallback callback,
- gpointer user_data)
-{
- MbimDevice *device;
- MbimMessage *message;
- GTask *task;
-
- if (!peek_device (self, &device, callback, user_data))
- return;
-
- task = g_task_new (self, NULL, callback, user_data);
-
- message = mbim_message_home_provider_query_new (NULL);
- mbim_device_command (device,
- message,
- 30,
- NULL,
- (GAsyncReadyCallback)load_operator_name_ready,
- task);
- mbim_message_unref (message);
-}
-
-/*****************************************************************************/
/* Common method to read transparent files */
typedef struct {
@@ -1150,6 +1028,173 @@ common_read_binary (MMSimMbim *self,
}
/*****************************************************************************/
+/* Load operator identifier */
+
+static gchar *
+load_operator_identifier_finish (MMBaseSim *self,
+ GAsyncResult *res,
+ GError **error)
+{
+ return g_task_propagate_pointer (G_TASK (res), error);
+}
+
+static void
+parent_load_operator_id_ready (MMBaseSim *self,
+ GAsyncResult *res,
+ GTask *task)
+{
+ g_autoptr(GError) error = NULL;
+ gchar *value;
+
+ value = MM_BASE_SIM_CLASS (mm_sim_mbim_parent_class)->load_operator_identifier_finish (self, res, &error);
+ if (value) {
+ g_task_return_pointer (task, value, g_free);
+ } else {
+ mm_obj_dbg (self, "failed reading operator ID using AT: %s", error->message);
+ g_task_return_new_error (task, MM_CORE_ERROR, MM_CORE_ERROR_FAILED,
+ "Failed reading operator ID from SIM card");
+ }
+
+ g_object_unref (task);
+}
+
+static void
+common_read_binary_operator_id_ready (MMSimMbim *self,
+ GAsyncResult *res,
+ GTask *task)
+{
+ g_autoptr(GError) error = NULL;
+ GByteArray *value;
+
+ value = common_read_binary_finish (self, res, &error);
+ if (!value) {
+ mm_obj_dbg (self, "failed reading operator ID using MBIM: %s", error->message);
+ } else if (value->len != 4) {
+ mm_obj_dbg (self, "failed reading operator ID using MBIM: unexpected field size");
+ } else {
+ guint mnc_len = value->data[3];
+
+ if (mnc_len == 2 || mnc_len == 3) {
+ g_task_return_pointer (task, g_strndup (self->priv->imsi, 3 + mnc_len), g_free);
+ g_object_unref (task);
+ return;
+ }
+ mm_obj_dbg (self, "failed reading operator ID using MBIM: unexpected MNC length: %u", mnc_len);
+ }
+
+ /* Fallback to parent implementation if possible */
+ MM_BASE_SIM_CLASS (mm_sim_mbim_parent_class)->load_operator_identifier (MM_BASE_SIM (self),
+ (GAsyncReadyCallback)parent_load_operator_id_ready,
+ task);
+}
+
+static void
+load_operator_identifier (MMBaseSim *self,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GTask *task;
+ const guint8 file_path[] = { 0x7F, 0xFF, 0x6F, 0xAD };
+
+ task = g_task_new (self, NULL, callback, user_data);
+
+ common_read_binary (MM_SIM_MBIM (self),
+ file_path,
+ G_N_ELEMENTS (file_path),
+ (GAsyncReadyCallback)common_read_binary_operator_id_ready,
+ task);
+}
+
+/*****************************************************************************/
+/* Load operator name */
+
+static gchar *
+load_operator_name_finish (MMBaseSim *self,
+ GAsyncResult *res,
+ GError **error)
+{
+ return g_task_propagate_pointer (G_TASK (res), error);
+}
+
+static void
+parent_load_operator_name_ready (MMBaseSim *self,
+ GAsyncResult *res,
+ GTask *task)
+{
+ g_autoptr(GError) error = NULL;
+ gchar *value;
+
+ value = MM_BASE_SIM_CLASS (mm_sim_mbim_parent_class)->load_operator_name_finish (self, res, &error);
+ if (value) {
+ g_task_return_pointer (task, value, g_free);
+ } else {
+ mm_obj_dbg (self, "failed reading operator name using AT: %s", error->message);
+ g_task_return_new_error (task, MM_CORE_ERROR, MM_CORE_ERROR_FAILED,
+ "Failed reading operator name from SIM card");
+ }
+
+ g_object_unref (task);
+}
+
+static void
+common_read_binary_operator_name_ready (MMSimMbim *self,
+ GAsyncResult *res,
+ GTask *task)
+{
+ g_autoptr(GError) error = NULL;
+ GByteArray *value;
+
+ value = common_read_binary_finish (self, res, &error);
+ if (!value) {
+ mm_obj_dbg (self, "failed reading operator name using MBIM: %s", error->message);
+ } else {
+ gsize len = value->len;
+
+ while (len > 1 && value->data[len - 1] == 0xff)
+ len--;
+ if (len <= 1) {
+ mm_obj_dbg (self, "failed reading operator name using MBIM: value is empty");
+ } else {
+ g_autoptr(GByteArray) array = NULL;
+ gchar *name;
+
+ /* Remove the first metadata byte and convert remainder to UTF8 string */
+ array = g_byte_array_sized_new (len - 1);
+ g_byte_array_append (array, value->data + 1, len - 1);
+ name = mm_modem_charset_bytearray_to_utf8 (array, MM_MODEM_CHARSET_GSM, FALSE, &error);
+ if (name) {
+ g_task_return_pointer (task, name, g_free);
+ g_object_unref (task);
+ return;
+ }
+ mm_obj_dbg (self, "failed reading operator name using MBIM: %s", error->message);
+ }
+ }
+
+ /* Fallback to parent implementation if possible */
+ MM_BASE_SIM_CLASS (mm_sim_mbim_parent_class)->load_operator_name (MM_BASE_SIM (self),
+ (GAsyncReadyCallback)parent_load_operator_name_ready,
+ task);
+}
+
+static void
+load_operator_name (MMBaseSim *self,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GTask *task;
+ const guint8 file_path[] = { 0x7F, 0xFF, 0x6F, 0x46 };
+
+ task = g_task_new (self, NULL, callback, user_data);
+
+ common_read_binary (MM_SIM_MBIM (self),
+ file_path,
+ G_N_ELEMENTS (file_path),
+ (GAsyncReadyCallback)common_read_binary_operator_name_ready,
+ task);
+}
+
+/*****************************************************************************/
/* Read GID1 */
static GByteArray *