iface-modem-signal: added 5G signal information

Extended the ModemManager Signal interface to include 5G signal
information for RSRP, RSRQ and SINR via libqmi.  Also extended mmci
to print 5G signal info.
This commit is contained in:
Walter Hagstrom
2020-06-23 11:14:43 -04:00
committed by Aleksander Morgado
parent 711b17278e
commit 88923ffe39
16 changed files with 198 additions and 20 deletions

View File

@@ -153,6 +153,9 @@ print_signal_info (void)
gchar *lte_rsrp = NULL;
gchar *lte_rsrq = NULL;
gchar *lte_snr = NULL;
gchar *nr5g_rsrp = NULL;
gchar *nr5g_rsrq = NULL;
gchar *nr5g_snr = NULL;
refresh_rate = g_strdup_printf ("%u", mm_modem_signal_get_rate (ctx->modem_signal));
@@ -204,6 +207,16 @@ print_signal_info (void)
lte_snr = g_strdup_printf ("%.2lf", value);
}
signal = mm_modem_signal_peek_nr5g (ctx->modem_signal);
if (signal) {
if ((value = mm_signal_get_rsrq (signal)) != MM_SIGNAL_UNKNOWN)
nr5g_rsrq = g_strdup_printf ("%.2lf", value);
if ((value = mm_signal_get_rsrp (signal)) != MM_SIGNAL_UNKNOWN)
nr5g_rsrp = g_strdup_printf ("%.2lf", value);
if ((value = mm_signal_get_snr (signal)) != MM_SIGNAL_UNKNOWN)
nr5g_snr = g_strdup_printf ("%.2lf", value);
}
mmcli_output_string_take_typed (MMC_F_SIGNAL_REFRESH_RATE, refresh_rate, "seconds");
mmcli_output_string_take_typed (MMC_F_SIGNAL_CDMA1X_RSSI, cdma1x_rssi, "dBm");
mmcli_output_string_take_typed (MMC_F_SIGNAL_CDMA1X_ECIO, cdma1x_ecio, "dBm");
@@ -219,6 +232,9 @@ print_signal_info (void)
mmcli_output_string_take_typed (MMC_F_SIGNAL_LTE_RSRQ, lte_rsrq, "dB");
mmcli_output_string_take_typed (MMC_F_SIGNAL_LTE_RSRP, lte_rsrp, "dBm");
mmcli_output_string_take_typed (MMC_F_SIGNAL_LTE_SNR, lte_snr, "dB");
mmcli_output_string_take_typed (MMC_F_SIGNAL_5G_RSRQ, nr5g_rsrq, "dB");
mmcli_output_string_take_typed (MMC_F_SIGNAL_5G_RSRP, nr5g_rsrp, "dBm");
mmcli_output_string_take_typed (MMC_F_SIGNAL_5G_SNR, nr5g_snr, "dB");
mmcli_output_dump ();
}

View File

