Merge "Fix crash caused by decryption response delay" into tizen
[platform/upstream/connman.git] / src / wispr.c
index 330aa1d..f4dcb73 100755 (executable)
@@ -30,9 +30,6 @@
 
 #include "connman.h"
 
-#define STATUS_URL_IPV4  "http://ipv4.connman.net/online/status.html"
-#define STATUS_URL_IPV6  "http://ipv6.connman.net/online/status.html"
-
 struct connman_wispr_message {
        bool has_error;
        const char *current_element;
@@ -96,6 +93,10 @@ static bool wispr_portal_web_result(GWebResult *result, gpointer user_data);
 
 static GHashTable *wispr_portal_list = NULL;
 
+static char *online_check_ipv4_url = NULL;
+static char *online_check_ipv6_url = NULL;
+static bool enable_online_to_ready_transition = false;
+
 static void connman_wispr_message_init(struct connman_wispr_message *msg)
 {
        DBG("");
@@ -422,6 +423,11 @@ static void wispr_portal_error(struct connman_wispr_portal_context *wp_context)
        DBG("Failed to proceed wispr/portal web request");
 
        wp_context->wispr_result = CONNMAN_WISPR_RESULT_FAILED;
+
+#if defined TIZEN_EXT
+       if (TIZEN_INS_ENABLED)
+               connman_service_set_internet_connection(wp_context->service, false);
+#endif
 }
 
 static void portal_manage_status(GWebResult *result,
@@ -450,10 +456,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,
@@ -555,12 +565,31 @@ static void wispr_portal_browser_reply_cb(struct connman_service *service,
                                        const char *error, void *user_data)
 {
        struct connman_wispr_portal_context *wp_context = user_data;
+       struct connman_wispr_portal *wispr_portal;
+       int index;
 
        DBG("");
 
        if (!service || !wp_context)
                return;
 
+       /*
+        * No way to cancel this if wp_context has been freed, so we lookup
+        * from the service and check that this is still the right context.
+        */
+       index = __connman_service_get_index(service);
+       if (index < 0)
+               return;
+
+       wispr_portal = g_hash_table_lookup(wispr_portal_list,
+                                       GINT_TO_POINTER(index));
+       if (!wispr_portal)
+               return;
+
+       if (wp_context != wispr_portal->ipv4_context &&
+               wp_context != wispr_portal->ipv6_context)
+               return;
+
        if (!authentication_done) {
                wispr_portal_error(wp_context);
                free_wispr_routes(wp_context);
@@ -568,7 +597,7 @@ static void wispr_portal_browser_reply_cb(struct connman_service *service,
        }
 
        /* Restarting the test */
-       __connman_wispr_start(service, wp_context->type);
+       __connman_service_wispr_start(service, wp_context->type);
 }
 
 static void wispr_portal_request_wispr_login(struct connman_service *service,
@@ -688,6 +717,9 @@ static bool wispr_portal_web_result(GWebResult *result, gpointer user_data)
        const char *str = NULL;
        guint16 status;
        gsize length;
+#if defined TIZEN_MAINTAIN_ONLINE
+       static int retried = 0;
+#endif
 
        DBG("");
 
@@ -719,6 +751,9 @@ static bool wispr_portal_web_result(GWebResult *result, gpointer user_data)
                                wp_context->status_url, wp_context);
                break;
        case 200:
+#if defined TIZEN_MAINTAIN_ONLINE
+               retried = 0;
+#endif
                if (wp_context->wispr_msg.message_type >= 0)
                        break;
 
@@ -732,7 +767,12 @@ static bool wispr_portal_web_result(GWebResult *result, gpointer user_data)
                                        wp_context->redirect_url, wp_context);
 
                break;
+       case 300:
+       case 301:
        case 302:
+       case 303:
+       case 307:
+       case 308:
                if (!g_web_supports_tls() ||
                        !g_web_result_get_header(result, "Location",
                                                        &redirect)) {
@@ -754,13 +794,21 @@ 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);
+#if defined TIZEN_MAINTAIN_ONLINE
+                       if (wp_context->type == CONNMAN_IPCONFIG_TYPE_IPV4) {
+                               if (retried == 0) {
+                                       connman_agent_report_error(wp_context->service,
+                                               __connman_service_get_path(wp_context->service),
+                                               "internet-unreachable",
+                                               NULL, NULL, NULL);
+
+                                       retried = 1;
+                               }
+                               break;
+                       }
+#endif
                break;
        case 505:
                __connman_agent_request_browser(wp_context->service,
@@ -832,8 +880,8 @@ static int wispr_portal_detect(struct connman_wispr_portal_context *wp_context)
        int err = 0;
        int i;
 
-       DBG("wispr/portal context %p", wp_context);
-       DBG("service %p", wp_context->service);
+       DBG("wispr/portal context %p service %p", wp_context,
+               wp_context->service);
 
        service_type = connman_service_get_type(wp_context->service);
 
@@ -849,6 +897,9 @@ static int wispr_portal_detect(struct connman_wispr_portal_context *wp_context)
        case CONNMAN_SERVICE_TYPE_GPS:
        case CONNMAN_SERVICE_TYPE_VPN:
        case CONNMAN_SERVICE_TYPE_P2P:
+#if defined TIZEN_EXT_WIFI_MESH
+       case CONNMAN_SERVICE_TYPE_MESH:
+#endif
                return -EOPNOTSUPP;
        }
 
@@ -879,15 +930,17 @@ static int wispr_portal_detect(struct connman_wispr_portal_context *wp_context)
                goto done;
        }
 
+#if !defined TIZEN_EXT
        if (getenv("CONNMAN_WEB_DEBUG"))
+#endif
                g_web_set_debug(wp_context->web, web_debug, "WEB");
 
        if (wp_context->type == CONNMAN_IPCONFIG_TYPE_IPV4) {
                g_web_set_address_family(wp_context->web, AF_INET);
-               wp_context->status_url = STATUS_URL_IPV4;
+               wp_context->status_url = online_check_ipv4_url;
        } else {
                g_web_set_address_family(wp_context->web, AF_INET6);
-               wp_context->status_url = STATUS_URL_IPV6;
+               wp_context->status_url = online_check_ipv6_url;
        }
 
        for (i = 0; nameservers[i]; i++)
@@ -906,8 +959,7 @@ static int wispr_portal_detect(struct connman_wispr_portal_context *wp_context)
                        free_connman_wispr_portal_context(wp_context);
                }
        } else if (wp_context->timeout == 0) {
-               wp_context->timeout =
-                       g_timeout_add_seconds(0, no_proxy_callback, wp_context);
+               wp_context->timeout = g_idle_add(no_proxy_callback, wp_context);
        }
 
 done:
