ipconfig: Add function to clear ipaddress information
[platform/upstream/connman.git] / src / wispr.c
index 4fe9e75..6807297 100644 (file)
@@ -61,6 +61,7 @@ struct wispr_route {
 struct connman_wispr_portal_context {
        struct connman_service *service;
        enum connman_ipconfig_type type;
+       struct connman_wispr_portal *wispr_portal;
 
        /* Portal/WISPr common */
        GWeb *web;
@@ -82,6 +83,8 @@ struct connman_wispr_portal_context {
        enum connman_wispr_result wispr_result;
 
        GSList *route_list;
+
+       guint timeout;
 };
 
 struct connman_wispr_portal {
@@ -159,7 +162,13 @@ static void free_connman_wispr_portal_context(struct connman_wispr_portal_contex
        if (wp_context == NULL)
                return;
 
-       connman_service_unref(wp_context->service);
+       if (wp_context->wispr_portal != NULL) {
+               if (wp_context->wispr_portal->ipv4_context == wp_context)
+                       wp_context->wispr_portal->ipv4_context = NULL;
+
+               if (wp_context->wispr_portal->ipv6_context == wp_context)
+                       wp_context->wispr_portal->ipv6_context = NULL;
+       }
 
        if (wp_context->token > 0)
                connman_proxy_lookup_cancel(wp_context->token);
@@ -167,11 +176,17 @@ static void free_connman_wispr_portal_context(struct connman_wispr_portal_contex
        if (wp_context->request_id > 0)
                g_web_cancel_request(wp_context->web, wp_context->request_id);
 
-       g_web_unref(wp_context->web);
+       if (wp_context->timeout > 0)
+               g_source_remove(wp_context->timeout);
+
+       if (wp_context->web != NULL)
+               g_web_unref(wp_context->web);
 
        g_free(wp_context->redirect_url);
 
-       g_web_parser_unref(wp_context->wispr_parser);
+       if (wp_context->wispr_parser != NULL)
+               g_web_parser_unref(wp_context->wispr_parser);
+
        connman_wispr_message_init(&wp_context->wispr_msg);
 
        g_free(wp_context->wispr_username);
@@ -183,6 +198,11 @@ static void free_connman_wispr_portal_context(struct connman_wispr_portal_contex
        g_free(wp_context);
 }
 
+static struct connman_wispr_portal_context *create_wispr_portal_context(void)
+{
+       return g_try_new0(struct connman_wispr_portal_context, 1);
+}
+
 static void free_connman_wispr_portal(gpointer data)
 {
        struct connman_wispr_portal *wispr_portal = data;
@@ -386,7 +406,7 @@ static void xml_wispr_parser_callback(const char *str, gpointer user_data)
        result = g_markup_parse_context_parse(parser_context,
                                        str, strlen(str), NULL);
        if (result == TRUE)
-               result = g_markup_parse_context_end_parse(parser_context, NULL);
+               g_markup_parse_context_end_parse(parser_context, NULL);
 
        g_markup_parse_context_free(parser_context);
 }
@@ -406,6 +426,8 @@ static void wispr_portal_error(struct connman_wispr_portal_context *wp_context)
 static void portal_manage_status(GWebResult *result,
                        struct connman_wispr_portal_context *wp_context)
 {
+       struct connman_service *service = wp_context->service;
+       enum connman_ipconfig_type type = wp_context->type;
        const char *str = NULL;
 
        DBG("");
@@ -423,9 +445,10 @@ static void portal_manage_status(GWebResult *result,
                                &str) == TRUE)
                connman_info("Client-Region: %s", str);
 
-       __connman_service_ipconfig_indicate_state(wp_context->service,
-                                               CONNMAN_SERVICE_STATE_ONLINE,
-                                               wp_context->type);
+       free_connman_wispr_portal_context(wp_context);
+
+       __connman_service_ipconfig_indicate_state(service,
+                                       CONNMAN_SERVICE_STATE_ONLINE, type);
 }
 
 static gboolean wispr_route_request(const char *address, int ai_family,
@@ -552,11 +575,17 @@ static void wispr_portal_request_wispr_login(struct connman_service *service,
 
        DBG("");
 
-       if (error != NULL && g_strcmp0(error,
+       if (error != NULL) {
+               if (g_strcmp0(error,
                        "net.connman.Agent.Error.LaunchBrowser") == 0) {
-               __connman_agent_request_browser(service,
-                               wispr_portal_browser_reply_cb,
-                               wp_context->redirect_url, wp_context);
+                       if (__connman_agent_request_browser(service,
+                                       wispr_portal_browser_reply_cb,
+                                       wp_context->redirect_url,
+                                       wp_context) == -EINPROGRESS)
+                               return;
+               }
+
+               free_connman_wispr_portal_context(wp_context);
                return;
        }
 
@@ -610,7 +639,7 @@ static gboolean wispr_manage_message(GWebResult *result,
 
                if (__connman_agent_request_login_input(wp_context->service,
                                        wispr_portal_request_wispr_login,
-                                       wp_context) != -EIO)
+                                       wp_context) != -EINPROGRESS)
                        wispr_portal_error(wp_context);
 
                break;
@@ -653,9 +682,6 @@ static gboolean wispr_portal_web_result(GWebResult *result, gpointer user_data)
 
        DBG("");
 
-       if (wp_context->request_id == 0)
-               return FALSE;
-
        if (wp_context->wispr_result != CONNMAN_WISPR_RESULT_ONLINE) {
                g_web_result_get_chunk(result, &chunk, &length);
 
@@ -683,8 +709,10 @@ static gboolean wispr_portal_web_result(GWebResult *result, gpointer user_data)
                        break;
 
                if (g_web_result_get_header(result, "X-ConnMan-Status",
-                                                               &str) == TRUE)
+                                               &str) == TRUE) {
                        portal_manage_status(result, wp_context);
+                       return FALSE;
+               }
                else
                        __connman_agent_request_browser(wp_context->service,
                                        wispr_portal_browser_reply_cb,
@@ -692,8 +720,10 @@ static gboolean wispr_portal_web_result(GWebResult *result, gpointer user_data)
 
                break;
        case 302:
-               if (g_web_result_get_header(result, "Location",
-                                               &redirect) == FALSE) {
+               if (g_web_supports_tls() == FALSE ||
+                               g_web_result_get_header(result, "Location",
+                                                       &redirect) == FALSE) {
+
                        __connman_agent_request_browser(wp_context->service,
                                        wispr_portal_browser_reply_cb,
                                        wp_context->status_url, wp_context);
@@ -712,8 +742,11 @@ static gboolean wispr_portal_web_result(GWebResult *result, gpointer user_data)
        case 400:
        case 404:
                if (__connman_service_online_check_failed(wp_context->service,
-                                                       wp_context->type) == 0)
+                                               wp_context->type) == 0) {
                        wispr_portal_error(wp_context);
+                       free_connman_wispr_portal_context(wp_context);
+                       return FALSE;
+               }
 
                break;
        default:
@@ -733,6 +766,9 @@ static void proxy_callback(const char *proxy, void *user_data)
 
        DBG("proxy %s", proxy);
 
+       if (wp_context == NULL)
+               return;
+
        wp_context->token = 0;
 
        if (proxy != NULL && g_strcmp0(proxy, "DIRECT") != 0)
@@ -756,6 +792,8 @@ static gboolean no_proxy_callback(gpointer user_data)
 {
        struct connman_wispr_portal_context *wp_context = user_data;
 
+       wp_context->timeout = 0;
+
        proxy_callback("DIRECT", wp_context);
 
        return FALSE;
@@ -840,10 +878,13 @@ static int wispr_portal_detect(struct connman_wispr_portal_context *wp_context)
                                                wp_context->service,
                                                proxy_callback, wp_context);
 
-               if (wp_context->token == 0)
+               if (wp_context->token == 0) {
                        err = -EINVAL;
-       } else {
-               g_timeout_add_seconds(0, no_proxy_callback, 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);
        }
 
 done:
@@ -891,14 +932,13 @@ int __connman_wispr_start(struct connman_service *service,
        if (wp_context != NULL)
                free_connman_wispr_portal_context(wp_context);
 
-       wp_context = g_try_new0(struct connman_wispr_portal_context, 1);
+       wp_context = create_wispr_portal_context();
        if (wp_context == NULL)
                return -ENOMEM;
 
-       connman_service_ref(service);
-
        wp_context->service = service;
        wp_context->type = type;
+       wp_context->wispr_portal = wispr_portal;
 
        if (type == CONNMAN_IPCONFIG_TYPE_IPV4)
                wispr_portal->ipv4_context = wp_context;