[wifi-manager] Added CAPI to support Multi Specific AP scan. 90/143890/4 submit/tizen/20170821.070104
authorNiraj Kumar Goit <niraj.g@samsung.com>
Sun, 13 Aug 2017 10:43:20 +0000 (16:13 +0530)
committerNiraj Kumar Goit <niraj.g@samsung.com>
Fri, 18 Aug 2017 09:15:41 +0000 (14:45 +0530)
Change-Id: Iba35f619dae3e75b5cbbd8f9cc7cc9da2d417d55
Signed-off-by: Niraj Kumar Goit <niraj.g@samsung.com>
include/network_dbus.h
include/network_interface.h
include/network_internal.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 f2cc15b..2d82d1f 100755 (executable)
@@ -108,6 +108,7 @@ int _net_dbus_specific_scan_request(const char *ssid);
 int _net_dbus_bssid_scan_request(void);
 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);
 
 int _net_dbus_cancel_wps(void);
 int _net_dbus_open_connection_without_ssid();
index 0979f1d..7db48fe 100755 (executable)
@@ -60,6 +60,7 @@ typedef enum {
        NET_EVENT_WIFI_POWER_IND,
        NET_EVENT_WIFI_SPECIFIC_SCAN_RSP,
        NET_EVENT_WIFI_SPECIFIC_SCAN_IND,
+       NET_EVENT_WIFI_MULTI_SCAN_IND,
        NET_EVENT_WIFI_WPS_RSP,
        NET_EVENT_WIFI_SCANNING_IND,
        NET_EVENT_WIFI_BSSID_SCAN_IND,
@@ -249,6 +250,7 @@ int net_bssid_scan_wifi(void);
 int net_wifi_get_passpoint(int *enable);
 int net_wifi_set_passpoint(int enable);
 int net_wifi_get_scan_state(int *scan_state);
+int net_multi_scan_wifi(GSList *specific_scan_list, int type);
 
 int net_wifi_add_vsie(unsigned int frame_id, const char *vsie_str);
 int net_wifi_get_vsie(unsigned int frame_id, char **vsie_str);
index 86d5082..85286ae 100755 (executable)
@@ -115,6 +115,7 @@ typedef enum {
        NETWORK_REQUEST_TYPE_ENROLL_WPS,
        NETWORK_REQUEST_TYPE_SPECIFIC_SCAN,
        NETWORK_REQUEST_TYPE_BSSID_SCAN,
+       NETWORK_REQUEST_TYPE_MULTI_SCAN,
        NETWORK_REQUEST_TYPE_SET_DEFAULT,
        NETWORK_REQUEST_TYPE_RESET_DEFAULT,
        NETWORK_REQUEST_TYPE_TDLS_DISCOVERY,
index 04cd835..161f98f 100755 (executable)
@@ -93,6 +93,7 @@ typedef enum {
        WIFI_SCAN_CHANGED_CB,
        WIFI_SPECIFIC_SCAN_CB,
        WIFI_BSSID_SCAN_CB,
+       WIFI_MULTI_SCAN_CB,
        WIFI_MANAGER_CONNECTION_STATE_CB,
        WIFI_ACTIVATED_CB,
        WIFI_DEACTIVATED_CB,
@@ -103,6 +104,11 @@ typedef enum {
        WIFI_MANAGER_TDLS_DISCOVERED_CB,
 } wifi_manager_handle_cb_e;
 
+typedef enum {
+       WIFI_MULTI_SCAN_SSID,
+       WIFI_MULTI_SCAN_FREQ,
+} wifi_manager_multi_scan_e;
+
 typedef struct {
        int count;
        net_profile_info_s *profiles;
@@ -169,6 +175,8 @@ typedef struct {
        void *tdls_discovered_user_data;
        wifi_manager_module_state_changed_cb module_state_changed_cb;
        void *module_state_changed_user_data;
+       wifi_manager_scan_finished_cb multi_scan_cb;
+       void *multi_scan_user_data;
 
 } wifi_manager_handle_s;
 
@@ -236,6 +244,19 @@ int _wifi_cancel_wps(void);
 int _wifi_bssid_scan_request(wifi_manager_h wifi,
                wifi_manager_bssid_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);
+void _wifi_remove_from_multi_scan_list(wifi_manager_specific_scan_h specific_scan);
+
+int _wifi_specific_scan_create(wifi_manager_specific_scan_h *specific_scan);
+void _wifi_specific_scan_set_ssid(wifi_manager_specific_scan_h specific_scan,
+               const char *ssid);
+void _wifi_specific_scan_set_freq(wifi_manager_specific_scan_h specific_scan,
+               int freq);
+int _wifi_start_multi_scan(wifi_manager_h wifi,
+               wifi_manager_specific_scan_h specific_scan,
+               wifi_manager_scan_finished_cb callback, void *user_data);
+
 /* WIFI Configuration */
 bool _wifi_check_config_validity(wifi_manager_config_h config_h);
 void _wifi_add_to_config_list(wifi_manager_config_h config_h);
index 83fa5af..3826121 100755 (executable)
@@ -2840,3 +2840,47 @@ int _net_dbus_get_autoscanmode(unsigned int *autoscanmode)
 
 //LCOV_EXCL_STOP
 
+int _net_dbus_multi_scan_request(GSList *multi_scan_list, int type)
+{
+       __NETWORK_FUNC_ENTER__;
+
+       net_err_e Error = NET_ERR_NONE;
+       GSList *list = NULL;
+       GVariant *params = NULL;
+       GVariantBuilder *builder;
+       char ssid[NET_WLAN_ESSID_LEN] = {0, };
+       int freq = 0;
+
+       WIFI_LOG(WIFI_INFO, "Number of elements in a list: %d", g_slist_length(multi_scan_list));
+
+       builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
+       if (type == WIFI_MULTI_SCAN_SSID) {
+               for (list = multi_scan_list; list; list = list->next) {
+                       WIFI_LOG(WIFI_INFO, "AP name: %s", (char *)list->data);
+                       g_strlcpy(ssid, (char *)list->data, NET_WLAN_ESSID_LEN);
+
+                       g_variant_builder_add(builder, "{sv}", "SSID", g_variant_new_string(ssid));
+               }
+       } else {
+               for (list = multi_scan_list; list; list = list->next) {
+                       WIFI_LOG(WIFI_INFO, "freq: %d", (int)list->data);
+                       freq = (int)list->data;
+
+                       g_variant_builder_add(builder, "{sv}", "Frequency", g_variant_new_uint16(freq));
+               }
+       }
+
+       params = g_variant_new("(@a{sv})", g_variant_builder_end(builder));
+       g_variant_builder_unref(builder);
+
+       Error = _net_invoke_dbus_method_nonblock(CONNMAN_SERVICE,
+                       CONNMAN_WIFI_TECHNOLOGY_PREFIX,
+                       CONNMAN_TECHNOLOGY_INTERFACE, "SpecificScan", params,
+                       DBUS_REPLY_TIMEOUT, NULL);
+
+       if (Error == NET_ERR_IN_PROGRESS)
+               Error = NET_ERR_NONE; //LCOV_EXCL_LINE
+
+       __NETWORK_FUNC_EXIT__;
+       return Error;
+}
index ddbcd2e..84b2f4e 100755 (executable)
@@ -1443,6 +1443,61 @@ int net_bssid_scan_wifi(void)
        __NETWORK_FUNC_EXIT__;
        return Error;
 }
+
+int net_multi_scan_wifi(GSList *multi_scan_list, int type)
+{
+       __NETWORK_FUNC_ENTER__;
+
+       net_err_e Error = NET_ERR_NONE;
+
+       if (multi_scan_list == NULL) {
+               WIFI_LOG(WIFI_ERROR, "Invalid parameter"); //LCOV_EXCL_LINE
+               __NETWORK_FUNC_EXIT__; //LCOV_EXCL_LINE
+               return NET_ERR_INVALID_PARAM; //LCOV_EXCL_LINE
+       }
+
+       if (NetworkInfo.ref_count < 1) {
+               WIFI_LOG(WIFI_ERROR, "Application is not registered"); //LCOV_EXCL_LINE
+               __NETWORK_FUNC_EXIT__; //LCOV_EXCL_LINE
+               return NET_ERR_APP_NOT_REGISTERED; //LCOV_EXCL_LINE
+       }
+
+       if (request_table[NETWORK_REQUEST_TYPE_MULTI_SCAN].flag == TRUE) {
+               WIFI_LOG(WIFI_ERROR, "Multi Scan request in progress"); //LCOV_EXCL_LINE
+               __NETWORK_FUNC_EXIT__; //LCOV_EXCL_LINE
+               return NET_ERR_IN_PROGRESS; //LCOV_EXCL_LINE
+       }
+
+       if (NetworkInfo.wifi_state == WIFI_OFF) {
+               if ((NetworkInfo.wifi_state = _net_get_wifi_state(&Error)) == WIFI_OFF) {
+                       WIFI_LOG(WIFI_ERROR, "Wi-Fi is powered off!"); //LCOV_EXCL_LINE
+                       __NETWORK_FUNC_EXIT__; //LCOV_EXCL_LINE
+                       return NET_ERR_INVALID_OPERATION; //LCOV_EXCL_LINE
+               }
+       }
+
+       if (_net_dbus_is_pending_call_used() == TRUE) {
+               WIFI_LOG(WIFI_ERROR, "pending call in progress"); //LCOV_EXCL_LINE
+               __NETWORK_FUNC_EXIT__; //LCOV_EXCL_LINE
+               return NET_ERR_INVALID_OPERATION; //LCOV_EXCL_LINE
+       }
+
+       request_table[NETWORK_REQUEST_TYPE_MULTI_SCAN].flag = TRUE;
+
+       Error = _net_dbus_multi_scan_request(multi_scan_list, type);
+       if (Error != NET_ERR_NONE) {
+               WIFI_LOG(WIFI_ERROR, //LCOV_EXCL_LINE
+                               "_net_dbus_multi_scan_request() failed. Error [%s]",
+                               _net_print_error(Error));
+
+               memset(&request_table[NETWORK_REQUEST_TYPE_MULTI_SCAN], 0, //LCOV_EXCL_LINE
+                               sizeof(network_request_table_s));
+       }
+
+       __NETWORK_FUNC_EXIT__;
+       return Error;
+}
+
 int net_get_wps_pin(char **wps_pin)
 {
        net_err_e error = NET_ERR_NONE;
index 2a81f1e..cdc943d 100755 (executable)
@@ -703,6 +703,13 @@ static int __net_handle_scan_done(GVariant *param)
 
                _net_client_callback(&event_data);
 
+       } else if (request_table[NETWORK_REQUEST_TYPE_MULTI_SCAN].flag == TRUE) {
+               memset(&request_table[NETWORK_REQUEST_TYPE_MULTI_SCAN], 0,
+                               sizeof(network_request_table_s));
+
+               _net_dbus_pending_call_unref();
+               event_data.Event = NET_EVENT_WIFI_MULTI_SCAN_IND;
+
        } else if (request_table[NETWORK_REQUEST_TYPE_SCAN].flag == TRUE) {
                memset(&request_table[NETWORK_REQUEST_TYPE_SCAN], 0,
                                sizeof(network_request_table_s));
index 171a8f6..3a0cea0 100755 (executable)
@@ -25,6 +25,7 @@
 
 bool is_disconnect_wps_pbc = false;
 bool is_disconnect_wps_pin = false;
+static int multi_scan_type = -1;
 
 #define WIFI_SECURITY_NONE                     "none"
 #define WIFI_SECURITY_WEP                      "wep"
@@ -34,6 +35,7 @@ bool is_disconnect_wps_pin = false;
 static __thread GSList *wifi_manager_handle_list = NULL;
 static __thread GSList *ap_handle_list = NULL;
 static __thread GSList *config_handle_list = NULL;
+static __thread GSList *multi_scan_handle_list = NULL;
 
 static __thread GSList *profile_iterator = NULL;
 static __thread GSList *specific_profile_iterator = NULL;
@@ -605,6 +607,17 @@ static void __set_bssid_scan_cb(wifi_manager_h wifi,
        }
 }
 
+static void __set_multi_scan_cb(wifi_manager_h wifi,
+               wifi_manager_scan_finished_cb user_cb, void *user_data)
+{
+       wifi_manager_handle_s *local_handle = (wifi_manager_handle_s *)wifi;
+
+       if (user_cb) {
+               local_handle->multi_scan_cb = user_cb;
+               local_handle->multi_scan_user_data = user_data;
+       }
+}
+
 static void __scan_cb(net_event_info_s *event_cb, bool is_requested)
 {
        GSList *list;
@@ -719,6 +732,35 @@ static void __bssid_scan_cb(net_event_info_s *event_cb)
        }
 }
 
+static void __multi_scan_cb(net_event_info_s *event_cb)
+{
+       GSList *list;
+       wifi_manager_error_e error_code = WIFI_MANAGER_ERROR_NONE;
+
+       if (net_check_ref_count() != true) {
+               WIFI_LOG(WIFI_ERROR, "Application is not registered"
+                               "If multi-threaded, thread integrity be broken.");
+               return;
+       }
+
+       if (event_cb->Error != NET_ERR_NONE) {
+               WIFI_LOG(WIFI_ERROR, "Multi Scan failed[%d]", event_cb->Error);
+               error_code = WIFI_MANAGER_ERROR_OPERATION_FAILED;
+       }
+
+       if (_wifi_get_callback_count_from_handle_list(WIFI_MULTI_SCAN_CB)) {
+               for (list = wifi_manager_handle_list; list; list = list->next) {
+                       wifi_manager_handle_s *local_handle = (wifi_manager_handle_s *)list->data;
+                       if (local_handle->multi_scan_cb)
+                               local_handle->multi_scan_cb(error_code, local_handle->multi_scan_user_data);
+
+                       local_handle->multi_scan_cb = NULL;
+                       local_handle->multi_scan_user_data = NULL;
+               }
+               return;
+       }
+}
+
 static void __set_connected_cb(wifi_manager_h wifi,
                wifi_manager_connected_cb user_cb, void *user_data)
 {
@@ -1026,6 +1068,10 @@ static void _wifi_evt_cb(net_event_info_s *event_cb, void *user_data)
                WIFI_LOG(WIFI_INFO, "Received TDLS Disconnected Ind");
                __tdls_state_changed_cb(WIFI_MANAGER_TDLS_STATE_DISCONNECTED, event_cb);
                break;
+       case NET_EVENT_WIFI_MULTI_SCAN_IND:
+               WIFI_LOG(WIFI_INFO, "Got Wi-Fi multi scan IND\n");
+               __multi_scan_cb(event_cb);
+               break;
        default:
                break;
        }
@@ -1149,6 +1195,10 @@ int _wifi_get_callback_count_from_handle_list(wifi_manager_handle_cb_e e)
                        if (local_handle->bssid_scan_cb)
                                ++count;
                        break;
+               case WIFI_MULTI_SCAN_CB:
+                       if (local_handle->multi_scan_cb)
+                               ++count;
+                       break;
                default:
                        break;
                }
@@ -2557,3 +2607,97 @@ void _wifi_module_state_changed_cb(keynode_t *node, void *user_data)
 }
 
 //LCOV_EXCL_STOP