@@ -57,6 +57,7 @@ static SectionInfo section_infos[] = {
[MMC_S_MODEM_SIGNAL_GSM] = { "GSM" },
[MMC_S_MODEM_SIGNAL_UMTS] = { "UMTS" },
[MMC_S_MODEM_SIGNAL_LTE] = { "LTE" },
[MMC_S_MODEM_SIGNAL_5G] = { "5G" },
[MMC_S_MODEM_OMA] = { "OMA" },
[MMC_S_MODEM_OMA_CURRENT] = { "Current session" },
[MMC_S_MODEM_OMA_PENDING] = { "Pending sessions" },
@@ -169,6 +170,9 @@ static FieldInfo field_infos[] = {
[MMC_F_SIGNAL_LTE_RSRQ] = { "modem.signal.lte.rsrq", "rsrq", MMC_S_MODEM_SIGNAL_LTE, },
[MMC_F_SIGNAL_LTE_RSRP] = { "modem.signal.lte.rsrp", "rsrp", MMC_S_MODEM_SIGNAL_LTE, },
[MMC_F_SIGNAL_LTE_SNR] = { "modem.signal.lte.snr", "s/n", MMC_S_MODEM_SIGNAL_LTE, },
[MMC_F_SIGNAL_5G_RSRQ] = { "modem.signal.5g.rsrq", "rsrq", MMC_S_MODEM_SIGNAL_5G, },
[MMC_F_SIGNAL_5G_RSRP] = { "modem.signal.5g.rsrp", "rsrp", MMC_S_MODEM_SIGNAL_5G, },
[MMC_F_SIGNAL_5G_SNR] = { "modem.signal.5g.snr", "s/n", MMC_S_MODEM_SIGNAL_5G, },
[MMC_F_OMA_FEATURES] = { "modem.oma.features", "features", MMC_S_MODEM_OMA, },
[MMC_F_OMA_CURRENT_TYPE] = { "modem.oma.current.type", "type", MMC_S_MODEM_OMA_CURRENT, },
[MMC_F_OMA_CURRENT_STATE] = { "modem.oma.current.state", "state", MMC_S_MODEM_OMA_CURRENT, },

View File

@@ -54,6 +54,7 @@ typedef enum {
MMC_S_MODEM_SIGNAL_GSM,
MMC_S_MODEM_SIGNAL_UMTS,
MMC_S_MODEM_SIGNAL_LTE,
MMC_S_MODEM_SIGNAL_5G,
MMC_S_MODEM_OMA,
MMC_S_MODEM_OMA_CURRENT,
MMC_S_MODEM_OMA_PENDING,
@@ -179,6 +180,9 @@ typedef enum {
MMC_F_SIGNAL_LTE_RSRQ,
MMC_F_SIGNAL_LTE_RSRP,
MMC_F_SIGNAL_LTE_SNR,
MMC_F_SIGNAL_5G_RSRQ,
MMC_F_SIGNAL_5G_RSRP,
MMC_F_SIGNAL_5G_SNR,
/* OMA section */
MMC_F_OMA_FEATURES,
MMC_F_OMA_CURRENT_TYPE,

View File

@@ -2793,11 +2793,13 @@ mm_gdbus_modem_signal_get_evdo
mm_gdbus_modem_signal_get_gsm
mm_gdbus_modem_signal_get_umts
mm_gdbus_modem_signal_get_lte
mm_gdbus_modem_signal_get_nr5g
mm_gdbus_modem_signal_dup_cdma
mm_gdbus_modem_signal_dup_evdo
mm_gdbus_modem_signal_dup_gsm
mm_gdbus_modem_signal_dup_umts
mm_gdbus_modem_signal_dup_lte
mm_gdbus_modem_signal_dup_nr5g
<SUBSECTION Methods>
mm_gdbus_modem_signal_call_setup
mm_gdbus_modem_signal_call_setup_finish

View File

@@ -221,5 +221,43 @@
-->
<property name="Lte" type="a{sv}" access="read" />
<!--
Nr5g:
Dictionary of available signal information for the 5G access
technology.
This dictionary is composed of a string key, with an associated data
which contains type-specific information.
<variablelist>
<varlistentry><term><literal>"rsrq"</literal></term>
<listitem>
<para>
The 5G RSRQ (Reference Signal Received Quality), in dB, given as
a floating point value (signature <literal>"d"</literal>).
</para>
</listitem>
</varlistentry>
<varlistentry><term><literal>"rsrp"</literal></term>
<listitem>
<para>
The 5G (Reference Signal Received Power), in dBm, given as
a floating point value (signature <literal>"d"</literal>).
</para>
</listitem>
</varlistentry>
<varlistentry><term><literal>"snr"</literal></term>
<listitem>
<para>
The 5G S/R ratio, in dB, given as
a floating point value (signature <literal>"d"</literal>).
</para>
</listitem>
</varlistentry>
</variablelist>
-->
<property name="Nr5g" type="a{sv}" access="read" />
</interface>
</node>

View File

@@ -53,6 +53,7 @@ typedef enum {
UPDATED_PROPERTY_TYPE_GSM = 2,
UPDATED_PROPERTY_TYPE_UMTS = 3,
UPDATED_PROPERTY_TYPE_LTE = 4,
UPDATED_PROPERTY_TYPE_NR5G = 5,
UPDATED_PROPERTY_TYPE_LAST
} UpdatedPropertyType;
@@ -250,6 +251,13 @@ lte_updated (MMModemSignal *self,
values_updated (self, pspec, UPDATED_PROPERTY_TYPE_LTE);
}
static void
nr5g_updated (MMModemSignal *self,
GParamSpec *pspec)
{
values_updated (self, pspec, UPDATED_PROPERTY_TYPE_NR5G);
}
typedef GVariant * (* Getter) (MmGdbusModemSignal *self);
typedef GVariant * (* Dupper) (MmGdbusModemSignal *self);
typedef void (* UpdatedCallback) (MMModemSignal *self, GParamSpec *pspec);
@@ -265,7 +273,8 @@ static const SignalData signal_data [UPDATED_PROPERTY_TYPE_LAST] = {
{ "notify::evdo", mm_gdbus_modem_signal_get_evdo, mm_gdbus_modem_signal_dup_evdo, evdo_updated },
{ "notify::gsm", mm_gdbus_modem_signal_get_gsm, mm_gdbus_modem_signal_dup_gsm, gsm_updated },
{ "notify::umts", mm_gdbus_modem_signal_get_umts, mm_gdbus_modem_signal_dup_umts, umts_updated },
{ "notify::lte", mm_gdbus_modem_signal_get_lte, mm_gdbus_modem_signal_dup_lte, lte_updated }
{ "notify::lte", mm_gdbus_modem_signal_get_lte, mm_gdbus_modem_signal_dup_lte, lte_updated },
{ "notify::nr5g", mm_gdbus_modem_signal_get_nr5g, mm_gdbus_modem_signal_dup_nr5g, nr5g_updated }
};
static void
@@ -571,6 +580,33 @@ mm_modem_signal_get_lte (MMModemSignal *self)
return info;
}
/**
* mm_modem_signal_get_nr5g:
* @self: A #MMModem.
*
* Gets a #MMSignal object specifying the 5G signal information.
*
* <warning>The values reported by @self are not updated when the values in the
* interface change. Instead, the client is expected to call
* mm_modem_signal_get_nr5g() again to get a new #MMSignal with the new values.
* </warning>
*
* Returns: (transfer full): A #MMSignal that must be freed with
* g_object_unref() or %NULL if unknown.
*
* Since: 1.16
*/
MMSignal *
mm_modem_signal_get_nr5g (MMModemSignal *self)
{
MMSignal *info = NULL;
g_return_val_if_fail (MM_IS_MODEM_SIGNAL (self), NULL);
ensure_internal (self, &info, UPDATED_PROPERTY_TYPE_NR5G);
return info;
}
/**
* mm_modem_signal_peek_lte:
* @self: A #MMModem.
@@ -595,6 +631,30 @@ mm_modem_signal_peek_lte (MMModemSignal *self)
return self->priv->values[UPDATED_PROPERTY_TYPE_LTE].info;
}
/**
* mm_modem_signal_peek_nr5g:
* @self: A #MMModem.
*
* Gets a #MMSignal object specifying the 5G signal information.
*
* <warning>The returned value is only valid until the property changes so it is
* only safe to use this function on the thread where @self was constructed. Use
* mm_modem_signal_get_nr5g() if on another thread.</warning>
*
* Returns: (transfer none): A #MMSignal. Do not free the returned value, it
* belongs to @self.
*
* Since: 1.16
*/
MMSignal *
mm_modem_signal_peek_nr5g (MMModemSignal *self)
{
g_return_val_if_fail (MM_IS_MODEM_SIGNAL (self), NULL);
ensure_internal (self, NULL, UPDATED_PROPERTY_TYPE_NR5G);
return self->priv->values[UPDATED_PROPERTY_TYPE_NR5G].info;
}
/*****************************************************************************/
static void

View File

@@ -97,6 +97,9 @@ MMSignal *mm_modem_signal_peek_umts (MMModemSignal *self);
MMSignal *mm_modem_signal_get_lte (MMModemSignal *self);
MMSignal *mm_modem_signal_peek_lte (MMModemSignal *self);
MMSignal *mm_modem_signal_get_nr5g (MMModemSignal *self);
MMSignal *mm_modem_signal_peek_nr5g (MMModemSignal *self);
G_END_DECLS
#endif /* _MM_MODEM_SIGNAL_H_ */

View File

@@ -2187,13 +2187,14 @@ signal_load_values_finish (MMIfaceModemSignal *_self,
MMSignal **gsm,
MMSignal **umts,
MMSignal **lte,
MMSignal **nr5g,
GError **error)
{
MMBroadbandModemCinterion *self = MM_BROADBAND_MODEM_CINTERION (_self);
const gchar *response;
if (self->priv->smoni_support == FEATURE_NOT_SUPPORTED)
return iface_modem_signal_parent->load_values_finish (_self, res, cdma, evdo, gsm, umts, lte, error);
return iface_modem_signal_parent->load_values_finish (_self, res, cdma, evdo, gsm, umts, lte, nr5g, error);
response = mm_base_modem_at_command_finish (MM_BASE_MODEM (_self), res, error);
if (!response || !mm_cinterion_smoni_response_to_signal_info (response, gsm, umts, lte, error))
@@ -2203,6 +2204,8 @@ signal_load_values_finish (MMIfaceModemSignal *_self,
*cdma = NULL;
if (evdo)
*evdo = NULL;
if (nr5g)
*nr5g = NULL;
return TRUE;
}

View File

@@ -87,6 +87,7 @@ typedef struct {
MMSignal *gsm;
MMSignal *umts;
MMSignal *lte;
MMSignal *nr5g;
} DetailedSignal;
struct _MMBroadbandModemHuaweiPrivate {
@@ -4209,6 +4210,7 @@ signal_load_values_finish (MMIfaceModemSignal *self,
MMSignal **gsm,
MMSignal **umts,
MMSignal **lte,
MMSignal **nr5g,
GError **error)
{
DetailedSignal *signals;
@@ -4222,6 +4224,7 @@ signal_load_values_finish (MMIfaceModemSignal *self,
*gsm = signals->gsm ? g_object_ref (signals->gsm) : NULL;
*umts = signals->umts ? g_object_ref (signals->umts) : NULL;
*lte = signals->lte ? g_object_ref (signals->lte) : NULL;
*nr5g = signals->nr5g ? g_object_ref (signals->nr5g) : NULL;
detailed_signal_free (signals);
return TRUE;

View File

@@ -761,6 +761,7 @@ mm_shared_xmm_signal_load_values_finish (MMIfaceModemSignal *self,
MMSignal **gsm,
MMSignal **umts,
MMSignal **lte,
MMSignal **nr5g,
GError **error)
{
const gchar *response;
@@ -773,6 +774,8 @@ mm_shared_xmm_signal_load_values_finish (MMIfaceModemSignal *self,
*cdma = NULL;
if (evdo)
*evdo = NULL;
if (nr5g)
*nr5g = NULL;
return TRUE;
}

View File

@@ -140,6 +140,7 @@ gboolean mm_shared_xmm_signal_load_values_finish (MMIfaceModemSign
MMSignal **gsm,
MMSignal **umts,
MMSignal **lte,
MMSignal **nr5g,
GError **error);
void mm_shared_xmm_signal_load_values (MMIfaceModemSignal *self,
GCancellable *cancellable,

View File

@@ -4342,6 +4342,7 @@ typedef struct {
MMSignal *gsm;
MMSignal *umts;
MMSignal *lte;
MMSignal *nr5g;
} SignalLoadValuesResult;
static void
@@ -4361,6 +4362,7 @@ modem_signal_load_values_finish (MMIfaceModemSignal *self,
MMSignal **gsm,
MMSignal **umts,
MMSignal **lte,
MMSignal **nr5g,
GError **error)
{
SignalLoadValuesResult *result;
@@ -4391,6 +4393,8 @@ modem_signal_load_values_finish (MMIfaceModemSignal *self,
*cdma = NULL;
if (evdo)
*evdo = NULL;
if (nr5g)
*nr5g = NULL;
return TRUE;
}
@@ -4489,7 +4493,7 @@ parent_signal_load_values_ready (MMIfaceModemSignal *self,
result = g_slice_new0 (SignalLoadValuesResult);
if (!iface_modem_signal_parent->load_values_finish (self, res,
NULL, NULL,
&result->gsm, &result->umts, &result->lte,
&result->gsm, &result->umts, &result->lte, &result->nr5g,
&error)) {
signal_load_values_result_free (result);
g_task_return_error (task, error);

View File

@@ -8463,6 +8463,7 @@ typedef struct {
MMSignal *gsm;
MMSignal *umts;
MMSignal *lte;
MMSignal *nr5g;
} SignalLoadValuesResult;
typedef struct {
@@ -8516,6 +8517,7 @@ signal_load_values_finish (MMIfaceModemSignal *self,
MMSignal **gsm,
MMSignal **umts,
MMSignal **lte,
MMSignal **nr5g,
GError **error)
{
SignalLoadValuesResult *values_result;
@@ -8529,6 +8531,7 @@ signal_load_values_finish (MMIfaceModemSignal *self,
*gsm = values_result->gsm ? g_object_ref (values_result->gsm) : NULL;
*umts = values_result->umts ? g_object_ref (values_result->umts) : NULL;
*lte = values_result->lte ? g_object_ref (values_result->lte) : NULL;
*nr5g = values_result->nr5g ? g_object_ref (values_result->nr5g) : NULL;
signal_load_values_result_free (values_result);
return TRUE;
}
@@ -8702,6 +8705,7 @@ signal_load_values_get_signal_info_ready (QmiClientNas *client,
gint8 rsrq;
gint16 rsrp;
gint16 snr;
gint16 rsrq_5g;
g_autoptr(QmiMessageNasGetSignalInfoOutput) output = NULL;
self = g_task_get_source_object (task);
@@ -8774,6 +8778,22 @@ signal_load_values_get_signal_info_ready (QmiClientNas *client,
mm_signal_set_snr (ctx->values_result->lte, (0.1) * ((gdouble)snr));
}
/* 5G */
if (qmi_message_nas_get_signal_info_output_get_5g_signal_strength (output,
&rsrp,
&snr,
NULL)) {
ctx->values_result->nr5g = mm_signal_new ();
mm_signal_set_rsrp (ctx->values_result->nr5g, (gdouble)rsrp);
mm_signal_set_snr (ctx->values_result->nr5g, (gdouble)snr);
}
if (qmi_message_nas_get_signal_info_output_get_5g_signal_strength_extended (output,
&rsrq_5g,
NULL)) {
mm_signal_set_rsrq (ctx->values_result->nr5g, (gdouble)rsrq_5g);
}
/* Keep on */
ctx->step++;
signal_load_values_context_step (task);

View File

@@ -9981,6 +9981,7 @@ modem_signal_load_values_finish (MMIfaceModemSignal *self,
MMSignal **gsm,
MMSignal **umts,
MMSignal **lte,
MMSignal **nr5g,
GError **error)
{
const gchar *response;
@@ -9994,6 +9995,9 @@ modem_signal_load_values_finish (MMIfaceModemSignal *self,
*cdma = NULL;
if (evdo)
*evdo = NULL;
if (nr5g)
*nr5g = NULL;
return TRUE;
}

View File

@@ -68,6 +68,7 @@ clear_values (MMIfaceModemSignal *self)
mm_gdbus_modem_signal_set_gsm (skeleton, NULL);
mm_gdbus_modem_signal_set_umts (skeleton, NULL);
mm_gdbus_modem_signal_set_lte (skeleton, NULL);
mm_gdbus_modem_signal_set_nr5g (skeleton, NULL);
g_object_unref (skeleton);
}
@@ -82,6 +83,7 @@ load_values_ready (MMIfaceModemSignal *self,
MMSignal *gsm = NULL;
MMSignal *umts = NULL;
MMSignal *lte = NULL;
MMSignal *nr5g = NULL;
MmGdbusModemSignal *skeleton;
if (!MM_IFACE_MODEM_SIGNAL_GET_INTERFACE (self)->load_values_finish (
@@ -92,6 +94,7 @@ load_values_ready (MMIfaceModemSignal *self,
&gsm,
&umts,
&lte,
&nr5g,
&error)) {
mm_obj_warn (self, "couldn't load extended signal information: %s", error->message);
g_error_free (error);
@@ -147,6 +150,15 @@ load_values_ready (MMIfaceModemSignal *self,
} else
mm_gdbus_modem_signal_set_lte (skeleton, NULL);
if (nr5g) {
dictionary = mm_signal_get_dictionary (nr5g);
mm_gdbus_modem_signal_set_nr5g (skeleton, dictionary);
g_variant_unref (dictionary);
g_object_unref (nr5g);
} else
mm_gdbus_modem_signal_set_nr5g (skeleton, NULL);
/* Flush right away */
g_dbus_interface_skeleton_flush (G_DBUS_INTERFACE_SKELETON (skeleton));

View File

@@ -54,6 +54,7 @@ struct _MMIfaceModemSignal {
MMSignal **gsm,
MMSignal **umts,
MMSignal **lte,
MMSignal **nr5g,
GError **error);
};