diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/Makefile.am | 2 | ||||
-rw-r--r-- | src/mm-bearer-list.c | 264 | ||||
-rw-r--r-- | src/mm-bearer-list.h | 68 | ||||
-rw-r--r-- | src/mm-broadband-modem.c | 148 | ||||
-rw-r--r-- | src/mm-iface-modem.c | 218 | ||||
-rw-r--r-- | src/mm-iface-modem.h | 42 |
6 files changed, 468 insertions, 274 deletions
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 <config.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <string.h> +#include <ctype.h> + +#include <ModemManager.h> + +#include <mm-enums-types.h> +#include <mm-errors-types.h> + +#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 <aleksander@lanedo.com> + * + * Copyright (C) 2011 Google, Inc. + */ + +#ifndef MM_BEARER_LIST_H +#define MM_BEARER_LIST_H + +#include <glib.h> +#include <glib-object.h> + +#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,129 +126,19 @@ 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 */ typedef struct { @@ -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 @@ -2779,6 +2667,10 @@ mm_broadband_modem_class_init (MMBroadbandModemClass *klass) 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); |