aboutsummaryrefslogtreecommitdiff
path: root/src/mm-iface-modem-simple.c
diff options
context:
space:
mode:
authorAleksander Morgado <aleksander@lanedo.com>2012-09-04 11:34:00 +0200
committerAleksander Morgado <aleksander@lanedo.com>2012-09-04 11:34:00 +0200
commitbf1da3faea4605a9a1305993b04e9db425561b1d (patch)
treeca58e96c0c6c499dd80336d76ef8eff50ad2cabe /src/mm-iface-modem-simple.c
parent72db2a53ed114a6b46515130a6ed8238eba35bfe (diff)
iface-modem-simple: never remove connected bearers
Modems have a maximum of bearers allowed to be connected at a time, number which is given by the number of available ports that may be used for data connections. When Simple.Connect() tries to launch a connection, it will try to find first an existing bearer with the required parameters (e.g. APN, IP type). If such bearer is found, it will just use it. If no such bearer is found, it will try to create one. When trying to create one, if there is no more room for bearers in the modem, we will remove the first disconnected bearer that we find, if any, before trying to create the new one. This logic now makes sure that no connected bearer gets removed in order to create a new one, and also that only one existing gets removed if possible (not every bearer as we did previously). Further logic to connect multiple bearers at a time cannot be done using the Simple interface.
Diffstat (limited to 'src/mm-iface-modem-simple.c')
-rw-r--r--src/mm-iface-modem-simple.c59
1 files changed, 55 insertions, 4 deletions
diff --git a/src/mm-iface-modem-simple.c b/src/mm-iface-modem-simple.c
index e4bc466e..cfec2805 100644
--- a/src/mm-iface-modem-simple.c
+++ b/src/mm-iface-modem-simple.c
@@ -489,6 +489,22 @@ unlock_check_ready (MMIfaceModem *self,
g_object_unref (sim);
}
+typedef struct {
+ MMBearer *found;
+} BearerListFindContext;
+
+static void
+bearer_list_find_disconnected (MMBearer *bearer,
+ BearerListFindContext *ctx)
+{
+ /* If already marked one to remove, do nothing */
+ if (ctx->found)
+ return;
+
+ if (mm_bearer_get_status (bearer) == MM_BEARER_STATUS_DISCONNECTED)
+ ctx->found = g_object_ref (bearer);
+}
+
static void
connection_step (ConnectionContext *ctx)
{
@@ -634,10 +650,45 @@ connection_step (ConnectionContext *ctx)
if (!ctx->bearer) {
mm_dbg ("Creating new bearer...");
/* If we don't have enough space to create the bearer, try to remove
- * all existing ones first. */
- if (mm_bearer_list_get_max (list) == mm_bearer_list_get_count (list))
- /* We'll remove all existing bearers, and then go on creating the new one */
- mm_bearer_list_delete_all_bearers (list);
+ * a disconnected bearer first. */
+ if (mm_bearer_list_get_max (list) == mm_bearer_list_get_count (list)) {
+ BearerListFindContext foreach_ctx;
+
+ foreach_ctx.found = NULL;
+ mm_bearer_list_foreach (list,
+ (MMBearerListForeachFunc)bearer_list_find_disconnected,
+ &foreach_ctx);
+
+ /* Found a disconnected bearer, remove it */
+ if (foreach_ctx.found) {
+ GError *error = NULL;
+
+ if (!mm_bearer_list_delete_bearer (list,
+ mm_bearer_get_path (foreach_ctx.found),
+ &error)) {
+ mm_dbg ("Couldn't delete disconnected bearer at '%s': '%s'",
+ mm_bearer_get_path (foreach_ctx.found),
+ error->message);
+ g_error_free (error);
+ } else
+ mm_dbg ("Deleted disconnected bearer at '%s'",
+ mm_bearer_get_path (foreach_ctx.found));
+ g_object_unref (foreach_ctx.found);
+ }
+
+ /* Re-check space, and if we still are in max, return an error */
+ if (mm_bearer_list_get_max (list) == mm_bearer_list_get_count (list)) {
+ g_dbus_method_invocation_return_error (
+ ctx->invocation,
+ MM_CORE_ERROR,
+ MM_CORE_ERROR_TOO_MANY,
+ "Cannot create new bearer: all existing bearers are connected");
+ connection_context_free (ctx);
+ g_object_unref (list);
+ g_object_unref (bearer_properties);
+ return;
+ }
+ }
mm_iface_modem_create_bearer (MM_IFACE_MODEM (ctx->self),
bearer_properties,