@@ -978,6 +1030,7 @@ int __connman_wispr_start(struct connman_service *service,
 
 void __connman_wispr_stop(struct connman_service *service)
 {
+       struct connman_wispr_portal *wispr_portal;
        int index;
 
        DBG("service %p", service);
@@ -989,7 +1042,16 @@ void __connman_wispr_stop(struct connman_service *service)
        if (index < 0)
                return;
 
-       g_hash_table_remove(wispr_portal_list, GINT_TO_POINTER(index));
+       wispr_portal = g_hash_table_lookup(wispr_portal_list,
+                                       GINT_TO_POINTER(index));
+       if (!wispr_portal)
+               return;
+
+       if ((wispr_portal->ipv4_context &&
+            service == wispr_portal->ipv4_context->service) ||
+           (wispr_portal->ipv6_context &&
+            service == wispr_portal->ipv6_context->service))
+               g_hash_table_remove(wispr_portal_list, GINT_TO_POINTER(index));
 }
 
 int __connman_wispr_init(void)
@@ -1000,6 +1062,14 @@ int __connman_wispr_init(void)
                                                g_direct_equal, NULL,
                                                free_connman_wispr_portal);
 
+       online_check_ipv4_url =
+               connman_setting_get_string("OnlineCheckIPv4URL");
+       online_check_ipv6_url =
+               connman_setting_get_string("OnlineCheckIPv6URL");
+
+       enable_online_to_ready_transition =
+               connman_setting_get_bool("EnableOnlineToReadyTransition");
+
        return 0;
 }