[net-config] Suspend/Resume WLAN driver
[platform/core/connectivity/net-config.git] / src / wifi-state.c
index 072431f..237e2e0 100755 (executable)
 
 #include <vconf.h>
 #include <vconf-keys.h>
-#include <bundle.h>
-#include <bundle_internal.h>
-#include <eventsystem.h>
-#include <syspopup_caller.h>
 
 #include "log.h"
 #include "util.h"
@@ -48,24 +44,50 @@ static GSList *notifier_list = NULL;
 static guint network_connected_popup_timer_id = 0;
 static gboolean block_network_connected_popup = FALSE;
 
-static void __netconfig_pop_wifi_connected_poppup(const char *ssid)
-{
-       bundle *b = NULL;
-
-       if (ssid == NULL)
-               return;
-
-       b = bundle_create();
-
-       bundle_add(b, "_SYSPOPUP_TITLE_", "Network connection popup");
-       bundle_add(b, "_SYSPOPUP_TYPE_", "toast_popup");
-       bundle_add(b, "_SYSPOPUP_CONTENT_", "wifi connected");
-       bundle_add(b, "_AP_NAME_", ssid);
+char *_convert_wifi_service_state_to_string(wifi_service_state_e wifi_service_state_type)
+{
+       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;
+       }
 
-       DBG("Launch Wi-Fi connected alert network popup");
-       syspopup_launch("net-popup", b);
+       return "Invalid parameter";
+}
+
+char *_convert_wifi_technology_state_to_string(wifi_tech_state_e wifi_tech_state_type)
+{
+       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;
+       }
 
-       bundle_free(b);
+       return "Invalid parameter";
 }
 
 static gboolean _block_network_connection_popup(gpointer data)
@@ -327,44 +349,6 @@ static void _deregister_network_notification(void)
        vconf_ignore_key_changed(VCONFKEY_WIFI_ENABLE_QS, __notification_value_changed_cb);
 }
 
-static void _set_power_save(gboolean power_save)
-{
-       gboolean result;
-       const char *if_path;
-       GVariant *input_args = NULL;
-       static gboolean old_state = TRUE;
-       const gchar *args_disable = "POWERMODE 1";
-       const gchar *args_enable = "POWERMODE 0";
-       if (old_state == power_save)
-               return;
-
-       if_path = netconfig_wifi_get_supplicant_interface();
-       if (if_path == NULL) {
-               ERR("Fail to get wpa_supplicant DBus path");
-               return;
-       }
-
-       if (power_save)
-               input_args = g_variant_new_string(args_enable);
-       else
-               input_args = g_variant_new_string(args_disable);
-
-       result = netconfig_supplicant_invoke_dbus_method_nonblock(
-                       SUPPLICANT_SERVICE,
-                       if_path,
-                       SUPPLICANT_INTERFACE ".Interface",
-                       "Driver",
-                       input_args,
-                       NULL);
-       if (result == FALSE)
-               ERR("Fail to set power save mode POWERMODE %d", power_save);
-       else
-               old_state = power_save;
-
-       g_variant_unref(input_args);
-       return;
-}
-
 static void _set_power_lock(gboolean power_lock)
 {
        gint32 ret = 0;
@@ -407,12 +391,14 @@ static void _set_power_lock(gboolean power_lock)
                return;
        }
 
-       ret = g_variant_get_int32(reply);
-       if (ret < 0)
-               ERR("Failed to set power lock %s with ret %d",
+       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;
+               else
+                       old_state = power_lock;
+       }
 
        g_variant_unref(reply);
 
@@ -460,9 +446,10 @@ void wifi_state_update_power_state(gboolean powered)
                        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_EVENT_WIFI_STATE, EVT_KEY_WIFI_STATE, EVT_VAL_WIFI_ON);
+                       netconfig_set_system_event(SYS_EVT_WIFI_STATE, EKEY_WIFI_STATE, EVAL_WIFI_ON);
 
                        netconfig_wifi_bgscan_stop();
+                       netconfig_wifi_bgscan_set_interval(SCAN_EXPONENTIAL_MIN);
                        netconfig_wifi_bgscan_start(TRUE);
 
                        /* Add callback to track change in notification setting */
