api,introspection: use per-technology dictionaries in the 'Signal' interface

This commit is contained in:
Aleksander Morgado
2013-07-18 08:27:20 +02:00
parent e8ce650ed0
commit 0502646f9f
12 changed files with 1244 additions and 386 deletions

View File

@@ -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

View File

@@ -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>

View File

@@ -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
@@ -799,6 +797,42 @@ MM_TYPE_MODEM_SIGNAL
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>
@@ -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

View File

@@ -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

View File

@@ -35,121 +35,178 @@
<property name="Rate" type="u" access="read" />
<!--
CdmaRssi:
Cdma:
CDMA1x RSSI (Received Signal Strength Indication), in dBm.
Dictionary of available signal information for the CDMA1x access
technology.
The boolean flag indicates whether the value is valid.
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="CdmaRssi" type="(bd)" access="read" />
<property name="Cdma" type="a{sv}" access="read" />
<!--
CdmaEcio:
Evdo:
CDMA1x Ec/Io, in dBm.
Dictionary of available signal information for the CDMA EV-DO access
technology.
The boolean flag indicates whether the value is valid.
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="CdmaEcio" type="(bd)" access="read" />
<property name="Evdo" type="a{sv}" access="read" />
<!--
EvdoRssi:
Gsm:
CDMA EV-DO RSSI (Received Signal Strength Indication), in dBm.
Dictionary of available signal information for the GSM/GPRS access
technology.
The boolean flag indicates whether the value is valid.
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="EvdoRssi" type="(bd)" access="read" />
<property name="Gsm" type="a{sv}" access="read" />
<!--
EvdoEcio:
Umts:
CDMA EV-DO Ec/Io, in dBm.
Dictionary of available signal information for the UMTS (WCDMA) access
technology.
The boolean flag indicates whether the value is valid.
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="EvdoEcio" type="(bd)" access="read" />
<property name="Umts" type="a{sv}" access="read" />
<!--
EvdoSinr:
Lte:
CDMA EV-DO SINR level, in dB.
Dictionary of available signal information for the UMTS (WCDMA) access
technology.
The boolean flag indicates whether the value is valid.
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="EvdoSinr" type="(bd)" access="read" />
<!--
EvdoIo:
CDMA EV-DO IO, in dBm.
The boolean flag indicates whether the value is valid.
-->
<property name="EvdoIo" type="(bd)" access="read" />
<!--
GsmRssi:
GSM RSSI (Received Signal Strength Indication), in dBm.
The boolean flag indicates whether the value is valid.
-->
<property name="GsmRssi" type="(bd)" access="read" />
<!--
UmtsRssi:
UMTS (WCDMA) RSSI (Received Signal Strength Indication), in dBm.
The boolean flag indicates whether the value is valid.
-->
<property name="UmtsRssi" type="(bd)" 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.
-->
<property name="LteRssi" type="(bd)" 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.
-->
<property name="LteSnr" type="(bd)" access="read" />
<property name="Lte" type="a{sv}" access="read" />
</interface>
</node>

View File

@@ -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 =

View File

@@ -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>

View File

