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 *modem_capabilities_string;
gchar *current_capabilities_string; gchar *current_capabilities_string;
gchar *access_technologies_string; gchar *access_technologies_string;
MMModemModeCombination *modes = NULL;
guint n_modes = 0;
gchar *supported_modes_string; gchar *supported_modes_string;
gchar *allowed_modes_string; gchar *allowed_modes_string;
gchar *preferred_mode_string; gchar *preferred_mode_string;
@@ -266,6 +268,9 @@ print_modem_info (void)
mm_modem_get_current_capabilities (ctx->modem)); mm_modem_get_current_capabilities (ctx->modem));
access_technologies_string = mm_modem_access_technology_build_string_from_mask ( access_technologies_string = mm_modem_access_technology_build_string_from_mask (
mm_modem_get_access_technologies (ctx->modem)); 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); mm_modem_get_current_bands (ctx->modem, &bands, &n_bands);
current_bands_string = mm_common_build_bands_string (bands, n_bands); current_bands_string = mm_common_build_bands_string (bands, n_bands);
g_free (bands); g_free (bands);
@@ -276,8 +281,6 @@ print_modem_info (void)
mm_modem_get_allowed_modes (ctx->modem)); mm_modem_get_allowed_modes (ctx->modem));
preferred_mode_string = mm_modem_mode_build_string_from_mask ( preferred_mode_string = mm_modem_mode_build_string_from_mask (
mm_modem_get_preferred_mode (ctx->modem)); 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 ( supported_ip_families_string = mm_bearer_ip_family_build_string_from_mask (
mm_modem_get_supported_ip_families (ctx->modem)); mm_modem_get_supported_ip_families (ctx->modem));
@@ -310,6 +313,15 @@ print_modem_info (void)
else else
prefixed_revision = NULL; 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 */ /* Get signal quality info */
signal_quality = mm_modem_get_signal_quality (ctx->modem, &signal_quality_recent); 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> <FILE>mm-modem</FILE>
<TITLE>MMModem</TITLE> <TITLE>MMModem</TITLE>
MMModem MMModem
MMModemModeCombination
<SUBSECTION Getters> <SUBSECTION Getters>
mm_modem_get_path mm_modem_get_path
mm_modem_dup_path mm_modem_dup_path
@@ -106,6 +107,7 @@ mm_modem_get_max_bearers
mm_modem_get_max_active_bearers mm_modem_get_max_active_bearers
mm_modem_get_own_numbers mm_modem_get_own_numbers
mm_modem_dup_own_numbers mm_modem_dup_own_numbers
mm_modem_peek_supported_modes
mm_modem_get_supported_modes mm_modem_get_supported_modes
mm_modem_get_allowed_modes mm_modem_get_allowed_modes
mm_modem_get_preferred_mode mm_modem_get_preferred_mode
@@ -1455,6 +1457,7 @@ mm_gdbus_modem_get_supported_bands
mm_gdbus_modem_dup_supported_bands mm_gdbus_modem_dup_supported_bands
mm_gdbus_modem_get_supported_ip_families mm_gdbus_modem_get_supported_ip_families
mm_gdbus_modem_get_supported_modes mm_gdbus_modem_get_supported_modes
mm_gdbus_modem_dup_supported_modes
mm_gdbus_modem_get_unlock_required mm_gdbus_modem_get_unlock_required
mm_gdbus_modem_get_unlock_retries mm_gdbus_modem_get_unlock_retries
mm_gdbus_modem_dup_unlock_retries mm_gdbus_modem_dup_unlock_retries

View File

@@ -410,14 +410,25 @@
<!-- <!--
SupportedModes: SupportedModes:
Bitmask of <link linkend="MMModemMode">MMModemMode</link> values, This property exposes the supported mode combinations, given as an array of unsigned
specifying the access technologies supported by the device. integer pairs, where:
For POTS devices, only the <variablelist>
<link linkend="MM-MODEM-MODE-ANY:CAPS"><constant>MM_MODEM_MODE_ANY</constant></link> <varlistentry>
mode will be returned. <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: AllowedModes:

View File

@@ -5,6 +5,7 @@ lib_LTLIBRARIES = libmm-glib.la
libmm_glib_la_SOURCES = \ libmm_glib_la_SOURCES = \
libmm-glib.h \ libmm-glib.h \
mm-helpers.h \ mm-helpers.h \
mm-helper-types.h \
mm-manager.h \ mm-manager.h \
mm-manager.c \ mm-manager.c \
mm-object.h \ mm-object.h \
@@ -77,6 +78,7 @@ libmm_glib_la_LIBADD = \
includedir = @includedir@/libmm-glib includedir = @includedir@/libmm-glib
include_HEADERS = \ include_HEADERS = \
libmm-glib.h \ libmm-glib.h \
mm-helper-types.h \
mm-manager.h \ mm-manager.h \
mm-object.h \ mm-object.h \
mm-modem.h \ mm-modem.h \

View File

@@ -52,6 +52,7 @@
# include <mm-common-helpers.h> # include <mm-common-helpers.h>
#endif #endif
#include <mm-helper-types.h>
#include <mm-simple-status.h> #include <mm-simple-status.h>
#include <mm-simple-connect-properties.h> #include <mm-simple-connect-properties.h>
#include <mm-sms-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); 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 * GArray *
mm_common_sms_storages_variant_to_garray (GVariant *variant) mm_common_sms_storages_variant_to_garray (GVariant *variant)
{ {
@@ -357,6 +389,96 @@ mm_common_bands_garray_cmp (GArray *a, GArray *b)
return !different; 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 gboolean
mm_common_get_boolean_from_string (const gchar *value, mm_common_get_boolean_from_string (const gchar *value,
GError **error) GError **error)

View File

@@ -17,6 +17,7 @@
#include <glib.h> #include <glib.h>
#include <ModemManager.h> #include <ModemManager.h>
#include "mm-helper-types.h"
#if !defined (__LIBMM_GLIB_H_INSIDE__) && !defined (LIBMM_GLIB_COMPILATION) #if !defined (__LIBMM_GLIB_H_INSIDE__) && !defined (LIBMM_GLIB_COMPILATION)
#error "Only <libmm-glib.h> can be included directly." #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, gchar *mm_common_build_sms_storages_string (const MMSmsStorage *storages,
guint n_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, MMModemMode mm_common_get_modes_from_string (const gchar *str,
GError **error); GError **error);
void mm_common_get_bands_from_string (const gchar *str, 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); 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, typedef gboolean (*MMParseKeyValueForeachFn) (const gchar *key,
const gchar *value, const gchar *value,
gpointer user_data); 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; guint unlock_retries_id;
MMUnlockRetries *unlock_retries; MMUnlockRetries *unlock_retries;
/* Supported Modes */
GMutex supported_modes_mutex;
guint supported_modes_id;
GArray *supported_modes;
/* Supported Bands */ /* Supported Bands */
GMutex supported_bands_mutex; GMutex supported_bands_mutex;
guint supported_bands_id; 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: * mm_modem_get_supported_modes:
* @self: A #MMModem. * @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: %TRUE if @modes and @n_modes are set, %FALSE otherwise.
*
* Returns: A bitmask of #MMModemMode values.
*/ */
MMModemMode gboolean
mm_modem_get_supported_modes (MMModem *self) 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, MM_TYPE_MODEM,
MMModemPrivate); MMModemPrivate);
g_mutex_init (&self->priv->unlock_retries_mutex); 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->supported_bands_mutex);
g_mutex_init (&self->priv->current_bands_mutex); g_mutex_init (&self->priv->current_bands_mutex);
} }
@@ -2543,9 +2647,12 @@ finalize (GObject *object)
MMModem *self = MM_MODEM (object); MMModem *self = MM_MODEM (object);
g_mutex_clear (&self->priv->unlock_retries_mutex); 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->supported_bands_mutex);
g_mutex_clear (&self->priv->current_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) if (self->priv->supported_bands)
g_array_unref (self->priv->supported_bands); g_array_unref (self->priv->supported_bands);
if (self->priv->current_bands) if (self->priv->current_bands)

