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