diff options
author | Aleksander Morgado <aleksander@lanedo.com> | 2012-09-04 11:34:00 +0200 |
---|---|---|
committer | Aleksander Morgado <aleksander@lanedo.com> | 2012-09-04 11:34:00 +0200 |
commit | bf1da3faea4605a9a1305993b04e9db425561b1d (patch) | |
tree | ca58e96c0c6c499dd80336d76ef8eff50ad2cabe /src/mm-iface-modem-simple.c | |
parent | 72db2a53ed114a6b46515130a6ed8238eba35bfe (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.c | 59 |
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, |