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:
Aleksander Morgado
2013-06-05 19:15:14 +02:00
parent 212d00c529
commit 45ceba7692
35 changed files with 2060 additions and 307 deletions
+2
View File
@@ -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 \
+1
View File
@@ -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>
+122
View File
@@ -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)
+12
View File
@@ -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);
+44
View File
@@ -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
View File
@@ -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)
+7 -1
View File
@@ -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);