From 8c5cc42813d3870e182434fc75877ab5bcff5e72 Mon Sep 17 00:00:00 2001 From: Abhishek Sansanwal Date: Mon, 4 Sep 2017 10:59:54 +0530 Subject: [PATCH] Code refactored to replace WPS with BSSID scan Change-Id: I64e5ddda12e5f3f17c19d61f458a7a8331f8d78f Signed-off-by: Abhishek Sansanwal --- CMakeLists.txt | 1 + include/wifi-bssid-scan.h | 40 ++++ include/wifi-wps.h | 6 - src/signal-handler.c | 9 +- src/wifi-bssid-scan.c | 533 ++++++++++++++++++++++++++++++++++++++++++++++ src/wifi-power.c | 3 +- src/wifi-wps.c | 506 ------------------------------------------- src/wifi.c | 1 + 8 files changed, 582 insertions(+), 517 deletions(-) create mode 100644 include/wifi-bssid-scan.h create mode 100644 src/wifi-bssid-scan.c diff --git a/CMakeLists.txt b/CMakeLists.txt index c7b4f54..c05f3fd 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -14,6 +14,7 @@ SET(SRCS src/neterror.c src/wifi-eap.c src/wifi-wps.c + src/wifi-bssid-scan.c src/wifi-agent.c src/wifi-power.c src/wifi-state.c diff --git a/include/wifi-bssid-scan.h b/include/wifi-bssid-scan.h new file mode 100644 index 0000000..9916c46 --- /dev/null +++ b/include/wifi-bssid-scan.h @@ -0,0 +1,40 @@ +/* + * Network Configuration Module + * + * 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef __NETCONFIG_WIFI_BSSID_SCAN_H__ +#define __NETCONFIG_WIFI_BSSID_SCAN_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "wifi.h" + +gboolean netconfig_wifi_is_bssid_scan_started(void); + +void netconfig_wifi_bssid_signal_scandone(void); +void netconfig_wifi_bssid_signal_scanaborted(void); + +gboolean handle_request_bssid_scan(Wifi *wifi, GDBusMethodInvocation *context); + +#ifdef __cplusplus +} +#endif + +#endif /* __NETCONFIG_WIFI_BSSID_SCAN_H__ */ diff --git a/include/wifi-wps.h b/include/wifi-wps.h index 0879498..aaa3d6e 100755 --- a/include/wifi-wps.h +++ b/include/wifi-wps.h @@ -32,12 +32,6 @@ extern "C" { #define WPS_EI_NO_ERROR 0 #define WPS_EI_OPERATION_FAILED 1 -gboolean netconfig_wifi_is_wps_enabled(void); - -void netconfig_wifi_wps_signal_scandone(void); -void netconfig_wifi_wps_signal_scanaborted(void); - -gboolean handle_request_bssid_scan(Wifi *wifi, GDBusMethodInvocation *context); gboolean handle_request_wps_connect(Wifi *wifi, GDBusMethodInvocation *context, gchar *param); gboolean handle_request_wps_cancel(Wifi *wifi, GDBusMethodInvocation *context); void netconfig_wifi_notify_wps_completed(const char *ssid, gsize ssid_len); diff --git a/src/signal-handler.c b/src/signal-handler.c index 546ef2b..bc6d658 100755 --- a/src/signal-handler.c +++ b/src/signal-handler.c @@ -28,6 +28,7 @@ #include "netdbus.h" #include "neterror.h" #include "wifi-wps.h" +#include "wifi-bssid-scan.h" #include "wifi-agent.h" #include "wifi-power.h" #include "wifi-state.h" @@ -487,8 +488,8 @@ static void _supplicant_interface_removed(GDBusConnection *conn, const gchar *sig, GVariant *param, gpointer user_data) { DBG("Interface removed handling!"); - if (netconfig_wifi_is_wps_enabled() == TRUE) - netconfig_wifi_wps_signal_scanaborted(); + if (netconfig_wifi_is_bssid_scan_started() == TRUE) + netconfig_wifi_bssid_signal_scanaborted(); return; } @@ -547,8 +548,8 @@ static void _supplicant_scan_done(GDBusConnection *conn, DBG("Scan Done handling!"); netconfig_wifi_set_scanning(FALSE); - if (netconfig_wifi_is_wps_enabled() == TRUE) { - netconfig_wifi_wps_signal_scandone(); + if (netconfig_wifi_is_bssid_scan_started() == TRUE) { + netconfig_wifi_bssid_signal_scandone(); if (wifi_state_get_technology_state() < NETCONFIG_WIFI_TECH_POWERED) return; } diff --git a/src/wifi-bssid-scan.c b/src/wifi-bssid-scan.c new file mode 100644 index 0000000..96c6c83 --- /dev/null +++ b/src/wifi-bssid-scan.c @@ -0,0 +1,533 @@ +/* + * Network Configuration Module + * + * 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include + +#include "netsupplicant.h" +#include "log.h" +#include "wifi-bssid-scan.h" +#include "util.h" +#include "wifi-power.h" +#include "wifi-state.h" +#include "wifi-background-scan.h" + +#define NETCONFIG_SSID_LEN 32 +#define NETCONFIG_BSSID_LEN 6 + +#define VCONF_WIFI_ALWAYS_ALLOW_SCANNING \ + "file/private/wifi/always_allow_scanning" + +static gboolean netconfig_is_bssid_scan_started = FALSE; +static gboolean netconfig_is_device_scanning = FALSE; +static gboolean netconfig_is_bssid_scan_aborted = FALSE; +static int bssid_list_count = 0; +static GSList *bssid_info_list = NULL; + +struct bssid_scan_info_t { + unsigned char ssid[NETCONFIG_SSID_LEN + 1]; + unsigned char bssid[NETCONFIG_BSSID_LEN + 1]; + int ssid_len; + int rssi; + int mode; +}; + +gboolean netconfig_wifi_is_bssid_scan_started(void) +{ + return netconfig_is_bssid_scan_started; +} + +static void __netconfig_wifi_bssid_notify_scan_done(void) +{ + GVariantBuilder *builder = NULL; + GVariantBuilder *builder1 = NULL; + GSList* list = NULL; + const char *prop_ssid = "ssid"; + const char *prop_bssid = "bssid"; + const char *prop_rssi = "rssi"; + const char *prop_mode = "mode"; + + builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}")); + for (list = bssid_info_list; list != NULL; list = list->next) { + struct bssid_scan_info_t *bss_info = (struct bssid_scan_info_t *)list->data; + + if (bss_info) { + gchar bssid_buff[18] = { 0, }; + gchar *bssid_str = bssid_buff; + unsigned char *ssid = (unsigned char *)bss_info->ssid; + int ssid_len = (int)bss_info->ssid_len; + int rssi = (int)bss_info->rssi; + int mode = (int)bss_info->mode; + int i = 0; + g_snprintf(bssid_buff, 18, "%02x:%02x:%02x:%02x:%02x:%02x", + bss_info->bssid[0], bss_info->bssid[1], bss_info->bssid[2], + bss_info->bssid[3], bss_info->bssid[4], bss_info->bssid[5]); + + DBG("BSS found; SSID %s, BSSID %s, RSSI %d MODE %d", ssid, bssid_str, rssi, mode); + + builder1 = g_variant_builder_new(G_VARIANT_TYPE("ay")); + for (i = 0; i < ssid_len; i++) + g_variant_builder_add(builder1, "y", ssid[i]); + g_variant_builder_add(builder, "{sv}", prop_ssid, g_variant_builder_end(builder1)); + g_variant_builder_unref(builder1); + + g_variant_builder_add(builder, "{sv}", prop_bssid, g_variant_new_string(bssid_str)); + g_variant_builder_add(builder, "{sv}", prop_rssi, g_variant_new_int32(rssi)); + g_variant_builder_add(builder, "{sv}", prop_mode, g_variant_new_int32(mode)); + } + } + + wifi_emit_bssid_scan_completed((Wifi *)get_wifi_object(), g_variant_builder_end(builder)); + g_variant_builder_unref(builder); + + if (bssid_info_list != NULL) + g_slist_free_full(bssid_info_list, g_free); + + bssid_info_list = NULL; + bssid_list_count = 0; + INFO("BSSIDScanCompleted"); + + return; +} + +static void __netconfig_wifi_bssid_get_bss_info_result( + GObject *source_object, GAsyncResult *res, gpointer user_data) +{ + GVariant *reply = NULL; + GVariant *value; + GVariantIter *iter; + gchar *key; + struct bssid_scan_info_t *bss_info; + GDBusConnection *conn = NULL; + GError *error = NULL; + + conn = G_DBUS_CONNECTION(source_object); + reply = g_dbus_connection_call_finish(conn, res, &error); + + if (error != NULL) { + ERR("Error code: [%d] Error message: [%s]", error->code, error->message); + g_error_free(error); + goto done; + } + + bss_info = g_try_new0(struct bssid_scan_info_t, 1); + if (bss_info == NULL) + goto done; + + g_variant_get(reply, "(a{sv})", &iter); + while (g_variant_iter_loop(iter, "{sv}", &key, &value)) { + if (key != NULL) { + if (g_strcmp0(key, "BSSID") == 0) { + const guchar *bssid; + gsize bssid_len; + + bssid = g_variant_get_fixed_array(value, &bssid_len, sizeof(guchar)); + if (bssid_len == NETCONFIG_BSSID_LEN) + memcpy(bss_info->bssid, bssid, bssid_len); + } else if (g_strcmp0(key, "SSID") == 0) { + const guchar *ssid; + gsize ssid_len; + + ssid = g_variant_get_fixed_array(value, &ssid_len, sizeof(guchar)); + if (ssid != NULL && ssid_len > 0 && ssid_len <= NETCONFIG_SSID_LEN) { + memcpy(bss_info->ssid, ssid, ssid_len); + bss_info->ssid_len = ssid_len; + } else { + memset(bss_info->ssid, 0, sizeof(bss_info->ssid)); + bss_info->ssid_len = 0; + } + } else if (g_strcmp0(key, "Mode") == 0) { + gchar *mode = NULL; + + g_variant_get(value, "s", &mode); + if (mode == NULL) + bss_info->mode = 0; + else { + if (g_strcmp0(mode, "infrastructure") == 0) + bss_info->mode = 1; + else if (g_strcmp0(mode, "ad-hoc") == 0) + bss_info->mode = 2; + else + bss_info->mode = 0; + g_free(mode); + } + } else if (g_strcmp0(key, "Signal") == 0) { + gint16 signal; + + signal = g_variant_get_int16(value); + bss_info->rssi = signal; + } + } + } + + if (bss_info->ssid[0] == '\0') + g_free(bss_info); + else + bssid_info_list = g_slist_append(bssid_info_list, bss_info); + + g_variant_iter_free(iter); +done: + if (reply) + g_variant_unref(reply); + + netconfig_gdbus_pending_call_unref(); + + bssid_list_count--; + if (bssid_list_count <= 0) { + __netconfig_wifi_bssid_notify_scan_done(); + + if (netconfig_is_bssid_scan_aborted == FALSE) + wifi_power_driver_and_supplicant(FALSE); + } +} + +static void __netconfig_wifi_bssid_get_bss_info(const char *path, int index) +{ + gboolean reply = FALSE; + GVariant *param = NULL; + + param = g_variant_new("(s)", SUPPLICANT_IFACE_BSS); + + reply = netconfig_invoke_dbus_method_nonblock(SUPPLICANT_SERVICE, + path, DBUS_INTERFACE_PROPERTIES, + "GetAll", param, __netconfig_wifi_bssid_get_bss_info_result); + if (reply != TRUE) + ERR("Fail to invoke_dbus_method_nonblock GetAll"); + + return; +} + +static void __netconfig_wifi_bssid_get_bss_result(GObject *source_object, + GAsyncResult *res, gpointer user_data) +{ + GVariant *reply = NULL; + GVariant *value = NULL; + GVariantIter *iter = NULL; + GDBusConnection *conn = NULL; + gchar *path = NULL; + gboolean counter_flag = FALSE; + GError *error = NULL; + + conn = G_DBUS_CONNECTION(source_object); + reply = g_dbus_connection_call_finish(conn, res, &error); + if (error != NULL) { + ERR("Error code: [%d] Error message: [%s]", error->code, error->message); + g_error_free(error); + goto done; + } + + g_variant_get(reply, "(v)", &value); + if (g_variant_is_of_type(value, G_VARIANT_TYPE_OBJECT_PATH_ARRAY)) { + g_variant_get(value, "ao", &iter); + while (g_variant_iter_next(iter, "o", &path)) { + if (path != NULL && g_strcmp0(path, "/") != 0) { + __netconfig_wifi_bssid_get_bss_info(path, ++bssid_list_count); + + counter_flag = TRUE; + } + + if (path) + g_free(path); + } + } + + if (iter) + g_variant_iter_free(iter); + + if (value) + g_variant_unref(value); + +done: + if (reply) + g_variant_unref(reply); + + netconfig_gdbus_pending_call_unref(); + + /* Send BssidScanCompleted signal even when the BSS count is 0 */ + if (bssid_list_count <= 0 && counter_flag == FALSE) { + __netconfig_wifi_bssid_notify_scan_done(); + + if (netconfig_is_bssid_scan_aborted == FALSE) + wifi_power_driver_and_supplicant(FALSE); + } +} + +static int _netconfig_wifi_bssid_get_bss(void) +{ + gboolean reply = FALSE; + const char *if_path = NULL; + GVariant *params = NULL; + + if_path = netconfig_wifi_get_supplicant_interface(); + if (if_path == NULL) { + DBG("Fail to get wpa_supplicant DBus path"); + return -ESRCH; + } + + params = g_variant_new("(ss)", SUPPLICANT_IFACE_INTERFACE, "BSSs"); + + reply = netconfig_invoke_dbus_method_nonblock(SUPPLICANT_SERVICE, + if_path, DBUS_INTERFACE_PROPERTIES, + "Get", params, __netconfig_wifi_bssid_get_bss_result); + if (reply != TRUE) { + ERR("Fail to method: Get"); + + return -ESRCH; + } + + return 0; +} + + +static void __netconfig_set_bssid_scan_mode(gboolean enable) +{ + if (netconfig_is_bssid_scan_started == enable) + return; + + netconfig_is_bssid_scan_started = enable; +} + +void netconfig_wifi_bssid_signal_scandone(void) +{ + bssid_list_count = 0; + _netconfig_wifi_bssid_get_bss(); + + netconfig_is_device_scanning = FALSE; + + __netconfig_set_bssid_scan_mode(FALSE); +} + +void netconfig_wifi_bssid_signal_scanaborted(void) +{ + bssid_list_count = 0; + netconfig_is_bssid_scan_aborted = TRUE; + _netconfig_wifi_bssid_get_bss(); + + netconfig_is_device_scanning = FALSE; + + __netconfig_set_bssid_scan_mode(FALSE); +} + +static int __netconfig_wifi_bssid_request_scan(const char *if_path) +{ + GDBusConnection *connection = NULL; + GVariant *message = NULL; + GVariantBuilder *builder = NULL; + const char *key1 = "Type"; + const char *val1 = "passive"; + + if (if_path == NULL) + if_path = netconfig_wifi_get_supplicant_interface(); + + if (if_path == NULL) { + DBG("Fail to get wpa_supplicant DBus path"); + return -ESRCH; + } + + connection = netdbus_get_connection(); + if (connection == NULL) { + ERR("Failed to get GDBusconnection"); + return -EIO; + } + + builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}")); + g_variant_builder_add(builder, "{sv}", key1, g_variant_new_string(val1)); + message = g_variant_new("(@a{sv})", g_variant_builder_end(builder)); + g_variant_builder_unref(builder); + + g_dbus_connection_call(connection, + SUPPLICANT_SERVICE, + if_path, + SUPPLICANT_INTERFACE ".Interface", + "Scan", + message, + NULL, + G_DBUS_CALL_FLAGS_NONE, + NETCONFIG_DBUS_REPLY_TIMEOUT, + netdbus_get_cancellable(), + NULL, + NULL); + + netconfig_is_device_scanning = TRUE; + + g_variant_unref(message); + /* Clear bss_info_list for the next scan result */ + if (bssid_info_list) { + g_slist_free_full(bssid_info_list, g_free); + bssid_info_list = NULL; + } + + netconfig_is_bssid_scan_aborted = FALSE; + + return 0; +} + +static void __netconfig_wifi_interface_create_result( + GObject *source_object, GAsyncResult *res, gpointer user_data) +{ + GVariant *message; + gchar *path = NULL; + GDBusConnection *conn = NULL; + GError *error = NULL; + + conn = G_DBUS_CONNECTION(source_object); + + message = g_dbus_connection_call_finish(conn, res, &error); + if (error == NULL) { + g_variant_get(message, "(o)", &path); + + if (path) { + __netconfig_wifi_bssid_request_scan(path); + g_free(path); + } + } else if (NULL != strstr(error->message, ".InterfaceExists")) { + INFO("Error Message %s %s", error->message, path); + g_variant_get(message, "(o)", &path); + if (path) { + __netconfig_wifi_bssid_request_scan(path); + g_free(path); + } else + __netconfig_wifi_bssid_request_scan(NULL); + } else { + ERR("Failed to create interface, Error: %d[%s]", error->code, error->message); + __netconfig_set_bssid_scan_mode(FALSE); + wifi_power_driver_and_supplicant(FALSE); + } + + g_variant_unref(message); +} + +static int __netconfig_wifi_bssid_create_interface(void) +{ + GDBusConnection *connection = NULL; + GVariant *message = NULL; + GVariantBuilder *builder = NULL; + const char *key = "Ifname"; + const char *val = WIFI_IFNAME; + + connection = netdbus_get_connection(); + if (connection == NULL) { + DBG("Failed to get GDBusconnection"); + return -EIO; + } + + builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}")); + g_variant_builder_add(builder, "{sv}", key, g_variant_new_string(val)); + message = g_variant_new("(@a{sv})", g_variant_builder_end(builder)); + + g_dbus_connection_call(connection, + SUPPLICANT_SERVICE, + SUPPLICANT_PATH, + SUPPLICANT_INTERFACE, + "CreateInterface", + message, + NULL, + G_DBUS_CALL_FLAGS_NONE, + NETCONFIG_DBUS_REPLY_TIMEOUT, + netdbus_get_cancellable(), + (GAsyncReadyCallback) __netconfig_wifi_interface_create_result, + NULL); + + g_variant_unref(message); + + return 0; +} + +static int __netconfig_wifi_bssid_scan(void) +{ + int err = 0; + wifi_tech_state_e wifi_tech_state; + + if (netconfig_is_device_scanning == TRUE) + return -EINPROGRESS; + + wifi_tech_state = wifi_state_get_technology_state(); + if (wifi_tech_state <= NETCONFIG_WIFI_TECH_OFF) + err = wifi_power_driver_and_supplicant(TRUE); + + if (err < 0 && err != -EALREADY) + return err; + + netconfig_is_device_scanning = TRUE; + + DBG("BSSID scan requested"); + if (wifi_tech_state >= NETCONFIG_WIFI_TECH_POWERED) { + if (netconfig_wifi_get_scanning() == TRUE) + return -EINPROGRESS; + + netconfig_wifi_bgscan_start(TRUE); + + if (wifi_tech_state == NETCONFIG_WIFI_TECH_CONNECTED) + __netconfig_wifi_bssid_request_scan(NULL); + } else { + err = __netconfig_wifi_bssid_create_interface(); + } + + return err; +} + +gboolean handle_request_bssid_scan(Wifi *wifi, GDBusMethodInvocation *context) +{ + int err, enabled = 0; + wifi_tech_state_e tech_state; + + g_return_val_if_fail(wifi != NULL, FALSE); + + if (netconfig_is_wifi_tethering_on() == TRUE) { + ERR("Wi-Fi Tethering is enabled"); + netconfig_error_dbus_method_return(context, NETCONFIG_ERROR_NO_SERVICE, "TetheringEnabled"); + return -EBUSY; + } + +#if !defined TIZEN_WEARABLE + if (netconfig_wifi_is_bgscan_paused()) { + ERR("Scan is paused"); + netconfig_error_dbus_method_return(context, NETCONFIG_ERROR_NO_SERVICE, "ScanPaused"); + return FALSE; + } +#endif + + tech_state = wifi_state_get_technology_state(); + if (tech_state <= NETCONFIG_WIFI_TECH_OFF) { +#if !defined TIZEN_WEARABLE + enabled = 1; +#else + enabled = 0; +#endif + + if (enabled == 0) { + netconfig_error_permission_denied(context); + return FALSE; + } + } + + __netconfig_set_bssid_scan_mode(TRUE); + + err = __netconfig_wifi_bssid_scan(); + if (err < 0) { + if (err == -EINPROGRESS) + netconfig_error_inprogress(context); + else + netconfig_error_wifi_driver_failed(context); + + return FALSE; + } + + wifi_complete_request_bssid_scan(wifi, context); + return TRUE; +} diff --git a/src/wifi-power.c b/src/wifi-power.c index 260214e..4dd968a 100755 --- a/src/wifi-power.c +++ b/src/wifi-power.c @@ -30,6 +30,7 @@ #include "netdbus.h" #include "neterror.h" #include "wifi-wps.h" +#include "wifi-bssid-scan.h" #include "wifi-power.h" #include "wifi-state.h" #include "netsupplicant.h" @@ -184,7 +185,7 @@ static int _remove_driver_and_supplicant(void) INFO("remove driver and supplicant"); if (wifi_firmware_recovery_mode != TRUE && - netconfig_wifi_is_wps_enabled() == TRUE) { + netconfig_wifi_is_bssid_scan_started() == TRUE) { DBG("Wi-Fi WPS mode"); return 0; } diff --git a/src/wifi-wps.c b/src/wifi-wps.c index 38d4544..5f09eb7 100755 --- a/src/wifi-wps.c +++ b/src/wifi-wps.c @@ -31,26 +31,6 @@ #include "netsupplicant.h" #include "wifi-background-scan.h" -#define NETCONFIG_SSID_LEN 32 -#define NETCONFIG_BSSID_LEN 6 -#define NETCONFIG_WPS_DBUS_REPLY_TIMEOUT (10 * 1000) - -#define VCONF_WIFI_ALWAYS_ALLOW_SCANNING \ - "file/private/wifi/always_allow_scanning" - -static gboolean netconfig_is_wps_enabled = FALSE; -static gboolean netconfig_is_device_scanning = FALSE; -static gboolean netconfig_is_bssid_scan_aborted = FALSE; -static int wps_bss_list_count = 0; - -struct bssid_scan_info_t { - unsigned char ssid[NETCONFIG_SSID_LEN + 1]; - unsigned char bssid[NETCONFIG_BSSID_LEN + 1]; - int ssid_len; - int rssi; - int mode; -}; - struct netconfig_wifi_wps { char *pin; gboolean pbc; @@ -58,21 +38,6 @@ struct netconfig_wifi_wps { static struct netconfig_wifi_wps wifi_wps; -static GSList *wps_bss_info_list = NULL; - -static void __netconfig_wps_set_mode(gboolean enable) -{ - if (netconfig_is_wps_enabled == enable) - return; - - netconfig_is_wps_enabled = enable; -} - -gboolean netconfig_wifi_is_wps_enabled(void) -{ - return netconfig_is_wps_enabled; -} - void netconfig_wifi_notify_wps_credentials(const char *ssid, gsize ssid_len, const char *wps_key) { GVariantBuilder *builder; @@ -158,477 +123,6 @@ void netconfig_wifi_notify_wps_fail_event(int config_error, int error_indication return; } -static void __netconfig_wifi_wps_notify_scan_done(void) -{ - GVariantBuilder *builder = NULL; - GVariantBuilder *builder1 = NULL; - GSList* list = NULL; - const char *prop_ssid = "ssid"; - const char *prop_bssid = "bssid"; - const char *prop_rssi = "rssi"; - const char *prop_mode = "mode"; - - builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}")); - for (list = wps_bss_info_list; list != NULL; list = list->next) { - struct bssid_scan_info_t *bss_info = (struct bssid_scan_info_t *)list->data; - - if (bss_info) { - gchar bssid_buff[18] = { 0, }; - gchar *bssid_str = bssid_buff; - unsigned char *ssid = (unsigned char *)bss_info->ssid; - int ssid_len = (int)bss_info->ssid_len; - int rssi = (int)bss_info->rssi; - int mode = (int)bss_info->mode; - int i = 0; - g_snprintf(bssid_buff, 18, "%02x:%02x:%02x:%02x:%02x:%02x", - bss_info->bssid[0], bss_info->bssid[1], bss_info->bssid[2], - bss_info->bssid[3], bss_info->bssid[4], bss_info->bssid[5]); - - DBG("BSS found; SSID %s, BSSID %s, RSSI %d MODE %d", ssid, bssid_str, rssi, mode); - - builder1 = g_variant_builder_new(G_VARIANT_TYPE("ay")); - for (i = 0; i < ssid_len; i++) - g_variant_builder_add(builder1, "y", ssid[i]); - g_variant_builder_add(builder, "{sv}", prop_ssid, g_variant_builder_end(builder1)); - g_variant_builder_unref(builder1); - - g_variant_builder_add(builder, "{sv}", prop_bssid, g_variant_new_string(bssid_str)); - g_variant_builder_add(builder, "{sv}", prop_rssi, g_variant_new_int32(rssi)); - g_variant_builder_add(builder, "{sv}", prop_mode, g_variant_new_int32(mode)); - } - } - - wifi_emit_bssid_scan_completed((Wifi *)get_wifi_object(), g_variant_builder_end(builder)); - g_variant_builder_unref(builder); - - if (wps_bss_info_list != NULL) - g_slist_free_full(wps_bss_info_list, g_free); - - wps_bss_info_list = NULL; - wps_bss_list_count = 0; - INFO("BSSIDScanCompleted"); - - return; -} - -static void __netconfig_wifi_wps_get_bss_info_result( - GObject *source_object, GAsyncResult *res, gpointer user_data) -{ - GVariant *reply = NULL; - GVariant *value; - GVariantIter *iter; - gchar *key; - struct bssid_scan_info_t *bss_info; - GDBusConnection *conn = NULL; - GError *error = NULL; - - conn = G_DBUS_CONNECTION(source_object); - reply = g_dbus_connection_call_finish(conn, res, &error); - - if (error != NULL) { - ERR("Error code: [%d] Error message: [%s]", error->code, error->message); - g_error_free(error); - goto done; - } - - bss_info = g_try_new0(struct bssid_scan_info_t, 1); - if (bss_info == NULL) - goto done; - - g_variant_get(reply, "(a{sv})", &iter); - while (g_variant_iter_loop(iter, "{sv}", &key, &value)) { - if (key != NULL) { - if (g_strcmp0(key, "BSSID") == 0) { - const guchar *bssid; - gsize bssid_len; - - bssid = g_variant_get_fixed_array(value, &bssid_len, sizeof(guchar)); - if (bssid_len == NETCONFIG_BSSID_LEN) - memcpy(bss_info->bssid, bssid, bssid_len); - } else if (g_strcmp0(key, "SSID") == 0) { - const guchar *ssid; - gsize ssid_len; - - ssid = g_variant_get_fixed_array(value, &ssid_len, sizeof(guchar)); - if (ssid != NULL && ssid_len > 0 && ssid_len <= NETCONFIG_SSID_LEN) { - memcpy(bss_info->ssid, ssid, ssid_len); - bss_info->ssid_len = ssid_len; - } else { - memset(bss_info->ssid, 0, sizeof(bss_info->ssid)); - bss_info->ssid_len = 0; - } - } else if (g_strcmp0(key, "Mode") == 0) { - gchar *mode = NULL; - - g_variant_get(value, "s", &mode); - if (mode == NULL) - bss_info->mode = 0; - else { - if (g_strcmp0(mode, "infrastructure") == 0) - bss_info->mode = 1; - else if (g_strcmp0(mode, "ad-hoc") == 0) - bss_info->mode = 2; - else - bss_info->mode = 0; - g_free(mode); - } - } else if (g_strcmp0(key, "Signal") == 0) { - gint16 signal; - - signal = g_variant_get_int16(value); - bss_info->rssi = signal; - } - } - } - - if (bss_info->ssid[0] == '\0') - g_free(bss_info); - else - wps_bss_info_list = g_slist_append(wps_bss_info_list, bss_info); - - g_variant_iter_free(iter); -done: - if (reply) - g_variant_unref(reply); - - netconfig_gdbus_pending_call_unref(); - - wps_bss_list_count--; - if (wps_bss_list_count <= 0) { - __netconfig_wifi_wps_notify_scan_done(); - - if (netconfig_is_bssid_scan_aborted == FALSE) - wifi_power_driver_and_supplicant(FALSE); - } -} - -static void __netconfig_wifi_wps_get_bss_info(const char *path, int index) -{ - gboolean reply = FALSE; - GVariant *param = NULL; - - param = g_variant_new("(s)", SUPPLICANT_IFACE_BSS); - - reply = netconfig_invoke_dbus_method_nonblock(SUPPLICANT_SERVICE, - path, DBUS_INTERFACE_PROPERTIES, - "GetAll", param, __netconfig_wifi_wps_get_bss_info_result); - if (reply != TRUE) - ERR("Fail to invoke_dbus_method_nonblock GetAll"); - - return; -} - -static void __netconfig_wifi_wps_get_bsss_result(GObject *source_object, - GAsyncResult *res, gpointer user_data) -{ - GVariant *reply = NULL; - GVariant *value = NULL; - GVariantIter *iter = NULL; - GDBusConnection *conn = NULL; - gchar *path = NULL; - gboolean counter_flag = FALSE; - GError *error = NULL; - - conn = G_DBUS_CONNECTION(source_object); - reply = g_dbus_connection_call_finish(conn, res, &error); - if (error != NULL) { - ERR("Error code: [%d] Error message: [%s]", error->code, error->message); - g_error_free(error); - goto done; - } - - g_variant_get(reply, "(v)", &value); - if (g_variant_is_of_type(value, G_VARIANT_TYPE_OBJECT_PATH_ARRAY)) { - g_variant_get(value, "ao", &iter); - while (g_variant_iter_next(iter, "o", &path)) { - if (path != NULL && g_strcmp0(path, "/") != 0) { - __netconfig_wifi_wps_get_bss_info(path, ++wps_bss_list_count); - - counter_flag = TRUE; - } - - if (path) - g_free(path); - } - } - - if (iter) - g_variant_iter_free(iter); - - if (value) - g_variant_unref(value); - -done: - if (reply) - g_variant_unref(reply); - - netconfig_gdbus_pending_call_unref(); - - /* Send BssidScanCompleted signal even when the BSS count is 0 */ - if (wps_bss_list_count <= 0 && counter_flag == FALSE) { - __netconfig_wifi_wps_notify_scan_done(); - - if (netconfig_is_bssid_scan_aborted == FALSE) - wifi_power_driver_and_supplicant(FALSE); - } -} - -static int _netconfig_wifi_wps_get_bsss(void) -{ - gboolean reply = FALSE; - const char *if_path = NULL; - GVariant *params = NULL; - - if_path = netconfig_wifi_get_supplicant_interface(); - if (if_path == NULL) { - DBG("Fail to get wpa_supplicant DBus path"); - return -ESRCH; - } - - params = g_variant_new("(ss)", SUPPLICANT_IFACE_INTERFACE, "BSSs"); - - reply = netconfig_invoke_dbus_method_nonblock(SUPPLICANT_SERVICE, - if_path, DBUS_INTERFACE_PROPERTIES, - "Get", params, __netconfig_wifi_wps_get_bsss_result); - if (reply != TRUE) { - ERR("Fail to method: Get"); - - return -ESRCH; - } - - return 0; -} - -void netconfig_wifi_wps_signal_scandone(void) -{ - wps_bss_list_count = 0; - _netconfig_wifi_wps_get_bsss(); - - netconfig_is_device_scanning = FALSE; - - __netconfig_wps_set_mode(FALSE); -} - -void netconfig_wifi_wps_signal_scanaborted(void) -{ - wps_bss_list_count = 0; - netconfig_is_bssid_scan_aborted = TRUE; - _netconfig_wifi_wps_get_bsss(); - - netconfig_is_device_scanning = FALSE; - - __netconfig_wps_set_mode(FALSE); -} - -static int __netconfig_wifi_bssid_request_scan(const char *if_path) -{ - GDBusConnection *connection = NULL; - GVariant *message = NULL; - GVariantBuilder *builder = NULL; - const char *key1 = "Type"; - const char *val1 = "passive"; - - if (if_path == NULL) - if_path = netconfig_wifi_get_supplicant_interface(); - - if (if_path == NULL) { - DBG("Fail to get wpa_supplicant DBus path"); - return -ESRCH; - } - - connection = netdbus_get_connection(); - if (connection == NULL) { - ERR("Failed to get GDBusconnection"); - return -EIO; - } - - builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}")); - g_variant_builder_add(builder, "{sv}", key1, g_variant_new_string(val1)); - message = g_variant_new("(@a{sv})", g_variant_builder_end(builder)); - g_variant_builder_unref(builder); - - g_dbus_connection_call(connection, - SUPPLICANT_SERVICE, - if_path, - SUPPLICANT_INTERFACE ".Interface", - "Scan", - message, - NULL, - G_DBUS_CALL_FLAGS_NONE, - NETCONFIG_WPS_DBUS_REPLY_TIMEOUT, - netdbus_get_cancellable(), - NULL, - NULL); - - netconfig_is_device_scanning = TRUE; - - g_variant_unref(message); - /* Clear bss_info_list for the next scan result */ - if (wps_bss_info_list) { - g_slist_free_full(wps_bss_info_list, g_free); - wps_bss_info_list = NULL; - } - - netconfig_is_bssid_scan_aborted = FALSE; - - return 0; -} - -static void __netconfig_wifi_interface_create_result( - GObject *source_object, GAsyncResult *res, gpointer user_data) -{ - GVariant *message; - gchar *path = NULL; - GDBusConnection *conn = NULL; - GError *error = NULL; - - conn = G_DBUS_CONNECTION(source_object); - - message = g_dbus_connection_call_finish(conn, res, &error); - if (error == NULL) { - g_variant_get(message, "(o)", &path); - - if (path) { - __netconfig_wifi_bssid_request_scan(path); - g_free(path); - } - } else if (NULL != strstr(error->message, ".InterfaceExists")) { - INFO("Error Message %s %s", error->message, path); - g_variant_get(message, "(o)", &path); - if (path) { - __netconfig_wifi_bssid_request_scan(path); - g_free(path); - } else - __netconfig_wifi_bssid_request_scan(NULL); - } else { - ERR("Failed to create interface, Error: %d[%s]", error->code, error->message); - __netconfig_wps_set_mode(FALSE); - wifi_power_driver_and_supplicant(FALSE); - } - - g_variant_unref(message); -} - -static int __netconfig_wifi_wps_create_interface(void) -{ - GDBusConnection *connection = NULL; - GVariant *message = NULL; - GVariantBuilder *builder = NULL; - const char *key = "Ifname"; - const char *val = WIFI_IFNAME; - - connection = netdbus_get_connection(); - if (connection == NULL) { - DBG("Failed to get GDBusconnection"); - return -EIO; - } - - builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}")); - g_variant_builder_add(builder, "{sv}", key, g_variant_new_string(val)); - message = g_variant_new("(@a{sv})", g_variant_builder_end(builder)); - - g_dbus_connection_call(connection, - SUPPLICANT_SERVICE, - SUPPLICANT_PATH, - SUPPLICANT_INTERFACE, - "CreateInterface", - message, - NULL, - G_DBUS_CALL_FLAGS_NONE, - NETCONFIG_WPS_DBUS_REPLY_TIMEOUT, - netdbus_get_cancellable(), - (GAsyncReadyCallback) __netconfig_wifi_interface_create_result, - NULL); - - g_variant_unref(message); - - return 0; -} - -static int __netconfig_wifi_bssid_scan(void) -{ - int err = 0; - wifi_tech_state_e wifi_tech_state; - - if (netconfig_is_device_scanning == TRUE) - return -EINPROGRESS; - - wifi_tech_state = wifi_state_get_technology_state(); - if (wifi_tech_state <= NETCONFIG_WIFI_TECH_OFF) - err = wifi_power_driver_and_supplicant(TRUE); - - if (err < 0 && err != -EALREADY) - return err; - - netconfig_is_device_scanning = TRUE; - - DBG("BSSID scan requested"); - if (wifi_tech_state >= NETCONFIG_WIFI_TECH_POWERED) { - if (netconfig_wifi_get_scanning() == TRUE) - return -EINPROGRESS; - - netconfig_wifi_bgscan_start(TRUE); - - if (wifi_tech_state == NETCONFIG_WIFI_TECH_CONNECTED) - __netconfig_wifi_bssid_request_scan(NULL); - } else { - err = __netconfig_wifi_wps_create_interface(); - } - - return err; -} - -gboolean handle_request_bssid_scan(Wifi *wifi, GDBusMethodInvocation *context) -{ - int err, enabled = 0; - wifi_tech_state_e tech_state; - - g_return_val_if_fail(wifi != NULL, FALSE); - - if (netconfig_is_wifi_tethering_on() == TRUE) { - ERR("Wi-Fi Tethering is enabled"); - netconfig_error_dbus_method_return(context, NETCONFIG_ERROR_NO_SERVICE, "TetheringEnabled"); - return -EBUSY; - } - -#if !defined TIZEN_WEARABLE - if (netconfig_wifi_is_bgscan_paused()) { - ERR("Scan is paused"); - netconfig_error_dbus_method_return(context, NETCONFIG_ERROR_NO_SERVICE, "ScanPaused"); - return FALSE; - } -#endif - - tech_state = wifi_state_get_technology_state(); - if (tech_state <= NETCONFIG_WIFI_TECH_OFF) { -#if !defined TIZEN_WEARABLE - enabled = 1; -#else - enabled = 0; -#endif - - if (enabled == 0) { - netconfig_error_permission_denied(context); - return FALSE; - } - } - - __netconfig_wps_set_mode(TRUE); - - err = __netconfig_wifi_bssid_scan(); - if (err < 0) { - if (err == -EINPROGRESS) - netconfig_error_inprogress(context); - else - netconfig_error_wifi_driver_failed(context); - - return FALSE; - } - - wifi_complete_request_bssid_scan(wifi, context); - return TRUE; -} - static void interface_wps_start_result(GObject *source_object, GAsyncResult *res, gpointer user_data) { diff --git a/src/wifi.c b/src/wifi.c index 429a68c..97882e3 100755 --- a/src/wifi.c +++ b/src/wifi.c @@ -30,6 +30,7 @@ #include "neterror.h" #include "wifi-eap.h" #include "wifi-wps.h" +#include "wifi-bssid-scan.h" #include "wifi-power.h" #include "wifi-state.h" #include "wifi-agent.h" -- 2.7.4