Adding fix for Sonarqube major issues for IoTivity 1.2-rel
[platform/upstream/iotivity.git] / resource / csdk / connectivity / src / bt_le_adapter / caleadapter.c
old mode 100755 (executable)
new mode 100644 (file)
index 94b4f6e..10fdffd
@@ -59,6 +59,7 @@ typedef struct
     uint32_t totalDataLen;
     uint8_t *defragData;
     CAEndpoint_t *remoteEndpoint;
+    uint8_t refCount;
 } CABLESenderInfo_t;
 
 typedef enum
@@ -74,6 +75,7 @@ typedef enum
  * default value is 20 byte.
  */
 static uint16_t g_mtuSize = CA_DEFAULT_BLE_MTU_SIZE;
+
 /**
  * Callback to provide the status of the network change to CA layer.
  */
@@ -131,7 +133,6 @@ static oc_mutex g_bleClientReceiveDataMutex = NULL;
  */
 static oc_mutex g_bleServerReceiveDataMutex = NULL;
 
-
 /**
  * Callback to be called when network packet received from either
  * GattServer or GattClient.
@@ -281,6 +282,11 @@ static u_arraylist_t *g_bleServerSenderInfo = NULL;
 static u_arraylist_t *g_bleClientSenderInfo = NULL;
 
 /**
+ * Mutex to synchronize access to all senderInfos
+ */
+static oc_mutex g_senderInfoMutex = NULL;
+
+/**
  * Queue to process the outgoing packets from GATTServer.
  */
 static CAQueueingThread_t *g_bleServerSendQueueHandle = NULL;
