[PATCH 2/2] Telit plugin: add support to SIM hot swap
Aleksander Morgado
aleksander at aleksander.es
Mon Jul 11 12:09:50 UTC 2016
Hey,
On Wed, Jul 6, 2016 at 3:35 PM, Carlo Lobrano <c.lobrano at gmail.com> wrote:
> MMBroadbandModemTelit:
> * added logic to set MMBroadbandModem's SIM_HOT_SWAP property to TRUE
> * added function to enable QSS unsolicited
> * added QSS unsolicited handler
> ---
> plugins/telit/mm-broadband-modem-telit.c | 136 +++++++++++++++++++++++++++++-
> 1 files changed, 135 insertions(+), 1 deletions(-)
>
> diff --git a/plugins/telit/mm-broadband-modem-telit.c b/plugins/telit/mm-broadband-modem-telit.c
> index 8baf2cf..deb67b2 100644
> --- a/plugins/telit/mm-broadband-modem-telit.c
> +++ b/plugins/telit/mm-broadband-modem-telit.c
> @@ -43,6 +43,137 @@ G_DEFINE_TYPE_EXTENDED (MMBroadbandModemTelit, mm_broadband_modem_telit, MM_TYPE
> G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM_3GPP, iface_modem_3gpp_init));
>
> /*****************************************************************************/
> +/* Setup SIM hot swap (Modem interface) */
> +
> +static void
> +telit_qss_unsolicited_handler (MMPortSerialAt *port,
> + GMatchInfo *match_info,
> + MMBroadbandModemTelit *self)
> +{
> + guint qss;
> + gboolean is_sim_missing;
> +
> + if (!mm_get_uint_from_match_info (match_info, 1, &qss))
> + return;
> +
> + switch (qss) {
> + case 0:
> + mm_info ("QSS: SIM removed");
> + break;
> + case 1:
> + mm_info ("QSS: SIM inserted");
> + break;
> + case 2:
> + mm_info ("QSS: SIM inserted and PIN unlocked");
> + break;
> + case 3:
> + mm_info ("QSS: SIM inserted and PIN locked");
> + break;
> + default:
> + mm_warn ("QSS: unknown QSS value %d", qss);
> + break;
> + }
> +
> + is_sim_missing = (qss == 0) ? TRUE : FALSE;
> + mm_broadband_modem_update_sim_hot_swap_status (MM_BROADBAND_MODEM (self), is_sim_missing);
> +}
> +
> +typedef struct {
> + MMBroadbandModemTelit *self;
> + GSimpleAsyncResult *result;
> +} ToggleQssUnsolicitedContext;
> +
> +static void
> +toggle_qss_unsolicited_context_complete_and_free (ToggleQssUnsolicitedContext *ctx)
> +{
> + g_simple_async_result_complete (ctx->result);
> + g_object_unref (ctx->result);
> + g_object_unref (ctx->self);
> + g_slice_free (ToggleQssUnsolicitedContext, ctx);
> +}
> +
> +static gboolean
> +modem_setup_sim_hot_swap_finish (MMIfaceModem *self,
> + GAsyncResult *res,
> + GError **error)
> +{
> + return !g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error);
> +}
> +
> +static void
> +telit_qss_toggle_ready (MMBaseModem *self,
> + GAsyncResult *res,
> + ToggleQssUnsolicitedContext *ctx)
> +{
> + GError *error = NULL;
> +
> + mm_base_modem_at_command_finish (self, res, &error);
> + if (error) {
> + mm_warn ("Enable QSS failed: %s", error->message);
> + g_simple_async_result_set_error (ctx->result,
> + MM_CORE_ERROR,
> + MM_CORE_ERROR_FAILED,
> + "Could not enable QSS");
> + } else {
> + MMPortSerialAt *primary;
> + MMPortSerialAt *secondary;
> +
> + primary = mm_base_modem_peek_port_secondary (MM_BASE_MODEM (ctx->self));
> + mm_port_serial_at_add_unsolicited_msg_handler (
> + primary,
> + g_regex_new ("#QSS:\\s*([0-3])\\r\\n", G_REGEX_RAW, 0, NULL),
> + (MMPortSerialAtUnsolicitedMsgFn)telit_qss_unsolicited_handler,
> + ctx->self,
> + NULL);
> +
> + secondary = mm_base_modem_peek_port_secondary (MM_BASE_MODEM (ctx->self));
> + if (secondary)
> + mm_port_serial_at_add_unsolicited_msg_handler (
> + secondary,
> + g_regex_new ("#QSS:\\s*([0-3])\\r\\n", G_REGEX_RAW, 0, NULL),
> + (MMPortSerialAtUnsolicitedMsgFn)telit_qss_unsolicited_handler,
> + ctx->self,
> + NULL);
> + g_simple_async_result_set_op_res_gboolean (ctx->result, TRUE);
You shouldn't be passing the return of g_regex_new() directly to
mm_port_serial_at_add_unsolicited_msg_handler(), as that method takes
its own reference of the GRegex, and therefore the regex would be
leaking afterwards. You should g_regex_new() and store it in a local
variable, pass that variable to
mm_port_serial_at_add_unsolicited_msg_handler() and then
g_regex_unref() the variable.
And actually... the regex is the same for the primary and for the
secondary ports, right? So you should only do g_regex_new() once, just
pass the variable to both calls and then unref() the original
reference.
> + }
> +
> + toggle_qss_unsolicited_context_complete_and_free (ctx);
> +}
> +
> +
> +static void
> +modem_setup_sim_hot_swap (MMIfaceModem *self,
> + GAsyncReadyCallback callback,
> + gpointer user_data)
> +{
> + ToggleQssUnsolicitedContext *ctx;
> + MMPortSerialAt *port;
> +
> + mm_dbg ("Telit SIM hot swap: Enable QSS");
> +
> + ctx = g_slice_new0 (ToggleQssUnsolicitedContext);
> + ctx->self = g_object_ref (MM_BROADBAND_MODEM_TELIT (self));
> + ctx->result = g_simple_async_result_new (G_OBJECT (self),
> + callback,
> + user_data,
> + modem_setup_sim_hot_swap);
> +
> + port = mm_base_modem_peek_port_secondary (MM_BASE_MODEM (self));
> + if (!port)
> + port = mm_base_modem_peek_port_primary (MM_BASE_MODEM (self));
> +
> + mm_base_modem_at_command_full (MM_BASE_MODEM (self),
> + port,
> + "#QSS=1",
> + 3,
> + FALSE,
> + FALSE, /* raw */
> + NULL, /* cancellable */
> + (GAsyncReadyCallback) telit_qss_toggle_ready,
> + ctx);
> +}
> +
> +/*****************************************************************************/
> /* Set current bands (Modem interface) */
>
> static gboolean
> @@ -214,7 +345,7 @@ load_bands_ready (MMBaseModem *self,
> else
> g_simple_async_result_set_op_res_gpointer (ctx->result, bands, (GDestroyNotify)g_array_unref);
>
> - load_bands_context_complete_and_free(ctx);
> + load_bands_context_complete_and_free (ctx);
> }
>
> static void
> @@ -1017,6 +1148,7 @@ mm_broadband_modem_telit_new (const gchar *device,
> MM_BASE_MODEM_PLUGIN, plugin,
> MM_BASE_MODEM_VENDOR_ID, vendor_id,
> MM_BASE_MODEM_PRODUCT_ID, product_id,
> + MM_IFACE_MODEM_SIM_HOT_SWAP_SUPPORTED, TRUE,
> NULL);
> }
>
> @@ -1052,6 +1184,8 @@ iface_modem_init (MMIfaceModem *iface)
> iface->load_current_modes_finish = load_current_modes_finish;
> iface->set_current_modes = set_current_modes;
> iface->set_current_modes_finish = set_current_modes_finish;
> + iface->setup_sim_hot_swap = modem_setup_sim_hot_swap;
> + iface->setup_sim_hot_swap_finish = modem_setup_sim_hot_swap_finish;
> }
>
> static void
> --
> 2.7.4
>
> _______________________________________________
> ModemManager-devel mailing list
> ModemManager-devel at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/modemmanager-devel
--
Aleksander
https://aleksander.es
More information about the ModemManager-devel
mailing list