broadband-modem-mbim: fix signal quality reporting with MBIMEx v2.0
When we enable MBIMEx v2.0, the "Signal State" responses and
indications no longer report a valid RSSI value; and instead, they
report per access technology RSRP/RSRQ values.
>>>>>> Header:
>>>>>> length = 116
>>>>>> type = indicate-status (0x80000007)
>>>>>> transaction = 0
>>>>>> Fragment header:
>>>>>> total = 1
>>>>>> current = 0
>>>>>> Contents:
>>>>>> service = 'basic-connect' (a289cc33-bcbb-8b4f-b6b0-133ec2aae6df)
>>>>>> cid = 'signal-state' (0x0000000b)
>>>>>> Fields:
>>>>>> Rssi = '99'
>>>>>> ErrorRate = '99'
>>>>>> SignalStrengthInterval = '5'
>>>>>> RssiThreshold = '2'
>>>>>> ErrorRateThreshold = '4294967295'
>>>>>> RsrpSnr = '{
>>>>>> [0] = {
>>>>>> Rsrp = '0'
>>>>>> Snr = '0'
>>>>>> RsrpThreshold = '4294967295'
>>>>>> SnrThreshold = '4294967295'
>>>>>> SystemType = '5g-nsa'
>>>>>> },
>>>>>> [1] = {
>>>>>> Rsrp = '49'
>>>>>> Snr = '45'
>>>>>> RsrpThreshold = '4294967295'
>>>>>> SnrThreshold = '4294967295'
>>>>>> SystemType = 'lte'
>>>>>> },
>>>>>> }'
This commit is contained in:
@@ -1698,10 +1698,13 @@ signal_state_query_ready (MbimDevice *device,
|
||||
GAsyncResult *res,
|
||||
GTask *task)
|
||||
{
|
||||
g_autoptr(MbimMessage) response = NULL;
|
||||
MMBroadbandModemMbim *self;
|
||||
GError *error = NULL;
|
||||
guint32 rssi;
|
||||
MMBroadbandModemMbim *self;
|
||||
GError *error = NULL;
|
||||
g_autoptr(MbimMessage) response = NULL;
|
||||
g_autoptr(MbimRsrpSnrInfoArray) rsrp_snr = NULL;
|
||||
guint32 rsrp_snr_count = 0;
|
||||
guint32 rssi;
|
||||
guint quality;
|
||||
|
||||
self = g_task_get_source_object (task);
|
||||
|
||||
@@ -1720,8 +1723,8 @@ signal_state_query_ready (MbimDevice *device,
|
||||
NULL, /* signal_strength_interval */
|
||||
NULL, /* rssi_threshold */
|
||||
NULL, /* error_rate_threshold */
|
||||
NULL, /* rsrp_snr_count */
|
||||
NULL, /* rsrp_snr */
|
||||
&rsrp_snr_count,
|
||||
&rsrp_snr,
|
||||
&error))
|
||||
g_prefix_error (&error, "Failed processing MBIMEx v2.0 signal state response: ");
|
||||
else
|
||||
@@ -1742,10 +1745,10 @@ signal_state_query_ready (MbimDevice *device,
|
||||
|
||||
if (error)
|
||||
g_task_return_error (task, error);
|
||||
else
|
||||
/* Normalize the quality. 99 means unknown, we default it to 0 */
|
||||
g_task_return_int (task, MM_CLAMP_HIGH (rssi == 99 ? 0 : rssi, 31) * 100 / 31);
|
||||
|
||||
else {
|
||||
quality = mm_signal_quality_from_mbim_signal_state (rssi, rsrp_snr, rsrp_snr_count, self);
|
||||
g_task_return_int (task, quality);
|
||||
}
|
||||
g_object_unref (task);
|
||||
}
|
||||
|
||||
@@ -3250,9 +3253,11 @@ basic_connect_notification_signal_state (MMBroadbandModemMbim *self,
|
||||
MbimDevice *device,
|
||||
MbimMessage *notification)
|
||||
{
|
||||
g_autoptr(GError) error = NULL;
|
||||
guint32 rssi;
|
||||
guint32 quality;
|
||||
g_autoptr(GError) error = NULL;
|
||||
g_autoptr(MbimRsrpSnrInfoArray) rsrp_snr = NULL;
|
||||
guint32 rsrp_snr_count = 0;
|
||||
guint32 rssi;
|
||||
guint32 quality;
|
||||
|
||||
if (mbim_device_check_ms_mbimex_version (device, 2, 0)) {
|
||||
if (!mbim_message_ms_basic_connect_v2_signal_state_notification_parse (
|
||||
@@ -3262,8 +3267,8 @@ basic_connect_notification_signal_state (MMBroadbandModemMbim *self,
|
||||
NULL, /* signal_strength_interval */
|
||||
NULL, /* rssi_threshold */
|
||||
NULL, /* error_rate_threshold */
|
||||
NULL, /* rsrp_snr_count */
|
||||
NULL, /* rsrp_snr */
|
||||
&rsrp_snr_count,
|
||||
&rsrp_snr,
|
||||
&error)) {
|
||||
mm_obj_warn (self, "failed processing MBIMEx v2.0 signal state indication: %s", error->message);
|
||||
return;
|
||||
@@ -3284,9 +3289,7 @@ basic_connect_notification_signal_state (MMBroadbandModemMbim *self,
|
||||
mm_obj_dbg (self, "proccessed signal state indication");
|
||||
}
|
||||
|
||||
/* Normalize the quality. 99 means unknown, we default it to 0 */
|
||||
quality = MM_CLAMP_HIGH (rssi == 99 ? 0 : rssi, 31) * 100 / 31;
|
||||
mm_obj_dbg (self, "signal state indication: %u --> %u%%", rssi, quality);
|
||||
quality = mm_signal_quality_from_mbim_signal_state (rssi, rsrp_snr, rsrp_snr_count, self);
|
||||
mm_iface_modem_update_signal_quality (MM_IFACE_MODEM (self), quality);
|
||||
}
|
||||
|
||||
|
||||
@@ -503,3 +503,44 @@ mm_sms_state_from_mbim_message_status (MbimSmsStatus status)
|
||||
return MM_SMS_STATE_UNKNOWN;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
guint
|
||||
mm_signal_quality_from_mbim_signal_state (guint rssi,
|
||||
MbimRsrpSnrInfoArray *rsrp_snr,
|
||||
guint32 rsrp_snr_count,
|
||||
gpointer log_object)
|
||||
{
|
||||
guint quality;
|
||||
|
||||
/* When MBIMEx is enabled we may get RSSI unset, but per access technology
|
||||
* RSRP available. When more than one access technology in use (e.g. 4G+5G in
|
||||
* 5G NSA), take the highest RSRP value reported. */
|
||||
if (rssi == 99 && rsrp_snr && rsrp_snr_count) {
|
||||
guint i;
|
||||
gint max_rsrp = G_MININT;
|
||||
|
||||
for (i = 0; i < rsrp_snr_count; i++) {
|
||||
MbimRsrpSnrInfo *info;
|
||||
|
||||
info = rsrp_snr[i];
|
||||
/* scale the value to dBm */
|
||||
if (info->rsrp < 127) {
|
||||
gint rsrp;
|
||||
|
||||
rsrp = -157 + info->rsrp;
|
||||
if (rsrp > max_rsrp)
|
||||
max_rsrp = rsrp;
|
||||
}
|
||||
}
|
||||
quality = MM_RSRP_TO_QUALITY (max_rsrp);
|
||||
mm_obj_dbg (log_object, "signal state update: %ddBm --> %u%%", max_rsrp, quality);
|
||||
} else {
|
||||
/* Normalize the quality. 99 means unknown, we default it to 0 */
|
||||
quality = MM_CLAMP_HIGH (rssi == 99 ? 0 : rssi, 31) * 100 / 31;
|
||||
mm_obj_dbg (log_object, "signal state update: %u --> %u%%", rssi, quality);
|
||||
}
|
||||
|
||||
return quality;
|
||||
}
|
||||
|
||||
|
||||
@@ -60,4 +60,11 @@ MbimContextType mm_bearer_apn_type_to_mbim_context_type (MMBearerApnT
|
||||
|
||||
MMSmsState mm_sms_state_from_mbim_message_status (MbimSmsStatus status);
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
guint mm_signal_quality_from_mbim_signal_state (guint rssi,
|
||||
MbimRsrpSnrInfoArray *rsrp_snr,
|
||||
guint32 rsrp_snr_count,
|
||||
gpointer log_object);
|
||||
|
||||
#endif /* MM_MODEM_HELPERS_MBIM_H */
|
||||
|
||||
@@ -576,6 +576,10 @@ gboolean mm_sim_parse_cpol_test_response (const gchar *response,
|
||||
#define MM_RSSI_TO_QUALITY(rssi) \
|
||||
(guint8)(100 - ((CLAMP (rssi, -113, -51) + 51) * 100 / (-113 + 51)))
|
||||
|
||||
/* Limit the value betweeen [-110,-60] and scale it to a percentage */
|
||||
#define MM_RSRP_TO_QUALITY(rsrp) \
|
||||
(guint8)(100 - ((CLAMP (rsrp, -110, -60) + 60) * 100 / (-110 + 60)))
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/* Helper function to decode eid read from esim */
|
||||
|
||||
Reference in New Issue
Block a user