Use mutex to avoid destroying the wifi handle during event processing 05/249305/2
authorJaehyun Kim <jeik01.kim@samsung.com>
Wed, 9 Dec 2020 13:21:07 +0000 (22:21 +0900)
committerJaehyun Kim <jeik01.kim@samsung.com>
Fri, 11 Dec 2020 08:42:08 +0000 (17:42 +0900)
Problems such as crash may occur when an event is received during wifi handle creation
or the wifi handle is destroyed during event processing. To avoid this we use mutex.

Change-Id: I89b300514158922664cd1742a649bb9f6f0d46d3
Signed-off-by: Jaehyun Kim <jeik01.kim@samsung.com>
include/wifi_internal.h
src/network_interface.c
src/wifi_internal.c
src/wifi_manager.c

index 2154717..87c1ea3 100755 (executable)
@@ -79,6 +79,16 @@ typedef enum {
 /* It is specific to TV Profile that WiFi Module can be insert or remove in platform */
 #define VCONFKEY_WIFI_DEVICE_STATUS_UEVENT "memory/wifi/device/status_uevent"
 
+#define WIFI_LOCK \
+       do { \
+               _wifi_lock(); \
+       } while(0)
+
+#define WIFI_UNLOCK \
+       do { \
+               _wifi_unlock(); \
+       } while(0)
+
 #define CHECK_FEATURE_SUPPORTED(...) \
        do { \
                int rv = _wifi_check_feature_supported(__VA_ARGS__, NULL); \
@@ -556,6 +566,8 @@ int _wifi_dpp_request_own_uri_gen(wifi_dpp_s *p_dpp, const char *key);
 int _wifi_dpp_start(wifi_dpp_s *p_dpp, const char *auth_key,
                const char *configurator_key, const char *pass);
 int _wifi_dpp_stop(wifi_dpp_s *p_dpp);
+void _wifi_lock(void);
+void _wifi_unlock(void);
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */
index d387eec..91e0d84 100755 (executable)
@@ -2881,6 +2881,7 @@ void net_deregister_client_ext(network_info_s *network_info)
        if (network_info) {
                network_info->event_callback = NULL;
                network_info->user_data = NULL;
+               network_info->wifi_handle = NULL;
 
                _net_deregister_signal(network_info);
                _net_dbus_close_gdbus_call(network_info);
index d8e7765..4fa15c6 100755 (executable)
@@ -14,6 +14,8 @@
  * limitations under the License.
  */
 
+#define _GNU_SOURCE
+#include <pthread.h>
 #include <glib.h>
 #include <ctype.h>
 #include <stdio.h>
@@ -51,6 +53,8 @@ static gboolean multi_scan_type[WIFI_MULTI_SCAN_MAX] = {0, };
 static bool wifi_is_feature_checked[WIFI_SUPPORTED_FEATURE_MAX] = {0, };
 static bool wifi_feature_supported[WIFI_SUPPORTED_FEATURE_MAX] = {0, };
 
+static pthread_mutex_t g_wifi_thread_mutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
+
 //LCOV_EXCL_START
 static wifi_manager_error_e __convert_to_ap_error_type(net_err_e err_type)
 {
@@ -1227,11 +1231,18 @@ static void __dpp_removed_cb(wifi_manager_handle_s *wifi_handle,
 
 static void _wifi_evt_cb(net_event_info_s *event_cb, void *user_data)
 {
+       WIFI_LOCK;
        bool is_requested = false;
        net_profile_info_s *prof_info_p = NULL;
        wifi_manager_error_e result = WIFI_MANAGER_ERROR_NONE;
        wifi_manager_handle_s *wifi_handle = user_data;
 
+       if (!__wifi_check_handle_validity(wifi_handle)) {
+               WIFI_LOG(WIFI_ERROR, "Wifi handle is not initialized");
+               WIFI_UNLOCK;
+               return;
+       }
+
        switch (event_cb->Event) {
        case NET_EVENT_OPEN_RSP:
        case NET_EVENT_WIFI_WPS_RSP:
@@ -1246,8 +1257,10 @@ static void _wifi_evt_cb(net_event_info_s *event_cb, void *user_data)
                                (event_cb->Error !=
                                 NET_ERR_CONNECTION_WPS_OVERLAP) &&
                                (event_cb->Error !=
-                                NET_ERR_CONNECTION_WPS_WEP_PROHIBITED))
+                                NET_ERR_CONNECTION_WPS_WEP_PROHIBITED)) {
+                       WIFI_UNLOCK;
                        return;
+               }
 
                result = __convert_to_ap_error_type(event_cb->Error);
                WIFI_LOG(WIFI_INFO, "Connection open error %s",
@@ -1263,8 +1276,10 @@ static void _wifi_evt_cb(net_event_info_s *event_cb, void *user_data)
 
                        __state_changed_cb(wifi_handle, event_cb->ProfileName, prof_info_p,
                                                        WIFI_MANAGER_CONNECTION_STATE_CONNECTED);
+                       WIFI_UNLOCK;
                        return;
                case NET_ERR_ACTIVE_CONNECTION_EXISTS:
+                       WIFI_UNLOCK;
                        return;
                default:
                        if (event_cb->Datalength == sizeof(net_profile_info_s))
@@ -1281,8 +1296,10 @@ static void _wifi_evt_cb(net_event_info_s *event_cb, void *user_data)
                is_requested = true;
                /* fall through */
        case NET_EVENT_CLOSE_IND:
-               if (_wifi_check_profile_name_validity(event_cb->ProfileName) != true)
+               if (_wifi_check_profile_name_validity(event_cb->ProfileName) != true) {
+                       WIFI_UNLOCK;
                        return;
+               }
 
                result = __convert_to_ap_error_type(event_cb->Error);
                WIFI_LOG(WIFI_ERROR, "Connection close error %s",
@@ -1321,6 +1338,7 @@ static void _wifi_evt_cb(net_event_info_s *event_cb, void *user_data)
                                wifi_handle->is_disconnect_wps_pin = false;
                        }
 
+                       WIFI_UNLOCK;
                        return;
                default:
                        break;
@@ -1328,11 +1346,15 @@ static void _wifi_evt_cb(net_event_info_s *event_cb, void *user_data)
 
                break;
        case NET_EVENT_NET_STATE_IND:
-               if (_wifi_check_profile_name_validity(event_cb->ProfileName) != true)
+               if (_wifi_check_profile_name_validity(event_cb->ProfileName) != true) {
+                       WIFI_UNLOCK;
                        return;
+               }
 
-               if (event_cb->Datalength != sizeof(net_profile_info_s))
+               if (event_cb->Datalength != sizeof(net_profile_info_s)) {
+                       WIFI_UNLOCK;
                        return;
+               }
 
                prof_info_p = (net_profile_info_s *)event_cb->Data;
                net_state_type_e profile_state = prof_info_p->ProfileState;
@@ -1472,6 +1494,8 @@ static void _wifi_evt_cb(net_event_info_s *event_cb, void *user_data)
        default:
                break;
        }
+
+       WIFI_UNLOCK;
 }
 
 int _wifi_init(wifi_manager_h wifi, const char *ifname)
@@ -3912,3 +3936,13 @@ int _wifi_dpp_stop(wifi_dpp_s *p_dpp)
        return __convert_net_err_to_wifi_dpp_error(rv);
 }
 //LCOV_EXCL_STOP
+
+void _wifi_lock(void)
+{
+       pthread_mutex_lock(&g_wifi_thread_mutex);
+}
+
+void _wifi_unlock(void)
+{
+       pthread_mutex_unlock(&g_wifi_thread_mutex);
+}
index f6551c2..b2ad8cc 100755 (executable)
@@ -101,8 +101,11 @@ EXPORT_API int wifi_manager_initialize(wifi_manager_h *wifi)
                return WIFI_MANAGER_ERROR_INVALID_PARAMETER; //LCOV_EXCL_LINE
        }
 
+       WIFI_LOCK;
+
        if (__wifi_check_handle_validity(*wifi)) {
                WIFI_LOG(WIFI_ERROR, "Already initialized"); //LCOV_EXCL_LINE
+               WIFI_UNLOCK;
                __NETWORK_CAPI_FUNC_EXIT__; //LCOV_EXCL_LINE
                return WIFI_MANAGER_ERROR_ALREADY_INITIALIZED; //LCOV_EXCL_LINE
        }
@@ -110,6 +113,7 @@ EXPORT_API int wifi_manager_initialize(wifi_manager_h *wifi)
        rv = _wifi_create_handle(wifi);
        if (rv != WIFI_MANAGER_ERROR_NONE) {
                WIFI_LOG(WIFI_ERROR, "Init failed[%d]", rv); //LCOV_EXCL_LINE
+               WIFI_UNLOCK;
                __NETWORK_CAPI_FUNC_EXIT__; //LCOV_EXCL_LINE
                return WIFI_MANAGER_ERROR_OUT_OF_MEMORY; //LCOV_EXCL_LINE
        }
@@ -119,12 +123,14 @@ EXPORT_API int wifi_manager_initialize(wifi_manager_h *wifi)
                WIFI_LOG(WIFI_ERROR, "Access denied"); //LCOV_EXCL_LINE
                _wifi_deinit(*wifi); //LCOV_EXCL_LINE
                _wifi_destroy_handle(wifi); //LCOV_EXCL_LINE
+               WIFI_UNLOCK;
                __NETWORK_CAPI_FUNC_EXIT__; //LCOV_EXCL_LINE
                return WIFI_MANAGER_ERROR_PERMISSION_DENIED; //LCOV_EXCL_LINE
        } else if (rv != NET_ERR_NONE) {
                WIFI_LOG(WIFI_ERROR, "Init failed[%d]", rv); //LCOV_EXCL_LINE
                _wifi_deinit(*wifi); //LCOV_EXCL_LINE
                _wifi_destroy_handle(wifi); //LCOV_EXCL_LINE
+               WIFI_UNLOCK;
                __NETWORK_CAPI_FUNC_EXIT__; //LCOV_EXCL_LINE
                return WIFI_MANAGER_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
        }
