[PATCH 2/2] broadband-modem-mbim: implement initial signal quality loading
Aleksander Morgado
aleksander at aleksander.es
Tue Apr 24 18:04:44 UTC 2018
On Tue, Apr 24, 2018 at 1:24 AM, Ben Chan <benchan at chromium.org> wrote:
> ModemManager currently relies on unsolicited MBIM_CID_SIGNAL_STATE
> notifications to obtain signal quality updates, and it doesn't query the
> initial signal quality. It's been observed that some MBIM modems issue a
> MBIM_CID_SIGNAL_STATE notification only when there is a notable change
> in RSSI. The signal quality may remain at 0 for quite some time. It's
> more noticeable when simply restarting ModemManager after the modem has
> been initialized and enabled once.
>
> We could simply enable periodic signal check on an MBIM modem, but
> that's less ideal as it may unnecessarily wake the modem up from USB
> selective suspend (unless we use a much longer polling period).
>
> To address the issue, this patch adds the implementation of
> load_signal_quality to MMBroadbandModemMbim so that the signal quality
> is initially polled via a solicited MBIM_CID_SIGNAL_STATE query. To
> avoid the periodic signal check, we set the
> MM_IFACE_MODEM_PERIODIC_SIGNAL_CHECK_DISABLED property to TRUE for
> MMBroadbandModemMbim.
> ---
Pushed to git master, thanks!
> src/mm-broadband-modem-mbim.c | 80 ++++++++++++++++++++++++++++++++++-
> 1 file changed, 78 insertions(+), 2 deletions(-)
>
> diff --git a/src/mm-broadband-modem-mbim.c b/src/mm-broadband-modem-mbim.c
> index d6562088..09e1ffb7 100644
> --- a/src/mm-broadband-modem-mbim.c
> +++ b/src/mm-broadband-modem-mbim.c
> @@ -1433,6 +1433,79 @@ modem_power_down (MMIfaceModem *self,
> mbim_message_unref (message);
> }
>
> +/*****************************************************************************/
> +/* Signal quality loading (Modem interface) */
> +
> +static guint
> +modem_load_signal_quality_finish (MMIfaceModem *self,
> + GAsyncResult *res,
> + GError **error)
> +{
> + gssize value;
> +
> + value = g_task_propagate_int (G_TASK (res), error);
> + return value < 0 ? 0 : value;
> +}
> +
> +static void
> +signal_state_query_ready (MbimDevice *device,
> + GAsyncResult *res,
> + GTask *task)
> +{
> + MbimMessage *response;
> + GError *error = NULL;
> + guint32 rssi;
> +
> + response = mbim_device_command_finish (device, res, &error);
> + if (response &&
> + mbim_message_response_get_result (response, MBIM_MESSAGE_TYPE_COMMAND_DONE, &error) &&
> + mbim_message_signal_state_response_parse (
> + response,
> + &rssi,
> + NULL, /* error_rate */
> + NULL, /* signal_strength_interval */
> + NULL, /* rssi_threshold */
> + NULL, /* error_rate_threshold */
> + &error)) {
> + guint32 quality;
> +
> + /* Normalize the quality. 99 means unknown, we default it to 0 */
> + quality = CLAMP (rssi == 99 ? 0 : rssi, 0, 31) * 100 / 31;
> +
> + g_task_return_int (task, quality);
> + } else
> + g_task_return_error (task, error);
> +
> + g_object_unref (task);
> +
> + if (response)
> + mbim_message_unref (response);
> +}
> +
> +static void
> +modem_load_signal_quality (MMIfaceModem *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_signal_state_query_new (NULL);
> + mbim_device_command (device,
> + message,
> + 10,
> + NULL,
> + (GAsyncReadyCallback)signal_state_query_ready,
> + task);
> + mbim_message_unref (message);
> +}
> +
> /*****************************************************************************/
> /* Create Bearer (Modem interface) */
>
> @@ -3305,6 +3378,7 @@ mm_broadband_modem_mbim_new (const gchar *device,
> MM_BASE_MODEM_PRODUCT_ID, product_id,
> MM_IFACE_MODEM_SIM_HOT_SWAP_SUPPORTED, TRUE,
> MM_IFACE_MODEM_SIM_HOT_SWAP_CONFIGURED, FALSE,
> + MM_IFACE_MODEM_PERIODIC_SIGNAL_CHECK_DISABLED, TRUE,
> NULL);
> }
>
> @@ -3379,6 +3453,10 @@ iface_modem_init (MMIfaceModem *iface)
> iface->load_supported_ip_families = modem_load_supported_ip_families;
> iface->load_supported_ip_families_finish = modem_load_supported_ip_families_finish;
>
> + /* Additional actions */
> + iface->load_signal_quality = modem_load_signal_quality;
> + iface->load_signal_quality_finish = modem_load_signal_quality_finish;
> +
> /* Unneeded things */
> iface->modem_after_power_up = NULL;
> iface->modem_after_power_up_finish = NULL;
> @@ -3388,8 +3466,6 @@ iface_modem_init (MMIfaceModem *iface)
> iface->setup_flow_control_finish = NULL;
> iface->setup_charset = NULL;
> iface->setup_charset_finish = NULL;
> - iface->load_signal_quality = NULL;
> - iface->load_signal_quality_finish = NULL;
> iface->load_access_technologies = NULL;
> iface->load_access_technologies_finish = NULL;
>
> --
> 2.17.0.484.g0c8726318c-goog
>
--
Aleksander
https://aleksander.es
More information about the ModemManager-devel
mailing list