diff options
author | Aleksander Morgado <aleksander@lanedo.com> | 2013-04-07 21:02:31 +0200 |
---|---|---|
committer | Aleksander Morgado <aleksander@lanedo.com> | 2013-04-17 15:19:39 +0200 |
commit | deb9f21a6653c3ab68470395919aa21edc2d8034 (patch) | |
tree | 917a823e1789fa351860a59ee9f9624020a79e77 | |
parent | affe2fdeeb938285c697c6c97fd5ae90691d8c1e (diff) |
broadband-modem-mbim: implement unlock required & retries loading
-rw-r--r-- | src/Makefile.am | 8 | ||||
-rw-r--r-- | src/mm-broadband-modem-mbim.c | 142 | ||||
-rw-r--r-- | src/mm-modem-helpers-mbim.c | 63 | ||||
-rw-r--r-- | src/mm-modem-helpers-mbim.h | 29 |
4 files changed, 242 insertions, 0 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index 0856aa05..703410c5 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -40,6 +40,14 @@ libmodem_helpers_la_SOURCES += \ libmodem_helpers_la_CPPFLAGS += $(QMI_CFLAGS) endif +# Additional MBIM support in libmodem-helpers +if WITH_MBIM +libmodem_helpers_la_SOURCES += \ + mm-modem-helpers-mbim.c \ + mm-modem-helpers-mbim.h +libmodem_helpers_la_CPPFLAGS += $(MBIM_CFLAGS) +endif + # libserial specific enum types SERIAL_ENUMS = \ $(srcdir)/mm-port.h \ diff --git a/src/mm-broadband-modem-mbim.c b/src/mm-broadband-modem-mbim.c index f3af5596..5fe1ef67 100644 --- a/src/mm-broadband-modem-mbim.c +++ b/src/mm-broadband-modem-mbim.c @@ -21,6 +21,7 @@ #include <unistd.h> #include <ctype.h> +#include "mm-modem-helpers-mbim.h" #include "mm-broadband-modem-mbim.h" #include "mm-bearer-mbim.h" #include "mm-sim-mbim.h" @@ -44,6 +45,10 @@ struct _MMBroadbandModemMbimPrivate { guint caps_max_sessions; gchar *caps_device_id; gchar *caps_firmware_info; + + /* Queried and cached lock info */ + MMModemLock current_lock; + guint current_lock_retries; }; /*****************************************************************************/ @@ -325,6 +330,137 @@ modem_load_supported_modes (MMIfaceModem *self, } /*****************************************************************************/ +/* Unlock required loading (Modem interface) */ + +typedef struct { + MMBroadbandModemMbim *self; + GSimpleAsyncResult *result; +} LoadUnlockRequiredContext; + +static void +load_unlock_required_context_complete_and_free (LoadUnlockRequiredContext *ctx) +{ + g_simple_async_result_complete (ctx->result); + g_object_unref (ctx->result); + g_object_unref (ctx->self); + g_slice_free (LoadUnlockRequiredContext, ctx); +} + +static MMModemLock +modem_load_unlock_required_finish (MMIfaceModem *self, + GAsyncResult *res, + GError **error) +{ + if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error)) + return MM_MODEM_LOCK_UNKNOWN; + + return (MMModemLock) GPOINTER_TO_UINT (g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (res))); +} + +static void +pin_query_ready (MbimDevice *device, + GAsyncResult *res, + LoadUnlockRequiredContext *ctx) +{ + MMModemLock unlock_required; + MbimMessage *response; + GError *error = NULL; + + response = mbim_device_command_finish (device, res, &error); + if (!response) { + g_simple_async_result_take_error (ctx->result, error); + load_unlock_required_context_complete_and_free (ctx); + return; + } + + /* Gather and store the results we want */ + ctx->self->priv->current_lock = (mm_modem_lock_from_mbim_pin_type ( + mbim_message_basic_connect_pin_set_response_get_pin_type (response))); + ctx->self->priv->current_lock_retries = mbim_message_basic_connect_pin_set_response_get_remaining_attempts (response); + mbim_message_unref (response); + + if (mbim_message_basic_connect_pin_set_response_get_pin_state (response) == MBIM_PIN_STATE_UNLOCKED) + unlock_required = MM_MODEM_LOCK_NONE; + else + unlock_required = ctx->self->priv->current_lock; + + g_simple_async_result_set_op_res_gpointer (ctx->result, + GUINT_TO_POINTER (unlock_required), + NULL); + load_unlock_required_context_complete_and_free (ctx); +} + +static void +modem_load_unlock_required (MMIfaceModem *self, + GAsyncReadyCallback callback, + gpointer user_data) +{ + LoadUnlockRequiredContext *ctx; + MMMbimPort *port; + MbimMessage *message; + + ctx = g_slice_new (LoadUnlockRequiredContext); + ctx->self = g_object_ref (self); + ctx->result = g_simple_async_result_new (G_OBJECT (self), + callback, + user_data, + modem_load_unlock_required); + + mm_dbg ("loading unlock required..."); + port = mm_base_modem_peek_port_mbim (MM_BASE_MODEM (self)); + message = (mbim_message_basic_connect_pin_query_request_new ( + mm_mbim_port_get_next_transaction_id (port))); + mbim_device_command (mm_mbim_port_peek_device (port), + message, + 10, + NULL, + (GAsyncReadyCallback)pin_query_ready, + ctx); + mbim_message_unref (message); +} + +/*****************************************************************************/ +/* Unlock retries loading (Modem interface) */ + +static MMUnlockRetries * +modem_load_unlock_retries_finish (MMIfaceModem *self, + GAsyncResult *res, + GError **error) +{ + MMUnlockRetries *retries; + + if (MM_BROADBAND_MODEM_MBIM (self)->priv->current_lock == MM_MODEM_LOCK_UNKNOWN) { + g_set_error (error, + MM_CORE_ERROR, + MM_CORE_ERROR_FAILED, + "Current lock is unknown"); + return NULL; + } + + retries = mm_unlock_retries_new (); + mm_unlock_retries_set (retries, + MM_BROADBAND_MODEM_MBIM (self)->priv->current_lock, + MM_BROADBAND_MODEM_MBIM (self)->priv->current_lock_retries); + return retries; +} + +static void +modem_load_unlock_retries (MMIfaceModem *self, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GSimpleAsyncResult *result; + + /* Just complete */ + result = g_simple_async_result_new (G_OBJECT (self), + callback, + user_data, + modem_load_unlock_retries); + g_simple_async_result_complete_in_idle (result); + g_object_unref (result); +} + +/*****************************************************************************/ /* Create Bearer (Modem interface) */ static MMBearer * @@ -582,6 +718,8 @@ mm_broadband_modem_mbim_init (MMBroadbandModemMbim *self) self->priv = G_TYPE_INSTANCE_GET_PRIVATE ((self), MM_TYPE_BROADBAND_MODEM_MBIM, MMBroadbandModemMbimPrivate); + + self->priv->current_lock = MM_MODEM_LOCK_UNKNOWN; } static void @@ -633,6 +771,10 @@ iface_modem_init (MMIfaceModem *iface) iface->setup_flow_control_finish = NULL; iface->setup_charset = NULL; iface->setup_charset_finish = NULL; + iface->load_unlock_required = modem_load_unlock_required; + iface->load_unlock_required_finish = modem_load_unlock_required_finish; + iface->load_unlock_retries = modem_load_unlock_retries; + iface->load_unlock_retries_finish = modem_load_unlock_retries_finish; /* Create MBIM-specific SIM */ iface->create_sim = create_sim; diff --git a/src/mm-modem-helpers-mbim.c b/src/mm-modem-helpers-mbim.c new file mode 100644 index 00000000..c93d4576 --- /dev/null +++ b/src/mm-modem-helpers-mbim.c @@ -0,0 +1,63 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details: + * + * Copyright (C) 2013 Aleksander Morgado <aleksander@gnu.org> + */ + +#include "mm-modem-helpers-mbim.h" +#include "mm-enums-types.h" +#include "mm-log.h" + +/*****************************************************************************/ + +MMModemLock +mm_modem_lock_from_mbim_pin_type (MbimPinType pin_type) +{ + switch (pin_type) { + case MBIM_PIN_TYPE_CUSTOM: + break; + case MBIM_PIN_TYPE_PIN1: + return MM_MODEM_LOCK_SIM_PIN; + case MBIM_PIN_TYPE_PIN2: + return MM_MODEM_LOCK_SIM_PIN2; + case MBIM_PIN_TYPE_DEVICE_SIM_PIN: + return MM_MODEM_LOCK_PH_SIM_PIN; + case MBIM_PIN_TYPE_DEVICE_FIRST_SIM_PIN: + return MM_MODEM_LOCK_PH_FSIM_PIN; + case MBIM_PIN_TYPE_NETWORK_PIN: + return MM_MODEM_LOCK_PH_NET_PIN; + case MBIM_PIN_TYPE_NETWORK_SUBSET_PIN: + return MM_MODEM_LOCK_PH_NETSUB_PIN; + case MBIM_PIN_TYPE_SERVICE_PROVIDER_PIN: + return MM_MODEM_LOCK_PH_SP_PIN; + case MBIM_PIN_TYPE_CORPORATE_PIN: + return MM_MODEM_LOCK_PH_CORP_PIN; + case MBIM_PIN_TYPE_SUBSIDY_PIN: /* TODO: Update MM lock list? */ + break; + case MBIM_PIN_TYPE_PUK1: + return MM_MODEM_LOCK_SIM_PUK; + case MBIM_PIN_TYPE_PUK2: + return MM_MODEM_LOCK_SIM_PUK2; + case MBIM_PIN_TYPE_DEVICE_FIRST_SIM_PUK: + return MM_MODEM_LOCK_PH_FSIM_PUK; + case MBIM_PIN_TYPE_NETWORK_PUK: + return MM_MODEM_LOCK_PH_NET_PUK; + case MBIM_PIN_TYPE_NETWORK_SUBSET_PUK: + return MM_MODEM_LOCK_PH_NETSUB_PIN; + case MBIM_PIN_TYPE_SERVICE_PROVIDER_PUK: + return MM_MODEM_LOCK_PH_SP_PIN; + case MBIM_PIN_TYPE_CORPORATE_PUK: + return MM_MODEM_LOCK_PH_CORP_PUK; + } + + return MM_MODEM_LOCK_UNKNOWN; +} diff --git a/src/mm-modem-helpers-mbim.h b/src/mm-modem-helpers-mbim.h new file mode 100644 index 00000000..0c0d9f3c --- /dev/null +++ b/src/mm-modem-helpers-mbim.h @@ -0,0 +1,29 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details: + * + * Copyright (C) 2013 Aleksander Morgado <aleksander@gnu.org> + */ + +#ifndef MM_MODEM_HELPERS_MBIM_H +#define MM_MODEM_HELPERS_MBIM_H + +#include <config.h> + +#include <ModemManager.h> +#include <libmbim-glib.h> + +/*****************************************************************************/ +/* MBIM/BasicConnect to MM translations */ + +MMModemLock mm_modem_lock_from_mbim_pin_type (MbimPinType pin_type); + +#endif /* MM_MODEM_HELPERS_MBIM_H */ |