@@ -132,6 +138,7 @@ EXPORT_API int wifi_manager_initialize(wifi_manager_h *wifi)
        _wifi_add_to_handle_list(wifi);
        WIFI_LOG(WIFI_INFO, "Wi-Fi successfully initialized");
 
+       WIFI_UNLOCK;
        __NETWORK_CAPI_FUNC_EXIT__;
        return WIFI_MANAGER_ERROR_NONE;
 }
@@ -158,8 +165,11 @@ EXPORT_API int wifi_manager_initialize_with_interface_name(wifi_manager_h *wifi,
                return WIFI_MANAGER_ERROR_INVALID_PARAMETER; //LCOV_EXCL_LINE
        }
 
+       WIFI_LOCK;
+
        if (__wifi_check_handle_validity(*wifi)) {
                WIFI_LOG(WIFI_ERROR, "Already initialized"); //LCOV_EXCL_LINE
+               WIFI_UNLOCK;
                __NETWORK_CAPI_FUNC_EXIT__; //LCOV_EXCL_LINE
                return WIFI_MANAGER_ERROR_ALREADY_INITIALIZED; //LCOV_EXCL_LINE
        }
@@ -167,6 +177,7 @@ EXPORT_API int wifi_manager_initialize_with_interface_name(wifi_manager_h *wifi,
        rv = _wifi_create_handle(wifi);
        if (rv != WIFI_MANAGER_ERROR_NONE) {
                WIFI_LOG(WIFI_ERROR, "Init failed[%d]", rv); //LCOV_EXCL_LINE
+               WIFI_UNLOCK;
                __NETWORK_CAPI_FUNC_EXIT__; //LCOV_EXCL_LINE
                return WIFI_MANAGER_ERROR_OUT_OF_MEMORY; //LCOV_EXCL_LINE
        }
@@ -176,12 +187,14 @@ EXPORT_API int wifi_manager_initialize_with_interface_name(wifi_manager_h *wifi,
                WIFI_LOG(WIFI_ERROR, "Access denied"); //LCOV_EXCL_LINE
                _wifi_deinit(*wifi); //LCOV_EXCL_LINE
                _wifi_destroy_handle(wifi); //LCOV_EXCL_LINE
+               WIFI_UNLOCK;
                __NETWORK_CAPI_FUNC_EXIT__; //LCOV_EXCL_LINE
                return WIFI_MANAGER_ERROR_PERMISSION_DENIED; //LCOV_EXCL_LINE
        } else if (rv != NET_ERR_NONE) {
                WIFI_LOG(WIFI_ERROR, "Init failed[%d]", rv); //LCOV_EXCL_LINE
                _wifi_deinit(*wifi); //LCOV_EXCL_LINE
                _wifi_destroy_handle(wifi); //LCOV_EXCL_LINE
+               WIFI_UNLOCK;
                __NETWORK_CAPI_FUNC_EXIT__; //LCOV_EXCL_LINE
                return WIFI_MANAGER_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
        }
@@ -189,6 +202,7 @@ EXPORT_API int wifi_manager_initialize_with_interface_name(wifi_manager_h *wifi,
        _wifi_add_to_handle_list(wifi);
        WIFI_LOG(WIFI_INFO, "Wi-Fi successfully initialized with interface name [%s]", ifname);
 
+       WIFI_UNLOCK;
        __NETWORK_CAPI_FUNC_EXIT__;
        return WIFI_MANAGER_ERROR_NONE;
 }
@@ -200,7 +214,10 @@ EXPORT_API int wifi_manager_deinitialize(wifi_manager_h wifi)
 
        CHECK_FEATURE_SUPPORTED(WIFI_FEATURE);
 
-       RET_ERR_IF_HANDLE_IS_NOT_VALID_OR_NOT_INITIALIZED(wifi, __NETWORK_CAPI_FUNC_EXIT__);
+       WIFI_LOCK;
+       RET_ERR_IF_HANDLE_IS_NOT_VALID_OR_NOT_INITIALIZED(wifi,
+                       WIFI_UNLOCK;\
+                       __NETWORK_CAPI_FUNC_EXIT__);
 
        wifi_manager_unset_rssi_level_changed_cb(wifi);
 
@@ -215,6 +232,7 @@ EXPORT_API int wifi_manager_deinitialize(wifi_manager_h wifi)
 
        WIFI_LOG(WIFI_INFO, "Wi-Fi successfully de-initialized");
 
+       WIFI_UNLOCK;
        __NETWORK_CAPI_FUNC_EXIT__;
        return WIFI_MANAGER_ERROR_NONE;
 }
@@ -227,8 +245,11 @@ EXPORT_API int wifi_manager_initialize_cs(int tid, wifi_manager_h *wifi)
        int rv;
 
        rv = wifi_manager_initialize(wifi);
-       if (rv == WIFI_MANAGER_ERROR_NONE)
+       if (rv == WIFI_MANAGER_ERROR_NONE) {
+               WIFI_LOCK;
                _wifi_set_cs_tid(*wifi, tid);
+               WIFI_UNLOCK;
+       }
 
        __NETWORK_CAPI_FUNC_EXIT__;
        return rv;
@@ -240,7 +261,10 @@ EXPORT_API int wifi_manager_deinitialize_cs(int tid, wifi_manager_h wifi)
 
        int rv;
 
+       WIFI_LOCK;
        _wifi_unset_cs_tid(tid);
+       WIFI_UNLOCK;
+
        rv = wifi_manager_deinitialize(wifi);
 
        __NETWORK_CAPI_FUNC_EXIT__;