[PATCH] service: Add online to ready transition feature
by VAUTRIN Emmanuel (Canal Plus Prestataire)
WARNING: Experimental feature!!!
Global config option, which allows keeping calling the online check
request to guarantee that end-to-end connectivity is still successful.
If not, the default service transitions to READY state, enabling another
service to become the default one, in replacement.
---
doc/connman.conf.5.in | 13 +++++++++++++
src/connman.h | 5 +++--
src/main.c | 15 +++++++++++++++
src/main.conf | 12 ++++++++++++
src/service.c | 27 +++++++++++++++++++++++----
src/wispr.c | 19 ++++++++++++-------
6 files changed, 78 insertions(+), 13 deletions(-)
diff --git a/doc/connman.conf.5.in b/doc/connman.conf.5.in
index 19e6e0c0950d..2e06b3ef1f3c 100644
--- a/doc/connman.conf.5.in
+++ b/doc/connman.conf.5.in
@@ -175,6 +175,19 @@ between OnlineCheckInitialInterval and OnlineCheckMaxInterval.
Default range is [1, 12], corresponding to the following intervals, in
seconds: 1, 4, 9, 16, 25, 36, 49, 64, 81, 100, 121 and 144.
.TP
+.BI EnableOnlineToReadyTransition=true\ \fR|\fB\ false
+WARNING: Experimental feature!!!
+In addition to EnableOnlineCheck setting, enable or disable use of HTTP GET
+to detect the loss of end-to-end connectivity.
+If this setting is false, when the default service transitions to ONLINE
+state, the HTTP GET request is no more called until next cycle, initiated
+by a transition of the default service to DISCONNECT state.
+If this setting is true, the HTTP GET request keeps beeing called to guarantee
+that end-to-end connectivity is still successful. If not, the default service
+will transition to READY state, enabling another service to become the
+default one, in replacement.
+Default value is false.
+.TP
.BI AutoConnectRoamingServices=true\ \fR|\fB\ false
Automatically connect roaming services. This is not recommended unless you know
you won't have any billing problem.
diff --git a/src/connman.h b/src/connman.h
index a43a6b8bcd7a..59a78d9a666b 100644
--- a/src/connman.h
+++ b/src/connman.h
@@ -729,8 +729,9 @@ int __connman_service_set_mdns(struct connman_service *service,
void __connman_service_set_string(struct connman_service *service,
const char *key, const char *value);
-int __connman_service_online_check_failed(struct connman_service *service,
- enum connman_ipconfig_type type);
+void __connman_service_online_check(struct connman_service *service,
+ enum connman_ipconfig_type type,
+ bool success);
int __connman_service_ipconfig_indicate_state(struct connman_service *service,
enum connman_service_state new_state,
enum connman_ipconfig_type type);
diff --git a/src/main.c b/src/main.c
index 6835241525e2..8bd44ba18027 100644
--- a/src/main.c
+++ b/src/main.c
@@ -96,6 +96,7 @@ static struct {
bool enable_6to4;
char *vendor_class_id;
bool enable_online_check;
+ bool enable_online_to_ready_transition;
unsigned int online_check_initial_interval;
unsigned int online_check_max_interval;
bool auto_connect_roaming_services;
@@ -120,6 +121,7 @@ static struct {
.enable_6to4 = false,
.vendor_class_id = NULL,
.enable_online_check = true,
+ .enable_online_to_ready_transition = false,
.online_check_initial_interval = DEFAULT_ONLINE_CHECK_INITIAL_INTERVAL,
.online_check_max_interval = DEFAULT_ONLINE_CHECK_MAX_INTERVAL,
.auto_connect_roaming_services = false,
@@ -145,6 +147,7 @@ static struct {
#define CONF_ENABLE_6TO4 "Enable6to4"
#define CONF_VENDOR_CLASS_ID "VendorClassID"
#define CONF_ENABLE_ONLINE_CHECK "EnableOnlineCheck"
+#define CONF_ENABLE_ONLINE_TO_READY_TRANSITION "EnableOnlineToReadyTransition"
#define CONF_ONLINE_CHECK_INITIAL_INTERVAL "OnlineCheckInitialInterval"
#define CONF_ONLINE_CHECK_MAX_INTERVAL "OnlineCheckMaxInterval"
#define CONF_AUTO_CONNECT_ROAMING_SERVICES "AutoConnectRoamingServices"
@@ -170,6 +173,7 @@ static const char *supported_options[] = {
CONF_ENABLE_6TO4,
CONF_VENDOR_CLASS_ID,
CONF_ENABLE_ONLINE_CHECK,
+ CONF_ENABLE_ONLINE_TO_READY_TRANSITION,
CONF_ONLINE_CHECK_INITIAL_INTERVAL,
CONF_ONLINE_CHECK_MAX_INTERVAL,
CONF_AUTO_CONNECT_ROAMING_SERVICES,
@@ -474,6 +478,14 @@ static void parse_config(GKeyFile *config)
g_clear_error(&error);
+ boolean = __connman_config_get_bool(config, "General",
+ CONF_ENABLE_ONLINE_TO_READY_TRANSITION, &error);
+ if (!error) {
+ connman_settings.enable_online_to_ready_transition = boolean;
+ }
+
+ g_clear_error(&error);
+
integer = g_key_file_get_integer(config, "General",
CONF_ONLINE_CHECK_INITIAL_INTERVAL, &error);
if (!error && integer >= 0)
@@ -729,6 +741,9 @@ bool connman_setting_get_bool(const char *key)
if (g_str_equal(key, CONF_ENABLE_ONLINE_CHECK))
return connman_settings.enable_online_check;
+ if (g_str_equal(key, CONF_ENABLE_ONLINE_TO_READY_TRANSITION))
+ return connman_settings.enable_online_to_ready_transition;
+
if (g_str_equal(key, CONF_AUTO_CONNECT_ROAMING_SERVICES))
return connman_settings.auto_connect_roaming_services;
diff --git a/src/main.conf b/src/main.conf
index 83cd20f6159d..7065a3203d3a 100644
--- a/src/main.conf
+++ b/src/main.conf
@@ -134,6 +134,18 @@
# OnlineCheckInitialInterval = 1
# OnlineCheckMaxInterval = 12
+# WARNING: Experimental feature!!!
+# In addition to EnableOnlineCheck setting, enable or disable use of HTTP GET
+# to detect the loss of end-to-end connectivity.
+# If this setting is false, when the default service transitions to ONLINE
+# state, the HTTP GET request is no more called until next cycle, initiated
+# by a transition of the default service to DISCONNECT state.
+# If this setting is true, the HTTP GET request keeps beeing called to guarantee
+# that end-to-end connectivity is still successful. If not, the default service
+# will transition to READY state, enabling another service to become the
+# default one, in replacement.
+# EnableOnlineToReadyTransition = false
+
# List of technologies with AutoConnect = true which are always connected
# regardless of PreferredTechnologies setting. Default value is empty and
# will connect a technology only if it is at a higher preference than any
diff --git a/src/service.c b/src/service.c
index 99a52022b80b..c330700d61c8 100644
--- a/src/service.c
+++ b/src/service.c
@@ -54,6 +54,7 @@ static unsigned int autoconnect_id = 0;
static unsigned int vpn_autoconnect_id = 0;
static struct connman_service *current_default = NULL;
static bool services_dirty = false;
+static bool enable_online_to_ready_transition = false;
static unsigned int online_check_initial_interval = 0;
static unsigned int online_check_max_interval = 0;
@@ -1450,6 +1451,8 @@ static void start_online_check(struct connman_service *service,
"Default service remains in READY state.");
return;
}
+ enable_online_to_ready_transition =
+ connman_setting_get_bool("EnableOnlineToReadyTransition");
online_check_initial_interval =
connman_setting_get_uint("OnlineCheckInitialInterval");
online_check_max_interval =
@@ -6256,11 +6259,13 @@ static gboolean redo_wispr_ipv6(gpointer user_data)
return FALSE;
}
-int __connman_service_online_check_failed(struct connman_service *service,
- enum connman_ipconfig_type type)
+void __connman_service_online_check(struct connman_service *service,
+ enum connman_ipconfig_type type,
+ bool success)
{
GSourceFunc redo_func;
int *interval;
+ enum connman_service_state current_state;
if (type == CONNMAN_IPCONFIG_TYPE_IPV4) {
interval = &service->online_check_interval_ipv4;
@@ -6270,6 +6275,22 @@ int __connman_service_online_check_failed(struct connman_service *service,
redo_func = redo_wispr_ipv6;
}
+ if(!enable_online_to_ready_transition)
+ goto redo_func;
+
+ if (success) {
+ *interval = online_check_max_interval;
+ } else {
+ current_state = service->state;
+ downgrade_state(service);
+ if (current_state != service->state)
+ *interval = online_check_initial_interval;
+ if (service != connman_service_get_default()) {
+ return;
+ }
+ }
+
+redo_func:
DBG("service %p type %s interval %d", service,
__connman_ipconfig_type2string(type), *interval);
@@ -6281,8 +6302,6 @@ int __connman_service_online_check_failed(struct connman_service *service,
*/
if (*interval < online_check_max_interval)
(*interval)++;
-
- return EAGAIN;
}
int __connman_service_ipconfig_indicate_state(struct connman_service *service,
diff --git a/src/wispr.c b/src/wispr.c
index b107f9291ac4..27f5dc13f4a2 100644
--- a/src/wispr.c
+++ b/src/wispr.c
@@ -96,6 +96,8 @@ static bool wispr_portal_web_result(GWebResult *result, gpointer user_data);
static GHashTable *wispr_portal_list = NULL;
+static bool enable_online_to_ready_transition = false;
+
static void connman_wispr_message_init(struct connman_wispr_message *msg)
{
DBG("");
@@ -450,10 +452,14 @@ static void portal_manage_status(GWebResult *result,
&str))
connman_info("Client-Timezone: %s", str);
- free_connman_wispr_portal_context(wp_context);
+ if (!enable_online_to_ready_transition)
+ free_connman_wispr_portal_context(wp_context);
__connman_service_ipconfig_indicate_state(service,
CONNMAN_SERVICE_STATE_ONLINE, type);
+
+ if (enable_online_to_ready_transition)
+ __connman_service_online_check(service, type, true);
}
static bool wispr_route_request(const char *address, int ai_family,
@@ -773,12 +779,8 @@ static bool wispr_portal_web_result(GWebResult *result, gpointer user_data)
goto done;
case 400:
case 404:
- if (__connman_service_online_check_failed(wp_context->service,
- wp_context->type) == 0) {
- wispr_portal_error(wp_context);
- free_connman_wispr_portal_context(wp_context);
- return false;
- }
+ __connman_service_online_check(wp_context->service,
+ wp_context->type, false);
break;
case 505:
@@ -1029,6 +1031,9 @@ int __connman_wispr_init(void)
g_direct_equal, NULL,
free_connman_wispr_portal);
+ enable_online_to_ready_transition =
+ connman_setting_get_bool("EnableOnlineToReadyTransition");
+
return 0;
}
--
2.25.1