diff options
-rw-r--r-- | cli/mmcli-modem-signal.c | 100 | ||||
-rw-r--r-- | docs/reference/libmm-glib/libmm-glib-docs.xml | 1 | ||||
-rw-r--r-- | docs/reference/libmm-glib/libmm-glib-sections.txt | 114 | ||||
-rw-r--r-- | docs/reference/libmm-glib/libmm-glib.types | 1 | ||||
-rw-r--r-- | introspection/org.freedesktop.ModemManager1.Modem.Signal.xml | 261 | ||||
-rw-r--r-- | libmm-glib/Makefile.am | 7 | ||||
-rw-r--r-- | libmm-glib/libmm-glib.h | 1 | ||||
-rw-r--r-- | libmm-glib/mm-modem-signal.c | 490 | ||||
-rw-r--r-- | libmm-glib/mm-modem-signal.h | 53 | ||||
-rw-r--r-- | libmm-glib/mm-signal.c | 442 | ||||
-rw-r--r-- | libmm-glib/mm-signal.h | 98 | ||||
-rw-r--r-- | src/mm-iface-modem-signal.c | 86 |
12 files changed, 1256 insertions, 398 deletions
diff --git a/cli/mmcli-modem-signal.c b/cli/mmcli-modem-signal.c index 26e8f1da..e1def056 100644 --- a/cli/mmcli-modem-signal.c +++ b/cli/mmcli-modem-signal.c @@ -135,7 +135,7 @@ mmcli_modem_signal_shutdown (void) static void print_signal_info (void) { - gdouble value; + MMSignal *signal; g_print ("\n" "%s\n" @@ -145,71 +145,55 @@ print_signal_info (void) mm_modem_signal_get_rate (ctx->modem_signal)); /* CDMA */ - g_print (" -------------------------\n"); - if (mm_modem_signal_get_cdma_rssi (ctx->modem_signal, &value)) - g_print (" CDMA1x | RSSI: '%.2lf' dBm\n", value); - else - g_print (" CDMA1x | RSSI: unknown\n"); - if (mm_modem_signal_get_cdma_ecio (ctx->modem_signal, &value)) - g_print (" | EcIo: '%.2lf' dBm\n", value); - else - g_print (" | EcIo: unknown\n"); + signal = mm_modem_signal_peek_cdma (ctx->modem_signal); + if (signal) + g_print (" -------------------------\n" + " CDMA1x | RSSI: '%.2lf' dBm\n" + " | EcIo: '%.2lf' dBm\n", + mm_signal_get_rssi (signal), + mm_signal_get_ecio (signal)); /* EVDO */ - g_print (" -------------------------\n"); - if (mm_modem_signal_get_evdo_rssi (ctx->modem_signal, &value)) - g_print (" EV-DO | RSSI: '%.2lf' dBm\n", value); - else - g_print (" EV-DO | RSSI: unknown\n"); - if (mm_modem_signal_get_evdo_ecio (ctx->modem_signal, &value)) - g_print (" | EcIo: '%.2lf' dBm\n", value); - else - g_print (" | EcIo: unknown\n"); - if (mm_modem_signal_get_evdo_sinr (ctx->modem_signal, &value)) - g_print (" | SINR: '%.2lf' dBm\n", value); - else - g_print (" | SINR: unknown\n"); - if (mm_modem_signal_get_evdo_io (ctx->modem_signal, &value)) - g_print (" | Io: '%.2lf' dB\n", value); - else - g_print (" | Io: unknown\n"); + signal = mm_modem_signal_peek_evdo (ctx->modem_signal); + if (signal) + g_print (" -------------------------\n" + " EV-DO | RSSI: '%.2lf' dBm\n" + " | EcIo: '%.2lf' dBm\n" + " | SINR: '%.2lf' dBm\n" + " | Io: '%.2lf' dB\n", + mm_signal_get_rssi (signal), + mm_signal_get_ecio (signal), + mm_signal_get_sinr (signal), + mm_signal_get_io (signal)); /* GSM */ - g_print (" -------------------------\n"); - if (mm_modem_signal_get_gsm_rssi (ctx->modem_signal, &value)) - g_print (" GSM | RSSI: '%.2lf' dBm\n", value); - else - g_print (" GSM | RSSI: unknown\n"); + signal = mm_modem_signal_peek_gsm (ctx->modem_signal); + if (signal) + g_print (" -------------------------\n" + " GSM | RSSI: '%.2lf' dBm\n", + mm_signal_get_rssi (signal)); /* UMTS */ - g_print (" -------------------------\n"); - if (mm_modem_signal_get_umts_rssi (ctx->modem_signal, &value)) - g_print (" UMTS | RSSI: '%.2lf' dBm\n", value); - else - g_print (" UMTS | RSSI: unknown\n"); - if (mm_modem_signal_get_umts_ecio (ctx->modem_signal, &value)) - g_print (" | EcIo: '%.2lf' dBm\n", value); - else - g_print (" | EcIo: unknown\n"); + signal = mm_modem_signal_peek_umts (ctx->modem_signal); + if (signal) + g_print (" -------------------------\n" + " UMTS | RSSI: '%.2lf' dBm\n" + " | EcIo: '%.2lf' dBm\n", + mm_signal_get_rssi (signal), + mm_signal_get_ecio (signal)); /* LTE */ - g_print (" -------------------------\n"); - if (mm_modem_signal_get_lte_rssi (ctx->modem_signal, &value)) - g_print (" LTE | RSSI: '%.2lf' dBm\n", value); - else - g_print (" LTE | RSSI: unknown\n"); - if (mm_modem_signal_get_lte_rsrq (ctx->modem_signal, &value)) - g_print (" | RSRQ: '%.2lf' dB\n", value); - else - g_print (" | RSRQ: unknown\n"); - if (mm_modem_signal_get_lte_rsrp (ctx->modem_signal, &value)) - g_print (" | RSRP: '%.2lf' dBm\n", value); - else - g_print (" | RSRP: unknown\n"); - if (mm_modem_signal_get_lte_snr (ctx->modem_signal, &value)) - g_print (" | SNR: '%.2lf' dB\n", value); - else - g_print (" | SNR: unknown\n"); + signal = mm_modem_signal_peek_lte (ctx->modem_signal); + if (signal) + g_print (" -------------------------\n" + " LTE | RSSI: '%.2lf' dBm\n" + " | RSRQ: '%.2lf' dB\n" + " | RSRP: '%.2lf' dBm\n" + " | SNR: '%.2lf' dB\n", + mm_signal_get_rssi (signal), + mm_signal_get_rsrq (signal), + mm_signal_get_rsrp (signal), + mm_signal_get_snr (signal)); } static void diff --git a/docs/reference/libmm-glib/libmm-glib-docs.xml b/docs/reference/libmm-glib/libmm-glib-docs.xml index e175b208..e91438de 100644 --- a/docs/reference/libmm-glib/libmm-glib-docs.xml +++ b/docs/reference/libmm-glib/libmm-glib-docs.xml @@ -113,6 +113,7 @@ <section> <title>Extended signal information</title> <xi:include href="xml/mm-modem-signal.xml"/> + <xi:include href="xml/mm-signal.xml"/> </section> </chapter> diff --git a/docs/reference/libmm-glib/libmm-glib-sections.txt b/docs/reference/libmm-glib/libmm-glib-sections.txt index 57445748..5300e651 100644 --- a/docs/reference/libmm-glib/libmm-glib-sections.txt +++ b/docs/reference/libmm-glib/libmm-glib-sections.txt @@ -771,24 +771,22 @@ MMModemSignal mm_modem_signal_get_path mm_modem_signal_dup_path mm_modem_signal_get_rate -mm_modem_signal_get_cdma_rssi -mm_modem_signal_get_cdma_ecio -mm_modem_signal_get_evdo_rssi -mm_modem_signal_get_evdo_ecio -mm_modem_signal_get_evdo_sinr -mm_modem_signal_get_evdo_io -mm_modem_signal_get_gsm_rssi -mm_modem_signal_get_umts_rssi -mm_modem_signal_get_umts_ecio -mm_modem_signal_get_lte_rssi -mm_modem_signal_get_lte_rsrq -mm_modem_signal_get_lte_rsrp -mm_modem_signal_get_lte_snr +mm_modem_signal_peek_cdma +mm_modem_signal_get_cdma +mm_modem_signal_peek_evdo +mm_modem_signal_get_evdo +mm_modem_signal_peek_gsm +mm_modem_signal_get_gsm +mm_modem_signal_peek_umts +mm_modem_signal_get_umts +mm_modem_signal_peek_lte +mm_modem_signal_get_lte <SUBSECTION Methods> mm_modem_signal_setup mm_modem_signal_setup_finish mm_modem_signal_setup_sync <SUBSECTION Standard> +MMModemSignalPrivate MMModemSignalClass MM_IS_MODEM_SIGNAL MM_IS_MODEM_SIGNAL_CLASS @@ -800,6 +798,42 @@ mm_modem_signal_get_type </SECTION> <SECTION> +<FILE>mm-signal</FILE> +<TITLE>MMSignal</TITLE> +MMSignal +MM_SIGNAL_UNKNOWN +<SUBSECTION Getters> +mm_signal_get_rssi +mm_signal_get_ecio +mm_signal_get_sinr +mm_signal_get_io +mm_signal_get_rsrp +mm_signal_get_rsrq +mm_signal_get_snr +<SUBSECTION Private> +mm_signal_new +mm_signal_new_from_dictionary +mm_signal_get_dictionary +mm_signal_set_rssi +mm_signal_set_ecio +mm_signal_set_sinr +mm_signal_set_io +mm_signal_set_rsrp +mm_signal_set_rsrq +mm_signal_set_snr +<SUBSECTION Standard> +MMSignalClass +MMSignalPrivate +MM_SIGNAL +MM_SIGNAL_CLASS +MM_SIGNAL_GET_CLASS +MM_IS_SIGNAL +MM_IS_SIGNAL_CLASS +MM_TYPE_SIGNAL +mm_signal_get_type +</SECTION> + +<SECTION> <FILE>mm-bearer</FILE> <TITLE>MMBearer</TITLE> MMBearer @@ -2131,52 +2165,28 @@ mm_gdbus_modem_simple_skeleton_get_type MmGdbusModemSignal MmGdbusModemSignalIface <SUBSECTION Getters> -mm_gdbus_modem_signal_get_cdma_ecio -mm_gdbus_modem_signal_get_cdma_rssi -mm_gdbus_modem_signal_get_evdo_ecio -mm_gdbus_modem_signal_get_evdo_io -mm_gdbus_modem_signal_get_evdo_rssi -mm_gdbus_modem_signal_get_evdo_sinr -mm_gdbus_modem_signal_get_gsm_rssi -mm_gdbus_modem_signal_get_lte_rsrp -mm_gdbus_modem_signal_get_lte_rsrq -mm_gdbus_modem_signal_get_lte_rssi -mm_gdbus_modem_signal_get_lte_snr mm_gdbus_modem_signal_get_rate -mm_gdbus_modem_signal_get_umts_ecio -mm_gdbus_modem_signal_get_umts_rssi -mm_gdbus_modem_signal_dup_cdma_ecio -mm_gdbus_modem_signal_dup_cdma_rssi -mm_gdbus_modem_signal_dup_evdo_ecio -mm_gdbus_modem_signal_dup_evdo_io -mm_gdbus_modem_signal_dup_evdo_rssi -mm_gdbus_modem_signal_dup_evdo_sinr -mm_gdbus_modem_signal_dup_gsm_rssi -mm_gdbus_modem_signal_dup_lte_rsrp -mm_gdbus_modem_signal_dup_lte_rsrq -mm_gdbus_modem_signal_dup_lte_rssi -mm_gdbus_modem_signal_dup_lte_snr -mm_gdbus_modem_signal_dup_umts_ecio -mm_gdbus_modem_signal_dup_umts_rssi +mm_gdbus_modem_signal_get_cdma +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_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 <SUBSECTION Methods> mm_gdbus_modem_signal_call_setup mm_gdbus_modem_signal_call_setup_finish mm_gdbus_modem_signal_call_setup_sync <SUBSECTION Private> -mm_gdbus_modem_signal_set_cdma_ecio -mm_gdbus_modem_signal_set_cdma_rssi -mm_gdbus_modem_signal_set_evdo_ecio -mm_gdbus_modem_signal_set_evdo_io -mm_gdbus_modem_signal_set_evdo_rssi -mm_gdbus_modem_signal_set_evdo_sinr -mm_gdbus_modem_signal_set_gsm_rssi -mm_gdbus_modem_signal_set_lte_rsrp -mm_gdbus_modem_signal_set_lte_rsrq -mm_gdbus_modem_signal_set_lte_rssi -mm_gdbus_modem_signal_set_lte_snr +mm_gdbus_modem_signal_set_cdma +mm_gdbus_modem_signal_set_evdo +mm_gdbus_modem_signal_set_gsm +mm_gdbus_modem_signal_set_lte mm_gdbus_modem_signal_set_rate -mm_gdbus_modem_signal_set_umts_ecio -mm_gdbus_modem_signal_set_umts_rssi +mm_gdbus_modem_signal_set_umts mm_gdbus_modem_signal_complete_setup mm_gdbus_modem_signal_interface_info mm_gdbus_modem_signal_override_properties diff --git a/docs/reference/libmm-glib/libmm-glib.types b/docs/reference/libmm-glib/libmm-glib.types index c39e1b26..c0955e59 100644 --- a/docs/reference/libmm-glib/libmm-glib.types +++ b/docs/reference/libmm-glib/libmm-glib.types @@ -10,6 +10,7 @@ mm_connection_error_get_type mm_core_error_get_type mm_firmware_image_type_get_type mm_firmware_properties_get_type +mm_signal_get_type mm_gdbus_bearer_get_type mm_gdbus_bearer_proxy_get_type mm_gdbus_bearer_skeleton_get_type diff --git a/introspection/org.freedesktop.ModemManager1.Modem.Signal.xml b/introspection/org.freedesktop.ModemManager1.Modem.Signal.xml index 2a034644..5d50a265 100644 --- a/introspection/org.freedesktop.ModemManager1.Modem.Signal.xml +++ b/introspection/org.freedesktop.ModemManager1.Modem.Signal.xml @@ -35,121 +35,178 @@ <property name="Rate" type="u" access="read" /> <!-- - CdmaRssi: - - CDMA1x RSSI (Received Signal Strength Indication), in dBm. - - The boolean flag indicates whether the value is valid. - --> - <property name="CdmaRssi" type="(bd)" access="read" /> - - <!-- - CdmaEcio: - - CDMA1x Ec/Io, in dBm. - - The boolean flag indicates whether the value is valid. - --> - <property name="CdmaEcio" type="(bd)" access="read" /> - - <!-- - EvdoRssi: - - CDMA EV-DO RSSI (Received Signal Strength Indication), in dBm. - - The boolean flag indicates whether the value is valid. - --> - <property name="EvdoRssi" type="(bd)" access="read" /> - - <!-- - EvdoEcio: - - CDMA EV-DO Ec/Io, in dBm. - - The boolean flag indicates whether the value is valid. - --> - <property name="EvdoEcio" type="(bd)" access="read" /> - - <!-- - EvdoSinr: - - CDMA EV-DO SINR level, in dB. - - The boolean flag indicates whether the value is valid. - --> - <property name="EvdoSinr" type="(bd)" access="read" /> - - <!-- - EvdoIo: - - CDMA EV-DO IO, in dBm. - - The boolean flag indicates whether the value is valid. + Cdma: + + Dictionary of available signal information for the CDMA1x access + technology. + + This dictionary is composed of a string key, with an associated data + which contains type-specific information. + + <variablelist> + <varlistentry><term><literal>"rssi"</literal></term> + <listitem> + <para> + The CDMA1x RSSI (Received Signal Strength Indication), in dBm, + given as a floating point value (signature <literal>"d"</literal>). + </para> + </listitem> + </varlistentry> + <varlistentry><term><literal>"ecio"</literal></term> + <listitem> + <para> + The CDMA1x Ec/Io, in dBm, given as a floating point value + (signature <literal>"d"</literal>). + </para> + </listitem> + </varlistentry> + </variablelist> --> - <property name="EvdoIo" type="(bd)" access="read" /> + <property name="Cdma" type="a{sv}" access="read" /> <!-- - GsmRssi: - - GSM RSSI (Received Signal Strength Indication), in dBm. - - The boolean flag indicates whether the value is valid. + Evdo: + + Dictionary of available signal information for the CDMA EV-DO access + technology. + + This dictionary is composed of a string key, with an associated data + which contains type-specific information. + + <variablelist> + <varlistentry><term><literal>"rssi"</literal></term> + <listitem> + <para> + The CDMA EV-DO RSSI (Received Signal Strength Indication), in dBm, + given as a floating point value (signature <literal>"d"</literal>). + </para> + </listitem> + </varlistentry> + <varlistentry><term><literal>"ecio"</literal></term> + <listitem> + <para> + The CDMA EV-DO Ec/Io, in dBm, given as a floating point value + (signature <literal>"d"</literal>). + </para> + </listitem> + </varlistentry> + <varlistentry><term><literal>"sinr"</literal></term> + <listitem> + <para> + CDMA EV-DO SINR level, in dB, given as a floating point value + (signature <literal>"d"</literal>). + </para> + </listitem> + </varlistentry> + <varlistentry><term><literal>"io"</literal></term> + <listitem> + <para> + The CDMA EV-DO Io, in dBm, given as a floating point value + (signature <literal>"d"</literal>). + </para> + </listitem> + </varlistentry> + </variablelist> --> - <property name="GsmRssi" type="(bd)" access="read" /> + <property name="Evdo" type="a{sv}" access="read" /> <!-- - UmtsRssi: - - UMTS (WCDMA) RSSI (Received Signal Strength Indication), in dBm. - - The boolean flag indicates whether the value is valid. + Gsm: + + Dictionary of available signal information for the GSM/GPRS access + technology. + + This dictionary is composed of a string key, with an associated data + which contains type-specific information. + + <variablelist> + <varlistentry><term><literal>"rssi"</literal></term> + <listitem> + <para> + The GSM RSSI (Received Signal Strength Indication), in dBm, + given as a floating point value (signature <literal>"d"</literal>). + </para> + </listitem> + </varlistentry> + </variablelist> --> - <property name="UmtsRssi" type="(bd)" access="read" /> + <property name="Gsm" type="a{sv}" access="read" /> <!-- - UmtsEcio: - - UMTS (WCDMA) Ec/Io, in dBm. - - The boolean flag indicates whether the value is valid. - --> - <property name="UmtsEcio" type="(bd)" access="read" /> - - <!-- - LteRssi: - - LTE RSSI (Received Signal Strength Indication), in dBm. - - The boolean flag indicates whether the value is valid. + Umts: + + Dictionary of available signal information for the UMTS (WCDMA) access + technology. + + This dictionary is composed of a string key, with an associated data + which contains type-specific information. + + <variablelist> + <varlistentry><term><literal>"rssi"</literal></term> + <listitem> + <para> + The UMTS RSSI (Received Signal Strength Indication), in dBm, + given as a floating point value (signature <literal>"d"</literal>). + </para> + </listitem> + </varlistentry> + <varlistentry><term><literal>"ecio"</literal></term> + <listitem> + <para> + The UMTS Ec/Io, in dBm, given as a floating point value + (signature <literal>"d"</literal>). + </para> + </listitem> + </varlistentry> + </variablelist> --> - <property name="LteRssi" type="(bd)" access="read" /> + <property name="Umts" type="a{sv}" access="read" /> <!-- - LteRsrq: - - LTE RSRQ (Reference Signal Received Quality), in dB. - - The boolean flag indicates whether the value is valid. - --> - <property name="LteRsrq" type="(bd)" access="read" /> - - <!-- - LteRsrp: - - LTE RSRP (Reference Signal Received Power), in dBm. - - The boolean flag indicates whether the value is valid. - --> - <property name="LteRsrp" type="(bd)" access="read" /> - - <!-- - LteSnr: - - LTE S/R ratio, in dB. - - The boolean flag indicates whether the value is valid. + Lte: + + Dictionary of available signal information for the UMTS (WCDMA) access + technology. + + This dictionary is composed of a string key, with an associated data + which contains type-specific information. + + <variablelist> + <varlistentry><term><literal>"rssi"</literal></term> + <listitem> + <para> + The LTE RSSI (Received Signal Strength Indication), in dBm, + given as a floating point value (signature <literal>"d"</literal>). + </para> + </listitem> + </varlistentry> + <varlistentry><term><literal>"rsrq"</literal></term> + <listitem> + <para> + The LTE 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 LTE RSRP (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 LTE S/R ratio, in dB, given as + a floating point value (signature <literal>"d"</literal>). + </para> + </listitem> + </varlistentry> + </variablelist> --> - <property name="LteSnr" type="(bd)" access="read" /> + <property name="Lte" type="a{sv}" access="read" /> </interface> </node> diff --git a/libmm-glib/Makefile.am b/libmm-glib/Makefile.am index a9c6f2d5..d78235d4 100644 --- a/libmm-glib/Makefile.am +++ b/libmm-glib/Makefile.am @@ -65,7 +65,9 @@ libmm_glib_la_SOURCES = \ mm-firmware-properties.h \ mm-firmware-properties.c \ mm-cdma-manual-activation-properties.h \ - mm-cdma-manual-activation-properties.c + mm-cdma-manual-activation-properties.c \ + mm-signal.h \ + mm-signal.c libmm_glib_la_CPPFLAGS = \ -I$(srcdir) \ @@ -120,7 +122,8 @@ include_HEADERS = \ mm-unlock-retries.h \ mm-network-timezone.h \ mm-firmware-properties.h \ - mm-cdma-manual-activation-properties.h + mm-cdma-manual-activation-properties.h \ + mm-signal.h CLEANFILES = diff --git a/libmm-glib/libmm-glib.h b/libmm-glib/libmm-glib.h index 732b212c..98a25a4f 100644 --- a/libmm-glib/libmm-glib.h +++ b/libmm-glib/libmm-glib.h @@ -68,6 +68,7 @@ #include <mm-network-timezone.h> #include <mm-firmware-properties.h> #include <mm-cdma-manual-activation-properties.h> +#include <mm-signal.h> /* generated */ #include <mm-errors-types.h> diff --git a/libmm-glib/mm-modem-signal.c b/libmm-glib/mm-modem-signal.c index f930a923..e977f162 100644 --- a/libmm-glib/mm-modem-signal.c +++ b/libmm-glib/mm-modem-signal.c @@ -41,6 +41,25 @@ G_DEFINE_TYPE (MMModemSignal, mm_modem_signal, MM_GDBUS_TYPE_MODEM_SIGNAL_PROXY) +typedef struct { + GMutex mutex; + guint id; + MMSignal *info; +} UpdatedProperty; + +typedef enum { + UPDATED_PROPERTY_TYPE_CDMA = 0, + UPDATED_PROPERTY_TYPE_EVDO = 1, + UPDATED_PROPERTY_TYPE_GSM = 2, + UPDATED_PROPERTY_TYPE_UMTS = 3, + UPDATED_PROPERTY_TYPE_LTE = 4, + UPDATED_PROPERTY_TYPE_LAST +} UpdatedPropertyType; + +struct _MMModemSignalPrivate { + UpdatedProperty values [UPDATED_PROPERTY_TYPE_LAST]; +}; + /*****************************************************************************/ /** @@ -95,8 +114,8 @@ mm_modem_signal_dup_path (MMModemSignal *self) */ gboolean mm_modem_signal_setup_finish (MMModemSignal *self, - GAsyncResult *res, - GError **error) + GAsyncResult *res, + GError **error) { g_return_val_if_fail (MM_IS_MODEM_SIGNAL (self), FALSE); @@ -120,10 +139,10 @@ mm_modem_signal_setup_finish (MMModemSignal *self, */ void mm_modem_signal_setup (MMModemSignal *self, - guint rate, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data) + guint rate, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) { g_return_if_fail (MM_IS_MODEM_SIGNAL (self)); @@ -146,9 +165,9 @@ mm_modem_signal_setup (MMModemSignal *self, */ gboolean mm_modem_signal_setup_sync (MMModemSignal *self, - guint rate, - GCancellable *cancellable, - GError **error) + guint rate, + GCancellable *cancellable, + GError **error) { g_return_val_if_fail (MM_IS_MODEM_SIGNAL (self), FALSE); @@ -175,182 +194,409 @@ mm_modem_signal_get_rate (MMModemSignal *self) /*****************************************************************************/ -#define GETTER(VALUE) \ - gboolean \ - mm_modem_signal_get_##VALUE (MMModemSignal *self, \ - gdouble *value) \ - { \ - GVariant *variant; \ - gboolean is_valid = FALSE; \ - double val = 0.0; \ - \ - g_return_val_if_fail (MM_IS_MODEM_SIGNAL (self), FALSE); \ - \ - variant = mm_gdbus_modem_signal_dup_##VALUE (MM_GDBUS_MODEM_SIGNAL (self)); \ - if (variant) { \ - g_variant_get (variant, \ - "(bd)", \ - &is_valid, \ - &val); \ - g_variant_unref (variant); \ - } \ - \ - if (is_valid) \ - *value = val; \ - return is_valid; \ +static void values_updated (MMModemSignal *self, GParamSpec *pspec, UpdatedPropertyType type); + +static void +cdma_updated (MMModemSignal *self, + GParamSpec *pspec) +{ + values_updated (self, pspec, UPDATED_PROPERTY_TYPE_CDMA); +} + +static void +evdo_updated (MMModemSignal *self, + GParamSpec *pspec) +{ + values_updated (self, pspec, UPDATED_PROPERTY_TYPE_EVDO); +} + +static void +gsm_updated (MMModemSignal *self, + GParamSpec *pspec) +{ + values_updated (self, pspec, UPDATED_PROPERTY_TYPE_GSM); +} + +static void +umts_updated (MMModemSignal *self, + GParamSpec *pspec) +{ + values_updated (self, pspec, UPDATED_PROPERTY_TYPE_UMTS); +} + +static void +lte_updated (MMModemSignal *self, + GParamSpec *pspec) +{ + values_updated (self, pspec, UPDATED_PROPERTY_TYPE_LTE); +} + +typedef GVariant * (* Getter) (MmGdbusModemSignal *self); +typedef GVariant * (* Dupper) (MmGdbusModemSignal *self); +typedef void (* UpdatedCallback) (MMModemSignal *self, GParamSpec *pspec); +typedef struct { + const gchar *signal_name; + Getter get; + Dupper dup; + UpdatedCallback updated_callback; +} SignalData; + +static const SignalData signal_data [UPDATED_PROPERTY_TYPE_LAST] = { + { "notify::cdma", mm_gdbus_modem_signal_get_cdma, mm_gdbus_modem_signal_dup_cdma, cdma_updated }, + { "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 } +}; + +static void +values_updated (MMModemSignal *self, + GParamSpec *pspec, + UpdatedPropertyType type) +{ + g_mutex_lock (&self->priv->values[type].mutex); + { + GVariant *dictionary; + + g_clear_object (&self->priv->values[type].info); + dictionary = signal_data[type].get (MM_GDBUS_MODEM_SIGNAL (self)); + if (dictionary) { + GError *error = NULL; + + self->priv->values[type].info = mm_signal_new_from_dictionary (dictionary, &error); + if (error) { + g_warning ("Invalid signal info update received: %s", error->message); + g_error_free (error); + } + } } + g_mutex_unlock (&self->priv->values[type].mutex); +} -/** - * mm_modem_get_cdma_rssi: - * @self: A #MMModemSignal. - * @value: (out): Return location for the value. - * - * Gets the CDMA1x RSSI (Received Signal Strength Indication), in dBm. - * - * Returns: %TRUE if @value is valid, %FALSE otherwise. - */ -GETTER(cdma_rssi) +static void +ensure_internal (MMModemSignal *self, + MMSignal **dup, + UpdatedPropertyType type) +{ + g_mutex_lock (&self->priv->values[type].mutex); + { + /* If this is the first time ever asking for the object, setup the + * update listener and the initial object, if any. */ + if (!self->priv->values[type].id) { + GVariant *dictionary; + + dictionary = signal_data[type].dup (MM_GDBUS_MODEM_SIGNAL (self)); + if (dictionary) { + GError *error = NULL; + + self->priv->values[type].info = mm_signal_new_from_dictionary (dictionary, &error); + if (error) { + g_warning ("Invalid signal info: %s", error->message); + g_error_free (error); + } + g_variant_unref (dictionary); + } + + /* No need to clear this signal connection when freeing self */ + self->priv->values[type].id = + g_signal_connect (self, + signal_data[type].signal_name, + G_CALLBACK (signal_data[type].updated_callback), + NULL); + } + + if (dup && self->priv->values[type].info) + *dup = g_object_ref (self->priv->values[type].info); + } + g_mutex_unlock (&self->priv->values[type].mutex); +} -/** - * mm_modem_get_cdma_ecio: - * @self: A #MMModemSignal. - * @value: (out): Return location for the value. - * - * Gets the CDMA1x Ec/Io, in dBm. - * - * Returns: %TRUE if @value is valid, %FALSE otherwise. - */ -GETTER(cdma_ecio) +/*****************************************************************************/ /** - * mm_modem_get_evdo_rssi: - * @self: A #MMModemSignal. - * @value: (out): Return location for the value. + * mm_modem_get_cdma: + * @self: A #MMModem. * - * Gets the CDMA EV-DO RSSI (Received Signal Strength Indication), in dBm. + * Gets a #MMSignal object specifying the CDMA signal information. * - * Returns: %TRUE if @value is valid, %FALSE otherwise. - */ -GETTER(evdo_rssi) - -/** - * mm_modem_get_evdo_ecio: - * @self: A #MMModemSignal. - * @value: (out): Return location for the value. - * - * Gets the CDMA EV-DO Ec/Io, in dBm. + * <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_get_cdma() again to get a new #MMSignal with the + * new values.</warning> * - * Returns: %TRUE if @value is valid, %FALSE otherwise. + * Returns: (transfer full) A #MMSignal that must be freed with g_object_unref() or %NULL if unknown. */ -GETTER(evdo_ecio) +MMSignal * +mm_modem_signal_get_cdma (MMModemSignal *self) +{ + MMSignal *info = NULL; + + g_return_val_if_fail (MM_IS_MODEM_SIGNAL (self), NULL); + + ensure_internal (self, &info, UPDATED_PROPERTY_TYPE_CDMA); + return info; +} /** - * mm_modem_get_evdo_sinr: - * @self: A #MMModemSignal. - * @value: (out): Return location for the value. + * mm_modem_peek_cdma: + * @self: A #MMModem. * - * Gets the CDMA EV-DO SINR level, in dB. + * Gets a #MMSignal object specifying the CDMA signal information. * - * Returns: %TRUE if @value is valid, %FALSE otherwise. + * <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_get_cdma() if on another + * thread.</warning> + * + * Returns: (transfer none) A #MMSignal. Do not free the returned value, it belongs to @self. */ -GETTER(evdo_sinr) +MMSignal * +mm_modem_signal_peek_cdma (MMModemSignal *self) +{ + g_return_val_if_fail (MM_IS_MODEM_SIGNAL (self), NULL); + + ensure_internal (self, NULL, UPDATED_PROPERTY_TYPE_CDMA); + return self->priv->values[UPDATED_PROPERTY_TYPE_CDMA].info; +} + +/*****************************************************************************/ /** - * mm_modem_get_evdo_io: - * @self: A #MMModemSignal. - * @value: (out): Return location for the value. + * mm_modem_get_evdo: + * @self: A #MMModem. * - * Gets the CDMA EV-DO IO, in dBm. + * Gets a #MMSignal object specifying the EV-DO signal information. * - * Returns: %TRUE if @value is valid, %FALSE otherwise. + * <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_get_evdo() 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. */ -GETTER(evdo_io) +MMSignal * +mm_modem_signal_get_evdo (MMModemSignal *self) +{ + MMSignal *info = NULL; + + g_return_val_if_fail (MM_IS_MODEM_SIGNAL (self), NULL); + + ensure_internal (self, &info, UPDATED_PROPERTY_TYPE_EVDO); + return info; +} /** - * mm_modem_get_gsm_rssi: - * @self: A #MMModemSignal. - * @value: (out): Return location for the value. + * mm_modem_peek_evdo: + * @self: A #MMModem. + * + * Gets a #MMSignal object specifying the EV-DO signal information. * - * Gets the GSM RSSI (Received Signal Strength Indication), in dBm. + * <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_get_evdo() if on another + * thread.</warning> * - * Returns: %TRUE if @value is valid, %FALSE otherwise. + * Returns: (transfer none) A #MMSignal. Do not free the returned value, it belongs to @self. */ -GETTER(gsm_rssi) +MMSignal * +mm_modem_signal_peek_evdo (MMModemSignal *self) +{ + g_return_val_if_fail (MM_IS_MODEM_SIGNAL (self), NULL); + + ensure_internal (self, NULL, UPDATED_PROPERTY_TYPE_EVDO); + return self->priv->values[UPDATED_PROPERTY_TYPE_EVDO].info; +} + +/*****************************************************************************/ /** - * mm_modem_get_umts_rssi: - * @self: A #MMModemSignal. - * @value: (out): Return location for the value. + * mm_modem_get_gsm: + * @self: A #MMModem. * - * Gets the UMTS (WCDMA) RSSI (Received Signal Strength Indication), in dBm. + * Gets a #MMSignal object specifying the GSM signal information. * - * Returns: %TRUE if @value is valid, %FALSE otherwise. + * <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_get_gsm() 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. */ -GETTER(umts_rssi) +MMSignal * +mm_modem_signal_get_gsm (MMModemSignal *self) +{ + MMSignal *info = NULL; + + g_return_val_if_fail (MM_IS_MODEM_SIGNAL (self), NULL); + + ensure_internal (self, &info, UPDATED_PROPERTY_TYPE_GSM); + return info; +} /** - * mm_modem_get_umts_ecio: - * @self: A #MMModemSignal. - * @value: (out): Return location for the value. + * mm_modem_peek_gsm: + * @self: A #MMModem. + * + * Gets a #MMSignal object specifying the GSM signal information. * - * Gets the UMTS (WCDMA) Ec/Io, in dBm. + * <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_get_gsm() if on another + * thread.</warning> * - * Returns: %TRUE if @value is valid, %FALSE otherwise. + * Returns: (transfer none) A #MMSignal. Do not free the returned value, it belongs to @self. */ -GETTER(umts_ecio) +MMSignal * +mm_modem_signal_peek_gsm (MMModemSignal *self) +{ + g_return_val_if_fail (MM_IS_MODEM_SIGNAL (self), NULL); + + ensure_internal (self, NULL, UPDATED_PROPERTY_TYPE_GSM); + return self->priv->values[UPDATED_PROPERTY_TYPE_GSM].info; +} + +/*****************************************************************************/ /** - * mm_modem_get_lte_rssi: - * @self: A #MMModemSignal. - * @value: (out): Return location for the value. + * mm_modem_get_umts: + * @self: A #MMModem. * - * Gets the LTE RSSI (Received Signal Strength Indication), in dBm. + * Gets a #MMSignal object specifying the UMTS signal information. * - * Returns: %TRUE if @value is valid, %FALSE otherwise. + * <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_get_umts() 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. */ -GETTER(lte_rssi) +MMSignal * +mm_modem_signal_get_umts (MMModemSignal *self) +{ + MMSignal *info = NULL; + + g_return_val_if_fail (MM_IS_MODEM_SIGNAL (self), NULL); + + ensure_internal (self, &info, UPDATED_PROPERTY_TYPE_UMTS); + return info; +} /** - * mm_modem_get_lte_rsrq: - * @self: A #MMModemSignal. - * @value: (out): Return location for the value. + * mm_modem_peek_umts: + * @self: A #MMModem. + * + * Gets a #MMSignal object specifying the UMTS signal information. * - * Gets the LTE RSRQ (Reference Signal Received Quality), in dB. + * <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_get_umts() if on another + * thread.</warning> * - * Returns: %TRUE if @value is valid, %FALSE otherwise. + * Returns: (transfer none) A #MMSignal. Do not free the returned value, it belongs to @self. */ -GETTER(lte_rsrq) +MMSignal * +mm_modem_signal_peek_umts (MMModemSignal *self) +{ + g_return_val_if_fail (MM_IS_MODEM_SIGNAL (self), NULL); + + ensure_internal (self, NULL, UPDATED_PROPERTY_TYPE_UMTS); + return self->priv->values[UPDATED_PROPERTY_TYPE_UMTS].info; +} + +/*****************************************************************************/ /** - * mm_modem_get_lte_rsrp: - * @self: A #MMModemSignal. - * @value: (out): Return location for the value. + * mm_modem_get_lte: + * @self: A #MMModem. * - * Gets the LTE RSRP (Reference Signal Received Power), in dBm. + * Gets a #MMSignal object specifying the LTE signal information. * - * Returns: %TRUE if @value is valid, %FALSE otherwise. + * <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_get_lte() 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. */ -GETTER(lte_rsrp) +MMSignal * +mm_modem_signal_get_lte (MMModemSignal *self) +{ + MMSignal *info = NULL; + + g_return_val_if_fail (MM_IS_MODEM_SIGNAL (self), NULL); + + ensure_internal (self, &info, UPDATED_PROPERTY_TYPE_LTE); + return info; +} /** - * mm_modem_get_lte_snr: - * @self: A #MMModemSignal. - * @value: (out): Return location for the value. + * mm_modem_peek_lte: + * @self: A #MMModem. + * + * Gets a #MMSignal object specifying the LTE signal information. * - * Gets the LTE S/R ratio, in dB. + * <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_get_lte() if on another + * thread.</warning> * - * Returns: %TRUE if @value is valid, %FALSE otherwise. + * Returns: (transfer none) A #MMSignal. Do not free the returned value, it belongs to @self. */ -GETTER(lte_snr) +MMSignal * +mm_modem_signal_peek_lte (MMModemSignal *self) +{ + g_return_val_if_fail (MM_IS_MODEM_SIGNAL (self), NULL); + + ensure_internal (self, NULL, UPDATED_PROPERTY_TYPE_LTE); + return self->priv->values[UPDATED_PROPERTY_TYPE_LTE].info; +} /*****************************************************************************/ static void mm_modem_signal_init (MMModemSignal *self) { + guint i; + + /* Setup private data */ + self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, MM_TYPE_MODEM_SIGNAL, MMModemSignalPrivate); + + for (i = 0; i < UPDATED_PROPERTY_TYPE_LAST; i++) + g_mutex_init (&self->priv->values[i].mutex); +} + +static void +finalize (GObject *object) +{ + MMModemSignal *self = MM_MODEM_SIGNAL (object); + guint i; + + for (i = 0; i < UPDATED_PROPERTY_TYPE_LAST; i++) + g_mutex_clear (&self->priv->values[i].mutex); + + G_OBJECT_CLASS (mm_modem_signal_parent_class)->finalize (object); +} + +static void +dispose (GObject *object) +{ + MMModemSignal *self = MM_MODEM_SIGNAL (object); + guint i; + + for (i = 0; i < UPDATED_PROPERTY_TYPE_LAST; i++) + g_clear_object (&self->priv->values[i].info); + + G_OBJECT_CLASS (mm_modem_signal_parent_class)->dispose (object); } static void mm_modem_signal_class_init (MMModemSignalClass *modem_class) { + GObjectClass *object_class = G_OBJECT_CLASS (modem_class); + + g_type_class_add_private (object_class, sizeof (MMModemSignalPrivate)); + + /* Virtual methods */ + object_class->dispose = dispose; + object_class->finalize = finalize; } diff --git a/libmm-glib/mm-modem-signal.h b/libmm-glib/mm-modem-signal.h index 67bc62cc..ef2c8e1c 100644 --- a/libmm-glib/mm-modem-signal.h +++ b/libmm-glib/mm-modem-signal.h @@ -29,6 +29,7 @@ #include <ModemManager.h> +#include "mm-signal.h" #include "mm-gdbus-modem.h" G_BEGIN_DECLS @@ -42,6 +43,7 @@ G_BEGIN_DECLS typedef struct _MMModemSignal MMModemSignal; typedef struct _MMModemSignalClass MMModemSignalClass; +typedef struct _MMModemSignalPrivate MMModemSignalPrivate; /** * MMModemSignal: @@ -52,7 +54,7 @@ typedef struct _MMModemSignalClass MMModemSignalClass; struct _MMModemSignal { /*< private >*/ MmGdbusModemSignalProxy parent; - gpointer unused; + MMModemSignalPrivate *priv; }; struct _MMModemSignalClass { @@ -79,41 +81,20 @@ gboolean mm_modem_signal_setup_sync (MMModemSignal *self, GCancellable *cancellable, GError **error); -/* CDMA1x */ -gboolean mm_modem_signal_get_cdma_rssi (MMModemSignal *self, - gdouble *value); -gboolean mm_modem_signal_get_cdma_ecio (MMModemSignal *self, - gdouble *value); - -/* EV-DO */ -gboolean mm_modem_signal_get_evdo_rssi (MMModemSignal *self, - gdouble *value); -gboolean mm_modem_signal_get_evdo_ecio (MMModemSignal *self, - gdouble *value); -gboolean mm_modem_signal_get_evdo_sinr (MMModemSignal *self, - gdouble *value); -gboolean mm_modem_signal_get_evdo_io (MMModemSignal *self, - gdouble *value); - -/* GSM */ -gboolean mm_modem_signal_get_gsm_rssi (MMModemSignal *self, - gdouble *value); - -/* UMTS */ -gboolean mm_modem_signal_get_umts_rssi (MMModemSignal *self, - gdouble *value); -gboolean mm_modem_signal_get_umts_ecio (MMModemSignal *self, - gdouble *value); - -/* LTE */ -gboolean mm_modem_signal_get_lte_rssi (MMModemSignal *self, - gdouble *value); -gboolean mm_modem_signal_get_lte_rsrq (MMModemSignal *self, - gdouble *value); -gboolean mm_modem_signal_get_lte_rsrp (MMModemSignal *self, - gdouble *value); -gboolean mm_modem_signal_get_lte_snr (MMModemSignal *self, - gdouble *value); +MMSignal *mm_modem_signal_get_cdma (MMModemSignal *self); +MMSignal *mm_modem_signal_peek_cdma (MMModemSignal *self); + +MMSignal *mm_modem_signal_get_evdo (MMModemSignal *self); +MMSignal *mm_modem_signal_peek_evdo (MMModemSignal *self); + +MMSignal *mm_modem_signal_get_gsm (MMModemSignal *self); +MMSignal *mm_modem_signal_peek_gsm (MMModemSignal *self); + +MMSignal *mm_modem_signal_get_umts (MMModemSignal *self); +MMSignal *mm_modem_signal_peek_umts (MMModemSignal *self); + +MMSignal *mm_modem_signal_get_lte (MMModemSignal *self); +MMSignal *mm_modem_signal_peek_lte (MMModemSignal *self); G_END_DECLS diff --git a/libmm-glib/mm-signal.c b/libmm-glib/mm-signal.c new file mode 100644 index 00000000..b93e0bb4 --- /dev/null +++ b/libmm-glib/mm-signal.c @@ -0,0 +1,442 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details: + * + * Copyright (C) 2013 Aleksander Morgado <aleksander@gnu.org> + */ + +#include <string.h> +#include <ctype.h> +#include <stdlib.h> + +#include "mm-signal.h" +#include "mm-errors-types.h" + +/** + * SECTION: mm-signal + * @title: MMSignal + * @short_description: Helper object to handle extended Signal information. + * + * The #MMSignal is an object handling the signal information of the + * modem. + */ + +G_DEFINE_TYPE (MMSignal, mm_signal, G_TYPE_OBJECT) + +#define PROPERTY_RSSI "rssi" +#define PROPERTY_ECIO "ecio" +#define PROPERTY_SINR "sinr" +#define PROPERTY_IO "io" +#define PROPERTY_RSRQ "rsrq" +#define PROPERTY_RSRP "rsrp" +#define PROPERTY_SNR "snr" + +struct _MMSignalPrivate { + gdouble rssi; + gdouble ecio; + gdouble sinr; + gdouble io; + gdouble rsrq; + gdouble rsrp; + gdouble snr; +}; + +/*****************************************************************************/ + +/** + * mm_signal_get_rssi: + * @self: a #MMSignal. + * + * Gets the RSSI (Received Signal Strength Indication), in dBm. + * + * Returns: the RSSI, or %MM_SIGNAL_UNKNOWN if unknown. + */ +gdouble +mm_signal_get_rssi (MMSignal *self) +{ + g_return_val_if_fail (MM_IS_SIGNAL (self), MM_SIGNAL_UNKNOWN); + + return self->priv->rssi; +} + +void +mm_signal_set_rssi (MMSignal *self, + gdouble value) +{ + g_return_if_fail (MM_IS_SIGNAL (self)); + + self->priv->rssi = value; +} + +/*****************************************************************************/ + +/** + * mm_signal_get_ecio: + * @self: a #MMSignal. + * + * Gets the Ec/Io, in dBm. + * + * Only applicable to CDMA1x, CDMA EV-DO and UMTS (WCDMA). + * + * Returns: the ECIO, or %MM_SIGNAL_UNKNOWN if unknown. + */ +gdouble +mm_signal_get_ecio (MMSignal *self) +{ + g_return_val_if_fail (MM_IS_SIGNAL (self), MM_SIGNAL_UNKNOWN); + + return self->priv->ecio; +} + +void +mm_signal_set_ecio (MMSignal *self, + gdouble value) +{ + g_return_if_fail (MM_IS_SIGNAL (self)); + + self->priv->ecio = value; +} + +/*****************************************************************************/ + +/** + * mm_signal_get_sinr: + * @self: a #MMSignal. + * + * Gets the SINR level, in dB. + * + * Only applicable to CDMA EV-DO. + * + * Returns: the SINR, or %MM_SIGNAL_UNKNOWN if unknown. + */ +gdouble +mm_signal_get_sinr (MMSignal *self) +{ + g_return_val_if_fail (MM_IS_SIGNAL (self), MM_SIGNAL_UNKNOWN); + + return self->priv->sinr; +} + +void +mm_signal_set_sinr (MMSignal *self, + gdouble value) +{ + g_return_if_fail (MM_IS_SIGNAL (self)); + + self->priv->sinr = value; +} + +/*****************************************************************************/ + +/** + * mm_signal_get_io: + * @self: a #MMSignal. + * + * Gets the Io, in dBm. + * + * Only applicable to CDMA EV-DO. + * + * Returns: the Io, or %MM_SIGNAL_UNKNOWN if unknown. + */ +gdouble +mm_signal_get_io (MMSignal *self) +{ + g_return_val_if_fail (MM_IS_SIGNAL (self), MM_SIGNAL_UNKNOWN); + + return self->priv->io; +} + +void +mm_signal_set_io (MMSignal *self, + gdouble value) +{ + g_return_if_fail (MM_IS_SIGNAL (self)); + + self->priv->io = value; +} + +/*****************************************************************************/ + +/** + * mm_signal_get_rsrp: + * @self: a #MMSignal. + * + * Gets the RSRP (Reference Signal Received Power), in dBm. + * + * Only applicable to LTE. + * + * Returns: the RSRP, or %MM_SIGNAL_UNKNOWN if unknown. + */ +gdouble +mm_signal_get_rsrp (MMSignal *self) +{ + g_return_val_if_fail (MM_IS_SIGNAL (self), MM_SIGNAL_UNKNOWN); + + return self->priv->rsrp; +} + +void +mm_signal_set_rsrp (MMSignal *self, + gdouble value) +{ + g_return_if_fail (MM_IS_SIGNAL (self)); + + self->priv->rsrp = value; +} + +/*****************************************************************************/ + +/** + * mm_signal_get_rsrq: + * @self: a #MMSignal. + * + * Gets the RSRQ (Reference Signal Received Quality), in dB. + * + * Only applicable to LTE. + * + * Returns: the RSRQ, or %MM_SIGNAL_UNKNOWN if unknown. + */ +gdouble +mm_signal_get_rsrq (MMSignal *self) +{ + g_return_val_if_fail (MM_IS_SIGNAL (self), MM_SIGNAL_UNKNOWN); + + return self->priv->rsrq; +} + +void +mm_signal_set_rsrq (MMSignal *self, + gdouble value) +{ + g_return_if_fail (MM_IS_SIGNAL (self)); + + self->priv->rsrq = value; +} + +/*****************************************************************************/ + +/** + * mm_signal_get_snr: + * @self: a #MMSignal. + * + * Gets the S/R ration, in dB. + * + * Only applicable to LTE. + * + * Returns: the S/R ratio, or %MM_SIGNAL_UNKNOWN if unknown. + */ +gdouble +mm_signal_get_snr (MMSignal *self) +{ + g_return_val_if_fail (MM_IS_SIGNAL (self), MM_SIGNAL_UNKNOWN); + + return self->priv->snr; +} + +void +mm_signal_set_snr (MMSignal *self, + gdouble value) +{ + g_return_if_fail (MM_IS_SIGNAL (self)); + + self->priv->snr = value; +} + +/*****************************************************************************/ + +/** + * mm_signal_get_dictionary: + * @self: A #MMSignal. + * + * Gets a variant dictionary with the contents of @self. + * + * Returns: (transfer full): A dictionary with the signal values. The returned value should be freed with g_variant_unref(). + */ +GVariant * +mm_signal_get_dictionary (MMSignal *self) +{ + GVariantBuilder builder; + + /* We do allow NULL */ + if (!self) + return NULL; + + g_return_val_if_fail (MM_IS_SIGNAL (self), NULL); + + g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sv}")); + + if (self->priv->rssi != MM_SIGNAL_UNKNOWN) + g_variant_builder_add (&builder, + "{sv}", + PROPERTY_RSSI, + g_variant_new_double (self->priv->rssi)); + + if (self->priv->ecio != MM_SIGNAL_UNKNOWN) + g_variant_builder_add (&builder, + "{sv}", + PROPERTY_ECIO, + g_variant_new_double (self->priv->ecio)); + + if (self->priv->sinr != MM_SIGNAL_UNKNOWN) + g_variant_builder_add (&builder, + "{sv}", + PROPERTY_SINR, + g_variant_new_double (self->priv->sinr)); + + if (self->priv->io != MM_SIGNAL_UNKNOWN) + g_variant_builder_add (&builder, + "{sv}", + PROPERTY_IO, + g_variant_new_double (self->priv->io)); + + if (self->priv->rsrp != MM_SIGNAL_UNKNOWN) + g_variant_builder_add (&builder, + "{sv}", + PROPERTY_RSRP, + g_variant_new_double (self->priv->rsrp)); + + if (self->priv->rsrq != MM_SIGNAL_UNKNOWN) + g_variant_builder_add (&builder, + "{sv}", + PROPERTY_RSRQ, + g_variant_new_double (self->priv->rsrq)); + + if (self->priv->snr != MM_SIGNAL_UNKNOWN) + g_variant_builder_add (&builder, + "{sv}", + PROPERTY_SNR, + g_variant_new_double (self->priv->snr)); + + return g_variant_ref_sink (g_variant_builder_end (&builder)); +} + +/*****************************************************************************/ + +static gboolean +consume_variant (MMSignal *self, + const gchar *key, + GVariant *value, + GError **error) +{ + if (g_str_equal (key, PROPERTY_RSSI)) + self->priv->rssi = g_variant_get_double (value); + else if (g_str_equal (key, PROPERTY_ECIO)) + self->priv->ecio = g_variant_get_double (value); + else if (g_str_equal (key, PROPERTY_SINR)) + self->priv->sinr = g_variant_get_double (value); + else if (g_str_equal (key, PROPERTY_IO)) + self->priv->io = g_variant_get_double (value); + else if (g_str_equal (key, PROPERTY_RSRP)) + self->priv->rsrp = g_variant_get_double (value); + else if (g_str_equal (key, PROPERTY_RSRQ)) + self->priv->rsrq = g_variant_get_double (value); + else if (g_str_equal (key, PROPERTY_SNR)) + self->priv->snr = g_variant_get_double (value); + else { + /* Set error */ + g_set_error (error, + MM_CORE_ERROR, + MM_CORE_ERROR_INVALID_ARGS, + "Invalid signal dictionary, unexpected key '%s'", + key); + return FALSE; + } + + return TRUE; +} + +/** + * mm_signal_new_from_dictionary: + * @dictionary: A variant dictionary with the signal information. + * @error: Return location for error or %NULL. + * + * Creates a new #MMSignal object with the values exposed in + * the dictionary. + * + * Returns: (transfer full): A #MMSignal or %NULL if @error is set. The returned value should be freed with g_object_unref(). + */ +MMSignal * +mm_signal_new_from_dictionary (GVariant *dictionary, + GError **error) +{ + GError *inner_error = NULL; + GVariantIter iter; + gchar *key; + GVariant *value; + MMSignal *self; + + if (!dictionary) { + g_set_error (error, + MM_CORE_ERROR, + MM_CORE_ERROR_INVALID_ARGS, + "Cannot create Signal info from empty dictionary"); + return NULL; + } + + if (!g_variant_is_of_type (dictionary, G_VARIANT_TYPE ("a{sv}"))) { + g_set_error (error, + MM_CORE_ERROR, + MM_CORE_ERROR_INVALID_ARGS, + "Cannot create Signal info from dictionary: " + "invalid variant type received"); + return NULL; + } + + self = mm_signal_new (); + g_variant_iter_init (&iter, dictionary); + while (!inner_error && + g_variant_iter_next (&iter, "{sv}", &key, &value)) { + consume_variant (self, + key, + value, + &inner_error); + g_free (key); + g_variant_unref (value); + } + + /* If error, destroy the object */ + if (inner_error) { + g_propagate_error (error, inner_error); + g_object_unref (self); + return NULL; + } + + return self; +} + +/*****************************************************************************/ + +MMSignal * +mm_signal_new (void) +{ + return MM_SIGNAL (g_object_new (MM_TYPE_SIGNAL, NULL)); +} + +static void +mm_signal_init (MMSignal *self) +{ + self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, MM_TYPE_SIGNAL, MMSignalPrivate); + self->priv->rssi = MM_SIGNAL_UNKNOWN; + self->priv->ecio = MM_SIGNAL_UNKNOWN; + self->priv->sinr = MM_SIGNAL_UNKNOWN; + self->priv->io = MM_SIGNAL_UNKNOWN; + self->priv->rsrq = MM_SIGNAL_UNKNOWN; + self->priv->rsrp = MM_SIGNAL_UNKNOWN; + self->priv->snr = MM_SIGNAL_UNKNOWN; +} + +static void +mm_signal_class_init (MMSignalClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + g_type_class_add_private (object_class, sizeof (MMSignalPrivate)); +} diff --git a/libmm-glib/mm-signal.h b/libmm-glib/mm-signal.h new file mode 100644 index 00000000..47391f0e --- /dev/null +++ b/libmm-glib/mm-signal.h @@ -0,0 +1,98 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details: + * + * Copyright (C) 2013 Aleksander Morgado <aleksander@gnu.org> + */ + +#ifndef MM_SIGNAL_H +#define MM_SIGNAL_H + +#if !defined (__LIBMM_GLIB_H_INSIDE__) && !defined (LIBMM_GLIB_COMPILATION) +#error "Only <libmm-glib.h> can be included directly." +#endif + +#include <ModemManager.h> +#include <glib-object.h> + +G_BEGIN_DECLS + +/** + * MM_SIGNAL_UNKNOWN: + * + * Identifier for an unknown signal value. + */ +#define MM_SIGNAL_UNKNOWN G_MINDOUBLE + +#define MM_TYPE_SIGNAL (mm_signal_get_type ()) +#define MM_SIGNAL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MM_TYPE_SIGNAL, MMSignal)) +#define MM_SIGNAL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), MM_TYPE_SIGNAL, MMSignalClass)) +#define MM_IS_SIGNAL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MM_TYPE_SIGNAL)) +#define MM_IS_SIGNAL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), MM_TYPE_SIGNAL)) +#define MM_SIGNAL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), MM_TYPE_SIGNAL, MMSignalClass)) + +typedef struct _MMSignal MMSignal; +typedef struct _MMSignalClass MMSignalClass; +typedef struct _MMSignalPrivate MMSignalPrivate; + +/** + * MMSignal: + * + * The #MMSignal structure contains private data and should + * only be accessed using the provided API. + */ +struct _MMSignal { + /*< private >*/ + GObject parent; + MMSignalPrivate *priv; +}; + +struct _MMSignalClass { + /*< private >*/ + GObjectClass parent; +}; + +GType mm_signal_get_type (void); + +gdouble mm_signal_get_rssi (MMSignal *self); +gdouble mm_signal_get_ecio (MMSignal *self); +gdouble mm_signal_get_sinr (MMSignal *self); +gdouble mm_signal_get_io (MMSignal *self); +gdouble mm_signal_get_rsrq (MMSignal *self); +gdouble mm_signal_get_rsrp (MMSignal *self); +gdouble mm_signal_get_snr (MMSignal *self); + +/*****************************************************************************/ +/* ModemManager/libmm-glib/mmcli specific methods */ + +#if defined (_LIBMM_INSIDE_MM) || \ + defined (_LIBMM_INSIDE_MMCLI) || \ + defined (LIBMM_GLIB_COMPILATION) + +GVariant *mm_signal_get_dictionary (MMSignal *self); + +MMSignal *mm_signal_new (void); +MMSignal *mm_signal_new_from_dictionary (GVariant *dictionary, + GError **error); + +void mm_signal_set_rssi (MMSignal *self, gdouble value); +void mm_signal_set_ecio (MMSignal *self, gdouble value); +void mm_signal_set_sinr (MMSignal *self, gdouble value); +void mm_signal_set_io (MMSignal *self, gdouble value); +void mm_signal_set_rsrq (MMSignal *self, gdouble value); +void mm_signal_set_rsrp (MMSignal *self, gdouble value); +void mm_signal_set_snr (MMSignal *self, gdouble value); + +#endif + +G_END_DECLS + +#endif /* MM_SIGNAL_H */ diff --git a/src/mm-iface-modem-signal.c b/src/mm-iface-modem-signal.c index 7425d32e..bd415efe 100644 --- a/src/mm-iface-modem-signal.c +++ b/src/mm-iface-modem-signal.c @@ -59,19 +59,11 @@ clear_values (MMIfaceModemSignal *self) if (!skeleton) return; - mm_gdbus_modem_signal_set_cdma_rssi (skeleton, g_variant_new ("(bd)", FALSE, 0.0)); - mm_gdbus_modem_signal_set_cdma_ecio (skeleton, g_variant_new ("(bd)", FALSE, 0.0)); - mm_gdbus_modem_signal_set_evdo_rssi (skeleton, g_variant_new ("(bd)", FALSE, 0.0)); - mm_gdbus_modem_signal_set_evdo_ecio (skeleton, g_variant_new ("(bd)", FALSE, 0.0)); - mm_gdbus_modem_signal_set_evdo_sinr (skeleton, g_variant_new ("(bd)", FALSE, 0.0)); - mm_gdbus_modem_signal_set_evdo_io (skeleton, g_variant_new ("(bd)", FALSE, 0.0)); - mm_gdbus_modem_signal_set_gsm_rssi (skeleton, g_variant_new ("(bd)", FALSE, 0.0)); - mm_gdbus_modem_signal_set_umts_rssi (skeleton, g_variant_new ("(bd)", FALSE, 0.0)); - mm_gdbus_modem_signal_set_umts_ecio (skeleton, g_variant_new ("(bd)", FALSE, 0.0)); - mm_gdbus_modem_signal_set_lte_rssi (skeleton, g_variant_new ("(bd)", FALSE, 0.0)); - mm_gdbus_modem_signal_set_lte_rsrq (skeleton, g_variant_new ("(bd)", FALSE, 0.0)); - mm_gdbus_modem_signal_set_lte_rsrp (skeleton, g_variant_new ("(bd)", FALSE, 0.0)); - mm_gdbus_modem_signal_set_lte_snr (skeleton, g_variant_new ("(bd)", FALSE, 0.0)); + mm_gdbus_modem_signal_set_cdma (skeleton, NULL); + mm_gdbus_modem_signal_set_evdo (skeleton, NULL); + mm_gdbus_modem_signal_set_gsm (skeleton, NULL); + mm_gdbus_modem_signal_set_umts (skeleton, NULL); + mm_gdbus_modem_signal_set_lte (skeleton, NULL); g_object_unref (skeleton); } @@ -79,6 +71,8 @@ static void load_values_ready (MMIfaceModemSignal *self, GAsyncResult *res) { + MMSignal *info; + GVariant *dictionary; GError *error = NULL; gboolean cdma_available; gdouble cdma_rssi; @@ -137,19 +131,59 @@ load_values_ready (MMIfaceModemSignal *self, return; } - mm_gdbus_modem_signal_set_cdma_rssi (skeleton, g_variant_new ("(bd)", cdma_available, cdma_rssi)); - mm_gdbus_modem_signal_set_cdma_ecio (skeleton, g_variant_new ("(bd)", cdma_available, cdma_ecio)); - mm_gdbus_modem_signal_set_evdo_rssi (skeleton, g_variant_new ("(bd)", evdo_available, evdo_rssi)); - mm_gdbus_modem_signal_set_evdo_ecio (skeleton, g_variant_new ("(bd)", evdo_available, evdo_ecio)); - mm_gdbus_modem_signal_set_evdo_sinr (skeleton, g_variant_new ("(bd)", evdo_available, evdo_sinr)); - mm_gdbus_modem_signal_set_evdo_io (skeleton, g_variant_new ("(bd)", evdo_available, evdo_io)); - mm_gdbus_modem_signal_set_gsm_rssi (skeleton, g_variant_new ("(bd)", gsm_available, gsm_rssi)); - mm_gdbus_modem_signal_set_umts_rssi (skeleton, g_variant_new ("(bd)", umts_available, umts_rssi)); - mm_gdbus_modem_signal_set_umts_ecio (skeleton, g_variant_new ("(bd)", umts_available, umts_ecio)); - mm_gdbus_modem_signal_set_lte_rssi (skeleton, g_variant_new ("(bd)", lte_available, lte_rssi)); - mm_gdbus_modem_signal_set_lte_rsrq (skeleton, g_variant_new ("(bd)", lte_available, lte_rsrq)); - mm_gdbus_modem_signal_set_lte_rsrp (skeleton, g_variant_new ("(bd)", lte_available,lte_rsrp)); - mm_gdbus_modem_signal_set_lte_snr (skeleton, g_variant_new ("(bd)", lte_available, lte_snr)); + if (cdma_available) { + info = mm_signal_new (); + mm_signal_set_rssi (info, cdma_rssi); + mm_signal_set_ecio (info, cdma_ecio); + dictionary = mm_signal_get_dictionary (info); + mm_gdbus_modem_signal_set_cdma (skeleton, dictionary); + g_variant_unref (dictionary); + g_object_unref (info); + } + + if (evdo_available) { + info = mm_signal_new (); + mm_signal_set_rssi (info, evdo_rssi); + mm_signal_set_ecio (info, evdo_ecio); + mm_signal_set_sinr (info, evdo_sinr); + mm_signal_set_io (info, evdo_io); + dictionary = mm_signal_get_dictionary (info); + mm_gdbus_modem_signal_set_evdo (skeleton, dictionary); + g_variant_unref (dictionary); + g_object_unref (info); + } + + if (gsm_available) { + info = mm_signal_new (); + mm_signal_set_rssi (info, gsm_rssi); + dictionary = mm_signal_get_dictionary (info); + mm_gdbus_modem_signal_set_gsm (skeleton, dictionary); + g_variant_unref (dictionary); + g_object_unref (info); + } + + if (umts_available) { + info = mm_signal_new (); + mm_signal_set_rssi (info, umts_rssi); + mm_signal_set_ecio (info, umts_ecio); + dictionary = mm_signal_get_dictionary (info); + mm_gdbus_modem_signal_set_umts (skeleton, dictionary); + g_variant_unref (dictionary); + g_object_unref (info); + } + + if (lte_available) { + info = mm_signal_new (); + mm_signal_set_rssi (info, lte_rssi); + mm_signal_set_rsrq (info, lte_rsrq); + mm_signal_set_rsrp (info, lte_rsrp); + mm_signal_set_snr (info, lte_snr); + dictionary = mm_signal_get_dictionary (info); + mm_gdbus_modem_signal_set_lte (skeleton, dictionary); + g_variant_unref (dictionary); + g_object_unref (info); + } + /* Flush right away */ g_dbus_interface_skeleton_flush (G_DBUS_INTERFACE_SKELETON (skeleton)); |