+
+bool _wifi_check_multi_scan_validity(wifi_manager_specific_scan_h specific_scan)
+{
+       GSList *list = NULL;
+
+       if (specific_scan == NULL)
+               return false;
+
+       for (list = multi_scan_handle_list; list; list = list->next)
+               if (specific_scan == list->data) return true;
+
+       return false;
+}
+
+void _wifi_add_to_multi_scan_list(wifi_manager_specific_scan_h *specific_scan)
+{
+       multi_scan_handle_list = g_slist_append(multi_scan_handle_list, *specific_scan);
+}
+
+void _wifi_remove_from_multi_scan_list(wifi_manager_specific_scan_h specific_scan)
+{
+       GSList *list = (GSList *)specific_scan;
+       GSList *multi_scan_list = list->next;
+
+       if (multi_scan_type == WIFI_MULTI_SCAN_SSID)
+               g_slist_free_full(multi_scan_list, g_free);
+
+       multi_scan_handle_list = g_slist_remove(multi_scan_handle_list, specific_scan);
+       g_free(specific_scan);
+       specific_scan = NULL;
+       multi_scan_type = -1;
+}
+
+int _wifi_specific_scan_create(wifi_manager_specific_scan_h *specific_scan)
+{
+       *specific_scan = g_try_malloc0(sizeof(int));
+
+       if (*specific_scan == NULL) {
+               WIFI_LOG(WIFI_ERROR, "Failed to create specific scan handle");
+               return WIFI_MANAGER_ERROR_OUT_OF_MEMORY;
+       }
+
+       WIFI_LOG(WIFI_INFO, "New specific scan handle[%p]", *specific_scan);
+       return WIFI_MANAGER_ERROR_NONE;
+}
+
+void _wifi_specific_scan_set_ssid(wifi_manager_specific_scan_h specific_scan,
+               const char *essid)
+{
+       GSList *list = (GSList *)specific_scan;
+
+       list = g_slist_append(list, g_strdup(essid));
+       multi_scan_type = WIFI_MULTI_SCAN_SSID;
+
+       specific_scan = (wifi_manager_specific_scan_h)list;
+}
+
+void _wifi_specific_scan_set_freq(wifi_manager_specific_scan_h specific_scan,
+               int freq)
+{
+       GSList *list = (GSList *)specific_scan;
+
+       list = g_slist_append(list, GINT_TO_POINTER(freq));
+       multi_scan_type = WIFI_MULTI_SCAN_FREQ;
+
+       specific_scan = (wifi_manager_specific_scan_h)list;
+}
+
+int _wifi_start_multi_scan(wifi_manager_h wifi,
+               wifi_manager_specific_scan_h specific_scan,
+               wifi_manager_scan_finished_cb callback, void *user_data)
+{
+       int rv = -1;
+
+       GSList *multi_scan_list = (GSList *)specific_scan;
+
+       if (multi_scan_type == -1) {
+               WIFI_LOG(WIFI_ERROR, "SSID/Freq not set for multi scan");
+               return WIFI_MANAGER_ERROR_INVALID_OPERATION;
+       }
+
+       rv = net_multi_scan_wifi(multi_scan_list->next, multi_scan_type);
+       if (rv == NET_ERR_ACCESS_DENIED) {
+               WIFI_LOG(WIFI_ERROR, "Access denied"); //LCOV_EXCL_LINE
+               return WIFI_MANAGER_ERROR_PERMISSION_DENIED; //LCOV_EXCL_LINE
+       } else if (rv == NET_ERR_INVALID_OPERATION) {
+               return WIFI_MANAGER_ERROR_INVALID_OPERATION; //LCOV_EXCL_LINE
+       } else if (rv == NET_ERR_NONE) {
+               __set_multi_scan_cb(wifi, callback, user_data);
+               return WIFI_MANAGER_ERROR_NONE;
+       }
+
+       return WIFI_MANAGER_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
+}
index 2f590a2..260a6f6 100755 (executable)
@@ -1010,3 +1010,86 @@ EXPORT_API int wifi_manager_get_vsie_list(wifi_manager_h wifi,
 
        return _wifi_get_vsie_list(callback, user_data);
 }
