uint32_t totalDataLen;
uint8_t *defragData;
CAEndpoint_t *remoteEndpoint;
+ uint8_t refCount;
} CABLESenderInfo_t;
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.
*/
*/
static oc_mutex g_bleServerReceiveDataMutex = NULL;
-
/**
* Callback to be called when network packet received from either
* GattServer or GattClient.
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;
/**
* 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.
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.
static CAResult_t CAInitLEServerQueues()
{
-
CAResult_t result = CAInitLEServerSenderQueue();
if (CA_STATUS_OK != result)
{
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)
{
}
}
u_arraylist_free(list);
+ oc_mutex_unlock(g_senderInfoMutex);
}
static void CALEClearSenderInfo()
"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++)
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__);
{
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;
}
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;
}
if (NULL == newSender->defragData)
{
OIC_LOG(ERROR, CALEADAPTER_TAG, "defragData is NULL!");
- OICFree(newSender);
+ CALEFreeSenderInfo(newSender);
oc_mutex_unlock(bleReceiveDataMutex);
return;
}
if (NULL == newSender->remoteEndpoint)
{
OIC_LOG(ERROR, CALEADAPTER_TAG, "remoteEndpoint is NULL!");
- OICFree(newSender->defragData);
- OICFree(newSender);
+ CALEFreeSenderInfo(newSender);
oc_mutex_unlock(bleReceiveDataMutex);
return;
}
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;
}
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
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;
}
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;
}
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;
}
}
#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);
}
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");
}
}
+ 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;
}
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;
}
/**
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
{