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

Reply via email to