api,introspection: rename 'ModemCapabilities' to 'SupportedCapabilities'

And also make it a list of masks, specifying which are the specific combinations
supported, not just one mask with all.

E.g.:
  -------------------------
  Hardware |   manufacturer: 'Sierra Wireless, Incorporated'
           |          model: 'MC7710'
           |       revision: 'SWI9200X_03.05.19.04ap r5475 carmd-en-10527 2012/09/17 17:57:14'
           |      supported: 'gsm-umts
           |                  gsm-umts, lte'
           |        current: 'gsm-umts, lte'
           |   equipment id: '358178040668164'
This commit is contained in:
Aleksander Morgado
2013-05-24 12:35:44 +02:00
parent 1c67d050cb
commit 700ebc5c07
15 changed files with 546 additions and 95 deletions

View File

@@ -235,7 +235,9 @@ print_modem_info (void)
{ {
gchar *drivers_string; gchar *drivers_string;
gchar *prefixed_revision; gchar *prefixed_revision;
gchar *modem_capabilities_string; gchar *supported_capabilities_string;
MMModemCapability *capabilities = NULL;
guint n_capabilities = 0;
gchar *current_capabilities_string; gchar *current_capabilities_string;
gchar *access_technologies_string; gchar *access_technologies_string;
MMModemModeCombination *modes = NULL; MMModemModeCombination *modes = NULL;
@@ -264,8 +266,9 @@ print_modem_info (void)
#define VALIDATE_PATH(str) ((str && !g_str_equal (str, "/")) ? str : "none") #define VALIDATE_PATH(str) ((str && !g_str_equal (str, "/")) ? str : "none")
/* Strings in heap */ /* Strings in heap */
modem_capabilities_string = mm_modem_capability_build_string_from_mask ( mm_modem_get_supported_capabilities (ctx->modem, &capabilities, &n_capabilities);
mm_modem_get_modem_capabilities (ctx->modem)); supported_capabilities_string = mm_common_build_capabilities_string (capabilities, n_capabilities);
g_free (capabilities);
current_capabilities_string = mm_modem_capability_build_string_from_mask ( current_capabilities_string = mm_modem_capability_build_string_from_mask (
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 (
@@ -324,6 +327,15 @@ print_modem_info (void)
supported_modes_string = prefixed; supported_modes_string = prefixed;
} }
if (supported_capabilities_string) {
gchar *prefixed;
prefixed = mmcli_prefix_newlines (" | ",
supported_capabilities_string);
g_free (supported_capabilities_string);
supported_capabilities_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);
@@ -338,13 +350,13 @@ print_modem_info (void)
" Hardware | manufacturer: '%s'\n" " Hardware | manufacturer: '%s'\n"
" | model: '%s'\n" " | model: '%s'\n"
" | revision: '%s'\n" " | revision: '%s'\n"
" | capabilities: '%s'\n" " | supported: '%s'\n"
" | current: '%s'\n" " | current: '%s'\n"
" | equipment id: '%s'\n", " | equipment id: '%s'\n",
VALIDATE_UNKNOWN (mm_modem_get_manufacturer (ctx->modem)), VALIDATE_UNKNOWN (mm_modem_get_manufacturer (ctx->modem)),
VALIDATE_UNKNOWN (mm_modem_get_model (ctx->modem)), VALIDATE_UNKNOWN (mm_modem_get_model (ctx->modem)),
VALIDATE_UNKNOWN (prefixed_revision), VALIDATE_UNKNOWN (prefixed_revision),
VALIDATE_UNKNOWN (modem_capabilities_string), VALIDATE_UNKNOWN (supported_capabilities_string),
VALIDATE_UNKNOWN (current_capabilities_string), VALIDATE_UNKNOWN (current_capabilities_string),
VALIDATE_UNKNOWN (mm_modem_get_equipment_identifier (ctx->modem))); VALIDATE_UNKNOWN (mm_modem_get_equipment_identifier (ctx->modem)));
@@ -475,7 +487,7 @@ print_modem_info (void)
g_free (current_bands_string); g_free (current_bands_string);
g_free (supported_bands_string); g_free (supported_bands_string);
g_free (access_technologies_string); g_free (access_technologies_string);
g_free (modem_capabilities_string); g_free (supported_capabilities_string);
g_free (current_capabilities_string); g_free (current_capabilities_string);
g_free (prefixed_revision); g_free (prefixed_revision);
g_free (allowed_modes_string); g_free (allowed_modes_string);

View File

@@ -80,7 +80,8 @@ mm_modem_dup_path
mm_modem_get_state mm_modem_get_state
mm_modem_get_state_failed_reason mm_modem_get_state_failed_reason
mm_modem_get_power_state mm_modem_get_power_state
mm_modem_get_modem_capabilities mm_modem_peek_supported_capabilities
mm_modem_get_supported_capabilities
mm_modem_get_current_capabilities mm_modem_get_current_capabilities
mm_modem_get_manufacturer mm_modem_get_manufacturer
mm_modem_dup_manufacturer mm_modem_dup_manufacturer
@@ -1436,7 +1437,6 @@ mm_gdbus_modem_get_max_active_bearers
mm_gdbus_modem_get_max_bearers mm_gdbus_modem_get_max_bearers
mm_gdbus_modem_get_model mm_gdbus_modem_get_model
mm_gdbus_modem_dup_model mm_gdbus_modem_dup_model
mm_gdbus_modem_get_modem_capabilities
mm_gdbus_modem_get_own_numbers mm_gdbus_modem_get_own_numbers
mm_gdbus_modem_dup_own_numbers mm_gdbus_modem_dup_own_numbers
mm_gdbus_modem_get_plugin mm_gdbus_modem_get_plugin
@@ -1450,6 +1450,8 @@ mm_gdbus_modem_get_signal_quality
mm_gdbus_modem_dup_signal_quality mm_gdbus_modem_dup_signal_quality
mm_gdbus_modem_get_sim mm_gdbus_modem_get_sim
mm_gdbus_modem_dup_sim mm_gdbus_modem_dup_sim
mm_gdbus_modem_get_supported_capabilities
mm_gdbus_modem_dup_supported_capabilities
mm_gdbus_modem_get_state mm_gdbus_modem_get_state
mm_gdbus_modem_get_state_failed_reason mm_gdbus_modem_get_state_failed_reason
mm_gdbus_modem_get_supported_bands mm_gdbus_modem_get_supported_bands
@@ -1504,13 +1506,13 @@ mm_gdbus_modem_set_manufacturer
mm_gdbus_modem_set_max_active_bearers mm_gdbus_modem_set_max_active_bearers
mm_gdbus_modem_set_max_bearers mm_gdbus_modem_set_max_bearers
mm_gdbus_modem_set_model mm_gdbus_modem_set_model
mm_gdbus_modem_set_modem_capabilities
mm_gdbus_modem_set_own_numbers mm_gdbus_modem_set_own_numbers
mm_gdbus_modem_set_plugin mm_gdbus_modem_set_plugin
mm_gdbus_modem_set_primary_port mm_gdbus_modem_set_primary_port
mm_gdbus_modem_set_revision mm_gdbus_modem_set_revision
mm_gdbus_modem_set_signal_quality mm_gdbus_modem_set_signal_quality
mm_gdbus_modem_set_sim mm_gdbus_modem_set_sim
mm_gdbus_modem_set_supported_capabilities
mm_gdbus_modem_set_state mm_gdbus_modem_set_state
mm_gdbus_modem_set_state_failed_reason mm_gdbus_modem_set_state_failed_reason
mm_gdbus_modem_set_power_state mm_gdbus_modem_set_power_state

View File

@@ -38,6 +38,7 @@
* @MM_MODEM_CAPABILITY_LTE: Modem has LTE data capability. * @MM_MODEM_CAPABILITY_LTE: Modem has LTE data capability.
* @MM_MODEM_CAPABILITY_LTE_ADVANCED: Modem has LTE Advanced data capability. * @MM_MODEM_CAPABILITY_LTE_ADVANCED: Modem has LTE Advanced data capability.
* @MM_MODEM_CAPABILITY_IRIDIUM: Modem has Iridium capabilities. * @MM_MODEM_CAPABILITY_IRIDIUM: Modem has Iridium capabilities.
* @MM_MODEM_CAPABILITY_ANY: Mask specifying all capabilities.
* *
* Flags describing one or more of the general access technology families that a * Flags describing one or more of the general access technology families that a
* modem supports. * modem supports.
@@ -50,6 +51,7 @@ typedef enum { /*< underscore_name=mm_modem_capability >*/
MM_MODEM_CAPABILITY_LTE = 1 << 3, MM_MODEM_CAPABILITY_LTE = 1 << 3,
MM_MODEM_CAPABILITY_LTE_ADVANCED = 1 << 4, MM_MODEM_CAPABILITY_LTE_ADVANCED = 1 << 4,
MM_MODEM_CAPABILITY_IRIDIUM = 1 << 5, MM_MODEM_CAPABILITY_IRIDIUM = 1 << 5,
MM_MODEM_CAPABILITY_ANY = 0xFFFFFFFF
} MMModemCapability; } MMModemCapability;
/** /**

View File

@@ -200,17 +200,17 @@
<property name="Sim" type="o" access="read" /> <property name="Sim" type="o" access="read" />
<!-- <!--
ModemCapabilities: SupportedCapabilities:
Bitmask of <link linkend="MMModemCapability">MMModemCapability</link> List of <link linkend="MMModemCapability">MMModemCapability</link>
values, specifying the generic family of access technologies the modem values, specifying the combinations of generic family of access
supports. technologies the modem supports.
Not all capabilities are available at the same time however; some If the modem doesn't allow changing the current capabilities, a single entry with
modems require a firmware reload or other reinitialization to switch <link linkend="MM-MODEM-CAPABILITY-ANY:CAPS"><constant>MM_MODEM_CAPABILITY_ANY</constant></link>
between e.g. CDMA/EVDO and GSM/UMTS. will be given.
--> -->
<property name="ModemCapabilities" type="u" access="read" /> <property name="SupportedCapabilities" type="au" access="read" />
<!-- <!--
CurrentCapabilities: CurrentCapabilities:

View File

@@ -25,6 +25,34 @@
#include "mm-errors-types.h" #include "mm-errors-types.h"
#include "mm-common-helpers.h" #include "mm-common-helpers.h"
gchar *
mm_common_build_capabilities_string (const MMModemCapability *capabilities,
guint n_capabilities)
{
gboolean first = TRUE;
GString *str;
guint i;
if (!capabilities || !n_capabilities)
return g_strdup ("none");
str = g_string_new ("");
for (i = 0; i < n_capabilities; i++) {
gchar *tmp;
tmp = mm_modem_capability_build_string_from_mask (capabilities[i]);
g_string_append_printf (str, "%s%s",
first ? "" : "\n",
tmp);
g_free (tmp);
if (first)
first = FALSE;
}
return g_string_free (str, FALSE);
}
gchar * gchar *
mm_common_build_bands_string (const MMModemBand *bands, mm_common_build_bands_string (const MMModemBand *bands,
guint n_bands) guint n_bands)
@@ -216,6 +244,103 @@ mm_common_get_modes_from_string (const gchar *str,
return modes; return modes;
} }
GArray *
mm_common_capability_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) {
guint32 capability;
array = g_array_sized_new (FALSE, FALSE, sizeof (MMModemCapability), n);
while (g_variant_iter_loop (&iter, "u", &capability))
g_array_append_val (array, capability);
}
}
/* If nothing set, fallback to default */
if (!array) {
guint32 capability = MM_MODEM_CAPABILITY_NONE;
array = g_array_sized_new (FALSE, FALSE, sizeof (MMModemCapability), 1);
g_array_append_val (array, capability);
}
return array;
}
MMModemCapability *
mm_common_capability_combinations_variant_to_array (GVariant *variant,
guint *n_capabilities)
{
GArray *array;
array = mm_common_capability_combinations_variant_to_garray (variant);
if (n_capabilities)
*n_capabilities = array->len;
return (MMModemCapability *) g_array_free (array, FALSE);
}
GVariant *
mm_common_capability_combinations_array_to_variant (const MMModemCapability *capabilities,
guint n_capabilities)
{
GVariantBuilder builder;
g_variant_builder_init (&builder, G_VARIANT_TYPE ("au"));
if (n_capabilities > 0) {
guint i;
for (i = 0; i < n_capabilities; i++)
g_variant_builder_add_value (&builder,
g_variant_new_uint32 ((guint32)capabilities[i]));
} else
g_variant_builder_add_value (&builder,
g_variant_new_uint32 (MM_MODEM_CAPABILITY_NONE));
return g_variant_builder_end (&builder);
}
GVariant *
mm_common_capability_combinations_garray_to_variant (GArray *array)
{
if (array)
return mm_common_capability_combinations_array_to_variant ((const MMModemCapability *)array->data,
array->len);
return mm_common_capability_combinations_array_to_variant (NULL, 0);
}
GVariant *
mm_common_build_capability_combinations_none (void)
{
GVariantBuilder builder;
g_variant_builder_init (&builder, G_VARIANT_TYPE ("au"));
g_variant_builder_add_value (&builder,
g_variant_new_uint32 (MM_MODEM_CAPABILITY_NONE));
return g_variant_builder_end (&builder);
}
GVariant *
mm_common_build_capability_combinations_any (void)
{
GVariantBuilder builder;
g_variant_builder_init (&builder, G_VARIANT_TYPE ("au"));
g_variant_builder_add_value (&builder,
g_variant_new_uint32 (MM_MODEM_CAPABILITY_ANY));
return g_variant_builder_end (&builder);
}
void void
mm_common_get_bands_from_string (const gchar *str, mm_common_get_bands_from_string (const gchar *str,
MMModemBand **bands, MMModemBand **bands,

View File

@@ -26,6 +26,9 @@
#ifndef MM_COMMON_HELPERS_H #ifndef MM_COMMON_HELPERS_H
#define MM_COMMON_HELPERS_H #define MM_COMMON_HELPERS_H
gchar *mm_common_build_capabilities_string (const MMModemCapability *capabilities,
guint n_capabilities);
gchar *mm_common_build_bands_string (const MMModemBand *bands, gchar *mm_common_build_bands_string (const MMModemBand *bands,
guint n_bands); guint n_bands);
@@ -79,6 +82,15 @@ GVariant *mm_common_mode_combinations_array_to_variant (const MMM
GVariant *mm_common_mode_combinations_garray_to_variant (GArray *array); GVariant *mm_common_mode_combinations_garray_to_variant (GArray *array);
GVariant *mm_common_build_mode_combinations_default (void); GVariant *mm_common_build_mode_combinations_default (void);
GArray *mm_common_capability_combinations_variant_to_garray (GVariant *variant);
MMModemCapability *mm_common_capability_combinations_variant_to_array (GVariant *variant,
guint *n_capabilities);
GVariant *mm_common_capability_combinations_array_to_variant (const MMModemCapability *capabilities,
guint n_capabilities);
GVariant *mm_common_capability_combinations_garray_to_variant (GArray *array);
GVariant *mm_common_build_capability_combinations_any (void);
GVariant *mm_common_build_capability_combinations_none (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

@@ -54,6 +54,11 @@ struct _MMModemPrivate {
guint supported_modes_id; guint supported_modes_id;
GArray *supported_modes; GArray *supported_modes;
/* Supported Capabilities */
GMutex supported_capabilities_mutex;
guint supported_capabilities_id;
GArray *supported_capabilities;
/* Supported Bands */ /* Supported Bands */
GMutex supported_bands_mutex; GMutex supported_bands_mutex;
guint supported_bands_id; guint supported_bands_id;
@@ -148,24 +153,118 @@ mm_modem_dup_sim_path (MMModem *self)
/*****************************************************************************/ /*****************************************************************************/
/** static void
* mm_modem_get_modem_capabilities: supported_capabilities_updated (MMModem *self,
* @self: A #MMModem. GParamSpec *pspec)
*
* Gets the list of generic families of access technologies supported by this #MMModem.
*
* Not all capabilities are available at the same time however; some
* modems require a firmware reload or other reinitialization to switch
* between e.g. CDMA/EVDO and GSM/UMTS.
*
* Returns: A bitmask of #MMModemCapability flags.
*/
MMModemCapability
mm_modem_get_modem_capabilities (MMModem *self)
{ {
g_return_val_if_fail (MM_IS_MODEM (self), MM_MODEM_CAPABILITY_NONE); g_mutex_lock (&self->priv->supported_capabilities_mutex);
{
GVariant *dictionary;
return (MMModemCapability) mm_gdbus_modem_get_modem_capabilities (MM_GDBUS_MODEM (self)); if (self->priv->supported_capabilities)
g_array_unref (self->priv->supported_capabilities);
dictionary = mm_gdbus_modem_get_supported_capabilities (MM_GDBUS_MODEM (self));
self->priv->supported_capabilities = (dictionary ?
mm_common_capability_combinations_variant_to_garray (dictionary) :
NULL);
}
g_mutex_unlock (&self->priv->supported_capabilities_mutex);
}
static gboolean
ensure_internal_supported_capabilities (MMModem *self,
MMModemCapability **dup_capabilities,
guint *dup_capabilities_n)
{
gboolean ret;
g_mutex_lock (&self->priv->supported_capabilities_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_capabilities_id) {
GVariant *dictionary;
dictionary = mm_gdbus_modem_dup_supported_capabilities (MM_GDBUS_MODEM (self));
if (dictionary) {
self->priv->supported_capabilities = mm_common_capability_combinations_variant_to_garray (dictionary);
g_variant_unref (dictionary);
}
/* No need to clear this signal connection when freeing self */
self->priv->supported_capabilities_id =
g_signal_connect (self,
"notify::supported-capabilities",
G_CALLBACK (supported_capabilities_updated),
NULL);
}
if (!self->priv->supported_capabilities)
ret = FALSE;
else {
ret = TRUE;
if (dup_capabilities && dup_capabilities_n) {
*dup_capabilities_n = self->priv->supported_capabilities->len;
if (self->priv->supported_capabilities->len > 0) {
*dup_capabilities = g_malloc (sizeof (MMModemCapability) * self->priv->supported_capabilities->len);
memcpy (*dup_capabilities, self->priv->supported_capabilities->data, sizeof (MMModemCapability) * self->priv->supported_capabilities->len);
} else
*dup_capabilities = NULL;
}
}
}
g_mutex_unlock (&self->priv->supported_capabilities_mutex);
return ret;
}
/**
* mm_modem_get_supported_capabilities:
* @self: A #MMModem.
* @capabilities: (out) (array length=n_capabilities): Return location for the array of #MMModemCapability values. The returned array should be freed with g_free() when no longer needed.
* @n_capabilities: (out): Return location for the number of values in @capabilities.
*
* Gets the list of combinations of generic families of access technologies supported by this #MMModem.
*
* Returns: %TRUE if @capabilities and @n_capabilities are set, %FALSE otherwise.
*/
gboolean
mm_modem_get_supported_capabilities (MMModem *self,
MMModemCapability **capabilities,
guint *n_capabilities)
{
g_return_val_if_fail (MM_IS_MODEM (self), FALSE);
return ensure_internal_supported_capabilities (self, capabilities, n_capabilities);
}
/**
* mm_modem_peek_supported_capabilities:
* @self: A #MMModem.
* @capabilities: (out) (array length=n_capabilities): Return location for the array of #MMModemCapability values. Do not free the returned array, it is owned by @self.
* @n_capabilities: (out): Return location for the number of values in @capabilities.
*
* Gets the list of combinations of generic families of access technologies supported by this #MMModem.
*
* Returns: %TRUE if @capabilities and @n_capabilities are set, %FALSE otherwise.
*/
gboolean
mm_modem_peek_supported_capabilities (MMModem *self,
const MMModemCapability **capabilities,
guint *n_capabilities)
{
g_return_val_if_fail (MM_IS_MODEM (self), FALSE);
g_return_val_if_fail (capabilities != NULL, FALSE);
g_return_val_if_fail (n_capabilities != NULL, FALSE);
if (!ensure_internal_supported_capabilities (self, NULL, NULL))
return FALSE;
*n_capabilities = self->priv->supported_capabilities->len;
*capabilities = (MMModemCapability *)self->priv->supported_capabilities->data;
return TRUE;
} }
/*****************************************************************************/ /*****************************************************************************/
@@ -2642,6 +2741,7 @@ mm_modem_init (MMModem *self)
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_modes_mutex);
g_mutex_init (&self->priv->supported_capabilities_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);
} }
@@ -2658,6 +2758,8 @@ finalize (GObject *object)
if (self->priv->supported_modes) if (self->priv->supported_modes)
g_array_unref (self->priv->supported_modes); g_array_unref (self->priv->supported_modes);
if (self->priv->supported_capabilities)
g_array_unref (self->priv->supported_capabilities);
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

@@ -74,7 +74,12 @@ gchar *mm_modem_dup_path (MMModem *self);
const gchar *mm_modem_get_sim_path (MMModem *self); const gchar *mm_modem_get_sim_path (MMModem *self);
gchar *mm_modem_dup_sim_path (MMModem *self); gchar *mm_modem_dup_sim_path (MMModem *self);
MMModemCapability mm_modem_get_modem_capabilities (MMModem *self); gboolean mm_modem_peek_supported_capabilities (MMModem *self,
const MMModemCapability **capabilities,
guint *n_capabilities);
gboolean mm_modem_get_supported_capabilities (MMModem *self,
MMModemCapability **capabilities,
guint *n_capabilities);
MMModemCapability mm_modem_get_current_capabilities (MMModem *self); MMModemCapability mm_modem_get_current_capabilities (MMModem *self);

View File

@@ -2169,8 +2169,6 @@ iface_modem_init (MMIfaceModem *iface)
/* Initialization steps */ /* Initialization steps */
iface->load_current_capabilities = modem_load_current_capabilities; iface->load_current_capabilities = modem_load_current_capabilities;
iface->load_current_capabilities_finish = modem_load_current_capabilities_finish; iface->load_current_capabilities_finish = modem_load_current_capabilities_finish;
iface->load_modem_capabilities = NULL;
iface->load_modem_capabilities_finish = NULL;
iface->load_manufacturer = modem_load_manufacturer; iface->load_manufacturer = modem_load_manufacturer;
iface->load_manufacturer_finish = modem_load_manufacturer_finish; iface->load_manufacturer_finish = modem_load_manufacturer_finish;
iface->load_model = modem_load_model; iface->load_model = modem_load_model;

View File

@@ -555,46 +555,37 @@ modem_load_current_capabilities (MMIfaceModem *self,
} }
/*****************************************************************************/ /*****************************************************************************/
/* Modem Capabilities loading (Modem interface) */ /* Supported capabilities loading (Modem interface) */
typedef struct { typedef struct {
MMBroadbandModemQmi *self; MMBroadbandModemQmi *self;
GSimpleAsyncResult *result; GSimpleAsyncResult *result;
} LoadModemCapabilitiesContext; } LoadSupportedCapabilitiesContext;
static void static void
load_modem_capabilities_context_complete_and_free (LoadModemCapabilitiesContext *ctx) load_supported_capabilities_context_complete_and_free (LoadSupportedCapabilitiesContext *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_slice_free (LoadModemCapabilitiesContext, ctx); g_slice_free (LoadSupportedCapabilitiesContext, ctx);
} }
static MMModemCapability static GArray *
modem_load_modem_capabilities_finish (MMIfaceModem *self, modem_load_supported_capabilities_finish (MMIfaceModem *self,
GAsyncResult *res, GAsyncResult *res,
GError **error) GError **error)
{ {
MMModemCapability caps;
gchar *caps_str;
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_CAPABILITY_NONE; return NULL;
caps = ((MMModemCapability) GPOINTER_TO_UINT ( return g_array_ref (g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (res)));
g_simple_async_result_get_op_res_gpointer (
G_SIMPLE_ASYNC_RESULT (res))));
caps_str = mm_modem_capability_build_string_from_mask (caps);
mm_dbg ("loaded modem capabilities: %s", caps_str);
g_free (caps_str);
return caps;
} }
static void static void
dms_get_capabilities_ready (QmiClientDms *client, dms_get_capabilities_ready (QmiClientDms *client,
GAsyncResult *res, GAsyncResult *res,
LoadModemCapabilitiesContext *ctx) LoadSupportedCapabilitiesContext *ctx)
{ {
QmiMessageDmsGetCapabilitiesOutput *output = NULL; QmiMessageDmsGetCapabilitiesOutput *output = NULL;
GError *error = NULL; GError *error = NULL;
@@ -604,12 +595,15 @@ dms_get_capabilities_ready (QmiClientDms *client,
g_prefix_error (&error, "QMI operation failed: "); g_prefix_error (&error, "QMI operation failed: ");
g_simple_async_result_take_error (ctx->result, 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 supported capabilities: ");
g_simple_async_result_take_error (ctx->result, error); g_simple_async_result_take_error (ctx->result, error);
} else { } else {
guint i; guint i;
guint mask = MM_MODEM_CAPABILITY_NONE; MMModemCapability mask = MM_MODEM_CAPABILITY_NONE;
MMModemCapability single;
GArray *radio_interface_list; GArray *radio_interface_list;
GArray *supported_combinations;
GArray *filtered_combinations;
qmi_message_dms_get_capabilities_output_get_info ( qmi_message_dms_get_capabilities_output_get_info (
output, output,
@@ -631,23 +625,55 @@ dms_get_capabilities_ready (QmiClientDms *client,
g_array_unref (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); ctx->self->priv->supported_radio_interfaces = g_array_ref (radio_interface_list);
supported_combinations = g_array_sized_new (FALSE, FALSE, sizeof (MMModemCapability), 7);
/* Add all possible supported capability combinations, we will filter
* them out afterwards */
/* GSM/UMTS */
single = MM_MODEM_CAPABILITY_GSM_UMTS;
g_array_append_val (supported_combinations, single);
/* CDMA/EVDO */
single = MM_MODEM_CAPABILITY_CDMA_EVDO;
g_array_append_val (supported_combinations, single);
/* LTE only */
single = MM_MODEM_CAPABILITY_LTE;
g_array_append_val (supported_combinations, single);
/* GSM/UMTS + CDMA/EVDO */
single = (MM_MODEM_CAPABILITY_CDMA_EVDO | MM_MODEM_CAPABILITY_GSM_UMTS);
g_array_append_val (supported_combinations, single);
/* GSM/UMTS + LTE */
single = (MM_MODEM_CAPABILITY_GSM_UMTS | MM_MODEM_CAPABILITY_LTE);
g_array_append_val (supported_combinations, single);
/* CDMA/EVDO + LTE */
single = (MM_MODEM_CAPABILITY_CDMA_EVDO | MM_MODEM_CAPABILITY_LTE);
g_array_append_val (supported_combinations, single);
/* GSM/UMTS + CDMA/EVDO + LTE */
single = (MM_MODEM_CAPABILITY_CDMA_EVDO | MM_MODEM_CAPABILITY_GSM_UMTS | MM_MODEM_CAPABILITY_LTE);
g_array_append_val (supported_combinations, single);
/* Now filter out based on the real capabilities of the modem */
filtered_combinations = mm_filter_supported_capabilities (mask,
supported_combinations);
g_array_unref (supported_combinations);
g_simple_async_result_set_op_res_gpointer (ctx->result, g_simple_async_result_set_op_res_gpointer (ctx->result,
GUINT_TO_POINTER (mask), filtered_combinations,
NULL); (GDestroyNotify) g_array_unref);
} }
if (output) if (output)
qmi_message_dms_get_capabilities_output_unref (output); qmi_message_dms_get_capabilities_output_unref (output);
load_modem_capabilities_context_complete_and_free (ctx); load_supported_capabilities_context_complete_and_free (ctx);
} }
static void static void
modem_load_modem_capabilities (MMIfaceModem *self, modem_load_supported_capabilities (MMIfaceModem *self,
GAsyncReadyCallback callback, GAsyncReadyCallback callback,
gpointer user_data) gpointer user_data)
{ {
LoadModemCapabilitiesContext *ctx; LoadSupportedCapabilitiesContext *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),
@@ -655,14 +681,14 @@ modem_load_modem_capabilities (MMIfaceModem *self,
callback, user_data)) callback, user_data))
return; return;
ctx = g_slice_new (LoadModemCapabilitiesContext); ctx = g_slice_new (LoadSupportedCapabilitiesContext);
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,
user_data, user_data,
modem_load_modem_capabilities); modem_load_supported_capabilities);
mm_dbg ("loading modem capabilities..."); mm_dbg ("loading supported capabilities...");
qmi_client_dms_get_capabilities (QMI_CLIENT_DMS (client), qmi_client_dms_get_capabilities (QMI_CLIENT_DMS (client),
NULL, NULL,
5, 5,
@@ -8182,8 +8208,8 @@ iface_modem_init (MMIfaceModem *iface)
/* Initialization steps */ /* Initialization steps */
iface->load_current_capabilities = modem_load_current_capabilities; iface->load_current_capabilities = modem_load_current_capabilities;
iface->load_current_capabilities_finish = modem_load_current_capabilities_finish; iface->load_current_capabilities_finish = modem_load_current_capabilities_finish;
iface->load_modem_capabilities = modem_load_modem_capabilities; iface->load_supported_capabilities = modem_load_supported_capabilities;
iface->load_modem_capabilities_finish = modem_load_modem_capabilities_finish; iface->load_supported_capabilities_finish = modem_load_supported_capabilities_finish;
iface->load_manufacturer = modem_load_manufacturer; iface->load_manufacturer = modem_load_manufacturer;
iface->load_manufacturer_finish = modem_load_manufacturer_finish; iface->load_manufacturer_finish = modem_load_manufacturer_finish;
iface->load_model = modem_load_model; iface->load_model = modem_load_model;

View File

@@ -3501,7 +3501,7 @@ static void interface_initialization_step (InitializationContext *ctx);
typedef enum { typedef enum {
INITIALIZATION_STEP_FIRST, INITIALIZATION_STEP_FIRST,
INITIALIZATION_STEP_CURRENT_CAPABILITIES, INITIALIZATION_STEP_CURRENT_CAPABILITIES,
INITIALIZATION_STEP_MODEM_CAPABILITIES, INITIALIZATION_STEP_SUPPORTED_CAPABILITIES,
INITIALIZATION_STEP_BEARERS, INITIALIZATION_STEP_BEARERS,
INITIALIZATION_STEP_MANUFACTURER, INITIALIZATION_STEP_MANUFACTURER,
INITIALIZATION_STEP_MODEL, INITIALIZATION_STEP_MODEL,
@@ -3681,7 +3681,33 @@ load_current_capabilities_ready (MMIfaceModem *self,
interface_initialization_step (ctx); interface_initialization_step (ctx);
} }
UINT_REPLY_READY_FN (modem_capabilities, "Modem Capabilities") static void
load_supported_capabilities_ready (MMIfaceModem *self,
GAsyncResult *res,
InitializationContext *ctx)
{
GArray *supported_capabilities;
GError *error = NULL;
supported_capabilities = MM_IFACE_MODEM_GET_INTERFACE (self)->load_supported_capabilities_finish (self, res, &error);
if (error) {
g_propagate_error (&ctx->fatal_error, error);
g_prefix_error (&ctx->fatal_error, "couldn't load supported capabilities: ");
/* Jump to the last step */
ctx->step = INITIALIZATION_STEP_LAST;
interface_initialization_step (ctx);
return;
}
/* Update supported caps */
mm_gdbus_modem_set_supported_capabilities (ctx->skeleton,
mm_common_capability_combinations_garray_to_variant (supported_capabilities));
g_array_unref (supported_capabilities);
ctx->step++;
interface_initialization_step (ctx);
}
STR_REPLY_READY_FN (manufacturer, "Manufacturer") STR_REPLY_READY_FN (manufacturer, "Manufacturer")
STR_REPLY_READY_FN (model, "Model") STR_REPLY_READY_FN (model, "Model")
STR_REPLY_READY_FN (revision, "Revision") STR_REPLY_READY_FN (revision, "Revision")
@@ -3935,26 +3961,42 @@ interface_initialization_step (InitializationContext *ctx)
/* Fall down to next step */ /* Fall down to next step */
ctx->step++; ctx->step++;
case INITIALIZATION_STEP_MODEM_CAPABILITIES: case INITIALIZATION_STEP_SUPPORTED_CAPABILITIES: {
/* Modem capabilities are meant to be loaded only once during the whole GArray *supported_capabilities;
supported_capabilities = (mm_common_capability_combinations_variant_to_garray (
mm_gdbus_modem_get_supported_capabilities (ctx->skeleton)));
/* Supported capabilities 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_modem_capabilities (ctx->skeleton) == MM_MODEM_CAPABILITY_NONE && if (supported_capabilities->len == 0 ||
MM_IFACE_MODEM_GET_INTERFACE (ctx->self)->load_modem_capabilities && g_array_index (supported_capabilities, MMModemCapability, 0) == MM_MODEM_CAPABILITY_NONE) {
MM_IFACE_MODEM_GET_INTERFACE (ctx->self)->load_modem_capabilities_finish) { MMModemCapability current;
MM_IFACE_MODEM_GET_INTERFACE (ctx->self)->load_modem_capabilities (
ctx->self, if (MM_IFACE_MODEM_GET_INTERFACE (ctx->self)->load_supported_capabilities &&
(GAsyncReadyCallback)load_modem_capabilities_ready, MM_IFACE_MODEM_GET_INTERFACE (ctx->self)->load_supported_capabilities_finish) {
ctx); MM_IFACE_MODEM_GET_INTERFACE (ctx->self)->load_supported_capabilities (
return; ctx->self,
(GAsyncReadyCallback)load_supported_capabilities_ready,
ctx);
return;
}
/* If no specific way of getting modem capabilities, default to the current ones */
g_array_unref (supported_capabilities);
supported_capabilities = g_array_sized_new (FALSE, FALSE, sizeof (MMModemCapability), 1);
current = mm_gdbus_modem_get_current_capabilities (ctx->skeleton);
g_array_append_val (supported_capabilities, current);
mm_gdbus_modem_set_supported_capabilities (
ctx->skeleton,
mm_common_capability_combinations_garray_to_variant (supported_capabilities));
} }
/* If no specific way of getting modem capabilities, assume they are g_array_unref (supported_capabilities);
* equal to the current capabilities */
mm_gdbus_modem_set_modem_capabilities (
ctx->skeleton,
mm_gdbus_modem_get_current_capabilities (ctx->skeleton));
/* Fall down to next step */ /* Fall down to next step */
ctx->step++; ctx->step++;
}
case INITIALIZATION_STEP_BEARERS: { case INITIALIZATION_STEP_BEARERS: {
MMBearerList *list = NULL; MMBearerList *list = NULL;
@@ -4318,8 +4360,8 @@ mm_iface_modem_initialize (MMIfaceModem *self,
/* Set all initial property defaults */ /* Set all initial property defaults */
mm_gdbus_modem_set_sim (skeleton, NULL); mm_gdbus_modem_set_sim (skeleton, NULL);
mm_gdbus_modem_set_supported_capabilities (skeleton, mm_common_build_capability_combinations_none ());
mm_gdbus_modem_set_current_capabilities (skeleton, MM_MODEM_CAPABILITY_NONE); mm_gdbus_modem_set_current_capabilities (skeleton, MM_MODEM_CAPABILITY_NONE);
mm_gdbus_modem_set_modem_capabilities (skeleton, MM_MODEM_CAPABILITY_NONE);
mm_gdbus_modem_set_max_bearers (skeleton, 0); mm_gdbus_modem_set_max_bearers (skeleton, 0);
mm_gdbus_modem_set_max_active_bearers (skeleton, 0); mm_gdbus_modem_set_max_active_bearers (skeleton, 0);
mm_gdbus_modem_set_manufacturer (skeleton, NULL); mm_gdbus_modem_set_manufacturer (skeleton, NULL);

View File

@@ -42,13 +42,13 @@ typedef struct _MMIfaceModem MMIfaceModem;
struct _MMIfaceModem { struct _MMIfaceModem {
GTypeInterface g_iface; GTypeInterface g_iface;
/* Loading of the ModemCapabilities property */ /* Loading of the SupportedCapabilities property */
void (*load_modem_capabilities) (MMIfaceModem *self, void (*load_supported_capabilities) (MMIfaceModem *self,
GAsyncReadyCallback callback, GAsyncReadyCallback callback,
gpointer user_data); gpointer user_data);
MMModemCapability (*load_modem_capabilities_finish) (MMIfaceModem *self, GArray * (*load_supported_capabilities_finish) (MMIfaceModem *self,
GAsyncResult *res, GAsyncResult *res,
GError **error); GError **error);
/* Loading of the CurrentCapabilities property */ /* Loading of the CurrentCapabilities property */
void (*load_current_capabilities) (MMIfaceModem *self, void (*load_current_capabilities) (MMIfaceModem *self,

View File

@@ -295,6 +295,34 @@ mm_filter_supported_modes (const GArray *all,
/*****************************************************************************/ /*****************************************************************************/
GArray *
mm_filter_supported_capabilities (MMModemCapability all,
const GArray *supported_combinations)
{
guint i;
GArray *filtered_combinations;
g_return_val_if_fail (all != MM_MODEM_CAPABILITY_NONE, NULL);
g_return_val_if_fail (supported_combinations != NULL, NULL);
/* We will filter out all combinations which have modes not listed in 'all' */
filtered_combinations = g_array_sized_new (FALSE, FALSE, sizeof (MMModemCapability), supported_combinations->len);
for (i = 0; i < supported_combinations->len; i++) {
MMModemCapability capability;
capability = g_array_index (supported_combinations, MMModemCapability, i);
if (!(capability & ~all))
g_array_append_val (filtered_combinations, capability);
}
if (filtered_combinations->len == 0)
mm_warn ("All supported capability combinations were filtered out.");
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

@@ -76,6 +76,9 @@ gchar *mm_new_iso8601_time (guint year,
GArray *mm_filter_supported_modes (const GArray *all, GArray *mm_filter_supported_modes (const GArray *all,
const GArray *supported_combinations); const GArray *supported_combinations);
GArray *mm_filter_supported_capabilities (MMModemCapability all,
const GArray *supported_combinations);
/*****************************************************************************/ /*****************************************************************************/
/* 3GPP specific helpers and utilities */ /* 3GPP specific helpers and utilities */
/*****************************************************************************/ /*****************************************************************************/

View File

@@ -2053,6 +2053,98 @@ test_supported_mode_filter (void *f, gpointer d)
/*****************************************************************************/ /*****************************************************************************/
static gboolean
find_capability_combination (GArray *capabilities,
MMModemCapability capability)
{
guint i;
for (i = 0; i < capabilities->len; i++) {
MMModemCapability capability_i;
capability_i = g_array_index (capabilities, MMModemCapability, i);
if (capability_i == capability)
return TRUE;
}
return FALSE;
}
static void
test_supported_capability_filter (void *f, gpointer d)
{
MMModemCapability capability;
GArray *combinations;
GArray *filtered;
combinations = g_array_sized_new (FALSE, FALSE, sizeof (MMModemCapability), 6);
/* GSM/UMTS only */
capability = MM_MODEM_CAPABILITY_GSM_UMTS;
g_array_append_val (combinations, capability);
/* CDMA/EVDO only */
capability = MM_MODEM_CAPABILITY_CDMA_EVDO;
g_array_append_val (combinations, capability);
/* GSM/UMTS and CDMA/EVDO */
capability = (MM_MODEM_CAPABILITY_CDMA_EVDO | MM_MODEM_CAPABILITY_GSM_UMTS);
g_array_append_val (combinations, capability);
/* GSM/UMTS+LTE */
capability = (MM_MODEM_CAPABILITY_GSM_UMTS | MM_MODEM_CAPABILITY_LTE);
g_array_append_val (combinations, capability);
/* CDMA/EVDO+LTE */
capability = (MM_MODEM_CAPABILITY_CDMA_EVDO | MM_MODEM_CAPABILITY_LTE);
g_array_append_val (combinations, capability);
/* GSM/UMTS+CDMA/EVDO+LTE */
capability = (MM_MODEM_CAPABILITY_GSM_UMTS | MM_MODEM_CAPABILITY_CDMA_EVDO | MM_MODEM_CAPABILITY_LTE);
g_array_append_val (combinations, capability);
/* Only GSM-UMTS supported */
filtered = mm_filter_supported_capabilities (MM_MODEM_CAPABILITY_GSM_UMTS, combinations);
g_assert_cmpuint (filtered->len, ==, 1);
g_assert (find_capability_combination (filtered, MM_MODEM_CAPABILITY_GSM_UMTS));
g_array_unref (filtered);
/* Only CDMA-EVDO supported */
filtered = mm_filter_supported_capabilities (MM_MODEM_CAPABILITY_CDMA_EVDO, combinations);
g_assert_cmpuint (filtered->len, ==, 1);
g_assert (find_capability_combination (filtered, MM_MODEM_CAPABILITY_CDMA_EVDO));
g_array_unref (filtered);
/* GSM-UMTS and CDMA-EVDO supported */
filtered = mm_filter_supported_capabilities ((MM_MODEM_CAPABILITY_CDMA_EVDO |
MM_MODEM_CAPABILITY_GSM_UMTS),
combinations);
g_assert_cmpuint (filtered->len, ==, 3);
g_assert (find_capability_combination (filtered, MM_MODEM_CAPABILITY_CDMA_EVDO));
g_assert (find_capability_combination (filtered, MM_MODEM_CAPABILITY_GSM_UMTS));
g_assert (find_capability_combination (filtered, (MM_MODEM_CAPABILITY_GSM_UMTS |
MM_MODEM_CAPABILITY_CDMA_EVDO)));
g_array_unref (filtered);
/* GSM-UMTS, CDMA-EVDO and LTE supported */
filtered = mm_filter_supported_capabilities ((MM_MODEM_CAPABILITY_CDMA_EVDO |
MM_MODEM_CAPABILITY_GSM_UMTS |
MM_MODEM_CAPABILITY_LTE),
combinations);
g_assert_cmpuint (filtered->len, ==, 6);
g_assert (find_capability_combination (filtered, MM_MODEM_CAPABILITY_CDMA_EVDO));
g_assert (find_capability_combination (filtered, MM_MODEM_CAPABILITY_GSM_UMTS));
g_assert (find_capability_combination (filtered, (MM_MODEM_CAPABILITY_GSM_UMTS |
MM_MODEM_CAPABILITY_CDMA_EVDO)));
g_assert (find_capability_combination (filtered, (MM_MODEM_CAPABILITY_GSM_UMTS |
MM_MODEM_CAPABILITY_LTE)));
g_assert (find_capability_combination (filtered, (MM_MODEM_CAPABILITY_CDMA_EVDO |
MM_MODEM_CAPABILITY_LTE)));
g_assert (find_capability_combination (filtered, (MM_MODEM_CAPABILITY_GSM_UMTS |
MM_MODEM_CAPABILITY_CDMA_EVDO |
MM_MODEM_CAPABILITY_LTE)));
g_array_unref (filtered);
g_array_unref (combinations);
}
/*****************************************************************************/
void void
_mm_log (const char *loc, _mm_log (const char *loc,
const char *func, const char *func,
@@ -2184,6 +2276,8 @@ int main (int argc, char **argv)
g_test_suite_add (suite, TESTCASE (test_supported_mode_filter, NULL)); g_test_suite_add (suite, TESTCASE (test_supported_mode_filter, NULL));
g_test_suite_add (suite, TESTCASE (test_supported_capability_filter, NULL));
result = g_test_run (); result = g_test_run ();
reg_test_data_free (reg_data); reg_test_data_free (reg_data);