diff options
author | Aleksander Morgado <aleksander@aleksander.es> | 2021-10-14 12:48:29 +0200 |
---|---|---|
committer | Aleksander Morgado <aleksander@aleksander.es> | 2021-10-20 22:14:57 +0200 |
commit | e8c4b884931db166265aea514afbbe39075899ad (patch) | |
tree | 32c552bdfae2b1689aff5b65db87a0cfd22f79f5 | |
parent | f27d7f9362a0291ff64e97f70ae70a11b74a906c (diff) |
libmm-glib: new 'MMSignalThresholdProperties' helper object
To avoid needing to work with GVariants directly.
-rw-r--r-- | cli/mmcli-modem-signal.c | 88 | ||||
-rw-r--r-- | docs/reference/libmm-glib/libmm-glib-docs.xml | 1 | ||||
-rw-r--r-- | docs/reference/libmm-glib/libmm-glib-sections.txt | 27 | ||||
-rw-r--r-- | libmm-glib/Makefile.am | 3 | ||||
-rw-r--r-- | libmm-glib/libmm-glib.h | 1 | ||||
-rw-r--r-- | libmm-glib/meson.build | 2 | ||||
-rw-r--r-- | libmm-glib/mm-modem-signal.c | 32 | ||||
-rw-r--r-- | libmm-glib/mm-modem-signal.h | 49 | ||||
-rw-r--r-- | libmm-glib/mm-signal-threshold-properties.c | 322 | ||||
-rw-r--r-- | libmm-glib/mm-signal-threshold-properties.h | 86 | ||||
-rw-r--r-- | src/mm-iface-modem-signal.c | 62 |
11 files changed, 513 insertions, 160 deletions
diff --git a/cli/mmcli-modem-signal.c b/cli/mmcli-modem-signal.c index 5237938a..7d1e2ff6 100644 --- a/cli/mmcli-modem-signal.c +++ b/cli/mmcli-modem-signal.c @@ -274,71 +274,6 @@ print_signal_info (void) mmcli_output_dump (); } -typedef struct { - guint rssi_threshold; - gboolean rssi_set; - gboolean error_rate_threshold; - gboolean error_rate_set; - GError *error; -} ParseKeyValueContext; - -static gboolean -key_value_foreach (const gchar *key, - const gchar *value, - ParseKeyValueContext *parse_ctx) -{ - if (g_str_equal (key, "rssi-threshold")) { - if (!mm_get_uint_from_str (value, &parse_ctx->rssi_threshold)) { - g_set_error (&parse_ctx->error, MM_CORE_ERROR, MM_CORE_ERROR_INVALID_ARGS, - "invalid RSSI threshold value given: %s", value); - return FALSE; - } - parse_ctx->rssi_set = TRUE; - } else if (g_str_equal (key, "error-rate-threshold")) { - parse_ctx->error_rate_threshold = mm_common_get_boolean_from_string (value, &parse_ctx->error); - if (parse_ctx->error) - return FALSE; - parse_ctx->error_rate_set = TRUE; - } else { - g_set_error (&parse_ctx->error, MM_CORE_ERROR, MM_CORE_ERROR_UNSUPPORTED, - "Invalid properties string, unsupported key '%s'", key); - return FALSE; - } - return TRUE; -} - -static GVariant * -setup_thresholds_build_input (const gchar *str) -{ - ParseKeyValueContext parse_ctx = { 0 }; - GVariantBuilder builder; - - mm_common_parse_key_value_string (setup_thresholds_str, - &parse_ctx.error, - (MMParseKeyValueForeachFn)key_value_foreach, - &parse_ctx); - /* If error, destroy the object */ - if (parse_ctx.error) { - return NULL; - } - - g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sv}")); - - if (parse_ctx.rssi_set) - g_variant_builder_add (&builder, - "{sv}", - "rssi-threshold", - g_variant_new_uint32 (parse_ctx.rssi_threshold)); - - if (parse_ctx.error_rate_set) - g_variant_builder_add (&builder, - "{sv}", - "error-rate-threshold", - g_variant_new_boolean (parse_ctx.error_rate_threshold)); - - return g_variant_ref_sink (g_variant_builder_end (&builder)); -} - static void setup_thresholds_process_reply (gboolean result, const GError *error) @@ -427,17 +362,18 @@ get_modem_ready (GObject *source, /* Request to setup threshold? */ if (setup_thresholds_str) { - g_autoptr(GVariant) dictionary = NULL; + g_autoptr(MMSignalThresholdProperties) properties = NULL; + g_autoptr(GError) error = NULL; - dictionary = setup_thresholds_build_input (setup_thresholds_str); - if (!dictionary) { - g_printerr ("error: failed to parse input threshold setup settings: '%s'", setup_thresholds_str); + properties = mm_signal_threshold_properties_new_from_string (setup_thresholds_str, &error); + if (!properties) { + g_printerr ("error: failed to parse properties string: '%s'\n", error->message); exit (EXIT_FAILURE); } g_debug ("Asynchronously setting up threshold values..."); mm_modem_signal_setup_thresholds (ctx->modem_signal, - dictionary, + properties, ctx->cancellable, (GAsyncReadyCallback)setup_thresholds_ready, NULL); @@ -509,18 +445,18 @@ mmcli_modem_signal_run_synchronous (GDBusConnection *connection) /* Request to setup threshold? */ if (setup_thresholds_str) { - g_autoptr(GVariant) dictionary = NULL; - gboolean result; + g_autoptr(MMSignalThresholdProperties) properties = NULL; + gboolean result; - dictionary = setup_thresholds_build_input (setup_thresholds_str); - if (!dictionary) { - g_printerr ("error: failed to parse input threshold setup settings: '%s'", setup_thresholds_str); + properties = mm_signal_threshold_properties_new_from_string (setup_thresholds_str, &error); + if (!properties) { + g_printerr ("error: failed to parse properties string: '%s'\n", error->message); exit (EXIT_FAILURE); } g_debug ("Asynchronously setting up threshold values..."); result = mm_modem_signal_setup_thresholds_sync (ctx->modem_signal, - dictionary, + properties, NULL, &error); setup_thresholds_process_reply (result, error); diff --git a/docs/reference/libmm-glib/libmm-glib-docs.xml b/docs/reference/libmm-glib/libmm-glib-docs.xml index 92e105f0..9953d552 100644 --- a/docs/reference/libmm-glib/libmm-glib-docs.xml +++ b/docs/reference/libmm-glib/libmm-glib-docs.xml @@ -135,6 +135,7 @@ <title>Extended signal information</title> <xi:include href="xml/mm-modem-signal.xml"/> <xi:include href="xml/mm-signal.xml"/> + <xi:include href="xml/mm-signal-threshold-properties.xml"/> </section> <section> <title>OMA support</title> diff --git a/docs/reference/libmm-glib/libmm-glib-sections.txt b/docs/reference/libmm-glib/libmm-glib-sections.txt index 3bd7fd8f..a4569784 100644 --- a/docs/reference/libmm-glib/libmm-glib-sections.txt +++ b/docs/reference/libmm-glib/libmm-glib-sections.txt @@ -1061,6 +1061,33 @@ mm_signal_get_type </SECTION> <SECTION> +<FILE>mm-signal-threshold-properties</FILE> +<TITLE>MMSignalThresholdProperties</TITLE> +MMSignalThresholdProperties +<SUBSECTION New> +mm_signal_threshold_properties_new +<SUBSECTION GettersSetters> +mm_signal_threshold_properties_get_rssi +mm_signal_threshold_properties_set_rssi +mm_signal_threshold_properties_get_error_rate +mm_signal_threshold_properties_set_error_rate +<SUBSECTION Private> +mm_signal_threshold_properties_new_from_dictionary +mm_signal_threshold_properties_new_from_string +mm_signal_threshold_properties_get_dictionary +<SUBSECTION Standard> +MMSignalThresholdPropertiesClass +MMSignalThresholdPropertiesPrivate +MM_SIGNAL_THRESHOLD_PROPERTIES +MM_SIGNAL_THRESHOLD_PROPERTIES_CLASS +MM_SIGNAL_THRESHOLD_PROPERTIES_GET_CLASS +MM_IS_SIGNAL_THRESHOLD_PROPERTIES +MM_IS_SIGNAL_THRESHOLD_PROPERTIES_CLASS +MM_TYPE_SIGNAL_THRESHOLD_PROPERTIES +mm_signal_threshold_properties_get_type +</SECTION> + +<SECTION> <FILE>mm-modem-voice</FILE> <TITLE>MMModemVoice</TITLE> MMModemVoice diff --git a/libmm-glib/Makefile.am b/libmm-glib/Makefile.am index 77f69e19..7084f294 100644 --- a/libmm-glib/Makefile.am +++ b/libmm-glib/Makefile.am @@ -97,6 +97,8 @@ libmm_glib_la_SOURCES = \ mm-sim-preferred-network.c \ mm-3gpp-profile.h \ mm-3gpp-profile.c \ + mm-signal-threshold-properties.h \ + mm-signal-threshold-properties.c \ mm-compat.h \ mm-compat.c \ $(NULL) @@ -174,6 +176,7 @@ include_HEADERS = \ mm-call-audio-format.h \ mm-sim-preferred-network.h \ mm-3gpp-profile.h \ + mm-signal-threshold-properties.h \ mm-compat.h \ $(NULL) diff --git a/libmm-glib/libmm-glib.h b/libmm-glib/libmm-glib.h index 4366ca42..e8b98ed8 100644 --- a/libmm-glib/libmm-glib.h +++ b/libmm-glib/libmm-glib.h @@ -84,6 +84,7 @@ #include <mm-pco.h> #include <mm-sim-preferred-network.h> #include <mm-3gpp-profile.h> +#include <mm-signal-threshold-properties.h> #include <mm-compat.h> /* generated */ diff --git a/libmm-glib/meson.build b/libmm-glib/meson.build index c43c44e8..e2641d2c 100644 --- a/libmm-glib/meson.build +++ b/libmm-glib/meson.build @@ -45,6 +45,7 @@ headers = files( 'mm-object.h', 'mm-pco.h', 'mm-signal.h', + 'mm-signal-threshold-properties.h', 'mm-sim.h', 'mm-simple-connect-properties.h', 'mm-simple-status.h', @@ -98,6 +99,7 @@ sources = files( 'mm-object.c', 'mm-pco.c', 'mm-signal.c', + 'mm-signal-threshold-properties.c', 'mm-sim.c', 'mm-simple-connect-properties.c', 'mm-simple-status.c', diff --git a/libmm-glib/mm-modem-signal.c b/libmm-glib/mm-modem-signal.c index b864c8ff..c94a3eb6 100644 --- a/libmm-glib/mm-modem-signal.c +++ b/libmm-glib/mm-modem-signal.c @@ -216,7 +216,7 @@ mm_modem_signal_setup_thresholds_finish (MMModemSignal *self, /** * mm_modem_signal_setup_thresholds: * @self: A #MMModemSignal. - * @settings: Threshold values to set. + * @properties: Threshold values to set. * @cancellable: (allow-none): A #GCancellable or %NULL. * @callback: A #GAsyncReadyCallback to call when the request is satisfied or * %NULL. @@ -236,21 +236,24 @@ mm_modem_signal_setup_thresholds_finish (MMModemSignal *self, * Since: 1.20 */ void -mm_modem_signal_setup_thresholds (MMModemSignal *self, - GVariant *settings, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data) +mm_modem_signal_setup_thresholds (MMModemSignal *self, + MMSignalThresholdProperties *properties, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) { + g_autoptr(GVariant) dictionary = NULL; + g_return_if_fail (MM_IS_MODEM_SIGNAL (self)); - mm_gdbus_modem_signal_call_setup_thresholds (MM_GDBUS_MODEM_SIGNAL (self), settings, cancellable, callback, user_data); + dictionary = mm_signal_threshold_properties_get_dictionary (properties); + mm_gdbus_modem_signal_call_setup_thresholds (MM_GDBUS_MODEM_SIGNAL (self), dictionary, cancellable, callback, user_data); } /** * mm_modem_signal_setup_thresholds_sync: * @self: A #MMModemSignal. - * @settings: Threshold values to set. + * @properties: Threshold values to set. * @cancellable: (allow-none): A #GCancellable or %NULL. * @error: Return location for error or %NULL. * @@ -265,14 +268,17 @@ mm_modem_signal_setup_thresholds (MMModemSignal *self, * Since: 1.20 */ gboolean -mm_modem_signal_setup_thresholds_sync (MMModemSignal *self, - GVariant *settings, - GCancellable *cancellable, - GError **error) +mm_modem_signal_setup_thresholds_sync (MMModemSignal *self, + MMSignalThresholdProperties *properties, + GCancellable *cancellable, + GError **error) { + g_autoptr(GVariant) dictionary = NULL; + g_return_val_if_fail (MM_IS_MODEM_SIGNAL (self), FALSE); - return mm_gdbus_modem_signal_call_setup_thresholds_sync (MM_GDBUS_MODEM_SIGNAL (self), settings, cancellable, error); + dictionary = mm_signal_threshold_properties_get_dictionary (properties); + return mm_gdbus_modem_signal_call_setup_thresholds_sync (MM_GDBUS_MODEM_SIGNAL (self), dictionary, cancellable, error); } /*****************************************************************************/ diff --git a/libmm-glib/mm-modem-signal.h b/libmm-glib/mm-modem-signal.h index 8c859a96..d494b06a 100644 --- a/libmm-glib/mm-modem-signal.h +++ b/libmm-glib/mm-modem-signal.h @@ -31,6 +31,7 @@ #include <ModemManager.h> #include "mm-signal.h" +#include "mm-signal-threshold-properties.h" #include "mm-gdbus-modem.h" G_BEGIN_DECLS @@ -72,30 +73,30 @@ guint mm_modem_signal_get_rate (MMModemSignal *self); guint mm_modem_signal_get_rssi_threshold (MMModemSignal *self); gboolean mm_modem_signal_get_error_rate_threshold (MMModemSignal *self); -void mm_modem_signal_setup (MMModemSignal *self, - guint rate, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data); -gboolean mm_modem_signal_setup_finish (MMModemSignal *self, - GAsyncResult *res, - GError **error); -gboolean mm_modem_signal_setup_sync (MMModemSignal *self, - guint rate, - GCancellable *cancellable, - GError **error); -void mm_modem_signal_setup_thresholds (MMModemSignal *self, - GVariant *settings, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data); -gboolean mm_modem_signal_setup_thresholds_finish (MMModemSignal *self, - GAsyncResult *res, - GError **error); -gboolean mm_modem_signal_setup_thresholds_sync (MMModemSignal *self, - GVariant *settings, - GCancellable *cancellable, - GError **error); +void mm_modem_signal_setup (MMModemSignal *self, + guint rate, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +gboolean mm_modem_signal_setup_finish (MMModemSignal *self, + GAsyncResult *res, + GError **error); +gboolean mm_modem_signal_setup_sync (MMModemSignal *self, + guint rate, + GCancellable *cancellable, + GError **error); +void mm_modem_signal_setup_thresholds (MMModemSignal *self, + MMSignalThresholdProperties *properties, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +gboolean mm_modem_signal_setup_thresholds_finish (MMModemSignal *self, + GAsyncResult *res, + GError **error); +gboolean mm_modem_signal_setup_thresholds_sync (MMModemSignal *self, + MMSignalThresholdProperties *properties, + GCancellable *cancellable, + GError **error); MMSignal *mm_modem_signal_get_cdma (MMModemSignal *self); MMSignal *mm_modem_signal_peek_cdma (MMModemSignal *self); diff --git a/libmm-glib/mm-signal-threshold-properties.c b/libmm-glib/mm-signal-threshold-properties.c new file mode 100644 index 00000000..48a55b81 --- /dev/null +++ b/libmm-glib/mm-signal-threshold-properties.c @@ -0,0 +1,322 @@ +/* -*- 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) 2021 Aleksander Morgado <aleksander@aleksander.es> + * Copyright (C) 2021 Intel Corporation + */ + +#include <string.h> + +#include "mm-errors-types.h" +#include "mm-common-helpers.h" +#include "mm-signal-threshold-properties.h" + +/** + * SECTION: mm-signal-threshold-properties + * @title: MMSignalThresholdProperties + * @short_description: Helper object to handle signal threshold properties. + * + * The #MMSignalThresholdProperties is an object handling the properties requested + * when setting up threshold based signal quality information reporting. + * + * This object is created by the user and passed to ModemManager with either + * mm_modem_signal_setup_thresholds() or mm_modem_signal_setup_thresholds_sync(). + */ + +G_DEFINE_TYPE (MMSignalThresholdProperties, mm_signal_threshold_properties, G_TYPE_OBJECT) + +#define PROPERTY_RSSI_THRESHOLD "rssi-threshold" +#define PROPERTY_ERROR_RATE_THRESHOLD "error-rate-threshold" + +struct _MMSignalThresholdPropertiesPrivate { + guint rssi_threshold; + gboolean rssi_threshold_set; + gboolean error_rate_threshold; + gboolean error_rate_threshold_set; +}; + +/*****************************************************************************/ + +/** + * mm_signal_threshold_properties_set_rssi: + * @self: a #MMSignalThresholdProperties. + * @rssi_threshold: the RSSI threshold, or 0 to disable. + * + * Sets the RSSI threshold, in dBm. + * + * Since: 1.20 + */ +void +mm_signal_threshold_properties_set_rssi (MMSignalThresholdProperties *self, + guint rssi_threshold) +{ + g_return_if_fail (MM_IS_SIGNAL_THRESHOLD_PROPERTIES (self)); + + self->priv->rssi_threshold = rssi_threshold; + self->priv->rssi_threshold_set = TRUE; +} + +/** + * mm_signal_threshold_properties_get_rssi: + * @self: a #MMSignalThresholdProperties. + * + * Gets the RSSI threshold, in dBm. + * + * Returns: the RSSI threshold, or 0 if disabled. + * + * Since: 1.20 + */ +guint +mm_signal_threshold_properties_get_rssi (MMSignalThresholdProperties *self) +{ + g_return_val_if_fail (MM_IS_SIGNAL_THRESHOLD_PROPERTIES (self), 0); + + return self->priv->rssi_threshold; +} + +/*****************************************************************************/ + +/** + * mm_signal_threshold_properties_set_error_rate: + * @self: a #MMSignalThresholdProperties. + * @error_rate_threshold: %TRUE to enable, %FALSE to disable. + * + * Enables or disables the error rate threshold. + * + * Since: 1.20 + */ +void +mm_signal_threshold_properties_set_error_rate (MMSignalThresholdProperties *self, + gboolean error_rate_threshold) +{ + g_return_if_fail (MM_IS_SIGNAL_THRESHOLD_PROPERTIES (self)); + + self->priv->error_rate_threshold = error_rate_threshold; + self->priv->error_rate_threshold_set = TRUE; +} + +/** + * mm_signal_threshold_properties_get_error_rate: + * @self: a #MMSignalThresholdProperties. + * + * Gets whether the error rate threshold is enabled or disabled. + * + * Returns: %TRUE if the error rate threshold is enabled, %FALSE otherwise. + * + * Since: 1.20 + */ +gboolean +mm_signal_threshold_properties_get_error_rate (MMSignalThresholdProperties *self) +{ + g_return_val_if_fail (MM_IS_SIGNAL_THRESHOLD_PROPERTIES (self), FALSE); + + return self->priv->error_rate_threshold; +} + +/*****************************************************************************/ + +/** + * mm_signal_threshold_properties_get_dictionary: (skip) + */ +GVariant * +mm_signal_threshold_properties_get_dictionary (MMSignalThresholdProperties *self) +{ + GVariantBuilder builder; + + /* We do allow NULL */ + if (!self) + return NULL; + + g_return_val_if_fail (MM_IS_SIGNAL_THRESHOLD_PROPERTIES (self), NULL); + + g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sv}")); + + if (self->priv->rssi_threshold_set) + g_variant_builder_add (&builder, + "{sv}", + PROPERTY_RSSI_THRESHOLD, + g_variant_new_uint32 (self->priv->rssi_threshold)); + + if (self->priv->error_rate_threshold_set) + g_variant_builder_add (&builder, + "{sv}", + PROPERTY_ERROR_RATE_THRESHOLD, + g_variant_new_boolean (self->priv->error_rate_threshold)); + + return g_variant_ref_sink (g_variant_builder_end (&builder)); +} + +/*****************************************************************************/ + +typedef struct { + MMSignalThresholdProperties *properties; + GError *error; +} ParseKeyValueContext; + +static gboolean +key_value_foreach (const gchar *key, + const gchar *value, + ParseKeyValueContext *ctx) +{ + if (g_str_equal (key, PROPERTY_RSSI_THRESHOLD)) { + guint rssi_threshold; + + if (!mm_get_uint_from_str (value, &rssi_threshold)) { + g_set_error (&ctx->error, MM_CORE_ERROR, MM_CORE_ERROR_INVALID_ARGS, + "invalid RSSI threshold value given: %s", value); + return FALSE; + } + mm_signal_threshold_properties_set_rssi (ctx->properties, rssi_threshold); + return TRUE; + } + + if (g_str_equal (key, PROPERTY_ERROR_RATE_THRESHOLD)) { + gboolean error_rate_threshold; + + error_rate_threshold = mm_common_get_boolean_from_string (value, &ctx->error); + if (ctx->error) { + g_prefix_error (&ctx->error, "invalid error rate threshold value given: "); + return FALSE; + } + mm_signal_threshold_properties_set_error_rate (ctx->properties, error_rate_threshold); + return TRUE; + } + + g_set_error (&ctx->error, MM_CORE_ERROR, MM_CORE_ERROR_UNSUPPORTED, + "Invalid properties string, unsupported key '%s'", key); + return FALSE; +} + +/** + * mm_signal_threshold_properties_new_from_string: (skip) + */ +MMSignalThresholdProperties * +mm_signal_threshold_properties_new_from_string (const gchar *str, + GError **error) +{ + ParseKeyValueContext ctx; + + ctx.error = NULL; + ctx.properties = mm_signal_threshold_properties_new (); + + mm_common_parse_key_value_string (str, + &ctx.error, + (MMParseKeyValueForeachFn)key_value_foreach, + &ctx); + /* If error, destroy the object */ + if (ctx.error) { + g_propagate_error (error, ctx.error); + g_clear_object (&ctx.properties); + } + + return ctx.properties; +} + +/*****************************************************************************/ + +static gboolean +consume_variant (MMSignalThresholdProperties *self, + const gchar *key, + GVariant *value, + GError **error) +{ + if (g_str_equal (key, PROPERTY_RSSI_THRESHOLD)) + mm_signal_threshold_properties_set_rssi (self, g_variant_get_uint32 (value)); + else if (g_str_equal (key, PROPERTY_ERROR_RATE_THRESHOLD)) + mm_signal_threshold_properties_set_error_rate (self, g_variant_get_boolean (value)); + else { + /* Set error */ + g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_INVALID_ARGS, + "Invalid properties dictionary, unexpected key '%s'", key); + return FALSE; + } + + return TRUE; +} + +/** + * mm_signal_threshold_properties_new_from_dictionary: (skip) + */ +MMSignalThresholdProperties * +mm_signal_threshold_properties_new_from_dictionary (GVariant *dictionary, + GError **error) +{ + GError *inner_error = NULL; + GVariantIter iter; + gchar *key; + GVariant *value; + MMSignalThresholdProperties *properties; + + properties = mm_signal_threshold_properties_new (); + if (!dictionary) + return properties; + + 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 threshold properties from dictionary: " + "invalid variant type received"); + g_object_unref (properties); + return NULL; + } + + g_variant_iter_init (&iter, dictionary); + while (!inner_error && g_variant_iter_next (&iter, "{sv}", &key, &value)) { + consume_variant (properties, 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 (properties); + properties = NULL; + } + + return properties; +} + +/*****************************************************************************/ + +/** + * mm_signal_threshold_properties_new: + * + * Creates a new empty #MMSignalThresholdProperties. + * + * Returns: (transfer full): a #MMSignalThresholdProperties. The returned value should be freed with g_object_unref(). + * + * Since: 1.20 + */ +MMSignalThresholdProperties * +mm_signal_threshold_properties_new (void) +{ + return (MM_SIGNAL_THRESHOLD_PROPERTIES ( + g_object_new (MM_TYPE_SIGNAL_THRESHOLD_PROPERTIES, NULL))); +} + +static void +mm_signal_threshold_properties_init (MMSignalThresholdProperties *self) +{ + self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, + MM_TYPE_SIGNAL_THRESHOLD_PROPERTIES, + MMSignalThresholdPropertiesPrivate); +} + +static void +mm_signal_threshold_properties_class_init (MMSignalThresholdPropertiesClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + g_type_class_add_private (object_class, sizeof (MMSignalThresholdPropertiesPrivate)); +} diff --git a/libmm-glib/mm-signal-threshold-properties.h b/libmm-glib/mm-signal-threshold-properties.h new file mode 100644 index 00000000..ccba9a34 --- /dev/null +++ b/libmm-glib/mm-signal-threshold-properties.h @@ -0,0 +1,86 @@ +/* -*- 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) 2021 Aleksander Morgado <aleksander@aleksander.es> + * Copyright (C) 2021 Intel Corporation + */ + +#ifndef MM_SIGNAL_THRESHOLD_PROPERTIES_H +#define MM_SIGNAL_THRESHOLD_PROPERTIES_H + +#include <ModemManager.h> +#include <glib-object.h> + +#if !defined (__LIBMM_GLIB_H_INSIDE__) && !defined (LIBMM_GLIB_COMPILATION) +#error "Only <libmm-glib.h> can be included directly." +#endif + +G_BEGIN_DECLS + +#define MM_TYPE_SIGNAL_THRESHOLD_PROPERTIES (mm_signal_threshold_properties_get_type ()) +#define MM_SIGNAL_THRESHOLD_PROPERTIES(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MM_TYPE_SIGNAL_THRESHOLD_PROPERTIES, MMSignalThresholdProperties)) +#define MM_SIGNAL_THRESHOLD_PROPERTIES_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), MM_TYPE_SIGNAL_THRESHOLD_PROPERTIES, MMSignalThresholdPropertiesClass)) +#define MM_IS_SIGNAL_THRESHOLD_PROPERTIES(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MM_TYPE_SIGNAL_THRESHOLD_PROPERTIES)) +#define MM_IS_SIGNAL_THRESHOLD_PROPERTIES_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), MM_TYPE_SIGNAL_THRESHOLD_PROPERTIES)) +#define MM_SIGNAL_THRESHOLD_PROPERTIES_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), MM_TYPE_SIGNAL_THRESHOLD_PROPERTIES, MMSignalThresholdPropertiesClass)) + +typedef struct _MMSignalThresholdProperties MMSignalThresholdProperties; +typedef struct _MMSignalThresholdPropertiesClass MMSignalThresholdPropertiesClass; +typedef struct _MMSignalThresholdPropertiesPrivate MMSignalThresholdPropertiesPrivate; + +/** + * MMSignalThresholdProperties: + * + * The #MMSignalThresholdProperties structure contains private data and should + * only be accessed using the provided API. + */ +struct _MMSignalThresholdProperties { + /*< private >*/ + GObject parent; + MMSignalThresholdPropertiesPrivate *priv; +}; + +struct _MMSignalThresholdPropertiesClass { + /*< private >*/ + GObjectClass parent; +}; + +GType mm_signal_threshold_properties_get_type (void); +G_DEFINE_AUTOPTR_CLEANUP_FUNC (MMSignalThresholdProperties, g_object_unref) + +MMSignalThresholdProperties *mm_signal_threshold_properties_new (void); + +void mm_signal_threshold_properties_set_rssi (MMSignalThresholdProperties *self, + guint rssi_threshold); +void mm_signal_threshold_properties_set_error_rate (MMSignalThresholdProperties *self, + gboolean error_rate_threshold); +guint mm_signal_threshold_properties_get_rssi (MMSignalThresholdProperties *self); +gboolean mm_signal_threshold_properties_get_error_rate (MMSignalThresholdProperties *self); + +/*****************************************************************************/ +/* ModemManager/libmm-glib/mmcli specific methods */ + +#if defined (_LIBMM_INSIDE_MM) || \ + defined (_LIBMM_INSIDE_MMCLI) || \ + defined (LIBMM_GLIB_COMPILATION) + +MMSignalThresholdProperties *mm_signal_threshold_properties_new_from_string (const gchar *str, + GError **error); +MMSignalThresholdProperties *mm_signal_threshold_properties_new_from_dictionary (GVariant *dictionary, + GError **error); +GVariant *mm_signal_threshold_properties_get_dictionary (MMSignalThresholdProperties *self); + +#endif + +G_END_DECLS + +#endif /* MM_SIGNAL_THRESHOLD_PROPERTIES_H */ diff --git a/src/mm-iface-modem-signal.c b/src/mm-iface-modem-signal.c index d793bba3..d2040390 100644 --- a/src/mm-iface-modem-signal.c +++ b/src/mm-iface-modem-signal.c @@ -382,56 +382,14 @@ setup_thresholds_ready (MMIfaceModemSignal *self, handle_setup_thresholds_context_free (ctx); } -static gboolean -select_new_threshold_settings (HandleSetupThresholdsContext *ctx, - GError **error) -{ - GError *inner_error = NULL; - GVariantIter iter; - gchar *key; - GVariant *value; - - if (!g_variant_is_of_type (ctx->settings, G_VARIANT_TYPE ("a{sv}"))) { - g_set_error (error, - MM_CORE_ERROR, - MM_CORE_ERROR_INVALID_ARGS, - "Cannot get threshold settings from dictionary: " - "invalid variant type received"); - return FALSE; - } - - g_variant_iter_init (&iter, ctx->settings); - while (!inner_error && g_variant_iter_next (&iter, "{sv}", &key, &value)) { - if (g_str_equal (key, "rssi-threshold")) - ctx->rssi_threshold = g_variant_get_uint32 (value); - else if (g_str_equal (key, "error-rate-threshold")) - ctx->error_rate_threshold = g_variant_get_boolean (value); - else { - /* Set inner error, will stop the loop */ - inner_error = g_error_new (MM_CORE_ERROR, - MM_CORE_ERROR_INVALID_ARGS, - "Invalid settings dictionary, unexpected key '%s'", - key); - } - - g_free (key); - g_variant_unref (value); - } - - if (inner_error) { - g_propagate_error (error, inner_error); - return FALSE; - } - return TRUE; -} - static void handle_setup_thresholds_auth_ready (MMBaseModem *self, GAsyncResult *res, HandleSetupThresholdsContext *ctx) { - GError *error = NULL; - Private *priv; + g_autoptr(MMSignalThresholdProperties) properties = NULL; + GError *error = NULL; + Private *priv; priv = get_private (MM_IFACE_MODEM_SIGNAL (self)); @@ -456,12 +414,22 @@ handle_setup_thresholds_auth_ready (MMBaseModem *self, return; } - /* Process received settings */ - if (!select_new_threshold_settings (ctx, &error)) { + properties = mm_signal_threshold_properties_new_from_dictionary (ctx->settings, &error); + if (!properties) { g_dbus_method_invocation_take_error (ctx->invocation, error); handle_setup_thresholds_context_free (ctx); return; } + ctx->rssi_threshold = mm_signal_threshold_properties_get_rssi (properties); + ctx->error_rate_threshold = mm_signal_threshold_properties_get_error_rate (properties); + + /* Already there? */ + if ((ctx->rssi_threshold == mm_gdbus_modem_signal_get_rssi_threshold (ctx->skeleton)) && + (ctx->error_rate_threshold == mm_gdbus_modem_signal_get_error_rate_threshold (ctx->skeleton))) { + mm_gdbus_modem_signal_complete_setup_thresholds (ctx->skeleton, ctx->invocation); + handle_setup_thresholds_context_free (ctx); + return; + } /* Same settings? */ if ((ctx->rssi_threshold == priv->rssi_threshold) && |