Adjust the critical sections of wifi_manager
authorSeongil Hahm <seongil.hahm@samsung.com>
Wed, 20 Sep 2017 07:38:29 +0000 (00:38 -0700)
committerSeongil Hahm <seongil.hahm@samsung.com>
Thu, 21 Sep 2017 03:34:13 +0000 (20:34 -0700)
1. relocate w_mutex to protect g_manager_info and to prevent wifi_utils apis from being called simultaneously
2. add mac_addr in wifi_manager_get_info() api

apps/examples/testcase/ta_tc/wifi_manager/utc/utc_wifi_manager_main.c
framework/include/wifi_manager/wifi_manager.h
framework/src/wifi_manager/wifi_manager.c

index e9e5905..e82cfc8 100644 (file)
@@ -111,7 +111,7 @@ static int wifi_test_signal_init(void)
        return 0;
 }
 
-void wifi_test_signal_deinit(void)
+static void wifi_test_signal_deinit(void)
 {
        pthread_mutex_destroy(&g_wifi_manager_test_mutex);
        pthread_cond_destroy(&g_wifi_manager_test_cond);
@@ -198,6 +198,7 @@ static void utc_wifi_manager_get_mode_p(void)
        wifi_manager_result_e ret = WIFI_MANAGER_FAIL;
        wifi_manager_info_s info;
        int ret_cmp = 0;
+       int i;
 
        ret = wifi_manager_get_info(&info);
 
@@ -218,6 +219,11 @@ static void utc_wifi_manager_get_mode_p(void)
 
        TC_ASSERT_EQ("wifi_manager_get_mode_p", ret, WIFI_MANAGER_SUCCESS);
        TC_ASSERT_EQ("wifi_manager_get_mode_p", info.mode, SOFTAP_MODE);
+       printf("\nMAC Address: ");
+       for (i = 0; i < 5; i++) {
+               printf("%x:", info.mac_address[i]);
+       }
+       printf("%x\n", info.mac_address[5]);
        ret_cmp = strncmp(info.ssid, ap_config.ssid, strlen(CONFIG_EXAMPLES_TESTCASE_WIFI_MANAGER_UTC_SOFTAP_SSID));
        TC_ASSERT_EQ("wifi_manager_get_mode_p", ret_cmp, 0);
 
index 5629c8b..00139ef 100644 (file)
@@ -33,7 +33,10 @@ typedef enum {
 
        // SOFT AP mode status
        CLIENT_CONNECTED,
-       CLIENT_DISCONNECTED
+       CLIENT_DISCONNECTED,
+
+       // Unkown
+       STATUS_UNKNOWN
 } connect_status_e;
 
 /**
@@ -82,10 +85,10 @@ typedef struct {
 typedef struct {
        char ip4_address[18];
        char ssid[32];
+       char mac_address[6];       /**<  MAC address of wifi interface             */
        int rssi;
        connect_status_e status;
        wifi_manager_mode_e mode;
-       wifi_manager_cb_s *wmcb;
 } wifi_manager_info_s;
 
 typedef struct {
index 5879196..89ec492 100644 (file)
@@ -53,7 +53,7 @@ void __tizenrt_manual_linkset(const char *msg)
 #endif
 
 static wifi_manager_info_s g_manager_info;
-
+static wifi_manager_cb_s *g_manager_callback = NULL;
 static wifi_mutex *w_mutex = NULL;
 
 static wifi_utils_result_e start_dhcp_client(void)
@@ -145,7 +145,11 @@ static void wifi_status_set(connect_status_e status)
 
 static void wifi_linkup_event_func(void)
 {
-       wifi_manager_cb_s *wifi_cb = g_manager_info.wmcb;
+       wifi_manager_cb_s *wifi_cb = g_manager_callback;
+       wifi_utils_info info;
+
+       wifi_mutex_acquire(w_mutex, WIFI_UTILS_FOREVER);
+
        if (g_manager_info.mode == STA_MODE) {
                nvdbg("WIFI CONNECTED AP - STA MODE");
                wifi_status_set(AP_CONNECTED);
@@ -153,13 +157,27 @@ static void wifi_linkup_event_func(void)
                /* Perform DHCP client */
                if (start_dhcp_client() != WIFI_UTILS_SUCCESS) {
                        ndbg("DHCP client start failed\n");
+                       wifi_mutex_release(w_mutex);
                        return;
                }
                if (stop_dhcp_client() != WIFI_UTILS_SUCCESS) {
                        ndbg("DHCP client stop failed\n");
                }
 
-               if (wifi_cb != NULL && wifi_cb->sta_connected) {
+               char ip4_add_str[18] = { 0, };
+               if (wifi_utils_get_info(&info) == WIFI_UTILS_SUCCESS) {
+                       wifi_net_ip4_addr_to_ip4_str(info.ip4_address, ip4_add_str);
+                       g_manager_info.rssi = info.rssi;
+                       g_manager_info.status = info.wifi_status;
+               } else {
+                       g_manager_info.rssi = 0;
+                       g_manager_info.status = STATUS_UNKNOWN;
+               }
+               strncpy(g_manager_info.ip4_address, ip4_add_str, 18);
+
+               wifi_mutex_release(w_mutex);
+
+               if (wifi_cb != NULL && wifi_cb->sta_connected != NULL) {
                        wifi_cb->sta_connected();
                } else {
                        ndbg("Callback wifimanager ap_connect failed\n");
@@ -168,10 +186,13 @@ static void wifi_linkup_event_func(void)
                nvdbg("CONNECTED FROM CLIENT - SOFT AP MODE");
                wifi_status_set(CLIENT_CONNECTED);
 
+               wifi_mutex_release(w_mutex);
+
                /* No callbacks here, in case new client joins, we invoke callback
                 * from DHCP server instead
                 */
        }
+
 #ifdef CONFIG_ENABLE_IOTIVITY
        __tizenrt_manual_linkset("gen");
 #endif
@@ -182,7 +203,12 @@ static void wifi_linkup_event_func(void)
 
 static void wifi_linkdown_event_func(void)
 {
-       wifi_manager_cb_s *wifi_cb = g_manager_info.wmcb;
+// here, send a message to callback handler and rest of this function should be done by the callback handler.
+// wifi_manager_init() creates the callback handler and deinit() joins the callback handler.
+       wifi_manager_cb_s *wifi_cb = g_manager_callback;
+
+       wifi_mutex_acquire(w_mutex, WIFI_UTILS_FOREVER);
+
        if (g_manager_info.mode == STA_MODE) {
                nvdbg("WIFI DISCONNECTED AP - STA MODE");
                g_manager_info.ssid[0] = '\0';
@@ -190,7 +216,7 @@ static void wifi_linkdown_event_func(void)
                g_manager_info.rssi = 0;
                wifi_status_set(AP_DISCONNECTED);
 
-               if (wifi_cb != NULL && wifi_cb->sta_disconnected) {
+               if (wifi_cb != NULL && wifi_cb->sta_disconnected != NULL) {
                        wifi_cb->sta_disconnected();
                } else {
                        ndbg("Callback wifimanager ap_disconnected failed\n");
@@ -198,12 +224,15 @@ static void wifi_linkdown_event_func(void)
        } else if (g_manager_info.mode == SOFTAP_MODE) {
                nvdbg("DISCONNECTED FROM CLIENT - SOFT AP MODE");
                wifi_status_set(CLIENT_DISCONNECTED);
-               if (wifi_cb != NULL && wifi_cb->softap_sta_left) {
+               if (wifi_cb != NULL && wifi_cb->softap_sta_left != NULL) {
                        wifi_cb->softap_sta_left();
                } else {
                        ndbg("Callback wifimanager ap_disconnected failed\n");
                }
        }
+
+       wifi_mutex_release(w_mutex);
+
 #ifdef CONFIG_ENABLE_IOTIVITY
        __tizenrt_manual_linkset("del");
 #endif
@@ -274,17 +303,18 @@ static wifi_manager_result_e wifi_fetch_scan_results(slsi_scan_info_t **wifi_sca
 static wifi_manager_result_e wifi_scan_result_callback(slsi_reason_t *reason)
 {
        wifi_manager_scan_info_s *wifi_manager_scan_info = 0;
+       wifi_manager_cb_s *wifi_cb = g_manager_callback;
        if (reason->reason_code == 0) {
                slsi_scan_info_t *wifi_scan_result;
                WiFiGetScanResults(&wifi_scan_result);
                if (wifi_fetch_scan_results(&wifi_scan_result, &wifi_manager_scan_info) == WIFI_MANAGER_SUCCESS) {
-                       g_manager_info.wmcb->scan_ap_done(&wifi_manager_scan_info, WIFI_SCAN_SUCCESS);
+                       wifi_cb->scan_ap_done(&wifi_manager_scan_info, WIFI_SCAN_SUCCESS);
                        wifi_free_scan_results(&wifi_manager_scan_info);
                }
                WiFiFreeScanResults(&wifi_scan_result);
        } else {
                ndbg("Scan failed %d\n");
-               g_manager_info.wmcb->scan_ap_done(&wifi_manager_scan_info, WIFI_SCAN_FAIL);
+               wifi_cb->scan_ap_done(&wifi_manager_scan_info, WIFI_SCAN_FAIL);
                return WIFI_MANAGER_FAIL;
        }
        return WIFI_MANAGER_SUCCESS;
@@ -309,7 +339,10 @@ wifi_manager_result_e wifi_manager_connect_ap(wifi_manager_ap_config_s *config)
        wifi_utils_info info;
        wifi_utils_ap_config_s util_config;
 
-       wifi_utils_get_info(&info);
+       if (wifi_utils_get_info(&info) != WIFI_UTILS_SUCCESS) {
+               ndbg("Wi-Fi info retrival fails.\n");
+               return WIFI_MANAGER_FAIL;
+       }
 
        if (info.wifi_status == WIFI_UTILS_SOFTAP_MODE) {
                ndbg("Current mode soft ap mode, can not connect ap");
@@ -332,14 +365,7 @@ wifi_manager_result_e wifi_manager_connect_ap(wifi_manager_ap_config_s *config)
                return WIFI_MANAGER_FAIL;
        }
 
-       /* g_manager_info.wmcb->sta_connected(); */
-       wifi_utils_get_info(&info);
-
-       char ip4_add_str[18] = { 0, };
-       wifi_net_ip4_addr_to_ip4_str(info.ip4_address, ip4_add_str);
        strncpy(g_manager_info.ssid, config->ssid, config->ssid_length + 1);
-       strncpy(g_manager_info.ip4_address, ip4_add_str, 18);
-       g_manager_info.rssi = info.rssi;
 
        wifi_mutex_release(w_mutex);
 
@@ -360,6 +386,7 @@ wifi_manager_result_e wifi_manager_disconnect_ap(void)
 wifi_manager_result_e wifi_manager_init(wifi_manager_cb_s *wmcb)
 {
        wifi_utils_result_e result = WIFI_UTILS_SUCCESS;
+       wifi_utils_info info;
 
        if (wmcb == NULL) {
                        ndbg("Wi-Fi Manager init fail because of no callbacks");
@@ -372,22 +399,24 @@ wifi_manager_result_e wifi_manager_init(wifi_manager_cb_s *wmcb)
        }
 
        w_mutex = (wifi_mutex *)malloc(sizeof(wifi_mutex));
+       if (w_mutex == NULL) {
+               ndbg("w_mutex malloc fails.\n");
+               return WIFI_MANAGER_FAIL;
+       }
 
        result = wifi_mutex_create(w_mutex);
        if (result != WIFI_UTILS_SUCCESS) {
                ndbg("wifi_mutex_create fail");
-               free(w_mutex);
-               w_mutex = NULL;
-               return WIFI_MANAGER_FAIL;
+               goto error_without_mutex_release;
        }
 
+       wifi_mutex_acquire(w_mutex, WIFI_UTILS_FOREVER);
+
        result = wifi_utils_init();
 
        if (result != WIFI_UTILS_SUCCESS) {
                ndbg("wifi_utils_init fail");
-               free(w_mutex);
-               w_mutex = NULL;
-               return WIFI_MANAGER_FAIL;
+               goto error_with_mutex_release;
        }
 
        wifi_utils_register_callback(wifi_linkup_event_func, wifi_linkdown_event_func);
@@ -395,8 +424,16 @@ wifi_manager_result_e wifi_manager_init(wifi_manager_cb_s *wmcb)
        g_manager_info.ip4_address[0] = '\0';
        g_manager_info.rssi = 0;
        g_manager_info.mode = STA_MODE;
+       g_manager_callback = wmcb;
        wifi_status_set(AP_DISCONNECTED);
-       g_manager_info.wmcb = wmcb;
+
+       if (wifi_utils_get_info(&info) != WIFI_UTILS_SUCCESS) {
+               ndbg("wifi_utils_get_info fail");
+               goto error_with_mutex_release;
+       }
+       strncpy(g_manager_info.mac_address, info.mac_address, 6);
+
+       wifi_mutex_release(w_mutex);
 
 #ifdef CONFIG_ENABLE_IOTIVITY
        struct mq_attr lq_attr;
@@ -407,47 +444,66 @@ wifi_manager_result_e wifi_manager_init(wifi_manager_cb_s *wmcb)
 
        if (g_dw_nwevent_mqfd == (mqd_t)ERROR) {
                ndbg("iotivity connect event message queue init fail");
-               free(w_mutex);
-               w_mutex = NULL;
-               return WIFI_MANAGER_FAIL;
+               goto error_with_mutex_destory;
        }
 #endif
 
        return WIFI_MANAGER_SUCCESS;
+
+error_with_mutex_release:
+       wifi_mutex_release(w_mutex);
+#ifdef CONFIG_ENABLE_IOTIVITY
+error_with_mutex_destory:
+#endif
+               result = wifi_mutex_destroy(w_mutex);
+               if (result != WIFI_UTILS_SUCCESS) {
+                       ndbg("wifi_mutex_destroy fail %d", result);
+                       return WIFI_MANAGER_FAIL;
+               }
+error_without_mutex_release:
+               free(w_mutex);
+               w_mutex = NULL;
+               return WIFI_MANAGER_FAIL;
 }
 
 wifi_manager_result_e wifi_manager_deinit()
 {
        wifi_utils_result_e result = WIFI_UTILS_SUCCESS;
 
-       if (g_manager_info.mode == WIFI_NONE) {
+       if ((g_manager_info.mode == WIFI_NONE) || (w_mutex == NULL)) {
                ndbg("WI-FI is already deinitialized.\n");
                return WIFI_MANAGER_DEINITIALIZED;
        }
 
+       wifi_mutex_acquire(w_mutex, WIFI_UTILS_FOREVER);
+
        if ((g_manager_info.mode == SOFTAP_MODE) && (stop_dhcp_server() != WIFI_UTILS_SUCCESS)) {
                ndbg("dhcp server stop fail\n");
+               wifi_mutex_release(w_mutex);
                return WIFI_MANAGER_FAIL;
        }
 
-       ndbg("w_mutex->semcount: %d, w_mutex->flags: %d\n", w_mutex->semcount, w_mutex->flags);
+       result = wifi_utils_deinit();
 
-       result = wifi_mutex_destroy(w_mutex);
        if (result != WIFI_UTILS_SUCCESS) {
-               ndbg("wifi_mutex_destroy fail %d", result);
+               ndbg("wifi_utils_deinit fail");
+               wifi_mutex_release(w_mutex);
                return WIFI_MANAGER_FAIL;
        }
-       free(w_mutex);
-       w_mutex = NULL;
 
-       result = wifi_utils_deinit();
+       g_manager_info.mode = WIFI_NONE;
+
+       ndbg("w_mutex->semcount: %d, w_mutex->flags: %d\n", w_mutex->semcount, w_mutex->flags);
 
+       wifi_mutex_release(w_mutex);
+
+       result = wifi_mutex_destroy(w_mutex);
        if (result != WIFI_UTILS_SUCCESS) {
-               ndbg("wifi_utils_deinit fail");
+               ndbg("wifi_mutex_destroy fail %d", result);
                return WIFI_MANAGER_FAIL;
        }
-
-       g_manager_info.mode = WIFI_NONE;
+       free(w_mutex);
+       w_mutex = NULL;
 
        return WIFI_MANAGER_SUCCESS;
 }
@@ -461,7 +517,7 @@ wifi_manager_result_e wifi_manager_set_mode(wifi_manager_mode_e mode, wifi_manag
                return WIFI_MANAGER_INVALID_ARGS;
        }
 
-       if ((mode != SOFTAP_MODE) && ((strlen(config->ssid) > 31) || (strlen(config->passphrase) > 63))) {
+       if ((mode == SOFTAP_MODE) && ((strlen(config->ssid) > 31) || (strlen(config->passphrase) > 63))) {
                ndbg("SoftAP configuration fails: too long ssid or passphrase\n");
                ndbg("Make sure that length of SSID < 32 and length of passphrase < 64\n");
                return WIFI_MANAGER_INVALID_ARGS;
@@ -483,7 +539,7 @@ wifi_manager_result_e wifi_manager_set_mode(wifi_manager_mode_e mode, wifi_manag
                softap_config.passphrase_length = strlen(config->passphrase);
                strncpy(softap_config.ssid, config->ssid, softap_config.ssid_length + 1);
                strncpy(softap_config.passphrase, config->passphrase, softap_config.passphrase_length + 1);
-               softap_config.inform_new_sta_join = g_manager_info.wmcb->softap_sta_joined;
+               softap_config.inform_new_sta_join = g_manager_callback->softap_sta_joined;
 
                wifi_mutex_acquire(w_mutex, WIFI_UTILS_FOREVER);
 
@@ -498,6 +554,7 @@ wifi_manager_result_e wifi_manager_set_mode(wifi_manager_mode_e mode, wifi_manag
 
                if (start_dhcp_server() != WIFI_UTILS_SUCCESS) {
                        ndbg("start DHCP server Failed\n");
+                       wifi_mutex_release(w_mutex);
                        return WIFI_MANAGER_FAIL;
                }
 
@@ -558,15 +615,21 @@ wifi_manager_result_e wifi_manager_get_info(wifi_manager_info_s *info)
 wifi_manager_result_e wifi_manager_scan_ap(void)
 {
        wifi_manager_result_e ret = WIFI_MANAGER_FAIL;
-       if (g_manager_info.wmcb->scan_ap_done == NULL) {
+
+       if (g_manager_callback->scan_ap_done == NULL) {
                ndbg("Missing callback for WiFi scan");
                return WIFI_MANAGER_INVALID_ARGS;
        }
 
+       wifi_mutex_acquire(w_mutex, WIFI_UTILS_FOREVER);
+
        WiFiRegisterScanCallback(wifi_scan_result_callback);
        if (WiFiScanNetwork() == SLSI_STATUS_SUCCESS) {
                ndbg("WiFI scan succeeds.");
                ret = WIFI_MANAGER_SUCCESS;
        }
+
+       wifi_mutex_release(w_mutex);
+       
        return ret;
 }