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-05-29 12:41:49 +02:00
parent 212d00c529
commit 45ceba7692
35 changed files with 2060 additions and 307 deletions

View File

@@ -238,6 +238,8 @@ print_modem_info (void)
gchar *modem_capabilities_string;
gchar *current_capabilities_string;
gchar *access_technologies_string;
MMModemModeCombination *modes = NULL;
guint n_modes = 0;
gchar *supported_modes_string;
gchar *allowed_modes_string;
gchar *preferred_mode_string;
@@ -266,6 +268,9 @@ print_modem_info (void)
mm_modem_get_current_capabilities (ctx->modem));
access_technologies_string = mm_modem_access_technology_build_string_from_mask (
mm_modem_get_access_technologies (ctx->modem));
mm_modem_get_supported_modes (ctx->modem, &modes, &n_modes);
supported_modes_string = mm_common_build_mode_combinations_string (modes, n_modes);
g_free (modes);
mm_modem_get_current_bands (ctx->modem, &bands, &n_bands);
current_bands_string = mm_common_build_bands_string (bands, n_bands);
g_free (bands);
@@ -276,8 +281,6 @@ print_modem_info (void)
mm_modem_get_allowed_modes (ctx->modem));
preferred_mode_string = mm_modem_mode_build_string_from_mask (
mm_modem_get_preferred_mode (ctx->modem));
supported_modes_string = mm_modem_mode_build_string_from_mask (
mm_modem_get_supported_modes (ctx->modem));
supported_ip_families_string = mm_bearer_ip_family_build_string_from_mask (
mm_modem_get_supported_ip_families (ctx->modem));
@@ -310,6 +313,15 @@ print_modem_info (void)
else
prefixed_revision = NULL;
if (supported_modes_string) {
gchar *prefixed;
prefixed = mmcli_prefix_newlines (" | ",
supported_modes_string);
g_free (supported_modes_string);
supported_modes_string = prefixed;
}
/* Get signal quality info */
signal_quality = mm_modem_get_signal_quality (ctx->modem, &signal_quality_recent);

View File

@@ -73,6 +73,7 @@ mm_object_get_type
<FILE>mm-modem</FILE>
<TITLE>MMModem</TITLE>
MMModem
MMModemModeCombination
<SUBSECTION Getters>
mm_modem_get_path
mm_modem_dup_path
@@ -106,6 +107,7 @@ mm_modem_get_max_bearers
mm_modem_get_max_active_bearers
mm_modem_get_own_numbers
mm_modem_dup_own_numbers
mm_modem_peek_supported_modes
mm_modem_get_supported_modes
mm_modem_get_allowed_modes
mm_modem_get_preferred_mode
@@ -1455,6 +1457,7 @@ mm_gdbus_modem_get_supported_bands
mm_gdbus_modem_dup_supported_bands
mm_gdbus_modem_get_supported_ip_families
mm_gdbus_modem_get_supported_modes
mm_gdbus_modem_dup_supported_modes
mm_gdbus_modem_get_unlock_required
mm_gdbus_modem_get_unlock_retries
mm_gdbus_modem_dup_unlock_retries

View File

@@ -410,14 +410,25 @@
<!--
SupportedModes:
Bitmask of <link linkend="MMModemMode">MMModemMode</link> values,
specifying the access technologies supported by the device.
This property exposes the supported mode combinations, given as an array of unsigned
integer pairs, where:
For POTS devices, only the
<link linkend="MM-MODEM-MODE-ANY:CAPS"><constant>MM_MODEM_MODE_ANY</constant></link>
mode will be returned.
<variablelist>
<varlistentry>
<listitem>
The first integer is a bitmask of <link linkend="MMModemMode">MMModemMode</link> values,
specifying the allowed modes.
</listitem>
</varlistentry>
<varlistentry>
<listitem>
The second integer is a single <link linkend="MMModemMode">MMModemMode</link>, which
specifies the preferred access technology, among the ones defined in the allowed modes.
</listitem>
</varlistentry>
</variablelist>
-->
<property name="SupportedModes" type="u" access="read" />
<property name="SupportedModes" type="a(uu)" access="read" />
<!--
AllowedModes:

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 \

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>

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)

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

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

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)

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

View File