View File

@@ -34,6 +34,7 @@
#include "mm-unlock-retries.h" #include "mm-unlock-retries.h"
#include "mm-sim.h" #include "mm-sim.h"
#include "mm-bearer.h" #include "mm-bearer.h"
#include "mm-helper-types.h"
G_BEGIN_DECLS G_BEGIN_DECLS
@@ -127,7 +128,12 @@ MMModemAccessTechnology mm_modem_get_access_technologies (MMModem *self);
guint mm_modem_get_signal_quality (MMModem *self, guint mm_modem_get_signal_quality (MMModem *self,
gboolean *recent); 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); 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_3gpp_init (MMIfaceModem3gpp *iface);
static void iface_modem_messaging_init (MMIfaceModemMessaging *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_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, 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)
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 { struct _MMBroadbandModemCinterionPrivate {
/* Flag to know if we should try AT^SIND or not to get psinfo */ /* Flag to know if we should try AT^SIND or not to get psinfo */
@@ -513,6 +515,80 @@ load_access_technologies (MMIfaceModem *self,
result); 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 */ /* ALLOWED MODES */
@@ -1191,6 +1267,10 @@ finalize (GObject *object)
static void static void
iface_modem_init (MMIfaceModem *iface) 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 = set_allowed_modes;
iface->set_allowed_modes_finish = set_allowed_modes_finish; iface->set_allowed_modes_finish = set_allowed_modes_finish;
iface->load_supported_bands = load_supported_bands; iface->load_supported_bands = load_supported_bands;

View File

@@ -1074,6 +1074,90 @@ set_current_bands (MMIfaceModem *self,
g_free (bands_string); 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) */ /* 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; *preferred = MM_MODEM_MODE_3G;
return TRUE; return TRUE;
} else if (a == 8) { } else if (a == 8) {
*preferred = MM_MODEM_MODE_2G | MM_MODEM_MODE_3G; *preferred = MM_MODEM_MODE_NONE;
return TRUE; return TRUE;
} }
@@ -1116,10 +1200,7 @@ load_allowed_modes_finish (MMIfaceModem *self,
return FALSE; return FALSE;
if (mm_iface_modem_is_cdma_only (self)) { if (mm_iface_modem_is_cdma_only (self)) {
/* CDMA-only devices always support 2G and 3G if they have 3G, so just *allowed = (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G);
* use the modes from GCAP as the list of allowed modes.
*/
*allowed = mm_iface_modem_get_supported_modes (self);
return parse_prefmode (response, preferred, error); 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->load_current_bands_finish = load_current_bands_finish;
iface->set_current_bands = set_current_bands; iface->set_current_bands = set_current_bands;
iface->set_current_bands_finish = set_current_bands_finish; 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 = load_allowed_modes;
iface->load_allowed_modes_finish = load_allowed_modes_finish; iface->load_allowed_modes_finish = load_allowed_modes_finish;
iface->set_allowed_modes = set_allowed_modes; 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_3gpp_init (MMIfaceModem3gpp *iface);
static void iface_modem_time_init (MMIfaceModemTime *iface); static void iface_modem_time_init (MMIfaceModemTime *iface);
static MMIfaceModem *iface_modem_parent;
static MMIfaceModem3gpp *iface_modem_3gpp_parent; static MMIfaceModem3gpp *iface_modem_3gpp_parent;
G_DEFINE_TYPE_EXTENDED (MMBroadbandModemIcera, mm_broadband_modem_icera, MM_TYPE_BROADBAND_MODEM, 0, 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, 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)
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 { enum {
PROP_0, PROP_0,
@@ -66,6 +67,88 @@ struct _MMBroadbandModemIceraPrivate {
MMModemAccessTechnology last_act; 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) */ /* Load initial allowed/preferred modes (Modem interface) */
@@ -201,7 +284,8 @@ modem_set_allowed_modes (MMIfaceModem *self,
icera_mode = 3; icera_mode = 3;
else /* none preferred, so AUTO */ else /* none preferred, so AUTO */
icera_mode = 5; icera_mode = 5;
} } else if (allowed == MM_MODEM_MODE_ANY && preferred == MM_MODEM_MODE_NONE)
icera_mode = 5;
if (icera_mode < 0) { if (icera_mode < 0) {
gchar *allowed_str; gchar *allowed_str;
@@ -1769,6 +1853,10 @@ finalize (GObject *object)
static void static void
iface_modem_init (MMIfaceModem *iface) 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 = modem_load_allowed_modes;
iface->load_allowed_modes_finish = modem_load_allowed_modes_finish; iface->load_allowed_modes_finish = modem_load_allowed_modes_finish;
iface->set_allowed_modes = modem_set_allowed_modes; iface->set_allowed_modes = modem_set_allowed_modes;

View File

@@ -219,13 +219,12 @@ setup_flow_control (MMIfaceModem *self,
/*****************************************************************************/ /*****************************************************************************/
/* Load supported modes (Modem inteface) */ /* Load supported modes (Modem inteface) */
static MMModemMode static GArray *
load_supported_modes_finish (MMIfaceModem *self, load_supported_modes_finish (MMIfaceModem *self,
GAsyncResult *res, GAsyncResult *res,
GError **error) GError **error)
{ {
/* Report CS only, Iridium connections are circuit-switched */ return g_array_ref (g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (res)));
return MM_MODEM_MODE_CS;
} }
static void static void
@@ -234,11 +233,23 @@ load_supported_modes (MMIfaceModem *self,
gpointer user_data) gpointer user_data)
{ {
GSimpleAsyncResult *result; GSimpleAsyncResult *result;
GArray *combinations;
MMModemModeCombination mode;
result = g_simple_async_result_new (G_OBJECT (self), result = g_simple_async_result_new (G_OBJECT (self),
callback, callback,
user_data, user_data,
load_supported_modes); 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_simple_async_result_complete_in_idle (result);
g_object_unref (result); g_object_unref (result);
} }

View File

@@ -40,8 +40,84 @@
static void iface_modem_init (MMIfaceModem *iface); 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_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) */ /* Load initial allowed/preferred modes (Modem interface) */
@@ -158,9 +234,11 @@ set_allowed_modes (MMIfaceModem *self,
else if (allowed == MM_MODEM_MODE_3G) else if (allowed == MM_MODEM_MODE_3G)
linktop_mode = LINKTOP_MODE_3G; linktop_mode = LINKTOP_MODE_3G;
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)) { (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; linktop_mode = LINKTOP_MODE_ANY;
}
if (linktop_mode < 0) { if (linktop_mode < 0) {
gchar *allowed_str; gchar *allowed_str;
@@ -220,6 +298,10 @@ mm_broadband_modem_linktop_init (MMBroadbandModemLinktop *self)
static void static void
iface_modem_init (MMIfaceModem *iface) 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 = load_allowed_modes;
iface->load_allowed_modes_finish = load_allowed_modes_finish; iface->load_allowed_modes_finish = load_allowed_modes_finish;
iface->set_allowed_modes = set_allowed_modes; iface->set_allowed_modes = set_allowed_modes;

View File

@@ -33,8 +33,88 @@
static void iface_modem_init (MMIfaceModem *iface); 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_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) */ /* 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); *allowed = (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G);
*preferred = MM_MODEM_MODE_3G; *preferred = MM_MODEM_MODE_3G;
return TRUE; return TRUE;
case 4:
/* GSM preferred */
*allowed = (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G);
*preferred = MM_MODEM_MODE_2G;
return TRUE;
case 3: case 3:
/* GSM only */ /* GSM only */
*allowed = MM_MODEM_MODE_2G; *allowed = MM_MODEM_MODE_2G;
*preferred = MM_MODEM_MODE_NONE; *preferred = MM_MODEM_MODE_NONE;
return TRUE; return TRUE;
case 4:
/* GSM preferred */
*allowed = (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G);
*preferred = MM_MODEM_MODE_2G;
return TRUE;
default: default:
break; break;
} }
@@ -159,14 +239,14 @@ set_allowed_modes (MMIfaceModem *self,
mododr = 3; mododr = 3;
else if (allowed == MM_MODEM_MODE_3G) else if (allowed == MM_MODEM_MODE_3G)
mododr = 1; 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) if (preferred == MM_MODEM_MODE_2G)
mododr = 4; mododr = 4;
else if (preferred == MM_MODEM_MODE_3G || else if (preferred == MM_MODEM_MODE_3G)
preferred == MM_MODEM_MODE_NONE || mododr = 2;
preferred == MM_MODEM_MODE_ANY) } else if (allowed == MM_MODEM_MODE_ANY && preferred == MM_MODEM_MODE_NONE)
/* Default to 3G preferred */
mododr = 2; mododr = 2;
}
if (mododr == 0) { if (mododr == 0) {
gchar *allowed_str; gchar *allowed_str;
@@ -338,8 +418,12 @@ mm_broadband_modem_longcheer_init (MMBroadbandModemLongcheer *self)
static void static void
iface_modem_init (MMIfaceModem *iface) 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 = load_access_technologies;
iface->load_access_technologies_finish = load_access_technologies_finish; 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 = load_allowed_modes;
iface->load_allowed_modes_finish = load_allowed_modes_finish; iface->load_allowed_modes_finish = load_allowed_modes_finish;
iface->set_allowed_modes = set_allowed_modes; iface->set_allowed_modes = set_allowed_modes;

View File

@@ -45,6 +45,7 @@
static void iface_modem_init (MMIfaceModem *iface); static void iface_modem_init (MMIfaceModem *iface);
static void iface_modem_3gpp_init (MMIfaceModem3gpp *iface); static void iface_modem_3gpp_init (MMIfaceModem3gpp *iface);
static MMIfaceModem *iface_modem_parent;
static MMIfaceModem3gpp *iface_modem_3gpp_parent; static MMIfaceModem3gpp *iface_modem_3gpp_parent;
G_DEFINE_TYPE_EXTENDED (MMBroadbandModemMbm, mm_broadband_modem_mbm, MM_TYPE_BROADBAND_MODEM, 0, 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); 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) */ /* Load initial allowed/preferred modes (Modem interface) */
@@ -1237,12 +1312,16 @@ finalize (GObject *object)
static void static void
iface_modem_init (MMIfaceModem *iface) iface_modem_init (MMIfaceModem *iface)
{ {
iface_modem_parent = g_type_interface_peek_parent (iface);
iface->create_bearer = modem_create_bearer; iface->create_bearer = modem_create_bearer;
iface->create_bearer_finish = modem_create_bearer_finish; iface->create_bearer_finish = modem_create_bearer_finish;
iface->create_sim = create_sim; iface->create_sim = create_sim;
iface->create_sim_finish = create_sim_finish; iface->create_sim_finish = create_sim_finish;
iface->modem_after_sim_unlock = modem_after_sim_unlock; iface->modem_after_sim_unlock = modem_after_sim_unlock;
iface->modem_after_sim_unlock_finish = modem_after_sim_unlock_finish; 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 = load_allowed_modes;
iface->load_allowed_modes_finish = load_allowed_modes_finish; iface->load_allowed_modes_finish = load_allowed_modes_finish;
iface->set_allowed_modes = set_allowed_modes; iface->set_allowed_modes = set_allowed_modes;

View File

@@ -67,45 +67,6 @@ create_sim (MMIfaceModem *self,
user_data); 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) */ /* Load access technologies (Modem interface) */
@@ -407,8 +368,6 @@ iface_modem_init (MMIfaceModem *iface)
iface->modem_power_down = NULL; iface->modem_power_down = NULL;
iface->modem_power_down_finish = 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 = load_access_technologies;
iface->load_access_technologies_finish = load_access_technologies_finish; 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, iface_modem_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)
G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM_CDMA, iface_modem_cdma_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) */ /* Load initial allowed/preferred modes (Modem interface) */
@@ -275,6 +357,10 @@ set_allowed_modes (MMIfaceModem *self,
a = 1; a = 1;
else if (preferred == MM_MODEM_MODE_3G) else if (preferred == MM_MODEM_MODE_3G)
a = 2; a = 2;
} else if (allowed == MM_MODEM_MODE_ANY &&
preferred == MM_MODEM_MODE_NONE) {
b = 2;
a = 0;
} }
if (a < 0 || b < 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_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 = load_allowed_modes;
iface->load_allowed_modes_finish = load_allowed_modes_finish; iface->load_allowed_modes_finish = load_allowed_modes_finish;
iface->set_allowed_modes = set_allowed_modes; iface->set_allowed_modes = set_allowed_modes;

View File

@@ -35,11 +35,12 @@
static void iface_modem_init (MMIfaceModem *iface); static void iface_modem_init (MMIfaceModem *iface);
static void iface_modem_3gpp_init (MMIfaceModem3gpp *iface); static void iface_modem_3gpp_init (MMIfaceModem3gpp *iface);
static MMIfaceModem *iface_modem_parent;
static MMIfaceModem3gpp *iface_modem_3gpp_parent; static MMIfaceModem3gpp *iface_modem_3gpp_parent;
G_DEFINE_TYPE_EXTENDED (MMBroadbandModemOption, mm_broadband_modem_option, MM_TYPE_BROADBAND_MODEM, 0, 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, 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 { struct _MMBroadbandModemOptionPrivate {
/* Regex for access-technology related notifications */ /* Regex for access-technology related notifications */
@@ -56,6 +57,88 @@ struct _MMBroadbandModemOptionPrivate {
guint after_power_up_wait_id; 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) */ /* Load initial allowed/preferred modes (Modem interface) */
@@ -186,7 +269,8 @@ set_allowed_modes (MMIfaceModem *self,
option_mode = 3; option_mode = 3;
else /* none preferred, so AUTO */ else /* none preferred, so AUTO */
option_mode = 5; option_mode = 5;
} } else if (allowed == MM_MODEM_MODE_ANY && preferred == MM_MODEM_MODE_NONE)
option_mode = 5;
if (option_mode < 0) { if (option_mode < 0) {
gchar *allowed_str; gchar *allowed_str;
@@ -1140,10 +1224,14 @@ mm_broadband_modem_option_init (MMBroadbandModemOption *self)
static void static void
iface_modem_init (MMIfaceModem *iface) 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 = modem_after_power_up;
iface->modem_after_power_up_finish = modem_after_power_up_finish; iface->modem_after_power_up_finish = modem_after_power_up_finish;
iface->load_access_technologies = load_access_technologies; iface->load_access_technologies = load_access_technologies;
iface->load_access_technologies_finish = load_access_technologies_finish; 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 = load_allowed_modes;
iface->load_allowed_modes_finish = load_allowed_modes_finish; iface->load_allowed_modes_finish = load_allowed_modes_finish;
iface->set_allowed_modes = set_allowed_modes; iface->set_allowed_modes = set_allowed_modes;

View File

@@ -513,6 +513,109 @@ load_access_technologies (MMIfaceModem *self,
g_assert_not_reached (); 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) */ /* 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) { if (mm_get_uint_from_match_info (match_info, 1, &mode) && mode <= 7) {
switch (mode) { switch (mode) {
case 0: 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; result.preferred = MM_MODEM_MODE_NONE;
break; break;
case 1: case 1:
@@ -583,7 +689,7 @@ selrat_query_ready (MMBaseModem *self,
case 3: case 3:
/* in Sierra LTE devices, mode 3 is automatic, including LTE, no preference */ /* in Sierra LTE devices, mode 3 is automatic, including LTE, no preference */
if (mm_iface_modem_is_3gpp_lte (MM_IFACE_MODEM (self))) { 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; result.preferred = MM_MODEM_MODE_NONE;
} else { } else {
result.allowed = (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G); result.allowed = (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G);
@@ -593,7 +699,7 @@ selrat_query_ready (MMBaseModem *self,
case 4: case 4:
/* in Sierra LTE devices, mode 4 is automatic, including LTE, no preference */ /* in Sierra LTE devices, mode 4 is automatic, including LTE, no preference */
if (mm_iface_modem_is_3gpp_lte (MM_IFACE_MODEM (self))) { 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; result.preferred = MM_MODEM_MODE_NONE;
} else { } else {
result.allowed = (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G); result.allowed = (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G);
@@ -773,9 +879,10 @@ set_allowed_modes (MMIfaceModem *self,
idx = 0; idx = 0;
} else if (allowed == MM_MODEM_MODE_4G) } else if (allowed == MM_MODEM_MODE_4G)
idx = 6; 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; idx = 7;
else if (allowed == MM_MODEM_MODE_ANY) else if (allowed == MM_MODEM_MODE_ANY && preferred == MM_MODEM_MODE_NONE)
idx = 0; idx = 0;
if (idx < 0) { if (idx < 0) {
@@ -1556,6 +1663,8 @@ iface_modem_init (MMIfaceModem *iface)
mm_common_sierra_peek_parent_interfaces (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 = load_allowed_modes;
iface->load_allowed_modes_finish = load_allowed_modes_finish; iface->load_allowed_modes_finish = load_allowed_modes_finish;
iface->set_allowed_modes = set_allowed_modes; iface->set_allowed_modes = set_allowed_modes;

View File

@@ -37,11 +37,12 @@
static void iface_modem_init (MMIfaceModem *iface); static void iface_modem_init (MMIfaceModem *iface);
static void iface_modem_3gpp_init (MMIfaceModem3gpp *iface); static void iface_modem_3gpp_init (MMIfaceModem3gpp *iface);
static MMIfaceModem *iface_modem_parent;
static MMIfaceModem3gpp *iface_modem_3gpp_parent; static MMIfaceModem3gpp *iface_modem_3gpp_parent;
G_DEFINE_TYPE_EXTENDED (MMBroadbandModemSimtech, mm_broadband_modem_simtech, MM_TYPE_BROADBAND_MODEM, 0, 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, 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) */ /* Setup/Cleanup unsolicited events (3GPP interface) */
@@ -444,6 +445,87 @@ load_access_technologies (MMIfaceModem *self,
result); 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) */ /* Load initial allowed/preferred modes (Modem interface) */
@@ -731,19 +813,28 @@ set_allowed_modes (MMIfaceModem *self,
user_data, user_data,
set_allowed_modes); set_allowed_modes);
ctx->nmp = 2; /* automatic mode preference */ /* Defaults: automatic search */
ctx->naop = 0; /* automatic acquisition order */ 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; ctx->nmp = 13;
else if (allowed == MM_MODEM_MODE_3G) ctx->naop = 0;
} else if (allowed == MM_MODEM_MODE_3G) {
ctx->nmp = 14; 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) if (preferred == MM_MODEM_MODE_2G)
ctx->naop = 3; ctx->naop = 3;
else if (preferred == MM_MODEM_MODE_3G) else if (preferred == MM_MODEM_MODE_3G)
ctx->naop = 2; ctx->naop = 2;
/* else, auto */ else
/* default naop */
ctx->naop = 0;
} else { } else {
gchar *allowed_str; gchar *allowed_str;
gchar *preferred_str; gchar *preferred_str;
@@ -830,8 +921,12 @@ iface_modem_3gpp_init (MMIfaceModem3gpp *iface)
static void static void
iface_modem_init (MMIfaceModem *iface) 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 = load_access_technologies;
iface->load_access_technologies_finish = load_access_technologies_finish; 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 = load_allowed_modes;
iface->load_allowed_modes_finish = load_allowed_modes_finish; iface->load_allowed_modes_finish = load_allowed_modes_finish;
iface->set_allowed_modes = set_allowed_modes; iface->set_allowed_modes = set_allowed_modes;

View File

@@ -37,6 +37,8 @@
static void iface_modem_init (MMIfaceModem *iface); 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_DEFINE_TYPE_EXTENDED (MMBroadbandModemWavecom, mm_broadband_modem_wavecom, 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))
@@ -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, load_supported_modes_finish (MMIfaceModem *self,
GAsyncResult *res, GAsyncResult *res,
GError **error) GError **error)
{ {
if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), 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 ( return g_array_ref (g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (res)));
G_SIMPLE_ASYNC_RESULT (res)));
} }
static void static void
@@ -101,9 +102,13 @@ supported_ms_classes_query_ready (MMBaseModem *self,
GAsyncResult *res, GAsyncResult *res,
GSimpleAsyncResult *simple) GSimpleAsyncResult *simple)
{ {
GArray *all;
GArray *combinations;
GArray *filtered;
const gchar *response; const gchar *response;
GError *error = NULL; GError *error = NULL;
MMModemMode mode; MMModemModeCombination mode;
MMModemMode mode_all;
response = mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, &error); response = mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, &error);
if (!response) { if (!response) {
@@ -115,40 +120,71 @@ supported_ms_classes_query_ready (MMBaseModem *self,
} }
response = mm_strip_tag (response, "+CGCLASS:"); response = mm_strip_tag (response, "+CGCLASS:");
mode = MM_MODEM_MODE_NONE; mode_all = MM_MODEM_MODE_NONE;
if (strstr (response, WAVECOM_MS_CLASS_A_IDSTR))
if (strstr (response, WAVECOM_MS_CLASS_A_IDSTR)) { mode_all |= MM_MODEM_MODE_3G;
mm_dbg ("Modem supports Class A mobile station"); if (strstr (response, WAVECOM_MS_CLASS_B_IDSTR))
mode |= MM_MODEM_MODE_3G; 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_B_IDSTR)) { if (strstr (response, WAVECOM_MS_CLASS_CC_IDSTR))
mm_dbg ("Modem supports Class B mobile station"); mode_all |= MM_MODEM_MODE_CS;
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;
}
/* If none received, error */ /* If none received, error */
if (mode == MM_MODEM_MODE_NONE) if (mode_all == MM_MODEM_MODE_NONE) {
g_simple_async_result_set_error (simple, g_simple_async_result_set_error (simple,
MM_CORE_ERROR, MM_CORE_ERROR,
MM_CORE_ERROR_FAILED, MM_CORE_ERROR_FAILED,
"Couldn't get supported mobile station classes: '%s'", "Couldn't get supported mobile station classes: '%s'",
response); response);
else g_simple_async_result_complete (simple);
g_simple_async_result_set_op_res_gpointer (simple, g_object_unref (simple);
GUINT_TO_POINTER (mode), return;
NULL); }
/* 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_simple_async_result_complete (simple);
g_object_unref (simple); g_object_unref (simple);
} }
@@ -158,20 +194,16 @@ load_supported_modes (MMIfaceModem *self,
GAsyncReadyCallback callback, GAsyncReadyCallback callback,
gpointer user_data) 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_at_command (
MM_BASE_MODEM (self), MM_BASE_MODEM (self),
"+CGCLASS=?", "+CGCLASS=?",
3, 3,
FALSE, FALSE,
(GAsyncReadyCallback)supported_ms_classes_query_ready, (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 { typedef struct {
MMBroadbandModemWavecom *self; MMBroadbandModemWavecom *self;
GSimpleAsyncResult *result; GSimpleAsyncResult *result;
MMModemMode allowed;
MMModemMode preferred;
gchar *cgclass_command; gchar *cgclass_command;
gchar *wwsm_command; gchar *wwsm_command;
} SetAllowedModesContext; } SetAllowedModesContext;
@@ -473,19 +503,27 @@ set_allowed_modes (MMIfaceModem *self,
callback, callback,
user_data, user_data,
set_allowed_modes); 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) if (allowed == MM_MODEM_MODE_CS)
ctx->cgclass_command = g_strdup ("+CGCLASS=" WAVECOM_MS_CLASS_CC_IDSTR); ctx->cgclass_command = g_strdup ("+CGCLASS=" WAVECOM_MS_CLASS_CC_IDSTR);
else if (allowed == MM_MODEM_MODE_2G) else if (allowed == MM_MODEM_MODE_2G)
ctx->cgclass_command = g_strdup ("+CGCLASS=" WAVECOM_MS_CLASS_CG_IDSTR); ctx->cgclass_command = g_strdup ("+CGCLASS=" WAVECOM_MS_CLASS_CG_IDSTR);
else if (allowed == (MM_MODEM_MODE_2G | MM_MODEM_MODE_CS) && 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); ctx->cgclass_command = g_strdup ("+CGCLASS=" WAVECOM_MS_CLASS_B_IDSTR);
else if (allowed & MM_MODEM_MODE_3G) { else if (allowed & MM_MODEM_MODE_3G) {
if (allowed == (MM_MODEM_MODE_2G | 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 (preferred == MM_MODEM_MODE_2G) if (preferred == MM_MODEM_MODE_2G)
ctx->wwsm_command = g_strdup ("+WWSM=2,1"); ctx->wwsm_command = g_strdup ("+WWSM=2,1");
else if (preferred == MM_MODEM_MODE_3G) else if (preferred == MM_MODEM_MODE_3G)
@@ -1144,6 +1182,8 @@ mm_broadband_modem_wavecom_init (MMBroadbandModemWavecom *self)
static void static void
iface_modem_init (MMIfaceModem *iface) 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 = load_supported_modes;
iface->load_supported_modes_finish = load_supported_modes_finish; iface->load_supported_modes_finish = load_supported_modes_finish;
iface->load_allowed_modes = load_allowed_modes; iface->load_allowed_modes = load_allowed_modes;

View File

@@ -33,8 +33,83 @@
static void iface_modem_init (MMIfaceModem *iface); 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_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) */ /* Load initial allowed/preferred modes (Modem interface) */
@@ -168,7 +243,8 @@ set_allowed_modes (MMIfaceModem *self,
else if (allowed == MM_MODEM_MODE_ANY && else if (allowed == MM_MODEM_MODE_ANY &&
preferred == MM_MODEM_MODE_NONE) preferred == MM_MODEM_MODE_NONE)
syssel = 0; 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; syssel = 0;
else { else {
gchar *allowed_str; gchar *allowed_str;
@@ -264,8 +340,12 @@ mm_broadband_modem_x22x_init (MMBroadbandModemX22x *self)
static void static void
iface_modem_init (MMIfaceModem *iface) 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 = load_access_technologies;
iface->load_access_technologies_finish = load_access_technologies_finish; 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 = load_allowed_modes;
iface->load_allowed_modes_finish = load_allowed_modes_finish; iface->load_allowed_modes_finish = load_allowed_modes_finish;
iface->set_allowed_modes = set_allowed_modes; iface->set_allowed_modes = set_allowed_modes;

View File

@@ -249,6 +249,100 @@ modem_power_down (MMIfaceModem *self,
user_data); 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) */ /* Load initial allowed/preferred modes (Modem interface) */
@@ -413,7 +507,12 @@ set_allowed_modes (MMIfaceModem *self,
pref_acq = 2; pref_acq = 2;
else /* none preferred, so AUTO */ else /* none preferred, so AUTO */
pref_acq = 0; 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; cm_mode = 0;
pref_acq = 0; pref_acq = 0;
} else if (allowed == MM_MODEM_MODE_4G) { } 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->modem_power_down_finish = modem_power_down_finish;
iface->load_access_technologies = load_access_technologies; iface->load_access_technologies = load_access_technologies;
iface->load_access_technologies_finish = load_access_technologies_finish; 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 = load_allowed_modes;
iface->load_allowed_modes_finish = load_allowed_modes_finish; iface->load_allowed_modes_finish = load_allowed_modes_finish;
iface->set_allowed_modes = set_allowed_modes; iface->set_allowed_modes = set_allowed_modes;

View File

@@ -370,62 +370,74 @@ modem_load_device_identifier (MMIfaceModem *self,
/*****************************************************************************/ /*****************************************************************************/
/* Supported modes loading (Modem interface) */ /* Supported modes loading (Modem interface) */
static MMModemMode static GArray *
modem_load_supported_modes_finish (MMIfaceModem *_self, modem_load_supported_modes_finish (MMIfaceModem *self,
GAsyncResult *res, GAsyncResult *res,
GError **error) GError **error)
{ {
MMModemMode mask; return g_array_ref (g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (res)));
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;
} }
static void static void
modem_load_supported_modes (MMIfaceModem *self, modem_load_supported_modes (MMIfaceModem *_self,
GAsyncReadyCallback callback, GAsyncReadyCallback callback,
gpointer user_data) gpointer user_data)
{ {
MMBroadbandModemMbim *self = MM_BROADBAND_MODEM_MBIM (_self);
GArray *combinations;
MMModemModeCombination mode;
GSimpleAsyncResult *result; GSimpleAsyncResult *result;
MMModemMode all;
/* Just complete */ /* Just complete */
result = g_simple_async_result_new (G_OBJECT (self), result = g_simple_async_result_new (G_OBJECT (self),
callback, callback,
user_data, user_data,
modem_load_supported_modes); 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_simple_async_result_complete_in_idle (result);
g_object_unref (result); g_object_unref (result);
} }

View File

@@ -65,6 +65,9 @@ struct _MMBroadbandModemQmiPrivate {
gchar *meid; gchar *meid;
gchar *esn; 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 */ /* Cached supported frequency bands; in order to handle ANY */
GArray *supported_bands; GArray *supported_bands;
@@ -554,6 +557,20 @@ modem_load_current_capabilities (MMIfaceModem *self,
/*****************************************************************************/ /*****************************************************************************/
/* Modem Capabilities loading (Modem interface) */ /* 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 static MMModemCapability
modem_load_modem_capabilities_finish (MMIfaceModem *self, modem_load_modem_capabilities_finish (MMIfaceModem *self,
GAsyncResult *res, GAsyncResult *res,
@@ -577,7 +594,7 @@ modem_load_modem_capabilities_finish (MMIfaceModem *self,
static void static void
dms_get_capabilities_ready (QmiClientDms *client, dms_get_capabilities_ready (QmiClientDms *client,
GAsyncResult *res, GAsyncResult *res,
GSimpleAsyncResult *simple) LoadModemCapabilitiesContext *ctx)
{ {
QmiMessageDmsGetCapabilitiesOutput *output = NULL; QmiMessageDmsGetCapabilitiesOutput *output = NULL;
GError *error = NULL; GError *error = NULL;
@@ -585,10 +602,10 @@ dms_get_capabilities_ready (QmiClientDms *client,
output = qmi_client_dms_get_capabilities_finish (client, res, &error); output = qmi_client_dms_get_capabilities_finish (client, res, &error);
if (!output) { if (!output) {
g_prefix_error (&error, "QMI operation failed: "); 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)) { } else if (!qmi_message_dms_get_capabilities_output_get_result (output, &error)) {
g_prefix_error (&error, "Couldn't get modem capabilities: "); 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 { } else {
guint i; guint i;
guint mask = MM_MODEM_CAPABILITY_NONE; guint mask = MM_MODEM_CAPABILITY_NONE;
@@ -609,7 +626,12 @@ dms_get_capabilities_ready (QmiClientDms *client,
i)); 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), GUINT_TO_POINTER (mask),
NULL); NULL);
} }
@@ -617,8 +639,7 @@ dms_get_capabilities_ready (QmiClientDms *client,
if (output) if (output)
qmi_message_dms_get_capabilities_output_unref (output); qmi_message_dms_get_capabilities_output_unref (output);
g_simple_async_result_complete (simple); load_modem_capabilities_context_complete_and_free (ctx);
g_object_unref (simple);
} }
static void static void
@@ -626,7 +647,7 @@ modem_load_modem_capabilities (MMIfaceModem *self,
GAsyncReadyCallback callback, GAsyncReadyCallback callback,
gpointer user_data) gpointer user_data)
{ {
GSimpleAsyncResult *result; LoadModemCapabilitiesContext *ctx;
QmiClient *client = NULL; QmiClient *client = NULL;
if (!ensure_qmi_client (MM_BROADBAND_MODEM_QMI (self), if (!ensure_qmi_client (MM_BROADBAND_MODEM_QMI (self),
@@ -634,7 +655,9 @@ modem_load_modem_capabilities (MMIfaceModem *self,
callback, user_data)) callback, user_data))
return; return;
result = g_simple_async_result_new (G_OBJECT (self), ctx = g_slice_new (LoadModemCapabilitiesContext);
ctx->self = g_object_ref (self);
ctx->result = g_simple_async_result_new (G_OBJECT (self),
callback, callback,
user_data, user_data,
modem_load_modem_capabilities); modem_load_modem_capabilities);
@@ -645,7 +668,7 @@ modem_load_modem_capabilities (MMIfaceModem *self,
5, 5,
NULL, NULL,
(GAsyncReadyCallback)dms_get_capabilities_ready, (GAsyncReadyCallback)dms_get_capabilities_ready,
result); ctx);
} }
/*****************************************************************************/ /*****************************************************************************/
@@ -1711,37 +1734,89 @@ set_current_bands (MMIfaceModem *_self,
/*****************************************************************************/ /*****************************************************************************/
/* Load supported modes (Modem interface) */ /* Load supported modes (Modem interface) */
static MMModemMode static GArray *
modem_load_supported_modes_finish (MMIfaceModem *self, modem_load_supported_modes_finish (MMIfaceModem *self,
GAsyncResult *res, GAsyncResult *res,
GError **error) GError **error)
{ {
return (MMModemMode)GPOINTER_TO_UINT (g_simple_async_result_get_op_res_gpointer ( return g_array_ref (g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (res)));
G_SIMPLE_ASYNC_RESULT (res)));
} }
static void static void
modem_load_supported_modes (MMIfaceModem *self, modem_load_supported_modes (MMIfaceModem *_self,
GAsyncReadyCallback callback, GAsyncReadyCallback callback,
gpointer user_data) gpointer user_data)
{ {
MMBroadbandModemQmi *self = MM_BROADBAND_MODEM_QMI (_self);
GSimpleAsyncResult *result; GSimpleAsyncResult *result;
MMModemMode mode; GArray *all;
GArray *combinations;
/* For QMI-powered modems, it is safe to assume they do 2G and 3G */ GArray *filtered;
mode = (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G); MMModemModeCombination mode;
guint i;
/* 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), result = g_simple_async_result_new (G_OBJECT (self),
callback, callback,
user_data, user_data,
modem_load_supported_modes); modem_load_supported_modes);
g_simple_async_result_set_op_res_gpointer (result,
GUINT_TO_POINTER (mode), if (!self->priv->supported_radio_interfaces) {
NULL); 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_simple_async_result_complete_in_idle (result);
g_object_unref (result); g_object_unref (result);
} }
@@ -2842,8 +2917,16 @@ set_allowed_modes (MMIfaceModem *self,
callback, callback,
user_data, user_data,
set_allowed_modes); set_allowed_modes);
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->allowed = allowed;
ctx->preferred = preferred; ctx->preferred = preferred;
}
/* System selection preference introduced in NAS 1.1 */ /* System selection preference introduced in NAS 1.1 */
ctx->run_set_system_selection_preference = qmi_client_check_version (client, 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); g_free (self->priv->current_operator_description);
if (self->priv->supported_bands) if (self->priv->supported_bands)
g_array_unref (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); 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_simple_async_result_complete (ctx->result);
g_object_unref (ctx->result); g_object_unref (ctx->result);
g_object_unref (ctx->self); g_object_unref (ctx->self);
g_free (ctx); g_slice_free (LoadSupportedModesContext, ctx);
} }
static MMModemMode static GArray *
modem_load_supported_modes_finish (MMIfaceModem *self, modem_load_supported_modes_finish (MMIfaceModem *self,
GAsyncResult *res, GAsyncResult *res,
GError **error) GError **error)
{ {
if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error)) GArray *modes;
return MM_MODEM_MODE_NONE; MMModemModeCombination mode;
return (MMModemMode)GPOINTER_TO_UINT (g_simple_async_result_get_op_res_gpointer ( 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))); 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); static void load_supported_modes_step (LoadSupportedModesContext *ctx);
@@ -1515,8 +1524,8 @@ modem_load_supported_modes (MMIfaceModem *self,
{ {
LoadSupportedModesContext *ctx; LoadSupportedModesContext *ctx;
mm_dbg ("loading initial supported modes..."); mm_dbg ("loading supported modes...");
ctx = g_new0 (LoadSupportedModesContext, 1); ctx = g_slice_new0 (LoadSupportedModesContext);
ctx->self = g_object_ref (self); ctx->self = g_object_ref (self);
ctx->result = g_simple_async_result_new (G_OBJECT (self), ctx->result = g_simple_async_result_new (G_OBJECT (self),
callback, callback,

View File

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

View File

@@ -126,7 +126,7 @@ struct _MMIfaceModem {
void (*load_supported_modes) (MMIfaceModem *self, void (*load_supported_modes) (MMIfaceModem *self,
GAsyncReadyCallback callback, GAsyncReadyCallback callback,
gpointer user_data); gpointer user_data);
MMModemMode (*load_supported_modes_finish) (MMIfaceModem *self, GArray * (*load_supported_modes_finish) (MMIfaceModem *self,
GAsyncResult *res, GAsyncResult *res,
GError **error); GError **error);
@@ -328,7 +328,6 @@ gboolean mm_iface_modem_is_cdma (MMIfaceModem *self);
gboolean mm_iface_modem_is_cdma_only (MMIfaceModem *self); gboolean mm_iface_modem_is_cdma_only (MMIfaceModem *self);
/* Helpers to query supported modes */ /* 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 (MMIfaceModem *self);
gboolean mm_iface_modem_is_2g_only (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 (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 */ /* pin1 TRUE for PIN1, FALSE for PIN2 */
MMModemLock MMModemLock
mm_modem_lock_from_qmi_uim_pin_status (QmiDmsUimPinStatus status, 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); 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, MMModemLock mm_modem_lock_from_qmi_uim_pin_status (QmiDmsUimPinStatus status,
gboolean pin1); 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) */ /* +CREG: <stat> (GSM 07.07 CREG=1 unsolicited) */
#define CREG1 "\\+(CREG|CGREG|CEREG):\\s*0*([0-9])" #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, gboolean have_offset,
gint offset_minutes); gint offset_minutes);
GArray *mm_filter_supported_modes (const GArray *all,
const GArray *supported_combinations);
/*****************************************************************************/ /*****************************************************************************/
/* 3GPP specific helpers and utilities */ /* 3GPP specific helpers and utilities */
/*****************************************************************************/ /*****************************************************************************/

View File

@@ -18,6 +18,7 @@
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
#include <libmm-glib.h>
#include "mm-modem-helpers.h" #include "mm-modem-helpers.h"
#include "mm-log.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 void
_mm_log (const char *loc, _mm_log (const char *loc,
const char *func, 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, NULL));
g_test_suite_add (suite, TESTCASE (test_cmgl_response_pantech_multiple, 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 (); result = g_test_run ();
reg_test_data_free (reg_data); reg_test_data_free (reg_data);