[net-config] Suspend/Resume WLAN driver
[platform/core/connectivity/net-config.git] / src / wifi-state.c
old mode 100644 (file)
new mode 100755 (executable)
index dc513a6..237e2e0
@@ -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 "log.h"
 #include "util.h"
 #include "netdbus.h"
-#include "network-state.h"
-#include "network-statistics.h"
 #include "wifi-state.h"
+#include "wifi-power.h"
+#include "netsupplicant.h"
+#include "network-state.h"
 #include "wifi-indicator.h"
+#include "network-statistics.h"
 #include "wifi-background-scan.h"
 
-static int profiles_count = 0;
+#define NETCONFIG_NETWORK_NOTIFICATION_TIMEOUT 15 * 1000
 
-static enum netconfig_wifi_service_state
-       wifi_service_state = NETCONFIG_WIFI_UNKNOWN;
+static gboolean new_bss_found = FALSE;
+static guint network_noti_timer_id = 0;
+
+static wifi_service_state_e g_service_state = NETCONFIG_WIFI_UNKNOWN;
+static wifi_tech_state_e g_tech_state = NETCONFIG_WIFI_TECH_UNKNOWN;
 
 static GSList *notifier_list = NULL;
 
+static guint network_connected_popup_timer_id = 0;
+static gboolean block_network_connected_popup = FALSE;
 
-static void __netconfig_wifi_set_profiles_count(const int count)
+char *_convert_wifi_service_state_to_string(wifi_service_state_e wifi_service_state_type)
 {
-       profiles_count = count;
+       switch (wifi_service_state_type) {
+       case NETCONFIG_WIFI_UNKNOWN:
+               return "unknown";
+       case NETCONFIG_WIFI_IDLE:
+               return "idle";
+       case NETCONFIG_WIFI_ASSOCIATION:
+               return "association";
+       case NETCONFIG_WIFI_CONFIGURATION:
+               return "configuration";
+       case NETCONFIG_WIFI_CONNECTED:
+               return "connected";
+       case NETCONFIG_WIFI_FAILURE:
+               return "failure";
+       default:
+               ERR("Invalid wifi_service_state_e parameter");
+               break;
+       }
+
+       return "Invalid parameter";
 }
 
-static int __netconfig_wifi_get_profiles_count(void)
+char *_convert_wifi_technology_state_to_string(wifi_tech_state_e wifi_tech_state_type)
 {
-       return profiles_count;
+       switch (wifi_tech_state_type) {
+       case NETCONFIG_WIFI_TECH_UNKNOWN:
+               return "unknown";
+       case NETCONFIG_WIFI_TECH_OFF:
+               return "off";
+       case NETCONFIG_WIFI_TECH_WPS_ONLY:
+               return "wps only";
+       case NETCONFIG_WIFI_TECH_POWERED:
+               return "powered";
+       case NETCONFIG_WIFI_TECH_CONNECTED:
+               return "connected";
+       case NETCONFIG_WIFI_TECH_TETHERED:
+               return "tethered";
+       default:
+               ERR("Invalid wifi_tech_state_e parameter");
+               break;
+       }
+
+       return "Invalid parameter";
+}
+
+static gboolean _block_network_connection_popup(gpointer data)
+{
+       block_network_connected_popup = FALSE;
+       netconfig_stop_timer(&network_connected_popup_timer_id);
+       return FALSE;
 }
 
-static void __netconfig_wifi_set_essid(void)
+static void __set_wifi_connected_essid(void)
 {
        const char *essid_name = NULL;
        const char *wifi_profile = netconfig_get_default_profile();
 
-       if (netconfig_wifi_state_get_service_state() != NETCONFIG_WIFI_CONNECTED)
+       if (wifi_state_get_service_state() != NETCONFIG_WIFI_CONNECTED)
                return;
 
        if (wifi_profile == NULL ||
@@ -67,393 +117,652 @@ static void __netconfig_wifi_set_essid(void)
                return;
        }
 
-       vconf_set_str(VCONFKEY_WIFI_CONNECTED_AP_NAME, essid_name);
+       netconfig_set_vconf_str(VCONFKEY_WIFI_CONNECTED_AP_NAME, essid_name);
+
+       /* Block Network Connected popup for 3sec
+        * to avoid multiple popup's due to ready signals */
+       if (block_network_connected_popup == FALSE) {
+               block_network_connected_popup = TRUE;
+               netconfig_start_timer(3000, _block_network_connection_popup,
+                               NULL, &network_connected_popup_timer_id);
+               __netconfig_pop_wifi_connected_poppup(essid_name);
+       }
 }
 
-static void __netconfig_wifi_unset_essid(void)
+static void __unset_wifi_connected_essid(void)
 {
-       vconf_set_str(VCONFKEY_WIFI_CONNECTED_AP_NAME, "");
+       netconfig_set_vconf_str(VCONFKEY_WIFI_CONNECTED_AP_NAME, "");
 }
 
