Add support for unspecified IPv6 gateway address
[platform/core/connectivity/net-config.git] / src / wifi-agent.c
old mode 100644 (file)
new mode 100755 (executable)
index ba7d331..f130d95
@@ -1,7 +1,7 @@
 /*
  * Network Configuration Module
  *
- * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  */
 
 #include <stdio.h>
+#include <vconf.h>
+#include <stdlib.h>
 #include <unistd.h>
+#include <vconf-keys.h>
 
-#include "wifi-agent.h"
 #include "log.h"
+#include "util.h"
 #include "wifi.h"
 #include "netdbus.h"
-
+#include "wifi-agent.h"
+#include "wifi-state.h"
+#include "wifi-eap-config.h"
+#include "network-state.h"
+#include "network-accessibility.h"
+#include "wifi-key-encryption.h"
+
+#define NETCONFIG_AGENT_FIELD_NAME                             "Name"
+#define NETCONFIG_AGENT_FIELD_SSID                             "SSID"
+#define NETCONFIG_AGENT_FIELD_IDENTITY                 "Identity"
 #define NETCONFIG_AGENT_FIELD_PASSPHRASE               "Passphrase"
 #define NETCONFIG_AGENT_FIELD_WPS                              "WPS"
 #define NETCONFIG_AGENT_FIELD_WPS_PBC                  "WPS_PBC"
 #define NETCONFIG_AGENT_FIELD_WPS_PIN                  "WPS_PIN"
-
-struct netconfig_wifi_agent {
+#if defined TIZEN_CAPTIVE_PORTAL
+#define NETCONFIG_AGENT_FIELD_USERNAME                 "Username"
+#define NETCONFIG_AGENT_FIELD_PASSWORD                 "Password"
+#endif
+
+#define NETCONFIG_AGENT_ERR_CONNECT_FAILED             "connect-failed"
+
+typedef struct {
+       char *interface_name;
+       GByteArray *ssid;
+       char *name;
+       char *identity;
        char *passphrase;
        char *wps_pin;
+#if defined TIZEN_CAPTIVE_PORTAL
+       char *username;
+       char *password;
+#endif
        gboolean wps_pbc;
-};
+} netconfig_wifi_agent_s;
 
-static struct netconfig_wifi_agent agent;
+static GSList *g_agent_list = NULL;
 
-static void __netconfig_agent_clear_fields(void)
+static void __agent_clear_fields(netconfig_wifi_agent_s *agent)
 {
-       DBG("__netconfig_agent_clear_fields");
+       if (!agent)
+               return;
+
+       g_free(agent->interface_name);
+       if (agent->ssid)
+               g_byte_array_free(agent->ssid, TRUE);
+       g_free(agent->name);
+       g_free(agent->identity);
+       g_free(agent->passphrase);
+       g_free(agent->wps_pin);
+#if defined TIZEN_CAPTIVE_PORTAL
+       g_free(agent->username);
+       g_free(agent->password);
+#endif
+
+       agent->interface_name = NULL;
+       agent->ssid = NULL;
+       agent->name = NULL;
+       agent->identity = NULL;
+       agent->passphrase = NULL;
+       agent->wps_pin = NULL;
+#if defined TIZEN_CAPTIVE_PORTAL
+       agent->username = NULL;
+       agent->password = NULL;
+#endif
+       agent->wps_pbc = FALSE;
+}
 
-       g_free(agent.passphrase);
-       g_free(agent.wps_pin);
+static void __agent_free_data(gpointer data)
+{
+       netconfig_wifi_agent_s *agent = data;
 
-       agent.passphrase = NULL;
-       agent.wps_pin = NULL;
-       agent.wps_pbc = FALSE;
+       __agent_clear_fields(agent);
+       g_free(agent);
 }
 
