From: Daniel Wagner <[email protected]>

---
 src/connman.h |  1 +
 src/service.c | 89 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 90 insertions(+)

diff --git a/src/connman.h b/src/connman.h
index 4133df6..74ac3b8 100644
--- a/src/connman.h
+++ b/src/connman.h
@@ -703,6 +703,7 @@ struct connman_session;
 void __connman_service_set_active_session(struct connman_session *session,
                                                bool enable, GSList *list);
 void __connman_service_auto_connect(void);
+void __connman_service_auto_disconnect(void);
 bool __connman_service_remove(struct connman_service *service);
 bool __connman_service_is_provider_pending(struct connman_service *service);
 void __connman_service_set_provider_pending(struct connman_service *service,
diff --git a/src/service.c b/src/service.c
index 5efa0fe..3de0dbb 100644
--- a/src/service.c
+++ b/src/service.c
@@ -46,6 +46,7 @@ static GSList *session_list = NULL;
 static GHashTable *service_hash = NULL;
 static GSList *counter_list = NULL;
 static unsigned int autoconnect_timeout = 0;
+static unsigned int autodisconnect_timeout = 0;
 static unsigned int vpn_autoconnect_timeout = 0;
 static struct connman_service *current_default = NULL;
 static bool services_dirty = false;
@@ -3637,6 +3638,67 @@ static GList *preferred_tech_list_get(void)
        return tech_data.preferred_list;
 }
 
+static bool is_used_by_sessions(struct connman_service *service)
+{
+       GSList *list;
+
+       if (!service->sessions)
+               return false;
+
+       for (list = service->sessions; list; list = list->next) {
+               struct connman_session *session = list->data;
+
+               DBG("session %p requests %d service %p", session,
+                       __connman_session_wants_connection(session),
+                       __connman_session_get_service(session));
+
+               if (!__connman_session_wants_connection(session))
+                       continue;
+
+               if (__connman_session_get_service(session) == service)
+                       return true;
+       }
+
+       return false;
+}
+
+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_setting_get_bool("SessionAutoConnectMode"))
+                       continue;
+
+               if (is_used_by_sessions(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 bool auto_connect_service(GList *services, bool preferred)
 {
        struct connman_service *service = NULL;
@@ -3723,6 +3785,18 @@ static gboolean run_auto_connect(gpointer data)
        if (!autoconnecting || session_list)
                auto_connect_service(service_list, false);
 
+       /* let's try to get rid of something as well */
+       auto_disconnect_service();
+
+       return FALSE;
+}
+
+static gboolean run_auto_disconnect(gpointer data)
+{
+       autodisconnect_timeout = 0;
+
+       auto_disconnect_service();
+
        return FALSE;
 }
 
@@ -3736,6 +3810,16 @@ void __connman_service_auto_connect(void)
        autoconnect_timeout = g_timeout_add_seconds(0, run_auto_connect, NULL);
 }
 
+void __connman_service_auto_disconnect(void)
+{
+       DBG("");
+
+       if (autodisconnect_timeout != 0)
+               return;
+
+       autodisconnect_timeout = g_timeout_add_seconds(0, run_auto_disconnect, 
NULL);
+}
+
 static gboolean run_vpn_auto_connect(gpointer data) {
        GList *list;
 
@@ -7075,6 +7159,11 @@ void __connman_service_cleanup(void)
                vpn_autoconnect_timeout = 0;
        }
 
+       if (autodisconnect_timeout) {
+               g_source_remove(autodisconnect_timeout);
+               autodisconnect_timeout = 0;
+       }
+
        if (autoconnect_timeout != 0) {
                g_source_remove(autoconnect_timeout);
                autoconnect_timeout = 0;
-- 
1.8.4.474.g128a96c

_______________________________________________
connman mailing list
[email protected]
https://lists.connman.net/mailman/listinfo/connman

Reply via email to