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.
This commit is contained in:
Aleksander Morgado
2012-09-04 11:34:00 +02:00
parent 72db2a53ed
commit bf1da3faea

View File

@@ -489,6 +489,22 @@ unlock_check_ready (MMIfaceModem *self,
g_object_unref (sim); 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 static void
connection_step (ConnectionContext *ctx) connection_step (ConnectionContext *ctx)
{ {
@@ -634,10 +650,45 @@ connection_step (ConnectionContext *ctx)
if (!ctx->bearer) { if (!ctx->bearer) {
mm_dbg ("Creating new bearer..."); mm_dbg ("Creating new bearer...");
/* If we don't have enough space to create the bearer, try to remove /* If we don't have enough space to create the bearer, try to remove
* all existing ones first. */ * a disconnected bearer first. */
if (mm_bearer_list_get_max (list) == mm_bearer_list_get_count (list)) 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 */ BearerListFindContext foreach_ctx;
mm_bearer_list_delete_all_bearers (list);
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), mm_iface_modem_create_bearer (MM_IFACE_MODEM (ctx->self),
bearer_properties, bearer_properties,