diff options
author | Aleksander Morgado <aleksander@aleksander.es> | 2016-01-30 20:14:24 -0800 |
---|---|---|
committer | Aleksander Morgado <aleksander@aleksander.es> | 2016-02-11 10:51:53 +0100 |
commit | 9cbd0c61b0562b2f2370d5c192d06fe8694bb021 (patch) | |
tree | 983dfafcd73a76aea85ca0df6a7b10673a06b80f /src/mm-sim-qmi.c | |
parent | 7ded4f3c3be0a437d39777f38dfd58df4b570c07 (diff) |
sim-qmi: implement SIM verify/unblock/change/enable with UIM service
Newer modems like the MC7455 don't implement the "DMS UIM" commands in the
DMS service, and therefore these modems need to use the UIM service directly.
We include a new flag to detect whether any of the DMS UIM commands is flagged
as invalid, and if so, we'll fallback to the UIM specific implementations for
all.
libqmi version bump to 1.13.7, which includes the new required methods.
Diffstat (limited to 'src/mm-sim-qmi.c')
-rw-r--r-- | src/mm-sim-qmi.c | 552 |
1 files changed, 497 insertions, 55 deletions
diff --git a/src/mm-sim-qmi.c b/src/mm-sim-qmi.c index 6254cd3d..ea9f2a77 100644 --- a/src/mm-sim-qmi.c +++ b/src/mm-sim-qmi.c @@ -11,6 +11,7 @@ * GNU General Public License for more details: * * Copyright (C) 2012 Google, Inc. + * Copyright (C) 2016 Aleksander Morgado <aleksander@aleksander.es> */ #include <config.h> @@ -29,6 +30,10 @@ G_DEFINE_TYPE (MMSimQmi, mm_sim_qmi, MM_TYPE_BASE_SIM) +struct _MMSimQmiPrivate { + gboolean dms_uim_deprecated; +}; + /*****************************************************************************/ static gboolean @@ -50,9 +55,11 @@ ensure_qmi_client (GTask *task, g_object_unref (modem); if (!port) { - g_task_return_new_error (task, MM_CORE_ERROR, MM_CORE_ERROR_FAILED, - "Couldn't peek QMI port"); - g_object_unref (task); + if (task) { + g_task_return_new_error (task, MM_CORE_ERROR, MM_CORE_ERROR_FAILED, + "Couldn't peek QMI port"); + g_object_unref (task); + } return FALSE; } @@ -60,10 +67,12 @@ ensure_qmi_client (GTask *task, service, MM_PORT_QMI_FLAG_DEFAULT); if (!client) { - g_task_return_new_error (task, MM_CORE_ERROR, MM_CORE_ERROR_FAILED, - "Couldn't peek client for service '%s'", - qmi_service_get_string (service)); - g_object_unref (task); + if (task) { + g_task_return_new_error (task, MM_CORE_ERROR, MM_CORE_ERROR_FAILED, + "Couldn't peek client for service '%s'", + qmi_service_get_string (service)); + g_object_unref (task); + } return FALSE; } @@ -402,18 +411,87 @@ send_pin_finish (MMBaseSim *self, } static void +uim_verify_pin_ready (QmiClientUim *client, + GAsyncResult *res, + GTask *task) +{ + QmiMessageUimVerifyPinOutput *output = NULL; + GError *error = NULL; + + output = qmi_client_uim_verify_pin_finish (client, res, &error); + if (!output) { + g_prefix_error (&error, "QMI operation failed: "); + g_task_return_error (task, error); + } else if (!qmi_message_uim_verify_pin_output_get_result (output, &error)) { + g_prefix_error (&error, "Couldn't verify PIN: "); + g_task_return_error (task, pin_qmi_error_to_mobile_equipment_error (error)); + } else + g_task_return_boolean (task, TRUE); + + if (output) + qmi_message_uim_verify_pin_output_unref (output); + g_object_unref (task); +} + +static void +uim_verify_pin (MMSimQmi *self, + GTask *task) +{ + QmiMessageUimVerifyPinInput *input; + QmiClient *client = NULL; + + if (!ensure_qmi_client (task, + MM_SIM_QMI (self), + QMI_SERVICE_UIM, &client)) + return; + + input = qmi_message_uim_verify_pin_input_new (); + qmi_message_uim_verify_pin_input_set_info ( + input, + QMI_UIM_PIN_ID_PIN1, + g_task_get_task_data (task), + NULL); + qmi_message_uim_verify_pin_input_set_session_information ( + input, + QMI_UIM_SESSION_TYPE_CARD_SLOT_1, + "", /* ignored */ + NULL); + qmi_client_uim_verify_pin (QMI_CLIENT_UIM (client), + input, + 5, + NULL, + (GAsyncReadyCallback) uim_verify_pin_ready, + task); + qmi_message_uim_verify_pin_input_unref (input); +} + +static void dms_uim_verify_pin_ready (QmiClientDms *client, GAsyncResult *res, GTask *task) { QmiMessageDmsUimVerifyPinOutput *output = NULL; GError *error = NULL; + MMSimQmi *self; + + self = g_task_get_source_object (task); output = qmi_client_dms_uim_verify_pin_finish (client, res, &error); if (!output) { g_prefix_error (&error, "QMI operation failed: "); g_task_return_error (task, error); } else if (!qmi_message_dms_uim_verify_pin_output_get_result (output, &error)) { + /* DMS UIM deprecated? */ + if (g_error_matches (error, + QMI_PROTOCOL_ERROR, + QMI_PROTOCOL_ERROR_INVALID_QMI_COMMAND)) { + g_error_free (error); + qmi_message_dms_uim_verify_pin_output_unref (output); + /* Flag as deprecated and try with UIM */ + self->priv->dms_uim_deprecated = TRUE; + uim_verify_pin (self, task); + return; + } g_prefix_error (&error, "Couldn't verify PIN: "); g_task_return_error (task, pin_qmi_error_to_mobile_equipment_error (error)); } else @@ -425,40 +503,74 @@ dms_uim_verify_pin_ready (QmiClientDms *client, } static void -send_pin (MMBaseSim *self, - const gchar *pin, - GAsyncReadyCallback callback, - gpointer user_data) +dms_uim_verify_pin (MMSimQmi *self, + GTask *task) { - GTask *task; QmiMessageDmsUimVerifyPinInput *input; QmiClient *client = NULL; - task = g_task_new (self, NULL, callback, user_data); - if (!ensure_qmi_client (task, + if (!ensure_qmi_client (NULL, MM_SIM_QMI (self), - QMI_SERVICE_DMS, &client)) + QMI_SERVICE_DMS, &client)) { + /* Very unlikely that this will ever happen, but anyway, try with + * UIM service instead */ + uim_verify_pin (self, task); return; + } mm_dbg ("Sending PIN..."); input = qmi_message_dms_uim_verify_pin_input_new (); qmi_message_dms_uim_verify_pin_input_set_info ( input, QMI_DMS_UIM_PIN_ID_PIN, - pin, + g_task_get_task_data (task), NULL); qmi_client_dms_uim_verify_pin (QMI_CLIENT_DMS (client), input, 5, NULL, - (GAsyncReadyCallback)dms_uim_verify_pin_ready, + (GAsyncReadyCallback) dms_uim_verify_pin_ready, task); qmi_message_dms_uim_verify_pin_input_unref (input); } +static void +send_pin (MMBaseSim *_self, + const gchar *pin, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GTask *task; + MMSimQmi *self; + + self = MM_SIM_QMI (_self); + task = g_task_new (self, NULL, callback, user_data); + + g_task_set_task_data (task, g_strdup (pin), (GDestroyNotify) g_free); + + mm_dbg ("Verifying PIN..."); + if (!self->priv->dms_uim_deprecated) + dms_uim_verify_pin (self, task); + else + uim_verify_pin (self, task); +} + /*****************************************************************************/ /* Send PUK */ +typedef struct { + gchar *puk; + gchar *new_pin; +} UnblockPinContext; + +static void +unblock_pin_context_free (UnblockPinContext *ctx) +{ + g_free (ctx->puk); + g_free (ctx->new_pin); + g_slice_free (UnblockPinContext, ctx); +} + static gboolean send_puk_finish (MMBaseSim *self, GAsyncResult *res, @@ -468,18 +580,91 @@ send_puk_finish (MMBaseSim *self, } static void +uim_unblock_pin_ready (QmiClientUim *client, + GAsyncResult *res, + GTask *task) +{ + QmiMessageUimUnblockPinOutput *output = NULL; + GError *error = NULL; + + output = qmi_client_uim_unblock_pin_finish (client, res, &error); + if (!output) { + g_prefix_error (&error, "QMI operation failed: "); + g_task_return_error (task, error); + } else if (!qmi_message_uim_unblock_pin_output_get_result (output, &error)) { + g_prefix_error (&error, "Couldn't unblock PIN: "); + g_task_return_error (task, pin_qmi_error_to_mobile_equipment_error (error)); + } else + g_task_return_boolean (task, TRUE); + + if (output) + qmi_message_uim_unblock_pin_output_unref (output); + g_object_unref (task); +} + +static void +uim_unblock_pin (MMSimQmi *self, + GTask *task) +{ + QmiMessageUimUnblockPinInput *input; + QmiClient *client = NULL; + UnblockPinContext *ctx; + + if (!ensure_qmi_client (task, + MM_SIM_QMI (self), + QMI_SERVICE_UIM, &client)) + return; + + ctx = g_task_get_task_data (task); + + input = qmi_message_uim_unblock_pin_input_new (); + qmi_message_uim_unblock_pin_input_set_info ( + input, + QMI_UIM_PIN_ID_PIN1, + ctx->puk, + ctx->new_pin, + NULL); + qmi_message_uim_unblock_pin_input_set_session_information ( + input, + QMI_UIM_SESSION_TYPE_CARD_SLOT_1, + "", /* ignored */ + NULL); + qmi_client_uim_unblock_pin (QMI_CLIENT_UIM (client), + input, + 5, + NULL, + (GAsyncReadyCallback) uim_unblock_pin_ready, + task); + qmi_message_uim_unblock_pin_input_unref (input); +} + +static void dms_uim_unblock_pin_ready (QmiClientDms *client, GAsyncResult *res, GTask *task) { QmiMessageDmsUimUnblockPinOutput *output = NULL; GError *error = NULL; + MMSimQmi *self; + + self = g_task_get_source_object (task); output = qmi_client_dms_uim_unblock_pin_finish (client, res, &error); if (!output) { g_prefix_error (&error, "QMI operation failed: "); g_task_return_error (task, error); } else if (!qmi_message_dms_uim_unblock_pin_output_get_result (output, &error)) { + /* DMS UIM deprecated? */ + if (g_error_matches (error, + QMI_PROTOCOL_ERROR, + QMI_PROTOCOL_ERROR_INVALID_QMI_COMMAND)) { + g_error_free (error); + qmi_message_dms_uim_unblock_pin_output_unref (output); + /* Flag as deprecated and try with UIM */ + self->priv->dms_uim_deprecated = TRUE; + uim_unblock_pin (self, task); + return; + } g_prefix_error (&error, "Couldn't unblock PIN: "); g_task_return_error (task, pin_qmi_error_to_mobile_equipment_error (error)); } else @@ -491,29 +676,30 @@ dms_uim_unblock_pin_ready (QmiClientDms *client, } static void -send_puk (MMBaseSim *self, - const gchar *puk, - const gchar *new_pin, - GAsyncReadyCallback callback, - gpointer user_data) +dms_uim_unblock_pin (MMSimQmi *self, + GTask *task) { - GTask *task; QmiMessageDmsUimUnblockPinInput *input; QmiClient *client = NULL; + UnblockPinContext *ctx; - task = g_task_new (self, NULL, callback, user_data); - if (!ensure_qmi_client (task, + if (!ensure_qmi_client (NULL, MM_SIM_QMI (self), - QMI_SERVICE_DMS, &client)) + QMI_SERVICE_DMS, &client)) { + /* Very unlikely that this will ever happen, but anyway, try with + * UIM service instead */ + uim_unblock_pin (self, task); return; + } + + ctx = g_task_get_task_data (task); - mm_dbg ("Sending PUK..."); input = qmi_message_dms_uim_unblock_pin_input_new (); qmi_message_dms_uim_unblock_pin_input_set_info ( input, QMI_DMS_UIM_PIN_ID_PIN, - puk, - new_pin, + ctx->puk, + ctx->new_pin, NULL); qmi_client_dms_uim_unblock_pin (QMI_CLIENT_DMS (client), input, @@ -524,9 +710,48 @@ send_puk (MMBaseSim *self, qmi_message_dms_uim_unblock_pin_input_unref (input); } +static void +send_puk (MMBaseSim *_self, + const gchar *puk, + const gchar *new_pin, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GTask *task; + UnblockPinContext *ctx; + MMSimQmi *self; + + self = MM_SIM_QMI (_self); + task = g_task_new (self, NULL, callback, user_data); + + ctx = g_slice_new (UnblockPinContext); + ctx->puk = g_strdup (puk); + ctx->new_pin = g_strdup (new_pin); + g_task_set_task_data (task, ctx, (GDestroyNotify) unblock_pin_context_free); + + mm_dbg ("Unblocking PIN..."); + if (!self->priv->dms_uim_deprecated) + dms_uim_unblock_pin (self, task); + else + uim_unblock_pin (self, task); +} + /*****************************************************************************/ /* Change PIN */ +typedef struct { + gchar *old_pin; + gchar *new_pin; +} ChangePinContext; + +static void +change_pin_context_free (ChangePinContext *ctx) +{ + g_free (ctx->old_pin); + g_free (ctx->new_pin); + g_slice_free (ChangePinContext, ctx); +} + static gboolean change_pin_finish (MMBaseSim *self, GAsyncResult *res, @@ -536,18 +761,91 @@ change_pin_finish (MMBaseSim *self, } static void +uim_change_pin_ready (QmiClientUim *client, + GAsyncResult *res, + GTask *task) +{ + QmiMessageUimChangePinOutput *output = NULL; + GError *error = NULL; + + output = qmi_client_uim_change_pin_finish (client, res, &error); + if (!output) { + g_prefix_error (&error, "QMI operation failed: "); + g_task_return_error (task, error); + } else if (!qmi_message_uim_change_pin_output_get_result (output, &error)) { + g_prefix_error (&error, "Couldn't change PIN: "); + g_task_return_error (task, pin_qmi_error_to_mobile_equipment_error (error)); + } else + g_task_return_boolean (task, TRUE); + + if (output) + qmi_message_uim_change_pin_output_unref (output); + g_object_unref (task); +} + +static void +uim_change_pin (MMSimQmi *self, + GTask *task) +{ + QmiMessageUimChangePinInput *input; + QmiClient *client = NULL; + ChangePinContext *ctx; + + if (!ensure_qmi_client (task, + MM_SIM_QMI (self), + QMI_SERVICE_UIM, &client)) + return; + + ctx = g_task_get_task_data (task); + + input = qmi_message_uim_change_pin_input_new (); + qmi_message_uim_change_pin_input_set_info ( + input, + QMI_UIM_PIN_ID_PIN1, + ctx->old_pin, + ctx->new_pin, + NULL); + qmi_message_uim_change_pin_input_set_session_information ( + input, + QMI_UIM_SESSION_TYPE_CARD_SLOT_1, + "", /* ignored */ + NULL); + qmi_client_uim_change_pin (QMI_CLIENT_UIM (client), + input, + 5, + NULL, + (GAsyncReadyCallback) uim_change_pin_ready, + task); + qmi_message_uim_change_pin_input_unref (input); +} + +static void dms_uim_change_pin_ready (QmiClientDms *client, GAsyncResult *res, GTask *task) { QmiMessageDmsUimChangePinOutput *output = NULL; GError *error = NULL; + MMSimQmi *self; + + self = g_task_get_source_object (task); output = qmi_client_dms_uim_change_pin_finish (client, res, &error); if (!output) { g_prefix_error (&error, "QMI operation failed: "); g_task_return_error (task, error); } else if (!qmi_message_dms_uim_change_pin_output_get_result (output, &error)) { + /* DMS UIM deprecated? */ + if (g_error_matches (error, + QMI_PROTOCOL_ERROR, + QMI_PROTOCOL_ERROR_INVALID_QMI_COMMAND)) { + g_error_free (error); + qmi_message_dms_uim_change_pin_output_unref (output); + /* Flag as deprecated and try with UIM */ + self->priv->dms_uim_deprecated = TRUE; + uim_change_pin (self, task); + return; + } g_prefix_error (&error, "Couldn't change PIN: "); g_task_return_error (task, pin_qmi_error_to_mobile_equipment_error (error)); } else @@ -559,42 +857,81 @@ dms_uim_change_pin_ready (QmiClientDms *client, } static void -change_pin (MMBaseSim *self, - const gchar *old_pin, - const gchar *new_pin, - GAsyncReadyCallback callback, - gpointer user_data) +dms_uim_change_pin (MMSimQmi *self, + GTask *task) { - GTask *task; QmiMessageDmsUimChangePinInput *input; QmiClient *client = NULL; + ChangePinContext *ctx; - task = g_task_new (self, NULL, callback, user_data); - if (!ensure_qmi_client (task, + if (!ensure_qmi_client (NULL, MM_SIM_QMI (self), - QMI_SERVICE_DMS, &client)) + QMI_SERVICE_DMS, &client)) { + /* Very unlikely that this will ever happen, but anyway, try with + * UIM service instead */ + uim_change_pin (self, task); return; + } + + ctx = g_task_get_task_data (task); - mm_dbg ("Changing PIN..."); input = qmi_message_dms_uim_change_pin_input_new (); qmi_message_dms_uim_change_pin_input_set_info ( input, QMI_DMS_UIM_PIN_ID_PIN, - old_pin, - new_pin, + ctx->old_pin, + ctx->new_pin, NULL); qmi_client_dms_uim_change_pin (QMI_CLIENT_DMS (client), input, 5, NULL, - (GAsyncReadyCallback)dms_uim_change_pin_ready, + (GAsyncReadyCallback) dms_uim_change_pin_ready, task); qmi_message_dms_uim_change_pin_input_unref (input); } +static void +change_pin (MMBaseSim *_self, + const gchar *old_pin, + const gchar *new_pin, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GTask *task; + ChangePinContext *ctx; + MMSimQmi *self; + + self = MM_SIM_QMI (_self); + task = g_task_new (self, NULL, callback, user_data); + + ctx = g_slice_new (ChangePinContext); + ctx->old_pin = g_strdup (old_pin); + ctx->new_pin = g_strdup (new_pin); + g_task_set_task_data (task, ctx, (GDestroyNotify) change_pin_context_free); + + mm_dbg ("Changing PIN..."); + if (!self->priv->dms_uim_deprecated) + dms_uim_change_pin (self, task); + else + uim_change_pin (self, task); +} + /*****************************************************************************/ /* Enable PIN */ +typedef struct { + gchar *pin; + gboolean enabled; +} EnablePinContext; + +static void +enable_pin_context_free (EnablePinContext *ctx) +{ + g_free (ctx->pin); + g_slice_free (EnablePinContext, ctx); +} + static gboolean enable_pin_finish (MMBaseSim *self, GAsyncResult *res, @@ -604,18 +941,91 @@ enable_pin_finish (MMBaseSim *self, } static void +uim_set_pin_protection_ready (QmiClientUim *client, + GAsyncResult *res, + GTask *task) +{ + QmiMessageUimSetPinProtectionOutput *output = NULL; + GError *error = NULL; + + output = qmi_client_uim_set_pin_protection_finish (client, res, &error); + if (!output) { + g_prefix_error (&error, "QMI operation failed: "); + g_task_return_error (task, error); + } else if (!qmi_message_uim_set_pin_protection_output_get_result (output, &error)) { + g_prefix_error (&error, "Couldn't enable PIN: "); + g_task_return_error (task, pin_qmi_error_to_mobile_equipment_error (error)); + } else + g_task_return_boolean (task, TRUE); + + if (output) + qmi_message_uim_set_pin_protection_output_unref (output); + g_object_unref (task); +} + +static void +uim_enable_pin (MMSimQmi *self, + GTask *task) +{ + QmiMessageUimSetPinProtectionInput *input; + QmiClient *client = NULL; + EnablePinContext *ctx; + + if (!ensure_qmi_client (task, + MM_SIM_QMI (self), + QMI_SERVICE_UIM, &client)) + return; + + ctx = g_task_get_task_data (task); + + input = qmi_message_uim_set_pin_protection_input_new (); + qmi_message_uim_set_pin_protection_input_set_info ( + input, + QMI_UIM_PIN_ID_PIN1, + ctx->enabled, + ctx->pin, + NULL); + qmi_message_uim_set_pin_protection_input_set_session_information ( + input, + QMI_UIM_SESSION_TYPE_CARD_SLOT_1, + "", /* ignored */ + NULL); + qmi_client_uim_set_pin_protection (QMI_CLIENT_UIM (client), + input, + 5, + NULL, + (GAsyncReadyCallback)uim_set_pin_protection_ready, + task); + qmi_message_uim_set_pin_protection_input_unref (input); +} + +static void dms_uim_set_pin_protection_ready (QmiClientDms *client, GAsyncResult *res, GTask *task) { QmiMessageDmsUimSetPinProtectionOutput *output = NULL; GError *error = NULL; + MMSimQmi *self; + + self = g_task_get_source_object (task); output = qmi_client_dms_uim_set_pin_protection_finish (client, res, &error); if (!output) { g_prefix_error (&error, "QMI operation failed: "); g_task_return_error (task, error); } else if (!qmi_message_dms_uim_set_pin_protection_output_get_result (output, &error)) { + /* DMS UIM deprecated? */ + if (g_error_matches (error, + QMI_PROTOCOL_ERROR, + QMI_PROTOCOL_ERROR_INVALID_QMI_COMMAND)) { + g_error_free (error); + qmi_message_dms_uim_set_pin_protection_output_unref (output); + /* Flag as deprecated and try with UIM */ + self->priv->dms_uim_deprecated = TRUE; + uim_enable_pin (self, task); + return; + } g_prefix_error (&error, "Couldn't enable PIN: "); g_task_return_error (task, pin_qmi_error_to_mobile_equipment_error (error)); } else @@ -627,31 +1037,30 @@ dms_uim_set_pin_protection_ready (QmiClientDms *client, } static void -enable_pin (MMBaseSim *self, - const gchar *pin, - gboolean enabled, - GAsyncReadyCallback callback, - gpointer user_data) +dms_uim_enable_pin (MMSimQmi *self, + GTask *task) { - GTask *task; QmiMessageDmsUimSetPinProtectionInput *input; QmiClient *client = NULL; + EnablePinContext *ctx; - task = g_task_new (self, NULL, callback, user_data); - if (!ensure_qmi_client (task, + if (!ensure_qmi_client (NULL, MM_SIM_QMI (self), - QMI_SERVICE_DMS, &client)) + QMI_SERVICE_DMS, &client)) { + /* Very unlikely that this will ever happen, but anyway, try with + * UIM service instead */ + uim_enable_pin (self, task); return; + } - mm_dbg ("%s PIN...", - enabled ? "Enabling" : "Disabling"); + ctx = g_task_get_task_data (task); input = qmi_message_dms_uim_set_pin_protection_input_new (); qmi_message_dms_uim_set_pin_protection_input_set_info ( input, QMI_DMS_UIM_PIN_ID_PIN, - enabled, - pin, + ctx->enabled, + ctx->pin, NULL); qmi_client_dms_uim_set_pin_protection (QMI_CLIENT_DMS (client), input, @@ -662,6 +1071,32 @@ enable_pin (MMBaseSim *self, qmi_message_dms_uim_set_pin_protection_input_unref (input); } +static void +enable_pin (MMBaseSim *_self, + const gchar *pin, + gboolean enabled, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GTask *task; + EnablePinContext *ctx; + MMSimQmi *self; + + self = MM_SIM_QMI (_self); + task = g_task_new (self, NULL, callback, user_data); + + ctx = g_slice_new (EnablePinContext); + ctx->pin = g_strdup (pin); + ctx->enabled = enabled; + g_task_set_task_data (task, ctx, (GDestroyNotify) enable_pin_context_free); + + mm_dbg ("%s PIN...", enabled ? "Enabling" : "Disabling"); + if (!self->priv->dms_uim_deprecated) + dms_uim_enable_pin (self, task); + else + uim_enable_pin (self, task); +} + /*****************************************************************************/ MMBaseSim * @@ -702,13 +1137,20 @@ mm_sim_qmi_new (MMBaseModem *modem, static void mm_sim_qmi_init (MMSimQmi *self) { + /* Initialize private data */ + self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, + MM_TYPE_SIM_QMI, + MMSimQmiPrivate); } static void mm_sim_qmi_class_init (MMSimQmiClass *klass) { + GObjectClass *object_class = G_OBJECT_CLASS (klass); MMBaseSimClass *base_sim_class = MM_BASE_SIM_CLASS (klass); + g_type_class_add_private (object_class, sizeof (MMSimQmiPrivate)); + base_sim_class->load_sim_identifier = load_sim_identifier; base_sim_class->load_sim_identifier_finish = load_sim_identifier_finish; base_sim_class->load_imsi = load_imsi; |