-gboolean netconfig_agent_register(void)
+static netconfig_wifi_agent_s *__agent_get_data(const char *interface_name)
 {
-       DBG("netconfig_agent_register");
+       GSList *list = NULL;
 
-       DBusMessage *reply = NULL;
-       char param1[64] = "";
-       char *param_array[] = {NULL, NULL};
+       for (list = g_agent_list; list; list = list->next) {
+               netconfig_wifi_agent_s *wifi_agent = list->data;
+               if (g_strcmp0(wifi_agent->interface_name, interface_name) == 0)
+                       return wifi_agent;
+       }
 
-       snprintf(param1, 64, "objpath:%s", NETCONFIG_WIFI_PATH);
-       param_array[0] = param1;
+       return NULL;
+}
+
+int connman_register_agent(void)
+{
+       GVariant *reply = NULL;
+       GVariant *params = NULL;
 
+       params = g_variant_new("(o)", NETCONFIG_WIFI_PATH);
        reply = netconfig_invoke_dbus_method(CONNMAN_SERVICE,
                        CONNMAN_MANAGER_PATH, CONNMAN_MANAGER_INTERFACE,
-                       "RegisterAgent", param_array);
+                       "RegisterAgent", params);
 
        if (reply == NULL) {
-               ERR("Error! Request failed");
-               return FALSE;
-       }
+                       ERR("Fail to register agent");
+                       return FALSE;
+       } else
+               g_variant_unref(reply);
 
-       dbus_message_unref(reply);
+       INFO("Registered to connman agent successfully");
 
        return TRUE;
 }
 
-gboolean netconfig_agent_unregister(void)
+int connman_unregister_agent(void)
 {
-       DBG("netconfig_agent_unregister");
+       gboolean reply = FALSE;
+       GVariant *param = NULL;
+       const char *path = NETCONFIG_WIFI_PATH;
 
-       DBusMessage *reply = NULL;
-       char param1[64] = "";
-       char *param_array[] = {NULL, NULL};
+       param = g_variant_new("(o)", path);
 
-       snprintf(param1, 64, "objpath:%s", NETCONFIG_WIFI_PATH);
-       param_array[0] = param1;
+       DBG("ConnMan agent unregister");
 
-       reply = netconfig_invoke_dbus_method(CONNMAN_SERVICE,
+       reply = netconfig_invoke_dbus_method_nonblock(CONNMAN_SERVICE,
                        CONNMAN_MANAGER_PATH, CONNMAN_MANAGER_INTERFACE,
-                       "UnregisterAgent", param_array);
+                       "UnregisterAgent", param, NULL, NULL);
 
-       if (reply == NULL) {
-               ERR("Error! Request failed");
+       if (reply != TRUE)
+               ERR("Fail to unregister agent");
+
+       /* Clearing the agent fields */
+       g_slist_free_full(g_agent_list, __agent_free_data);
+
+       return reply;
+}
+
+gboolean netconfig_wifi_set_agent_field_for_eap_network(const char *interface_name,
+                       const char *name, const char *identity, const char *passphrase)
+{
+       int name_len;
+       netconfig_wifi_agent_s *wifi_agent = NULL;
+
+       if (name == NULL)
+               return FALSE;
+
+       wifi_agent = __agent_get_data(interface_name);
+       if (wifi_agent == NULL)
                return FALSE;
-       }
 
-       dbus_message_unref(reply);
+       __agent_clear_fields(wifi_agent);
 
-       /* Clearing the agent fields */
-       __netconfig_agent_clear_fields();
+       name_len = strlen(name);
+       wifi_agent->ssid = g_byte_array_sized_new(name_len);
+       wifi_agent->ssid->len = name_len;
+       memcpy(wifi_agent->ssid->data, name, name_len + 1);
+
+       if (identity)
+               wifi_agent->identity = g_strdup(identity);
+
+       if (passphrase)
+               wifi_agent->passphrase = g_strdup(passphrase);
+
+       gchar *enc_data = NULL;
+       enc_data = _netconfig_encrypt_passphrase(wifi_agent->passphrase);
+
+       if (!enc_data) {
+               ERR("Failed to encrypt the passphrase");
+       } else {
+               g_free(wifi_agent->passphrase);
+               wifi_agent->passphrase = enc_data;
+       }
+
+       DBG("Successfully configured for EAP network");
 
        return TRUE;
 }
 
