broadband-modem-mbim: implement initial signal quality loading
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.
This commit is contained in:
committed by
Aleksander Morgado
parent
708b00ae3b
commit
5e5160c46a
@@ -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;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user