<div dir="ltr"><div class="gmail_default" style="font-family:arial,helvetica,sans-serif">Hi Aleksander,<br><br>I fixed the memory leak (GRegex) according to your code review<br><br>---<br><br>MMBroadbandModemTelit:<br> * added logic to set MMBroadbandModem's SIM_HOT_SWAP property to TRUE<br> * added function to enable QSS unsolicited<br> * added QSS unsolicited handler<br>---<br> plugins/telit/mm-broadband-modem-telit.c | 143 ++++++++++++++++++++++++++++++-<br> 1 files changed, 142 insertions(+), 1 deletions(-)<br><br>diff --git a/plugins/telit/mm-broadband-modem-telit.c b/plugins/telit/mm-broadband-modem-telit.c<br>index 8baf2cf..ca64e82 100644<br>--- a/plugins/telit/mm-broadband-modem-telit.c<br>+++ b/plugins/telit/mm-broadband-modem-telit.c<br>@@ -43,6 +43,144 @@ G_DEFINE_TYPE_EXTENDED (MMBroadbandModemTelit, mm_broadband_modem_telit, MM_TYPE<br> G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM_3GPP, iface_modem_3gpp_init));<br> <br> /*****************************************************************************/<br>+/* Setup SIM hot swap (Modem interface) */<br>+<br>+static void<br>+telit_qss_unsolicited_handler (MMPortSerialAt *port,<br>+ GMatchInfo *match_info,<br>+ MMBroadbandModemTelit *self)<br>+{<br>+ guint qss;<br>+ gboolean is_sim_missing;<br>+<br>+ if (!mm_get_uint_from_match_info (match_info, 1, &qss))<br>+ return;<br>+<br>+ switch (qss) {<br>+ case 0:<br>+ mm_info ("QSS: SIM removed");<br>+ break;<br>+ case 1:<br>+ mm_info ("QSS: SIM inserted");<br>+ break;<br>+ case 2:<br>+ mm_info ("QSS: SIM inserted and PIN unlocked");<br>+ break;<br>+ case 3:<br>+ mm_info ("QSS: SIM inserted and PIN locked");<br>+ break;<br>+ default:<br>+ mm_warn ("QSS: unknown QSS value %d", qss);<br>+ break;<br>+ }<br>+<br>+ is_sim_missing = (qss == 0) ? TRUE : FALSE;<br>+ mm_broadband_modem_update_sim_hot_swap_status (MM_BROADBAND_MODEM (self), is_sim_missing);<br>+}<br>+<br>+typedef struct {<br>+ MMBroadbandModemTelit *self;<br>+ GSimpleAsyncResult *result;<br>+} ToggleQssUnsolicitedContext;<br>+<br>+static void<br>+toggle_qss_unsolicited_context_complete_and_free (ToggleQssUnsolicitedContext *ctx)<br>+{<br>+ g_simple_async_result_complete (ctx->result);<br>+ g_object_unref (ctx->result);<br>+ g_object_unref (ctx->self);<br>+ g_slice_free (ToggleQssUnsolicitedContext, ctx);<br>+}<br>+<br>+static gboolean<br>+modem_setup_sim_hot_swap_finish (MMIfaceModem *self,<br>+ GAsyncResult *res,<br>+ GError **error)<br>+{<br>+ return !g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error);<br>+}<br>+<br>+static void<br>+telit_qss_toggle_ready (MMBaseModem *self,<br>+ GAsyncResult *res,<br>+ ToggleQssUnsolicitedContext *ctx)<br>+{<br>+ GError *error = NULL;<br>+<br>+ mm_base_modem_at_command_finish (self, res, &error);<br>+ if (error) {<br>+ mm_warn ("Enable QSS failed: %s", error->message);<br>+ g_simple_async_result_set_error (ctx->result,<br>+ MM_CORE_ERROR,<br>+ MM_CORE_ERROR_FAILED,<br>+ "Could not enable QSS");<br>+ } else {<br>+ MMPortSerialAt *primary;<br>+ MMPortSerialAt *secondary;<br>+ GRegex *pattern;<br>+<br>+ pattern = g_regex_new ("#QSS:\\s*([0-3])\\r\\n", G_REGEX_RAW, 0, NULL);<br>+ g_assert (pattern);<br>+<br>+ primary = mm_base_modem_peek_port_secondary (MM_BASE_MODEM (ctx->self));<br>+ mm_port_serial_at_add_unsolicited_msg_handler (<br>+ primary,<br>+ pattern,<br>+ (MMPortSerialAtUnsolicitedMsgFn)telit_qss_unsolicited_handler,<br>+ ctx->self,<br>+ NULL);<br>+<br>+ secondary = mm_base_modem_peek_port_secondary (MM_BASE_MODEM (ctx->self));<br>+ if (secondary)<br>+ mm_port_serial_at_add_unsolicited_msg_handler (<br>+ secondary,<br>+ pattern,<br>+ (MMPortSerialAtUnsolicitedMsgFn)telit_qss_unsolicited_handler,<br>+ ctx->self,<br>+ NULL);<br>+<br>+ g_regex_unref (pattern);<br>+ g_simple_async_result_set_op_res_gboolean (ctx->result, TRUE);<br>+<br>+ }<br>+<br>+ toggle_qss_unsolicited_context_complete_and_free (ctx);<br>+}<br>+<br>+<br>+static void<br>+modem_setup_sim_hot_swap (MMIfaceModem *self,<br>+ GAsyncReadyCallback callback,<br>+ gpointer user_data)<br>+{<br>+ ToggleQssUnsolicitedContext *ctx;<br>+ MMPortSerialAt *port;<br>+<br>+ mm_dbg ("Telit SIM hot swap: Enable QSS");<br>+<br>+ ctx = g_slice_new0 (ToggleQssUnsolicitedContext);<br>+ ctx->self = g_object_ref (MM_BROADBAND_MODEM_TELIT (self));<br>+ ctx->result = g_simple_async_result_new (G_OBJECT (self),<br>+ callback,<br>+ user_data,<br>+ modem_setup_sim_hot_swap);<br>+<br>+ port = mm_base_modem_peek_port_secondary (MM_BASE_MODEM (self));<br>+ if (!port)<br>+ port = mm_base_modem_peek_port_primary (MM_BASE_MODEM (self));<br>+<br>+ mm_base_modem_at_command_full (MM_BASE_MODEM (self),<br>+ port,<br>+ "#QSS=1",<br>+ 3,<br>+ FALSE,<br>+ FALSE, /* raw */<br>+ NULL, /* cancellable */<br>+ (GAsyncReadyCallback) telit_qss_toggle_ready,<br>+ ctx);<br>+}<br>+<br>+/*****************************************************************************/<br> /* Set current bands (Modem interface) */<br> <br> static gboolean<br>@@ -214,7 +352,7 @@ load_bands_ready (MMBaseModem *self,<br> else<br> g_simple_async_result_set_op_res_gpointer (ctx->result, bands, (GDestroyNotify)g_array_unref);<br> <br>- load_bands_context_complete_and_free(ctx);<br>+ load_bands_context_complete_and_free (ctx);<br> }<br> <br> static void<br>@@ -1017,6 +1155,7 @@ mm_broadband_modem_telit_new (const gchar *device,<br> MM_BASE_MODEM_PLUGIN, plugin,<br> MM_BASE_MODEM_VENDOR_ID, vendor_id,<br> MM_BASE_MODEM_PRODUCT_ID, product_id,<br>+ MM_IFACE_MODEM_SIM_HOT_SWAP_SUPPORTED, TRUE,<br> NULL);<br> }<br> <br>@@ -1052,6 +1191,8 @@ iface_modem_init (MMIfaceModem *iface)<br> iface->load_current_modes_finish = load_current_modes_finish;<br> iface->set_current_modes = set_current_modes;<br> iface->set_current_modes_finish = set_current_modes_finish;<br>+ iface->setup_sim_hot_swap = modem_setup_sim_hot_swap;<br>+ iface->setup_sim_hot_swap_finish = modem_setup_sim_hot_swap_finish;<br> }<br> <br> static void<br><br></div></div><div class="gmail_extra"><br><div class="gmail_quote">On 11 July 2016 at 14:14, Carlo Lobrano <span dir="ltr"><<a href="mailto:c.lobrano@gmail.com" target="_blank">c.lobrano@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><span class=""><br><div class="gmail_quote">On 11 July 2016 at 14:09, Aleksander Morgado <span dir="ltr"><<a href="mailto:aleksander@aleksander.es" target="_blank">aleksander@aleksander.es</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div>You shouldn't be passing the return of g_regex_new() directly to<br>
mm_port_serial_at_add_unsolicited_msg_handler(), as that method takes<br>
its own reference of the GRegex, and therefore the regex would be<br>
leaking afterwards. You should g_regex_new() and store it in a local<br>
variable, pass that variable to<br>
mm_port_serial_at_add_unsolicited_msg_handler() and then<br>
g_regex_unref() the variable.</div></blockquote></div><br><br></span><div class="gmail_default" style="font-family:arial,helvetica,sans-serif">Oh, sorry, I missed that point in the first review</div></div></div>
</blockquote></div><br></div>