-gboolean netconfig_iface_wifi_set_field(NetconfigWifi *wifi,
-               GHashTable *fields, GError **error)
+gboolean handle_set_field(NetConnmanAgent *connman_agent,
+               GDBusMethodInvocation *context, const gchar *service, GVariant *fields)
 {
-       GHashTableIter iter;
-       gpointer field, value;
+       GError *error = NULL;
+       GVariantIter *iter;
+       gpointer field;
+       GVariant *value;
+       gboolean updated = FALSE;
+       gboolean reply = FALSE;
+       const char *interface_name = NULL;
+       netconfig_wifi_agent_s *wifi_agent = NULL;
+
+       g_return_val_if_fail(connman_agent != NULL, TRUE);
+
+       DBG("Set agent fields for %s", service);
+
+       if (netconfig_is_wifi_profile(service) != TRUE) {
+               error = g_error_new(G_DBUS_ERROR,
+                               G_DBUS_ERROR_AUTH_FAILED,
+                               CONNMAN_ERROR_INTERFACE ".InvalidService");
+
+               g_dbus_method_invocation_return_gerror(context, error);
+               g_clear_error(&error);
+
+               return TRUE;
+       }
+
+       interface_name = netconfig_get_ifname(service);
+       if (interface_name == NULL) {
+               error = g_error_new(G_DBUS_ERROR,
+                               G_DBUS_ERROR_AUTH_FAILED,
+                               CONNMAN_ERROR_INTERFACE ".InvalidService");
+
+               g_dbus_method_invocation_return_gerror(context, error);
+               g_clear_error(&error);
+
+               return TRUE;
+       }
 
-       DBG("Set agent fields");
+       wifi_agent = __agent_get_data(interface_name);
+       if (wifi_agent == NULL) {
+               wifi_agent = g_try_malloc0(sizeof(netconfig_wifi_agent_s));
+               if (wifi_agent == NULL) {
+                       error = g_error_new(G_DBUS_ERROR,
+                                       G_DBUS_ERROR_AUTH_FAILED,
+                                       CONNMAN_ERROR_INTERFACE ".OutOfMemory");
 
-       g_return_val_if_fail(wifi != NULL, FALSE);
+                       g_dbus_method_invocation_return_gerror(context, error);
+                       g_clear_error(&error);
 
-       __netconfig_agent_clear_fields();
+                       return TRUE;
+               }
+
+               g_agent_list = g_slist_append(g_agent_list, wifi_agent);
+       }
 
-       g_hash_table_iter_init(&iter, fields);
+       __agent_clear_fields(wifi_agent);
+       wifi_agent->interface_name = g_strdup(interface_name);
 
-       while (g_hash_table_iter_next(&iter, &field, &value)) {
-               DBG("Field - [%s]", field);
+       g_variant_get(fields, "a{sv}", &iter);
+       while (g_variant_iter_loop(iter, "{sv}", &field, &value)) {
                if (g_strcmp0(field, NETCONFIG_AGENT_FIELD_PASSPHRASE) == 0) {
-                       g_free(agent.passphrase);
-                       agent.passphrase = g_strdup(value);
+                       if (g_variant_is_of_type(value, G_VARIANT_TYPE_STRING)) {
+                               wifi_agent->passphrase = g_strdup(g_variant_get_string(value, NULL));
+                               updated = TRUE;
+
+                               DBG("Field [%s] - []", (gchar *)field);
+
+                               if (wifi_agent->passphrase == NULL)
+                                       continue;
+
+                               if (netconfig_check_passphrase(service, wifi_agent->passphrase) == FALSE) {
+                                       ERR("Invalid passphrase");
 
-                       DBG("Field [%s] - []", field);
+                                       g_free(wifi_agent->passphrase);
+                                       wifi_agent->passphrase = NULL;
+
+                                       updated = FALSE;
+                                       continue;
+                               }
+
+                               gchar *enc_data = NULL;
+                               enc_data = _netconfig_encrypt_passphrase(wifi_agent->passphrase);
+
+                               if (!enc_data) {
+                                       ERR("Failed to encrypt the passphrase");
+                                       continue;
+                               }
+
+                               g_free(wifi_agent->passphrase);
+                               wifi_agent->passphrase = enc_data;
+                       }
                } else if (g_strcmp0(field, NETCONFIG_AGENT_FIELD_WPS_PBC) == 0) {
-                       agent.wps_pbc = FALSE;
-                       if (g_strcmp0(value, "enable") == 0)
-                               agent.wps_pbc = TRUE;
+                       if (g_variant_is_of_type(value, G_VARIANT_TYPE_STRING) &&
+                                       g_strcmp0(g_variant_get_string(value, NULL), "enable") == 0) {
+                               wifi_agent->wps_pbc = TRUE;
+                               updated = TRUE;
 
-                       DBG("Field [%s] - [%d]", field, agent.wps_pbc);
+                               DBG("Field [%s] - [%d]", (gchar *)field, wifi_agent->wps_pbc);
+                       }
                } else if (g_strcmp0(field, NETCONFIG_AGENT_FIELD_WPS_PIN) == 0) {
-                       g_free(agent.wps_pin);
-                       agent.wps_pbc = FALSE;
-                       agent.wps_pin = g_strdup(value);
+                       if (g_variant_is_of_type(value, G_VARIANT_TYPE_STRING)) {
+                               wifi_agent->wps_pin = g_strdup(g_variant_get_string(value, NULL));
+                               updated = TRUE;
+
+                               DBG("Field [%s] - [%s]", (gchar *)field, wifi_agent->wps_pin);
+                       }
+               } else if (g_strcmp0(field, NETCONFIG_AGENT_FIELD_NAME) == 0) {
+                       if (g_variant_is_of_type(value, G_VARIANT_TYPE_STRING)) {
+                               wifi_agent->name = g_strdup(g_variant_get_string(value, NULL));
+                               updated = TRUE;
+
+                               DBG("Field [%s] - [%s]", (gchar *)field, wifi_agent->name);
+                       }
+               } else if (g_strcmp0(field, NETCONFIG_AGENT_FIELD_SSID) == 0) {
+                       if (wifi_agent->ssid != NULL) {
+                               g_byte_array_free(wifi_agent->ssid, TRUE);
+                               wifi_agent->ssid = NULL;
+                       }
+
+                       if (g_variant_is_of_type(value, G_VARIANT_TYPE_BYTESTRING)) {
+                               guint8 char_value;
+                               GVariantIter *iter1;
+                               GByteArray *array = g_byte_array_new();
+
+                               g_variant_get(value, "ay", &iter1);
+                               while (g_variant_iter_loop(iter1, "y", &char_value))
+                                       g_byte_array_append(array, &char_value, 1);
+                               g_variant_iter_free(iter1);
+                               if (array != NULL && (array->len > 0)) {
+                                       wifi_agent->ssid = g_byte_array_sized_new(array->len);
+                                       wifi_agent->ssid->len = array->len;
+                                       memcpy(wifi_agent->ssid->data, array->data, array->len);
+                                       updated = TRUE;
+
+                                       DBG("Field [%s] - []", (gchar *)field);
+                               }
+                       }
+               } else if (g_strcmp0(field, NETCONFIG_AGENT_FIELD_IDENTITY) == 0) {
+                       if (g_variant_is_of_type(value, G_VARIANT_TYPE_STRING)) {
+                               wifi_agent->identity = g_strdup(g_variant_get_string(value, NULL));
+                               updated = TRUE;
+
+                               DBG("Field [%s] - [%s]", (gchar *)field, wifi_agent->identity);
+                       }
+#if defined TIZEN_CAPTIVE_PORTAL
+               } else if (g_strcmp0(field, NETCONFIG_AGENT_FIELD_USERNAME) == 0) {
+                       if (g_variant_is_of_type(value, G_VARIANT_TYPE_STRING)) {
+                               wifi_agent->username = g_strdup(g_variant_get_string(value, NULL));
+                               updated = TRUE;
 
-                       DBG("Field [%s] - []", field);
+                               DBG("Field [%s] - [%s]", (gchar *)field, wifi_agent->username);
+                       }
+               } else if (g_strcmp0(field, NETCONFIG_AGENT_FIELD_PASSWORD) == 0) {
+                       if (g_variant_is_of_type(value, G_VARIANT_TYPE_STRING)) {
+                               wifi_agent->password = g_strdup(g_variant_get_string(value, NULL));
+                               updated = TRUE;
+
+                               DBG("Field [%s] - [%s]", (gchar *)field, wifi_agent->password);
+                       }
+#endif
                }
        }
 
+       g_variant_iter_free(iter);
+
+       if (updated == TRUE) {
+               reply = netconfig_invoke_dbus_method_nonblock(CONNMAN_SERVICE,
+                               service, CONNMAN_SERVICE_INTERFACE, "Connect",
+                               NULL, __netconfig_wifi_connect_reply,
+                               g_strdup(interface_name));
+               if (reply != TRUE) {
+                       ERR("Fail to connect Wi-Fi");
+                       __agent_clear_fields(wifi_agent);
+                       error = g_error_new(G_DBUS_ERROR,
+                                       G_DBUS_ERROR_AUTH_FAILED,
+                                       CONNMAN_ERROR_INTERFACE ".InvalidArguments");
+
+                       g_dbus_method_invocation_return_gerror(context, error);
+                       g_clear_error(&error);
+                       return TRUE;
+               }
+       } else {
+               ERR("Fail to connect Wi-Fi");
+               __agent_clear_fields(wifi_agent);
+
+               error = g_error_new(G_DBUS_ERROR,
+                               G_DBUS_ERROR_AUTH_FAILED,
+                               CONNMAN_ERROR_INTERFACE ".InvalidArguments");
+
+               g_dbus_method_invocation_return_gerror(context, error);
+               g_clear_error(&error);
+               return TRUE;
+       }
+
+       net_connman_agent_complete_set_field(connman_agent, context);
        return TRUE;
 }
 
-gboolean netconfig_iface_wifi_request_input(NetconfigWifi *wifi,
-               gchar *service, GHashTable *fields,
-               DBusGMethodInvocation *context)
+gboolean handle_request_input(NetConnmanAgent *connman_agent,
+               GDBusMethodInvocation *context, const gchar *service, GVariant *fields)
 {
-       GHashTableIter iter;
-       gpointer field, value;
-       GHashTable *out_table = NULL;
-       GValue *ret_value = NULL;
-
-       g_return_val_if_fail(wifi != NULL, FALSE);
+       GVariantIter *iter;
+       gchar *field = NULL;
+       GVariant *r_value = NULL;
+       GVariant *out_table = NULL;
+       gboolean updated = FALSE;
+       GVariantBuilder *builder = NULL;
+       GError *error = NULL;
+       const char *interface_name = NULL;
+       netconfig_wifi_agent_s *wifi_agent = NULL;
+
+       g_return_val_if_fail(connman_agent != NULL, TRUE);
 
        if (NULL == service)
-               return FALSE;
+               return TRUE;
 
        DBG("Agent fields requested for service: %s", service);
 
-       out_table = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
-       if (NULL == out_table)
-               return FALSE;
+       interface_name = netconfig_get_ifname(service);
+       if (interface_name == NULL) {
+               error = g_error_new(G_DBUS_ERROR,
+                               G_DBUS_ERROR_AUTH_FAILED,
+                               CONNMAN_ERROR_INTERFACE ".InvalidService");
 
-       g_hash_table_iter_init(&iter, fields);
+               g_dbus_method_invocation_return_gerror(context, error);
+               g_clear_error(&error);
 
-       while (g_hash_table_iter_next(&iter, &field, &value)) {
-               if (g_strcmp0(field, NETCONFIG_AGENT_FIELD_PASSPHRASE) == 0 &&
-                               agent.passphrase != NULL) {
-                       ret_value = g_slice_new0(GValue);
+               return TRUE;
+       }
 
-                       g_value_init(ret_value, G_TYPE_STRING);
-                       g_value_set_string(ret_value, agent.passphrase);
-                       g_hash_table_insert(out_table, g_strdup(field), ret_value);
+       wifi_agent = __agent_get_data(interface_name);
+       if (wifi_agent == NULL) {
+               error = g_error_new(G_DBUS_ERROR,
+                               G_DBUS_ERROR_AUTH_FAILED,
+                               CONNMAN_ERROR_INTERFACE ".InvalidService");
 
-                       DBG("Setting [%s] - []", field);
-               } else if (g_strcmp0(field, NETCONFIG_AGENT_FIELD_WPS) == 0 &&
-                               (agent.wps_pbc == TRUE || agent.wps_pin != NULL)) {
-                       ret_value = g_slice_new0(GValue);
+               g_dbus_method_invocation_return_gerror(context, error);
+               g_clear_error(&error);
+
+               return TRUE;
+       }
 
-                       g_value_init(ret_value, G_TYPE_STRING);
+       builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
 
-                       if (agent.wps_pbc == TRUE) {
+       g_variant_get(fields, "a{sv}", &iter);
+       while (g_variant_iter_loop(iter, "{sv}", &field, &r_value)) {
+
+               if (g_strcmp0(field, NETCONFIG_AGENT_FIELD_PASSPHRASE) == 0 &&
+                               wifi_agent->passphrase != NULL) {
+                       g_variant_builder_add(builder, "{sv}", NETCONFIG_AGENT_FIELD_PASSPHRASE,
+                                                       g_variant_new_string(wifi_agent->passphrase));
+
+                       updated = TRUE;
+                       DBG("Setting [%s] - [%s]", field, wifi_agent->passphrase);
+               } else if (g_strcmp0(field, NETCONFIG_AGENT_FIELD_WPS) == 0 &&
+                               (wifi_agent->wps_pbc == TRUE || wifi_agent->wps_pin != NULL)) {
+                       if (wifi_agent->wps_pbc == TRUE) {
                                /* Sending empty string for WPS push button method */
-                               g_value_set_string(ret_value, "");
+                               g_variant_builder_add(builder, "{sv}", NETCONFIG_AGENT_FIELD_WPS,
+                                       g_variant_new_string(""));
 
+                               updated = TRUE;
                                DBG("Setting empty string for [%s]", field);
-                       } else if (agent.wps_pin != NULL) {
-                               g_value_set_string(ret_value, agent.wps_pin);
+                       } else if (wifi_agent->wps_pin != NULL) {
+                               g_variant_builder_add(builder, "{sv}", NETCONFIG_AGENT_FIELD_WPS,
+                                       g_variant_new_string(wifi_agent->wps_pin));
 
-                               DBG("Setting string [%s] - []", field);
+                               updated = TRUE;
+                               DBG("Setting string [%s] - [%s]", field, wifi_agent->wps_pin);
                        }
+               } else if (g_strcmp0(field, NETCONFIG_AGENT_FIELD_NAME) == 0 &&
+                               wifi_agent->name != NULL) {
+                       g_variant_builder_add(builder, "{sv}", NETCONFIG_AGENT_FIELD_NAME,
+                               g_variant_new_string(wifi_agent->name));
+
+                       updated = TRUE;
+                       DBG("Settings [%s] - [%s]", field, wifi_agent->name);
+               } else if (g_strcmp0(field, NETCONFIG_AGENT_FIELD_SSID) == 0 &&
+                               wifi_agent->ssid != NULL) {
+                       int i = 0;
+                       GVariantBuilder *builder1 = NULL;
+                       builder1 = g_variant_builder_new(G_VARIANT_TYPE("ay"));
+
+                       for (i = 0; i < (wifi_agent->ssid->len); i++)
+                               g_variant_builder_add(builder1, "y", wifi_agent->ssid->data[i]);
+
+                       g_variant_builder_add(builder, "{sv}", NETCONFIG_AGENT_FIELD_SSID,
+                                       g_variant_builder_end(builder1));
+
+                       g_variant_builder_unref(builder1);
+
+                       updated = TRUE;
+                       DBG("Settings [%s] - []", field);
+               } else if (g_strcmp0(field, NETCONFIG_AGENT_FIELD_IDENTITY) == 0 &&
+                               wifi_agent->identity != NULL) {
+                       g_variant_builder_add(builder, "{sv}", NETCONFIG_AGENT_FIELD_IDENTITY,
+                               g_variant_new_string(wifi_agent->identity));
+
+                       updated = TRUE;
+                       DBG("Settings [%s] - [%s]", field, wifi_agent->identity);
+#if defined TIZEN_CAPTIVE_PORTAL
+               } else if (g_strcmp0(field, NETCONFIG_AGENT_FIELD_USERNAME) == 0 &&
+                               wifi_agent->username != NULL) {
+                       g_variant_builder_add(builder, "{sv}", NETCONFIG_AGENT_FIELD_USERNAME,
+                               g_variant_new_string(wifi_agent->username));
+
+                       updated = TRUE;
+                       DBG("Settings [%s] - [%s]", field, wifi_agent->username);
+               } else if (g_strcmp0(field, NETCONFIG_AGENT_FIELD_PASSWORD) == 0 &&
+                               wifi_agent->password != NULL) {
+                       g_variant_builder_add(builder, "{sv}", NETCONFIG_AGENT_FIELD_PASSWORD,
+                               g_variant_new_string(wifi_agent->password));
+
+                       updated = TRUE;
+                       DBG("Settings [%s] - [%s]", field, wifi_agent->password);
+#endif
+               }
+       }
+
+       out_table = g_variant_new("(@a{sv})", g_variant_builder_end(builder));
+
+       g_variant_builder_unref(builder);
+
+       g_variant_iter_free(iter);
+
+
+       if (NULL == out_table) {
+               net_connman_agent_complete_request_input(connman_agent, context, out_table);
+
+               return TRUE;
+       }
+
+       if (updated == TRUE)
+               g_dbus_method_invocation_return_value(context, out_table);
+       else {
+               GError *error = NULL;
+               error = g_error_new(G_DBUS_ERROR,
+                               G_DBUS_ERROR_AUTH_FAILED,
+                               "net.connman.Agent.Error.Canceled");
+
+               g_dbus_method_invocation_return_gerror(context, error);
+               g_clear_error(&error);
+       }
+
+       __agent_clear_fields(wifi_agent);
+
+       return TRUE;
+}
+
+
+gboolean handle_report_error(NetConnmanAgent *connman_agent,
+               GDBusMethodInvocation *context, const gchar *service, const gchar *error)
+{
+       g_return_val_if_fail(connman_agent != NULL, TRUE);
+
+       net_connman_agent_complete_report_error(connman_agent, context);
+       DBG("Agent error for service[%s] - [%s]", service, error);
+
+       /* Do something when it failed to make a connection */
+
+       return TRUE;
+}
+
+#if defined TIZEN_CAPTIVE_PORTAL
+#if defined TIZEN_WEARABLE
+#define QUERY_FOR_INTERNET_INTERVAL                    2
+#define TIMER_THRESHOLD                                                4
+#else
+#define QUERY_FOR_INTERNET_INTERVAL                    20
+#define TIMER_THRESHOLD                                                120
+#endif
+
+static gboolean is_monitor_notifier_registered = FALSE;
+
+#if defined TIZEN_WEARABLE
+static gboolean is_portal_msg_shown = FALSE;
+#endif
+
+struct poll_timer_data {
+       guint time_elapsed;
+       guint timer_id;
+       void* data;
+};
+
+static struct poll_timer_data timer_data = {
+               QUERY_FOR_INTERNET_INTERVAL, 0, NULL};
 
-                       g_hash_table_insert(out_table, g_strdup(field), ret_value);
+static gboolean __check_ignore_portal_list(const char * ssid)
+{
+       char def_str[1024];
+       int i = 0;
+       int ignore_ap_count = 0;
+
+       if (ssid == NULL)
+               return FALSE;
+
+       DBG("checking ssid [%s]", ssid);
+
+       DBG("csc string [%s]", def_str);
+       gchar ** ignore_ap_list = g_strsplit(def_str, ",", 0);
+       ignore_ap_count = g_strv_length(ignore_ap_list);
+       for (i = 0; i < ignore_ap_count; i++) {
+               DBG("[%d] - [%s]", i, ignore_ap_list[i]);
+               if (strncmp(ignore_ap_list[i], ssid, strlen(ssid)) == 0) {
+                       g_strfreev(ignore_ap_list);
+                       return TRUE;
                }
        }
 
-       dbus_g_method_return(context, out_table);
+       g_strfreev(ignore_ap_list);
+       return FALSE;
+}
+
+static void __wifi_state_monitor(wifi_state_notifier_s *notifier,
+               char *service, wifi_service_state_e state, void *user_data);
+
+static wifi_state_notifier_s wifi_state_monitor_notifier = {
+               .notifier = NULL,
+               .service = NULL,
+               .wifi_state_changed = __wifi_state_monitor,
+               .user_data = NULL,
+};
+
+static void __wifi_state_monitor(wifi_state_notifier_s *notifier,
+               char *service, wifi_service_state_e state, void *user_data)
+{
+       DBG("Wi-Fi state: %x", state);
+
+       if (state == NETCONFIG_WIFI_CONNECTED)
+               return;
+
+       if (is_monitor_notifier_registered == TRUE) {
+               wifi_state_notifier_unregister(&wifi_state_monitor_notifier);
+               is_monitor_notifier_registered = FALSE;
+       }
+
+#if defined TIZEN_WEARABLE
+       is_portal_msg_shown = FALSE;
+#endif
+
+       /* suspend if Internet check activity in progress */
+       if (timer_data.timer_id == 0)
+               return;
+
+       netconfig_stop_timer(&timer_data.timer_id);
+       netconfig_stop_internet_check();
+
+       DBG("Stopped Internet accessibility check");
+}
+
+static gboolean __netconfig_wifi_portal_login_timeout(gpointer data)
+{
+       char *service_profile = NULL;
+       GVariant *reply = NULL;
+
+       DBG("");
+
+       struct poll_timer_data *timer = (struct poll_timer_data *)data;
+       if (timer == NULL)
+               return FALSE;
+
+       if (TRUE == netconfig_get_internet_status()) {
+               if (is_monitor_notifier_registered == TRUE) {
+                       wifi_state_notifier_unregister(&wifi_state_monitor_notifier);
+                       is_monitor_notifier_registered = FALSE;
+               }
+
+               DBG("Portal logged in successfully and update ConnMan state");
+               return FALSE; /* to stop the timer */
+       } else {
+               if (timer->time_elapsed >= TIMER_THRESHOLD) {
+                       DBG("Login failed, update ConnMan");
+
+                       if (is_monitor_notifier_registered == TRUE) {
+                               wifi_state_notifier_unregister(&wifi_state_monitor_notifier);
+                               is_monitor_notifier_registered = FALSE;
+                       }
+
+                       /* Disconnect and forget the AP */
+                       service_profile = (char *)netconfig_get_default_profile();
+                       if (service_profile && netconfig_is_wifi_profile(service_profile)) {
+                               /* Now forget the AP*/
+                               reply = netconfig_invoke_dbus_method(CONNMAN_SERVICE,
+                                               service_profile, CONNMAN_SERVICE_INTERFACE, "Remove",
+                                               NULL);
+
+                               if (reply != NULL)
+                                       g_variant_unref(reply);
+                               else
+                                       ERR("Failed to forget the AP ");
+                       }
+               } else {
+                       if (wifi_state_get_service_state(netconfig_get_default_ifname())
+                                       == NETCONFIG_WIFI_CONNECTED) {
+                               /* check Internet availability by sending and receiving data*/
+                               netconfig_check_internet_accessibility();
+                               /* Returning TRUE itself is enough to restart the timer */
+                               timer->time_elapsed = timer->time_elapsed +
+                                                                       QUERY_FOR_INTERNET_INTERVAL;
+                               return TRUE;
+                       }
+               }
+       }
+
+       return FALSE;
+}
+
+static void __netconfig_wifi_portal_login_timer_start(struct poll_timer_data
+               *data)
+{
+       DBG("__netconfig_wifi_browser_start_timer...starting timer");
+
+       if (data == NULL)
+               return;
+
+       netconfig_stop_timer(&(data->timer_id));
+
+       /* Timer logic: After successful launch of browser, we would check for
+        * Internet status for every 20s until a threshold of 120s
+        */
+
+       data->time_elapsed = QUERY_FOR_INTERNET_INTERVAL;
+       netconfig_start_timer_seconds(QUERY_FOR_INTERNET_INTERVAL,
+               __netconfig_wifi_portal_login_timeout, data, &(data->timer_id));
+}
+#endif
+
+gboolean handle_request_browser(NetConnmanAgent *connman_agent,
+               GDBusMethodInvocation *context, const gchar *service, const gchar *url)
+{
+#if defined TIZEN_CAPTIVE_PORTAL
+       gboolean ignore_portal = FALSE;
+       const char * ssid = NULL;
+
+       g_return_val_if_fail(connman_agent != NULL, TRUE);
+
+       DBG("service[%s] - url[%s]", service, url);
+
+       ssid = netconfig_wifi_get_connected_essid(netconfig_get_default_profile());
+       if (ssid == NULL) {
+               ERR("Connected AP name is NULL!!");
+               net_connman_agent_complete_request_browser(connman_agent, context);
+               return TRUE;
+       }
+
+       ignore_portal = __check_ignore_portal_list(ssid);
+
+       if (ignore_portal == TRUE) {
+               net_connman_agent_complete_request_browser(connman_agent, context);
+               return TRUE;
+       }
+       /* Register for Wifi state change notifier*/
+       if (is_monitor_notifier_registered == FALSE) {
+               wifi_state_notifier_register(&wifi_state_monitor_notifier);
+               is_monitor_notifier_registered = TRUE;
+       }
+
+       netconfig_send_notification_to_net_popup(NETCONFIG_ADD_PORTAL_NOTI, ssid);
+
+       timer_data.time_elapsed = 0;
+       __netconfig_wifi_portal_login_timer_start(&timer_data);
+
+       net_connman_agent_complete_request_browser(connman_agent, context);
+       return TRUE;
+#else
+       GError *error = NULL;
+       error = g_error_new(G_DBUS_ERROR,
+                       G_DBUS_ERROR_AUTH_FAILED,
+                       CONNMAN_ERROR_INTERFACE ".NotSupported");
 
-       __netconfig_agent_clear_fields();
+       g_dbus_method_invocation_return_gerror(context, error);
+       g_clear_error(&error);
 
        return TRUE;
+#endif
 }