From: Niraj Kumar Goit Date: Thu, 14 Dec 2017 12:15:07 +0000 (+0530) Subject: Added CAPI for netlink specific AP scan. X-Git-Tag: submit/tizen_4.0/20171227.021428~3 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=249113c687e36827fab414e88a838bc64d18a76b;p=platform%2Fcore%2Fapi%2Fwifi-manager.git Added CAPI for netlink specific AP scan. Added CAPI "wifi_manager_netlink_scan_specific_ap" to search specific AP using netlink scan. Change-Id: I9dbbdd56ce5baa34e4e9dcfcce03dde9ff18cafa Signed-off-by: Niraj Kumar Goit --- diff --git a/include/network_dbus.h b/include/network_dbus.h index 8795d27..787d7d3 100755 --- a/include/network_dbus.h +++ b/include/network_dbus.h @@ -108,6 +108,7 @@ int _net_dbus_remove_wifi_driver(void); int _net_dbus_specific_scan_request(const char *ssid); int _net_dbus_bssid_scan_request(void); int _net_dbus_netlink_scan_request(void); +int _net_dbus_netlink_scan_specific_ap(const char *essid); int _net_dbus_get_passpoint(int *enabled); int _net_dbus_set_passpoint(int enable); int _net_dbus_multi_scan_request(GSList *multi_scan_list, int type); diff --git a/include/network_interface.h b/include/network_interface.h index 7cf9165..2076f8e 100755 --- a/include/network_interface.h +++ b/include/network_interface.h @@ -66,6 +66,7 @@ typedef enum { NET_EVENT_WIFI_SCANNING_IND, NET_EVENT_WIFI_BSSID_SCAN_IND, NET_EVENT_WIFI_NETLINK_SCAN_IND, + NET_EVENT_WIFI_NETLINK_SCAN_SPECIFIC_AP_IND, NET_EVENT_WIFI_IP_CONFLICT_IND, NET_EVENT_WIFI_TDLS_DISCOVERED_IND, NET_EVENT_WIFI_TDLS_CONNECTED_IND, @@ -261,7 +262,7 @@ int net_init_profile_info(net_profile_info_s *ProfInfo); int net_specific_scan_wifi(const char *ssid); int net_get_wps_pin(char **wps_pin); int net_bssid_scan_wifi(int activated); -int net_netlink_scan_wifi(void); +int net_netlink_scan_wifi(const char *essid); int net_wifi_get_passpoint(int *enable); int net_wifi_set_passpoint(int enable); int net_wifi_get_scan_state(int *scan_state); diff --git a/include/network_internal.h b/include/network_internal.h index 43a607a..ba1b47e 100755 --- a/include/network_internal.h +++ b/include/network_internal.h @@ -120,6 +120,7 @@ typedef enum { NETWORK_REQUEST_TYPE_SPECIFIC_SCAN, NETWORK_REQUEST_TYPE_BSSID_SCAN, NETWORK_REQUEST_TYPE_NETLINK_SCAN, + NETWORK_REQUEST_TYPE_NETLINK_SCAN_SPECIFIC_AP, NETWORK_REQUEST_TYPE_IP_CONFLICT, NETWORK_REQUEST_TYPE_MULTI_SCAN, NETWORK_REQUEST_TYPE_SET_DEFAULT, diff --git a/include/wifi-manager-extension.h b/include/wifi-manager-extension.h index 7674a13..19db076 100755 --- a/include/wifi-manager-extension.h +++ b/include/wifi-manager-extension.h @@ -264,6 +264,28 @@ typedef void(*wifi_manager_netlink_scan_finished_cb)(wifi_manager_error_e error_ int wifi_manager_foreach_found_netlink_scan_ap(wifi_manager_h wifi, wifi_manager_found_ap_cb callback, void *user_data); +/** + * @brief Gets the result of the netlink specific AP scan. + * @details If tethering is enabled in device then wlan interface is available but + * wifi module is in deactivated state and wpa-supplicant service is not active. So + * in this case to search specific AP wifi_manager_netlink_scan_specific_ap() API will be used. + * @since_tizen 5.0 + * @privlevel public + * @privilege %http://tizen.org/privilege/network.get + * @param[in] wifi The Wi-Fi handle + * @param[in] callback The callback to be called + * @param[in] user_data The user data passed to the callback function + * @return 0 on success, otherwise negative error value + * @retval #WIFI_MANAGER_ERROR_NONE Successful + * @retval #WIFI_MANAGER_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #WIFI_MANAGER_ERROR_OPERATION_FAILED Operation failed + * @retval #WIFI_MANAGER_ERROR_NOT_SUPPORTED Not supported + * @post This function invokes wifi_manager_found_ap_cb(). + * @see wifi_manager_netlink_scan_specific_ap() + */ +int wifi_manager_foreach_found_netlink_scan_specific_ap(wifi_manager_h wifi, + wifi_manager_found_ap_cb callback, void *user_data); + /** * @brief Starts netlink scan asynchronously. * @details If tethering is enabled in device then wlan interface is available but @@ -289,6 +311,31 @@ int wifi_manager_foreach_found_netlink_scan_ap(wifi_manager_h wifi, int wifi_manager_netlink_scan(wifi_manager_h wifi, wifi_manager_netlink_scan_finished_cb callback, void *user_data); +/** + * @brief Starts netlink specific AP scan asynchronously. + * @details If tethering is enabled in device then wlan interface is available but + * wifi module is in deactivated state and wpa-supplicant service is not active. So + * in this case to search specific AP use wifi_manager_netlink_scan_specific_ap() API. + * @since_tizen 5.0 + * @privlevel public + * @privilege %http://tizen.org/privilege/network.set \n + * %http://tizen.org/privilege/network.get + * @remarks This function needs both privileges. + * @param[in] wifi The Wi-Fi handle + * @param[in] callback The callback function to be called + * @param[in] user_data The user data passed to the callback function + * @return 0 on success, otherwise negative error value + * @retval #WIFI_MANAGER_ERROR_NONE Successful + * @retval #WIFI_MANAGER_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #WIFI_MANAGER_ERROR_INVALID_OPERATION Invalid operation + * @retval #WIFI_MANAGER_ERROR_OPERATION_FAILED Operation failed + * @retval #WIFI_MANAGER_ERROR_PERMISSION_DENIED Permission Denied + * @retval #WIFI_MANAGER_ERROR_NOT_SUPPORTED Not supported + * @post This function invokes wifi_manager_netlink_scan_finished_cb(). + */ +int wifi_manager_netlink_scan_specific_ap(wifi_manager_h wifi, + const char* essid, wifi_manager_netlink_scan_finished_cb callback, void *user_data); + /** * @} */ diff --git a/include/wifi_internal.h b/include/wifi_internal.h index c2ebb3f..fa0cc7e 100755 --- a/include/wifi_internal.h +++ b/include/wifi_internal.h @@ -228,6 +228,8 @@ int _wifi_foreach_found_ap(wifi_manager_found_ap_cb callback, void *user_data); int _wifi_foreach_found_specific_ap(wifi_manager_found_ap_cb callback, void *user_data); int _wifi_foreach_found_bssid_ap(wifi_manager_found_ap_cb callback, void *user_data); int _wifi_foreach_found_netlink_scan_ap(wifi_manager_found_ap_cb callback, void *user_data); +int _wifi_foreach_found_netlink_scan_specific_ap(wifi_manager_found_ap_cb callback, + void *user_data); int _wifi_open_profile(wifi_manager_h wifi, wifi_manager_ap_h ap_h, wifi_manager_connected_cb callback, void *user_data); @@ -252,6 +254,8 @@ int _wifi_bssid_scan_request(wifi_manager_h wifi, wifi_manager_bssid_scan_finished_cb callback, void *user_data); int _wifi_netlink_scan_request(wifi_manager_h wifi, wifi_manager_netlink_scan_finished_cb callback, void *user_data); +int _wifi_netlink_scan_specific_ap(wifi_manager_h wifi, const char *essid, + wifi_manager_netlink_scan_finished_cb callback, void *user_data); bool _wifi_check_multi_scan_validity(wifi_manager_specific_scan_h specific_scan); void _wifi_add_to_multi_scan_list(wifi_manager_specific_scan_h *specific_scan); diff --git a/src/network_dbus.c b/src/network_dbus.c index 05ecf6a..d78bffc 100755 --- a/src/network_dbus.c +++ b/src/network_dbus.c @@ -585,19 +585,26 @@ static void __net_netlink_scan_wifi_reply(GObject *source_object, GAsyncResult * if (request_table[NETWORK_REQUEST_TYPE_NETLINK_SCAN].flag == TRUE) { memset(&request_table[NETWORK_REQUEST_TYPE_NETLINK_SCAN], 0, sizeof(network_request_table_s)); - event_data.Event = NET_EVENT_WIFI_NETLINK_SCAN_IND; - event_data.Datalength = 0; - event_data.Data = NULL; - event_data.Error = Error; - _net_dbus_pending_call_unref(); + } else if (request_table[NETWORK_REQUEST_TYPE_NETLINK_SCAN_SPECIFIC_AP].flag == TRUE) { + memset(&request_table[NETWORK_REQUEST_TYPE_NETLINK_SCAN_SPECIFIC_AP], + 0, sizeof(network_request_table_s)); + event_data.Event = NET_EVENT_WIFI_NETLINK_SCAN_SPECIFIC_AP_IND; + } else { + /** Do Nothing. */ + } - _net_client_callback(&event_data); + event_data.Datalength = 0; + event_data.Data = NULL; + event_data.Error = Error; - __NETWORK_FUNC_EXIT__; - return; - } + _net_dbus_pending_call_unref(); + + _net_client_callback(&event_data); + + __NETWORK_FUNC_EXIT__; + return; } else WIFI_LOG(WIFI_INFO, "netlink scan succeed"); @@ -1995,6 +2002,22 @@ int _net_dbus_netlink_scan_request(void) return Error; } +int _net_dbus_netlink_scan_specific_ap(const char *essid) +{ + __NETWORK_FUNC_ENTER__; + net_err_e Error = NET_ERR_NONE; + GVariant *params = NULL; + + params = g_variant_new("(s)", essid); + Error = _net_invoke_dbus_method_nonblock(NETCONFIG_SERVICE, + NETCONFIG_WIFI_PATH, NETCONFIG_WIFI_INTERFACE, + "NetlinkSpecificScan", params, 6 * DBUS_REPLY_TIMEOUT, + __net_netlink_scan_wifi_reply); + + __NETWORK_FUNC_EXIT__; + return Error; +} + int _net_dbus_get_passpoint(int *enabled) { __NETWORK_FUNC_ENTER__; diff --git a/src/network_interface.c b/src/network_interface.c index eb4620c..ec6cf57 100755 --- a/src/network_interface.c +++ b/src/network_interface.c @@ -1550,7 +1550,7 @@ int net_bssid_scan_wifi(int activated) return Error; } -int net_netlink_scan_wifi(void) +int net_netlink_scan_wifi(const char *essid) { __NETWORK_FUNC_ENTER__; @@ -1571,17 +1571,26 @@ int net_netlink_scan_wifi(void) return NET_ERR_INVALID_OPERATION; } - request_table[NETWORK_REQUEST_TYPE_NETLINK_SCAN].flag = TRUE; + if (!essid) { + request_table[NETWORK_REQUEST_TYPE_NETLINK_SCAN].flag = TRUE; - Error = _net_dbus_netlink_scan_request(); + Error = _net_dbus_netlink_scan_request(); + } else { + request_table[NETWORK_REQUEST_TYPE_NETLINK_SCAN_SPECIFIC_AP].flag = TRUE; + Error = _net_dbus_netlink_scan_specific_ap(essid); + } if (Error != NET_ERR_NONE) { WIFI_LOG(WIFI_ERROR, - "_net_dbus_netlink_scan_request() failed. Error [%s]", + "netlink dbus request failed. Error [%s]", _net_print_error(Error)); - memset(&request_table[NETWORK_REQUEST_TYPE_NETLINK_SCAN], 0, - sizeof(network_request_table_s)); + if (request_table[NETWORK_REQUEST_TYPE_NETLINK_SCAN].flag) + memset(&request_table[NETWORK_REQUEST_TYPE_NETLINK_SCAN], 0, + sizeof(network_request_table_s)); + else + memset(&request_table[NETWORK_REQUEST_TYPE_NETLINK_SCAN_SPECIFIC_AP], 0, + sizeof(network_request_table_s)); } __NETWORK_FUNC_EXIT__; diff --git a/src/network_signal.c b/src/network_signal.c index 3ad2a11..a46f434 100755 --- a/src/network_signal.c +++ b/src/network_signal.c @@ -398,6 +398,18 @@ static int __net_handle_netlink_scan_resp(GSList *bss_info_list) event_data.Datalength = count; event_data.Data = bss_info_list; + _net_client_callback(&event_data); + } else if (request_table[NETWORK_REQUEST_TYPE_NETLINK_SCAN_SPECIFIC_AP].flag == TRUE) { + memset(&request_table[NETWORK_REQUEST_TYPE_NETLINK_SCAN], + 0, sizeof(network_request_table_s)); + + _net_dbus_pending_call_unref(); + count = (int)g_slist_length(bss_info_list); + + event_data.Event = NET_EVENT_WIFI_NETLINK_SCAN_SPECIFIC_AP_IND; + event_data.Datalength = count; + event_data.Data = bss_info_list; + _net_client_callback(&event_data); } else g_slist_free_full(bss_info_list, g_free); diff --git a/src/wifi_internal.c b/src/wifi_internal.c index ba35ee4..f515d54 100755 --- a/src/wifi_internal.c +++ b/src/wifi_internal.c @@ -1171,6 +1171,7 @@ static void _wifi_evt_cb(net_event_info_s *event_cb, void *user_data) __ip_conflict_cb(event_cb); break; case NET_EVENT_WIFI_NETLINK_SCAN_IND: + case NET_EVENT_WIFI_NETLINK_SCAN_SPECIFIC_AP_IND: WIFI_LOG(WIFI_INFO, "Got NETLINK scan done IND\n"); __netlink_scan_cb(event_cb); break; @@ -1788,7 +1789,7 @@ int _wifi_netlink_scan_request(wifi_manager_h wifi, } } - rv = net_netlink_scan_wifi(); + rv = net_netlink_scan_wifi(NULL); if (rv == NET_ERR_ACCESS_DENIED) { WIFI_LOG(WIFI_ERROR, "Access denied"); @@ -1804,6 +1805,40 @@ int _wifi_netlink_scan_request(wifi_manager_h wifi, return WIFI_MANAGER_ERROR_OPERATION_FAILED; } +int _wifi_netlink_scan_specific_ap(wifi_manager_h wifi, const char *essid, + wifi_manager_netlink_scan_finished_cb callback, void *user_data) +{ + int rv; + wifi_manager_device_state_e device_state; + + /** When tethering is enabled wlan interface is available but wifi device is + in deactivated state and so to search specific AP wifi_manager_netlink_scan_specific_ap() + API is used. When wifi device is in activated state use wifi_manager_scan_specific_ap() API instead. */ + rv = _wifi_get_wifi_device_state(&device_state); + if (rv == WIFI_MANAGER_ERROR_NONE) { + if (WIFI_MANAGER_DEVICE_STATE_ACTIVATED == device_state) { + WIFI_LOG(WIFI_ERROR, "Invalid Operation, Device state activated."); + return WIFI_MANAGER_ERROR_INVALID_OPERATION; + } + } + + rv = net_netlink_scan_wifi(essid); + + if (rv == NET_ERR_ACCESS_DENIED) { + WIFI_LOG(WIFI_ERROR, "Access denied"); + return WIFI_MANAGER_ERROR_PERMISSION_DENIED; + } else if (rv == NET_ERR_INVALID_OPERATION) { + return WIFI_MANAGER_ERROR_INVALID_OPERATION; + } else if (rv == NET_ERR_NONE) { + g_strlcpy(specific_profile_essid, essid, NET_WLAN_ESSID_LEN+1); + __set_netlink_scan_cb(wifi, callback, user_data); + return WIFI_MANAGER_ERROR_NONE; + } + + WIFI_LOG(WIFI_ERROR, "Operation Failed"); + return WIFI_MANAGER_ERROR_OPERATION_FAILED; +} + //LCOV_EXCL_START int _wifi_add_vsie(wifi_manager_h wifi, wifi_manager_vsie_frames_e frame_id, const char *vsie_str) @@ -2143,6 +2178,28 @@ int _wifi_foreach_found_netlink_scan_ap(wifi_manager_found_ap_cb callback, void return WIFI_MANAGER_ERROR_NONE; } +int _wifi_foreach_found_netlink_scan_specific_ap(wifi_manager_found_ap_cb callback, void *user_data) +{ + int rv; + GSList *list; + + if (bss_profile_iterator == NULL) { + WIFI_LOG(WIFI_ERROR, "Failed to search APs"); + return WIFI_MANAGER_ERROR_OPERATION_FAILED; + } + + for (list = bss_profile_iterator; list; list = list->next) { + net_profile_info_s *prof_info = (net_profile_info_s *)list->data; + if (!g_strcmp0(specific_profile_essid, prof_info->essid)) { + rv = callback((wifi_manager_ap_h)prof_info, user_data); + if (rv == false) break; + } + } + + __clear_profile_list(&bss_profile_iterator); + return WIFI_MANAGER_ERROR_NONE; +} + int _wifi_open_profile(wifi_manager_h wifi, wifi_manager_ap_h ap_h, wifi_manager_connected_cb callback, void *user_data) { diff --git a/src/wifi_manager.c b/src/wifi_manager.c index f3d5c44..32372f0 100755 --- a/src/wifi_manager.c +++ b/src/wifi_manager.c @@ -613,6 +613,23 @@ EXPORT_API int wifi_manager_foreach_found_netlink_scan_ap(wifi_manager_h wifi, return _wifi_foreach_found_netlink_scan_ap(callback, user_data); } +EXPORT_API int wifi_manager_foreach_found_netlink_scan_specific_ap(wifi_manager_h wifi, + wifi_manager_found_ap_cb callback, void *user_data) +{ + __NETWORK_CAPI_FUNC_ENTER__; + + CHECK_FEATURE_SUPPORTED(WIFI_FEATURE); + + if (callback == NULL || !(__wifi_check_handle_validity(wifi))) { + WIFI_LOG(WIFI_ERROR, "Invalid parameter"); //LCOV_EXCL_LINE + __NETWORK_CAPI_FUNC_EXIT__; //LCOV_EXCL_LINE + return WIFI_MANAGER_ERROR_INVALID_PARAMETER; //LCOV_EXCL_LINE + } + + __NETWORK_CAPI_FUNC_EXIT__; + return _wifi_foreach_found_netlink_scan_specific_ap(callback, user_data); +} + EXPORT_API int wifi_manager_connect(wifi_manager_h wifi, wifi_manager_ap_h ap, wifi_manager_connected_cb callback, void *user_data) { @@ -1298,6 +1315,29 @@ EXPORT_API int wifi_manager_netlink_scan(wifi_manager_h wifi, return _wifi_netlink_scan_request(wifi, callback, user_data); } +EXPORT_API int wifi_manager_netlink_scan_specific_ap(wifi_manager_h wifi, + const char* essid, wifi_manager_netlink_scan_finished_cb callback, void *user_data) +{ + __NETWORK_CAPI_FUNC_ENTER__; + + CHECK_FEATURE_SUPPORTED(WIFI_FEATURE); + int rv; + + if (!(__wifi_check_handle_validity(wifi)) || + essid == NULL || callback == NULL) { + WIFI_LOG(WIFI_ERROR, "Invalid parameter"); + __NETWORK_CAPI_FUNC_EXIT__; //LCOV_EXCL_LINE + return WIFI_MANAGER_ERROR_INVALID_PARAMETER; + } + + rv = _wifi_netlink_scan_specific_ap(wifi, essid, callback, user_data); + if (rv != WIFI_MANAGER_ERROR_NONE) + WIFI_LOG(WIFI_ERROR, "Wi-Fi hidden scan failed.\n"); + + __NETWORK_CAPI_FUNC_EXIT__; + return rv; +} + //LCOV_EXCL_START EXPORT_API int wifi_manager_add_vsie(wifi_manager_h wifi, wifi_manager_vsie_frames_e frame_id, const char *vsie_str) diff --git a/test/wifi_manager_test.c b/test/wifi_manager_test.c index 3b16407..d191154 100755 --- a/test/wifi_manager_test.c +++ b/test/wifi_manager_test.c @@ -44,6 +44,7 @@ wifi_manager_h wifi2 = NULL; gboolean test_thread(GIOChannel *source, GIOCondition condition, gpointer data); int test_wifi_manager_foreach_bssid_scan(void); int test_wifi_manager_foreach_netlink_scan(void); +int test_wifi_manager_foreach_netlink_scan_specific_ap(void); static const char *__test_convert_error_to_string(wifi_manager_error_e err_type) { @@ -161,6 +162,15 @@ static void __test_netlink_scan_request_callback(wifi_manager_error_e error_code test_wifi_manager_foreach_netlink_scan(); } +static void __test_netlink_scan_specific_ap_callback(wifi_manager_error_e error_code, void *user_data) +{ + printf("Netlink Specific Scan Completed, error code : %s\n", + __test_convert_error_to_string(error_code)); + + if (error_code == WIFI_MANAGER_ERROR_NONE) + test_wifi_manager_foreach_netlink_scan_specific_ap(); +} + static void __test_connection_state_callback(wifi_manager_connection_state_e state, wifi_manager_ap_h ap, void* user_data) { int rv = 0; @@ -2573,6 +2583,43 @@ int test_wifi_manager_netlink_scan(void) return 1; } +int test_wifi_manager_foreach_netlink_scan_specific_ap(void) +{ + int rv; + + rv = wifi_manager_foreach_found_netlink_scan_specific_ap(wifi, + __test_get_netlink_scan_list, NULL); + if (rv != WIFI_MANAGER_ERROR_NONE) { + printf("Failed to get netlink scan list [%s]\n", + __test_convert_error_to_string(rv)); + return -1; + } + + return 1; +} + +int test_wifi_manager_netlink_scan_specific_ap(void) +{ + int rv = 0; + char ap_name[33]; + + printf("Input a part of specific AP name to connect: "); + rv = scanf("%32s", ap_name); + if (rv <= 0) + return -1; + + rv = wifi_manager_netlink_scan_specific_ap(wifi, ap_name, + __test_netlink_scan_specific_ap_callback, NULL); + if (rv != WIFI_MANAGER_ERROR_NONE) { + printf("Fail to request netlink specific scan [%s]\n", + __test_convert_error_to_string(rv)); + return -1; + } + + printf("netlink specific scan request succeeded\n"); + return 1; +} + int test_wifi_manager_get_scan_state(void) { int rv = 0; @@ -2950,6 +2997,7 @@ gboolean test_thread(GIOChannel *source, GIOCondition condition, gpointer data) printf("R - Set the IP conflict detection period\n"); printf("S - Get the IP conflict detection period\n"); printf("T - Netlink Scan\n"); + printf("U - Netlink Specific Scan\n"); printf(LOG_RED "0 - Exit \n" LOG_END); printf("ENTER - Show options menu.......\n"); @@ -3123,6 +3171,9 @@ gboolean test_thread(GIOChannel *source, GIOCondition condition, gpointer data) case 'T': rv = test_wifi_manager_netlink_scan(); break; + case 'U': + rv = test_wifi_manager_netlink_scan_specific_ap(); + break; default: break; }