X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2Fwifi-wps.c;h=5f09eb7958012039776dce0ccbf423ac5163df0c;hb=4330e4aa70b3933edb887bd275561652fecd6c53;hp=ac222a04d4dec43245513cdbbf8a411967b8832b;hpb=8f8c2d3c799d334ced79250e995ad22801337255;p=platform%2Fcore%2Fconnectivity%2Fnet-config.git diff --git a/src/wifi-wps.c b/src/wifi-wps.c index ac222a0..5f09eb7 100755 --- a/src/wifi-wps.c +++ b/src/wifi-wps.c @@ -31,515 +31,219 @@ #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_wps_scan_aborted = FALSE; -static int wps_bss_list_count = 0; - -struct wps_bss_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; }; -static GSList *wps_bss_info_list = NULL; +static struct netconfig_wifi_wps wifi_wps; -static void __netconfig_wps_set_mode(gboolean enable) +void netconfig_wifi_notify_wps_credentials(const char *ssid, gsize ssid_len, const char *wps_key) { - if (netconfig_is_wps_enabled == enable) - return; - - netconfig_is_wps_enabled = enable; -} - -gboolean netconfig_wifi_is_wps_enabled(void) -{ - return netconfig_is_wps_enabled; -} - -static void __netconfig_wifi_wps_notify_scan_done(void) -{ - GVariantBuilder *builder = NULL; - GVariantBuilder *builder1 = NULL; - GSList* list = NULL; + GVariantBuilder *builder; + GVariant *params; + const char *sig_name = "WpsCredentials"; const char *prop_ssid = "ssid"; - const char *prop_bssid = "bssid"; - const char *prop_rssi = "rssi"; - const char *prop_mode = "mode"; + const char *prop_key = "key"; + GVariantBuilder *rawssid_builder = NULL; + int i; builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}")); - for (list = wps_bss_info_list; list != NULL; list = list->next) { - struct wps_bss_info_t *bss_info = (struct wps_bss_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_wps_scan_completed((Wifi *)get_wifi_object(), g_variant_builder_end(builder)); + rawssid_builder = g_variant_builder_new(G_VARIANT_TYPE("ay")); + for (i = 0; i < ssid_len; i++) + g_variant_builder_add(rawssid_builder, "y", ssid[i]); + g_variant_builder_add(builder, "{sv}", prop_ssid, g_variant_new("ay", rawssid_builder)); + g_variant_builder_unref(rawssid_builder); + g_variant_builder_add(builder, "{sv}", prop_key, g_variant_new_string(wps_key)); + + params = g_variant_new("(@a{sv})", 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("WpsScanCompleted"); + netconfig_dbus_emit_signal(NULL, + NETCONFIG_WIFI_PATH, + NETCONFIG_WIFI_INTERFACE, + sig_name, + params); + INFO("Sent signal (%s)", sig_name); return; } -static void __netconfig_wifi_wps_get_bss_info_result( - GObject *source_object, GAsyncResult *res, gpointer user_data) +void netconfig_wifi_notify_wps_completed(const char *ssid, gsize ssid_len) { - GVariant *reply = NULL; - GVariant *value; - GVariantIter *iter; - gchar *key; - struct wps_bss_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 wps_bss_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); + GVariantBuilder *builder; + GVariant *params; + const char *sig_name = "WpsCompleted"; + const char *prop_ssid = "ssid"; + GVariantBuilder *rawssid_builder = NULL; + int i; - g_variant_iter_free(iter); -done: - if (reply) - g_variant_unref(reply); + builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}")); + rawssid_builder = g_variant_builder_new(G_VARIANT_TYPE("ay")); + for (i = 0; i < ssid_len; i++) + g_variant_builder_add(rawssid_builder, "y", ssid[i]); + g_variant_builder_add(builder, "{sv}", prop_ssid, g_variant_new("ay", rawssid_builder)); + g_variant_builder_unref(rawssid_builder); - netconfig_gdbus_pending_call_unref(); + params = g_variant_new("(@a{sv})", g_variant_builder_end(builder)); + g_variant_builder_unref(builder); - wps_bss_list_count--; - if (wps_bss_list_count <= 0) { - __netconfig_wifi_wps_notify_scan_done(); + netconfig_dbus_emit_signal(NULL, + NETCONFIG_WIFI_PATH, + NETCONFIG_WIFI_INTERFACE, + sig_name, + params); - if (netconfig_is_wps_scan_aborted == FALSE) - wifi_power_driver_and_supplicant(FALSE); - } + INFO("Sent signal (%s)", sig_name); + return; } -static void __netconfig_wifi_wps_get_bss_info(const char *path, int index) +void netconfig_wifi_notify_wps_fail_event(int config_error, int error_indication) { - gboolean reply = FALSE; - GVariant *param = NULL; + GVariantBuilder *builder; + GVariant *params; + const char *sig_name = "WpsFailEvent"; + const char *prop_config_error = "config_error"; + const char *prop_error_indication = "error_indication"; - param = g_variant_new("(s)", SUPPLICANT_IFACE_BSS); + builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}")); + g_variant_builder_add(builder, "{sv}", prop_config_error, g_variant_new_int32(config_error)); + g_variant_builder_add(builder, "{sv}", prop_error_indication, g_variant_new_int32(error_indication)); - 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"); + params = g_variant_new("(@a{sv})", g_variant_builder_end(builder)); + g_variant_builder_unref(builder); + + netconfig_dbus_emit_signal(NULL, + NETCONFIG_WIFI_PATH, + NETCONFIG_WIFI_INTERFACE, + sig_name, + params); + INFO("Sent signal (%s)", sig_name); return; } -static void __netconfig_wifi_wps_get_bsss_result(GObject *source_object, - GAsyncResult *res, gpointer user_data) +static void interface_wps_start_result(GObject *source_object, + GAsyncResult *res, gpointer user_data) { - GVariant *reply = NULL; - GVariant *value = NULL; - GVariantIter *iter = NULL; + GVariant *reply; 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 (reply == NULL) { + if (error != NULL) { + ERR("Fail to request status [%d: %s]", + error->code, error->message); + g_error_free(error); + } else { + ERR("Fail torequest status"); } + } else { + DBG("Successfully M/W--->WPAS: Interface.WPS.Start Method"); } - if (iter) - g_variant_iter_free(iter); - - if (value) - g_variant_unref(value); - -done: - if (reply) - g_variant_unref(reply); - + g_variant_unref(reply); netconfig_gdbus_pending_call_unref(); - - /* Send WpsScanCompleted 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_wps_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_wps_scan_aborted = TRUE; - _netconfig_wifi_wps_get_bsss(); - - netconfig_is_device_scanning = FALSE; - - __netconfig_wps_set_mode(FALSE); -} - -static int __netconfig_wifi_wps_request_scan(const char *if_path) +static void __netconfig_wifi_invoke_wps_connect(GObject *source_object, + GAsyncResult *res, gpointer user_data) { - GDBusConnection *connection = NULL; GVariant *message = NULL; GVariantBuilder *builder = NULL; - const char *key1 = "Type"; - const char *val1 = "passive"; + const char *role = "enrollee", *type, *key; + const char *if_path = NULL; + gboolean reply = FALSE; 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; + return; } 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_wps_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); + key = "Role"; + g_variant_builder_add(builder, "{sv}", key, g_variant_new_string(role)); - message = g_dbus_connection_call_finish(conn, res, &error); - if (error == NULL) { - g_variant_get(message, "(o)", &path); + key = "Type"; - if (path) { - __netconfig_wifi_wps_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_wps_request_scan(path); - g_free(path); - } - else - __netconfig_wifi_wps_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); - } + if (wifi_wps.pbc == TRUE) + type = "pbc"; + else + type = "pin"; - g_variant_unref(message); -} + g_variant_builder_add(builder, "{sv}", key, g_variant_new_string(type)); -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; + if (wifi_wps.pin != NULL) { + key = "Pin"; + g_variant_builder_add(builder, "{sv}", key, g_variant_new_string(wifi_wps.pin)); } - - 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_variant_builder_unref(builder); - g_dbus_connection_call(connection, + DBG("[net-config]: TizenMW-->WPAS: .Interface.WPS.Start"); + reply = netconfig_supplicant_invoke_dbus_method_nonblock( SUPPLICANT_SERVICE, - SUPPLICANT_PATH, - SUPPLICANT_INTERFACE, - "CreateInterface", + if_path, + SUPPLICANT_IFACE_WPS, + "Start", message, - NULL, - G_DBUS_CALL_FLAGS_NONE, - NETCONFIG_WPS_DBUS_REPLY_TIMEOUT, - netdbus_get_cancellable(), - (GAsyncReadyCallback) __netconfig_wifi_interface_create_result, - NULL); + (GAsyncReadyCallback) interface_wps_start_result); - g_variant_unref(message); + if (reply != TRUE) + ERR("Fail to Scan"); - return 0; + return; } -static int __netconfig_wifi_wps_scan(void) +static gboolean __netconfig_wifi_invoke_wps_process_credentials(const char *object_path) { - 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; + gboolean reply = FALSE; + GVariant *params = NULL; + const char *interface = SUPPLICANT_IFACE_WPS; + const char *key = "ProcessCredentials"; + gboolean credentials = TRUE; + GVariant *var = NULL; - DBG("WPS scan requested"); - if (wifi_tech_state >= NETCONFIG_WIFI_TECH_POWERED) { - if (netconfig_wifi_get_scanning() == TRUE) - return -EINPROGRESS; + var = g_variant_new_boolean(credentials); + params = g_variant_new("(ssv)", interface, key, var); - netconfig_wifi_bgscan_start(TRUE); + INFO("[net-config]: TizenMW-->WPAS: .Set"); + reply = netconfig_invoke_dbus_method_nonblock(SUPPLICANT_SERVICE, + object_path, DBUS_INTERFACE_PROPERTIES, + "Set", params, __netconfig_wifi_invoke_wps_connect); - if (wifi_tech_state == NETCONFIG_WIFI_TECH_CONNECTED) - __netconfig_wifi_wps_request_scan(NULL); - } else { - err = __netconfig_wifi_wps_create_interface(); - } + if (reply != TRUE) + ERR("M/W--->WPAS: Interface.WPS.Set Method Failed"); - return err; + return reply; } -gboolean handle_request_wps_scan(Wifi *wifi, GDBusMethodInvocation *context) +gboolean netconfig_wifi_wps_connect() { - 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; - } + const char *if_path = NULL; -#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 - vconf_get_int(VCONF_WIFI_ALWAYS_ALLOW_SCANNING, &enabled); -#else - enabled = 0; -#endif - - if (enabled == 0) { - netconfig_error_permission_denied(context); - return FALSE; - } + if_path = netconfig_wifi_get_supplicant_interface(); + if (if_path == NULL) { + DBG("Fail to get wpa_supplicant DBus path"); + return FALSE; } - __netconfig_wps_set_mode(TRUE); - - err = __netconfig_wifi_wps_scan(); - if (err < 0) { - if (err == -EINPROGRESS) - netconfig_error_inprogress(context); - else - netconfig_error_wifi_driver_failed(context); + if (__netconfig_wifi_invoke_wps_process_credentials(if_path) == TRUE) { + ERR("Wi-Fi WPS Connect started"); - return FALSE; + return TRUE; } - wifi_complete_request_wps_scan(wifi, context); - return TRUE; + return FALSE; } -#if defined TIZEN_TV static void __interface_wps_cancel_result(GObject *source_object, GAsyncResult *res, gpointer user_data) { @@ -588,16 +292,41 @@ static gboolean __netconfig_wifi_invoke_wps_cancel() return reply; } -#endif -gboolean netconfig_iface_wifi_request_wps_cancel(Wifi *wifi, GDBusMethodInvocation **context) +gboolean netconfig_get_wps_field() +{ + return wifi_wps.pbc; +} + +gboolean handle_request_wps_cancel(Wifi *wifi, GDBusMethodInvocation *context) { -#if defined TIZEN_TV - DBG("Received WPS PBC Cancel Request"); + INFO("Received WPS PBC Cancel Request"); g_return_val_if_fail(wifi != NULL, FALSE); - return __netconfig_wifi_invoke_wps_cancel(); -#else - /*Not supported for mobile and Wearable profile*/ - return FALSE; -#endif + __netconfig_wifi_invoke_wps_cancel(); + + wifi_complete_request_wps_cancel(wifi, context); + return TRUE; +} + +gboolean handle_request_wps_connect(Wifi *wifi, GDBusMethodInvocation *context, gchar *param) +{ + INFO("Received WPS PBC/PIN Connection Request"); + + g_return_val_if_fail(wifi != NULL, FALSE); + + /* Checking the value of pin if param have a string "PBC" + * in that scenario PBC will trigger otherwise PIN Connection */ + + if (g_strcmp0(param, "PBC") == 0) { + wifi_wps.pbc = TRUE; + wifi_wps.pin = NULL; + } else { + wifi_wps.pin = g_strdup(param); + wifi_wps.pbc = FALSE; + } + + netconfig_wifi_wps_connect(); + + wifi_complete_request_wps_connect(wifi, context); + return TRUE; }