@@ -38,10 +38,12 @@ static void iface_modem_init (MMIfaceModem *iface);
static void iface_modem_3gpp_init (MMIfaceModem3gpp *iface);
static void iface_modem_messaging_init (MMIfaceModemMessaging *iface);
static MMIfaceModem *iface_modem_parent;
G_DEFINE_TYPE_EXTENDED (MMBroadbandModemCinterion, mm_broadband_modem_cinterion, MM_TYPE_BROADBAND_MODEM, 0,
G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM, iface_modem_init)
G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM_3GPP, iface_modem_3gpp_init)
G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM_MESSAGING, iface_modem_messaging_init));
G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM_MESSAGING, iface_modem_messaging_init))
struct _MMBroadbandModemCinterionPrivate {
/* Flag to know if we should try AT^SIND or not to get psinfo */
@@ -513,6 +515,80 @@ load_access_technologies (MMIfaceModem *self,
result);
}
/*****************************************************************************/
/* Load supported modes (Modem interface) */
static GArray *
load_supported_modes_finish (MMIfaceModem *self,
GAsyncResult *res,
GError **error)
{
if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error))
return NULL;
return g_array_ref (g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (res)));
}
static void
parent_load_supported_modes_ready (MMIfaceModem *self,
GAsyncResult *res,
GSimpleAsyncResult *simple)
{
GError *error = NULL;
GArray *all;
GArray *combinations;
GArray *filtered;
MMModemModeCombination mode;
all = iface_modem_parent->load_supported_modes_finish (self, res, &error);
if (!all) {
g_simple_async_result_take_error (simple, error);
g_simple_async_result_complete (simple);
g_object_unref (simple);
return;
}
/* Build list of combinations */
combinations = g_array_sized_new (FALSE, FALSE, sizeof (MMModemModeCombination), 3);
/* 2G only */
mode.allowed = MM_MODEM_MODE_2G;
mode.preferred = MM_MODEM_MODE_NONE;
g_array_append_val (combinations, mode);
/* 3G only */
mode.allowed = MM_MODEM_MODE_3G;
mode.preferred = MM_MODEM_MODE_NONE;
g_array_append_val (combinations, mode);
/* 2G and 3G */
mode.allowed = (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G);
mode.preferred = MM_MODEM_MODE_NONE;
g_array_append_val (combinations, mode);
/* Filter out those unsupported modes */
filtered = mm_filter_supported_modes (all, combinations);
g_array_unref (all);
g_array_unref (combinations);
g_simple_async_result_set_op_res_gpointer (simple, filtered, (GDestroyNotify) g_array_unref);
g_simple_async_result_complete (simple);
g_object_unref (simple);
}
static void
load_supported_modes (MMIfaceModem *self,
GAsyncReadyCallback callback,
gpointer user_data)
{
/* Run parent's loading */
iface_modem_parent->load_supported_modes (
MM_IFACE_MODEM (self),
(GAsyncReadyCallback)parent_load_supported_modes_ready,
g_simple_async_result_new (G_OBJECT (self),
callback,
user_data,
load_supported_modes));
}
/*****************************************************************************/
/* ALLOWED MODES */
@@ -1191,6 +1267,10 @@ finalize (GObject *object)
static void
iface_modem_init (MMIfaceModem *iface)
{
iface_modem_parent = g_type_interface_peek_parent (iface);
iface->load_supported_modes = load_supported_modes;
iface->load_supported_modes_finish = load_supported_modes_finish;
iface->set_allowed_modes = set_allowed_modes;
iface->set_allowed_modes_finish = set_allowed_modes_finish;
iface->load_supported_bands = load_supported_bands;

View File

@@ -1074,6 +1074,90 @@ set_current_bands (MMIfaceModem *self,
g_free (bands_string);
}
/*****************************************************************************/
/* Load supported modes (Modem interface) */
static GArray *
load_supported_modes_finish (MMIfaceModem *self,
GAsyncResult *res,
GError **error)
{
if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error))
return NULL;
return g_array_ref (g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (res)));
}
static void
parent_load_supported_modes_ready (MMIfaceModem *self,
GAsyncResult *res,
GSimpleAsyncResult *simple)
{
GError *error = NULL;
GArray *all;
GArray *combinations;
GArray *filtered;
MMModemModeCombination mode;
all = iface_modem_parent->load_supported_modes_finish (self, res, &error);
if (!all) {
g_simple_async_result_take_error (simple, error);
g_simple_async_result_complete (simple);
g_object_unref (simple);
return;
}
/* Build list of combinations */
combinations = g_array_sized_new (FALSE, FALSE, sizeof (MMModemModeCombination), 5);
/* 2G only */
mode.allowed = MM_MODEM_MODE_2G;
mode.preferred = MM_MODEM_MODE_NONE;
g_array_append_val (combinations, mode);
/* 3G only */
mode.allowed = MM_MODEM_MODE_3G;
mode.preferred = MM_MODEM_MODE_NONE;
g_array_append_val (combinations, mode);
/* 2G and 3G */
mode.allowed = (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G);
mode.preferred = MM_MODEM_MODE_NONE;
g_array_append_val (combinations, mode);
/* CDMA modems don't support 'preferred' setups */
if (!mm_iface_modem_is_cdma_only (self)) {
/* 2G and 3G, 2G preferred */
mode.allowed = (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G);
mode.preferred = MM_MODEM_MODE_2G;
g_array_append_val (combinations, mode);
/* 2G and 3G, 3G preferred */
mode.allowed = (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G);
mode.preferred = MM_MODEM_MODE_3G;
g_array_append_val (combinations, mode);
}
/* Filter out those unsupported modes */
filtered = mm_filter_supported_modes (all, combinations);
g_array_unref (all);
g_array_unref (combinations);
g_simple_async_result_set_op_res_gpointer (simple, filtered, (GDestroyNotify) g_array_unref);
g_simple_async_result_complete (simple);
g_object_unref (simple);
}
static void
load_supported_modes (MMIfaceModem *self,
GAsyncReadyCallback callback,
gpointer user_data)
{
/* Run parent's loading */
iface_modem_parent->load_supported_modes (
MM_IFACE_MODEM (self),
(GAsyncReadyCallback)parent_load_supported_modes_ready,
g_simple_async_result_new (G_OBJECT (self),
callback,
user_data,
load_supported_modes));
}
/*****************************************************************************/
/* Load initial allowed/preferred modes (Modem interface) */
@@ -1091,7 +1175,7 @@ parse_prefmode (const gchar *response, MMModemMode *preferred, GError **error)
*preferred = MM_MODEM_MODE_3G;
return TRUE;
} else if (a == 8) {
*preferred = MM_MODEM_MODE_2G | MM_MODEM_MODE_3G;
*preferred = MM_MODEM_MODE_NONE;
return TRUE;
}
@@ -1116,10 +1200,7 @@ load_allowed_modes_finish (MMIfaceModem *self,
return FALSE;
if (mm_iface_modem_is_cdma_only (self)) {
/* CDMA-only devices always support 2G and 3G if they have 3G, so just
* use the modes from GCAP as the list of allowed modes.
*/
*allowed = mm_iface_modem_get_supported_modes (self);
*allowed = (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G);
return parse_prefmode (response, preferred, error);
}
@@ -2660,6 +2741,8 @@ iface_modem_init (MMIfaceModem *iface)
iface->load_current_bands_finish = load_current_bands_finish;
iface->set_current_bands = set_current_bands;
iface->set_current_bands_finish = set_current_bands_finish;
iface->load_supported_modes = load_supported_modes;
iface->load_supported_modes_finish = load_supported_modes_finish;
iface->load_allowed_modes = load_allowed_modes;
iface->load_allowed_modes_finish = load_allowed_modes_finish;
iface->set_allowed_modes = set_allowed_modes;

View File

@@ -40,12 +40,13 @@ static void iface_modem_init (MMIfaceModem *iface);
static void iface_modem_3gpp_init (MMIfaceModem3gpp *iface);
static void iface_modem_time_init (MMIfaceModemTime *iface);
static MMIfaceModem *iface_modem_parent;
static MMIfaceModem3gpp *iface_modem_3gpp_parent;
G_DEFINE_TYPE_EXTENDED (MMBroadbandModemIcera, mm_broadband_modem_icera, MM_TYPE_BROADBAND_MODEM, 0,
G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM, iface_modem_init)
G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM_3GPP, iface_modem_3gpp_init)
G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM_TIME, iface_modem_time_init));
G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM_TIME, iface_modem_time_init))
enum {
PROP_0,
@@ -66,6 +67,88 @@ struct _MMBroadbandModemIceraPrivate {
MMModemAccessTechnology last_act;
};
/*****************************************************************************/
/* Load supported modes (Modem interface) */
static GArray *
load_supported_modes_finish (MMIfaceModem *self,
GAsyncResult *res,
GError **error)
{
if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error))
return NULL;
return g_array_ref (g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (res)));
}
static void
parent_load_supported_modes_ready (MMIfaceModem *self,
GAsyncResult *res,
GSimpleAsyncResult *simple)
{
GError *error = NULL;
GArray *all;
GArray *combinations;
GArray *filtered;
MMModemModeCombination mode;
all = iface_modem_parent->load_supported_modes_finish (self, res, &error);
if (!all) {
g_simple_async_result_take_error (simple, error);
g_simple_async_result_complete (simple);
g_object_unref (simple);
return;
}
/* Build list of combinations */
combinations = g_array_sized_new (FALSE, FALSE, sizeof (MMModemModeCombination), 5);
/* 2G only */
mode.allowed = MM_MODEM_MODE_2G;
mode.preferred = MM_MODEM_MODE_NONE;
g_array_append_val (combinations, mode);
/* 3G only */
mode.allowed = MM_MODEM_MODE_3G;
mode.preferred = MM_MODEM_MODE_NONE;
g_array_append_val (combinations, mode);
/* 2G and 3G */
mode.allowed = (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G);
mode.preferred = MM_MODEM_MODE_NONE;
g_array_append_val (combinations, mode);
/* 2G and 3G, 2G preferred */
mode.allowed = (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G);
mode.preferred = MM_MODEM_MODE_2G;
g_array_append_val (combinations, mode);
/* 2G and 3G, 3G preferred */
mode.allowed = (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G);
mode.preferred = MM_MODEM_MODE_3G;
g_array_append_val (combinations, mode);
/* Filter out those unsupported modes */
filtered = mm_filter_supported_modes (all, combinations);
g_array_unref (all);
g_array_unref (combinations);
g_simple_async_result_set_op_res_gpointer (simple, filtered, (GDestroyNotify) g_array_unref);
g_simple_async_result_complete (simple);
g_object_unref (simple);
}
static void
load_supported_modes (MMIfaceModem *self,
GAsyncReadyCallback callback,
gpointer user_data)
{
/* Run parent's loading */
iface_modem_parent->load_supported_modes (
MM_IFACE_MODEM (self),
(GAsyncReadyCallback)parent_load_supported_modes_ready,
g_simple_async_result_new (G_OBJECT (self),
callback,
user_data,
load_supported_modes));
}
/*****************************************************************************/
/* Load initial allowed/preferred modes (Modem interface) */
@@ -201,7 +284,8 @@ modem_set_allowed_modes (MMIfaceModem *self,
icera_mode = 3;
else /* none preferred, so AUTO */
icera_mode = 5;
}
} else if (allowed == MM_MODEM_MODE_ANY && preferred == MM_MODEM_MODE_NONE)
icera_mode = 5;
if (icera_mode < 0) {
gchar *allowed_str;
@@ -1769,6 +1853,10 @@ finalize (GObject *object)
static void
iface_modem_init (MMIfaceModem *iface)
{
iface_modem_parent = g_type_interface_peek_parent (iface);
iface->load_supported_modes = load_supported_modes;
iface->load_supported_modes_finish = load_supported_modes_finish;
iface->load_allowed_modes = modem_load_allowed_modes;
iface->load_allowed_modes_finish = modem_load_allowed_modes_finish;
iface->set_allowed_modes = modem_set_allowed_modes;

View File

@@ -219,13 +219,12 @@ setup_flow_control (MMIfaceModem *self,
/*****************************************************************************/
/* Load supported modes (Modem inteface) */
static MMModemMode
static GArray *
load_supported_modes_finish (MMIfaceModem *self,
GAsyncResult *res,
GError **error)
{
/* Report CS only, Iridium connections are circuit-switched */
return MM_MODEM_MODE_CS;
return g_array_ref (g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (res)));
}
static void
@@ -234,11 +233,23 @@ load_supported_modes (MMIfaceModem *self,
gpointer user_data)
{
GSimpleAsyncResult *result;
GArray *combinations;
MMModemModeCombination mode;
result = g_simple_async_result_new (G_OBJECT (self),
callback,
user_data,
load_supported_modes);
/* Build list of combinations */
combinations = g_array_sized_new (FALSE, FALSE, sizeof (MMModemModeCombination), 1);
/* Report CS only, Iridium connections are circuit-switched */
mode.allowed = MM_MODEM_MODE_CS;
mode.preferred = MM_MODEM_MODE_NONE;
g_array_append_val (combinations, mode);
g_simple_async_result_set_op_res_gpointer (result, combinations, (GDestroyNotify) g_array_unref);
g_simple_async_result_complete_in_idle (result);
g_object_unref (result);
}

View File

@@ -40,8 +40,84 @@
static void iface_modem_init (MMIfaceModem *iface);
static MMIfaceModem *iface_modem_parent;
G_DEFINE_TYPE_EXTENDED (MMBroadbandModemLinktop, mm_broadband_modem_linktop, MM_TYPE_BROADBAND_MODEM, 0,
G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM, iface_modem_init));
G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM, iface_modem_init))
/*****************************************************************************/
/* Load supported modes (Modem interface) */
static GArray *
load_supported_modes_finish (MMIfaceModem *self,
GAsyncResult *res,
GError **error)
{
if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error))
return NULL;
return g_array_ref (g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (res)));
}
static void
parent_load_supported_modes_ready (MMIfaceModem *self,
GAsyncResult *res,
GSimpleAsyncResult *simple)
{
GError *error = NULL;
GArray *all;
GArray *combinations;
GArray *filtered;
MMModemModeCombination mode;
all = iface_modem_parent->load_supported_modes_finish (self, res, &error);
if (!all) {
g_simple_async_result_take_error (simple, error);
g_simple_async_result_complete (simple);
g_object_unref (simple);
return;
}
/* Build list of combinations */
combinations = g_array_sized_new (FALSE, FALSE, sizeof (MMModemModeCombination), 3);
/* 2G only */
mode.allowed = MM_MODEM_MODE_2G;
mode.preferred = MM_MODEM_MODE_NONE;
g_array_append_val (combinations, mode);
/* 3G only */
mode.allowed = MM_MODEM_MODE_3G;
mode.preferred = MM_MODEM_MODE_NONE;
g_array_append_val (combinations, mode);
/* 2G and 3G */
mode.allowed = (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G);
mode.preferred = MM_MODEM_MODE_NONE;
g_array_append_val (combinations, mode);
/* Filter out those unsupported modes */
filtered = mm_filter_supported_modes (all, combinations);
g_array_unref (all);
g_array_unref (combinations);
g_simple_async_result_set_op_res_gpointer (simple, filtered, (GDestroyNotify) g_array_unref);
g_simple_async_result_complete (simple);
g_object_unref (simple);
}
static void
load_supported_modes (MMIfaceModem *self,
GAsyncReadyCallback callback,
gpointer user_data)
{
/* Run parent's loading */
iface_modem_parent->load_supported_modes (
MM_IFACE_MODEM (self),
(GAsyncReadyCallback)parent_load_supported_modes_ready,
g_simple_async_result_new (G_OBJECT (self),
callback,
user_data,
load_supported_modes));
}
/*****************************************************************************/
/* Load initial allowed/preferred modes (Modem interface) */
@@ -158,9 +234,11 @@ set_allowed_modes (MMIfaceModem *self,
else if (allowed == MM_MODEM_MODE_3G)
linktop_mode = LINKTOP_MODE_3G;
else if ((allowed == (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G)) &&
(preferred == MM_MODEM_MODE_NONE)) {
(preferred == MM_MODEM_MODE_NONE))
linktop_mode = LINKTOP_MODE_ANY;
else if ((allowed == MM_MODEM_MODE_ANY &&
preferred == MM_MODEM_MODE_NONE))
linktop_mode = LINKTOP_MODE_ANY;
}
if (linktop_mode < 0) {
gchar *allowed_str;
@@ -220,6 +298,10 @@ mm_broadband_modem_linktop_init (MMBroadbandModemLinktop *self)
static void
iface_modem_init (MMIfaceModem *iface)
{
iface_modem_parent = g_type_interface_peek_parent (iface);
iface->load_supported_modes = load_supported_modes;
iface->load_supported_modes_finish = load_supported_modes_finish;
iface->load_allowed_modes = load_allowed_modes;
iface->load_allowed_modes_finish = load_allowed_modes_finish;
iface->set_allowed_modes = set_allowed_modes;

View File

@@ -33,8 +33,88 @@
static void iface_modem_init (MMIfaceModem *iface);
static MMIfaceModem *iface_modem_parent;
G_DEFINE_TYPE_EXTENDED (MMBroadbandModemLongcheer, mm_broadband_modem_longcheer, MM_TYPE_BROADBAND_MODEM, 0,
G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM, iface_modem_init));
G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM, iface_modem_init))
/*****************************************************************************/
/* Load supported modes (Modem interface) */
static GArray *
load_supported_modes_finish (MMIfaceModem *self,
GAsyncResult *res,
GError **error)
{
if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error))
return NULL;
return g_array_ref (g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (res)));
}
static void
parent_load_supported_modes_ready (MMIfaceModem *self,
GAsyncResult *res,
GSimpleAsyncResult *simple)
{
GError *error = NULL;
GArray *all;
GArray *combinations;
GArray *filtered;
MMModemModeCombination mode;
all = iface_modem_parent->load_supported_modes_finish (self, res, &error);
if (!all) {
g_simple_async_result_take_error (simple, error);
g_simple_async_result_complete (simple);
g_object_unref (simple);
return;
}
/* Build list of combinations */
combinations = g_array_sized_new (FALSE, FALSE, sizeof (MMModemModeCombination), 4);
/* 2G only */
mode.allowed = MM_MODEM_MODE_2G;
mode.preferred = MM_MODEM_MODE_NONE;
g_array_append_val (combinations, mode);
/* 3G only */
mode.allowed = MM_MODEM_MODE_3G;
mode.preferred = MM_MODEM_MODE_NONE;
g_array_append_val (combinations, mode);
/* 2G and 3G, 2G preferred */
mode.allowed = (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G);
mode.preferred = MM_MODEM_MODE_2G;
g_array_append_val (combinations, mode);
/* 2G and 3G, 3G preferred */
mode.allowed = (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G);
mode.preferred = MM_MODEM_MODE_3G;
g_array_append_val (combinations, mode);
/* Filter out those unsupported modes */
filtered = mm_filter_supported_modes (all, combinations);
g_array_unref (all);
g_array_unref (combinations);
g_simple_async_result_set_op_res_gpointer (simple, filtered, (GDestroyNotify) g_array_unref);
g_simple_async_result_complete (simple);
g_object_unref (simple);
}
static void
load_supported_modes (MMIfaceModem *self,
GAsyncReadyCallback callback,
gpointer user_data)
{
/* Run parent's loading */
iface_modem_parent->load_supported_modes (
MM_IFACE_MODEM (self),
(GAsyncReadyCallback)parent_load_supported_modes_ready,
g_simple_async_result_new (G_OBJECT (self),
callback,
user_data,
load_supported_modes));
}
/*****************************************************************************/
/* Load initial allowed/preferred modes (Modem interface) */
@@ -76,16 +156,16 @@ load_allowed_modes_finish (MMIfaceModem *self,
*allowed = (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G);
*preferred = MM_MODEM_MODE_3G;
return TRUE;
case 4:
/* GSM preferred */
*allowed = (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G);
*preferred = MM_MODEM_MODE_2G;
return TRUE;
case 3:
/* GSM only */
*allowed = MM_MODEM_MODE_2G;
*preferred = MM_MODEM_MODE_NONE;
return TRUE;
case 4:
/* GSM preferred */
*allowed = (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G);
*preferred = MM_MODEM_MODE_2G;
return TRUE;
default:
break;
}
@@ -159,14 +239,14 @@ set_allowed_modes (MMIfaceModem *self,
mododr = 3;
else if (allowed == MM_MODEM_MODE_3G)
mododr = 1;
else if (allowed == MM_MODEM_MODE_ANY || (allowed == (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G))) {
else if (allowed == (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G)) {
if (preferred == MM_MODEM_MODE_2G)
mododr = 4;
else if (preferred == MM_MODEM_MODE_3G ||
preferred == MM_MODEM_MODE_NONE ||
preferred == MM_MODEM_MODE_ANY)
else if (preferred == MM_MODEM_MODE_3G)
mododr = 2;
}
} else if (allowed == MM_MODEM_MODE_ANY && preferred == MM_MODEM_MODE_NONE)
/* Default to 3G preferred */
mododr = 2;
if (mododr == 0) {
gchar *allowed_str;
@@ -338,8 +418,12 @@ mm_broadband_modem_longcheer_init (MMBroadbandModemLongcheer *self)
static void
iface_modem_init (MMIfaceModem *iface)
{
iface_modem_parent = g_type_interface_peek_parent (iface);
iface->load_access_technologies = load_access_technologies;
iface->load_access_technologies_finish = load_access_technologies_finish;
iface->load_supported_modes = load_supported_modes;
iface->load_supported_modes_finish = load_supported_modes_finish;
iface->load_allowed_modes = load_allowed_modes;
iface->load_allowed_modes_finish = load_allowed_modes_finish;
iface->set_allowed_modes = set_allowed_modes;

View File

@@ -45,6 +45,7 @@
static void iface_modem_init (MMIfaceModem *iface);
static void iface_modem_3gpp_init (MMIfaceModem3gpp *iface);
static MMIfaceModem *iface_modem_parent;
static MMIfaceModem3gpp *iface_modem_3gpp_parent;
G_DEFINE_TYPE_EXTENDED (MMBroadbandModemMbm, mm_broadband_modem_mbm, MM_TYPE_BROADBAND_MODEM, 0,
@@ -190,6 +191,80 @@ modem_after_sim_unlock (MMIfaceModem *self,
g_timeout_add (500, (GSourceFunc)after_sim_unlock_wait_cb, result);
}
/*****************************************************************************/
/* Load supported modes (Modem interface) */
static GArray *
load_supported_modes_finish (MMIfaceModem *self,
GAsyncResult *res,
GError **error)
{
if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error))
return NULL;
return g_array_ref (g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (res)));
}
static void
parent_load_supported_modes_ready (MMIfaceModem *self,
GAsyncResult *res,
GSimpleAsyncResult *simple)
{
GError *error = NULL;
GArray *all;
GArray *combinations;
GArray *filtered;
MMModemModeCombination mode;
all = iface_modem_parent->load_supported_modes_finish (self, res, &error);
if (!all) {
g_simple_async_result_take_error (simple, error);
g_simple_async_result_complete (simple);
g_object_unref (simple);
return;
}
/* Build list of combinations */
combinations = g_array_sized_new (FALSE, FALSE, sizeof (MMModemModeCombination), 3);
/* 2G only */
mode.allowed = MM_MODEM_MODE_2G;
mode.preferred = MM_MODEM_MODE_NONE;
g_array_append_val (combinations, mode);
/* 3G only */
mode.allowed = MM_MODEM_MODE_3G;
mode.preferred = MM_MODEM_MODE_NONE;
g_array_append_val (combinations, mode);
/* 2G and 3G */
mode.allowed = (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G);
mode.preferred = MM_MODEM_MODE_NONE;
g_array_append_val (combinations, mode);
/* Filter out those unsupported modes */
filtered = mm_filter_supported_modes (all, combinations);
g_array_unref (all);
g_array_unref (combinations);
g_simple_async_result_set_op_res_gpointer (simple, filtered, (GDestroyNotify) g_array_unref);
g_simple_async_result_complete (simple);
g_object_unref (simple);
}
static void
load_supported_modes (MMIfaceModem *self,
GAsyncReadyCallback callback,
gpointer user_data)
{
/* Run parent's loading */
iface_modem_parent->load_supported_modes (
MM_IFACE_MODEM (self),
(GAsyncReadyCallback)parent_load_supported_modes_ready,
g_simple_async_result_new (G_OBJECT (self),
callback,
user_data,
load_supported_modes));
}
/*****************************************************************************/
/* Load initial allowed/preferred modes (Modem interface) */
@@ -1237,12 +1312,16 @@ finalize (GObject *object)
static void
iface_modem_init (MMIfaceModem *iface)
{
iface_modem_parent = g_type_interface_peek_parent (iface);
iface->create_bearer = modem_create_bearer;
iface->create_bearer_finish = modem_create_bearer_finish;
iface->create_sim = create_sim;
iface->create_sim_finish = create_sim_finish;
iface->modem_after_sim_unlock = modem_after_sim_unlock;
iface->modem_after_sim_unlock_finish = modem_after_sim_unlock_finish;
iface->load_supported_modes = load_supported_modes;
iface->load_supported_modes_finish = load_supported_modes_finish;
iface->load_allowed_modes = load_allowed_modes;
iface->load_allowed_modes_finish = load_allowed_modes_finish;
iface->set_allowed_modes = set_allowed_modes;

View File

@@ -67,45 +67,6 @@ create_sim (MMIfaceModem *self,
user_data);
}
/*****************************************************************************/
/* Load supported modes (Modem interface) */
static MMModemMode
modem_load_supported_modes_finish (MMIfaceModem *self,
GAsyncResult *res,
GError **error)
{
return (MMModemMode)GPOINTER_TO_UINT (g_simple_async_result_get_op_res_gpointer (
G_SIMPLE_ASYNC_RESULT (res)));
}
static void
modem_load_supported_modes (MMIfaceModem *self,
GAsyncReadyCallback callback,
gpointer user_data)
{
GSimpleAsyncResult *result;
MMModemMode mode;
/* Nokia phones don't seem to like AT+WS46?, they just report 2G even if
* 3G is supported, so we'll just assume they actually do 3G. */
mode = (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G);
/* Then, if the modem has LTE caps, it does 4G */
if (mm_iface_modem_is_3gpp_lte (MM_IFACE_MODEM (self)))
mode |= MM_MODEM_MODE_4G;
result = g_simple_async_result_new (G_OBJECT (self),
callback,
user_data,
modem_load_supported_modes);
g_simple_async_result_set_op_res_gpointer (result,
GUINT_TO_POINTER (mode),
NULL);
g_simple_async_result_complete_in_idle (result);
g_object_unref (result);
}
/*****************************************************************************/
/* Load access technologies (Modem interface) */
@@ -407,8 +368,6 @@ iface_modem_init (MMIfaceModem *iface)
iface->modem_power_down = NULL;
iface->modem_power_down_finish = NULL;
iface->load_supported_modes = modem_load_supported_modes;
iface->load_supported_modes_finish = modem_load_supported_modes_finish;
iface->load_access_technologies = load_access_technologies;
iface->load_access_technologies_finish = load_access_technologies_finish;
}

