mot-agent: add mutex at every APIs which goes to CA layer
authorsaerome.kim <saerome.kim@samsung.com>
Wed, 31 Jan 2018 08:27:19 +0000 (17:27 +0900)
committersaerome.kim <saerome.kim@samsung.com>
Mon, 2 Jul 2018 10:38:48 +0000 (19:38 +0900)
Signed-off-by: saerome.kim <saerome.kim@samsung.com>
src/mot-agent/ma-subowner.c

index 4d66fe2706b5866d9e5bbfe0123ee142e9b9e851..2a00adac9171486c8de95cecd7518db6738deb0b 100644 (file)
@@ -137,6 +137,7 @@ typedef struct _ma_subowner {
 } ma_subowner_s;
 
 ma_subowner_s *g_client;
+GMutex iotivity_mutex;
 
 #define CASE_TO_STR(x) case x: return #x;
 const char* _error_to_string(OCStackResult err)
@@ -379,21 +380,101 @@ static FILE* _fopen_prvn_mng(const char* path, const char* mode)
        return fopen(data_dir, mode);
 }
 
+#ifdef THREAD_COND_WAIT_USED
+/*
+ * data structure
+ */
+typedef struct _proc {
+    char name[2];
+    int data;
+    pthread_t thread;
+    pthread_mutex_t lock;
+    pthread_cond_t cond;
+    long int waits;
+} PROC;
+void _exec_and_wait(void* args) {
+       OCStackResult ret = OC_STACK_OK;
+       static struct timespec time_to_wait = {0, 0};
+       PROC *proc = (PROC*) args;
+       int TIMES = proc->waits /100;
+
+       time_to_wait.tv_sec = time(NULL) + proc->waits / 1000;
+       time_to_wait.tv_nsec = (proc->waits % 1000) * 1000000;
+
+       MA_LOGE("before increase proc[%s] data to [%d]", proc->name, proc->data);
+
+       while(g_client->g_doneCB && proc->data < TIMES) {
+               MA_LOGE("increase proc[%s] data to [%d]", proc->name, proc->data);
+               pthread_mutex_lock(&proc->lock);
+               pthread_cond_timedwait(&proc->cond, &proc->lock, &time_to_wait);
+               proc->data++;
+
+               ret = OCProcess();
+               if (OC_STACK_OK != ret) {
+                       MA_LOGE( "OCStack process error = %d", ret);
+                       proc->data =  TIMES;
+               }
+
+               pthread_mutex_unlock(&proc->lock);
+       }
+}
+
+int _init_proc(PROC *proc, void *(*routine) (void *)) {
+       pthread_attr_t attr;
+
+       MA_LOGI("try to init proc [%s]", proc->name);
+       pthread_attr_init(&attr);
+       pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
+
+       pthread_mutex_init(&proc->lock, NULL);
+       pthread_cond_init(&proc->cond, NULL);
+
+       pthread_create(&proc->thread, &attr, routine, (void*) proc);
+       pthread_attr_destroy(&attr);
+
+       return MA_ERROR_NONE;
+}
+#endif
 static int _wait_cb_ret(int msec)
 {
        OCStackResult ret = OC_STACK_OK;
 
+#ifndef THREAD_COND_WAIT_USED
+       struct timespec request, remaining;
+       request.tv_sec = msec / 1000;
+       request.tv_nsec = (msec % 1000) * 1000000;
+#endif
+
        ma_check_null_ret_error("g_client", g_client, OC_STACK_INVALID_PARAM);
 
+#ifdef THREAD_COND_WAIT_USED
+       int  result_a = 0;
+       PROC proc_a;
+
+       strcpy(proc_a.name, "A\0");
+       proc_a.data = 0;
+       proc_a.waits = msec;
+
+       if (MA_ERROR_NONE !=_init_proc(&proc_a, _exec_and_wait))
+               MA_LOGE("Fail to init proc [%s]", proc_a.name);
+
+       pthread_join(proc_a.thread, (void*) &result_a);
+#else
        for (int i=0; !g_client->g_doneCB && msec > i; ++i) {
-               usleep(1000);
+               ret = nanosleep(&request, &remaining);
+               if (-1 == ret && EINTR == errno) {
+                       MA_LOGE( "Onanosleep error = %d", errno);
+                       break;
+               }
+               g_mutex_lock(&iotivity_mutex);
                ret = OCProcess();
+               g_mutex_unlock(&iotivity_mutex);
                if (OC_STACK_OK != ret) {
                        MA_LOGE( "OCStack process error = %d", ret);
-                       return ret;
+                       break;
                }
        }
-
+#endif
        if (!g_client->g_doneCB)
                OCPDMCleanupForTimeout();
 
@@ -479,13 +560,17 @@ static int _init_provision_client(void)
        if (g_client)
                return ret;
 
+       g_mutex_init(&iotivity_mutex);
+
        snprintf(data_dir, MAX_FILE_PATH_LEN, "%s/network/%s",
                        "/opt/usr/data", PRVN_DB_FILE_NAME);
 
        /* initialize persistent storage for SVR DB */
        static OCPersistentStorage ps = { _fopen_prvn_mng, fread, fwrite, fclose, unlink };
 
+       g_mutex_lock(&iotivity_mutex);
        ret = OCRegisterPersistentStorageHandler(&ps);
+       g_mutex_unlock(&iotivity_mutex);
        if (OC_STACK_OK != ret ) {
                MA_LOGE( "OCRegisterPersistentStorageHandler error = %d", ret);
                return ret;
@@ -494,19 +579,25 @@ static int _init_provision_client(void)
        _set_device_id_seed();
 
        /* initialize OC stack and provisioning manager */
+       g_mutex_lock(&iotivity_mutex);
        ret = OCInit(NULL, 0, OC_CLIENT_SERVER);
+       g_mutex_unlock(&iotivity_mutex);
        if (OC_STACK_OK != ret ) {
                MA_LOGE( "OCInit() error = [%d][%s]", ret, _error_to_string(ret));
                return ret;
        }
 
        /* Do Self-Ownership Transfer */
+       g_mutex_lock(&iotivity_mutex);
        ret = OCConfigSelfOwnership();
+       g_mutex_unlock(&iotivity_mutex);
        if (OC_STACK_OK != ret ) {
                MA_LOGE( "OCConfigSelfOwnership() error = [%d][%s]", ret, _error_to_string(ret));
        }
 
+       g_mutex_lock(&iotivity_mutex);
        ret = OCInitPM(data_dir);
+       g_mutex_unlock(&iotivity_mutex);
        if (OC_STACK_OK != ret ) {
                MA_LOGE( "OCInitPM() error = [%d][%s]", ret, _error_to_string(ret));
                return ret;
@@ -762,12 +853,16 @@ static gboolean _ma_timeout_cb(gpointer data)
 #endif
 static gpointer _disc_mot_env_devs_func(gpointer data)
 {
+       int ret = OC_STACK_OK;
        ma_req_cb_s *con = (ma_req_cb_s *)data;
        ma_check_null_ret_error("con", con, NULL);
 
        MA_LOGI("Discovering Multiple Ownership Transfer enabled Devices on Network..");
-       if (OC_STACK_OK != OCDiscoverMultipleOwnerEnabledDevices(con->timeout,
-               &g_client->g_motdev_list)) {
+
+       g_mutex_lock(&iotivity_mutex);
+       OCDiscoverMultipleOwnerEnabledDevices(con->timeout, &g_client->g_motdev_list);
+       g_mutex_unlock(&iotivity_mutex);
+       if (OC_STACK_OK != ret) {
                MA_LOGE( "OCDiscoverMultipleOwnerEnalbedDevices API error");
                goto DISC_MOT_ENB_DEVS_END;
        }
@@ -829,7 +924,9 @@ static gpointer _disc_owned_devs_func(gpointer data)
        _remove_owned_client();
 
        MA_LOGD("Discovering Multiple Owned Devices");
+       g_mutex_lock(&iotivity_mutex);
        ret = OCDiscoverMultipleOwnedDevices(con->timeout, &g_client->g_mowned_list);
+       g_mutex_unlock(&iotivity_mutex);
        if (OC_STACK_OK != ret) {
                MA_LOGE( "OCDiscoverMultipleOwnerEnabledDevices API error");
                goto DISC_OWNED_DEVS_END;
@@ -2103,14 +2200,19 @@ static gpointer _pair_func(gpointer data)
        if(OIC_PRECONFIG_PIN == src_dev->doxm->oxmSel) {
                /* Pre-Configured PIN initialization */
                const char* testPreconfigPin = con->pin;/* Ex) "12341234" */
+               g_mutex_lock(&iotivity_mutex);
                ret = OCAddPreconfigPin(src_dev, testPreconfigPin, strlen(testPreconfigPin));
+               g_mutex_unlock(&iotivity_mutex);
                if(OC_STACK_OK != ret) {
                        MA_LOGE("Failed to save the pre-configured PIN");
                        MA_LOGE("You can't use the pre-configured PIN OxM for MOT");
                        goto PVPAIR_ERROR;
                }
        }
+
+       g_mutex_lock(&iotivity_mutex);
        ret = OCDoMultipleOwnershipTransfer(g_client, src_dev, _mot_cb);
+       g_mutex_unlock(&iotivity_mutex);
        if (OC_STACK_OK != ret )  {
                MA_LOGE( "OCDoMultipleOwnershipTransfer: ret = %d (%s)", ret, _error_to_string(ret));
                goto PVPAIR_ERROR;
@@ -2148,9 +2250,11 @@ static gpointer _pair_func(gpointer data)
                goto PVPAIR_ERROR;
        }
 
+       g_mutex_lock(&iotivity_mutex);
        ret = OCProvisionPairwiseDevices((void*) g_client, SYMMETRIC_PAIR_WISE_KEY,
                                                         OWNER_PSK_LENGTH_256, target_dev_1, acl_1,
                                                         target_dev_2, acl_2, _pairwise_cb);
+       g_mutex_unlock(&iotivity_mutex);
        if (OC_STACK_OK != ret) {
                MA_LOGD( "OCProvisionPairwiseDevices API error: %d (%s)", ret,
                                   _error_to_string(ret));
@@ -2275,7 +2379,9 @@ static gpointer _unpair_func(gpointer data)
        g_client->g_doneCB = false;
 
        MA_LOGI("Unlink Selected Pairwise Devices..");
+       g_mutex_lock(&iotivity_mutex);
        ret = OCUnlinkDevices((void*) g_client, owner_dev, owned_dev, _unlink_cb );
+       g_mutex_unlock(&iotivity_mutex);
        if (OC_STACK_OK != ret)  {
                MA_LOGD( "OCUnlinkDevices API error = %d (%s)", ret, _error_to_string(ret));
        } else {
@@ -2297,7 +2403,9 @@ static gpointer _unpair_func(gpointer data)
                goto PVUNPAIR_ERROR;
        }
 
+       g_mutex_lock(&iotivity_mutex);
        ret = OCRemoveSubOwner(g_client, owned_dev, &uuid_mowner, _remove_mo_cb);
+       g_mutex_unlock(&iotivity_mutex);
        if (OC_STACK_OK != ret )  {
                MA_LOGE( "OCRemoveSubOwner: ret = %d (%s)", ret, _error_to_string(ret));
                goto PVUNPAIR_ERROR;
@@ -2315,8 +2423,10 @@ static gpointer _unpair_func(gpointer data)
 
        MA_LOGI(" Removing CRED for remote device at local SVR DB");
 
+       g_mutex_lock(&iotivity_mutex);
        ret = OCRemoveDeviceWithUuid((void*) g_client, CALLBACK_TIMEOUT_5S,  owned_uuid,
                _remove_remove_cred_local_cb );
+       g_mutex_unlock(&iotivity_mutex);
        if (OC_STACK_OK != ret) {
                MA_LOGD( "OCRemoveDeviceWithUuid API error = %d (%s)", ret, _error_to_string(ret));
                goto PVUNPAIR_ERROR;
@@ -2729,16 +2839,25 @@ int ma_request_enable(ma_service *service)
 
 int ma_request_disable(ma_service *service)
 {
+       int ret = OC_STACK_OK;
+
        NOTUSED(service);
 
        if (!g_client)
                return MA_ERROR_NONE;
 
-       if (OC_STACK_OK != OCStop()) {
+       g_mutex_lock(&iotivity_mutex);
+       ret = OCStop();
+       g_mutex_unlock(&iotivity_mutex);
+       if (OC_STACK_OK != ret) {
                MA_LOGE( "OCStack stop error");
        }
 
+       g_mutex_lock(&iotivity_mutex);
        OCTerminatePM();
+       g_mutex_unlock(&iotivity_mutex);
+
+       g_mutex_clear(&iotivity_mutex);
 
        if (g_client->g_mowned_list) {
                OCDeleteDiscoveredDevices(g_client->g_mowned_list);