@@ -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];
};
/*****************************************************************************/
/**
@@ -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);
}
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);
}
/**
* 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)
/* 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.
* mm_modem_get_cdma:
* @self: A #MMModem.
*
* Gets the CDMA1x Ec/Io, in dBm.
* Gets a #MMSignal object specifying the CDMA 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_cdma() 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(cdma_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_rssi:
* @self: A #MMModemSignal.
* @value: (out): Return location for the value.
* mm_modem_peek_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.
* <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_rssi)
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_ecio:
* @self: A #MMModemSignal.
* @value: (out): Return location for the value.
* mm_modem_get_evdo:
* @self: A #MMModem.
*
* Gets the CDMA EV-DO Ec/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_ecio)
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_evdo_sinr:
* @self: A #MMModemSignal.
* @value: (out): Return location for the value.
* mm_modem_peek_evdo:
* @self: A #MMModem.
*
* Gets the CDMA EV-DO SINR level, in dB.
* Gets a #MMSignal object specifying the EV-DO 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_evdo() 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_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_evdo_io:
* @self: A #MMModemSignal.
* @value: (out): Return location for the value.
* mm_modem_get_gsm:
* @self: A #MMModem.
*
* Gets the CDMA EV-DO IO, 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(evdo_io)
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_gsm_rssi:
* @self: A #MMModemSignal.
* @value: (out): Return location for the value.
* mm_modem_peek_gsm:
* @self: A #MMModem.
*
* Gets the GSM 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 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: (transfer none) A #MMSignal. Do not free the returned value, it belongs to @self.
*/
GETTER(gsm_rssi)
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_umts_rssi:
* @self: A #MMModemSignal.
* @value: (out): Return location for the value.
* mm_modem_get_umts:
* @self: A #MMModem.
*
* Gets the UMTS (WCDMA) 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(umts_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_umts_ecio:
* @self: A #MMModemSignal.
* @value: (out): Return location for the value.
* mm_modem_peek_umts:
* @self: A #MMModem.
*
* Gets the UMTS (WCDMA) Ec/Io, in dBm.
* Gets a #MMSignal object specifying the UMTS 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_umts() if on another
* thread.</warning>
*
* Returns: (transfer none) A #MMSignal. Do not free the returned value, it belongs to @self.
*/
GETTER(umts_ecio)
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_rssi:
* @self: A #MMModemSignal.
* @value: (out): Return location for the value.
* mm_modem_get_lte:
* @self: A #MMModem.
*
* Gets the LTE RSSI (Received Signal Strength Indication), 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_rssi)
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_rsrq:
* @self: A #MMModemSignal.
* @value: (out): Return location for the value.
* mm_modem_peek_lte:
* @self: A #MMModem.
*
* Gets the LTE RSRQ (Reference Signal Received Quality), in dB.
* Gets a #MMSignal object specifying the LTE 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_lte() if on another
* thread.</warning>
*
* Returns: (transfer none) A #MMSignal. Do not free the returned value, it belongs to @self.
*/
GETTER(lte_rsrq)
MMSignal *
mm_modem_signal_peek_lte (MMModemSignal *self)
{
g_return_val_if_fail (MM_IS_MODEM_SIGNAL (self), NULL);
/**
* mm_modem_get_lte_rsrp:
* @self: A #MMModemSignal.
* @value: (out): Return location for the value.
*
* Gets the LTE RSRP (Reference Signal Received Power), in dBm.
*
* Returns: %TRUE if @value is valid, %FALSE otherwise.
*/
GETTER(lte_rsrp)
/**
* mm_modem_get_lte_snr:
* @self: A #MMModemSignal.
* @value: (out): Return location for the value.
*
* Gets the LTE S/R ratio, in dB.
*
* Returns: %TRUE if @value is valid, %FALSE otherwise.
*/
GETTER(lte_snr)
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;
}

View File

@@ -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);
MMSignal *mm_modem_signal_get_cdma (MMModemSignal *self);
MMSignal *mm_modem_signal_peek_cdma (MMModemSignal *self);
/* 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);
MMSignal *mm_modem_signal_get_evdo (MMModemSignal *self);
MMSignal *mm_modem_signal_peek_evdo (MMModemSignal *self);
/* GSM */
gboolean mm_modem_signal_get_gsm_rssi (MMModemSignal *self,
gdouble *value);
MMSignal *mm_modem_signal_get_gsm (MMModemSignal *self);
MMSignal *mm_modem_signal_peek_gsm (MMModemSignal *self);
/* UMTS */
gboolean mm_modem_signal_get_umts_rssi (MMModemSignal *self,
gdouble *value);
gboolean mm_modem_signal_get_umts_ecio (MMModemSignal *self,
gdouble *value);
MMSignal *mm_modem_signal_get_umts (MMModemSignal *self);
MMSignal *mm_modem_signal_peek_umts (MMModemSignal *self);
/* 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_lte (MMModemSignal *self);
MMSignal *mm_modem_signal_peek_lte (MMModemSignal *self);
G_END_DECLS

442
libmm-glib/mm-signal.c Normal file
View File

@@ -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));
}

98
libmm-glib/mm-signal.h Normal file
View File

@@ -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 */

View File

@@ -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));