aboutsummaryrefslogtreecommitdiff
path: root/libmm-glib/mm-modem.c
diff options
context:
space:
mode:
Diffstat (limited to 'libmm-glib/mm-modem.c')
-rw-r--r--libmm-glib/mm-modem.c122
1 files changed, 112 insertions, 10 deletions
diff --git a/libmm-glib/mm-modem.c b/libmm-glib/mm-modem.c
index 715bca52..39c7ff2e 100644
--- a/libmm-glib/mm-modem.c
+++ b/libmm-glib/mm-modem.c
@@ -54,6 +54,11 @@ struct _MMModemPrivate {
guint supported_modes_id;
GArray *supported_modes;
+ /* Supported Capabilities */
+ GMutex supported_capabilities_mutex;
+ guint supported_capabilities_id;
+ GArray *supported_capabilities;
+
/* Supported Bands */
GMutex supported_bands_mutex;
guint supported_bands_id;
@@ -148,24 +153,118 @@ mm_modem_dup_sim_path (MMModem *self)
/*****************************************************************************/
+static void
+supported_capabilities_updated (MMModem *self,
+ GParamSpec *pspec)
+{
+ g_mutex_lock (&self->priv->supported_capabilities_mutex);
+ {
+ GVariant *dictionary;
+
+ 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_modem_capabilities:
+ * 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 generic families of access technologies supported by this #MMModem.
+ * Gets the list of combinations 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: %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.
*
- * Returns: A bitmask of #MMModemCapability flags.
+ * 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.
*/
-MMModemCapability
-mm_modem_get_modem_capabilities (MMModem *self)
+gboolean
+mm_modem_peek_supported_capabilities (MMModem *self,
+ const MMModemCapability **capabilities,
+ guint *n_capabilities)
{
- g_return_val_if_fail (MM_IS_MODEM (self), MM_MODEM_CAPABILITY_NONE);
+ 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);
- return (MMModemCapability) mm_gdbus_modem_get_modem_capabilities (MM_GDBUS_MODEM (self));
+ 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);
g_mutex_init (&self->priv->unlock_retries_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->current_bands_mutex);
}
@@ -2658,6 +2758,8 @@ finalize (GObject *object)
if (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)
g_array_unref (self->priv->supported_bands);
if (self->priv->current_bands)