diff options
author | Aleksander Morgado <aleksander@aleksander.es> | 2021-10-17 22:27:49 +0200 |
---|---|---|
committer | Aleksander Morgado <aleksander@aleksander.es> | 2021-10-18 00:04:59 +0200 |
commit | d6aa72736610865729625e295ff39128c7dd4b17 (patch) | |
tree | 0d8c96d6fd2698c22b890a5e11d537fe7cc147e5 | |
parent | c01f22804e0e4ac35216208e4a38da02cc56290c (diff) |
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'
>>>>>> },
>>>>>> }'
-rw-r--r-- | src/mm-broadband-modem-mbim.c | 39 | ||||
-rw-r--r-- | src/mm-modem-helpers-mbim.c | 41 | ||||
-rw-r--r-- | src/mm-modem-helpers-mbim.h | 7 | ||||
-rw-r--r-- | src/mm-modem-helpers.h | 4 |
4 files changed, 73 insertions, 18 deletions
diff --git a/src/mm-broadband-modem-mbim.c b/src/mm-broadband-modem-mbim.c index 218cf597..901a4985 100644 --- a/src/mm-broadband-modem-mbim.c +++ b/src/mm-broadband-modem-mbim.c @@ -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); } diff --git a/src/mm-modem-helpers-mbim.c b/src/mm-modem-helpers-mbim.c index a1debd00..8d05227a 100644 --- a/src/mm-modem-helpers-mbim.c +++ b/src/mm-modem-helpers-mbim.c @@ -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; +} + diff --git a/src/mm-modem-helpers-mbim.h b/src/mm-modem-helpers-mbim.h index 35ee98f1..3a06d03e 100644 --- a/src/mm-modem-helpers-mbim.h +++ b/src/mm-modem-helpers-mbim.h @@ -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 */ diff --git a/src/mm-modem-helpers.h b/src/mm-modem-helpers.h index 7391409f..4107137c 100644 --- a/src/mm-modem-helpers.h +++ b/src/mm-modem-helpers.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 */ |