@@ -511,6 +517,8 @@ static void CALERemoveReceiveQueueData(u_arraylist_t *dataInfoList,
 /**
  * get received data info and positioned index from the received data list
  * for client / server which is matched same leAddress and port.
+ * CABLESenderInfo_t is reference counted structure, you must call
+ * CALEFreeSenderInfo on senderInfo to release reference.
  *
  * @param[in]  leAddress       target address to get serderInfo.
  * @param[in]  port            target port to get senderInfo.
@@ -527,6 +535,36 @@ static CAResult_t CALEGetSenderInfo(const char *leAddress,
                                     uint32_t *senderIndex);
 
 /**
+ * Add sender info to list.
+ *
+ * @param[in] u_arraylist_t   Array list to add sender info to.
+ * @param[in] senderInfo      Sender info to be added to list.
+ *
+ * @return true on success, otherwise false.
+ */
+static bool CALEAddSenderInfoToList(u_arraylist_t *senderInfoList,
+                                          CABLESenderInfo_t *senderInfo);
+
+/**
+ * Remove desired sender info from list.
+ *
+ * @param[in] u_arraylist_t   Array list to remove sender info from.
+ * @param[in] senderInfo      Sender info to be removed from list.
+ *
+ */
+static void CALERemoveSenderInfoFromList(u_arraylist_t *senderInfoList,
+                                         CABLESenderInfo_t *senderInfo);
+
+/**
+ * Free sender info. CABLESenderInfo_t is reference counted structure
+ * and info will be freed only when reference count reaches 0 or negative.
+ *
+ * @param[in] senderInfo      Sender info to be freed.
+ *
+ */
+static CAResult_t CALEFreeSenderInfo(CABLESenderInfo_t *senderInfo);
+
+/**
  * get ports related to remote address. It is need because multi application
  * can have more than 2 senderInfo using same BLE address. So before remove
  * receive queue data, should get port list from sender Info.
@@ -542,7 +580,6 @@ static CAResult_t CALEGetPortsFromSenderInfo(const char *leAddress,
 
 static CAResult_t CAInitLEServerQueues()
 {
-    
     CAResult_t result = CAInitLEServerSenderQueue();
     if (CA_STATUS_OK != result)
     {
@@ -713,6 +750,7 @@ static CAResult_t CAInitLEServerSenderQueue()
 
 static void CALEClearSenderInfoImpl(u_arraylist_t **list)
 {
+    oc_mutex_lock(g_senderInfoMutex);
     const size_t length = u_arraylist_length(*list);
     for (size_t i = 0; i < length; ++i)
     {
@@ -726,6 +764,7 @@ static void CALEClearSenderInfoImpl(u_arraylist_t **list)
          }
     }
     u_arraylist_free(list);
+    oc_mutex_unlock(g_senderInfoMutex);
 }
 
 static void CALEClearSenderInfo()
@@ -821,6 +860,7 @@ static CAResult_t CALEGetSenderInfo(const char *leAddress,
                         "NULL index argument",
                         CA_STATUS_INVALID_PARAM);
 
+    oc_mutex_lock(g_senderInfoMutex);
     const uint32_t listLength = u_arraylist_length(senderInfoList);
     const uint32_t addrLength = strlen(leAddress);
     for (uint32_t index = 0; index < listLength; index++)
@@ -831,23 +871,73 @@ static CAResult_t CALEGetSenderInfo(const char *leAddress,
             continue;
         }
 
-        if (!strncmp(info->remoteEndpoint->addr, leAddress, addrLength))
+        if (!strncmp(info->remoteEndpoint->addr, leAddress, addrLength)
+            && info->remoteEndpoint->port == port)
         {
-            if (info->remoteEndpoint->port == port)
+            *senderIndex = index;
+            if (senderInfo)
             {
-                *senderIndex = index;
-                if (senderInfo)
-                {
-                    *senderInfo = info;
-                }
-                return CA_STATUS_OK;
+                *senderInfo = info;
+                (*senderInfo)->refCount++;
             }
+            oc_mutex_unlock(g_senderInfoMutex);
+            return CA_STATUS_OK;
         }
     }
 
+    oc_mutex_unlock(g_senderInfoMutex);
     return CA_STATUS_FAILED;
 }
 
+static bool CALEAddSenderInfoToList(u_arraylist_t *senderInfoList, CABLESenderInfo_t *senderInfo)
+{
+    oc_mutex_lock(g_senderInfoMutex);
+    senderInfo->refCount++;
+    if (!u_arraylist_add(senderInfoList,(void *)senderInfo))
+    {
+        senderInfo->refCount--;
+        oc_mutex_unlock(g_senderInfoMutex);
+        return false;
+    }
+    oc_mutex_unlock(g_senderInfoMutex);
+    return true;
+}
+
+static void CALERemoveSenderInfoFromList(u_arraylist_t *senderInfoList, CABLESenderInfo_t *senderInfo)
+{
+    oc_mutex_lock(g_senderInfoMutex);
+    uint32_t idx;
+    bool elemFound = u_arraylist_get_index(senderInfoList, (const void*)senderInfo, &idx);
+    if(elemFound)
+    {
+        void *info = u_arraylist_remove(senderInfoList, idx);
+        if (info != NULL)
+        {
+            senderInfo->refCount--;
+        }
+    }
+    oc_mutex_unlock(g_senderInfoMutex);
+}
+
+static CAResult_t CALEFreeSenderInfo(CABLESenderInfo_t *senderInfo)
+{
+    VERIFY_NON_NULL_RET(senderInfo,
+                        CALEADAPTER_TAG,
+                        "NULL senderInfo to remove argument",
+                        CA_STATUS_INVALID_PARAM);
+
+    oc_mutex_lock(g_senderInfoMutex);
+    senderInfo->refCount--;
+    if(senderInfo->refCount <= 0)
+    {
+        OICFree(senderInfo->defragData);
+        OICFree(senderInfo->remoteEndpoint);
+        OICFree(senderInfo);
+    }
+    oc_mutex_unlock(g_senderInfoMutex);
+    return CA_STATUS_OK;
+}
+
 static void CALEDataReceiverHandler(void *threadData, CABLEAdapter_t receiverType)
 {
     OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "%s", __func__);
@@ -935,9 +1025,8 @@ static void CALEDataReceiverHandler(void *threadData, CABLEAdapter_t receiverTyp
             {
                 OIC_LOG(ERROR, CALEADAPTER_TAG,
                         "This packet is start packet but exist senderInfo. Remove senderInfo");
-                u_arraylist_remove(bleData->senderInfo, senderIndex);
-                OICFree(senderInfo->defragData);
-                OICFree(senderInfo);
+                CALERemoveSenderInfoFromList(bleData->senderInfo, senderInfo);
+                CALEFreeSenderInfo(senderInfo);
                 senderInfo = NULL;
                 senderIndex = 0;
             }
@@ -957,26 +1046,21 @@ static void CALEDataReceiverHandler(void *threadData, CABLEAdapter_t receiverTyp
                 return;
             }
 
-            CABLESenderInfo_t *newSender = OICMalloc(sizeof(CABLESenderInfo_t));
+            CABLESenderInfo_t *newSender = OICCalloc(1, sizeof(CABLESenderInfo_t));
             if (!newSender)
             {
                 OIC_LOG(ERROR, CALEADAPTER_TAG, "Memory allocation failed for new sender");
                 oc_mutex_unlock(bleReceiveDataMutex);
                 return;
             }
-            newSender->recvDataLen = 0;
-            newSender->totalDataLen = 0;
-            newSender->defragData = NULL;
-            newSender->remoteEndpoint = NULL;
 
             OIC_LOG(DEBUG, CALEADAPTER_TAG, "Parsing the header");
 
             newSender->totalDataLen = totalLength;
-
             if (!(newSender->totalDataLen))
             {
                 OIC_LOG(ERROR, CALEADAPTER_TAG, "Total Data Length is parsed as 0!!!");
-                OICFree(newSender);
+                CALEFreeSenderInfo(newSender);
                 oc_mutex_unlock(bleReceiveDataMutex);
                 return;
             }
@@ -994,7 +1078,7 @@ static void CALEDataReceiverHandler(void *threadData, CABLEAdapter_t receiverTyp
             if (NULL == newSender->defragData)
             {
                 OIC_LOG(ERROR, CALEADAPTER_TAG, "defragData is NULL!");
-                OICFree(newSender);
+                CALEFreeSenderInfo(newSender);
                 oc_mutex_unlock(bleReceiveDataMutex);
                 return;
             }
@@ -1015,8 +1099,7 @@ static void CALEDataReceiverHandler(void *threadData, CABLEAdapter_t receiverTyp
             if (NULL == newSender->remoteEndpoint)
             {
                 OIC_LOG(ERROR, CALEADAPTER_TAG, "remoteEndpoint is NULL!");
-                OICFree(newSender->defragData);
-                OICFree(newSender);
+                CALEFreeSenderInfo(newSender);
                 oc_mutex_unlock(bleReceiveDataMutex);
                 return;
             }
@@ -1024,9 +1107,7 @@ static void CALEDataReceiverHandler(void *threadData, CABLEAdapter_t receiverTyp
             if (newSender->recvDataLen + dataOnlyLen > newSender->totalDataLen)
             {
                 OIC_LOG(ERROR, CALEADAPTER_TAG, "buffer is smaller than received data");
-                OICFree(newSender->defragData);
-                CAFreeEndpoint(newSender->remoteEndpoint);
-                OICFree(newSender);
+                CALEFreeSenderInfo(newSender);
                 oc_mutex_unlock(bleReceiveDataMutex);
                 return;
             }
@@ -1035,22 +1116,16 @@ static void CALEDataReceiverHandler(void *threadData, CABLEAdapter_t receiverTyp
                    dataOnlyLen);
             newSender->recvDataLen += dataOnlyLen;
 
-            u_arraylist_add(bleData->senderInfo,(void *)newSender);
+            newSender->refCount = 1;
 
-            //Getting newSender index position in bleSenderInfo array list
-            if (CA_STATUS_OK !=
-                    CALEGetSenderInfo(newSender->remoteEndpoint->addr,
-                                      newSender->remoteEndpoint->port,
-                                      bleData->senderInfo,
-                                      NULL, &senderIndex))
+            if (!CALEAddSenderInfoToList(bleData->senderInfo, newSender))
             {
-                OIC_LOG(ERROR, CALEADAPTER_TAG, "Existing sender index not found!!");
-                OICFree(newSender->defragData);
-                CAFreeEndpoint(newSender->remoteEndpoint);
-                OICFree(newSender);
+                OIC_LOG(ERROR, CALEADAPTER_TAG, "Failed to add sender info!");
+                CALEFreeSenderInfo(newSender);
                 oc_mutex_unlock(bleReceiveDataMutex);
                 return;
             }
+
             senderInfo = newSender;
         }
         else
@@ -1061,9 +1136,8 @@ static void CALEDataReceiverHandler(void *threadData, CABLEAdapter_t receiverTyp
                 OIC_LOG_V(ERROR, CALEADAPTER_TAG,
                           "Data Length exceeding error!! Receiving [%zu] total length [%u]",
                           senderInfo->recvDataLen + dataOnlyLen, senderInfo->totalDataLen);
-                u_arraylist_remove(bleData->senderInfo, senderIndex);
-                OICFree(senderInfo->defragData);
-                OICFree(senderInfo);
+                CALERemoveSenderInfoFromList(bleData->senderInfo, senderInfo);
+                CALEFreeSenderInfo(senderInfo);
                 oc_mutex_unlock(bleReceiveDataMutex);
                 return;
             }
@@ -1082,10 +1156,8 @@ static void CALEDataReceiverHandler(void *threadData, CABLEAdapter_t receiverTyp
             if (NULL == g_networkPacketReceivedCallback)
             {
                 OIC_LOG(ERROR, CALEADAPTER_TAG, "gReqRespCallback is NULL!");
-
-                u_arraylist_remove(bleData->senderInfo, senderIndex);
-                OICFree(senderInfo->defragData);
-                OICFree(senderInfo);
+                CALERemoveSenderInfoFromList(bleData->senderInfo, senderInfo);
+                CALEFreeSenderInfo(senderInfo);
                 oc_mutex_unlock(bleReceiveDataMutex);
                 return;
             }
@@ -1112,10 +1184,10 @@ static void CALEDataReceiverHandler(void *threadData, CABLEAdapter_t receiverTyp
                         break;
                     default:
                         OIC_LOG_V(ERROR, CALEADAPTER_TAG, "Unsupported rcvr type:%d",receiverType);
-                        u_arraylist_remove(bleData->senderInfo, senderIndex);
+                        CALERemoveSenderInfoFromList(bleData->senderInfo, senderInfo);
                         senderInfo->remoteEndpoint = NULL;
                         senderInfo->defragData = NULL;
-                        OICFree(senderInfo);
+                        CALEFreeSenderInfo(senderInfo);
                         oc_mutex_unlock(bleReceiveDataMutex);
                         return;
                 }
@@ -1143,11 +1215,14 @@ static void CALEDataReceiverHandler(void *threadData, CABLEAdapter_t receiverTyp
             }
 #endif
 
-            u_arraylist_remove(bleData->senderInfo, senderIndex);
+            CALERemoveSenderInfoFromList(bleData->senderInfo, senderInfo);
             senderInfo->remoteEndpoint = NULL;
             senderInfo->defragData = NULL;
-            OICFree(senderInfo);
+            CALEFreeSenderInfo(senderInfo);
+            oc_mutex_unlock(bleReceiveDataMutex);
+            return;
         }
+        CALEFreeSenderInfo(senderInfo);
     }
     oc_mutex_unlock(bleReceiveDataMutex);
 }
@@ -1180,7 +1255,7 @@ static void CALEServerSendDataThread(void *threadData)
         return;
     }
 
-#if defined(__ANDROID__)
+#if defined(__TIZEN__) || defined(__ANDROID__)
     // get MTU size
     g_mtuSize = CALEServerGetMtuSize(bleData->remoteEndpoint->addr);
 #endif
@@ -1326,7 +1401,7 @@ static void CALEServerSendDataThread(void *threadData)
 
         OIC_LOG_V(DEBUG,
                   CALEADAPTER_TAG,
-                  "Server Sent Unicast First Data - data length [%zu]",
+                  "Server Sent Unicast First Data - data length [%u]",
                   length);
 
         result = CAGenerateHeader(dataHeader,
@@ -1487,6 +1562,8 @@ static void CALEClientSendDataThread(void *threadData)
             return;
         }
     }
+#endif
+#if defined(__TIZEN__) || defined(__ANDROID__)
     g_mtuSize = CALEClientGetMtuSize(bleData->remoteEndpoint->addr);
 #endif
     OIC_LOG_V(INFO, CALEADAPTER_TAG, "MTU size [%d]", g_mtuSize);
@@ -1629,7 +1706,7 @@ static void CALEClientSendDataThread(void *threadData)
         }
         OIC_LOG_V(DEBUG,
                   CALEADAPTER_TAG,
-                  "Client Sent Unicast First Data - data length [%zu]",
+                  "Client Sent Unicast First Data - data length [%u]",
                   length);
 
         result = CAGenerateHeader(dataHeader,
@@ -1691,7 +1768,7 @@ static void CALEClientSendDataThread(void *threadData)
             }
             OIC_LOG_V(DEBUG,
                       CALEADAPTER_TAG,
-                      "Client Sent Unicast %d Data - data(mtu) length [%zu]",
+                      "Client Sent Unicast %d Data - data(mtu) length [%hu]",
                       index + 1,
                       g_mtuSize);
         }
@@ -1929,7 +2006,7 @@ static void CALEDataReceiverHandlerSingleThread(const uint8_t *data,
 static CAResult_t CALEServerSendDataSingleThread(const uint8_t *data,
                                                  uint32_t dataLen)
 {
-    OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "%s", __func__););
+    OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "%s", __func__);
 
     VERIFY_NON_NULL(data, CALEADAPTER_TAG, "Param data is NULL");
 
@@ -2152,6 +2229,16 @@ static CAResult_t CAInitLEAdapterMutex()
         }
     }
 
+    if (NULL == g_senderInfoMutex)
+    {
+        g_senderInfoMutex = oc_mutex_new();
+        if (NULL == g_senderInfoMutex)
+        {
+            OIC_LOG(ERROR, CALEADAPTER_TAG, "oc_mutex_new failed");
+            return CA_STATUS_FAILED;
+        }
+    }
+
     return CA_STATUS_OK;
 }
 
@@ -2166,13 +2253,14 @@ static void CATerminateLEAdapterMutex()
     oc_mutex_free(g_bleLocalAddressMutex);
     g_bleLocalAddressMutex = NULL;
 
-    
-
     oc_mutex_free(g_bleServerReceiveDataMutex);
     g_bleServerReceiveDataMutex = NULL;
 
     oc_mutex_free(g_bleClientReceiveDataMutex);
     g_bleClientReceiveDataMutex = NULL;
+
+    oc_mutex_free(g_senderInfoMutex);
+    g_senderInfoMutex = NULL;
 }
 
 /**
@@ -2377,6 +2465,7 @@ static CAResult_t CALEAdapterClientSendData(const CAEndpoint_t *remoteEndpoint,
 static CAResult_t CALEAdapterGattServerStart()
 {
     OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "%s", __func__);
+    CAResult_t result = CA_STATUS_FAILED;
 
     if (caglobals.bleFlags & CA_LE_SERVER_DISABLE)
     {
@@ -2385,7 +2474,10 @@ static CAResult_t CALEAdapterGattServerStart()
         return CA_STATUS_OK;
     }
 
-    CAResult_t result = CAStartLEGattServer();
+#ifndef DISABLE_BLE_SERVER
+    OIC_LOG_V(INFO, CALEADAPTER_TAG, "Starting LE GATT Server");
+    result = CAStartLEGattServer();
+#endif
 
 #ifndef SINGLE_THREAD
     /*
@@ -2486,7 +2578,7 @@ static ssize_t CALESecureSendDataCB(CAEndpoint_t *endpoint, const void *data, si
     VERIFY_NON_NULL(endpoint, CALEADAPTER_TAG, "endpoint is NULL");
     VERIFY_NON_NULL(data, CALEADAPTER_TAG, "data is NULL");
     OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "IN %s", __func__);
-    OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "encrypted datalen = %d", dataLen);
+    OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "encrypted datalen = %zd", dataLen);
 
     CAResult_t result;
     CADataType_t dataType = g_dataType;
@@ -2544,7 +2636,7 @@ CAResult_t CALESecureReceiveDataCB(const CASecureEndpoint_t *sep, const void *da
     VERIFY_NON_NULL(data, CALEADAPTER_TAG, "data is NULL");
 
     OIC_LOG_V(DEBUG, CALEADAPTER_TAG,
-              "Secure Data Receive - decrypted datalen = %d", dataLen);
+              "Secure Data Receive - decrypted datalen = %zd", dataLen);
 
     if (dataLen <= 0)
     {
@@ -3188,8 +3280,54 @@ static void CALEConnectionStateChangedCb(CATransportAdapter_t adapter, const cha
 #endif
 
 #ifdef __WITH_DTLS__
+#if defined(__TIZEN__) && !defined(SINGLE_THREAD)
+        // CAcloseSslConnection returns CAResult_t instead of void*, but the size is the same and crash shouldn't occur
+        pthread_t ccThread;
+        pthread_attr_t attr;
+        int initAttrRes = -1;
+        int pthreadCreateRes = -1;
+        int detachStatusRes = -1;
+        int memoryAllocationRes = -1;
+
+        do
+        {
+            initAttrRes = pthread_attr_init(&attr);
+            if (initAttrRes != 0)
+            {
+                break;
+            }
+            CAEndpoint_t *localEndpointCpyPtr = OICMalloc(sizeof(CAEndpoint_t));
+
+            if(NULL == localEndpointCpyPtr)
+            {
+                memoryAllocationRes = -1;
+                break;
+            }
+            else
+            {
+                memoryAllocationRes = 0;
+            }
+
+            (*localEndpointCpyPtr) = localEndpoint;
+            // this piece of code is reached on the main thread
+            // CAcloseSslConnection might wait for too long (network + mutexes) and watchdog might kill it
+            // Asynchronous call protects this function from watchdog
+            pthreadCreateRes = pthread_create(&ccThread, &attr, (void *(*)(void*))&CAcloseSslConnectionFreeEndpoint, (void*)localEndpointCpyPtr);
+
+            if (pthreadCreateRes != 0)
+            {
+                break;
+            }
+            detachStatusRes = pthread_detach(ccThread);
+        }while (0);
+
+        // regardless of CAcloseSslConnection result, the function will continue and g_connectionCallback will be called
+        OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "CAcloseSslConnection pthread_init [%d], mem_alloc [%d] pthread_create [%d], pthread_detach [%d]",
+                initAttrRes, memoryAllocationRes, pthreadCreateRes, detachStatusRes);
+#else
         CAcloseSslConnection(&localEndpoint);
 #endif
+#endif
     }
 
     if (g_connectionCallback)
@@ -3441,7 +3579,7 @@ static CAResult_t CALEAdapterClientReceivedData(const char *remoteAddress,
     // Create bleData to add to queue
     OIC_LOG_V(DEBUG,
               CALEADAPTER_TAG,
-              "Data received from LE Client layer [%zu]",
+              "Data received from LE Client layer [%u]",
               dataLength);
 
     CALEData_t * const bleData =
@@ -3566,13 +3704,10 @@ static void CALERemoveReceiveQueueData(u_arraylist_t *dataInfoList, const char*
                                                   dataInfoList, &senderInfo,
                                                   &senderIndex))
             {
-                u_arraylist_remove(dataInfoList, senderIndex);
-                OICFree(senderInfo->defragData);
-                OICFree(senderInfo->remoteEndpoint);
-                OICFree(senderInfo);
-
                 OIC_LOG(DEBUG, CALEADAPTER_TAG,
                         "SenderInfo is removed for disconnection");
+                CALERemoveSenderInfoFromList(dataInfoList, senderInfo);
+                CALEFreeSenderInfo(senderInfo);
             }
             else
             {