X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2Fwifi-state.c;h=40d0a959511063042dca4db3bcb587459a820b38;hb=0bafa3aeab494367d930afa52ee8c460ad9f514b;hp=f4bc1038bec4f6859737dce9a13a355f0d97e6ef;hpb=4ea8b5ee83c3160fe4e0960300559865907baa40;p=platform%2Fcore%2Fconnectivity%2Fnet-config.git diff --git a/src/wifi-state.c b/src/wifi-state.c old mode 100644 new mode 100755 index f4bc103..40d0a95 --- a/src/wifi-state.c +++ b/src/wifi-state.c @@ -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. @@ -23,36 +23,86 @@ #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) +static const 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) +static const 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,400 +117,662 @@ 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; - gboolean wifi_tethering = 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) { - wifi_tethering = TRUE; - } - } 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_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; - dbus_message_iter_next(&array); + if_path = netconfig_wifi_get_supplicant_interface(); + if (if_path == NULL) { + ERR("Fail to get wpa_supplicant DBus path"); + return; } - dbus_message_unref(message); + 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; +} - if (wifi_tech_powered) - ret = NETCONFIG_WIFI_TECH_POWERED; +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 (wifi_tech_connected) - ret = NETCONFIG_WIFI_TECH_CONNECTED; + if (power_lock == TRUE) { + /* deviced power lock enable */ + params = g_variant_new("(sssi)", state, flag, standby, timeout); - if (wifi_tethering) - ret = NETCONFIG_WIFI_TECH_TETHERING_ON; + lock_method = lockstate; + } else { + /* deviced power lock disable */ + params = g_variant_new("(ss)", state, sleepmargin); - return ret; + lock_method = unlockstate; + } + + 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; + } + + 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; + + g_variant_unref(reply); + + return; } -void netconfig_wifi_update_power_state(gboolean powered) +void wifi_state_emit_power_completed(gboolean power_on) { - int wifi_state = 0; + 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 wifi_state_update_power_state(gboolean powered) +{ + 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"); - vconf_set_int(VCONFKEY_NETWORK_WIFI_STATE, VCONFKEY_NETWORK_WIFI_NOT_CONNECTED); - vconf_set_int(VCONF_WIFI_LAST_POWER_STATE, WIFI_POWER_ON); - vconf_set_int(VCONFKEY_WIFI_STATE, VCONFKEY_WIFI_UNCONNECTED); + wifi_state_set_tech_state(NETCONFIG_WIFI_TECH_POWERED); - netconfig_wifi_notify_power_completed(TRUE); + wifi_state_emit_power_completed(TRUE); netconfig_wifi_device_picker_service_start(); - netconfig_wifi_bgscan_start(); + 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); + + netconfig_set_system_event(SYS_EVT_WIFI_STATE, EKEY_WIFI_STATE, EVAL_WIFI_ON); + + netconfig_wifi_bgscan_stop(); + netconfig_wifi_bgscan_start(TRUE); + + /* 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); - if (netconfig_is_wifi_tethering_on() != TRUE) - netconfig_wifi_remove_driver(); + netconfig_wifi_device_picker_service_stop(); - vconf_set_int(VCONFKEY_NETWORK_WIFI_STATE, VCONFKEY_NETWORK_WIFI_OFF); - vconf_set_int(VCONF_WIFI_LAST_POWER_STATE, WIFI_POWER_OFF); - vconf_set_int(VCONFKEY_WIFI_STATE, VCONFKEY_WIFI_OFF); + wifi_power_disable_technology_state_by_only_connman_signal(); + wifi_power_driver_and_supplicant(FALSE); - netconfig_wifi_notify_power_completed(FALSE); + wifi_state_emit_power_completed(FALSE); - netconfig_del_wifi_found_notification(); + 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_bgscan_stop(); + netconfig_set_system_event(SYS_EVT_WIFI_STATE, EKEY_WIFI_STATE, EVAL_WIFI_OFF); - __netconfig_wifi_set_profiles_count(0); - } + netconfig_wifi_set_bgscan_pause(FALSE); + netconfig_wifi_bgscan_stop(); + + _set_bss_found(FALSE); + + /* 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); + + _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); +} + +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); +} - if (ug_state == VCONFKEY_WIFI_UG_RUN_STATE_ON_FOREGROUND) { - DBG("ug_state == VCONFKEY_WIFI_UG_RUN_STATE_ON_FOREGROUND"); +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)); + + /* During DHCP, temporarily disable Wi-Fi power saving */ + if ((old_state < NETCONFIG_WIFI_ASSOCIATION || old_state == NETCONFIG_WIFI_FAILURE) && new_state == NETCONFIG_WIFI_CONFIGURATION) { + _set_power_lock(TRUE); + _set_power_save(FALSE); + dhcp_stage = TRUE; + } else if (dhcp_stage == TRUE) { + _set_power_lock(FALSE); + _set_power_save(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_set_bgscan_pause(FALSE); + + netconfig_wifi_bgscan_stop(); + 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); } - 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); + g_variant_iter_free(next); } - 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); - netconfig_add_wifi_found_notification(); - __netconfig_wifi_set_profiles_count(profiles_count); - } else - DBG("No change in profile count[%d]", profiles_count); + 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; + + return g_tech_state; } -void netconfig_wifi_state_notifier_cleanup(void) +void wifi_state_set_connected_essid(void) { - /* - * Now, all the user_data of notifier_list's element - * is NULL, so we don't free that, only use g_slist_free. - * If user_data is not NULL, using g_slist_free_full with - * destory_notify function to free user_data - */ - g_slist_free(notifier_list); + __set_wifi_connected_essid(); } -void netconfig_wifi_state_notifier_register( - struct netconfig_wifi_state_notifier *notifier) +void wifi_state_get_connected_essid(gchar **essid) { - DBG("register notifier"); - - notifier_list = g_slist_append(notifier_list, notifier); + *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, FALSE); + 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; }