api,introspection: 'SupportedModes' is now a list of possible combinations
Instead of just a mask of MMModemMode values, we now provide a list of the
allowed and preferred mode combinations supported by the modem. E.g.:
$> sudo mmcli -m 0
-------------------------
Modes | supported: 'allowed: 2g; preferred: none
| allowed: 3g; preferred: none
| allowed: 2g, 3g; preferred: none
| allowed: 2g, 3g; preferred: 2g
| allowed: 2g, 3g; preferred: 3g
| allowed: 4g; preferred: none
| allowed: 2g, 3g, 4g; preferred: none'
This commit is contained in:
@@ -5,6 +5,7 @@ lib_LTLIBRARIES = libmm-glib.la
|
||||
libmm_glib_la_SOURCES = \
|
||||
libmm-glib.h \
|
||||
mm-helpers.h \
|
||||
mm-helper-types.h \
|
||||
mm-manager.h \
|
||||
mm-manager.c \
|
||||
mm-object.h \
|
||||
@@ -77,6 +78,7 @@ libmm_glib_la_LIBADD = \
|
||||
includedir = @includedir@/libmm-glib
|
||||
include_HEADERS = \
|
||||
libmm-glib.h \
|
||||
mm-helper-types.h \
|
||||
mm-manager.h \
|
||||
mm-object.h \
|
||||
mm-modem.h \
|
||||
|
||||
@@ -52,6 +52,7 @@
|
||||
# include <mm-common-helpers.h>
|
||||
#endif
|
||||
|
||||
#include <mm-helper-types.h>
|
||||
#include <mm-simple-status.h>
|
||||
#include <mm-simple-connect-properties.h>
|
||||
#include <mm-sms-properties.h>
|
||||
|
||||
@@ -73,6 +73,38 @@ mm_common_build_sms_storages_string (const MMSmsStorage *storages,
|
||||
return g_string_free (str, FALSE);
|
||||
}
|
||||
|
||||
gchar *
|
||||
mm_common_build_mode_combinations_string (const MMModemModeCombination *modes,
|
||||
guint n_modes)
|
||||
{
|
||||
gboolean first = TRUE;
|
||||
GString *str;
|
||||
guint i;
|
||||
|
||||
if (!modes || !n_modes)
|
||||
return g_strdup ("none");
|
||||
|
||||
str = g_string_new ("");
|
||||
for (i = 0; i < n_modes; i++) {
|
||||
gchar *allowed;
|
||||
gchar *preferred;
|
||||
|
||||
allowed = mm_modem_mode_build_string_from_mask (modes[i].allowed);
|
||||
preferred = mm_modem_mode_build_string_from_mask (modes[i].preferred);
|
||||
g_string_append_printf (str, "%sallowed: %s; preferred: %s",
|
||||
first ? "" : "\n",
|
||||
allowed,
|
||||
preferred);
|
||||
g_free (allowed);
|
||||
g_free (preferred);
|
||||
|
||||
if (first)
|
||||
first = FALSE;
|
||||
}
|
||||
|
||||
return g_string_free (str, FALSE);
|
||||
}
|
||||
|
||||
GArray *
|
||||
mm_common_sms_storages_variant_to_garray (GVariant *variant)
|
||||
{
|
||||
@@ -357,6 +389,96 @@ mm_common_bands_garray_cmp (GArray *a, GArray *b)
|
||||
return !different;
|
||||
}
|
||||
|
||||
GArray *
|
||||
mm_common_mode_combinations_variant_to_garray (GVariant *variant)
|
||||
{
|
||||
GArray *array = NULL;
|
||||
|
||||
if (variant) {
|
||||
GVariantIter iter;
|
||||
guint n;
|
||||
|
||||
g_variant_iter_init (&iter, variant);
|
||||
n = g_variant_iter_n_children (&iter);
|
||||
|
||||
if (n > 0) {
|
||||
MMModemModeCombination mode;
|
||||
|
||||
array = g_array_sized_new (FALSE, FALSE, sizeof (MMModemModeCombination), n);
|
||||
while (g_variant_iter_loop (&iter, "(uu)", &mode.allowed, &mode.preferred))
|
||||
g_array_append_val (array, mode);
|
||||
}
|
||||
}
|
||||
|
||||
/* If nothing set, fallback to default */
|
||||
if (!array) {
|
||||
MMModemModeCombination default_mode;
|
||||
|
||||
default_mode.allowed = MM_MODEM_MODE_ANY;
|
||||
default_mode.preferred = MM_MODEM_MODE_NONE;
|
||||
array = g_array_sized_new (FALSE, FALSE, sizeof (MMModemModeCombination), 1);
|
||||
g_array_append_val (array, default_mode);
|
||||
}
|
||||
|
||||
return array;
|
||||
}
|
||||
|
||||
MMModemModeCombination *
|
||||
mm_common_mode_combinations_variant_to_array (GVariant *variant,
|
||||
guint *n_modes)
|
||||
{
|
||||
GArray *array;
|
||||
|
||||
array = mm_common_mode_combinations_variant_to_garray (variant);
|
||||
if (n_modes)
|
||||
*n_modes = array->len;
|
||||
return (MMModemModeCombination *) g_array_free (array, FALSE);
|
||||
}
|
||||
|
||||
GVariant *
|
||||
mm_common_mode_combinations_array_to_variant (const MMModemModeCombination *modes,
|
||||
guint n_modes)
|
||||
{
|
||||
if (n_modes > 0) {
|
||||
GVariantBuilder builder;
|
||||
guint i;
|
||||
|
||||
g_variant_builder_init (&builder, G_VARIANT_TYPE ("a(uu)"));
|
||||
|
||||
for (i = 0; i < n_modes; i++)
|
||||
g_variant_builder_add_value (&builder,
|
||||
g_variant_new ("(uu)",
|
||||
((guint32)modes[i].allowed),
|
||||
((guint32)modes[i].preferred)));
|
||||
return g_variant_builder_end (&builder);
|
||||
}
|
||||
|
||||
return mm_common_build_mode_combinations_default ();
|
||||
}
|
||||
|
||||
GVariant *
|
||||
mm_common_mode_combinations_garray_to_variant (GArray *array)
|
||||
{
|
||||
if (array)
|
||||
return mm_common_mode_combinations_array_to_variant ((const MMModemModeCombination *)array->data,
|
||||
array->len);
|
||||
|
||||
return mm_common_mode_combinations_array_to_variant (NULL, 0);
|
||||
}
|
||||
|
||||
GVariant *
|
||||
mm_common_build_mode_combinations_default (void)
|
||||
{
|
||||
GVariantBuilder builder;
|
||||
|
||||
g_variant_builder_init (&builder, G_VARIANT_TYPE ("a(uu)"));
|
||||
g_variant_builder_add_value (&builder,
|
||||
g_variant_new ("(uu)",
|
||||
MM_MODEM_MODE_ANY,
|
||||
MM_MODEM_MODE_NONE));
|
||||
return g_variant_builder_end (&builder);
|
||||
}
|
||||
|
||||
gboolean
|
||||
mm_common_get_boolean_from_string (const gchar *value,
|
||||
GError **error)
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
|
||||
#include <glib.h>
|
||||
#include <ModemManager.h>
|
||||
#include "mm-helper-types.h"
|
||||
|
||||
#if !defined (__LIBMM_GLIB_H_INSIDE__) && !defined (LIBMM_GLIB_COMPILATION)
|
||||
#error "Only <libmm-glib.h> can be included directly."
|
||||
@@ -31,6 +32,9 @@ gchar *mm_common_build_bands_string (const MMModemBand *bands,
|
||||
gchar *mm_common_build_sms_storages_string (const MMSmsStorage *storages,
|
||||
guint n_storages);
|
||||
|
||||
gchar *mm_common_build_mode_combinations_string (const MMModemModeCombination *modes,
|
||||
guint n_modes);
|
||||
|
||||
MMModemMode mm_common_get_modes_from_string (const gchar *str,
|
||||
GError **error);
|
||||
void mm_common_get_bands_from_string (const gchar *str,
|
||||
@@ -67,6 +71,14 @@ GVariant *mm_common_build_bands_unknown (void);
|
||||
|
||||
gboolean mm_common_bands_garray_cmp (GArray *a, GArray *b);
|
||||
|
||||
GArray *mm_common_mode_combinations_variant_to_garray (GVariant *variant);
|
||||
MMModemModeCombination *mm_common_mode_combinations_variant_to_array (GVariant *variant,
|
||||
guint *n_modes);
|
||||
GVariant *mm_common_mode_combinations_array_to_variant (const MMModemModeCombination *modes,
|
||||
guint n_modes);
|
||||
GVariant *mm_common_mode_combinations_garray_to_variant (GArray *array);
|
||||
GVariant *mm_common_build_mode_combinations_default (void);
|
||||
|
||||
typedef gboolean (*MMParseKeyValueForeachFn) (const gchar *key,
|
||||
const gchar *value,
|
||||
gpointer user_data);
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/*
|
||||
* libmm -- Access modem status & information from glib applications
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Copyright (C) 2013 Aleksander Morgado <aleksander@gnu.org>
|
||||
*/
|
||||
|
||||
#include <ModemManager.h>
|
||||
|
||||
#if !defined (__LIBMM_GLIB_H_INSIDE__) && !defined (LIBMM_GLIB_COMPILATION)
|
||||
#error "Only <libmm-glib.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#ifndef _MM_HELPER_TYPES_H_
|
||||
#define _MM_HELPER_TYPES_H_
|
||||
|
||||
/**
|
||||
* MMModemModeCombination:
|
||||
* @allowed: Mask of #MMModemMode values specifying allowed modes.
|
||||
* @preferred: A single #MMModemMode value specifying the preferred mode.
|
||||
*
|
||||
* #MMModemModeCombination is a simple struct holding a pair of #MMModemMode values.
|
||||
*/
|
||||
typedef struct _MMModemModeCombination {
|
||||
MMModemMode allowed;
|
||||
MMModemMode preferred;
|
||||
} MMModemModeCombination;
|
||||
|
||||
#endif /* _MM_HELPER_TYPES_H_ */
|
||||
+115
-8
@@ -49,6 +49,11 @@ struct _MMModemPrivate {
|
||||
guint unlock_retries_id;
|
||||
MMUnlockRetries *unlock_retries;
|
||||
|
||||
/* Supported Modes */
|
||||
GMutex supported_modes_mutex;
|
||||
guint supported_modes_id;
|
||||
GArray *supported_modes;
|
||||
|
||||
/* Supported Bands */
|
||||
GMutex supported_bands_mutex;
|
||||
guint supported_bands_id;
|
||||
@@ -910,22 +915,120 @@ mm_modem_get_signal_quality (MMModem *self,
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static void
|
||||
supported_modes_updated (MMModem *self,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
g_mutex_lock (&self->priv->supported_modes_mutex);
|
||||
{
|
||||
GVariant *dictionary;
|
||||
|
||||
if (self->priv->supported_modes)
|
||||
g_array_unref (self->priv->supported_modes);
|
||||
|
||||
dictionary = mm_gdbus_modem_get_supported_modes (MM_GDBUS_MODEM (self));
|
||||
self->priv->supported_modes = (dictionary ?
|
||||
mm_common_mode_combinations_variant_to_garray (dictionary) :
|
||||
NULL);
|
||||
}
|
||||
g_mutex_unlock (&self->priv->supported_modes_mutex);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
ensure_internal_supported_modes (MMModem *self,
|
||||
MMModemModeCombination **dup_modes,
|
||||
guint *dup_modes_n)
|
||||
{
|
||||
gboolean ret;
|
||||
|
||||
g_mutex_lock (&self->priv->supported_modes_mutex);
|
||||
{
|
||||
/* If this is the first time ever asking for the array, setup the
|
||||
* update listener and the initial array, if any. */
|
||||
if (!self->priv->supported_modes_id) {
|
||||
GVariant *dictionary;
|
||||
|
||||
dictionary = mm_gdbus_modem_dup_supported_modes (MM_GDBUS_MODEM (self));
|
||||
if (dictionary) {
|
||||
self->priv->supported_modes = mm_common_mode_combinations_variant_to_garray (dictionary);
|
||||
g_variant_unref (dictionary);
|
||||
}
|
||||
|
||||
/* No need to clear this signal connection when freeing self */
|
||||
self->priv->supported_modes_id =
|
||||
g_signal_connect (self,
|
||||
"notify::supported-modes",
|
||||
G_CALLBACK (supported_modes_updated),
|
||||
NULL);
|
||||
}
|
||||
|
||||
if (!self->priv->supported_modes)
|
||||
ret = FALSE;
|
||||
else {
|
||||
ret = TRUE;
|
||||
|
||||
if (dup_modes && dup_modes_n) {
|
||||
*dup_modes_n = self->priv->supported_modes->len;
|
||||
if (self->priv->supported_modes->len > 0) {
|
||||
*dup_modes = g_malloc (sizeof (MMModemModeCombination) * self->priv->supported_modes->len);
|
||||
memcpy (*dup_modes, self->priv->supported_modes->data, sizeof (MMModemModeCombination) * self->priv->supported_modes->len);
|
||||
} else
|
||||
*dup_modes = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
g_mutex_unlock (&self->priv->supported_modes_mutex);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* mm_modem_get_supported_modes:
|
||||
* @self: A #MMModem.
|
||||
* @modes: (out) (array length=n_modes): Return location for the array of #MMModemModeCombination structs. The returned array should be freed with g_free() when no longer needed.
|
||||
* @n_modes: (out): Return location for the number of values in @modes.
|
||||
*
|
||||
* Gets the list of modes specifying the access technologies supported by the #MMModem.
|
||||
* Gets the list of supported mode combinations.
|
||||
*
|
||||
* For POTS devices, only #MM_MODEM_MODE_ANY will be returned.
|
||||
*
|
||||
* Returns: A bitmask of #MMModemMode values.
|
||||
* Returns: %TRUE if @modes and @n_modes are set, %FALSE otherwise.
|
||||
*/
|
||||
MMModemMode
|
||||
mm_modem_get_supported_modes (MMModem *self)
|
||||
gboolean
|
||||
mm_modem_get_supported_modes (MMModem *self,
|
||||
MMModemModeCombination **modes,
|
||||
guint *n_modes)
|
||||
{
|
||||
g_return_val_if_fail (MM_IS_MODEM (self), MM_MODEM_MODE_NONE);
|
||||
g_return_val_if_fail (MM_IS_MODEM (self), FALSE);
|
||||
g_return_val_if_fail (modes != NULL, FALSE);
|
||||
g_return_val_if_fail (n_modes != NULL, FALSE);
|
||||
|
||||
return (MMModemMode) mm_gdbus_modem_get_supported_modes (MM_GDBUS_MODEM (self));
|
||||
return ensure_internal_supported_modes (self, modes, n_modes);
|
||||
}
|
||||
|
||||
/**
|
||||
* mm_modem_peek_supported_modes:
|
||||
* @self: A #MMModem.
|
||||
* @modes: (out) (array length=n_modes): Return location for the array of #MMModemModeCombination values. Do not free the returned array, it is owned by @self.
|
||||
* @n_modes: (out): Return location for the number of values in @modes.
|
||||
*
|
||||
* Gets the list of supported mode combinations.
|
||||
*
|
||||
* Returns: %TRUE if @modes and @n_modes are set, %FALSE otherwise.
|
||||
*/
|
||||
gboolean
|
||||
mm_modem_peek_supported_modes (MMModem *self,
|
||||
const MMModemModeCombination **modes,
|
||||
guint *n_modes)
|
||||
{
|
||||
g_return_val_if_fail (MM_IS_MODEM (self), FALSE);
|
||||
g_return_val_if_fail (modes != NULL, FALSE);
|
||||
g_return_val_if_fail (n_modes != NULL, FALSE);
|
||||
|
||||
if (!ensure_internal_supported_modes (self, NULL, NULL))
|
||||
return FALSE;
|
||||
|
||||
*n_modes = self->priv->supported_modes->len;
|
||||
*modes = (MMModemModeCombination *)self->priv->supported_modes->data;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
@@ -2533,6 +2636,7 @@ mm_modem_init (MMModem *self)
|
||||
MM_TYPE_MODEM,
|
||||
MMModemPrivate);
|
||||
g_mutex_init (&self->priv->unlock_retries_mutex);
|
||||
g_mutex_init (&self->priv->supported_modes_mutex);
|
||||
g_mutex_init (&self->priv->supported_bands_mutex);
|
||||
g_mutex_init (&self->priv->current_bands_mutex);
|
||||
}
|
||||
@@ -2543,9 +2647,12 @@ finalize (GObject *object)
|
||||
MMModem *self = MM_MODEM (object);
|
||||
|
||||
g_mutex_clear (&self->priv->unlock_retries_mutex);
|
||||
g_mutex_clear (&self->priv->supported_modes_mutex);
|
||||
g_mutex_clear (&self->priv->supported_bands_mutex);
|
||||
g_mutex_clear (&self->priv->current_bands_mutex);
|
||||
|
||||
if (self->priv->supported_modes)
|
||||
g_array_unref (self->priv->supported_modes);
|
||||
if (self->priv->supported_bands)
|
||||
g_array_unref (self->priv->supported_bands);
|
||||
if (self->priv->current_bands)
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
#include "mm-unlock-retries.h"
|
||||
#include "mm-sim.h"
|
||||
#include "mm-bearer.h"
|
||||
#include "mm-helper-types.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
@@ -127,7 +128,12 @@ MMModemAccessTechnology mm_modem_get_access_technologies (MMModem *self);
|
||||
guint mm_modem_get_signal_quality (MMModem *self,
|
||||
gboolean *recent);
|
||||
|
||||
MMModemMode mm_modem_get_supported_modes (MMModem *self);
|
||||
gboolean mm_modem_peek_supported_modes (MMModem *self,
|
||||
const MMModemModeCombination **modes,
|
||||
guint *n_modes);
|
||||
gboolean mm_modem_get_supported_modes (MMModem *self,
|
||||
MMModemModeCombination **modes,
|
||||
guint *n_modes);
|
||||
|
||||
MMModemMode mm_modem_get_allowed_modes (MMModem *self);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user