@@ -484,9 +471,8 @@ void wifi_state_update_power_state(gboolean powered)
                netconfig_set_vconf_int(VCONFKEY_WIFI_STATE, VCONFKEY_WIFI_OFF);
                netconfig_set_vconf_int(VCONFKEY_NETWORK_WIFI_STATE, VCONFKEY_NETWORK_WIFI_OFF);
 
-               netconfig_set_system_event(SYS_EVENT_WIFI_STATE, EVT_KEY_WIFI_STATE, EVT_VAL_WIFI_OFF);
+               netconfig_set_system_event(SYS_EVT_WIFI_STATE, EKEY_WIFI_STATE, EVAL_WIFI_OFF);
 
-               netconfig_wifi_set_bgscan_pause(FALSE);
                netconfig_wifi_bgscan_stop();
 
                _set_bss_found(FALSE);
@@ -494,6 +480,7 @@ void wifi_state_update_power_state(gboolean powered)
                /* 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();
        }
@@ -551,16 +538,17 @@ void wifi_state_set_service_state(wifi_service_state_e new_state)
                return;
 
        g_service_state = new_state;
-       DBG("Wi-Fi state %d ==> %d", old_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));
 
-       /* During DHCP, temporarily disable Wi-Fi power saving */
-       if ((old_state < NETCONFIG_WIFI_ASSOCIATION || old_state == NETCONFIG_WIFI_FAILURE) && new_state == NETCONFIG_WIFI_CONFIGURATION) {
+       /* 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);
-               _set_power_save(FALSE);
+               wifi_set_early_suspend(FALSE);
                dhcp_stage = TRUE;
-       } else if (dhcp_stage == TRUE) {
+       } else if (dhcp_stage == TRUE && new_state != NETCONFIG_WIFI_CONFIGURATION) {
                _set_power_lock(FALSE);
-               _set_power_save(TRUE);
+               wifi_set_early_suspend(TRUE);
                dhcp_stage = FALSE;
        }
 
@@ -570,7 +558,7 @@ void wifi_state_set_service_state(wifi_service_state_e new_state)
                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_EVENT_WIFI_STATE, EVT_KEY_WIFI_STATE, EVT_VAL_WIFI_CONNECTED);
+               netconfig_set_system_event(SYS_EVT_WIFI_STATE, EKEY_WIFI_STATE, EVAL_WIFI_CONNECTED);
 
                __set_wifi_connected_essid();
 
@@ -583,18 +571,16 @@ void wifi_state_set_service_state(wifi_service_state_e new_state)
                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_EVENT_WIFI_STATE, EVT_KEY_WIFI_STATE, EVT_VAL_WIFI_ON);
+               netconfig_set_system_event(SYS_EVT_WIFI_STATE, EKEY_WIFI_STATE, EVAL_WIFI_ON);
 
                netconfig_wifi_indicator_stop();
 
-               netconfig_wifi_set_bgscan_pause(FALSE);
-
                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_set_bgscan_pause(FALSE);
 
                netconfig_wifi_bgscan_stop();
                netconfig_wifi_bgscan_start(TRUE);
@@ -620,7 +606,8 @@ void wifi_state_set_tech_state(wifi_tech_state_e new_state)
 
        g_tech_state = new_state;
 
-       DBG("Wi-Fi technology state %d ==> %d", old_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)
@@ -669,7 +656,6 @@ wifi_tech_state_e wifi_state_get_technology_state(void)
                                DBG("%s", sdata);
                        }
                }
-               g_variant_iter_free(next);
        }
 
        g_variant_unref(message);
@@ -687,6 +673,34 @@ wifi_tech_state_e wifi_state_get_technology_state(void)
        return g_tech_state;
 }
 
+gboolean wifi_state_is_technology_available(void)
+{
+       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 wifi_state_set_connected_essid(void)
 {
        __set_wifi_connected_essid();
@@ -713,7 +727,7 @@ void wifi_state_get_connected_essid(gchar **essid)
  */
 gboolean handle_get_wifi_state(Wifi *wifi, GDBusMethodInvocation *context)
 {
-       g_return_val_if_fail(wifi != NULL, FALSE);
+       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;