+
+EXPORT_API int wifi_manager_specific_scan_create(wifi_manager_h wifi,
+               wifi_manager_specific_scan_h *specific_scan)
+{
+       CHECK_FEATURE_SUPPORTED(WIFI_FEATURE);
+       int rv;
+
+       if (!__wifi_check_handle_validity(wifi)) {
+               WIFI_LOG(WIFI_ERROR, "Invalid parameter");
+               return WIFI_MANAGER_ERROR_INVALID_PARAMETER;
+       }
+
+       rv = _wifi_specific_scan_create(specific_scan);
+       if (rv != WIFI_MANAGER_ERROR_NONE) {
+               WIFI_LOG(WIFI_ERROR, "Failed to create handle");
+               return rv;
+       }
+
+       _wifi_add_to_multi_scan_list(specific_scan);
+       return rv;
+}
+
+EXPORT_API int wifi_manager_specific_scan_destroy(wifi_manager_h wifi,
+               wifi_manager_specific_scan_h specific_scan)
+{
+       CHECK_FEATURE_SUPPORTED(WIFI_FEATURE);
+
+       if (!(__wifi_check_handle_validity(wifi)) ||
+                       !(_wifi_check_multi_scan_validity(specific_scan))) {
+               WIFI_LOG(WIFI_ERROR, "Invalid parameter");
+               return WIFI_MANAGER_ERROR_INVALID_PARAMETER;
+       }
+
+       _wifi_remove_from_multi_scan_list(specific_scan);
+       return WIFI_MANAGER_ERROR_NONE;
+}
+
+EXPORT_API int wifi_manager_specific_scan_set_ssid(wifi_manager_specific_scan_h specific_scan,
+               const char *essid)
+{
+       CHECK_FEATURE_SUPPORTED(WIFI_FEATURE);
+
+       if (!(_wifi_check_multi_scan_validity(specific_scan)) ||
+                       essid == NULL) {
+               WIFI_LOG(WIFI_ERROR, "Invalid parameter");
+               return WIFI_MANAGER_ERROR_INVALID_PARAMETER;
+       }
+
+       _wifi_specific_scan_set_ssid(specific_scan, essid);
+
+       return WIFI_MANAGER_ERROR_NONE;
+}
+
+EXPORT_API int wifi_manager_specific_scan_set_freq(wifi_manager_specific_scan_h specific_scan,
+               int freq)
+{
+       CHECK_FEATURE_SUPPORTED(WIFI_FEATURE);
+
+       if (!_wifi_check_multi_scan_validity(specific_scan)) {
+               WIFI_LOG(WIFI_ERROR, "Invalid parameter");
+               return WIFI_MANAGER_ERROR_INVALID_PARAMETER;
+       }
+
+       _wifi_specific_scan_set_freq(specific_scan, freq);
+
+       return WIFI_MANAGER_ERROR_NONE;
+}
+
+EXPORT_API int wifi_manager_specific_ap_start_multi_scan(wifi_manager_h wifi,
+               wifi_manager_specific_scan_h specific_scan,
+               wifi_manager_scan_finished_cb callback, void *user_data)
+{
+       CHECK_FEATURE_SUPPORTED(WIFI_FEATURE);
+       WIFI_LOG(WIFI_ERROR, "specific scan handle %p", specific_scan);
+
+       if (!(__wifi_check_handle_validity(wifi)) ||
+               !(_wifi_check_multi_scan_validity(specific_scan)) || callback == NULL) {
+               WIFI_LOG(WIFI_ERROR, "Invalid parameter");
+               return WIFI_MANAGER_ERROR_INVALID_PARAMETER;
+       }
+
+       return _wifi_start_multi_scan(wifi, specific_scan, callback, user_data);
+}
index 68afa22..574e092 100755 (executable)
@@ -1284,6 +1284,12 @@ static void __test_scan_specific_ap_callback(wifi_manager_error_e error_code, vo
        }
 }
 
