From 776cc66e2c8cd366a9179d66cd193a1ea09a76ea Mon Sep 17 00:00:00 2001 From: Aleksander Morgado Date: Mon, 12 Dec 2011 20:22:51 +0100 Subject: iface-modem: implement all bearer list operations in the interface Bearer list operations, except for Bearer creation, are so generic that the interface itself can implement it for every object implementing the interface. This implementation is based on a new MMBearerList object. --- src/Makefile.am | 2 + src/mm-bearer-list.c | 264 +++++++++++++++++++++++++++++++++++++++++++++++ src/mm-bearer-list.h | 68 ++++++++++++ src/mm-broadband-modem.c | 148 ++++---------------------- src/mm-iface-modem.c | 218 +++++++++++++++++++------------------- src/mm-iface-modem.h | 42 +------- 6 files changed, 468 insertions(+), 274 deletions(-) create mode 100644 src/mm-bearer-list.c create mode 100644 src/mm-bearer-list.h (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index ba1dc5e5..99b091a1 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -112,6 +112,8 @@ modem_manager_SOURCES = \ mm-sim.c \ mm-bearer.h \ mm-bearer.c \ + mm-bearer-list.h \ + mm-bearer-list.c \ mm-base-modem-at.h \ mm-base-modem-at.c \ mm-base-modem.h \ diff --git a/src/mm-bearer-list.c b/src/mm-bearer-list.c new file mode 100644 index 00000000..51476d9e --- /dev/null +++ b/src/mm-bearer-list.c @@ -0,0 +1,264 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details: + * + * Copyright (C) 2008 - 2009 Novell, Inc. + * Copyright (C) 2009 - 2011 Red Hat, Inc. + * Copyright (C) 2011 Google, Inc. + */ + +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +#include "mm-bearer-list.h" +#include "mm-utils.h" +#include "mm-log.h" + +G_DEFINE_TYPE (MMBearerList, mm_bearer_list, G_TYPE_OBJECT); + +enum { + PROP_0, + PROP_MAX_BEARERS, + PROP_MAX_ACTIVE_BEARERS, + PROP_LAST +}; + +static GParamSpec *properties[PROP_LAST]; + +struct _MMBearerListPrivate { + /* List of bearers */ + GList *bearers; + /* Max number of bearers */ + guint max_bearers; + /* Max number of active bearers */ + guint max_active_bearers; +}; + +/*****************************************************************************/ + +guint +mm_bearer_list_get_max (MMBearerList *self) +{ + return self->priv->max_bearers; +} + +guint +mm_bearer_list_get_max_active (MMBearerList *self) +{ + return self->priv->max_active_bearers; +} + +guint +mm_bearer_list_get_count (MMBearerList *self) +{ + return g_list_length (self->priv->bearers); +} + +guint +mm_bearer_list_get_count_active (MMBearerList *self) +{ + return 0; /* TODO */ +} + +gboolean +mm_bearer_list_add_bearer (MMBearerList *self, + MMBearer *bearer, + GError **error) +{ + /* Just in case, ensure we don't go off limits */ + if (g_list_length (self->priv->bearers) == self->priv->max_bearers) { + g_set_error (error, + MM_CORE_ERROR, + MM_CORE_ERROR_TOO_MANY, + "Cannot add new bearer: already reached maximum (%u)", + self->priv->max_bearers); + return FALSE; + } + + /* Keep our own reference */ + self->priv->bearers = g_list_prepend (self->priv->bearers, + g_object_ref (bearer)); + return TRUE; +} + +gboolean +mm_bearer_list_delete_bearer (MMBearerList *self, + const gchar *path, + GError **error) +{ + GList *l; + + if (!g_str_has_prefix (path, MM_DBUS_BEARER_PREFIX)) { + g_set_error (error, + MM_CORE_ERROR, + MM_CORE_ERROR_INVALID_ARGS, + "Cannot delete bearer: invalid path '%s'", + path); + return FALSE; + } + + for (l = self->priv->bearers; l; l = g_list_next (l)) { + if (g_str_equal (path, mm_bearer_get_path (MM_BEARER (l->data)))) { + g_object_unref (l->data); + self->priv->bearers = + g_list_delete_link (self->priv->bearers, l); + return TRUE; + } + } + + g_set_error (error, + MM_CORE_ERROR, + MM_CORE_ERROR_NOT_FOUND, + "Cannot delete bearer: path '%s' not found", + path); + return FALSE; +} + +GStrv +mm_bearer_list_get_paths (MMBearerList *self) +{ + GStrv path_list = NULL; + GList *l; + guint i; + + path_list = g_new0 (gchar *, + 1 + g_list_length (self->priv->bearers)); + + for (i = 0, l = self->priv->bearers; l; l = g_list_next (l)) + path_list[i++] = g_strdup (mm_bearer_get_path (MM_BEARER (l->data))); + + return path_list; +} + +/*****************************************************************************/ + +MMBearerList * +mm_bearer_list_new (guint max_bearers, + guint max_active_bearers) +{ + mm_dbg ("Crearing bearer list (max: %u, max active: %u)", + max_bearers, + max_active_bearers); + + /* Create the object */ + return g_object_new (MM_TYPE_BEARER_LIST, + MM_BEARER_LIST_MAX_BEARERS, max_bearers, + MM_BEARER_LIST_MAX_ACTIVE_BEARERS, max_active_bearers, + NULL); +} + +static void +set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + MMBearerList *self = MM_BEARER_LIST (object); + + switch (prop_id) { + case PROP_MAX_BEARERS: + self->priv->max_bearers = g_value_get_uint (value); + break; + case PROP_MAX_ACTIVE_BEARERS: + self->priv->max_active_bearers = g_value_get_uint (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + MMBearerList *self = MM_BEARER_LIST (object); + + switch (prop_id) { + case PROP_MAX_BEARERS: + g_value_set_uint (value, self->priv->max_bearers); + break; + case PROP_MAX_ACTIVE_BEARERS: + g_value_set_uint (value, self->priv->max_active_bearers); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +mm_bearer_list_init (MMBearerList *self) +{ + /* Initialize private data */ + self->priv = G_TYPE_INSTANCE_GET_PRIVATE ((self), + MM_TYPE_BEARER_LIST, + MMBearerListPrivate); +} + +static void +dispose (GObject *object) +{ + MMBearerList *self = MM_BEARER_LIST (object); + + if (self->priv->bearers) { + g_list_foreach (self->priv->bearers, (GFunc)g_object_unref, NULL); + g_list_free (self->priv->bearers); + self->priv->bearers = NULL; + } + + G_OBJECT_CLASS (mm_bearer_list_parent_class)->dispose (object); +} + +static void +mm_bearer_list_class_init (MMBearerListClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + g_type_class_add_private (object_class, sizeof (MMBearerListPrivate)); + + /* Virtual methods */ + object_class->get_property = get_property; + object_class->set_property = set_property; + object_class->dispose = dispose; + + properties[PROP_MAX_BEARERS] = + g_param_spec_uint (MM_BEARER_LIST_MAX_BEARERS, + "Max bearers", + "Maximum number of bearers the list can handle", + 1, + G_MAXUINT, + 1, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); + g_object_class_install_property (object_class, PROP_MAX_BEARERS, properties[PROP_MAX_BEARERS]); + + properties[PROP_MAX_ACTIVE_BEARERS] = + g_param_spec_uint (MM_BEARER_LIST_MAX_ACTIVE_BEARERS, + "Max active bearers", + "Maximum number of active bearers the list can handle", + 1, + G_MAXUINT, + 1, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); + g_object_class_install_property (object_class, PROP_MAX_ACTIVE_BEARERS, properties[PROP_MAX_ACTIVE_BEARERS]); + +} diff --git a/src/mm-bearer-list.h b/src/mm-bearer-list.h new file mode 100644 index 00000000..52885d09 --- /dev/null +++ b/src/mm-bearer-list.h @@ -0,0 +1,68 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details: + * + * Author: Aleksander Morgado + * + * Copyright (C) 2011 Google, Inc. + */ + +#ifndef MM_BEARER_LIST_H +#define MM_BEARER_LIST_H + +#include +#include + +#include "mm-bearer.h" + +#define MM_TYPE_BEARER_LIST (mm_bearer_list_get_type ()) +#define MM_BEARER_LIST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MM_TYPE_BEARER_LIST, MMBearerList)) +#define MM_BEARER_LIST_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), MM_TYPE_BEARER_LIST, MMBearerListClass)) +#define MM_IS_BEARER_LIST(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MM_TYPE_BEARER_LIST)) +#define MM_IS_BEARER_LIST_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), MM_TYPE_BEARER_LIST)) +#define MM_BEARER_LIST_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), MM_TYPE_BEARER_LIST, MMBearerListClass)) + +#define MM_BEARER_LIST_MAX_BEARERS "max-bearers" +#define MM_BEARER_LIST_MAX_ACTIVE_BEARERS "max-active-bearers" + +typedef struct _MMBearerList MMBearerList; +typedef struct _MMBearerListClass MMBearerListClass; +typedef struct _MMBearerListPrivate MMBearerListPrivate; + +struct _MMBearerList { + GObject parent; + MMBearerListPrivate *priv; +}; + +struct _MMBearerListClass { + GObjectClass parent; +}; + +GType mm_bearer_list_get_type (void); + +MMBearerList *mm_bearer_list_new (guint max_bearers, + guint max_active_bearers); + +GStrv mm_bearer_list_get_paths (MMBearerList *self); + +guint mm_bearer_list_get_count (MMBearerList *self); +guint mm_bearer_list_get_count_active (MMBearerList *self); +guint mm_bearer_list_get_max (MMBearerList *self); +guint mm_bearer_list_get_max_active (MMBearerList *self); + +gboolean mm_bearer_list_add_bearer (MMBearerList *self, + MMBearer *bearer, + GError **error); +gboolean mm_bearer_list_delete_bearer (MMBearerList *self, + const gchar *path, + GError **error); + +#endif /* MM_BEARER_LIST_H */ diff --git a/src/mm-broadband-modem.c b/src/mm-broadband-modem.c index fc006015..2af4db6b 100644 --- a/src/mm-broadband-modem.c +++ b/src/mm-broadband-modem.c @@ -31,6 +31,7 @@ #include "mm-iface-modem.h" #include "mm-iface-modem-3gpp.h" #include "mm-bearer.h" +#include "mm-bearer-list.h" #include "mm-sim.h" #include "mm-log.h" #include "mm-modem-helpers.h" @@ -53,6 +54,7 @@ enum { PROP_MODEM_DBUS_SKELETON, PROP_MODEM_3GPP_DBUS_SKELETON, PROP_MODEM_SIM, + PROP_MODEM_BEARER_LIST, PROP_MODEM_STATE, PROP_MODEM_CURRENT_CAPABILITIES, PROP_MODEM_3GPP_REGISTRATION_STATE, @@ -63,10 +65,10 @@ struct _MMBroadbandModemPrivate { GObject *modem_dbus_skeleton; GObject *modem_3gpp_dbus_skeleton; MMSim *modem_sim; + MMBearerList *modem_bearer_list; MMModemState modem_state; MMModemCapability modem_current_capabilities; MMModem3gppRegistrationState modem_3gpp_registration_state; - GList *modem_bearers; /* Modem helpers */ MMModemCharset current_charset; @@ -83,24 +85,20 @@ struct _MMBroadbandModemPrivate { /*****************************************************************************/ /* CREATE BEARER */ -static gchar * +static MMBearer * modem_create_bearer_finish (MMIfaceModem *self, GAsyncResult *res, GError **error) { - GObject *bearer; - gchar *bearer_path = NULL; + MMBearer *bearer; if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error)) return NULL; bearer = g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (res)); - g_object_get (bearer, - MM_BEARER_PATH, &bearer_path, - NULL); + mm_dbg ("New bearer created at DBus path '%s'", mm_bearer_get_path (bearer)); - mm_dbg ("New bearer created at DBus path '%s'", bearer_path); - return bearer_path; + return g_object_ref (bearer); } static void @@ -109,7 +107,6 @@ modem_create_bearer (MMIfaceModem *self, GAsyncReadyCallback callback, gpointer user_data) { - MMBroadbandModem *broadband = MM_BROADBAND_MODEM (self); GSimpleAsyncResult *result; MMBearer *bearer; GError *error = NULL; @@ -129,128 +126,18 @@ modem_create_bearer (MMIfaceModem *self, return; } - /* Store the bearer */ - broadband->priv->modem_bearers = g_list_prepend (broadband->priv->modem_bearers, - bearer); - /* Set a new ref to the bearer object as result */ result = g_simple_async_result_new (G_OBJECT (self), callback, user_data, modem_create_bearer); g_simple_async_result_set_op_res_gpointer (result, - g_object_ref (bearer), + bearer, (GDestroyNotify)g_object_unref); g_simple_async_result_complete_in_idle (result); g_object_unref (result); } -/*****************************************************************************/ -/* DELETE BEARER */ - -static gboolean -modem_delete_bearer_finish (MMIfaceModem *self, - GAsyncResult *res, - GError **error) -{ - return !g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error); -} - -static void -modem_delete_bearer (MMIfaceModem *self, - const gchar *path, - GAsyncReadyCallback callback, - gpointer user_data) -{ - MMBroadbandModem *broadband = MM_BROADBAND_MODEM (self); - GList *l; - - if (!g_str_has_prefix (path, MM_DBUS_BEARER_PREFIX)) { - g_simple_async_report_error_in_idle ( - G_OBJECT (self), - callback, - user_data, - MM_CORE_ERROR, - MM_CORE_ERROR_INVALID_ARGS, - "Cannot delete bearer: invalid path '%s'", - path); - return; - } - - for (l = broadband->priv->modem_bearers; l; l = g_list_next (l)) { - if (g_str_equal (path, mm_bearer_get_path (MM_BEARER (l->data)))) { - GSimpleAsyncResult *result; - - g_object_unref (l->data); - broadband->priv->modem_bearers = - g_list_delete_link (broadband->priv->modem_bearers, l); - - /* Complete successfully */ - mm_dbg ("Bearer at '%s' deleted", path); - result = g_simple_async_result_new (G_OBJECT (self), - callback, - user_data, - modem_delete_bearer); - g_simple_async_result_set_op_res_gboolean (result, TRUE); - g_simple_async_result_complete_in_idle (result); - g_object_unref (result); - return; - } - } - - g_simple_async_report_error_in_idle ( - G_OBJECT (self), - callback, - user_data, - MM_CORE_ERROR, - MM_CORE_ERROR_INVALID_ARGS, - "Cannot delete bearer: path '%s' not found", - path); -} - -/*****************************************************************************/ -/* LIST BEARERS */ - -static GStrv -modem_list_bearers_finish (MMIfaceModem *self, - GAsyncResult *res, - GError **error) -{ - MMBroadbandModem *broadband = MM_BROADBAND_MODEM (self); - GStrv path_list = NULL; - GList *l; - guint i; - - path_list = g_new0 (gchar *, - 1 + g_list_length (broadband->priv->modem_bearers)); - - for (i = 0, l = broadband->priv->modem_bearers; l; l = g_list_next (l)) { - path_list[i++] = g_strdup (mm_bearer_get_path (MM_BEARER (l->data))); - } - - return path_list; -} - -static void -modem_list_bearers (MMIfaceModem *self, - GAsyncReadyCallback callback, - gpointer user_data) -{ - - GSimpleAsyncResult *result; - - /* Complete successfully, we'll build the result in finish() */ - result = g_simple_async_result_new (G_OBJECT (self), - callback, - user_data, - modem_list_bearers); - g_simple_async_result_set_op_res_gboolean (result, TRUE); - g_simple_async_result_complete_in_idle (result); - g_object_unref (result); -} - - - /*****************************************************************************/ /* CAPABILITIES */ @@ -2581,6 +2468,9 @@ set_property (GObject *object, case PROP_MODEM_SIM: self->priv->modem_sim = g_value_dup_object (value); break; + case PROP_MODEM_BEARER_LIST: + self->priv->modem_bearer_list = g_value_dup_object (value); + break; case PROP_MODEM_STATE: self->priv->modem_state = g_value_get_enum (value); break; @@ -2614,6 +2504,9 @@ get_property (GObject *object, case PROP_MODEM_SIM: g_value_set_object (value, self->priv->modem_sim); break; + case PROP_MODEM_BEARER_LIST: + g_value_set_object (value, self->priv->modem_bearer_list); + break; case PROP_MODEM_STATE: g_value_set_enum (value, self->priv->modem_state); break; @@ -2670,9 +2563,8 @@ dispose (GObject *object) if (self->priv->modem_sim) g_clear_object (&self->priv->modem_sim); - g_list_foreach (self->priv->modem_bearers, (GFunc)g_object_unref, NULL); - g_list_free (self->priv->modem_bearers); - self->priv->modem_bearers = NULL; + if (self->priv->modem_bearer_list) + g_clear_object (&self->priv->modem_bearer_list); G_OBJECT_CLASS (mm_broadband_modem_parent_class)->dispose (object); } @@ -2707,10 +2599,6 @@ iface_modem_init (MMIfaceModem *iface) iface->modem_charset_finish = modem_charset_finish; iface->create_bearer = modem_create_bearer; iface->create_bearer_finish = modem_create_bearer_finish; - iface->delete_bearer = modem_delete_bearer; - iface->delete_bearer_finish = modem_delete_bearer_finish; - iface->list_bearers = modem_list_bearers; - iface->list_bearers_finish = modem_list_bearers_finish; } static void @@ -2778,6 +2666,10 @@ mm_broadband_modem_class_init (MMBroadbandModemClass *klass) PROP_MODEM_SIM, MM_IFACE_MODEM_SIM); + g_object_class_override_property (object_class, + PROP_MODEM_BEARER_LIST, + MM_IFACE_MODEM_BEARER_LIST); + g_object_class_override_property (object_class, PROP_MODEM_STATE, MM_IFACE_MODEM_STATE); diff --git a/src/mm-iface-modem.c b/src/mm-iface-modem.c index d9766fef..4176af3b 100644 --- a/src/mm-iface-modem.c +++ b/src/mm-iface-modem.c @@ -24,6 +24,7 @@ #include "mm-iface-modem.h" #include "mm-base-modem.h" #include "mm-sim.h" +#include "mm-bearer-list.h" #include "mm-log.h" typedef struct _InitializationContext InitializationContext; @@ -71,20 +72,29 @@ handle_create_bearer_ready (MMIfaceModem *self, GAsyncResult *res, DbusCallContext *ctx) { - gchar *path; + MMBearer *bearer; GError *error = NULL; - path = MM_IFACE_MODEM_GET_INTERFACE (self)->create_bearer_finish (self, - res, - &error); + bearer = MM_IFACE_MODEM_GET_INTERFACE (self)->create_bearer_finish (self, + res, + &error); if (error) - g_dbus_method_invocation_take_error (ctx->invocation, - error); - else - mm_gdbus_modem_complete_create_bearer (ctx->skeleton, - ctx->invocation, - path); - g_free (path); + g_dbus_method_invocation_take_error (ctx->invocation, error); + else { + MMBearerList *list = NULL; + + g_object_get (self, + MM_IFACE_MODEM_BEARER_LIST, &list, + NULL); + + if (!mm_bearer_list_add_bearer (list, bearer, &error)) + g_dbus_method_invocation_take_error (ctx->invocation, error); + else + mm_gdbus_modem_complete_create_bearer (ctx->skeleton, + ctx->invocation, + mm_bearer_get_path (bearer)); + g_object_unref (bearer); + } dbus_call_context_free (ctx); } @@ -94,87 +104,78 @@ handle_create_bearer (MmGdbusModem *skeleton, GVariant *arg_properties, MMIfaceModem *self) { - MM_IFACE_MODEM_GET_INTERFACE (self)->create_bearer ( - self, - arg_properties, - (GAsyncReadyCallback)handle_create_bearer_ready, - dbus_call_context_new (skeleton, - invocation, - self)); - return TRUE; -} + MMBearerList *list = NULL; -/*****************************************************************************/ + g_object_get (self, + MM_IFACE_MODEM_BEARER_LIST, &list, + NULL); -static void -handle_delete_bearer_ready (MMIfaceModem *self, - GAsyncResult *res, - DbusCallContext *ctx) -{ - GError *error = NULL; + if (mm_bearer_list_get_count (list) == mm_bearer_list_get_max (list)) { + g_dbus_method_invocation_return_error ( + invocation, + MM_CORE_ERROR, + MM_CORE_ERROR_TOO_MANY, + "Cannot add new bearer: already reached maximum (%u)", + mm_bearer_list_get_count (list)); + } else { + MM_IFACE_MODEM_GET_INTERFACE (self)->create_bearer ( + self, + arg_properties, + (GAsyncReadyCallback)handle_create_bearer_ready, + dbus_call_context_new (skeleton, + invocation, + self)); + } - if (!MM_IFACE_MODEM_GET_INTERFACE (self)->delete_bearer_finish (self, - res, - &error)) - g_dbus_method_invocation_take_error (ctx->invocation, - error); - else - mm_gdbus_modem_complete_delete_bearer (ctx->skeleton, - ctx->invocation); - dbus_call_context_free (ctx); + g_object_unref (list); + return TRUE; } +/*****************************************************************************/ + static gboolean handle_delete_bearer (MmGdbusModem *skeleton, GDBusMethodInvocation *invocation, const gchar *arg_bearer, MMIfaceModem *self) { - MM_IFACE_MODEM_GET_INTERFACE (self)->delete_bearer ( - self, - arg_bearer, - (GAsyncReadyCallback)handle_delete_bearer_ready, - dbus_call_context_new (skeleton, - invocation, - self)); - return TRUE; -} - -/*****************************************************************************/ - -static void -handle_list_bearers_ready (MMIfaceModem *self, - GAsyncResult *res, - DbusCallContext *ctx) -{ - GStrv path_list; + MMBearerList *list = NULL; GError *error = NULL; - path_list = MM_IFACE_MODEM_GET_INTERFACE (self)->list_bearers_finish (self, - res, - &error); - if (error) - g_dbus_method_invocation_take_error (ctx->invocation, - error); + g_object_get (self, + MM_IFACE_MODEM_BEARER_LIST, &list, + NULL); + + if (!mm_bearer_list_delete_bearer (list, arg_bearer, &error)) + g_dbus_method_invocation_take_error (invocation, error); else - mm_gdbus_modem_complete_list_bearers (ctx->skeleton, - ctx->invocation, - (const gchar *const *)path_list); - g_strfreev (path_list); - dbus_call_context_free (ctx); + mm_gdbus_modem_complete_delete_bearer (skeleton, invocation); + + g_object_unref (list); + return TRUE; } +/*****************************************************************************/ + static gboolean handle_list_bearers (MmGdbusModem *skeleton, GDBusMethodInvocation *invocation, MMIfaceModem *self) { - MM_IFACE_MODEM_GET_INTERFACE (self)->list_bearers ( - self, - (GAsyncReadyCallback)handle_list_bearers_ready, - dbus_call_context_new (skeleton, - invocation, - self)); + GStrv paths; + MMBearerList *list = NULL; + + g_object_get (self, + MM_IFACE_MODEM_BEARER_LIST, &list, + NULL); + + paths = mm_bearer_list_get_paths (list); + mm_gdbus_modem_complete_list_bearers (skeleton, + invocation, + (const gchar *const *)paths); + + g_strfreev (paths); + g_object_unref (list); return TRUE; } @@ -1514,8 +1515,7 @@ typedef enum { INITIALIZATION_STEP_FIRST, INITIALIZATION_STEP_CURRENT_CAPABILITIES, INITIALIZATION_STEP_MODEM_CAPABILITIES, - INITIALIZATION_STEP_MAX_BEARERS, - INITIALIZATION_STEP_MAX_ACTIVE_BEARERS, + INITIALIZATION_STEP_BEARERS, INITIALIZATION_STEP_MANUFACTURER, INITIALIZATION_STEP_MODEL, INITIALIZATION_STEP_REVISION, @@ -1645,8 +1645,6 @@ load_current_capabilities_ready (MMIfaceModem *self, } UINT_REPLY_READY_FN (modem_capabilities, "Modem Capabilities") -UINT_REPLY_READY_FN (max_bearers, "Max Bearers") -UINT_REPLY_READY_FN (max_active_bearers, "Max Active Bearers") STR_REPLY_READY_FN (manufacturer, "Manufacturer") STR_REPLY_READY_FN (model, "Model") STR_REPLY_READY_FN (revision, "Revision") @@ -1799,44 +1797,38 @@ interface_initialization_step (InitializationContext *ctx) /* Fall down to next step */ ctx->step++; - case INITIALIZATION_STEP_MAX_BEARERS: - /* Max bearers value is meant to be loaded only once during the whole - * lifetime of the modem. Therefore, if we already have them loaded, - * don't try to load them again. */ - if (mm_gdbus_modem_get_max_bearers (ctx->skeleton) == 0 && - MM_IFACE_MODEM_GET_INTERFACE (ctx->self)->load_max_bearers && - MM_IFACE_MODEM_GET_INTERFACE (ctx->self)->load_max_bearers_finish) { - MM_IFACE_MODEM_GET_INTERFACE (ctx->self)->load_max_bearers ( - ctx->self, - (GAsyncReadyCallback)load_max_bearers_ready, - ctx); - return; - } - /* Default to one bearer */ - mm_gdbus_modem_set_max_bearers (ctx->skeleton, 1); - /* Fall down to next step */ - ctx->step++; + case INITIALIZATION_STEP_BEARERS: { + MMBearerList *list = NULL; - case INITIALIZATION_STEP_MAX_ACTIVE_BEARERS: - /* Max active bearers value is meant to be loaded only once during the - * whole lifetime of the modem. Therefore, if we already have them - * loaded, don't try to load them again. */ - if (mm_gdbus_modem_get_max_active_bearers (ctx->skeleton) == 0 && - MM_IFACE_MODEM_GET_INTERFACE (ctx->self)->load_max_active_bearers && - MM_IFACE_MODEM_GET_INTERFACE (ctx->self)->load_max_active_bearers_finish) { - MM_IFACE_MODEM_GET_INTERFACE (ctx->self)->load_max_active_bearers ( - ctx->self, - (GAsyncReadyCallback)load_max_active_bearers_ready, - ctx); - return; + /* Bearers setup is meant to be loaded only once during the whole + * lifetime of the modem. The list may have been created by the object + * implementing the interface; if so use it. */ + g_object_get (ctx->self, + MM_IFACE_MODEM_BEARER_LIST, &list, + NULL); + + if (!list) { + list = mm_bearer_list_new (1, 1); + + /* Create new default list */ + g_object_set (ctx->self, + MM_IFACE_MODEM_BEARER_LIST, list, + NULL); } - /* If no specific way of getting max active bearers, assume they are - * equal to the absolute max bearers */ - mm_gdbus_modem_set_max_active_bearers ( - ctx->skeleton, - mm_gdbus_modem_get_max_bearers (ctx->skeleton)); + + if (mm_gdbus_modem_get_max_bearers (ctx->skeleton) == 0) + mm_gdbus_modem_set_max_bearers ( + ctx->skeleton, + mm_bearer_list_get_max (list)); + if (mm_gdbus_modem_get_max_active_bearers (ctx->skeleton) == 0) + mm_gdbus_modem_set_max_active_bearers ( + ctx->skeleton, + mm_bearer_list_get_max_active (list)); + g_object_unref (list); + /* Fall down to next step */ ctx->step++; + } case INITIALIZATION_STEP_MANUFACTURER: /* Manufacturer is meant to be loaded only once during the whole @@ -2190,6 +2182,14 @@ iface_modem_init (gpointer g_iface) MM_MODEM_CAPABILITY_NONE, G_PARAM_READWRITE)); + g_object_interface_install_property + (g_iface, + g_param_spec_object (MM_IFACE_MODEM_BEARER_LIST, + "Bearer list", + "List of bearers handled by the modem", + MM_TYPE_BEARER_LIST, + G_PARAM_READWRITE)); + initialized = TRUE; } diff --git a/src/mm-iface-modem.h b/src/mm-iface-modem.h index 22bb2d3a..9aed17e0 100644 --- a/src/mm-iface-modem.h +++ b/src/mm-iface-modem.h @@ -21,6 +21,7 @@ #include "mm-charsets.h" #include "mm-at-serial-port.h" +#include "mm-bearer.h" #define MM_TYPE_IFACE_MODEM (mm_iface_modem_get_type ()) #define MM_IFACE_MODEM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MM_TYPE_IFACE_MODEM, MMIfaceModem)) @@ -31,6 +32,7 @@ #define MM_IFACE_MODEM_CURRENT_CAPABILITIES "iface-modem-current-capabilities" #define MM_IFACE_MODEM_STATE "iface-modem-state" #define MM_IFACE_MODEM_SIM "iface-modem-sim" +#define MM_IFACE_MODEM_BEARER_LIST "iface-modem-bearer-list" typedef struct _MMIfaceModem MMIfaceModem; @@ -53,22 +55,6 @@ struct _MMIfaceModem { GAsyncResult *res, GError **error); - /* Loading of the MaxBearers property */ - void (*load_max_bearers) (MMIfaceModem *self, - GAsyncReadyCallback callback, - gpointer user_data); - guint (*load_max_bearers_finish) (MMIfaceModem *self, - GAsyncResult *res, - GError **error); - - /* Loading of the MaxActiveBearers property */ - void (*load_max_active_bearers) (MMIfaceModem *self, - GAsyncReadyCallback callback, - gpointer user_data); - guint (*load_max_active_bearers_finish) (MMIfaceModem *self, - GAsyncResult *res, - GError **error); - /* Loading of the Manufacturer property */ void (*load_manufacturer) (MMIfaceModem *self, GAsyncReadyCallback callback, @@ -249,27 +235,9 @@ struct _MMIfaceModem { GVariant *properties, GAsyncReadyCallback callback, gpointer user_data); - gchar * (*create_bearer_finish) (MMIfaceModem *self, - GAsyncResult *res, - GError **error); - - /* List bearers */ - void (*list_bearers) (MMIfaceModem *self, - GAsyncReadyCallback callback, - gpointer user_data); - GStrv (*list_bearers_finish) (MMIfaceModem *self, - GAsyncResult *res, - GError **error); - - /* Delete bearer */ - void (*delete_bearer) (MMIfaceModem *self, - const gchar *path, - GAsyncReadyCallback callback, - gpointer user_data); - gboolean (*delete_bearer_finish) (MMIfaceModem *self, - GAsyncResult *res, - GError **error); - + MMBearer * (*create_bearer_finish) (MMIfaceModem *self, + GAsyncResult *res, + GError **error); }; GType mm_iface_modem_get_type (void); -- cgit v1.2.3-70-g09d2