diff options
-rw-r--r-- | libmm-glib/mm-bearer.c | 545 | ||||
-rw-r--r-- | libmm-glib/mm-bearer.h | 51 | ||||
-rw-r--r-- | libmm-glib/mm-modem-simple.c | 49 | ||||
-rw-r--r-- | libmm-glib/mm-modem.c | 118 |
4 files changed, 596 insertions, 167 deletions
diff --git a/libmm-glib/mm-bearer.c b/libmm-glib/mm-bearer.c index ccd3e77f..36da4f7f 100644 --- a/libmm-glib/mm-bearer.c +++ b/libmm-glib/mm-bearer.c @@ -17,12 +17,45 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * Copyright (C) 2011 Aleksander Morgado <aleksander@gnu.org> + * Copyright (C) 2011 - 2012 Aleksander Morgado <aleksander@gnu.org> + * Copyright (C) 2012 Google, Inc. */ #include "mm-helpers.h" #include "mm-bearer.h" -#include "mm-modem.h" + +/** + * SECTION: mm-bearer + * @title: MMBearer + * @short_description: The Bearer interface + * + * The #MMBearer is an object providing access to the methods, signals and + * properties of the Bearer interface. + * + * When the bearer is exposed and available in the bus, it is ensured that at + * least this interface is also available. + */ + +G_DEFINE_TYPE (MMBearer, mm_bearer, MM_GDBUS_TYPE_BEARER_PROXY) + +struct _MMBearerPrivate { + /* IPv4 config */ + GMutex ipv4_config_mutex; + guint ipv4_config_id; + MMBearerIpConfig *ipv4_config; + + /* IPv6 config */ + GMutex ipv6_config_mutex; + guint ipv6_config_id; + MMBearerIpConfig *ipv6_config; + + /* Properties */ + GMutex properties_mutex; + guint properties_id; + MMBearerProperties *properties; +}; + +/*****************************************************************************/ /** * mm_bearer_get_path: @@ -35,7 +68,7 @@ const gchar * mm_bearer_get_path (MMBearer *self) { - g_return_val_if_fail (G_IS_DBUS_PROXY (self), NULL); + g_return_val_if_fail (MM_IS_BEARER (self), NULL); RETURN_NON_EMPTY_CONSTANT_STRING ( g_dbus_proxy_get_object_path (G_DBUS_PROXY (self))); @@ -54,7 +87,7 @@ mm_bearer_dup_path (MMBearer *self) { gchar *value; - g_return_val_if_fail (G_IS_DBUS_PROXY (self), NULL); + g_return_val_if_fail (MM_IS_BEARER (self), NULL); g_object_get (G_OBJECT (self), "g-object-path", &value, @@ -63,6 +96,8 @@ mm_bearer_dup_path (MMBearer *self) RETURN_NON_EMPTY_STRING (value); } +/*****************************************************************************/ + /** * mm_bearer_get_interface: * @self: A #MMBearer. @@ -71,17 +106,20 @@ mm_bearer_dup_path (MMBearer *self) * packet data using this #MMBearer. This will only be available once the #MMBearer * is in connected state. * - * <warning>It is only safe to use this function on the thread where @self was constructed. Use mm_bearer_dup_interface() if on another thread.</warning> + * <warning>The returned value is only valid until the property changes so + * it is only safe to use this function on the thread where + * @self was constructed. Use mm_bearer_dup_interface() if on another + * thread.</warning> * * Returns: (transfer none): The name of the interface, or %NULL if it couldn't be retrieved. */ const gchar * mm_bearer_get_interface (MMBearer *self) { - g_return_val_if_fail (MM_GDBUS_IS_BEARER (self), NULL); + g_return_val_if_fail (MM_IS_BEARER (self), NULL); RETURN_NON_EMPTY_CONSTANT_STRING ( - mm_gdbus_bearer_get_interface (self)); + mm_gdbus_bearer_get_interface (MM_GDBUS_BEARER (self))); } /** @@ -97,12 +135,14 @@ mm_bearer_get_interface (MMBearer *self) gchar * mm_bearer_dup_interface (MMBearer *self) { - g_return_val_if_fail (MM_GDBUS_IS_BEARER (self), NULL); + g_return_val_if_fail (MM_IS_BEARER (self), NULL); RETURN_NON_EMPTY_STRING ( - mm_gdbus_bearer_dup_interface (self)); + mm_gdbus_bearer_dup_interface (MM_GDBUS_BEARER (self))); } +/*****************************************************************************/ + /** * mm_bearer_get_connected: * @self: A #MMBearer. @@ -115,11 +155,13 @@ mm_bearer_dup_interface (MMBearer *self) gboolean mm_bearer_get_connected (MMBearer *self) { - g_return_val_if_fail (MM_GDBUS_IS_BEARER (self), FALSE); + g_return_val_if_fail (MM_IS_BEARER (self), FALSE); - return mm_gdbus_bearer_get_connected (self); + return mm_gdbus_bearer_get_connected (MM_GDBUS_BEARER (self)); } +/*****************************************************************************/ + /** * mm_bearer_get_suspended: * @self: A #MMBearer. @@ -132,107 +174,367 @@ mm_bearer_get_connected (MMBearer *self) gboolean mm_bearer_get_suspended (MMBearer *self) { - g_return_val_if_fail (MM_GDBUS_IS_BEARER (self), FALSE); + g_return_val_if_fail (MM_IS_BEARER (self), FALSE); - return mm_gdbus_bearer_get_suspended (self); + return mm_gdbus_bearer_get_suspended (MM_GDBUS_BEARER (self)); } +/*****************************************************************************/ + +/** + * mm_bearer_get_ip_timeout: + * @self: A #MMBearer. + * + * Gets the maximum time to wait for the bearer to retrieve a valid IP address. + * + * Returns: The IP timeout, or 0 if no specific one given. + */ guint mm_bearer_get_ip_timeout (MMBearer *self) { - g_return_val_if_fail (MM_GDBUS_IS_BEARER (self), 0); + g_return_val_if_fail (MM_IS_BEARER (self), 0); + + return mm_gdbus_bearer_get_ip_timeout (MM_GDBUS_BEARER (self)); +} + +/*****************************************************************************/ + +static void +ipv4_config_updated (MMBearer *self, + GParamSpec *pspec) +{ + g_mutex_lock (&self->priv->ipv4_config_mutex); + { + GVariant *dictionary; + + g_clear_object (&self->priv->ipv4_config); + + /* TODO: update existing object instead of re-creating? */ + dictionary = mm_gdbus_bearer_get_ip4_config (MM_GDBUS_BEARER (self)); + if (dictionary) { + GError *error = NULL; + + self->priv->ipv4_config = mm_bearer_ip_config_new_from_dictionary (dictionary, &error); + if (error) { + g_warning ("Invalid IPv4 configuration update received: %s", error->message); + g_error_free (error); + } + } + } + g_mutex_unlock (&self->priv->ipv4_config_mutex); +} - return mm_gdbus_bearer_get_ip_timeout (self); +static void +ensure_internal_ipv4_config (MMBearer *self, + MMBearerIpConfig **dup) +{ + g_mutex_lock (&self->priv->ipv4_config_mutex); + { + /* If this is the first time ever asking for the object, setup the + * update listener and the initial object, if any. */ + if (!self->priv->ipv4_config_id) { + GVariant *dictionary; + + dictionary = mm_gdbus_bearer_dup_ip4_config (MM_GDBUS_BEARER (self)); + if (dictionary) { + GError *error = NULL; + + self->priv->ipv4_config = mm_bearer_ip_config_new_from_dictionary (dictionary, &error); + if (error) { + g_warning ("Invalid initial IPv4 configuration: %s", error->message); + g_error_free (error); + } + g_variant_unref (dictionary); + } + + /* No need to clear this signal connection when freeing self */ + self->priv->ipv4_config_id = + g_signal_connect (self, + "notify::ip4-config", + G_CALLBACK (ipv4_config_updated), + NULL); + } + + if (dup && self->priv->ipv4_config) + *dup = g_object_ref (self->priv->ipv4_config); + } + g_mutex_unlock (&self->priv->ipv4_config_mutex); } +/** + * mm_bearer_get_ipv4_config: + * @self: A #MMBearer. + * + * Gets a #MMBearerIpConfig object specifying the IPv4 configuration to use in + * the bearer. + * + * <warning>The values reported by @self are not updated when the values in the + * interface change. Instead, the client is expected to call + * mm_bearer_get_ipv4_config() again to get a new #MMBearerIpConfig with the + * new values.</warning> + * + * Returns: (transfer full) A #MMBearerIpConfig that must be freed with g_object_unref() or %NULL if unknown. + */ MMBearerIpConfig * mm_bearer_get_ipv4_config (MMBearer *self) { - MMBearerIpConfig *config; - GVariant *variant; - GError *error = NULL; + MMBearerIpConfig *config = NULL; g_return_val_if_fail (MM_IS_BEARER (self), NULL); - variant = mm_gdbus_bearer_dup_ip4_config (MM_GDBUS_BEARER (self)); - config = mm_bearer_ip_config_new_from_dictionary (variant, &error); - if (!config) { - g_warning ("Couldn't create IP config: '%s'", error->message); - g_error_free (error); + ensure_internal_ipv4_config (self, &config); + return config; +} + +/** + * mm_bearer_peek_ipv4_config: + * @self: A #MMBearer. + * + * Gets a #MMBearerIpConfig object specifying the IPv4 configuration to use in + * the bearer. + * + * <warning>The returned value is only valid until the property changes so + * it is only safe to use this function on the thread where + * @self was constructed. Use mm_bearer_get_ipv4_config() if on another + * thread.</warning> + * + * Returns: (transfer none) A #MMBearerIpConfig. Do not free the returned value, it belongs to @self. + */ +MMBearerIpConfig * +mm_bearer_peek_ipv4_config (MMBearer *self) +{ + g_return_val_if_fail (MM_IS_BEARER (self), NULL); + + ensure_internal_ipv4_config (self, NULL); + return self->priv->ipv4_config; +} + +/*****************************************************************************/ + +static void +ipv6_config_updated (MMBearer *self, + GParamSpec *pspec) +{ + g_mutex_lock (&self->priv->ipv6_config_mutex); + { + GVariant *dictionary; + + g_clear_object (&self->priv->ipv6_config); + + /* TODO: update existing object instead of re-creating? */ + dictionary = mm_gdbus_bearer_get_ip6_config (MM_GDBUS_BEARER (self)); + if (dictionary) { + GError *error = NULL; + + self->priv->ipv6_config = mm_bearer_ip_config_new_from_dictionary (dictionary, &error); + if (error) { + g_warning ("Invalid IPv6 configuration update received: %s", error->message); + g_error_free (error); + } + } } - g_variant_unref (variant); + g_mutex_unlock (&self->priv->ipv6_config_mutex); +} - return config; +static void +ensure_internal_ipv6_config (MMBearer *self, + MMBearerIpConfig **dup) +{ + g_mutex_lock (&self->priv->ipv6_config_mutex); + { + /* If this is the first time ever asking for the object, setup the + * update listener and the initial object, if any. */ + if (!self->priv->ipv6_config_id) { + GVariant *dictionary; + + dictionary = mm_gdbus_bearer_dup_ip6_config (MM_GDBUS_BEARER (self)); + if (dictionary) { + GError *error = NULL; + + self->priv->ipv6_config = mm_bearer_ip_config_new_from_dictionary (dictionary, &error); + if (error) { + g_warning ("Invalid initial IPv6 configuration: %s", error->message); + g_error_free (error); + } + g_variant_unref (dictionary); + } + + /* No need to clear this signal connection when freeing self */ + self->priv->ipv6_config_id = + g_signal_connect (self, + "notify::ip6-config", + G_CALLBACK (ipv6_config_updated), + NULL); + } + + if (dup && self->priv->ipv6_config) + *dup = g_object_ref (self->priv->ipv6_config); + } + g_mutex_unlock (&self->priv->ipv6_config_mutex); } +/** + * mm_bearer_get_ipv6_config: + * @self: A #MMBearer. + * + * Gets a #MMBearerIpConfig object specifying the IPv6 configuration to use in + * the bearer. + * + * <warning>The values reported by @self are not updated when the values in the + * interface change. Instead, the client is expected to call + * mm_bearer_get_ipv6_config() again to get a new #MMBearerIpConfig with the + * new values.</warning> + * + * Returns: (transfer full) A #MMBearerIpConfig that must be freed with g_object_unref() or %NULL if unknown. + */ MMBearerIpConfig * mm_bearer_get_ipv6_config (MMBearer *self) { - MMBearerIpConfig *config; - GVariant *variant; - GError *error = NULL; + MMBearerIpConfig *config = NULL; + + g_return_val_if_fail (MM_IS_BEARER (self), NULL); + ensure_internal_ipv6_config (self, &config); + return config; +} + +/** + * mm_bearer_peek_ipv6_config: + * @self: A #MMBearer. + * + * Gets a #MMBearerIpConfig object specifying the IPv6 configuration to use in + * the bearer. + * + * <warning>The returned value is only valid until the property changes so + * it is only safe to use this function on the thread where + * @self was constructed. Use mm_bearer_get_ipv6_config() if on another + * thread.</warning> + * + * Returns: (transfer none) A #MMBearerIpConfig. Do not free the returned value, it belongs to @self. + */ +MMBearerIpConfig * +mm_bearer_peek_ipv6_config (MMBearer *self) +{ g_return_val_if_fail (MM_IS_BEARER (self), NULL); - variant = mm_gdbus_bearer_dup_ip6_config (MM_GDBUS_BEARER (self)); - config = mm_bearer_ip_config_new_from_dictionary (variant, &error); - if (!config) { - g_warning ("Couldn't create IP config: '%s'", error->message); - g_error_free (error); + ensure_internal_ipv6_config (self, NULL); + return self->priv->ipv6_config; +} + +/*****************************************************************************/ + +static void +properties_updated (MMBearer *self, + GParamSpec *pspec) +{ + g_mutex_lock (&self->priv->properties_mutex); + { + GVariant *dictionary; + + g_clear_object (&self->priv->properties); + + /* TODO: update existing object instead of re-creating? */ + dictionary = mm_gdbus_bearer_get_properties (MM_GDBUS_BEARER (self)); + if (dictionary) { + GError *error = NULL; + + self->priv->properties = mm_bearer_properties_new_from_dictionary (dictionary, &error); + if (error) { + g_warning ("Invalid bearer properties received: %s", error->message); + g_error_free (error); + } + } } - g_variant_unref (variant); + g_mutex_unlock (&self->priv->properties_mutex); +} - return config; +static void +ensure_internal_properties (MMBearer *self, + MMBearerProperties **dup) +{ + g_mutex_lock (&self->priv->properties_mutex); + { + /* If this is the first time ever asking for the object, setup the + * update listener and the initial object, if any. */ + if (!self->priv->properties_id) { + GVariant *dictionary; + + dictionary = mm_gdbus_bearer_dup_properties (MM_GDBUS_BEARER (self)); + if (dictionary) { + GError *error = NULL; + + self->priv->properties = mm_bearer_properties_new_from_dictionary (dictionary, &error); + if (error) { + g_warning ("Invalid initial bearer properties: %s", error->message); + g_error_free (error); + } + g_variant_unref (dictionary); + } + + /* No need to clear this signal connection when freeing self */ + self->priv->properties_id = + g_signal_connect (self, + "notify::properties", + G_CALLBACK (properties_updated), + NULL); + } + + if (dup && self->priv->properties) + *dup = g_object_ref (self->priv->properties); + } + g_mutex_unlock (&self->priv->properties_mutex); } +/** + * mm_bearer_get_properties: + * @self: A #MMBearer. + * + * Gets a #MMBearerProperties object specifying the properties which were used + * to create the bearer. + * + * <warning>The values reported by @self are not updated when the values in the + * interface change. Instead, the client is expected to call + * mm_bearer_get_properties() again to get a new #MMBearerProperties with the + * new values.</warning> + * + * Returns: (transfer full) A #MMBearerProperties that must be freed with g_object_unref() or %NULL if unknown. + */ MMBearerProperties * mm_bearer_get_properties (MMBearer *self) { - GError *error = NULL; - MMBearerProperties *properties; + MMBearerProperties *props = NULL; g_return_val_if_fail (MM_IS_BEARER (self), NULL); - properties = (mm_bearer_properties_new_from_dictionary ( - mm_gdbus_bearer_get_properties (MM_GDBUS_BEARER (self)), - &error)); - if (!properties) { - g_warning ("Couldn't create properties: '%s'", error->message); - g_error_free (error); - } - - return properties; + ensure_internal_properties (self, &props); + return props; } /** - * mm_bearer_connect: + * mm_bearer_peek_properties: * @self: A #MMBearer. - * @cancellable: (allow-none): A #GCancellable or %NULL. - * @callback: A #GAsyncReadyCallback to call when the request is satisfied or %NULL. - * @user_data: User data to pass to @callback. * - * Asynchronously requests activation of a packet data connection with the - * network using this #MMBearer properties. + * Gets a #MMBearerProperties object specifying the properties which were used + * to create the bearer. * - * When the operation is finished, @callback will be invoked in the <link linkend="g-main-context-push-thread-default">thread-default main loop</link> of the thread you are calling this method from. - * You can then call mm_bearer_connect_finish() to get the result of the operation. + * <warning>The returned value is only valid until the property changes so + * it is only safe to use this function on the thread where + * @self was constructed. Use mm_bearer_get_properties() if on another + * thread.</warning> * - * See mm_bearer_connect_sync() for the synchronous, blocking version of this method. + * Returns: (transfer none) A #MMBearerProperties. Do not free the returned value, it belongs to @self. */ -void -mm_bearer_connect (MMBearer *self, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data) +MMBearerProperties * +mm_bearer_peek_properties (MMBearer *self) { - g_return_if_fail (MM_GDBUS_IS_BEARER (self)); + g_return_val_if_fail (MM_IS_BEARER (self), NULL); - mm_gdbus_bearer_call_connect (self, - cancellable, - callback, - user_data); + ensure_internal_properties (self, NULL); + return self->priv->properties; } +/*****************************************************************************/ + /** * mm_bearer_connect_finish: * @self: A #MMBearer. @@ -241,16 +543,42 @@ mm_bearer_connect (MMBearer *self, * * Finishes an operation started with mm_bearer_connect(). * - * Returns: (skip): %TRUE if the operation succeded, %FALSE if @error is set. + * Returns: %TRUE if the operation succeded, %FALSE if @error is set. */ gboolean mm_bearer_connect_finish (MMBearer *self, GAsyncResult *res, GError **error) { - g_return_val_if_fail (MM_GDBUS_IS_BEARER (self), FALSE); + g_return_val_if_fail (MM_IS_BEARER (self), FALSE); + + return mm_gdbus_bearer_call_connect_finish (MM_GDBUS_BEARER (self), res, error); +} + +/** + * mm_bearer_connect: + * @self: A #MMBearer. + * @cancellable: (allow-none): A #GCancellable or %NULL. + * @callback: A #GAsyncReadyCallback to call when the request is satisfied or %NULL. + * @user_data: User data to pass to @callback. + * + * Asynchronously requests activation of a packet data connection with the + * network using this #MMBearer properties. + * + * When the operation is finished, @callback will be invoked in the <link linkend="g-main-context-push-thread-default">thread-default main loop</link> of the thread you are calling this method from. + * You can then call mm_bearer_connect_finish() to get the result of the operation. + * + * See mm_bearer_connect_sync() for the synchronous, blocking version of this method. + */ +void +mm_bearer_connect (MMBearer *self, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + g_return_if_fail (MM_IS_BEARER (self)); - return mm_gdbus_bearer_call_connect_finish (self, res, error); + mm_gdbus_bearer_call_connect (MM_GDBUS_BEARER (self), cancellable, callback, user_data); } /** @@ -265,20 +593,20 @@ mm_bearer_connect_finish (MMBearer *self, * The calling thread is blocked until a reply is received. * See mm_bearer_connect() for the asynchronous version of this method. * - * Returns: (skip): %TRUE if the operation succeded, %FALSE if @error is set. + * Returns: %TRUE if the operation succeded, %FALSE if @error is set. */ gboolean mm_bearer_connect_sync (MMBearer *self, GCancellable *cancellable, GError **error) { - g_return_val_if_fail (MM_GDBUS_IS_BEARER (self), FALSE); + g_return_val_if_fail (MM_IS_BEARER (self), FALSE); - return mm_gdbus_bearer_call_connect_sync (self, - cancellable, - error); + return mm_gdbus_bearer_call_connect_sync (MM_GDBUS_BEARER (self), cancellable, error); } +/*****************************************************************************/ + /** * mm_bearer_disconnect: * @self: A #MMBearer. @@ -299,12 +627,9 @@ mm_bearer_disconnect (MMBearer *self, GAsyncReadyCallback callback, gpointer user_data) { - g_return_if_fail (MM_GDBUS_IS_BEARER (self)); + g_return_if_fail (MM_IS_BEARER (self)); - mm_gdbus_bearer_call_disconnect (self, - cancellable, - callback, - user_data); + mm_gdbus_bearer_call_disconnect (MM_GDBUS_BEARER (self), cancellable, callback, user_data); } /** @@ -315,16 +640,16 @@ mm_bearer_disconnect (MMBearer *self, * * Finishes an operation started with mm_bearer_disconnect(). * - * Returns: (skip): %TRUE if the operation succeded, %FALSE if @error is set. + * Returns: %TRUE if the operation succeded, %FALSE if @error is set. */ gboolean mm_bearer_disconnect_finish (MMBearer *self, GAsyncResult *res, GError **error) { - g_return_val_if_fail (MM_GDBUS_IS_BEARER (self), FALSE); + g_return_val_if_fail (MM_IS_BEARER (self), FALSE); - return mm_gdbus_bearer_call_disconnect_finish (self, res, error); + return mm_gdbus_bearer_call_disconnect_finish (MM_GDBUS_BEARER (self), res, error); } /** @@ -338,16 +663,64 @@ mm_bearer_disconnect_finish (MMBearer *self, * The calling thread is blocked until a reply is received. * See mm_bearer_disconnect() for the asynchronous version of this method. * - * Returns: (skip): %TRUE if the operation succeded, %FALSE if @error is set. + * Returns: %TRUE if the operation succeded, %FALSE if @error is set. */ gboolean mm_bearer_disconnect_sync (MMBearer *self, GCancellable *cancellable, GError **error) { - g_return_val_if_fail (MM_GDBUS_IS_BEARER (self), FALSE); + g_return_val_if_fail (MM_IS_BEARER (self), FALSE); + + return mm_gdbus_bearer_call_disconnect_sync (MM_GDBUS_BEARER (self), cancellable, error); +} + +/*****************************************************************************/ + +static void +mm_bearer_init (MMBearer *self) +{ + /* Setup private data */ + self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, + MM_TYPE_BEARER, + MMBearerPrivate); + g_mutex_init (&self->priv->ipv4_config_mutex); + g_mutex_init (&self->priv->ipv6_config_mutex); + g_mutex_init (&self->priv->properties_mutex); +} + +static void +finalize (GObject *object) +{ + MMBearer *self = MM_BEARER (object); + + g_mutex_clear (&self->priv->ipv4_config_mutex); + g_mutex_clear (&self->priv->ipv6_config_mutex); + g_mutex_clear (&self->priv->properties_mutex); + + G_OBJECT_CLASS (mm_bearer_parent_class)->finalize (object); +} + +static void +dispose (GObject *object) +{ + MMBearer *self = MM_BEARER (object); + + g_clear_object (&self->priv->ipv4_config); + g_clear_object (&self->priv->ipv6_config); + g_clear_object (&self->priv->properties); + + G_OBJECT_CLASS (mm_bearer_parent_class)->dispose (object); +} + +static void +mm_bearer_class_init (MMBearerClass *bearer_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (bearer_class); + + g_type_class_add_private (object_class, sizeof (MMBearerPrivate)); - return mm_gdbus_bearer_call_disconnect_sync (self, - cancellable, - error); + /* Virtual methods */ + object_class->dispose = dispose; + object_class->finalize = finalize; } diff --git a/libmm-glib/mm-bearer.h b/libmm-glib/mm-bearer.h index e03f8288..585746b7 100644 --- a/libmm-glib/mm-bearer.h +++ b/libmm-glib/mm-bearer.h @@ -17,7 +17,8 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * Copyright (C) 2011 Aleksander Morgado <aleksander@gnu.org> + * Copyright (C) 2011 - 2012 Aleksander Morgado <aleksander@gnu.org> + * Copyright (C) 2012 Google, Inc. */ #ifndef _MM_BEARER_H_ @@ -28,17 +29,46 @@ G_BEGIN_DECLS -typedef MmGdbusBearer MMBearer; -#define MM_TYPE_BEARER(o) MM_GDBUS_TYPE_BEARER (o) -#define MM_BEARER(o) MM_GDBUS_BEARER(o) -#define MM_IS_BEARER(o) MM_GDBUS_IS_BEARER(o) +#define MM_TYPE_BEARER (mm_bearer_get_type ()) +#define MM_BEARER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MM_TYPE_BEARER, MMBearer)) +#define MM_BEARER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), MM_TYPE_BEARER, MMBearerClass)) +#define MM_IS_BEARER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MM_TYPE_BEARER)) +#define MM_IS_BEARER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), MM_TYPE_BEARER)) +#define MM_BEARER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), MM_TYPE_BEARER, MMBearerClass)) + +typedef struct _MMBearer MMBearer; +typedef struct _MMBearerClass MMBearerClass; +typedef struct _MMBearerPrivate MMBearerPrivate; + +/** + * MMBearer: + * + * The #MMBearer structure contains private data and should only be accessed + * using the provided API. + */ +struct _MMBearer { + /*< private >*/ + MmGdbusBearerProxy parent; + MMBearerPrivate *priv; +}; + +struct _MMBearerClass { + /*< private >*/ + MmGdbusBearerProxyClass parent; +}; + +GType mm_bearer_get_type (void); const gchar *mm_bearer_get_path (MMBearer *self); gchar *mm_bearer_dup_path (MMBearer *self); + const gchar *mm_bearer_get_interface (MMBearer *self); gchar *mm_bearer_dup_interface (MMBearer *self); + gboolean mm_bearer_get_connected (MMBearer *self); + gboolean mm_bearer_get_suspended (MMBearer *self); + guint mm_bearer_get_ip_timeout (MMBearer *self); void mm_bearer_connect (MMBearer *self, @@ -63,9 +93,14 @@ gboolean mm_bearer_disconnect_sync (MMBearer *self, GCancellable *cancellable, GError **error); -MMBearerProperties *mm_bearer_get_properties (MMBearer *self); -MMBearerIpConfig *mm_bearer_get_ipv4_config (MMBearer *self); -MMBearerIpConfig *mm_bearer_get_ipv6_config (MMBearer *self); +MMBearerProperties *mm_bearer_get_properties (MMBearer *self); +MMBearerProperties *mm_bearer_peek_properties (MMBearer *self); + +MMBearerIpConfig *mm_bearer_get_ipv4_config (MMBearer *self); +MMBearerIpConfig *mm_bearer_peek_ipv4_config (MMBearer *self); + +MMBearerIpConfig *mm_bearer_get_ipv6_config (MMBearer *self); +MMBearerIpConfig *mm_bearer_peek_ipv6_config (MMBearer *self); G_END_DECLS diff --git a/libmm-glib/mm-modem-simple.c b/libmm-glib/mm-modem-simple.c index e9d09b2f..dd3ec84b 100644 --- a/libmm-glib/mm-modem-simple.c +++ b/libmm-glib/mm-modem-simple.c @@ -125,9 +125,13 @@ new_bearer_ready (GDBusConnection *connection, ConnectContext *ctx) { GError *error = NULL; - MMBearer *bearer; + GObject *bearer; + GObject *source_object; + + source_object = g_async_result_get_source_object (res); + bearer = g_async_initable_new_finish (G_ASYNC_INITABLE (source_object), res, &error); + g_object_unref (source_object); - bearer = mm_gdbus_bearer_proxy_new_finish (res, &error); if (error) g_simple_async_result_take_error (ctx->result, error); else @@ -155,15 +159,17 @@ simple_connect_ready (MMModemSimple *self, return; } - mm_gdbus_bearer_proxy_new ( - g_dbus_proxy_get_connection ( - G_DBUS_PROXY (self)), - G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START, - MM_DBUS_SERVICE, - bearer_path, - ctx->cancellable, - (GAsyncReadyCallback)new_bearer_ready, - ctx); + g_async_initable_new_async (MM_TYPE_BEARER, + G_PRIORITY_DEFAULT, + ctx->cancellable, + (GAsyncReadyCallback)new_bearer_ready, + ctx, + "g-flags", G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START, + "g-name", MM_DBUS_SERVICE, + "g-connection", g_dbus_proxy_get_connection (G_DBUS_PROXY (self)), + "g-object-path", bearer_path, + "g-interface-name", "org.freedesktop.ModemManager1.Bearer", + NULL); } /** @@ -232,7 +238,7 @@ mm_modem_simple_connect_sync (MMModemSimple *self, GCancellable *cancellable, GError **error) { - MMBearer *bearer = NULL; + GObject *bearer = NULL; gchar *bearer_path = NULL; GVariant *variant; @@ -245,20 +251,21 @@ mm_modem_simple_connect_sync (MMModemSimple *self, cancellable, error); if (bearer_path) { - bearer = mm_gdbus_bearer_proxy_new_sync ( - g_dbus_proxy_get_connection ( - G_DBUS_PROXY (self)), - G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START, - MM_DBUS_SERVICE, - bearer_path, - cancellable, - error); + bearer = g_initable_new (MM_TYPE_BEARER, + cancellable, + error, + "g-flags", G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START, + "g-name", MM_DBUS_SERVICE, + "g-connection", g_dbus_proxy_get_connection (G_DBUS_PROXY (self)), + "g-object-path", bearer_path, + "g-interface-name", "org.freedesktop.ModemManager1.Bearer", + NULL); g_free (bearer_path); } g_variant_unref (variant); - return bearer; + return (bearer ? MM_BEARER (bearer) : NULL); } /*****************************************************************************/ diff --git a/libmm-glib/mm-modem.c b/libmm-glib/mm-modem.c index 4b5ac774..37c5ab79 100644 --- a/libmm-glib/mm-modem.c +++ b/libmm-glib/mm-modem.c @@ -1327,15 +1327,21 @@ mm_modem_list_bearers_finish (MMModem *self, return g_list_copy (list); } +static void create_next_bearer (ListBearersContext *ctx); + static void modem_list_bearers_build_object_ready (GDBusConnection *connection, GAsyncResult *res, ListBearersContext *ctx) { - MMBearer *bearer; + GObject *bearer; GError *error = NULL; + GObject *source_object; + + source_object = g_async_result_get_source_object (res); + bearer = g_async_initable_new_finish (G_ASYNC_INITABLE (source_object), res, &error); + g_object_unref (source_object); - bearer = mm_gdbus_bearer_proxy_new_finish (res, &error); if (error) { g_simple_async_result_take_error (ctx->result, error); list_bearers_context_complete_and_free (ctx); @@ -1356,15 +1362,23 @@ modem_list_bearers_build_object_ready (GDBusConnection *connection, } /* Keep on creating next object */ - mm_gdbus_bearer_proxy_new ( - g_dbus_proxy_get_connection ( - G_DBUS_PROXY (ctx->self)), - G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START, - MM_DBUS_SERVICE, - ctx->bearer_paths[ctx->i], - ctx->cancellable, - (GAsyncReadyCallback)modem_list_bearers_build_object_ready, - ctx); + create_next_bearer (ctx); +} + +static void +create_next_bearer (ListBearersContext *ctx) +{ + g_async_initable_new_async (MM_TYPE_BEARER, + G_PRIORITY_DEFAULT, + ctx->cancellable, + (GAsyncReadyCallback)modem_list_bearers_build_object_ready, + ctx, + "g-flags", G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START, + "g-name", MM_DBUS_SERVICE, + "g-connection", g_dbus_proxy_get_connection (G_DBUS_PROXY (ctx->self)), + "g-object-path", ctx->bearer_paths[ctx->i], + "g-interface-name", "org.freedesktop.ModemManager1.Bearer", + NULL); } static void @@ -1390,15 +1404,7 @@ modem_list_bearers_ready (MMModem *self, /* Got list of paths. If at least one found, start creating objects for each */ ctx->i = 0; - mm_gdbus_bearer_proxy_new ( - g_dbus_proxy_get_connection ( - G_DBUS_PROXY (self)), - G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START, - MM_DBUS_SERVICE, - ctx->bearer_paths[ctx->i], - ctx->cancellable, - (GAsyncReadyCallback)modem_list_bearers_build_object_ready, - ctx); + create_next_bearer (ctx); } /** @@ -1475,17 +1481,17 @@ mm_modem_list_bearers_sync (MMModem *self, return NULL; for (i = 0; bearer_paths[i]; i++) { - MMBearer *bearer; - - bearer = mm_gdbus_bearer_proxy_new_sync ( - g_dbus_proxy_get_connection ( - G_DBUS_PROXY (self)), - G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START, - MM_DBUS_SERVICE, - bearer_paths[i], - cancellable, - error); - + GObject *bearer; + + bearer = g_initable_new (MM_TYPE_BEARER, + cancellable, + error, + "g-flags", G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START, + "g-name", MM_DBUS_SERVICE, + "g-connection", g_dbus_proxy_get_connection (G_DBUS_PROXY (self)), + "g-object-path", bearer_paths[i], + "g-interface-name", "org.freedesktop.ModemManager1.Bearer", + NULL); if (!bearer) { bearer_object_list_free (bearer_objects); g_strfreev (bearer_paths); @@ -1546,9 +1552,13 @@ modem_new_bearer_ready (GDBusConnection *connection, CreateBearerContext *ctx) { GError *error = NULL; - MMBearer *bearer; + GObject *bearer; + GObject *source_object; + + source_object = g_async_result_get_source_object (res); + bearer = g_async_initable_new_finish (G_ASYNC_INITABLE (source_object), res, &error); + g_object_unref (source_object); - bearer = mm_gdbus_bearer_proxy_new_finish (res, &error); if (error) g_simple_async_result_take_error (ctx->result, error); else @@ -1577,15 +1587,17 @@ modem_create_bearer_ready (MMModem *self, return; } - mm_gdbus_bearer_proxy_new ( - g_dbus_proxy_get_connection ( - G_DBUS_PROXY (self)), - G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START, - MM_DBUS_SERVICE, - bearer_path, - ctx->cancellable, - (GAsyncReadyCallback)modem_new_bearer_ready, - ctx); + g_async_initable_new_async (MM_TYPE_BEARER, + G_PRIORITY_DEFAULT, + ctx->cancellable, + (GAsyncReadyCallback)modem_new_bearer_ready, + ctx, + "g-flags", G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START, + "g-name", MM_DBUS_SERVICE, + "g-connection", g_dbus_proxy_get_connection (G_DBUS_PROXY (self)), + "g-object-path", bearer_path, + "g-interface-name", "org.freedesktop.ModemManager1.Bearer", + NULL); g_free (bearer_path); } @@ -1630,6 +1642,7 @@ mm_modem_create_bearer (MMModem *self, ctx->cancellable = g_object_ref (cancellable); dictionary = mm_bearer_properties_get_dictionary (properties); + mm_gdbus_modem_call_create_bearer ( MM_GDBUS_MODEM (self), dictionary, @@ -1665,7 +1678,7 @@ mm_modem_create_bearer_sync (MMModem *self, GCancellable *cancellable, GError **error) { - MMBearer *bearer = NULL; + GObject *bearer = NULL; gchar *bearer_path = NULL; GVariant *dictionary; @@ -1678,20 +1691,21 @@ mm_modem_create_bearer_sync (MMModem *self, cancellable, error); if (bearer_path) { - bearer = mm_gdbus_bearer_proxy_new_sync ( - g_dbus_proxy_get_connection ( - G_DBUS_PROXY (self)), - G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START, - MM_DBUS_SERVICE, - bearer_path, - cancellable, - error); + bearer = g_initable_new (MM_TYPE_BEARER, + cancellable, + error, + "g-flags", G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START, + "g-name", MM_DBUS_SERVICE, + "g-connection", g_dbus_proxy_get_connection (G_DBUS_PROXY (self)), + "g-object-path", bearer_path, + "g-interface-name", "org.freedesktop.ModemManager1.Bearer", + NULL); g_free (bearer_path); } g_variant_unref (dictionary); - return bearer; + return (bearer ? MM_BEARER (bearer) : NULL); } /*****************************************************************************/ |