-static GSList *__netconfig_wifi_state_get_service_profiles(DBusMessage *message)
+static const char *__get_wifi_connected_essid(void)
 {
-       GSList *service_profiles = NULL;
-       DBusMessageIter iter, dict;
-
-       dbus_message_iter_init(message, &iter);
-       dbus_message_iter_recurse(&iter, &dict);
-
-       while (dbus_message_iter_get_arg_type(&dict) == DBUS_TYPE_STRUCT) {
-               DBusMessageIter entry;
-               const char *object_path = NULL;
+       const char *essid_name = NULL;
+       const char *wifi_profile = NULL;
 
-               dbus_message_iter_recurse(&dict, &entry);
-               dbus_message_iter_get_basic(&entry, &object_path);
+       if (wifi_state_get_service_state() != NETCONFIG_WIFI_CONNECTED)
+               return NULL;
 
-               if (object_path == NULL) {
-                       dbus_message_iter_next(&dict);
-                       continue;
-               }
+       wifi_profile = netconfig_get_default_profile();
 
-               if (netconfig_is_wifi_profile(object_path) == TRUE)
-                       service_profiles = g_slist_append(service_profiles,
-                                       g_strdup(object_path));
+       if (wifi_profile == NULL || netconfig_is_wifi_profile(wifi_profile) != TRUE) {
+               ERR("Can't get Wi-Fi profile");
+               return NULL;
+       }
 
-               dbus_message_iter_next(&dict);
+       essid_name = netconfig_wifi_get_connected_essid(wifi_profile);
+       if (essid_name == NULL) {
+               ERR("Can't get Wi-Fi name");
+               return NULL;
        }
 
-       return service_profiles;
+       return essid_name;
 }
 
-static char *__netconfig_wifi_get_connman_favorite_service(void)
+static gboolean __is_wifi_profile_available(void)
 {
-       char *favorite_service = NULL;
-       DBusMessage *message = NULL;
-       GSList *service_profiles = NULL;
-       GSList *list = NULL;
+       GVariant *message = NULL;
+       GVariantIter *iter, *next;
+       gchar *obj;
 
        message = netconfig_invoke_dbus_method(CONNMAN_SERVICE,
                        CONNMAN_MANAGER_PATH, CONNMAN_MANAGER_INTERFACE,
                        "GetServices", NULL);
        if (message == NULL) {
                ERR("Failed to get service list");
-               return NULL;
+               return FALSE;
        }
 
-       /* Get service profiles from ConnMan Manager */
-       service_profiles = __netconfig_wifi_state_get_service_profiles(message);
-       dbus_message_unref(message);
-
-       for (list = service_profiles; list != NULL; list = list->next) {
-               char *profile_path = list->data;
-               DBusMessageIter iter, array;
-
-               if (favorite_service != NULL)
-                       break;
-
-               message = netconfig_invoke_dbus_method(CONNMAN_SERVICE,
-                               profile_path, CONNMAN_SERVICE_INTERFACE, "GetProperties", NULL);
-
-               if (message == NULL) {
-                       ERR("Failed to get service information of %s", profile_path);
+       g_variant_get(message, "(a(oa{sv}))", &iter);
+       while (g_variant_iter_loop(iter, "(oa{sv})", &obj, &next)) {
+               if (obj == NULL || netconfig_is_wifi_profile((const gchar*)obj) == FALSE)
                        continue;
-               }
-
-               dbus_message_iter_init(message, &iter);
-               dbus_message_iter_recurse(&iter, &array);
 
-               while (dbus_message_iter_get_arg_type(&array) == DBUS_TYPE_DICT_ENTRY) {
-                       DBusMessageIter entry, variant;
-                       const char *key = NULL;
-                       dbus_bool_t value;
+               g_variant_iter_free(next);
+               g_free(obj);
+               break;
+       }
 
-                       dbus_message_iter_recurse(&array, &entry);
-                       dbus_message_iter_get_basic(&entry, &key);
+       g_variant_unref(message);
 
-                       dbus_message_iter_next(&entry);
-                       dbus_message_iter_recurse(&entry, &variant);
+       g_variant_iter_free(iter);
 
-                       if (g_str_equal(key, "Favorite") != TRUE) {
-                               dbus_message_iter_next(&array);
-                               continue;
-                       }
+       return TRUE;
+}
 
-                       dbus_message_iter_get_basic(&variant, &value);
+static gboolean __is_favorited(GVariantIter *array)
+{
+       gboolean is_favorite = FALSE;
+       gchar *key;
+       GVariant *var;
 
-                       if (value)
-                               favorite_service = g_strdup(profile_path);
+       while (g_variant_iter_loop(array, "{sv}", &key, &var)) {
+               gboolean value;
 
-                       break;
-               }
+               if (g_str_equal(key, "Favorite") != TRUE)
+                       continue;
 
-               dbus_message_unref(message);
+               value = g_variant_get_boolean(var);
+               if (value)
+                       is_favorite = TRUE;
+               g_free(key);
+               g_variant_unref(var);
+               break;
        }
 
-       g_slist_free(service_profiles);
+       return is_favorite;
+}
 
-       return favorite_service;
+static void _wifi_state_connected_activation(void)
+{
+       /* Add activation of services when Wi-Fi is connected */
 }
 
-static void __netconfig_wifi_state_changed(
-               enum netconfig_wifi_service_state state)
+static void _wifi_state_changed(wifi_service_state_e state)
 {
        GSList *list;
 
        for (list = notifier_list; list; list = list->next) {
-               struct netconfig_wifi_state_notifier *notifier = list->data;
+               wifi_state_notifier *notifier = list->data;
 
-               if (notifier->netconfig_wifi_state_changed != NULL)
-                       notifier->netconfig_wifi_state_changed(state, notifier->user_data);
+               if (notifier->wifi_state_changed != NULL)
+                       notifier->wifi_state_changed(state, notifier->user_data);
        }
 }
 
-void netconfig_wifi_state_set_service_state(
-               enum netconfig_wifi_service_state new_state)
+static void _set_bss_found(gboolean found)
 {
-       enum netconfig_wifi_service_state old_state = wifi_service_state;
+       if (found != new_bss_found)
+               new_bss_found = found;
+}
 
-       if (old_state == new_state)
-               return;
+static gboolean _check_network_notification(gpointer data)
+{
+       int qs_enable = 0, ug_state = 0;
+       static gboolean check_again = FALSE;
 
-       wifi_service_state = new_state;
-       DBG("Wi-Fi state %d ==> %d", old_state, new_state);
+       wifi_tech_state_e tech_state;
+       wifi_service_state_e service_state;
 
-       if (new_state == NETCONFIG_WIFI_CONNECTED) {
-               netconfig_del_wifi_found_notification();
+       tech_state = wifi_state_get_technology_state();
+       if (tech_state < NETCONFIG_WIFI_TECH_POWERED) {
+               DBG("Wi-Fi off or WPS only supported[%d]", tech_state);
+               goto cleanup;
+       }
 
-               vconf_set_int(VCONFKEY_WIFI_STATE, VCONFKEY_WIFI_CONNECTED);
-               vconf_set_int(VCONFKEY_NETWORK_WIFI_STATE, VCONFKEY_NETWORK_WIFI_CONNECTED);
+       service_state = wifi_state_get_service_state();
+       if (service_state == NETCONFIG_WIFI_CONNECTED) {
+               DBG("Service state is connected");
+               goto cleanup;
+       } else if (service_state == NETCONFIG_WIFI_ASSOCIATION ||
+               service_state == NETCONFIG_WIFI_CONFIGURATION) {
+               DBG("Service state is connecting (check again : %d)", check_again);
+               if (!check_again) {
+                       check_again = TRUE;
+                       return TRUE;
+               } else
+                       check_again = FALSE;
+       }
 
-               __netconfig_wifi_set_essid();
+       if (__is_wifi_profile_available() == FALSE) {
+               netconfig_send_notification_to_net_popup(
+               NETCONFIG_DEL_FOUND_AP_NOTI, NULL);
+               goto cleanup;
+       }
 
-               netconfig_wifi_indicator_start();
-       } else if (old_state == NETCONFIG_WIFI_CONNECTED) {
-               vconf_set_int (VCONFKEY_WIFI_STATE, VCONFKEY_WIFI_UNCONNECTED);
-               vconf_set_int(VCONFKEY_NETWORK_WIFI_STATE, VCONFKEY_NETWORK_WIFI_NOT_CONNECTED);
+       netconfig_vconf_get_int(VCONFKEY_WIFI_ENABLE_QS, &qs_enable);
+       if (qs_enable != VCONFKEY_WIFI_QS_ENABLE) {
+               DBG("qs_enable != VCONFKEY_WIFI_QS_ENABLE");
+               goto cleanup;
+       }
 
-               __netconfig_wifi_unset_essid();
+       netconfig_vconf_get_int(VCONFKEY_WIFI_UG_RUN_STATE, &ug_state);
+       if (ug_state == VCONFKEY_WIFI_UG_RUN_STATE_ON_FOREGROUND)
+               goto cleanup;
 
-               netconfig_wifi_indicator_stop();
-       }
+       netconfig_send_notification_to_net_popup(NETCONFIG_ADD_FOUND_AP_NOTI, NULL);
 
-       __netconfig_wifi_state_changed(new_state);
-}
+       _set_bss_found(FALSE);
 
-enum netconfig_wifi_service_state
-netconfig_wifi_state_get_service_state(void)
-{
-       return wifi_service_state;
+cleanup:
+       netconfig_stop_timer(&network_noti_timer_id);
+       return FALSE;
 }
 
-enum netconfig_wifi_tech_state netconfig_wifi_get_technology_state(void)
+static char *_get_connman_favorite_service(void)
 {
-       DBusMessage *message = NULL;
-       DBusMessageIter iter, array;
-       enum netconfig_wifi_tech_state ret = NETCONFIG_WIFI_TECH_OFF;
-       gboolean wifi_tech_powered = FALSE;
-       gboolean wifi_tech_connected = FALSE;
+       char *favorite_service = NULL;
+       GVariant *message = NULL;
+       gchar *obj;
+       GVariantIter *iter, *next;
 
        message = netconfig_invoke_dbus_method(CONNMAN_SERVICE,
                        CONNMAN_MANAGER_PATH, CONNMAN_MANAGER_INTERFACE,
-                       "GetTechnologies", NULL);
+                       "GetServices", NULL);
        if (message == NULL) {
-               ERR("Failed to get Wi-Fi technology state");
-               return NETCONFIG_WIFI_TECH_UNKNOWN;
+               ERR("Failed to get service list");
+               return NULL;
        }
 
-       dbus_message_iter_init(message, &iter);
-       dbus_message_iter_recurse(&iter, &array);
+       g_variant_get(message, "(a(oa{sv}))", &iter);
+       while (g_variant_iter_loop(iter, "(oa{sv})", &obj, &next)) {
+               if (obj == NULL || netconfig_is_wifi_profile(obj) == FALSE)
+                       continue;
 
-       while (dbus_message_iter_get_arg_type(&array) == DBUS_TYPE_STRUCT) {
-               DBusMessageIter entry, dict;
-               const char *path;
+               if (__is_favorited(next) == TRUE) {
+                       favorite_service = g_strdup(obj);
+                       g_free(obj);
+                       g_variant_iter_free(next);
+                       break;
+               }
+       }
 
-               dbus_message_iter_recurse(&array, &entry);
-               dbus_message_iter_get_basic(&entry, &path);
+       g_variant_iter_free(iter);
+       g_variant_unref(message);
 
-               dbus_message_iter_next(&entry);
-               dbus_message_iter_recurse(&entry, &dict);
+       return favorite_service;
+}
 
-               if (path == NULL ||
-                       g_str_equal(path, CONNMAN_WIFI_TECHNOLOGY_PREFIX) == FALSE) {
-                       dbus_message_iter_next(&array);
-                       continue;
-               }
+static void __notification_value_changed_cb(keynode_t *node, void *user_data)
+{
+       int value = -1;
 
-               while (dbus_message_iter_get_arg_type(&dict) == DBUS_TYPE_DICT_ENTRY) {
-                       DBusMessageIter entry1, value1;
-                       const char *key, *sdata;
-                       dbus_bool_t data;
+       if (netconfig_vconf_get_int(VCONFKEY_WIFI_ENABLE_QS, &value) < 0)
+               return;
 
-                       dbus_message_iter_recurse(&dict, &entry1);
-                       dbus_message_iter_get_basic(&entry1, &key);
+       if (value == VCONFKEY_WIFI_QS_DISABLE)
+               netconfig_send_notification_to_net_popup(NETCONFIG_DEL_FOUND_AP_NOTI, NULL);
+}
 
-                       dbus_message_iter_next(&entry1);
-                       dbus_message_iter_recurse(&entry1, &value1);
+static void _register_network_notification(void)
+{
+#if defined TIZEN_WEARABLE
+       return;
+#endif
+       vconf_notify_key_changed(VCONFKEY_WIFI_ENABLE_QS, __notification_value_changed_cb, NULL);
+}
 
-                       if (dbus_message_iter_get_arg_type(&value1) ==
-                                       DBUS_TYPE_BOOLEAN) {
-                               dbus_message_iter_get_basic(&value1, &data);
-                               DBG("key-[%s] - %s", key, data ? "True" : "False");
+static void _deregister_network_notification(void)
+{
+#if defined TIZEN_WEARABLE
+               return;
+#endif
+       vconf_ignore_key_changed(VCONFKEY_WIFI_ENABLE_QS, __notification_value_changed_cb);
+}
 
-                               if (strcmp(key, "Powered") == 0 && data) {
-                                       wifi_tech_powered = TRUE;
-                               } else if (strcmp(key, "Connected") == 0 && data) {
-                                       wifi_tech_connected = TRUE;
-                               } else if (strcmp(key, "Tethering") == 0 && data) {
-                                       /* For further use */
-                               }
-                       } else if (dbus_message_iter_get_arg_type(&value1) ==
-                                       DBUS_TYPE_STRING) {
-                               dbus_message_iter_get_basic(&value1, &sdata);
-                               DBG("%s", sdata);
-                       }
-                       dbus_message_iter_next(&dict);
-               }
+static void _set_power_lock(gboolean power_lock)
+{
+       gint32 ret = 0;
+       GVariant *reply;
+       GVariant *params;
+       char state[] = "lcdoff";
+       char flag[] = "staycurstate";
+       char standby[] = "NULL";
+       int timeout = 0;
+       char sleepmargin[] = "sleepmargin";
+
+       const char *lockstate = "lockstate";
+       const char *unlockstate = "unlockstate";
+       static gboolean old_state = FALSE;
+       const char *lock_method;
+
+       if (old_state == power_lock)
+               return;
+
+       if (power_lock == TRUE) {
+               /* deviced power lock enable */
+               params = g_variant_new("(sssi)", state, flag, standby, timeout);
 
-               dbus_message_iter_next(&array);
+               lock_method = lockstate;
+       } else {
+               /* deviced power lock disable */
+               params = g_variant_new("(ss)", state, sleepmargin);
+
+               lock_method = unlockstate;
        }
 
-       dbus_message_unref(message);
+       reply = netconfig_invoke_dbus_method(
+                       "org.tizen.system.deviced",
+                       "/Org/Tizen/System/DeviceD/Display",
+                       "org.tizen.system.deviced.display",
+                       lock_method,
+                       params);
+       if (reply == NULL) {
+               ERR("Failed to set_power_lock");
+               return;
+       }
 
-       if (wifi_tech_powered)
-               ret = NETCONFIG_WIFI_TECH_POWERED;
+       if (g_variant_is_of_type(reply, G_VARIANT_TYPE_INT32)) {
+               ret = g_variant_get_int32(reply);
+               if (ret < 0)
+                       ERR("Failed to set power lock %s with ret %d",
+                               power_lock == TRUE ? "enable" : "disable", ret);
+               else
+                       old_state = power_lock;
+       }
 
-       if (wifi_tech_connected)
-               ret = NETCONFIG_WIFI_TECH_CONNECTED;
+       g_variant_unref(reply);
 
-       return ret;
+       return;
+}
+
+void wifi_state_emit_power_completed(gboolean power_on)
+{
+       if (power_on)
+               wifi_emit_power_on_completed((Wifi *)get_wifi_object());
+       else
+               wifi_emit_power_off_completed((Wifi *)get_wifi_object());
+
+       DBG("Successfully sent signal [%s]", (power_on) ? "powerOn" : "powerOff");
+}
+
+void wifi_state_emit_power_failed(void)
+{
+       wifi_emit_power_operation_failed((Wifi *)get_wifi_object());
+
+       DBG("Successfully sent signal [PowerOperationFailed]");
 }
 
-void netconfig_wifi_update_power_state(gboolean powered)
+void wifi_state_update_power_state(gboolean powered)
 {
-       int wifi_state = 0;
+       wifi_tech_state_e tech_state;
 
        /* It's automatically updated by signal-handler
         * DO NOT update manually
         * It includes Wi-Fi state configuration
         */
-       vconf_get_int(VCONFKEY_WIFI_STATE, &wifi_state);
+       tech_state = wifi_state_get_technology_state();
 
        if (powered == TRUE) {
-               if (wifi_state == VCONFKEY_WIFI_OFF &&
-                               netconfig_is_wifi_direct_on() != TRUE &&
-                               netconfig_is_wifi_tethering_on() != TRUE) {
-                       DBG("Wi-Fi successfully turned on or waken up from power-save mode");
+               if (tech_state < NETCONFIG_WIFI_TECH_POWERED && netconfig_is_wifi_tethering_on() != TRUE) {
+                       DBG("Wi-Fi turned on or waken up from power-save mode");
 
-                       netconfig_wifi_notify_power_completed(TRUE);
+                       wifi_state_set_tech_state(NETCONFIG_WIFI_TECH_POWERED);
+
+                       wifi_state_emit_power_completed(TRUE);
 
                        netconfig_wifi_device_picker_service_start();
 
-                       vconf_set_int(VCONFKEY_NETWORK_WIFI_STATE, VCONFKEY_NETWORK_WIFI_NOT_CONNECTED);
+                       netconfig_set_vconf_int(VCONF_WIFI_LAST_POWER_STATE, VCONFKEY_WIFI_UNCONNECTED);
+                       netconfig_set_vconf_int(VCONFKEY_WIFI_STATE, VCONFKEY_WIFI_UNCONNECTED);
+                       netconfig_set_vconf_int(VCONFKEY_NETWORK_WIFI_STATE, VCONFKEY_NETWORK_WIFI_NOT_CONNECTED);
 
-                       vconf_set_int(VCONF_WIFI_LAST_POWER_STATE, WIFI_POWER_ON);
+                       netconfig_set_system_event(SYS_EVT_WIFI_STATE, EKEY_WIFI_STATE, EVAL_WIFI_ON);
 
-                       vconf_set_int(VCONFKEY_WIFI_STATE, VCONFKEY_WIFI_UNCONNECTED);
+                       netconfig_wifi_bgscan_stop();
+                       netconfig_wifi_bgscan_set_interval(SCAN_EXPONENTIAL_MIN);
+                       netconfig_wifi_bgscan_start(TRUE);
 
-                       netconfig_wifi_bgscan_start();
+                       /* Add callback to track change in notification setting */
+                       _register_network_notification();
                }
-       } else {
-               if (wifi_state != VCONFKEY_WIFI_OFF) {
-                       DBG("Wi-Fi successfully turned off or in power-save mode");
+       } else if (tech_state > NETCONFIG_WIFI_TECH_OFF) {
+               DBG("Wi-Fi turned off or in power-save mode");
 
-                       netconfig_wifi_device_picker_service_stop();
+               wifi_state_set_tech_state(NETCONFIG_WIFI_TECH_WPS_ONLY);
 
-                       netconfig_wifi_remove_driver();
+               netconfig_wifi_device_picker_service_stop();
 
-                       netconfig_wifi_notify_power_completed(FALSE);
+               wifi_power_disable_technology_state_by_only_connman_signal();
+               wifi_power_driver_and_supplicant(FALSE);
 
-                       netconfig_del_wifi_found_notification();
+               wifi_state_emit_power_completed(FALSE);
 
-                       netconfig_wifi_bgscan_stop();
+               netconfig_set_vconf_int(VCONF_WIFI_LAST_POWER_STATE, VCONFKEY_WIFI_OFF);
+               netconfig_set_vconf_int(VCONFKEY_WIFI_STATE, VCONFKEY_WIFI_OFF);
+               netconfig_set_vconf_int(VCONFKEY_NETWORK_WIFI_STATE, VCONFKEY_NETWORK_WIFI_OFF);
 
-                       __netconfig_wifi_set_profiles_count(0);
+               netconfig_set_system_event(SYS_EVT_WIFI_STATE, EKEY_WIFI_STATE, EVAL_WIFI_OFF);
 
-                       vconf_set_int(VCONFKEY_NETWORK_WIFI_STATE, VCONFKEY_NETWORK_WIFI_OFF);
+               netconfig_wifi_bgscan_stop();
 
-                       vconf_set_int(VCONF_WIFI_LAST_POWER_STATE, WIFI_POWER_OFF);
+               _set_bss_found(FALSE);
 
-                       vconf_set_int(VCONFKEY_WIFI_STATE, VCONFKEY_WIFI_OFF);
-               }
+               /* Inform net-popup to remove the wifi found notification */
+               netconfig_send_notification_to_net_popup(NETCONFIG_DEL_FOUND_AP_NOTI, NULL);
+               netconfig_send_notification_to_net_popup(NETCONFIG_DEL_PORTAL_NOTI, NULL);
+               netconfig_send_notification_to_net_popup(NETCONFIG_DEL_IP_CONFLICT_NOTI, NULL);
+
+               _deregister_network_notification();
        }
 }
 
-char *netconfig_wifi_get_favorite_service(void)
+char *wifi_get_favorite_service(void)
 {
-       return __netconfig_wifi_get_connman_favorite_service();
+       return _get_connman_favorite_service();
 }
 
-void netconfig_wifi_check_network_notification(DBusMessage *message)
+void wifi_start_timer_network_notification(void)
 {
-       DBusMessageIter iter;
-       int profiles_count = 0;
-       int qs_enable, ug_state;
+#if defined TIZEN_WEARABLE
+               /* In case of wearable device, no need to notify available Wi-Fi APs */
+               return ;
+#endif
+       netconfig_start_timer(NETCONFIG_NETWORK_NOTIFICATION_TIMEOUT, _check_network_notification, NULL, &network_noti_timer_id);
+}
 
-       if (netconfig_wifi_state_get_service_state() == NETCONFIG_WIFI_CONNECTED) {
-               DBG("Service state is connected");
-               return;
-       }
+void wifi_state_notifier_register(wifi_state_notifier *notifier)
+{
+       DBG("register notifier");
 
-       if (vconf_get_int(VCONFKEY_WIFI_ENABLE_QS, &qs_enable) == -1) {
-               DBG("Fail to get %s", VCONFKEY_WIFI_ENABLE_QS);
-               return;
-       }
+       notifier_list = g_slist_append(notifier_list, notifier);
+}
 
-       if (qs_enable != VCONFKEY_WIFI_QS_ENABLE) {
-               DBG("qs_enable != VCONFKEY_WIFI_QS_ENABLE");
-               return;
-       }
+void wifi_state_notifier_unregister(wifi_state_notifier *notifier)
+{
+       DBG("un-register notifier");
 
-       if (vconf_get_int(VCONFKEY_WIFI_UG_RUN_STATE, &ug_state) == -1) {
-               DBG("Fail to get %s", VCONFKEY_WIFI_UG_RUN_STATE);
-               return;
-       }
+       notifier_list = g_slist_remove_all(notifier_list, notifier);
+}
 
-       if (ug_state == VCONFKEY_WIFI_UG_RUN_STATE_ON_FOREGROUND) {
-               DBG("ug_state == VCONFKEY_WIFI_UG_RUN_STATE_ON_FOREGROUND");
+void wifi_state_notifier_cleanup(void)
+{
+       g_slist_free_full(notifier_list, NULL);
+}
+
+void wifi_state_set_bss_found(gboolean found)
+{
+       _set_bss_found(found);
+}
+
+gboolean wifi_state_is_bss_found(void)
+{
+       return new_bss_found;
+}
+
+void wifi_state_set_service_state(wifi_service_state_e new_state)
+{
+       static gboolean dhcp_stage = FALSE;
+       wifi_service_state_e old_state = g_service_state;
+
+       if (old_state == new_state)
                return;
+
+       g_service_state = new_state;
+       DBG("Wi-Fi service state, old state[%s] ==> new state[%s]",
+               _convert_wifi_service_state_to_string(old_state), _convert_wifi_service_state_to_string(new_state));
+
+       /* From association, temporarily disable Wi-Fi power saving */
+       if ((old_state < NETCONFIG_WIFI_ASSOCIATION || old_state == NETCONFIG_WIFI_FAILURE) && new_state == NETCONFIG_WIFI_ASSOCIATION) {
+               _set_power_lock(TRUE);
+               wifi_set_early_suspend(FALSE);
+               dhcp_stage = TRUE;
+       } else if (dhcp_stage == TRUE && new_state != NETCONFIG_WIFI_CONFIGURATION) {
+               _set_power_lock(FALSE);
+               wifi_set_early_suspend(TRUE);
+               dhcp_stage = FALSE;
        }
 
-       if (message == NULL) {
-               ERR("Failed to get service list");
-               return;
+       if (new_state == NETCONFIG_WIFI_CONNECTED) {
+               netconfig_send_notification_to_net_popup(NETCONFIG_DEL_FOUND_AP_NOTI, NULL);
+
+               netconfig_set_vconf_int(VCONFKEY_WIFI_STATE, VCONFKEY_WIFI_CONNECTED);
+               netconfig_set_vconf_int(VCONFKEY_NETWORK_WIFI_STATE, VCONFKEY_NETWORK_WIFI_CONNECTED);
+
+               netconfig_set_system_event(SYS_EVT_WIFI_STATE, EKEY_WIFI_STATE, EVAL_WIFI_CONNECTED);
+
+               __set_wifi_connected_essid();
+
+               netconfig_wifi_indicator_start();
+       } else if (old_state == NETCONFIG_WIFI_CONNECTED) {
+               netconfig_send_notification_to_net_popup(NETCONFIG_DEL_PORTAL_NOTI, NULL);
+
+               __unset_wifi_connected_essid();
+
+               netconfig_set_vconf_int (VCONFKEY_WIFI_STATE, VCONFKEY_WIFI_UNCONNECTED);
+               netconfig_set_vconf_int(VCONFKEY_NETWORK_WIFI_STATE, VCONFKEY_NETWORK_WIFI_NOT_CONNECTED);
+
+               netconfig_set_system_event(SYS_EVT_WIFI_STATE, EKEY_WIFI_STATE, EVAL_WIFI_ON);
+
+               netconfig_wifi_indicator_stop();
+
+               netconfig_wifi_bgscan_stop();
+               netconfig_wifi_bgscan_set_interval(SCAN_EXPONENTIAL_MIN);
+               netconfig_wifi_bgscan_start(TRUE);
+       } else if ((old_state > NETCONFIG_WIFI_IDLE && old_state < NETCONFIG_WIFI_CONNECTED) && new_state == NETCONFIG_WIFI_IDLE) {
+               /* in ipv6 case disconnect/association -> association */
+               DBG("reset the bg scan period");
+
+               netconfig_wifi_bgscan_stop();
+               netconfig_wifi_bgscan_start(TRUE);
        }
 
-       dbus_message_iter_init(message, &iter);
-       DBusMessageIter array, value;
-       dbus_message_iter_recurse(&iter, &array);
-       if (dbus_message_iter_get_arg_type(&array) != DBUS_TYPE_STRUCT) {
-               DBG("Array not found. type %d", dbus_message_iter_get_arg_type(&array));
+       _wifi_state_changed(new_state);
+
+       if (new_state == NETCONFIG_WIFI_CONNECTED)
+               _wifi_state_connected_activation();
+}
+
+wifi_service_state_e wifi_state_get_service_state(void)
+{
+       return g_service_state;
+}
+
+void wifi_state_set_tech_state(wifi_tech_state_e new_state)
+{
+       wifi_tech_state_e old_state = g_tech_state;
+
+       if (old_state == new_state)
                return;
+
+       g_tech_state = new_state;
+
+       DBG("Wi-Fi technology state, old state[%s] ==> new state[%s]",
+               _convert_wifi_technology_state_to_string(old_state), _convert_wifi_technology_state_to_string(new_state));
+}
+
+wifi_tech_state_e wifi_state_get_technology_state(void)
+{
+       GVariant *message = NULL, *variant;
+       GVariantIter *iter, *next;
+       wifi_tech_state_e ret = NETCONFIG_WIFI_TECH_OFF;
+       gboolean wifi_tech_powered = FALSE;
+       gboolean wifi_tech_connected = FALSE;
+       const char *path;
+       gchar *key;
+
+       if (g_tech_state > NETCONFIG_WIFI_TECH_UNKNOWN)
+               return g_tech_state;
+
+       message = netconfig_invoke_dbus_method(CONNMAN_SERVICE,
+                       CONNMAN_MANAGER_PATH, CONNMAN_MANAGER_INTERFACE,
+                       "GetTechnologies", NULL);
+       if (message == NULL) {
+               ERR("Failed to get_technology_state");
+               return NETCONFIG_WIFI_TECH_UNKNOWN;
        }
 
-       dbus_message_iter_recurse(&array, &value);
-       while (dbus_message_iter_get_arg_type(&value) == DBUS_TYPE_OBJECT_PATH) {
-               const char *object_path = NULL;
+       g_variant_get(message, "(a(oa{sv}))", &iter);
+       while (g_variant_iter_loop(iter, "(oa{sv})", &path, &next)) {
+               if (path == NULL || g_strcmp0(path, CONNMAN_WIFI_TECHNOLOGY_PREFIX) != 0)
+                       continue;
 
-               dbus_message_iter_get_basic(&value, &object_path);
+               while (g_variant_iter_loop(next, "{sv}", &key, &variant)) {
+                       const gchar *sdata = NULL;
+                       gboolean data;
 
-               DBG("found a profile: %s", object_path);
-               if (netconfig_is_wifi_profile(object_path) == TRUE) {
-                       profiles_count++;
-                       DBG("Total wifi profile cnt = %d", profiles_count);
-               }
+                       if (g_variant_is_of_type(variant, G_VARIANT_TYPE_BOOLEAN)) {
+                               data = g_variant_get_boolean(variant);
+                               DBG("key-[%s] - %s", key, data ? "True" : "False");
 
-               dbus_message_iter_next(&array);
-               if (dbus_message_iter_get_arg_type(&array) != DBUS_TYPE_STRUCT) {
-                       DBG("Not a structure entry. Arg type = %d", dbus_message_iter_get_arg_type(&array));
-                       break;
+                               if (strcmp(key, "Powered") == 0 && data)
+                                       wifi_tech_powered = TRUE;
+                               else if (strcmp(key, "Connected") == 0 && data)
+                                       wifi_tech_connected = TRUE;
+                               /* For further use
+                               else if (strcmp(key, "Tethering") == 0 && data) {
+                               } */
+                       } else if (g_variant_is_of_type(variant, G_VARIANT_TYPE_STRING)) {
+                               sdata = g_variant_get_string(variant, NULL);
+                               DBG("%s", sdata);
+                       }
                }
-               dbus_message_iter_recurse(&array, &value);
        }
 
-       if (__netconfig_wifi_get_profiles_count() != profiles_count) {
-               DBG("profiles prev_count (%d) - profiles count (%d)",
-                               __netconfig_wifi_get_profiles_count(), profiles_count);
+       g_variant_unref(message);
+
+       g_variant_iter_free(iter);
+
+       if (wifi_tech_powered == TRUE)
+               ret = NETCONFIG_WIFI_TECH_POWERED;
+
+       if (wifi_tech_connected == TRUE)
+               ret = NETCONFIG_WIFI_TECH_CONNECTED;
+
+       g_tech_state = ret;
 
-               netconfig_add_wifi_found_notification();
-               __netconfig_wifi_set_profiles_count(profiles_count);
-       } else
-               DBG("No change in profile count[%d]", profiles_count);
+       return g_tech_state;
 }
 
-void netconfig_wifi_state_notifier_cleanup(void)
+gboolean wifi_state_is_technology_available(void)
 {
-       g_slist_free_full(notifier_list, NULL);
+       GVariant *message = NULL;
+       GVariantIter *iter, *next;
+       const char *path;
+       gboolean ret = FALSE;
+
+       message = netconfig_invoke_dbus_method(CONNMAN_SERVICE,
+                       CONNMAN_MANAGER_PATH, CONNMAN_MANAGER_INTERFACE,
+                       "GetTechnologies", NULL);
+       if (message == NULL) {
+               ERR("Failed to get_technology_state");
+               return FALSE;
+       }
+
+       g_variant_get(message, "(a(oa{sv}))", &iter);
+       while (g_variant_iter_loop(iter, "(oa{sv})", &path, &next)) {
+               if (path != NULL && g_strcmp0(path, CONNMAN_WIFI_TECHNOLOGY_PREFIX) == 0)
+                       ret = TRUE;
+       }
+
+       g_variant_unref(message);
+       g_variant_iter_free(iter);
+
+       DBG("Wi-Fi technology is %s", ret ? "available" : "unavailable");
+       return ret;
 }
 
-void netconfig_wifi_state_notifier_register(
-               struct netconfig_wifi_state_notifier *notifier)
+void wifi_state_set_connected_essid(void)
 {
-       DBG("register notifier");
+       __set_wifi_connected_essid();
+}
 
-       notifier_list = g_slist_append(notifier_list, notifier);
+void wifi_state_get_connected_essid(gchar **essid)
+{
+       *essid = g_strdup(__get_wifi_connected_essid());
 }
 
-void netconfig_wifi_state_notifier_unregister(
-               struct netconfig_wifi_state_notifier *notifier)
+/*     wifi_connection_state_e in CAPI
+ *
+ *     WIFI_CONNECTION_STATE_FAILURE           = -1
+ *     WIFI_CONNECTION_STATE_DISCONNECTED      = 0
+ *     WIFI_CONNECTION_STATE_ASSOCIATION       = 1
+ *     WIFI_CONNECTION_STATE_CONFIGURATION     = 2
+ *     WIFI_CONNECTION_STATE_CONNECTED         = 3
+ */
+/*     connection_wifi_state_e in CAPI
+ *
+ *     CONNECTION_WIFI_STATE_DEACTIVATED       = 0
+ *     CONNECTION_WIFI_STATE_DISCONNECTED      = 1
+ *     CONNECTION_WIFI_STATE_CONNECTED         = 2
+ */
+gboolean handle_get_wifi_state(Wifi *wifi, GDBusMethodInvocation *context)
 {
-       DBG("un-register notifier");
+       g_return_val_if_fail(wifi != NULL, TRUE);
+       GVariant *param = NULL;
+       wifi_tech_state_e tech_state = NETCONFIG_WIFI_TECH_UNKNOWN;
+       wifi_service_state_e service_state = NETCONFIG_WIFI_UNKNOWN;
+       tech_state = wifi_state_get_technology_state();
+       service_state = wifi_state_get_service_state();
+
+       if (tech_state == NETCONFIG_WIFI_TECH_UNKNOWN)
+               param = g_variant_new("(s)", "unknown");
+       else if (tech_state == NETCONFIG_WIFI_TECH_OFF ||
+               tech_state == NETCONFIG_WIFI_TECH_WPS_ONLY)
+               param = g_variant_new("(s)", "deactivated");
+       else if (tech_state == NETCONFIG_WIFI_TECH_CONNECTED)
+               param = g_variant_new("(s)", "connected");
+       else {
+               switch (service_state) {
+               case NETCONFIG_WIFI_FAILURE:
+                       param = g_variant_new("(s)", "failure");
+                       break;
+               case NETCONFIG_WIFI_ASSOCIATION:
+                       param = g_variant_new("(s)", "association");
+                       break;
+               case NETCONFIG_WIFI_CONFIGURATION:
+                       param = g_variant_new("(s)", "configuration");
+                       break;
+               case NETCONFIG_WIFI_CONNECTED:
+                       param = g_variant_new("(s)", "connected");
+                       break;
+               case NETCONFIG_WIFI_UNKNOWN:
+               case NETCONFIG_WIFI_IDLE:
+               default:
+                       param = g_variant_new("(s)", "disconnected");
+               }
+       }
 
-       notifier_list = g_slist_remove_all(notifier_list, notifier);
+       g_dbus_method_invocation_return_value(context, param);
+
+       return TRUE;
 }