Added CAPI for netlink specific AP scan. 41/165141/1
authorNiraj Kumar Goit <niraj.g@samsung.com>
Thu, 14 Dec 2017 12:15:07 +0000 (17:45 +0530)
committertaesub kim <taesub.kim@samsung.com>
Tue, 26 Dec 2017 23:19:55 +0000 (08:19 +0900)
Added CAPI "wifi_manager_netlink_scan_specific_ap" to search
specific AP using netlink scan.

Change-Id: I9dbbdd56ce5baa34e4e9dcfcce03dde9ff18cafa
Signed-off-by: Niraj Kumar Goit <niraj.g@samsung.com>
include/network_dbus.h
include/network_interface.h
include/network_internal.h
include/wifi-manager-extension.h
include/wifi_internal.h
src/network_dbus.c
src/network_interface.c
src/network_signal.c
src/wifi_internal.c
src/wifi_manager.c
test/wifi_manager_test.c

index 8795d271b74377849772ddf7a97b48445b7270e5..787d7d3936e68ed7ce2216a300e40ae193571310 100755 (executable)
@@ -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);
index 7cf91654aa02f8cb36d5cf83a0e2c67f7479ed0c..2076f8eb5b0c4783ac36d34546bb5adddd2e08e1 100755 (executable)
@@ -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);
index 43a607ae99742569404c50b79ff944ac223d1fe3..ba1b47e332c3b12364a757ed075bbd5e1e087d8a 100755 (executable)
@@ -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,
index 7674a139b9db872e2c7469591d1a629e9e1a0371..19db076106e931bfae29d81a40569deb203c17e0 100755 (executable)
@@ -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);
+
 /**
 * @}
 */
index c2ebb3f922834a9a601dea5096cda402203faba8..fa0cc7e5e03dcb02aa72ed503dbea1d1475a31de 100755 (executable)
@@ -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);
index 05ecf6a968664f8e305562f998a10c809bc55e02..d78bffcff42df03c137ad8f6bd13756459641c91 100755 (executable)
@@ -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__;
index eb4620c6650f593af12660ab2d355148e2ecc352..ec6cf572bade4d29fec48b2482ab76f3bbd8a6bf 100755 (executable)
@@ -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__;
index 3ad2a115415446bd1fe7816b613dea6fe60c5173..a46f434dd20595927311dff11db554ab750bbaee 100755 (executable)
@@ -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);
index ba35ee42fe85f558694208b9d0f00b5b695997ae..f515d540fe104dd2ada9dd3a57f99a071d6e8d0b 100755 (executable)
@@ -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)
 {
index f3d5c447caf14925c9c21e394623a3d5504ccbef..32372f0c5c6ac5470361dfb726dcb723ffccceea 100755 (executable)
@@ -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)
index 3b16407019c801d388919060a13eb711d18d51df..d19115484991ec70b1b3fbb7dbc71bb079e38d35 100755 (executable)
@@ -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;
        }