+static void __test_multi_scan_callback(wifi_manager_error_e error_code, void* user_data)
+{
+       printf("Multi scan Completed, error code : %s\n",
+                       __test_convert_error_to_string(error_code));
+}
+
 int test_wifi_manager_init(void)
 {
        int rv = wifi_manager_initialize(&wifi);
@@ -2381,6 +2387,79 @@ int test_wifi_manager_remove_vsie(void)
        return 1;
 }
 
+int test_wifi_manager_specific_ap_start_multi_scan(void)
+{
+       int rv = 0, scan_type, num = 0;
+       char ssid[32 + 1];
+       int freq;
+       int i;
+       wifi_manager_specific_scan_h specific_scan = NULL;
+
+       rv = wifi_manager_specific_scan_create(wifi, &specific_scan);
+       if (rv != WIFI_MANAGER_ERROR_NONE) {
+               printf("Failed to create specific scan handle [%s]", __test_convert_error_to_string(rv));
+               return -1;
+       }
+
+       printf("Specific Scan handle created [%p]\n", specific_scan);
+
+       rv = test_get_user_int("Input multi scan type"
+                       "(0:SSID, 1:Freq):", &scan_type);
+
+       if (rv == false || (scan_type != 0 && scan_type != 1)) {
+               printf("Invalid input!!\n");
+               return false;
+       }
+
+       rv = test_get_user_int("No. of specific ssid/freq for multi scan",
+                       &num);
+       if (rv == false || (num <= 0)) {
+               printf("Invalid input!!\n");
+               return false;
+       }
+
+       if (scan_type == 0) {
+               for (i = 0; i < num; i++) {
+                       printf("Input ssid[%d]:\n", i);
+                       rv = scanf("%32s", ssid);
+
+                       rv = wifi_manager_specific_scan_set_ssid(specific_scan, ssid);
+                       if (rv != WIFI_MANAGER_ERROR_NONE) {
+                               printf("Failed to set ssid [%s]", __test_convert_error_to_string(rv));
+                               return -1;
+                       }
+               }
+       } else {
+               for (i = 0; i < num; i++) {
+                       printf("Input freq[%d]:\n", i);
+                       rv = scanf("%d", &freq);
+                       rv = wifi_manager_specific_scan_set_freq(specific_scan, freq);
+                       if (rv != WIFI_MANAGER_ERROR_NONE) {
+                               printf("Failed to set freq [%s]", __test_convert_error_to_string(rv));
+                               return -1;
+                       }
+               }
+       }
+
+       rv = wifi_manager_specific_ap_start_multi_scan(wifi, specific_scan,
+                       __test_multi_scan_callback, NULL);
+       if (rv != WIFI_MANAGER_ERROR_NONE) {
+               printf("Failed to start multi scan[%s]", __test_convert_error_to_string(rv));
+               return -1;
+       }
+       printf("Specific Multi Scan requested\n");
+
+       rv = wifi_manager_specific_scan_destroy(wifi, specific_scan);
+       if (rv != WIFI_MANAGER_ERROR_NONE) {
+               printf("Failed to destroy specific scan handle [%s]", __test_convert_error_to_string(rv));
+               return -1;
+       }
+
+       printf("Specific Scan handle destroyed\n");
+
+       return 1;
+}
+
 int main(int argc, char **argv)
 {
        GMainLoop *mainloop;
@@ -2465,6 +2544,7 @@ gboolean test_thread(GIOChannel *source, GIOCondition condition, gpointer data)
                printf("F   - Add VSIE\n");
                printf("G   - Get VSIE\n");
                printf("H   - Remove VSIE\n");
+               printf("I   - Start Multi Scan\n");
                printf(LOG_RED "0   - Exit \n" LOG_END);
 
                printf("ENTER  - Show options menu.......\n");
@@ -2602,6 +2682,9 @@ gboolean test_thread(GIOChannel *source, GIOCondition condition, gpointer data)
        case 'H':
                rv = test_wifi_manager_remove_vsie();
                break;
+       case 'I':
+               rv = test_wifi_manager_specific_ap_start_multi_scan();
+               break;
        default:
                break;
        }