View File

@@ -48,7 +48,89 @@ G_DEFINE_TYPE_EXTENDED (MMBroadbandModemNovatel, mm_broadband_modem_novatel, MM_
G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM, iface_modem_init)
G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM_MESSAGING, iface_modem_messaging_init)
G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM_CDMA, iface_modem_cdma_init)
G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM_TIME, iface_modem_time_init));
G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM_TIME, iface_modem_time_init))
/*****************************************************************************/
/* Load supported modes (Modem interface) */
static GArray *
load_supported_modes_finish (MMIfaceModem *self,
GAsyncResult *res,
GError **error)
{
if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error))
return NULL;
return g_array_ref (g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (res)));
}
static void
parent_load_supported_modes_ready (MMIfaceModem *self,
GAsyncResult *res,
GSimpleAsyncResult *simple)
{
GError *error = NULL;
GArray *all;
GArray *combinations;
GArray *filtered;
MMModemModeCombination mode;
all = iface_modem_parent->load_supported_modes_finish (self, res, &error);
if (!all) {
g_simple_async_result_take_error (simple, error);
g_simple_async_result_complete (simple);
g_object_unref (simple);
return;
}
/* Build list of combinations */
combinations = g_array_sized_new (FALSE, FALSE, sizeof (MMModemModeCombination), 5);
/* 2G only */
mode.allowed = MM_MODEM_MODE_2G;
mode.preferred = MM_MODEM_MODE_NONE;
g_array_append_val (combinations, mode);
/* 3G only */
mode.allowed = MM_MODEM_MODE_3G;
mode.preferred = MM_MODEM_MODE_NONE;
g_array_append_val (combinations, mode);
/* 2G and 3G */
mode.allowed = (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G);
mode.preferred = MM_MODEM_MODE_NONE;
g_array_append_val (combinations, mode);
/* 2G and 3G, 2G preferred */
mode.allowed = (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G);
mode.preferred = MM_MODEM_MODE_2G;
g_array_append_val (combinations, mode);
/* 2G and 3G, 3G preferred */
mode.allowed = (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G);
mode.preferred = MM_MODEM_MODE_3G;
g_array_append_val (combinations, mode);
/* Filter out those unsupported modes */
filtered = mm_filter_supported_modes (all, combinations);
g_array_unref (all);
g_array_unref (combinations);
g_simple_async_result_set_op_res_gpointer (simple, filtered, (GDestroyNotify) g_array_unref);
g_simple_async_result_complete (simple);
g_object_unref (simple);
}
static void
load_supported_modes (MMIfaceModem *self,
GAsyncReadyCallback callback,
gpointer user_data)
{
/* Run parent's loading */
iface_modem_parent->load_supported_modes (
MM_IFACE_MODEM (self),
(GAsyncReadyCallback)parent_load_supported_modes_ready,
g_simple_async_result_new (G_OBJECT (self),
callback,
user_data,
load_supported_modes));
}
/*****************************************************************************/
/* Load initial allowed/preferred modes (Modem interface) */
@@ -275,6 +357,10 @@ set_allowed_modes (MMIfaceModem *self,
a = 1;
else if (preferred == MM_MODEM_MODE_3G)
a = 2;
} else if (allowed == MM_MODEM_MODE_ANY &&
preferred == MM_MODEM_MODE_NONE) {
b = 2;
a = 0;
}
if (a < 0 || b < 0) {
@@ -1149,6 +1235,8 @@ iface_modem_init (MMIfaceModem *iface)
{
iface_modem_parent = g_type_interface_peek_parent (iface);
iface->load_supported_modes = load_supported_modes;
iface->load_supported_modes_finish = load_supported_modes_finish;
iface->load_allowed_modes = load_allowed_modes;
iface->load_allowed_modes_finish = load_allowed_modes_finish;
iface->set_allowed_modes = set_allowed_modes;

View File

@@ -35,11 +35,12 @@
static void iface_modem_init (MMIfaceModem *iface);
static void iface_modem_3gpp_init (MMIfaceModem3gpp *iface);
static MMIfaceModem *iface_modem_parent;
static MMIfaceModem3gpp *iface_modem_3gpp_parent;
G_DEFINE_TYPE_EXTENDED (MMBroadbandModemOption, mm_broadband_modem_option, MM_TYPE_BROADBAND_MODEM, 0,
G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM, iface_modem_init)
G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM_3GPP, iface_modem_3gpp_init));
G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM_3GPP, iface_modem_3gpp_init))
struct _MMBroadbandModemOptionPrivate {
/* Regex for access-technology related notifications */
@@ -56,6 +57,88 @@ struct _MMBroadbandModemOptionPrivate {
guint after_power_up_wait_id;
};
/*****************************************************************************/
/* Load supported modes (Modem interface) */
static GArray *
load_supported_modes_finish (MMIfaceModem *self,
GAsyncResult *res,
GError **error)
{
if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error))
return NULL;
return g_array_ref (g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (res)));
}
static void
parent_load_supported_modes_ready (MMIfaceModem *self,
GAsyncResult *res,
GSimpleAsyncResult *simple)
{
GError *error = NULL;
GArray *all;
GArray *combinations;
GArray *filtered;
MMModemModeCombination mode;
all = iface_modem_parent->load_supported_modes_finish (self, res, &error);
if (!all) {
g_simple_async_result_take_error (simple, error);
g_simple_async_result_complete (simple);
g_object_unref (simple);
return;
}
/* Build list of combinations */
combinations = g_array_sized_new (FALSE, FALSE, sizeof (MMModemModeCombination), 5);
/* 2G only */
mode.allowed = MM_MODEM_MODE_2G;
mode.preferred = MM_MODEM_MODE_NONE;
g_array_append_val (combinations, mode);
/* 3G only */
mode.allowed = MM_MODEM_MODE_3G;
mode.preferred = MM_MODEM_MODE_NONE;
g_array_append_val (combinations, mode);
/* 2G and 3G */
mode.allowed = (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G);
mode.preferred = MM_MODEM_MODE_NONE;
g_array_append_val (combinations, mode);
/* 2G and 3G, 2G preferred */
mode.allowed = (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G);
mode.preferred = MM_MODEM_MODE_2G;
g_array_append_val (combinations, mode);
/* 2G and 3G, 3G preferred */
mode.allowed = (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G);
mode.preferred = MM_MODEM_MODE_3G;
g_array_append_val (combinations, mode);
/* Filter out those unsupported modes */
filtered = mm_filter_supported_modes (all, combinations);
g_array_unref (all);
g_array_unref (combinations);
g_simple_async_result_set_op_res_gpointer (simple, filtered, (GDestroyNotify) g_array_unref);
g_simple_async_result_complete (simple);
g_object_unref (simple);
}
static void
load_supported_modes (MMIfaceModem *self,
GAsyncReadyCallback callback,
gpointer user_data)
{
/* Run parent's loading */
iface_modem_parent->load_supported_modes (
MM_IFACE_MODEM (self),
(GAsyncReadyCallback)parent_load_supported_modes_ready,
g_simple_async_result_new (G_OBJECT (self),
callback,
user_data,
load_supported_modes));
}
/*****************************************************************************/
/* Load initial allowed/preferred modes (Modem interface) */
@@ -186,7 +269,8 @@ set_allowed_modes (MMIfaceModem *self,
option_mode = 3;
else /* none preferred, so AUTO */
option_mode = 5;
}
} else if (allowed == MM_MODEM_MODE_ANY && preferred == MM_MODEM_MODE_NONE)
option_mode = 5;
if (option_mode < 0) {
gchar *allowed_str;
@@ -1140,10 +1224,14 @@ mm_broadband_modem_option_init (MMBroadbandModemOption *self)
static void
iface_modem_init (MMIfaceModem *iface)
{
iface_modem_parent = g_type_interface_peek_parent (iface);
iface->modem_after_power_up = modem_after_power_up;
iface->modem_after_power_up_finish = modem_after_power_up_finish;
iface->load_access_technologies = load_access_technologies;
iface->load_access_technologies_finish = load_access_technologies_finish;
iface->load_supported_modes = load_supported_modes;
iface->load_supported_modes_finish = load_supported_modes_finish;
iface->load_allowed_modes = load_allowed_modes;
iface->load_allowed_modes_finish = load_allowed_modes_finish;
iface->set_allowed_modes = set_allowed_modes;

View File

@@ -513,6 +513,109 @@ load_access_technologies (MMIfaceModem *self,
g_assert_not_reached ();
}
/*****************************************************************************/
/* Load supported modes (Modem interface) */
static GArray *
load_supported_modes_finish (MMIfaceModem *self,
GAsyncResult *res,
GError **error)
{
if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error))
return NULL;
return g_array_ref (g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (res)));
}
static void
parent_load_supported_modes_ready (MMIfaceModem *self,
GAsyncResult *res,
GSimpleAsyncResult *simple)
{
GError *error = NULL;
GArray *all;
GArray *combinations;
GArray *filtered;
MMModemModeCombination mode;
all = iface_modem_parent->load_supported_modes_finish (self, res, &error);
if (!all) {
g_simple_async_result_take_error (simple, error);
g_simple_async_result_complete (simple);
g_object_unref (simple);
return;
}
/* CDMA-only modems don't support changing modes, default to parent's */
if (!mm_iface_modem_is_3gpp (self)) {
g_simple_async_result_set_op_res_gpointer (simple, all, (GDestroyNotify) g_array_unref);
g_simple_async_result_complete_in_idle (simple);
g_object_unref (simple);
return;
}
/* Build list of combinations for 3GPP devices */
combinations = g_array_sized_new (FALSE, FALSE, sizeof (MMModemModeCombination), 5);
/* 2G only */
mode.allowed = MM_MODEM_MODE_2G;
mode.preferred = MM_MODEM_MODE_NONE;
g_array_append_val (combinations, mode);
/* 3G only */
mode.allowed = MM_MODEM_MODE_3G;
mode.preferred = MM_MODEM_MODE_NONE;
g_array_append_val (combinations, mode);
/* 2G and 3G */
mode.allowed = (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G);
mode.preferred = MM_MODEM_MODE_NONE;
g_array_append_val (combinations, mode);
/* Non-LTE devices allow 2G/3G preferred modes */
if (!mm_iface_modem_is_3gpp_lte (self)) {
/* 2G and 3G, 2G preferred */
mode.allowed = (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G);
mode.preferred = MM_MODEM_MODE_2G;
g_array_append_val (combinations, mode);
/* 2G and 3G, 3G preferred */
mode.allowed = (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G);
mode.preferred = MM_MODEM_MODE_3G;
g_array_append_val (combinations, mode);
} else {
/* 4G only */
mode.allowed = MM_MODEM_MODE_4G;
mode.preferred = MM_MODEM_MODE_NONE;
g_array_append_val (combinations, mode);
/* 2G, 3G and 4G */
mode.allowed = (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G | MM_MODEM_MODE_4G);
mode.preferred = MM_MODEM_MODE_NONE;
g_array_append_val (combinations, mode);
}
/* Filter out those unsupported modes */
filtered = mm_filter_supported_modes (all, combinations);
g_array_unref (all);
g_array_unref (combinations);
g_simple_async_result_set_op_res_gpointer (simple, filtered, (GDestroyNotify) g_array_unref);
g_simple_async_result_complete (simple);
g_object_unref (simple);
}
static void
load_supported_modes (MMIfaceModem *self,
GAsyncReadyCallback callback,
gpointer user_data)
{
/* Run parent's loading */
iface_modem_parent->load_supported_modes (
MM_IFACE_MODEM (self),
(GAsyncReadyCallback)parent_load_supported_modes_ready,
g_simple_async_result_new (G_OBJECT (self),
callback,
user_data,
load_supported_modes));
}
/*****************************************************************************/
/* Load initial allowed/preferred modes (Modem interface) */
@@ -569,7 +672,10 @@ selrat_query_ready (MMBaseModem *self,
if (mm_get_uint_from_match_info (match_info, 1, &mode) && mode <= 7) {
switch (mode) {
case 0:
result.allowed = MM_MODEM_MODE_ANY;
result.allowed = (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G);
result.preferred = MM_MODEM_MODE_NONE;
if (mm_iface_modem_is_3gpp_lte (MM_IFACE_MODEM (self)))
result.allowed |= MM_MODEM_MODE_4G;
result.preferred = MM_MODEM_MODE_NONE;
break;
case 1:
@@ -583,7 +689,7 @@ selrat_query_ready (MMBaseModem *self,
case 3:
/* in Sierra LTE devices, mode 3 is automatic, including LTE, no preference */
if (mm_iface_modem_is_3gpp_lte (MM_IFACE_MODEM (self))) {
result.allowed = MM_MODEM_MODE_ANY;
result.allowed = (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G | MM_MODEM_MODE_4G);
result.preferred = MM_MODEM_MODE_NONE;
} else {
result.allowed = (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G);
@@ -593,7 +699,7 @@ selrat_query_ready (MMBaseModem *self,
case 4:
/* in Sierra LTE devices, mode 4 is automatic, including LTE, no preference */
if (mm_iface_modem_is_3gpp_lte (MM_IFACE_MODEM (self))) {
result.allowed = MM_MODEM_MODE_ANY;
result.allowed = (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G | MM_MODEM_MODE_4G);
result.preferred = MM_MODEM_MODE_NONE;
} else {
result.allowed = (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G);
@@ -773,9 +879,10 @@ set_allowed_modes (MMIfaceModem *self,
idx = 0;
} else if (allowed == MM_MODEM_MODE_4G)
idx = 6;
else if (allowed == (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G | MM_MODEM_MODE_4G))
else if (allowed == (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G | MM_MODEM_MODE_4G) &&
preferred == MM_MODEM_MODE_NONE)
idx = 7;
else if (allowed == MM_MODEM_MODE_ANY)
else if (allowed == MM_MODEM_MODE_ANY && preferred == MM_MODEM_MODE_NONE)
idx = 0;
if (idx < 0) {
@@ -1556,6 +1663,8 @@ iface_modem_init (MMIfaceModem *iface)
mm_common_sierra_peek_parent_interfaces (iface);
iface->load_supported_modes = load_supported_modes;
iface->load_supported_modes_finish = load_supported_modes_finish;
iface->load_allowed_modes = load_allowed_modes;
iface->load_allowed_modes_finish = load_allowed_modes_finish;
iface->set_allowed_modes = set_allowed_modes;

View File

@@ -37,11 +37,12 @@
static void iface_modem_init (MMIfaceModem *iface);
static void iface_modem_3gpp_init (MMIfaceModem3gpp *iface);
static MMIfaceModem *iface_modem_parent;
static MMIfaceModem3gpp *iface_modem_3gpp_parent;
G_DEFINE_TYPE_EXTENDED (MMBroadbandModemSimtech, mm_broadband_modem_simtech, MM_TYPE_BROADBAND_MODEM, 0,
G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM, iface_modem_init)
G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM_3GPP, iface_modem_3gpp_init));
G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM_3GPP, iface_modem_3gpp_init))
/*****************************************************************************/
/* Setup/Cleanup unsolicited events (3GPP interface) */
@@ -444,6 +445,87 @@ load_access_technologies (MMIfaceModem *self,
result);
}
/*****************************************************************************/
/* Load supported modes (Modem interface) */
static GArray *
load_supported_modes_finish (MMIfaceModem *self,
GAsyncResult *res,
GError **error)
{
if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error))
return NULL;
return g_array_ref (g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (res)));
}
static void
parent_load_supported_modes_ready (MMIfaceModem *self,
GAsyncResult *res,
GSimpleAsyncResult *simple)
{
GError *error = NULL;
GArray *all;
GArray *combinations;
GArray *filtered;
MMModemModeCombination mode;
all = iface_modem_parent->load_supported_modes_finish (self, res, &error);
if (!all) {
g_simple_async_result_take_error (simple, error);
g_simple_async_result_complete (simple);
g_object_unref (simple);
return;
}
/* Build list of combinations */
combinations = g_array_sized_new (FALSE, FALSE, sizeof (MMModemModeCombination), 5);
/* 2G only */
mode.allowed = MM_MODEM_MODE_2G;
mode.preferred = MM_MODEM_MODE_NONE;
g_array_append_val (combinations, mode);
/* 3G only */
mode.allowed = MM_MODEM_MODE_3G;
mode.preferred = MM_MODEM_MODE_NONE;
g_array_append_val (combinations, mode);
/* 2G and 3G */
mode.allowed = (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G);
mode.preferred = MM_MODEM_MODE_NONE;
g_array_append_val (combinations, mode);
/* 2G and 3G, 2G preferred */
mode.allowed = (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G);
mode.preferred = MM_MODEM_MODE_2G;
g_array_append_val (combinations, mode);
/* 2G and 3G, 3G preferred */
mode.allowed = (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G);
mode.preferred = MM_MODEM_MODE_3G;
g_array_append_val (combinations, mode);
/* Filter out those unsupported modes */
filtered = mm_filter_supported_modes (all, combinations);
g_array_unref (all);
g_array_unref (combinations);
g_simple_async_result_set_op_res_gpointer (simple, filtered, (GDestroyNotify) g_array_unref);
g_simple_async_result_complete (simple);
g_object_unref (simple);
}
static void
load_supported_modes (MMIfaceModem *self,
GAsyncReadyCallback callback,
gpointer user_data)
{
/* Run parent's loading */
iface_modem_parent->load_supported_modes (
MM_IFACE_MODEM (self),
(GAsyncReadyCallback)parent_load_supported_modes_ready,
g_simple_async_result_new (G_OBJECT (self),
callback,
user_data,
load_supported_modes));
}
/*****************************************************************************/
/* Load initial allowed/preferred modes (Modem interface) */
@@ -731,19 +813,28 @@ set_allowed_modes (MMIfaceModem *self,
user_data,
set_allowed_modes);
ctx->nmp = 2; /* automatic mode preference */
ctx->naop = 0; /* automatic acquisition order */
/* Defaults: automatic search */
ctx->nmp = 2;
ctx->naop = 0;
if (allowed == MM_MODEM_MODE_2G)
if (allowed == MM_MODEM_MODE_ANY &&
preferred == MM_MODEM_MODE_NONE) {
/* defaults nmp and naop */
} else if (allowed == MM_MODEM_MODE_2G) {
ctx->nmp = 13;
else if (allowed == MM_MODEM_MODE_3G)
ctx->naop = 0;
} else if (allowed == MM_MODEM_MODE_3G) {
ctx->nmp = 14;
else if (allowed == (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G)) {
ctx->naop = 0;
} else if (allowed == (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G)) {
/* default nmp */
if (preferred == MM_MODEM_MODE_2G)
ctx->naop = 3;
else if (preferred == MM_MODEM_MODE_3G)
ctx->naop = 2;
/* else, auto */
else
/* default naop */
ctx->naop = 0;
} else {
gchar *allowed_str;
gchar *preferred_str;
@@ -830,8 +921,12 @@ iface_modem_3gpp_init (MMIfaceModem3gpp *iface)
static void
iface_modem_init (MMIfaceModem *iface)
{
iface_modem_parent = g_type_interface_peek_parent (iface);
iface->load_access_technologies = load_access_technologies;
iface->load_access_technologies_finish = load_access_technologies_finish;
iface->load_supported_modes = load_supported_modes;
iface->load_supported_modes_finish = load_supported_modes_finish;
iface->load_allowed_modes = load_allowed_modes;
iface->load_allowed_modes_finish = load_allowed_modes_finish;
iface->set_allowed_modes = set_allowed_modes;

View File

@@ -37,6 +37,8 @@
static void iface_modem_init (MMIfaceModem *iface);
static MMIfaceModem *iface_modem_parent;
G_DEFINE_TYPE_EXTENDED (MMBroadbandModemWavecom, mm_broadband_modem_wavecom, MM_TYPE_BROADBAND_MODEM, 0,
G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM, iface_modem_init))
@@ -82,18 +84,17 @@ static const WavecomBand3G bands_3g[] = {
};
/*****************************************************************************/
/* Supported modes (Modem interface) */
/* Load supported modes (Modem interface) */
static MMModemMode
static GArray *
load_supported_modes_finish (MMIfaceModem *self,
GAsyncResult *res,
GError **error)
{
if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error))
return MM_MODEM_MODE_NONE;
return NULL;
return (MMModemMode) GPOINTER_TO_UINT (g_simple_async_result_get_op_res_gpointer (
G_SIMPLE_ASYNC_RESULT (res)));
return g_array_ref (g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (res)));
}
static void
@@ -101,9 +102,13 @@ supported_ms_classes_query_ready (MMBaseModem *self,
GAsyncResult *res,
GSimpleAsyncResult *simple)
{
GArray *all;
GArray *combinations;
GArray *filtered;
const gchar *response;
GError *error = NULL;
MMModemMode mode;
MMModemModeCombination mode;
MMModemMode mode_all;
response = mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, &error);
if (!response) {
@@ -115,40 +120,71 @@ supported_ms_classes_query_ready (MMBaseModem *self,
}
response = mm_strip_tag (response, "+CGCLASS:");
mode = MM_MODEM_MODE_NONE;
if (strstr (response, WAVECOM_MS_CLASS_A_IDSTR)) {
mm_dbg ("Modem supports Class A mobile station");
mode |= MM_MODEM_MODE_3G;
}
if (strstr (response, WAVECOM_MS_CLASS_B_IDSTR)) {
mm_dbg ("Modem supports Class B mobile station");
mode |= (MM_MODEM_MODE_2G | MM_MODEM_MODE_CS);
}
if (strstr (response, WAVECOM_MS_CLASS_CG_IDSTR)) {
mm_dbg ("Modem supports Class CG mobile station");
mode |= MM_MODEM_MODE_2G;
}
if (strstr (response, WAVECOM_MS_CLASS_CC_IDSTR)) {
mm_dbg ("Modem supports Class CC mobile station");
mode |= MM_MODEM_MODE_CS;
}
mode_all = MM_MODEM_MODE_NONE;
if (strstr (response, WAVECOM_MS_CLASS_A_IDSTR))
mode_all |= MM_MODEM_MODE_3G;
if (strstr (response, WAVECOM_MS_CLASS_B_IDSTR))
mode_all |= (MM_MODEM_MODE_2G | MM_MODEM_MODE_CS);
if (strstr (response, WAVECOM_MS_CLASS_CG_IDSTR))
mode_all |= MM_MODEM_MODE_2G;
if (strstr (response, WAVECOM_MS_CLASS_CC_IDSTR))
mode_all |= MM_MODEM_MODE_CS;
/* If none received, error */
if (mode == MM_MODEM_MODE_NONE)
if (mode_all == MM_MODEM_MODE_NONE) {
g_simple_async_result_set_error (simple,
MM_CORE_ERROR,
MM_CORE_ERROR_FAILED,
"Couldn't get supported mobile station classes: '%s'",
response);
else
g_simple_async_result_set_op_res_gpointer (simple,
GUINT_TO_POINTER (mode),
NULL);
g_simple_async_result_complete (simple);
g_object_unref (simple);
return;
}
/* Build ALL mask */
all = g_array_sized_new (FALSE, FALSE, sizeof (MMModemModeCombination), 1);
mode.allowed = mode_all;
mode.preferred = MM_MODEM_MODE_NONE;
g_array_append_val (all, mode);
/* Build list of combinations */
combinations = g_array_sized_new (FALSE, FALSE, sizeof (MMModemModeCombination), 7);
/* CS only */
mode.allowed = MM_MODEM_MODE_CS;
mode.preferred = MM_MODEM_MODE_NONE;
g_array_append_val (combinations, mode);
/* 2G only */
mode.allowed = MM_MODEM_MODE_2G;
mode.preferred = MM_MODEM_MODE_NONE;
g_array_append_val (combinations, mode);
/* CS and 2G */
mode.allowed = (MM_MODEM_MODE_CS | MM_MODEM_MODE_2G);
mode.preferred = MM_MODEM_MODE_2G;
g_array_append_val (combinations, mode);
/* 3G only */
mode.allowed = MM_MODEM_MODE_3G;
mode.preferred = MM_MODEM_MODE_NONE;
g_array_append_val (combinations, mode);
/* 2G and 3G */
mode.allowed = (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G);
mode.preferred = MM_MODEM_MODE_NONE;
g_array_append_val (combinations, mode);
/* 2G and 3G, 2G preferred */
mode.allowed = (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G);
mode.preferred = MM_MODEM_MODE_2G;
g_array_append_val (combinations, mode);
/* 2G and 3G, 3G preferred */
mode.allowed = (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G);
mode.preferred = MM_MODEM_MODE_3G;
g_array_append_val (combinations, mode);
/* Filter out those unsupported modes */
filtered = mm_filter_supported_modes (all, combinations);
g_array_unref (all);
g_array_unref (combinations);
g_simple_async_result_set_op_res_gpointer (simple, filtered, (GDestroyNotify) g_array_unref);
g_simple_async_result_complete (simple);
g_object_unref (simple);
}
@@ -158,20 +194,16 @@ load_supported_modes (MMIfaceModem *self,
GAsyncReadyCallback callback,
gpointer user_data)
{
GSimpleAsyncResult *result;
result = g_simple_async_result_new (G_OBJECT (self),
callback,
user_data,
load_supported_modes);
mm_base_modem_at_command (
MM_BASE_MODEM (self),
"+CGCLASS=?",
3,
FALSE,
(GAsyncReadyCallback)supported_ms_classes_query_ready,
result);
g_simple_async_result_new (G_OBJECT (self),
callback,
user_data,
load_supported_modes));
}
/*****************************************************************************/
@@ -387,8 +419,6 @@ load_allowed_modes (MMIfaceModem *self,
typedef struct {
MMBroadbandModemWavecom *self;
GSimpleAsyncResult *result;
MMModemMode allowed;
MMModemMode preferred;
gchar *cgclass_command;
gchar *wwsm_command;
} SetAllowedModesContext;
@@ -473,19 +503,27 @@ set_allowed_modes (MMIfaceModem *self,
callback,
user_data,
set_allowed_modes);
ctx->allowed = allowed;
ctx->preferred = preferred;
/* Handle ANY/NONE */
if (allowed == MM_MODEM_MODE_ANY && preferred == MM_MODEM_MODE_NONE) {
if (mm_iface_modem_is_3g (self)) {
allowed = (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G);
preferred = MM_MODEM_MODE_NONE;
} else {
allowed = (MM_MODEM_MODE_CS | MM_MODEM_MODE_2G);
preferred = MM_MODEM_MODE_2G;
}
}
if (allowed == MM_MODEM_MODE_CS)
ctx->cgclass_command = g_strdup ("+CGCLASS=" WAVECOM_MS_CLASS_CC_IDSTR);
else if (allowed == MM_MODEM_MODE_2G)
ctx->cgclass_command = g_strdup ("+CGCLASS=" WAVECOM_MS_CLASS_CG_IDSTR);
else if (allowed == (MM_MODEM_MODE_2G | MM_MODEM_MODE_CS) &&
preferred == MM_MODEM_MODE_NONE)
preferred == MM_MODEM_MODE_2G)
ctx->cgclass_command = g_strdup ("+CGCLASS=" WAVECOM_MS_CLASS_B_IDSTR);
else if (allowed & MM_MODEM_MODE_3G) {
if (allowed == (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G) ||
allowed == (MM_MODEM_MODE_CS | MM_MODEM_MODE_2G | MM_MODEM_MODE_3G)) {
if (allowed == (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G)) {
if (preferred == MM_MODEM_MODE_2G)
ctx->wwsm_command = g_strdup ("+WWSM=2,1");
else if (preferred == MM_MODEM_MODE_3G)
@@ -1144,6 +1182,8 @@ mm_broadband_modem_wavecom_init (MMBroadbandModemWavecom *self)
static void
iface_modem_init (MMIfaceModem *iface)
{
iface_modem_parent = g_type_interface_peek_parent (iface);
iface->load_supported_modes = load_supported_modes;
iface->load_supported_modes_finish = load_supported_modes_finish;
iface->load_allowed_modes = load_allowed_modes;

View File

@@ -33,8 +33,83 @@
static void iface_modem_init (MMIfaceModem *iface);
static MMIfaceModem *iface_modem_parent;
G_DEFINE_TYPE_EXTENDED (MMBroadbandModemX22x, mm_broadband_modem_x22x, MM_TYPE_BROADBAND_MODEM, 0,
G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM, iface_modem_init));
G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM, iface_modem_init))
/*****************************************************************************/
/* Load supported modes (Modem interface) */
static GArray *
load_supported_modes_finish (MMIfaceModem *self,
GAsyncResult *res,
GError **error)
{
if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error))
return NULL;
return g_array_ref (g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (res)));
}
static void
parent_load_supported_modes_ready (MMIfaceModem *self,
GAsyncResult *res,
GSimpleAsyncResult *simple)
{
GError *error = NULL;
GArray *all;
GArray *combinations;
GArray *filtered;
MMModemModeCombination mode;
all = iface_modem_parent->load_supported_modes_finish (self, res, &error);
if (!all) {
g_simple_async_result_take_error (simple, error);
g_simple_async_result_complete (simple);
g_object_unref (simple);
return;
}
/* Build list of combinations for 3GPP devices */
combinations = g_array_sized_new (FALSE, FALSE, sizeof (MMModemModeCombination), 3);
/* 2G only */
mode.allowed = MM_MODEM_MODE_2G;
mode.preferred = MM_MODEM_MODE_NONE;
g_array_append_val (combinations, mode);
/* 3G only */
mode.allowed = MM_MODEM_MODE_3G;
mode.preferred = MM_MODEM_MODE_NONE;
g_array_append_val (combinations, mode);
/* 2G and 3G */
mode.allowed = (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G);
mode.preferred = MM_MODEM_MODE_NONE;
g_array_append_val (combinations, mode);
/* Filter out those unsupported modes */
filtered = mm_filter_supported_modes (all, combinations);
g_array_unref (all);
g_array_unref (combinations);
g_simple_async_result_set_op_res_gpointer (simple, filtered, (GDestroyNotify) g_array_unref);
g_simple_async_result_complete (simple);
g_object_unref (simple);
}
static void
load_supported_modes (MMIfaceModem *self,
GAsyncReadyCallback callback,
gpointer user_data)
{
/* Run parent's loading */
iface_modem_parent->load_supported_modes (
MM_IFACE_MODEM (self),
(GAsyncReadyCallback)parent_load_supported_modes_ready,
g_simple_async_result_new (G_OBJECT (self),
callback,
user_data,
load_supported_modes));
}
/*****************************************************************************/
/* Load initial allowed/preferred modes (Modem interface) */
@@ -168,7 +243,8 @@ set_allowed_modes (MMIfaceModem *self,
else if (allowed == MM_MODEM_MODE_ANY &&
preferred == MM_MODEM_MODE_NONE)
syssel = 0;
else if (allowed == (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G))
else if (allowed == (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G) &&
preferred == MM_MODEM_MODE_NONE)
syssel = 0;
else {
gchar *allowed_str;
@@ -264,8 +340,12 @@ mm_broadband_modem_x22x_init (MMBroadbandModemX22x *self)
static void
iface_modem_init (MMIfaceModem *iface)
{
iface_modem_parent = g_type_interface_peek_parent (iface);
iface->load_access_technologies = load_access_technologies;
iface->load_access_technologies_finish = load_access_technologies_finish;
iface->load_supported_modes = load_supported_modes;
iface->load_supported_modes_finish = load_supported_modes_finish;
iface->load_allowed_modes = load_allowed_modes;
iface->load_allowed_modes_finish = load_allowed_modes_finish;
iface->set_allowed_modes = set_allowed_modes;

View File

@@ -249,6 +249,100 @@ modem_power_down (MMIfaceModem *self,
user_data);
}
/*****************************************************************************/
/* Load supported modes (Modem interface) */
static GArray *
load_supported_modes_finish (MMIfaceModem *self,
GAsyncResult *res,
GError **error)
{
if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error))
return NULL;
return g_array_ref (g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (res)));
}
static void
parent_load_supported_modes_ready (MMIfaceModem *self,
GAsyncResult *res,
GSimpleAsyncResult *simple)
{
GError *error = NULL;
GArray *all;
GArray *combinations;
GArray *filtered;
MMModemModeCombination mode;
all = iface_modem_parent->load_supported_modes_finish (self, res, &error);
if (!all) {
g_simple_async_result_take_error (simple, error);
g_simple_async_result_complete (simple);
g_object_unref (simple);
return;
}
/* Build list of combinations */
combinations = g_array_sized_new (FALSE, FALSE, sizeof (MMModemModeCombination), 5);
/* 2G only */
mode.allowed = MM_MODEM_MODE_2G;
mode.preferred = MM_MODEM_MODE_NONE;
g_array_append_val (combinations, mode);
/* 3G only */
mode.allowed = MM_MODEM_MODE_3G;
mode.preferred = MM_MODEM_MODE_NONE;
g_array_append_val (combinations, mode);
if (!mm_iface_modem_is_3gpp_lte (self)) {
/* 2G and 3G */
mode.allowed = (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G);
mode.preferred = MM_MODEM_MODE_NONE;
g_array_append_val (combinations, mode);
/* 2G and 3G, 2G preferred */
mode.allowed = (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G);
mode.preferred = MM_MODEM_MODE_2G;
g_array_append_val (combinations, mode);
/* 2G and 3G, 3G preferred */
mode.allowed = (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G);
mode.preferred = MM_MODEM_MODE_3G;
g_array_append_val (combinations, mode);
} else {
/* 4G only */
mode.allowed = MM_MODEM_MODE_4G;
mode.preferred = MM_MODEM_MODE_NONE;
g_array_append_val (combinations, mode);
/* 2G, 3G and 4G */
mode.allowed = (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G | MM_MODEM_MODE_4G);
mode.preferred = MM_MODEM_MODE_NONE;
g_array_append_val (combinations, mode);
}
/* Filter out those unsupported modes */
filtered = mm_filter_supported_modes (all, combinations);
g_array_unref (all);
g_array_unref (combinations);
g_simple_async_result_set_op_res_gpointer (simple, filtered, (GDestroyNotify) g_array_unref);
g_simple_async_result_complete (simple);
g_object_unref (simple);
}
static void
load_supported_modes (MMIfaceModem *self,
GAsyncReadyCallback callback,
gpointer user_data)
{
/* Run parent's loading */
iface_modem_parent->load_supported_modes (
MM_IFACE_MODEM (self),
(GAsyncReadyCallback)parent_load_supported_modes_ready,
g_simple_async_result_new (G_OBJECT (self),
callback,
user_data,
load_supported_modes));
}
/*****************************************************************************/
/* Load initial allowed/preferred modes (Modem interface) */
@@ -413,7 +507,12 @@ set_allowed_modes (MMIfaceModem *self,
pref_acq = 2;
else /* none preferred, so AUTO */
pref_acq = 0;
} else if (allowed == (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G | MM_MODEM_MODE_4G)) {
} else if (allowed == (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G | MM_MODEM_MODE_4G) &&
preferred == MM_MODEM_MODE_NONE) {
cm_mode = 0;
pref_acq = 0;
} else if (allowed == MM_MODEM_MODE_ANY &&
preferred == MM_MODEM_MODE_NONE) {
cm_mode = 0;
pref_acq = 0;
} else if (allowed == MM_MODEM_MODE_4G) {
@@ -679,6 +778,8 @@ iface_modem_init (MMIfaceModem *iface)
iface->modem_power_down_finish = modem_power_down_finish;
iface->load_access_technologies = load_access_technologies;
iface->load_access_technologies_finish = load_access_technologies_finish;
iface->load_supported_modes = load_supported_modes;
iface->load_supported_modes_finish = load_supported_modes_finish;
iface->load_allowed_modes = load_allowed_modes;
iface->load_allowed_modes_finish = load_allowed_modes_finish;
iface->set_allowed_modes = set_allowed_modes;

View File

@@ -370,62 +370,74 @@ modem_load_device_identifier (MMIfaceModem *self,
/*****************************************************************************/
/* Supported modes loading (Modem interface) */
static MMModemMode
modem_load_supported_modes_finish (MMIfaceModem *_self,
static GArray *
modem_load_supported_modes_finish (MMIfaceModem *self,
GAsyncResult *res,
GError **error)
{
MMModemMode mask;
MMBroadbandModemMbim *self = MM_BROADBAND_MODEM_MBIM (_self);
if (self->priv->caps_data_class == 0) {
g_set_error (error,
MM_CORE_ERROR,
MM_CORE_ERROR_FAILED,
"Data class not given in device capabilities");
return MM_MODEM_MODE_NONE;
}
mask = 0;
/* 3GPP... */
if (self->priv->caps_data_class & (MBIM_DATA_CLASS_GPRS |
MBIM_DATA_CLASS_EDGE))
mask |= MM_MODEM_MODE_2G;
if (self->priv->caps_data_class & (MBIM_DATA_CLASS_UMTS |
MBIM_DATA_CLASS_HSDPA |
MBIM_DATA_CLASS_HSUPA))
mask |= MM_MODEM_MODE_3G;
if (self->priv->caps_data_class & MBIM_DATA_CLASS_LTE)
mask |= MM_MODEM_MODE_4G;
/* 3GPP2... */
if (self->priv->caps_data_class & MBIM_DATA_CLASS_1XRTT)
mask |= MM_MODEM_MODE_2G;
if (self->priv->caps_data_class & (MBIM_DATA_CLASS_1XEVDO |
MBIM_DATA_CLASS_1XEVDO_REVA |
MBIM_DATA_CLASS_1XEVDV |
MBIM_DATA_CLASS_3XRTT |
MBIM_DATA_CLASS_1XEVDO_REVB))
mask |= MM_MODEM_MODE_3G;
if (self->priv->caps_data_class & MBIM_DATA_CLASS_UMB)
mask |= MM_MODEM_MODE_4G;
return mask;
return g_array_ref (g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (res)));
}
static void
modem_load_supported_modes (MMIfaceModem *self,
modem_load_supported_modes (MMIfaceModem *_self,
GAsyncReadyCallback callback,
gpointer user_data)
{
MMBroadbandModemMbim *self = MM_BROADBAND_MODEM_MBIM (_self);
GArray *combinations;
MMModemModeCombination mode;
GSimpleAsyncResult *result;
MMModemMode all;
/* Just complete */
result = g_simple_async_result_new (G_OBJECT (self),
callback,
user_data,
modem_load_supported_modes);
if (self->priv->caps_data_class == 0) {
g_simple_async_result_set_error (result,
MM_CORE_ERROR,
MM_CORE_ERROR_FAILED,
"Data class not given in device capabilities");
g_simple_async_result_complete_in_idle (result);
g_object_unref (result);
return;
}
all = 0;
/* 3GPP... */
if (self->priv->caps_data_class & (MBIM_DATA_CLASS_GPRS |
MBIM_DATA_CLASS_EDGE))
all |= MM_MODEM_MODE_2G;
if (self->priv->caps_data_class & (MBIM_DATA_CLASS_UMTS |
MBIM_DATA_CLASS_HSDPA |
MBIM_DATA_CLASS_HSUPA))
all |= MM_MODEM_MODE_3G;
if (self->priv->caps_data_class & MBIM_DATA_CLASS_LTE)
all |= MM_MODEM_MODE_4G;
/* 3GPP2... */
if (self->priv->caps_data_class & MBIM_DATA_CLASS_1XRTT)
all |= MM_MODEM_MODE_2G;
if (self->priv->caps_data_class & (MBIM_DATA_CLASS_1XEVDO |
MBIM_DATA_CLASS_1XEVDO_REVA |
MBIM_DATA_CLASS_1XEVDV |
MBIM_DATA_CLASS_3XRTT |
MBIM_DATA_CLASS_1XEVDO_REVB))
all |= MM_MODEM_MODE_3G;
if (self->priv->caps_data_class & MBIM_DATA_CLASS_UMB)
all |= MM_MODEM_MODE_4G;
/* Build a mask with all supported modes */
combinations = g_array_sized_new (FALSE, FALSE, sizeof (MMModemModeCombination), 1);
mode.allowed = all;
mode.preferred = MM_MODEM_MODE_NONE;
g_array_append_val (combinations, mode);
g_simple_async_result_set_op_res_gpointer (result, combinations, (GDestroyNotify) g_array_unref);
g_simple_async_result_complete_in_idle (result);
g_object_unref (result);
}

View File

@@ -65,6 +65,9 @@ struct _MMBroadbandModemQmiPrivate {
gchar *meid;
gchar *esn;
/* Cached supported radio interfaces; in order to load supported modes */
GArray *supported_radio_interfaces;
/* Cached supported frequency bands; in order to handle ANY */
GArray *supported_bands;
@@ -554,6 +557,20 @@ modem_load_current_capabilities (MMIfaceModem *self,
/*****************************************************************************/
/* Modem Capabilities loading (Modem interface) */
typedef struct {
MMBroadbandModemQmi *self;
GSimpleAsyncResult *result;
} LoadModemCapabilitiesContext;
static void
load_modem_capabilities_context_complete_and_free (LoadModemCapabilitiesContext *ctx)
{
g_simple_async_result_complete (ctx->result);
g_object_unref (ctx->result);
g_object_unref (ctx->self);
g_slice_free (LoadModemCapabilitiesContext, ctx);
}
static MMModemCapability
modem_load_modem_capabilities_finish (MMIfaceModem *self,
GAsyncResult *res,
@@ -577,7 +594,7 @@ modem_load_modem_capabilities_finish (MMIfaceModem *self,
static void
dms_get_capabilities_ready (QmiClientDms *client,
GAsyncResult *res,
GSimpleAsyncResult *simple)
LoadModemCapabilitiesContext *ctx)
{
QmiMessageDmsGetCapabilitiesOutput *output = NULL;
GError *error = NULL;
@@ -585,10 +602,10 @@ dms_get_capabilities_ready (QmiClientDms *client,
output = qmi_client_dms_get_capabilities_finish (client, res, &error);
if (!output) {
g_prefix_error (&error, "QMI operation failed: ");
g_simple_async_result_take_error (simple, error);
g_simple_async_result_take_error (ctx->result, error);
} else if (!qmi_message_dms_get_capabilities_output_get_result (output, &error)) {
g_prefix_error (&error, "Couldn't get modem capabilities: ");
g_simple_async_result_take_error (simple, error);
g_simple_async_result_take_error (ctx->result, error);
} else {
guint i;
guint mask = MM_MODEM_CAPABILITY_NONE;
@@ -609,7 +626,12 @@ dms_get_capabilities_ready (QmiClientDms *client,
i));
}
g_simple_async_result_set_op_res_gpointer (simple,
/* Cache supported radio interfaces */
if (ctx->self->priv->supported_radio_interfaces)
g_array_unref (ctx->self->priv->supported_radio_interfaces);
ctx->self->priv->supported_radio_interfaces = g_array_ref (radio_interface_list);
g_simple_async_result_set_op_res_gpointer (ctx->result,
GUINT_TO_POINTER (mask),
NULL);
}
@@ -617,8 +639,7 @@ dms_get_capabilities_ready (QmiClientDms *client,
if (output)
qmi_message_dms_get_capabilities_output_unref (output);
g_simple_async_result_complete (simple);
g_object_unref (simple);
load_modem_capabilities_context_complete_and_free (ctx);
}
static void
@@ -626,7 +647,7 @@ modem_load_modem_capabilities (MMIfaceModem *self,
GAsyncReadyCallback callback,
gpointer user_data)
{
GSimpleAsyncResult *result;
LoadModemCapabilitiesContext *ctx;
QmiClient *client = NULL;
if (!ensure_qmi_client (MM_BROADBAND_MODEM_QMI (self),
@@ -634,10 +655,12 @@ modem_load_modem_capabilities (MMIfaceModem *self,
callback, user_data))
return;
result = g_simple_async_result_new (G_OBJECT (self),
callback,
user_data,
modem_load_modem_capabilities);
ctx = g_slice_new (LoadModemCapabilitiesContext);
ctx->self = g_object_ref (self);
ctx->result = g_simple_async_result_new (G_OBJECT (self),
callback,
user_data,
modem_load_modem_capabilities);
mm_dbg ("loading modem capabilities...");
qmi_client_dms_get_capabilities (QMI_CLIENT_DMS (client),
@@ -645,7 +668,7 @@ modem_load_modem_capabilities (MMIfaceModem *self,
5,
NULL,
(GAsyncReadyCallback)dms_get_capabilities_ready,
result);
ctx);
}
/*****************************************************************************/
@@ -1711,37 +1734,89 @@ set_current_bands (MMIfaceModem *_self,
/*****************************************************************************/
/* Load supported modes (Modem interface) */
static MMModemMode
static GArray *
modem_load_supported_modes_finish (MMIfaceModem *self,
GAsyncResult *res,
GError **error)
{
return (MMModemMode)GPOINTER_TO_UINT (g_simple_async_result_get_op_res_gpointer (
G_SIMPLE_ASYNC_RESULT (res)));
return g_array_ref (g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (res)));
}
static void
modem_load_supported_modes (MMIfaceModem *self,
modem_load_supported_modes (MMIfaceModem *_self,
GAsyncReadyCallback callback,
gpointer user_data)
{
MMBroadbandModemQmi *self = MM_BROADBAND_MODEM_QMI (_self);
GSimpleAsyncResult *result;
MMModemMode mode;
/* For QMI-powered modems, it is safe to assume they do 2G and 3G */
mode = (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G);
/* Then, if the modem has LTE caps, it does 4G */
if (mm_iface_modem_is_3gpp_lte (MM_IFACE_MODEM (self)))
mode |= MM_MODEM_MODE_4G;
GArray *all;
GArray *combinations;
GArray *filtered;
MMModemModeCombination mode;
guint i;
result = g_simple_async_result_new (G_OBJECT (self),
callback,
user_data,
modem_load_supported_modes);
g_simple_async_result_set_op_res_gpointer (result,
GUINT_TO_POINTER (mode),
NULL);
if (!self->priv->supported_radio_interfaces) {
g_simple_async_result_set_error (result,
MM_CORE_ERROR,
MM_CORE_ERROR_FAILED,
"Cannot load supported modes, no radio interface list");
g_simple_async_result_complete_in_idle (result);
g_object_unref (result);
return;
}
/* Build all, based on the supported radio interfaces */
mode.allowed = MM_MODEM_MODE_NONE;
for (i = 0; i < self->priv->supported_radio_interfaces->len; i++)
mode.allowed |= mm_modem_mode_from_qmi_radio_interface (g_array_index (self->priv->supported_radio_interfaces,
QmiDmsRadioInterface,
i));
mode.preferred = MM_MODEM_MODE_NONE;
all = g_array_sized_new (FALSE, FALSE, sizeof (MMModemModeCombination), 1);
g_array_append_val (all, mode);
/* Build combinations */
combinations = g_array_sized_new (FALSE, FALSE, sizeof (MMModemModeCombination), 7);
/* 2G only */
mode.allowed = MM_MODEM_MODE_2G;
mode.preferred = MM_MODEM_MODE_NONE;
g_array_append_val (combinations, mode);
/* 3G only */
mode.allowed = MM_MODEM_MODE_3G;
mode.preferred = MM_MODEM_MODE_NONE;
g_array_append_val (combinations, mode);
/* 2G and 3G */
mode.allowed = (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G);
mode.preferred = MM_MODEM_MODE_NONE;
g_array_append_val (combinations, mode);
/* 2G and 3G, 2G preferred */
mode.allowed = (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G);
mode.preferred = MM_MODEM_MODE_2G;
g_array_append_val (combinations, mode);
/* 2G and 3G, 3G preferred */
mode.allowed = (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G);
mode.preferred = MM_MODEM_MODE_3G;
g_array_append_val (combinations, mode);
/* 4G only */
mode.allowed = MM_MODEM_MODE_4G;
mode.preferred = MM_MODEM_MODE_NONE;
g_array_append_val (combinations, mode);
/* 2G, 3G and 4G */
mode.allowed = (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G | MM_MODEM_MODE_4G);
mode.preferred = MM_MODEM_MODE_NONE;
g_array_append_val (combinations, mode);
/* Filter out those unsupported modes */
filtered = mm_filter_supported_modes (all, combinations);
g_array_unref (all);
g_array_unref (combinations);
g_simple_async_result_set_op_res_gpointer (result, filtered, (GDestroyNotify) g_array_unref);
g_simple_async_result_complete_in_idle (result);
g_object_unref (result);
}
@@ -2842,8 +2917,16 @@ set_allowed_modes (MMIfaceModem *self,
callback,
user_data,
set_allowed_modes);
ctx->allowed = allowed;
ctx->preferred = preferred;
if (allowed == MM_MODEM_MODE_ANY && ctx->preferred == MM_MODEM_MODE_NONE) {
ctx->allowed = (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G);
ctx->preferred = MM_MODEM_MODE_NONE;
if (mm_iface_modem_is_3gpp_lte (self))
ctx->allowed |= MM_MODEM_MODE_4G;
} else {
ctx->allowed = allowed;
ctx->preferred = preferred;
}
/* System selection preference introduced in NAS 1.1 */
ctx->run_set_system_selection_preference = qmi_client_check_version (client, 1, 1);
@@ -8074,6 +8157,8 @@ finalize (GObject *object)
g_free (self->priv->current_operator_description);
if (self->priv->supported_bands)
g_array_unref (self->priv->supported_bands);
if (self->priv->supported_radio_interfaces)
g_array_unref (self->priv->supported_radio_interfaces);
G_OBJECT_CLASS (mm_broadband_modem_qmi_parent_class)->finalize (object);
}

View File

@@ -1286,19 +1286,28 @@ load_supported_modes_context_complete_and_free (LoadSupportedModesContext *ctx)
g_simple_async_result_complete (ctx->result);
g_object_unref (ctx->result);
g_object_unref (ctx->self);
g_free (ctx);
g_slice_free (LoadSupportedModesContext, ctx);
}
static MMModemMode
static GArray *
modem_load_supported_modes_finish (MMIfaceModem *self,
GAsyncResult *res,
GError **error)
{
if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error))
return MM_MODEM_MODE_NONE;
GArray *modes;
MMModemModeCombination mode;
return (MMModemMode)GPOINTER_TO_UINT (g_simple_async_result_get_op_res_gpointer (
G_SIMPLE_ASYNC_RESULT (res)));
if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error))
return NULL;
/* Build a mask with all supported modes */
modes = g_array_sized_new (FALSE, FALSE, sizeof (MMModemModeCombination), 1);
mode.allowed = (MMModemMode) GPOINTER_TO_UINT (g_simple_async_result_get_op_res_gpointer (
G_SIMPLE_ASYNC_RESULT (res)));
mode.preferred = MM_MODEM_MODE_NONE;
g_array_append_val (modes, mode);
return modes;
}
static void load_supported_modes_step (LoadSupportedModesContext *ctx);
@@ -1515,8 +1524,8 @@ modem_load_supported_modes (MMIfaceModem *self,
{
LoadSupportedModesContext *ctx;
mm_dbg ("loading initial supported modes...");
ctx = g_new0 (LoadSupportedModesContext, 1);
mm_dbg ("loading supported modes...");
ctx = g_slice_new0 (LoadSupportedModesContext);
ctx->self = g_object_ref (self);
ctx->result = g_simple_async_result_new (G_OBJECT (self),
callback,

View File

@@ -2178,9 +2178,11 @@ mm_iface_modem_set_allowed_modes (MMIfaceModem *self,
GAsyncReadyCallback callback,
gpointer user_data)
{
GArray *supported;
SetAllowedModesContext *ctx;
MMModemMode supported;
MMModemMode not_supported;
MMModemMode current_allowed;
MMModemMode current_preferred;
guint i;
/* If setting allowed modes is not implemented, report an error */
if (!MM_IFACE_MODEM_GET_INTERFACE (self)->set_allowed_modes ||
@@ -2201,6 +2203,8 @@ mm_iface_modem_set_allowed_modes (MMIfaceModem *self,
callback,
user_data,
mm_iface_modem_set_allowed_modes);
ctx->allowed = allowed;
ctx->preferred = preferred;
g_object_get (self,
MM_IFACE_MODEM_DBUS_SKELETON, &ctx->skeleton,
NULL);
@@ -2214,43 +2218,58 @@ mm_iface_modem_set_allowed_modes (MMIfaceModem *self,
}
/* Get list of supported modes */
supported = mm_gdbus_modem_get_supported_modes (ctx->skeleton);
supported = mm_common_mode_combinations_variant_to_garray (
mm_gdbus_modem_get_supported_modes (ctx->skeleton));
/* Whenever we get 'any', just reset to be equal to the list of supported modes */
if (allowed == MM_MODEM_MODE_ANY)
allowed = supported;
ctx->allowed = allowed;
ctx->preferred = preferred;
/* Check if we already are in the requested setup */
if (mm_gdbus_modem_get_allowed_modes (ctx->skeleton) == allowed &&
mm_gdbus_modem_get_preferred_mode (ctx->skeleton) == preferred) {
g_simple_async_result_set_op_res_gboolean (ctx->result, TRUE);
/* Don't allow mode switchin if only one item given in the supported list */
if (supported->len == 1) {
g_simple_async_result_set_error (ctx->result,
MM_CORE_ERROR,
MM_CORE_ERROR_UNSUPPORTED,
"Cannot change modes: only one combination supported");
g_array_unref (supported);
set_allowed_modes_context_complete_and_free (ctx);
return;
}
/* Check if any of the modes being allowed is not supported */
not_supported = ((supported ^ allowed) & allowed);
if (allowed == MM_MODEM_MODE_ANY &&
preferred == MM_MODEM_MODE_NONE) {
/* Allow allowed=ANY & preferred=NONE, all plugins should support it */
} else {
gboolean matched = FALSE;
/* Ensure allowed is a subset of supported */
if (not_supported) {
gchar *not_supported_str;
gchar *supported_str;
/* Check if the given combination is supported */
for (i = 0; !matched && i < supported->len; i++) {
MMModemModeCombination *supported_mode;
not_supported_str = mm_modem_mode_build_string_from_mask (not_supported);
supported_str = mm_modem_mode_build_string_from_mask (supported);
g_simple_async_result_set_error (ctx->result,
MM_CORE_ERROR,
MM_CORE_ERROR_UNSUPPORTED,
"Some of the allowed modes (%s) are not "
"supported (%s)",
not_supported_str,
supported_str);
g_free (supported_str);
g_free (not_supported_str);
supported_mode = &g_array_index (supported, MMModemModeCombination, i);
if ((supported_mode->allowed == MM_MODEM_MODE_ANY &&
supported_mode->preferred == MM_MODEM_MODE_NONE) ||
(supported_mode->allowed == allowed &&
supported_mode->preferred == preferred)) {
matched = TRUE;
}
}
if (!matched) {
g_simple_async_result_set_error (ctx->result,
MM_CORE_ERROR,
MM_CORE_ERROR_UNSUPPORTED,
"The given combination of allowed and preferred modes is not supported");
g_array_unref (supported);
set_allowed_modes_context_complete_and_free (ctx);
return;
}
}
g_array_unref (supported);
/* Check if we already are in the requested setup */
current_allowed = mm_gdbus_modem_get_allowed_modes (ctx->skeleton);
current_preferred = mm_gdbus_modem_get_preferred_mode (ctx->skeleton);
if (current_allowed == allowed &&
current_preferred == preferred) {
g_simple_async_result_set_op_res_gboolean (ctx->result, TRUE);
set_allowed_modes_context_complete_and_free (ctx);
return;
}
@@ -2275,6 +2294,8 @@ mm_iface_modem_set_allowed_modes (MMIfaceModem *self,
return;
}
ctx->allowed = allowed;
ctx->preferred = preferred;
MM_IFACE_MODEM_GET_INTERFACE (self)->set_allowed_modes (self,
allowed,
preferred,
@@ -3209,9 +3230,8 @@ load_allowed_modes_ready (MMIfaceModem *self,
mm_warn ("couldn't load current allowed/preferred modes: '%s'", error->message);
g_error_free (error);
/* If errors getting allowed modes, assume allowed=supported,
* and none preferred */
allowed = mm_gdbus_modem_get_supported_modes (ctx->skeleton);
/* If errors getting allowed modes, assume ANY/NONE */
allowed = MM_MODEM_MODE_ANY;
preferred = MM_MODEM_MODE_NONE;
}
@@ -3364,10 +3384,9 @@ interface_enabling_step (EnablingContext *ctx)
return;
}
/* If no way to get allowed modes, assume allowed=supported,
/* If no way to get allowed modes, assume allowed=any,
* and none preferred */
mm_gdbus_modem_set_allowed_modes (ctx->skeleton,
mm_gdbus_modem_get_supported_modes (ctx->skeleton));
mm_gdbus_modem_set_allowed_modes (ctx->skeleton, MM_MODEM_MODE_ANY);
mm_gdbus_modem_set_preferred_mode (ctx->skeleton, MM_MODEM_MODE_NONE);
/* Fall down to next step */
ctx->step++;
@@ -3652,13 +3671,13 @@ load_supported_modes_ready (MMIfaceModem *self,
InitializationContext *ctx)
{
GError *error = NULL;
MMModemMode modes;
GArray *modes_array;
modes = MM_IFACE_MODEM_GET_INTERFACE (self)->load_supported_modes_finish (self, res, &error);
if (modes != MM_MODEM_MODE_NONE) {
mm_gdbus_modem_set_supported_modes (ctx->skeleton, modes);
mm_gdbus_modem_set_allowed_modes (ctx->skeleton, modes);
modes_array = MM_IFACE_MODEM_GET_INTERFACE (self)->load_supported_modes_finish (self, res, &error);
if (modes_array != NULL) {
mm_gdbus_modem_set_supported_modes (ctx->skeleton,
mm_common_mode_combinations_garray_to_variant (modes_array));
g_array_unref (modes_array);
}
if (error) {
@@ -4010,18 +4029,30 @@ interface_initialization_step (InitializationContext *ctx)
ctx->step++;
case INITIALIZATION_STEP_SUPPORTED_MODES:
g_assert (MM_IFACE_MODEM_GET_INTERFACE (ctx->self)->load_supported_modes != NULL);
g_assert (MM_IFACE_MODEM_GET_INTERFACE (ctx->self)->load_supported_modes_finish != NULL);
if (MM_IFACE_MODEM_GET_INTERFACE (ctx->self)->load_supported_modes != NULL &&
MM_IFACE_MODEM_GET_INTERFACE (ctx->self)->load_supported_modes_finish != NULL) {
GArray *supported_modes;
MMModemModeCombination *mode = NULL;
/* Supported modes are meant to be loaded only once during the whole
* lifetime of the modem. Therefore, if we already have them loaded,
* don't try to load them again. */
if (mm_gdbus_modem_get_supported_modes (ctx->skeleton) == MM_MODEM_MODE_NONE) {
MM_IFACE_MODEM_GET_INTERFACE (ctx->self)->load_supported_modes (
ctx->self,
(GAsyncReadyCallback)load_supported_modes_ready,
ctx);
return;
supported_modes = (mm_common_mode_combinations_variant_to_garray (
mm_gdbus_modem_get_supported_modes (ctx->skeleton)));
/* Supported modes are meant to be loaded only once during the whole
* lifetime of the modem. Therefore, if we already have them loaded,
* don't try to load them again. */
if (supported_modes->len == 1)
mode = &g_array_index (supported_modes, MMModemModeCombination, 0);
if (supported_modes->len == 0 ||
(mode && mode->allowed == MM_MODEM_MODE_ANY && mode->preferred == MM_MODEM_MODE_NONE)) {
MM_IFACE_MODEM_GET_INTERFACE (ctx->self)->load_supported_modes (
ctx->self,
(GAsyncReadyCallback)load_supported_modes_ready,
ctx);
g_array_unref (supported_modes);
return;
}
g_array_unref (supported_modes);
}
/* Fall down to next step */
ctx->step++;
@@ -4257,7 +4288,7 @@ mm_iface_modem_initialize (MMIfaceModem *self,
mm_gdbus_modem_set_unlock_retries (skeleton, 0);
mm_gdbus_modem_set_access_technologies (skeleton, MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN);
mm_gdbus_modem_set_signal_quality (skeleton, g_variant_new ("(ub)", 0, FALSE));
mm_gdbus_modem_set_supported_modes (skeleton, MM_MODEM_MODE_NONE);
mm_gdbus_modem_set_supported_modes (skeleton, mm_common_build_mode_combinations_default ());
mm_gdbus_modem_set_allowed_modes (skeleton, MM_MODEM_MODE_NONE);
mm_gdbus_modem_set_preferred_mode (skeleton, MM_MODEM_MODE_NONE);
mm_gdbus_modem_set_supported_bands (skeleton, mm_common_build_bands_unknown ());
@@ -4357,10 +4388,12 @@ mm_iface_modem_get_access_technologies (MMIfaceModem *self)
/*****************************************************************************/
MMModemMode
mm_iface_modem_get_supported_modes (MMIfaceModem *self)
static gboolean
find_supported_mode (MMIfaceModem *self,
MMModemMode mode,
gboolean *only)
{
MMModemMode supported = MM_MODEM_MODE_NONE;
gboolean matched = FALSE;
MmGdbusModem *skeleton;
g_object_get (self,
@@ -4368,56 +4401,85 @@ mm_iface_modem_get_supported_modes (MMIfaceModem *self)
NULL);
if (skeleton) {
supported = mm_gdbus_modem_get_supported_modes (skeleton);
GArray *supported;
guint i;
guint n_unmatched = 0;
supported = mm_common_mode_combinations_variant_to_garray (
mm_gdbus_modem_get_supported_modes (skeleton));
/* Check if the given mode is supported */
for (i = 0; i < supported->len; i++) {
MMModemModeCombination *supported_mode;
supported_mode = &g_array_index (supported, MMModemModeCombination, i);
if (supported_mode->allowed & mode) {
matched = TRUE;
if (supported_mode->allowed != mode)
n_unmatched++;
} else
n_unmatched++;
if (matched && (only == NULL || n_unmatched > 0))
break;
}
if (only)
*only = (n_unmatched == 0);
g_array_unref (supported);
g_object_unref (skeleton);
}
return supported;
return matched;
}
gboolean
mm_iface_modem_is_2g (MMIfaceModem *self)
{
return (mm_iface_modem_get_supported_modes (self) & MM_MODEM_MODE_2G);
return find_supported_mode (self, MM_MODEM_MODE_2G, NULL);
}
gboolean
mm_iface_modem_is_2g_only (MMIfaceModem *self)
{
MMModemMode supported;
gboolean only;
supported = mm_iface_modem_get_supported_modes (self);
return !((MM_MODEM_MODE_2G ^ supported) & supported);
return (find_supported_mode (self, MM_MODEM_MODE_2G, &only) ?
only :
FALSE);
}
gboolean
mm_iface_modem_is_3g (MMIfaceModem *self)
{
return (mm_iface_modem_get_supported_modes (self) & MM_MODEM_MODE_3G);
return find_supported_mode (self, MM_MODEM_MODE_3G, NULL);
}
gboolean
mm_iface_modem_is_3g_only (MMIfaceModem *self)
{
MMModemMode supported;
gboolean only;
supported = mm_iface_modem_get_supported_modes (self);
return !((MM_MODEM_MODE_3G ^ supported) & supported);
return (find_supported_mode (self, MM_MODEM_MODE_3G, &only) ?
only :
FALSE);
}
gboolean
mm_iface_modem_is_4g (MMIfaceModem *self)
{
return (mm_iface_modem_get_supported_modes (self) & MM_MODEM_MODE_4G);
return find_supported_mode (self, MM_MODEM_MODE_4G, NULL);
}
gboolean
mm_iface_modem_is_4g_only (MMIfaceModem *self)
{
MMModemMode supported;
gboolean only;
supported = mm_iface_modem_get_supported_modes (self);
return !((MM_MODEM_MODE_4G ^ supported) & supported);
return (find_supported_mode (self, MM_MODEM_MODE_4G, &only) ?
only :
FALSE);
}
/*****************************************************************************/

View File

@@ -126,9 +126,9 @@ struct _MMIfaceModem {
void (*load_supported_modes) (MMIfaceModem *self,
GAsyncReadyCallback callback,
gpointer user_data);
MMModemMode (*load_supported_modes_finish) (MMIfaceModem *self,
GAsyncResult *res,
GError **error);
GArray * (*load_supported_modes_finish) (MMIfaceModem *self,
GAsyncResult *res,
GError **error);
/* Loading of the AllowedModes and PreferredMode properties */
void (*load_allowed_modes) (MMIfaceModem *self,
@@ -328,13 +328,12 @@ gboolean mm_iface_modem_is_cdma (MMIfaceModem *self);
gboolean mm_iface_modem_is_cdma_only (MMIfaceModem *self);
/* Helpers to query supported modes */
MMModemMode mm_iface_modem_get_supported_modes (MMIfaceModem *self);
gboolean mm_iface_modem_is_2g (MMIfaceModem *self);
gboolean mm_iface_modem_is_2g_only (MMIfaceModem *self);
gboolean mm_iface_modem_is_3g (MMIfaceModem *self);
gboolean mm_iface_modem_is_3g_only (MMIfaceModem *self);
gboolean mm_iface_modem_is_4g (MMIfaceModem *self);
gboolean mm_iface_modem_is_4g_only (MMIfaceModem *self);
gboolean mm_iface_modem_is_2g (MMIfaceModem *self);
gboolean mm_iface_modem_is_2g_only (MMIfaceModem *self);
gboolean mm_iface_modem_is_3g (MMIfaceModem *self);
gboolean mm_iface_modem_is_3g_only (MMIfaceModem *self);
gboolean mm_iface_modem_is_4g (MMIfaceModem *self);
gboolean mm_iface_modem_is_4g_only (MMIfaceModem *self);
/* Initialize Modem interface (async) */
void mm_iface_modem_initialize (MMIfaceModem *self,

View File

@@ -42,6 +42,29 @@ mm_modem_capability_from_qmi_radio_interface (QmiDmsRadioInterface network)
/*****************************************************************************/
MMModemMode
mm_modem_mode_from_qmi_radio_interface (QmiDmsRadioInterface network)
{
switch (network) {
case QMI_DMS_RADIO_INTERFACE_CDMA20001X:
return MM_MODEM_MODE_2G;
case QMI_DMS_RADIO_INTERFACE_EVDO:
return MM_MODEM_MODE_3G;
case QMI_DMS_RADIO_INTERFACE_GSM:
return MM_MODEM_MODE_2G;
case QMI_DMS_RADIO_INTERFACE_UMTS:
return MM_MODEM_MODE_3G;
case QMI_DMS_RADIO_INTERFACE_LTE:
return MM_MODEM_MODE_4G;
default:
mm_warn ("Unhandled QMI radio interface (%u)",
(guint)network);
return MM_MODEM_MODE_NONE;
}
}
/*****************************************************************************/
/* pin1 TRUE for PIN1, FALSE for PIN2 */
MMModemLock
mm_modem_lock_from_qmi_uim_pin_status (QmiDmsUimPinStatus status,

View File

@@ -26,6 +26,8 @@
MMModemCapability mm_modem_capability_from_qmi_radio_interface (QmiDmsRadioInterface network);
MMModemMode mm_modem_mode_from_qmi_radio_interface (QmiDmsRadioInterface network);
MMModemLock mm_modem_lock_from_qmi_uim_pin_status (QmiDmsUimPinStatus status,
gboolean pin1);

View File

@@ -248,6 +248,53 @@ mm_new_iso8601_time (guint year,
/*****************************************************************************/
GArray *
mm_filter_supported_modes (const GArray *all,
const GArray *supported_combinations)
{
MMModemModeCombination all_item;
guint i;
GArray *filtered_combinations;
gboolean all_item_added = FALSE;
g_return_val_if_fail (all != NULL, NULL);
g_return_val_if_fail (all->len == 1, NULL);
g_return_val_if_fail (supported_combinations != NULL, NULL);
all_item = g_array_index (all, MMModemModeCombination, 0);
g_return_val_if_fail (all_item.allowed != MM_MODEM_MODE_NONE, NULL);
/* We will filter out all combinations which have modes not listed in 'all' */
filtered_combinations = g_array_sized_new (FALSE, FALSE, sizeof (MMModemModeCombination), supported_combinations->len);
for (i = 0; i < supported_combinations->len; i++) {
MMModemModeCombination *mode;
mode = &g_array_index (supported_combinations, MMModemModeCombination, i);
if (!(mode->allowed & ~all_item.allowed)) {
/* Compare only 'allowed', *not* preferred. If there is at least one item with allowed
* containing all supported modes, we're already good to go. This allows us to have a
* default with preferred != NONE (e.g. Wavecom 2G modem with allowed=CS+2G and
* preferred=2G */
if (all_item.allowed == mode->allowed)
all_item_added = TRUE;
g_array_append_val (filtered_combinations, *mode);
}
}
if (filtered_combinations->len == 0)
mm_warn ("All supported mode combinations were filtered out.");
/* Add default entry with the generic mask including all items */
if (!all_item_added) {
mm_dbg ("Adding an explicit item with all supported modes allowed");
g_array_append_val (filtered_combinations, all_item);
}
return filtered_combinations;
}
/*****************************************************************************/
/* +CREG: <stat> (GSM 07.07 CREG=1 unsolicited) */
#define CREG1 "\\+(CREG|CGREG|CEREG):\\s*0*([0-9])"

View File

@@ -73,6 +73,9 @@ gchar *mm_new_iso8601_time (guint year,
gboolean have_offset,
gint offset_minutes);
GArray *mm_filter_supported_modes (const GArray *all,
const GArray *supported_combinations);
/*****************************************************************************/
/* 3GPP specific helpers and utilities */
/*****************************************************************************/

View File

@@ -18,6 +18,7 @@
#include <string.h>
#include <stdlib.h>
#include <libmm-glib.h>
#include "mm-modem-helpers.h"
#include "mm-log.h"
@@ -1931,6 +1932,127 @@ test_cdma_parse_gsn (void *f, gpointer d)
/*****************************************************************************/
static gboolean
find_mode_combination (GArray *modes,
MMModemMode allowed,
MMModemMode preferred)
{
guint i;
for (i = 0; i < modes->len; i++) {
MMModemModeCombination *mode;
mode = &g_array_index (modes, MMModemModeCombination, i);
if (mode->allowed == allowed && mode->preferred == preferred)
return TRUE;
}
return FALSE;
}
static GArray *
build_mode_all (MMModemMode all_mask)
{
MMModemModeCombination all_item;
GArray *all;
all_item.allowed = all_mask;
all_item.preferred = MM_MODEM_MODE_NONE;
all = g_array_sized_new (FALSE, FALSE, sizeof (MMModemModeCombination), 1);
g_array_append_val (all, all_item);
return all;
}
static void
test_supported_mode_filter (void *f, gpointer d)
{
MMModemModeCombination mode;
GArray *all;
GArray *combinations;
GArray *filtered;
/* Build array of combinations */
combinations = g_array_sized_new (FALSE, FALSE, sizeof (MMModemModeCombination), 5);
/* 2G only */
mode.allowed = MM_MODEM_MODE_2G;
mode.preferred = MM_MODEM_MODE_NONE;
g_array_append_val (combinations, mode);
/* 3G only */
mode.allowed = MM_MODEM_MODE_3G;
mode.preferred = MM_MODEM_MODE_NONE;
g_array_append_val (combinations, mode);
/* 2G and 3G */
mode.allowed = (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G);
mode.preferred = MM_MODEM_MODE_NONE;
g_array_append_val (combinations, mode);
/* 4G only */
mode.allowed = MM_MODEM_MODE_4G;
mode.preferred = MM_MODEM_MODE_NONE;
g_array_append_val (combinations, mode);
/* 3G and 4G */
mode.allowed = (MM_MODEM_MODE_3G | MM_MODEM_MODE_4G);
mode.preferred = MM_MODEM_MODE_NONE;
g_array_append_val (combinations, mode);
/* 2G, 3G and 4G */
mode.allowed = (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G | MM_MODEM_MODE_4G);
mode.preferred = MM_MODEM_MODE_NONE;
g_array_append_val (combinations, mode);
/* Only 2G supported */
all = build_mode_all (MM_MODEM_MODE_2G);
filtered = mm_filter_supported_modes (all, combinations);
g_assert_cmpuint (filtered->len, ==, 1);
g_assert (find_mode_combination (filtered, MM_MODEM_MODE_2G, MM_MODEM_MODE_NONE));
g_array_unref (filtered);
g_array_unref (all);
/* Only 3G supported */
all = build_mode_all (MM_MODEM_MODE_3G);
filtered = mm_filter_supported_modes (all, combinations);
g_assert_cmpuint (filtered->len, ==, 1);
g_assert (find_mode_combination (filtered, MM_MODEM_MODE_3G, MM_MODEM_MODE_NONE));
g_array_unref (filtered);
g_array_unref (all);
/* 2G and 3G supported */
all = build_mode_all (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G);
filtered = mm_filter_supported_modes (all, combinations);
g_assert_cmpuint (filtered->len, ==, 3);
g_assert (find_mode_combination (filtered, MM_MODEM_MODE_2G, MM_MODEM_MODE_NONE));
g_assert (find_mode_combination (filtered, MM_MODEM_MODE_3G, MM_MODEM_MODE_NONE));
g_assert (find_mode_combination (filtered, (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G), MM_MODEM_MODE_NONE));
g_array_unref (filtered);
g_array_unref (all);
/* 3G and 4G supported */
all = build_mode_all (MM_MODEM_MODE_3G | MM_MODEM_MODE_4G);
filtered = mm_filter_supported_modes (all, combinations);
g_assert_cmpuint (filtered->len, ==, 3);
g_assert (find_mode_combination (filtered, MM_MODEM_MODE_3G, MM_MODEM_MODE_NONE));
g_assert (find_mode_combination (filtered, MM_MODEM_MODE_4G, MM_MODEM_MODE_NONE));
g_assert (find_mode_combination (filtered, (MM_MODEM_MODE_3G | MM_MODEM_MODE_4G), MM_MODEM_MODE_NONE));
g_array_unref (filtered);
g_array_unref (all);
/* 2G, 3G and 4G supported */
all = build_mode_all (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G | MM_MODEM_MODE_4G);
filtered = mm_filter_supported_modes (all, combinations);
g_assert_cmpuint (filtered->len, ==, 6);
g_assert (find_mode_combination (filtered, MM_MODEM_MODE_2G, MM_MODEM_MODE_NONE));
g_assert (find_mode_combination (filtered, MM_MODEM_MODE_3G, MM_MODEM_MODE_NONE));
g_assert (find_mode_combination (filtered, (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G), MM_MODEM_MODE_NONE));
g_assert (find_mode_combination (filtered, MM_MODEM_MODE_4G, MM_MODEM_MODE_NONE));
g_assert (find_mode_combination (filtered, (MM_MODEM_MODE_3G | MM_MODEM_MODE_4G), MM_MODEM_MODE_NONE));
g_assert (find_mode_combination (filtered, (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G | MM_MODEM_MODE_4G), MM_MODEM_MODE_NONE));
g_array_unref (filtered);
g_array_unref (all);
g_array_unref (combinations);
}
/*****************************************************************************/
void
_mm_log (const char *loc,
const char *func,
@@ -2060,6 +2182,8 @@ int main (int argc, char **argv)
g_test_suite_add (suite, TESTCASE (test_cmgl_response_pantech, NULL));
g_test_suite_add (suite, TESTCASE (test_cmgl_response_pantech_multiple, NULL));
g_test_suite_add (suite, TESTCASE (test_supported_mode_filter, NULL));
result = g_test_run ();
reg_test_data_free (reg_data);