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 21547178cbf95924a53c63150fd6c219c70d5177..87c1ea38fd98c9a6f8504d69e5f95e1bd01bba3d 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 d387eeccb0a71e5a9bacd44a69a86622c4a3964e..91e0d84830d5f5ed160e42e5f97f494383766d02 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 d8e7765f1cc263772d74d5b4df4cd3b38a00db38..4fa15c6ecfee7f5bf3c64378183364b8e905b287 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 f6551c2c350bb1db6d8d643debdefa29055c7ffd..b2ad8cc9dbec9f0d467519b0f9a914eff7770e95 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__;