From: Daniel Wagner <[email protected]>
When SessionAutoConnectMode is enabled we should also make sure
we disconnect unused Services. Unused means there is no
Session is using a Service (__connman_session_in_use()) and
asking for a connection (__connman_session_wants_connection())
Note if the user did a Service.Connect() (service->userconnect)
we won't disconnect the Service.
The algorithm could potentially be merged into auto_connect_service()
but this function is already complex enough let's have a
auto_disconnect_service() which runs after auto_connect_service(). The
upside is that we don't change the current play with auto connect
as it seems to work correctly.
---
src/connman.h | 2 ++
src/service.c | 38 ++++++++++++++++++++++++++++++++++++++
src/session.c | 40 ++++++++++++++++++++++++++++++++++++++++
3 files changed, 80 insertions(+)
diff --git a/src/connman.h b/src/connman.h
index dd9fa97..7b107b5 100644
--- a/src/connman.h
+++ b/src/connman.h
@@ -824,6 +824,8 @@ void __connman_session_set_mode(bool enable);
int __connman_session_create(DBusMessage *msg);
int __connman_session_destroy(DBusMessage *msg);
+bool __connman_session_wants_connection(struct connman_service *service);
+bool __connman_session_in_use(struct connman_service *service);
bool __connman_session_active_sessions(struct connman_service *service);
bool __connman_session_running(void);
diff --git a/src/service.c b/src/service.c
index 446b145..6e0b27f 100644
--- a/src/service.c
+++ b/src/service.c
@@ -3577,6 +3577,41 @@ static bool auto_connect_service(GList *services, bool
preferred)
return autoconnecting;
}
+static void auto_disconnect_service(void)
+{
+ GList *list, *services = NULL;
+
+ DBG("");
+
+ for (list = service_list; list; list = list->next) {
+ struct connman_service *service = list->data;
+
+ DBG("service %p userconnect %d", service, service->userconnect);
+
+ if (!is_connected(service))
+ continue;
+
+ if (service->userconnect)
+ continue;
+
+ if (!service->autoconnect)
+ continue;
+
+ if (__connman_session_in_use(service) &&
+ __connman_session_wants_connection(service))
+ continue;
+
+ services = g_list_prepend(services, service);
+ }
+
+ for (list = services; list; list = list->next) {
+ struct connman_service *service = list->data;
+
+ DBG("auto disconnect service %p", service);
+ __connman_service_disconnect(service);
+ }
+}
+
static gboolean run_auto_connect(gpointer data)
{
bool autoconnecting = false;
@@ -3595,6 +3630,9 @@ static gboolean run_auto_connect(gpointer data)
if (!autoconnecting || __connman_session_running())
auto_connect_service(service_list, false);
+ if (connman_setting_get_bool("SessionAutoConnectMode"))
+ auto_disconnect_service();
+
return FALSE;
}
diff --git a/src/session.c b/src/session.c
index 38bc176..cdf0f4d 100644
--- a/src/session.c
+++ b/src/session.c
@@ -1856,6 +1856,46 @@ static void notify_ipconfig_changed(struct
connman_service *service,
}
}
+bool __connman_session_wants_connection(struct connman_service *service)
+{
+ struct service_data *service_data;
+ struct connman_session *session;
+ GSList *list;
+
+ service_data = g_hash_table_lookup(service_hash, service);
+ if (!service_data)
+ return false;
+
+ for (list = service_data->sessions; list; list = list->next) {
+ session = list->data;
+
+ if (session->info->connect)
+ return true;
+ }
+
+ return false;
+}
+
+bool __connman_session_in_use(struct connman_service *service)
+{
+ struct service_data *service_data;
+ struct connman_session *session;
+ GSList *list;
+
+ service_data = g_hash_table_lookup(service_hash, service);
+ if (!service_data)
+ return false;
+
+ for (list = service_data->sessions; list; list = list->next) {
+ session = list->data;
+
+ if (session->service == service)
+ return true;
+ }
+
+ return false;
+}
+
bool __connman_session_active_sessions(struct connman_service *service)
{
struct service_data *service_data;
--
1.8.4.474.g128a96c
_______________________________________________
connman mailing list
[email protected]
https://lists.connman.net/mailman/listinfo/connman