--- /dev/null
+/* ****************************************************************
+ *
+ * Copyright 2016 Samsung Electronics All Rights Reserved.
+ *
+ *
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************/
+
+/**
+ * @file
+ *
+ * This file contains common utility functions to manage the CA msg
+ * fragmentation and reassemebly.
+ */
+
+
+#ifndef CA_FRAGMENTATION_H_
+#define CA_FRAGMENTATION_H_
+
+#include "cacommon.h"
+#include "logger.h"
+
+/**
+ * The MTU supported for BLE adapter
+ */
+#define CA_SUPPORTED_BLE_MTU_SIZE 20
+
+/**
+ * The maximum port value for BLE packet format
+ */
+#define CA_SUPPORTED_BLE_MAX_PORT 127
+
+/**
+ * The minimum port value for BLE packet format
+ */
+#define CA_SUPPORTED_BLE_MIN_PORT 1
+
+/**
+ * The multicaset packet remote port value
+ */
+#define CA_BLE_MULTICAST_PORT 0
+
+/**
+ * The header size for ble fragmentation.
+ * Specific header descriptions are below.
+ */
+#define CA_BLE_HEADER_SIZE 2
+
+/**
+ * The length header size for ble fragmentation.
+ * Length header is embedded in first packet of entire CoAP PDU.
+ */
+#define CA_BLE_LENGTH_HEADER_SIZE 4
+
+/**
+ * Current Header version.
+ */
+#define HEADER_VERSION 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/**
+ * This enum value is used to make the CA BLE packet header.
+ * 1st bit is used to check whether the packet is start packet or not.
+ * Start packet should be marked ad CA_BLE_PACKET_START(1) and any other
+ * packet is marked as CA_BLE_PACKET_NOT_START(0).
+ */
+typedef enum {
+ CA_BLE_PACKET_NOT_START = 0,
+ CA_BLE_PACKET_START = 1
+} CABLEPacketStart_t;
+
+/**
+ * This enum value is used to make the CA BLE packet header.
+ * 9th bit is uesd to check the packet use secure logic(dtls) or not.
+ * Secure packet should be marking CA_BLE_PACKET_SECURE(1) and other
+ * packet is makred CA_BLE_PACKET_NON_SECURE(0).
+ */
+typedef enum {
+ CA_BLE_PACKET_NON_SECURE = 0,
+ CA_BLE_PACKET_SECURE = 1
+} CABLEPacketSecure_t;
+
+
+/*****************************************************************
+ * @file The CA Header format
+ * CA Header will be defined by 2 bytes of Header.
+ * First one bit : Header type that is start packet or not.
+ * 2nd to 8th bit : Own unique port value.
+ * 9th bit: Secure type using dtls(1) or not(0).
+ * 10th to 16th bit : Remote endpoint unique port value.
+ *
+ * Start packet has additional 4 bytes size length header which
+ * represent total packet size.
+ *****************************************************************/
+
+/**
+ * This function is used to generate the CA BLE variable related to
+ * maintain the fragmentation logic. The variable is used in BLE send routine.
+ *
+ * @param[in] dataLength Original packet size about data to send.
+ * @param[out] midPacketCount Number of mid packet except first and last
+ * packet.
+ * @param[out] remainingLen Size of last packet before adding header.
+ * @param[out] totalLengh The total length of the data.
+ *
+ * @return ::CA_STATUS_OK on success. One of the CA_STATUS_FAILED
+ * or other error values on error.
+ * @retval ::CA_STATUS_OK Successful
+ * @retval ::CA_STATUS_FAILED Operation failed
+ */
+CAResult_t CAGenerateVariableForFragmentation(size_t dataLength,
+ uint32_t *midPacketCount,
+ size_t *remainingLen,
+ size_t *totalLength);
+
+/**
+ * This function is used to generate the CA BLE header to
+ * maintain the fragmentation logic. The header structure explained
+ * above will be formed and returned to the caller.
+ *
+ * @param[in,out] header Pointer to the octet array that will
+ * contain the generated header.
+ * @param[in] type Enum value to check start packet or not.
+ * it will be embedded in bit 1 of the header
+ * @param[in] sourcePort Source(own) port of the unique(in device)
+ * value. it will be embedded in bits 2~8 of
+ * the header.
+ * @param[in] secure Enum value to check whether secure or not.
+ * it will be embedded in bit 9 of the header.
+ * @param[in] destPort Destination(remote endpoint) port of the
+ * unique(in device) value. it will be embedded
+ * in bits 10~16 of the header.
+ *
+ * @return ::CA_STATUS_OK on success. One of the CA_STATUS_FAILED
+ * or other error values on error.
+ * @retval ::CA_STATUS_OK Successful
+ * @retval ::CA_STATUS_INVALID_PARAM Invalid input arguments
+ * @retval ::CA_STATUS_FAILED Operation failed
+ */
+CAResult_t CAGenerateHeader(uint8_t *header,
+ CABLEPacketStart_t type,
+ const uint8_t sourcePort,
+ CABLEPacketSecure_t secure,
+ const uint8_t destPort);
+
+/**
+ * This function is used to generate the CA BLE length header to
+ * maintain the fragmentation logic. The header structure explained
+ * above will be formed and returned to the caller.
+ *
+ * @param[in,out] header Pointer to the octet array that will
+ * contain the generated length header.
+ * @param[in] headerLength Length about header array. it should be
+ * same as CA_BLE_LENGTH_HEADER_SIZE.
+ * @param[in] dataLength The total length of data size. it will
+ * be embedded in 4 bytes of the length header.
+ *
+ * @return ::CA_STATUS_OK on success. One of the CA_STATUS_FAILED
+ * or other error values on error.
+ * @retval ::CA_STATUS_OK Successful
+ * @retval ::CA_STATUS_INVALID_PARAM Invalid input arguments
+ * @retval ::CA_STATUS_FAILED Operation failed
+ */
+CAResult_t CAGenerateHeaderPayloadLength(uint8_t *header,
+ size_t headerLength,
+ size_t dataLength);
+
+/**
+ * This function is used to make the CA BLE first data segment to
+ * maintain the fragmentation logic. start data segment is included
+ * 2 bytes header, 4 bytes length header and transmit data.
+ *
+ * @param[out] dataSegment Pointer to the octet array that will
+ * contain the generated data packet.
+ * @param[in] data Data to the octet array that required
+ * transmittin to remote device. it will
+ * be embedded in 7th byte to data length.
+ * @param[in] dataLength The length of data size.
+ * @param[in] dataHeader Pointer to the octet array that contain
+ * data header.
+ * @param[in] lengthHeader Pointer to the octet array that contain
+ * length header.
+ *
+ * @return ::CA_STATUS_OK on success. One of the CA_STATUS_FAILED
+ * or other error values on error.
+ * @retval ::CA_STATUS_OK Successful
+ * @retval ::CA_STATUS_INVALID_PARAM Invalid input arguments
+ * @retval ::CA_STATUS_FAILED Operation failed
+ */
+CAResult_t CAMakeFirstDataSegment(uint8_t *dataSegment,
+ const uint8_t *data,
+ const uint32_t dataLength,
+ const uint8_t *dataHeader,
+ const uint8_t *lengthHeader);
+
+/**
+ * This function is used to make the CA BLE second to end data segment
+ * to maintain the fragmentation logic. start data segment is included
+ * 2 bytes header and transmit data.
+ *
+ * @param[out] dataSegment Pointer to the octet array that will
+ * contain the generated data packet.
+ * @param[in] data Data to the octet array that required
+ * transmittin to remote device. it will
+ * be embedded in 7th byte to data length.
+ * @param[in] dataLength The length of data size.
+ * @param[in] index Index to determine whether some of the
+ * total data
+ * @param[in] dataHeader Pointer to the octet array that contain
+ * data header.
+ *
+ * @return ::CA_STATUS_OK on success. One of the CA_STATUS_FAILED
+ * or other error values on error.
+ * @retval ::CA_STATUS_OK Successful
+ * @retval ::CA_STATUS_INVALID_PARAM Invalid input arguments
+ * @retval ::CA_STATUS_FAILED Operation failed
+ */
+CAResult_t CAMakeRemainDataSegment(uint8_t *dataSegment,
+ const uint8_t *data,
+ const uint32_t dataLength,
+ const uint32_t index,
+ const uint8_t *dataHeader);
+
+/**
+ * This function is used to parse the header in the receiver end. This
+ * function will provide the information of the type of the packet, source(remote) /
+ * destination port info and secure infomation.
+ *
+ * @param[in] header Pointer to the octet array data which contains
+ * the header information. Note that pointer should
+ * point to two bytes of data header which needs to
+ * be parsed.
+ * @param[out] type Enum value to check start packet or not.
+ * it will be embedded in bit 1 of the header
+ * @param[out] sourcePort Source(own) port of the unique(in device)
+ * value. it will be embedded in bits 2~8 of
+ * the header.
+ * @param[out] secure Enum value to check whether secure or not.
+ * it will be embedded in bit 9 of the header.
+ * @param[out] destPort Destination(remote endpoint) port of the
+ * unique(in device) value. it will be embedded
+ * in bits 10~16 of the header.
+ *
+ * @return ::CA_STATUS_OK on success. One of the CA_STATUS_FAILED
+ * or other error values on error.
+ * @retval ::CA_STATUS_OK Successful
+ * @retval ::CA_STATUS_INVALID_PARAM Invalid input arguments
+ * @retval ::CA_STATUS_FAILED Operation failed
+ */
+CAResult_t CAParseHeader(const uint8_t *header,
+ CABLEPacketStart_t *startFlag,
+ uint16_t *sourcePort,
+ CABLEPacketSecure_t *secureFlag,
+ uint16_t *destPort);
+
+/**
+ * This function is used to parse the length header in the receiver end. This
+ * function will provide the total data length about defragmented data.
+ *
+ * @param[in] header Pointer to the octet array that will
+ * contain length infomation.
+ * @param[out] headerLength Length about header array. it should be
+ * same as CA_BLE_LENGTH_HEADER_SIZE.
+ * @param[out] dataLength The total length of data size. it will
+ * be embedded in 4 bytes of the length header.
+ *
+ * @return ::CA_STATUS_OK on success. One of the CA_STATUS_FAILED
+ * or other error values on error.
+ * @retval ::CA_STATUS_OK Successful
+ * @retval ::CA_STATUS_INVALID_PARAM Invalid input arguments
+ * @retval ::CA_STATUS_FAILED Operation failed
+ */
+CAResult_t CAParseHeaderPayloadLength(uint8_t *header,
+ size_t headerLength,
+ uint32_t *dataLength);
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif /* CA_FRAGMENTATION_H_ */
#include <stdio.h>
#include <stdlib.h>
+#include "cafragmentation.h"
+
#include "caleinterface.h"
#include "cacommon.h"
#include "camutex.h"
#define CALEADAPTER_TAG "OIC_CA_LE_ADAP"
/**
- * The MTU supported for BLE adapter
- */
-#define CA_SUPPORTED_BLE_MTU_SIZE 20
-
-/**
* Stores information of all the senders.
*
* This structure will be used to track and defragment all incoming
static CAConnectionChangeCallback g_connectionCallback = NULL;
/**
+ * Own port value to identify packet owner. Default port value is 1.
+ */
+static uint8_t g_localBLESourcePort = 1;
+
+/**
* bleAddress of the local adapter. Value will be initialized to zero,
* and will be updated later.
*/
*/
static CAErrorHandleCallback g_errorHandler = NULL;
+#ifdef SINGLE_THREAD
+/**
+ * Pointer to defragment received data from single threaded routine.
+ */
+static CABLESenderInfo_t *g_singleThreadReceiveData = NULL;
+
+/**
+ * This function will be associated with the receive for single thread.
+ *
+ * This function will defragment the received data from sender
+ * respectively and will send it up to CA layer. Respective sender's
+ * header will provide the length of the data sent.
+ *
+ * @param[in] data Actual data received from the remote
+ * device.
+ * @param[in] dataLen Length of the data received from the
+ * remote device.
+ */
+static void CALEDataReceiverHandlerSingleThread(const uint8_t *data,
+ uint32_t dataLen);
+
+/**
+ * This function will be associated with the send for single threaded
+ * GattServer.
+ *
+ * This function will fragment the data to the MTU of the transport
+ * and send the data in fragments to the adapters. The function will
+ * be blocked until all data is sent out from the adapter.
+ *
+ * @param[in] data Data to be transmitted from LE.
+ * @param[in] dataLen Length of the Data being transmitted.
+ */
+static CAResult_t CALEServerSendDataSingleThread(const uint8_t *data,
+ uint32_t dataLen);
+#endif
+
/**
* Register network change notification callback.
*
*/
static void CALERemoveReceiveQueueData(u_arraylist_t *dataInfoList,
const char* address);
+
+/**
+ * get received data info and positioned index from the received data list
+ * for client / server which is matched same leAddress and port.
+ *
+ * @param[in] leAddress target address to get serderInfo.
+ * @param[in] port target port to get serderInfo.
+ * @param[in] senderInfoList received data list for client / server.
+ * @param[out] senderInfo Pointer to contain matched(leAddress and port)
+ * received data info.
+ * @param[out] senderIndex Pointer to contain matched(leAddress and port)
+ * received data info index.
+ */
+static CAResult_t CALEGetSenderInfo(const char *leAddress,
+ const uint16_t port,
+ u_arraylist_t *senderInfoList,
+ CABLESenderInfo_t **senderInfo,
+ uint32_t *senderIndex);
+
+/**
+ * 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.
+ *
+ * @param[in] leAddress target address to get port in serderInfo.
+ * @param[in] senderInfoList received data list to remove for client / server.
+ * @param[out] portList target port list related to leAddress.
+ */
+static CAResult_t CALEGetPortsFromSenderInfo(const char *leAddress,
+ u_arraylist_t *senderInfoList,
+ u_arraylist_t *portList);
#endif
static CAResult_t CAInitLEServerQueues()
}
static CAResult_t CALEGetSenderInfo(const char *leAddress,
+ const uint16_t port,
u_arraylist_t *senderInfoList,
CABLESenderInfo_t **senderInfo,
uint32_t *senderIndex)
for (uint32_t index = 0; index < listLength; index++)
{
CABLESenderInfo_t *info = (CABLESenderInfo_t *) u_arraylist_get(senderInfoList, index);
- if(!info || !(info->remoteEndpoint))
+ if (!info || !(info->remoteEndpoint))
{
continue;
}
- if(!strncmp(info->remoteEndpoint->addr, leAddress, addrLength))
+ if (!strncmp(info->remoteEndpoint->addr, leAddress, addrLength))
{
- *senderIndex = index;
- if(senderInfo)
+ if (info->remoteEndpoint->port == port)
{
- *senderInfo = info;
+ *senderIndex = index;
+ if (senderInfo)
+ {
+ *senderInfo = info;
+ }
+ return CA_STATUS_OK;
}
- return CA_STATUS_OK;
}
}
CABLESenderInfo_t *senderInfo = NULL;
uint32_t senderIndex = 0;
- if(CA_STATUS_OK != CALEGetSenderInfo(bleData->remoteEndpoint->addr,
- bleData->senderInfo,
- &senderInfo, &senderIndex))
+ //packet parsing
+ CABLEPacketStart_t startFlag = CA_BLE_PACKET_NOT_START;
+ CABLEPacketSecure_t secureFlag = CA_BLE_PACKET_NON_SECURE;
+ uint16_t sourcePort = 0;
+ uint16_t destPort = 0;
+
+ CAParseHeader(bleData->data, &startFlag, &sourcePort, &secureFlag, &destPort);
+ OIC_LOG_V(DEBUG, CALEADAPTER_TAG,
+ "header info: startFlag[%X] sourcePort[%d] secureFlag[%X] destPort[%d]",
+ startFlag, sourcePort, secureFlag, destPort);
+
+ if (destPort != g_localBLESourcePort && destPort != CA_BLE_MULTICAST_PORT)
{
- OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "This is a new client [%s]",
- bleData->remoteEndpoint->addr);
+ OIC_LOG_V(ERROR, CALEADAPTER_TAG,
+ "this packet is not valid for this app(port mismatch[mine:%d, packet:%d])",
+ g_localBLESourcePort, destPort);
+ ca_mutex_unlock(g_bleReceiveDataMutex);
+ return;
+ }
+
+ bleData->remoteEndpoint->port = sourcePort;
+
+ if (CA_STATUS_OK != CALEGetSenderInfo(bleData->remoteEndpoint->addr,
+ bleData->remoteEndpoint->port,
+ bleData->senderInfo,
+ &senderInfo, &senderIndex))
+ {
+ OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "This is a new client [%s:%X]",
+ bleData->remoteEndpoint->addr, bleData->remoteEndpoint->port);
+ }
+ else
+ {
+ if (startFlag)
+ {
+ 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);
+ senderInfo = NULL;
+ senderIndex = 0;
+ }
}
- if(!senderInfo)
+ if (!senderInfo)
{
+ uint32_t totalLength = 0;
+ if (startFlag)
+ {
+ CAParseHeaderPayloadLength(bleData->data, CA_BLE_LENGTH_HEADER_SIZE, &totalLength);
+ }
+ else
+ {
+ OIC_LOG(ERROR, CALEADAPTER_TAG, "This packet is wrong packet! ignore.");
+ ca_mutex_unlock(g_bleReceiveDataMutex);
+ return;
+ }
+
CABLESenderInfo_t *newSender = OICMalloc(sizeof(CABLESenderInfo_t));
- if(!newSender)
+ if (!newSender)
{
OIC_LOG(ERROR, CALEADAPTER_TAG, "Memory allocation failed for new sender");
ca_mutex_unlock(g_bleReceiveDataMutex);
OIC_LOG(DEBUG, CALEADAPTER_TAG, "Parsing the header");
- newSender->totalDataLen = coap_get_total_message_length(bleData->data, bleData->dataLen);
+ newSender->totalDataLen = totalLength;
- if(!(newSender->totalDataLen))
+ if (!(newSender->totalDataLen))
{
OIC_LOG(ERROR, CALEADAPTER_TAG, "Total Data Length is parsed as 0!!!");
OICFree(newSender);
return;
}
+ size_t dataOnlyLen =
+ bleData->dataLen - (CA_BLE_HEADER_SIZE + CA_BLE_LENGTH_HEADER_SIZE);
OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "Total data to be accumulated [%u] bytes",
newSender->totalDataLen);
OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "data received in the first packet [%u] bytes",
- bleData->dataLen);
+ dataOnlyLen);
newSender->defragData = OICCalloc(newSender->totalDataLen + 1,
sizeof(*newSender->defragData));
newSender->remoteEndpoint = CACreateEndpointObject(CA_DEFAULT_FLAGS,
CA_ADAPTER_GATT_BTLE,
remoteAddress,
- 0);
+ bleData->remoteEndpoint->port);
+
if (NULL == newSender->remoteEndpoint)
{
OIC_LOG(ERROR, CALEADAPTER_TAG, "remoteEndpoint is NULL!");
return;
}
- if (newSender->recvDataLen + bleData->dataLen > newSender->totalDataLen)
+ if (newSender->recvDataLen + dataOnlyLen > newSender->totalDataLen)
{
OIC_LOG(ERROR, CALEADAPTER_TAG, "buffer is smaller than received data");
OICFree(newSender->defragData);
ca_mutex_unlock(g_bleReceiveDataMutex);
return;
}
- memcpy(newSender->defragData, bleData->data, bleData->dataLen);
- newSender->recvDataLen += bleData->dataLen;
+ memcpy(newSender->defragData,
+ bleData->data + (CA_BLE_HEADER_SIZE + CA_BLE_LENGTH_HEADER_SIZE),
+ dataOnlyLen);
+ newSender->recvDataLen += dataOnlyLen;
u_arraylist_add(bleData->senderInfo,(void *)newSender);
//Getting newSender index position in bleSenderInfo array list
- if(CA_STATUS_OK !=
- CALEGetSenderInfo(newSender->remoteEndpoint->addr, bleData->senderInfo,
- NULL, &senderIndex))
+ if (CA_STATUS_OK !=
+ CALEGetSenderInfo(newSender->remoteEndpoint->addr,
+ newSender->remoteEndpoint->port,
+ bleData->senderInfo,
+ NULL, &senderIndex))
{
OIC_LOG(ERROR, CALEADAPTER_TAG, "Existing sender index not found!!");
OICFree(newSender->defragData);
}
else
{
- if(senderInfo->recvDataLen + bleData->dataLen > senderInfo->totalDataLen)
+ size_t dataOnlyLen = bleData->dataLen - CA_BLE_HEADER_SIZE;
+ if (senderInfo->recvDataLen + dataOnlyLen > senderInfo->totalDataLen)
{
OIC_LOG_V(ERROR, CALEADAPTER_TAG,
"Data Length exceeding error!! Receiving [%d] total length [%d]",
- senderInfo->recvDataLen + bleData->dataLen, senderInfo->totalDataLen);
+ senderInfo->recvDataLen + dataOnlyLen, senderInfo->totalDataLen);
u_arraylist_remove(bleData->senderInfo, senderIndex);
OICFree(senderInfo->defragData);
OICFree(senderInfo);
return;
}
OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "Copying the data of length [%d]",
- bleData->dataLen);
- memcpy(senderInfo->defragData + senderInfo->recvDataLen, bleData->data,
- bleData->dataLen);
- senderInfo->recvDataLen += bleData->dataLen ;
+ dataOnlyLen);
+ memcpy(senderInfo->defragData + senderInfo->recvDataLen,
+ bleData->data + CA_BLE_HEADER_SIZE,
+ dataOnlyLen);
+ senderInfo->recvDataLen += dataOnlyLen;
OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "totalDatalength [%d] received Datalen [%d]",
senderInfo->totalDataLen, senderInfo->recvDataLen);
}
return;
}
- const uint32_t totalLength = bleData->dataLen;
+ uint32_t midPacketCount = 0;
+ size_t remainingLen = 0;
+ size_t totalLength = 0;
+ CABLEPacketSecure_t secureFlag = CA_BLE_PACKET_NON_SECURE;
+
+ CAResult_t result = CAGenerateVariableForFragmentation(bleData->dataLen,
+ &midPacketCount,
+ &remainingLen,
+ &totalLength);
+
+ if (CA_STATUS_OK != result)
+ {
+ OIC_LOG_V(ERROR, CALEADAPTER_TAG,
+ "CAGenerateVariableForFragmentation failed, result [%d]", result);
+ g_errorHandler(bleData->remoteEndpoint, bleData->data, bleData->dataLen, result);
+ return;
+ }
+
+ OIC_LOG_V(DEBUG, CALEADAPTER_TAG,
+ "Packet info: data size[%d] midPacketCount[%d] remainingLen[%d] totalLength[%d]",
+ bleData->dataLen, midPacketCount, remainingLen, totalLength);
OIC_LOG_V(DEBUG,
CALEADAPTER_TAG,
"Server total Data length with header is [%u]",
totalLength);
- uint8_t * const dataSegment = OICCalloc(totalLength, 1);
+ uint8_t dataSegment[CA_SUPPORTED_BLE_MTU_SIZE] = {0};
+ uint8_t dataHeader[CA_BLE_HEADER_SIZE] = {0};
+
+ if (NULL != bleData->remoteEndpoint) //Unicast Data
+ {
+ secureFlag = bleData->remoteEndpoint->flags == CA_SECURE ?
+ CA_BLE_PACKET_SECURE : CA_BLE_PACKET_NON_SECURE;
+
+ result = CAGenerateHeader(dataHeader,
+ CA_BLE_PACKET_START,
+ g_localBLESourcePort,
+ secureFlag,
+ bleData->remoteEndpoint->port);
+ }
+ else //Multicast Data
+ {
+ result = CAGenerateHeader(dataHeader,
+ CA_BLE_PACKET_START,
+ g_localBLESourcePort,
+ secureFlag,
+ CA_BLE_MULTICAST_PORT);
+ }
- if (NULL == dataSegment)
+ if (CA_STATUS_OK != result)
{
- OIC_LOG(ERROR, CALEADAPTER_TAG, "Malloc failed");
+ OIC_LOG_V(ERROR, CALEADAPTER_TAG,
+ "CAGenerateHeader failed, result [%d]", result);
+ g_errorHandler(bleData->remoteEndpoint, bleData->data, bleData->dataLen, result);
+ return;
+ }
+
+ uint8_t lengthHeader[CA_BLE_LENGTH_HEADER_SIZE] = {0};
+ result = CAGenerateHeaderPayloadLength(lengthHeader,
+ CA_BLE_LENGTH_HEADER_SIZE,
+ bleData->dataLen);
+
+ if (CA_STATUS_OK != result)
+ {
+ OIC_LOG_V(ERROR, CALEADAPTER_TAG,
+ "CAGenerateHeaderPayloadLength failed, result [%d]", result);
+ g_errorHandler(bleData->remoteEndpoint, bleData->data, bleData->dataLen, result);
return;
}
uint32_t length = 0;
+ uint32_t dataLen = 0;
if (CA_SUPPORTED_BLE_MTU_SIZE > totalLength)
{
length = totalLength;
- memcpy(dataSegment, bleData->data, bleData->dataLen);
+ dataLen = bleData->dataLen;
}
else
{
- length = CA_SUPPORTED_BLE_MTU_SIZE;
- memcpy(dataSegment, bleData->data, CA_SUPPORTED_BLE_MTU_SIZE);
+ length = CA_SUPPORTED_BLE_MTU_SIZE;
+ dataLen = CA_SUPPORTED_BLE_MTU_SIZE - CA_BLE_HEADER_SIZE - CA_BLE_LENGTH_HEADER_SIZE;
+ }
+
+ result = CAMakeFirstDataSegment(dataSegment,
+ bleData->data, dataLen,
+ dataHeader, lengthHeader);
+
+ if (CA_STATUS_OK != result)
+ {
+ OIC_LOG_V(ERROR, CALEADAPTER_TAG,
+ "Making data segment failed, result [%d]", result);
+ g_errorHandler(bleData->remoteEndpoint, bleData->data, bleData->dataLen, result);
+ return;
}
- uint32_t iter = totalLength / CA_SUPPORTED_BLE_MTU_SIZE;
+ const uint32_t iter = midPacketCount;
uint32_t index = 0;
- CAResult_t result = CA_STATUS_FAILED;
// Send the first segment with the header.
if (NULL != bleData->remoteEndpoint) // Sending Unicast Data
bleData->data,
bleData->dataLen,
result);
- OICFree(dataSegment);
return;
}
CALEADAPTER_TAG,
"Server Sent data length [%u]",
length);
- for (index = 1; index < iter; index++)
+
+ result = CAGenerateHeader(dataHeader,
+ CA_BLE_PACKET_NOT_START,
+ g_localBLESourcePort,
+ secureFlag,
+ bleData->remoteEndpoint->port);
+
+ if (CA_STATUS_OK != result)
+ {
+ OIC_LOG_V(ERROR, CALEADAPTER_TAG,
+ "CAGenerateHeader failed, result [%d]", result);
+ g_errorHandler(bleData->remoteEndpoint, bleData->data, bleData->dataLen, result);
+ return;
+ }
+
+ for (index = 0; index < iter; index++)
{
// Send the remaining header.
OIC_LOG_V(DEBUG,
"Sending the chunk number [%u]",
index);
+ result = CAMakeRemainDataSegment(dataSegment,
+ bleData->data,
+ CA_SUPPORTED_BLE_MTU_SIZE - CA_BLE_HEADER_SIZE,
+ index,
+ dataHeader);
+
+ if (CA_STATUS_OK != result)
+ {
+ OIC_LOG_V(ERROR, CALEADAPTER_TAG,
+ "Making data segment failed, result [%d]", result);
+ g_errorHandler(bleData->remoteEndpoint, bleData->data, bleData->dataLen, result);
+ return;
+ }
+
result =
CAUpdateCharacteristicsToGattClient(
bleData->remoteEndpoint->addr,
- bleData->data + ((index * CA_SUPPORTED_BLE_MTU_SIZE)),
+ dataSegment,
CA_SUPPORTED_BLE_MTU_SIZE);
if (CA_STATUS_OK != result)
OIC_LOG_V(ERROR, CALEADAPTER_TAG,
"Update characteristics failed, result [%d]", result);
g_errorHandler(bleData->remoteEndpoint, bleData->data, bleData->dataLen, result);
- OICFree(dataSegment);
return;
}
OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "Server Sent data length [%d]",
CA_SUPPORTED_BLE_MTU_SIZE);
}
- const uint32_t remainingLen =
- totalLength % CA_SUPPORTED_BLE_MTU_SIZE;
-
if (remainingLen && (totalLength > CA_SUPPORTED_BLE_MTU_SIZE))
{
// send the last segment of the data (Ex: 22 bytes of 622
// bytes of data when MTU is 200)
OIC_LOG(DEBUG, CALEADAPTER_TAG, "Sending the last chunk");
+ result = CAMakeRemainDataSegment(dataSegment,
+ bleData->data,
+ remainingLen,
+ index,
+ dataHeader);
+
+ if (CA_STATUS_OK != result)
+ {
+ OIC_LOG_V(ERROR, CALEADAPTER_TAG,
+ "Making data segment failed, result [%d]", result);
+ g_errorHandler(bleData->remoteEndpoint, bleData->data, bleData->dataLen, result);
+ return;
+ }
+
result = CAUpdateCharacteristicsToGattClient(
bleData->remoteEndpoint->addr,
- bleData->data + (index * CA_SUPPORTED_BLE_MTU_SIZE),
- remainingLen);
+ dataSegment,
+ remainingLen + CA_BLE_HEADER_SIZE);
if (CA_STATUS_OK != result)
{
bleData->data,
bleData->dataLen,
result);
- OICFree(dataSegment);
return;
}
- OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "Server Sent data length [%d]", remainingLen);
+ OIC_LOG_V(DEBUG, CALEADAPTER_TAG,
+ "Server Sent data length [%d]", remainingLen + CA_BLE_HEADER_SIZE);
}
}
else
OIC_LOG_V(ERROR, CALEADAPTER_TAG, "Update characteristics failed, result [%d]",
result);
CALEErrorHandler(NULL, bleData->data, bleData->dataLen, result);
- OICFree(dataSegment);
return;
}
OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "Server Sent data length [%d]", length);
- for (index = 1; index < iter; index++)
+
+ result = CAGenerateHeader(dataHeader,
+ CA_BLE_PACKET_NOT_START,
+ g_localBLESourcePort,
+ secureFlag,
+ CA_BLE_MULTICAST_PORT);
+
+ if (CA_STATUS_OK != result)
+ {
+ OIC_LOG_V(ERROR, CALEADAPTER_TAG,
+ "CAGenerateHeader failed, result [%d]", result);
+ g_errorHandler(bleData->remoteEndpoint, bleData->data, bleData->dataLen, result);
+ return;
+ }
+
+ for (index = 0; index < iter; index++)
{
// Send the remaining header.
OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "Sending the chunk number [%d]", index);
+ result = CAMakeRemainDataSegment(dataSegment,
+ bleData->data,
+ CA_SUPPORTED_BLE_MTU_SIZE - CA_BLE_HEADER_SIZE,
+ index,
+ dataHeader);
+
+ if (CA_STATUS_OK != result)
+ {
+ OIC_LOG_V(ERROR, CALEADAPTER_TAG,
+ "Making data segment failed, result [%d]", result);
+ g_errorHandler(bleData->remoteEndpoint, bleData->data, bleData->dataLen, result);
+ return;
+ }
+
result = CAUpdateCharacteristicsToAllGattClients(
- bleData->data + ((index * CA_SUPPORTED_BLE_MTU_SIZE)),
+ dataSegment,
CA_SUPPORTED_BLE_MTU_SIZE);
if (CA_STATUS_OK != result)
OIC_LOG_V(ERROR, CALEADAPTER_TAG, "Update characteristics failed, result [%d]",
result);
CALEErrorHandler(NULL, bleData->data, bleData->dataLen, result);
- OICFree(dataSegment);
return;
}
OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "Server Sent data length [%u]",
CA_SUPPORTED_BLE_MTU_SIZE);
}
- const uint32_t remainingLen = totalLength % CA_SUPPORTED_BLE_MTU_SIZE;
if (remainingLen && (totalLength > CA_SUPPORTED_BLE_MTU_SIZE))
{
// send the last segment of the data
OIC_LOG(DEBUG, CALEADAPTER_TAG, "Sending the last chunk");
+ result = CAMakeRemainDataSegment(dataSegment,
+ bleData->data,
+ remainingLen,
+ index,
+ dataHeader);
+
+ if (CA_STATUS_OK != result)
+ {
+ OIC_LOG_V(ERROR, CALEADAPTER_TAG,
+ "Making data segment failed, result [%d]", result);
+ g_errorHandler(bleData->remoteEndpoint, bleData->data, bleData->dataLen, result);
+ return;
+ }
+
result = CAUpdateCharacteristicsToAllGattClients(
- bleData->data + (index * CA_SUPPORTED_BLE_MTU_SIZE),
- remainingLen);
+ dataSegment,
+ remainingLen + CA_BLE_HEADER_SIZE);
if (CA_STATUS_OK != result)
{
OIC_LOG_V(ERROR, CALEADAPTER_TAG, "Update characteristics failed, result [%d]",
result);
CALEErrorHandler(NULL, bleData->data, bleData->dataLen, result);
- OICFree(dataSegment);
return;
}
- OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "Server Sent data length [%d]", remainingLen);
+ OIC_LOG_V(DEBUG, CALEADAPTER_TAG,
+ "Server Sent data length [%d]", remainingLen + CA_BLE_HEADER_SIZE);
}
}
- OICFree(dataSegment);
OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT - CALEServerSendDataThread");
}
return;
}
- const uint32_t totalLength = bleData->dataLen;
+ uint32_t midPacketCount = 0;
+ size_t remainingLen = 0;
+ size_t totalLength = 0;
+ CABLEPacketSecure_t secureFlag = CA_BLE_PACKET_NON_SECURE;
+
+ CAResult_t result = CAGenerateVariableForFragmentation(bleData->dataLen,
+ &midPacketCount,
+ &remainingLen,
+ &totalLength);
- uint8_t *dataSegment = OICCalloc(totalLength, 1);
- if (NULL == dataSegment)
+ if (CA_STATUS_OK != result)
{
- OIC_LOG(ERROR, CALEADAPTER_TAG, "Malloc failed");
+ OIC_LOG_V(ERROR, CALEADAPTER_TAG,
+ "CAGenerateVariableForFragmentation failed, result [%d]", result);
+ g_errorHandler(bleData->remoteEndpoint, bleData->data, bleData->dataLen, result);
+ return;
+ }
+
+ OIC_LOG_V(DEBUG, CALEADAPTER_TAG,
+ "Packet info: data size[%d] midPacketCount[%d] remainingLen[%d] totalLength[%d]",
+ bleData->dataLen, midPacketCount, remainingLen, totalLength);
+
+ uint8_t dataSegment[CA_SUPPORTED_BLE_MTU_SIZE] = {0};
+ uint8_t dataHeader[CA_BLE_HEADER_SIZE] = {0};
+
+ if (NULL != bleData->remoteEndpoint) //Unicast Data
+ {
+ secureFlag = bleData->remoteEndpoint->flags == CA_SECURE ?
+ CA_BLE_PACKET_SECURE : CA_BLE_PACKET_NON_SECURE;
+
+ result = CAGenerateHeader(dataHeader,
+ CA_BLE_PACKET_START,
+ g_localBLESourcePort,
+ secureFlag,
+ bleData->remoteEndpoint->port);
+ }
+ else //Multicast Data
+ {
+ result = CAGenerateHeader(dataHeader,
+ CA_BLE_PACKET_START,
+ g_localBLESourcePort,
+ secureFlag,
+ CA_BLE_MULTICAST_PORT);
+ }
+
+ if (CA_STATUS_OK != result)
+ {
+ OIC_LOG_V(ERROR, CALEADAPTER_TAG,
+ "CAGenerateHeader failed, result [%d]", result);
+ g_errorHandler(bleData->remoteEndpoint, bleData->data, bleData->dataLen, result);
+ return;
+ }
+
+ uint8_t lengthHeader[CA_BLE_LENGTH_HEADER_SIZE] = {0};
+ result = CAGenerateHeaderPayloadLength(lengthHeader,
+ CA_BLE_LENGTH_HEADER_SIZE,
+ bleData->dataLen);
+
+ if (CA_STATUS_OK != result)
+ {
+ OIC_LOG_V(ERROR, CALEADAPTER_TAG,
+ "CAGenerateHeaderPayloadLength failed, result [%d]", result);
+ g_errorHandler(bleData->remoteEndpoint, bleData->data, bleData->dataLen, result);
return;
}
uint32_t length = 0;
+ uint32_t dataLen = 0;
if (CA_SUPPORTED_BLE_MTU_SIZE > totalLength)
{
length = totalLength;
- memcpy(dataSegment,
- bleData->data,
- bleData->dataLen);
+ dataLen = bleData->dataLen;
}
else
{
length = CA_SUPPORTED_BLE_MTU_SIZE;
- memcpy(dataSegment,
- bleData->data,
- CA_SUPPORTED_BLE_MTU_SIZE);
+ dataLen = CA_SUPPORTED_BLE_MTU_SIZE - CA_BLE_HEADER_SIZE - CA_BLE_LENGTH_HEADER_SIZE;
}
- CAResult_t result = CA_STATUS_FAILED;
- const uint32_t iter = totalLength / CA_SUPPORTED_BLE_MTU_SIZE;
+ result = CAMakeFirstDataSegment(dataSegment,
+ bleData->data, dataLen,
+ dataHeader, lengthHeader);
+
+ if (CA_STATUS_OK != result)
+ {
+ OIC_LOG_V(ERROR, CALEADAPTER_TAG,
+ "Making data segment failed, result [%d]", result);
+ g_errorHandler(bleData->remoteEndpoint, bleData->data, bleData->dataLen, result);
+ return;
+ }
+
+ const uint32_t iter = midPacketCount;
uint32_t index = 0;
if (NULL != bleData->remoteEndpoint) //Sending Unicast Data
{
bleData->data,
bleData->dataLen,
result);
- OICFree(dataSegment);
return;
}
"Client Sent Data length is [%u]",
length);
- for (index = 1; index < iter; index++)
+ result = CAGenerateHeader(dataHeader,
+ CA_BLE_PACKET_NOT_START,
+ g_localBLESourcePort,
+ secureFlag,
+ bleData->remoteEndpoint->port);
+
+ if (CA_STATUS_OK != result)
{
+ OIC_LOG_V(ERROR, CALEADAPTER_TAG,
+ "CAGenerateHeader failed, result [%d]", result);
+ g_errorHandler(bleData->remoteEndpoint, bleData->data, bleData->dataLen, result);
+ return;
+ }
+
+ for (index = 0; index < iter; index++)
+ {
+ result = CAMakeRemainDataSegment(dataSegment,
+ bleData->data,
+ CA_SUPPORTED_BLE_MTU_SIZE - CA_BLE_HEADER_SIZE,
+ index,
+ dataHeader);
+
+ if (CA_STATUS_OK != result)
+ {
+ OIC_LOG_V(ERROR, CALEADAPTER_TAG,
+ "Making data segment failed, result [%d]", result);
+ g_errorHandler(bleData->remoteEndpoint, bleData->data, bleData->dataLen, result);
+ return;
+ }
+
// Send the remaining header.
result = CAUpdateCharacteristicsToGattServer(
bleData->remoteEndpoint->addr,
- bleData->data + (index * CA_SUPPORTED_BLE_MTU_SIZE),
+ dataSegment,
CA_SUPPORTED_BLE_MTU_SIZE,
LE_UNICAST, 0);
"Update characteristics failed, result [%d]",
result);
g_errorHandler(bleData->remoteEndpoint, bleData->data, bleData->dataLen, result);
- OICFree(dataSegment);
return;
}
OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "Client Sent Data length is [%d]",
CA_SUPPORTED_BLE_MTU_SIZE);
}
- const uint32_t remainingLen = totalLength % CA_SUPPORTED_BLE_MTU_SIZE;
if (remainingLen && (totalLength > CA_SUPPORTED_BLE_MTU_SIZE))
{
// send the last segment of the data (Ex: 22 bytes of 622
// bytes of data when MTU is 200)
OIC_LOG(DEBUG, CALEADAPTER_TAG, "Sending the last chunk");
+ result = CAMakeRemainDataSegment(dataSegment,
+ bleData->data,
+ remainingLen,
+ index,
+ dataHeader);
+
+ if (CA_STATUS_OK != result)
+ {
+ OIC_LOG_V(ERROR, CALEADAPTER_TAG,
+ "Making data segment failed, result [%d]", result);
+ g_errorHandler(bleData->remoteEndpoint, bleData->data, bleData->dataLen, result);
+ return;
+ }
+
result = CAUpdateCharacteristicsToGattServer(
bleData->remoteEndpoint->addr,
- bleData->data + (index * CA_SUPPORTED_BLE_MTU_SIZE),
- remainingLen,
+ dataSegment,
+ remainingLen + CA_BLE_HEADER_SIZE,
LE_UNICAST, 0);
if (CA_STATUS_OK != result)
OIC_LOG_V(ERROR, CALEADAPTER_TAG, "Update characteristics failed, result [%d]",
result);
g_errorHandler(bleData->remoteEndpoint, bleData->data, bleData->dataLen, result);
- OICFree(dataSegment);
return;
}
- OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "Client Sent Data length is [%d]", remainingLen);
+ OIC_LOG_V(DEBUG, CALEADAPTER_TAG,
+ "Client Sent Data length is [%d]", remainingLen + CA_BLE_HEADER_SIZE);
}
}
else
OIC_LOG_V(ERROR, CALEADAPTER_TAG,
"Update characteristics (all) failed, result [%d]", result);
CALEErrorHandler(NULL, bleData->data, bleData->dataLen, result);
- OICFree(dataSegment);
return ;
}
OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "Client Sent Data length is [%d]", length);
+
+ result = CAGenerateHeader(dataHeader,
+ CA_BLE_PACKET_NOT_START,
+ g_localBLESourcePort,
+ secureFlag,
+ 0);
+
+ if (CA_STATUS_OK != result)
+ {
+ OIC_LOG_V(ERROR, CALEADAPTER_TAG,
+ "CAGenerateHeader failed, result [%d]", result);
+ g_errorHandler(bleData->remoteEndpoint, bleData->data, bleData->dataLen, result);
+ return;
+ }
+
// Send the remaining header.
- for (index = 1; index < iter; index++)
+ for (index = 0; index < iter; index++)
{
+ result = CAMakeRemainDataSegment(dataSegment,
+ bleData->data,
+ CA_SUPPORTED_BLE_MTU_SIZE - CA_BLE_HEADER_SIZE,
+ index,
+ dataHeader);
+
+ if (CA_STATUS_OK != result)
+ {
+ OIC_LOG_V(ERROR, CALEADAPTER_TAG,
+ "Making data segment failed, result [%d]", result);
+ g_errorHandler(bleData->remoteEndpoint, bleData->data, bleData->dataLen, result);
+ return;
+ }
+
result = CAUpdateCharacteristicsToAllGattServers(
- bleData->data + (index * CA_SUPPORTED_BLE_MTU_SIZE),
+ dataSegment,
CA_SUPPORTED_BLE_MTU_SIZE);
if (CA_STATUS_OK != result)
OIC_LOG_V(ERROR, CALEADAPTER_TAG, "Update characteristics failed, result [%d]",
result);
CALEErrorHandler(NULL, bleData->data, bleData->dataLen, result);
- OICFree(dataSegment);
return;
}
OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "Client Sent Data length is [%d]",
CA_SUPPORTED_BLE_MTU_SIZE);
}
- uint32_t remainingLen = totalLength % CA_SUPPORTED_BLE_MTU_SIZE;
if (remainingLen && (totalLength > CA_SUPPORTED_BLE_MTU_SIZE))
{
// send the last segment of the data (Ex: 22 bytes of 622
// bytes of data when MTU is 200)
OIC_LOG(DEBUG, CALEADAPTER_TAG, "Sending the last chunk");
+
+ result = CAMakeRemainDataSegment(dataSegment,
+ bleData->data,
+ remainingLen,
+ index,
+ dataHeader);
+
+ if (CA_STATUS_OK != result)
+ {
+ OIC_LOG_V(ERROR, CALEADAPTER_TAG,
+ "Making data segment failed, result [%d]", result);
+ g_errorHandler(bleData->remoteEndpoint, bleData->data, bleData->dataLen, result);
+ return;
+ }
+
result =
CAUpdateCharacteristicsToAllGattServers(
- bleData->data + (index * CA_SUPPORTED_BLE_MTU_SIZE),
- remainingLen);
+ dataSegment,
+ remainingLen + CA_BLE_HEADER_SIZE);
if (CA_STATUS_OK != result)
{
OIC_LOG_V(ERROR, CALEADAPTER_TAG,
"Update characteristics (all) failed, result [%d]", result);
CALEErrorHandler(NULL, bleData->data, bleData->dataLen, result);
- OICFree(dataSegment);
return;
}
- OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "Client Sent Data length is [%d]", remainingLen);
+ OIC_LOG_V(DEBUG, CALEADAPTER_TAG,
+ "Client Sent Data length is [%d]", remainingLen + CA_BLE_HEADER_SIZE);
}
-
}
- OICFree(dataSegment);
-
OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT - CABLEClientSendDataThread");
}
}
#endif
+#ifdef SINGLE_THREAD
+static void CALEDataReceiverHandlerSingleThread(const uint8_t *data,
+ uint32_t dataLen)
+{
+ OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN");
+
+ VERIFY_NON_NULL(data, CALEADAPTER_TAG, "Param data is NULL");
+
+ //packet parsing
+ CABLEPacketStart_t startFlag = CA_BLE_PACKET_NOT_START;
+ CABLEPacketSecure_t secureFlag = CA_BLE_PACKET_NON_SECURE;
+ uint16_t sourcePort = 0;
+ uint16_t destPort = 0;
+
+ CAParseHeader(data, &startFlag, &sourcePort, &secureFlag, &destPort);
+ OIC_LOG_V(DEBUG, CALEADAPTER_TAG,
+ "header info: startFlag[%X] sourcePort[%d] secureFlag[%X] destPort[%d]",
+ startFlag, sourcePort, secureFlag, destPort);
+
+ if (destPort != g_localBLESourcePort && destPort != CA_BLE_MULTICAST_PORT)
+ {
+ OIC_LOG_V(ERROR, CALEADAPTER_TAG,
+ "this packet is not valid for this app(port mismatch[mine:%d, packet:%d])",
+ g_localBLESourcePort, destPort);
+ return;
+ }
+
+ if (startFlag)
+ {
+ if (g_singleThreadReceiveData)
+ {
+ OIC_LOG(ERROR, CALEADAPTER_TAG,
+ "This packet is start packet but exist senderInfo. Remove senderInfo");
+ OICFree(g_singleThreadReceiveData->defragData);
+ OICFree(g_singleThreadReceiveData);
+ g_singleThreadReceiveData = NULL;
+ }
+
+ uint32_t totalLength = 0;
+ CAParseHeaderPayloadLength(data, CA_BLE_LENGTH_HEADER_SIZE, &totalLength);
+
+ g_singleThreadReceiveData = OICMalloc(sizeof(CABLESenderInfo_t));
+
+ if (!g_singleThreadReceiveData)
+ {
+ OIC_LOG(ERROR, CALEADAPTER_TAG, "Memory allocation failed for new sender");
+ return;
+ }
+ g_singleThreadReceiveData->recvDataLen = 0;
+ g_singleThreadReceiveData->totalDataLen = 0;
+ g_singleThreadReceiveData->defragData = NULL;
+ g_singleThreadReceiveData->remoteEndpoint = NULL;
+
+ OIC_LOG(DEBUG, CALEADAPTER_TAG, "Parsing the header");
+
+ g_singleThreadReceiveData->totalDataLen = totalLength;
+
+ if (!(g_singleThreadReceiveData->totalDataLen))
+ {
+ OIC_LOG(ERROR, CALEADAPTER_TAG, "Total Data Length is parsed as 0!!!");
+ OICFree(g_singleThreadReceiveData);
+ return;
+ }
+
+ size_t dataOnlyLen = dataLen - (CA_BLE_HEADER_SIZE + CA_BLE_LENGTH_HEADER_SIZE);
+ OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "Total data to be accumulated [%u] bytes",
+ g_singleThreadReceiveData->totalDataLen);
+ OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "data received in the first packet [%u] bytes",
+ dataOnlyLen);
+
+ g_singleThreadReceiveData->defragData =
+ OICCalloc(g_singleThreadReceiveData->totalDataLen + 1,
+ sizeof(*g_singleThreadReceiveData->defragData));
+
+ if (NULL == g_singleThreadReceiveData->defragData)
+ {
+ OIC_LOG(ERROR, CALEADAPTER_TAG, "defragData is NULL!");
+ OICFree(g_singleThreadReceiveData);
+ return;
+ }
+
+ if (g_singleThreadReceiveData->recvDataLen + dataOnlyLen
+ > g_singleThreadReceiveData->totalDataLen)
+ {
+ OIC_LOG(ERROR, CALEADAPTER_TAG, "buffer is smaller than received data");
+ OICFree(g_singleThreadReceiveData->defragData);
+ OICFree(g_singleThreadReceiveData);
+ return;
+ }
+ memcpy(g_singleThreadReceiveData->defragData,
+ data + (CA_BLE_HEADER_SIZE + CA_BLE_LENGTH_HEADER_SIZE),
+ dataOnlyLen);
+ g_singleThreadReceiveData->recvDataLen += dataOnlyLen;
+ }
+ else
+ {
+ size_t dataOnlyLen = dataLen - CA_BLE_HEADER_SIZE;
+ if (g_singleThreadReceiveData->recvDataLen + dataOnlyLen
+ > g_singleThreadReceiveData->totalDataLen)
+ {
+ OIC_LOG_V(ERROR, CALEADAPTER_TAG,
+ "Data Length exceeding error!! Receiving [%d] total length [%d]",
+ g_singleThreadReceiveData->recvDataLen + dataOnlyLen,
+ g_singleThreadReceiveData->totalDataLen);
+ OICFree(g_singleThreadReceiveData->defragData);
+ OICFree(g_singleThreadReceiveData);
+ return;
+ }
+ OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "Copying the data of length [%d]",
+ dataOnlyLen);
+ memcpy(g_singleThreadReceiveData->defragData + g_singleThreadReceiveData->recvDataLen,
+ data + CA_BLE_HEADER_SIZE,
+ dataOnlyLen);
+ g_singleThreadReceiveData->recvDataLen += dataOnlyLen;
+ OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "totalDatalength [%d] received Datalen [%d]",
+ g_singleThreadReceiveData->totalDataLen, g_singleThreadReceiveData->recvDataLen);
+ }
+}
+
+static CAResult_t CALEServerSendDataSingleThread(const uint8_t *data,
+ uint32_t dataLen)
+{
+ OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN");
+
+ VERIFY_NON_NULL(data, CALEADAPTER_TAG, "Param data is NULL");
+
+ uint32_t midPacketCount = 0;
+ size_t remainingLen = 0;
+ size_t totalLength = 0;
+ CABLEPacketSecure_t secureFlag = CA_BLE_PACKET_NON_SECURE;
+
+ CAResult_t result = CAGenerateVariableForFragmentation(dataLen,
+ &midPacketCount,
+ &remainingLen,
+ &totalLength);
+
+ if (CA_STATUS_OK != result)
+ {
+ OIC_LOG_V(ERROR, CALEADAPTER_TAG,
+ "CAGenerateVariableForFragmentation failed, result [%d]", result);
+ return result;
+ }
+
+ OIC_LOG_V(DEBUG, CALEADAPTER_TAG,
+ "Packet info: data size[%d] midPacketCount[%d] remainingLen[%d] totalLength[%d]",
+ dataLen, midPacketCount, remainingLen, totalLength);
+
+ OIC_LOG_V(DEBUG,
+ CALEADAPTER_TAG,
+ "Server total Data length with header is [%u]",
+ totalLength);
+
+ uint8_t dataSegment[CA_SUPPORTED_BLE_MTU_SIZE] = {0};
+ uint8_t dataHeader[CA_BLE_HEADER_SIZE] = {0};
+
+ result = CAGenerateHeader(dataHeader,
+ CA_BLE_PACKET_START,
+ g_localBLESourcePort,
+ CA_BLE_PACKET_NON_SECURE,
+ CA_BLE_MULTICAST_PORT);
+
+ if (CA_STATUS_OK != result)
+ {
+ OIC_LOG_V(ERROR, CALEADAPTER_TAG,
+ "CAGenerateHeader failed, result [%d]", result);
+ return result;
+ }
+
+ uint8_t lengthHeader[CA_BLE_LENGTH_HEADER_SIZE] = {0};
+ result = CAGenerateHeaderPayloadLength(lengthHeader,
+ CA_BLE_LENGTH_HEADER_SIZE,
+ dataLen);
+
+ if (CA_STATUS_OK != result)
+ {
+ OIC_LOG_V(ERROR, CALEADAPTER_TAG,
+ "CAGenerateHeaderPayloadLength failed, result [%d]", result);
+ return result;
+ }
+
+ uint32_t length = 0;
+ uint32_t dataOnlyLen = 0;
+ if (CA_SUPPORTED_BLE_MTU_SIZE > totalLength)
+ {
+ length = totalLength;
+ dataOnlyLen = dataLen;
+ }
+ else
+ {
+ length = CA_SUPPORTED_BLE_MTU_SIZE;
+ dataOnlyLen = CA_SUPPORTED_BLE_MTU_SIZE - CA_BLE_HEADER_SIZE - CA_BLE_LENGTH_HEADER_SIZE;
+ }
+
+ result = CAMakeFirstDataSegment(dataSegment,
+ data, dataOnlyLen,
+ dataHeader, lengthHeader);
+
+ if (CA_STATUS_OK != result)
+ {
+ OIC_LOG_V(ERROR, CALEADAPTER_TAG,
+ "Making data segment failed, result [%d]", result);
+ return result;
+ }
+
+ OIC_LOG(DEBUG, CALEADAPTER_TAG, "Server Sending Multicast data");
+ result = CAUpdateCharacteristicsToAllGattClients(dataSegment, length);
+ if (CA_STATUS_OK != result)
+ {
+ OIC_LOG_V(ERROR, CALEADAPTER_TAG, "Update characteristics failed, result [%d]",
+ result);
+ return result;
+ }
+
+ CALEDoEvents();
+
+ OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "Server Sent data length [%d]", length);
+
+ result = CAGenerateHeader(dataHeader,
+ CA_BLE_PACKET_NOT_START,
+ g_localBLESourcePort,
+ CA_BLE_PACKET_NON_SECURE,
+ CA_BLE_MULTICAST_PORT);
+
+ if (CA_STATUS_OK != result)
+ {
+ OIC_LOG_V(ERROR, CALEADAPTER_TAG,
+ "CAGenerateHeader failed, result [%d]", result);
+ return result;
+ }
+
+ const uint32_t dataLimit = midPacketCount;
+ for (uint32_t iter = 0; iter < dataLimit; iter++)
+ {
+ result = CAMakeRemainDataSegment(dataSegment,
+ data,
+ CA_SUPPORTED_BLE_MTU_SIZE - CA_BLE_HEADER_SIZE,
+ iter,
+ dataHeader);
+
+ if (CA_STATUS_OK != result)
+ {
+ OIC_LOG_V(ERROR, CALEADAPTER_TAG,
+ "Making data segment failed, result [%d]", result);
+ return result;
+ }
+
+ result = CAUpdateCharacteristicsToAllGattClients(
+ dataSegment,
+ CA_SUPPORTED_BLE_MTU_SIZE);
+
+ if (CA_STATUS_OK != result)
+ {
+ OIC_LOG(ERROR, CALEADAPTER_TAG, "Update characteristics failed");
+ return result;
+ }
+
+ CALEDoEvents();
+ }
+
+ if (remainingLen && (totalLength > CA_SUPPORTED_BLE_MTU_SIZE))
+ {
+ // send the last segment of the data
+ OIC_LOG(DEBUG, CALEADAPTER_TAG, "Sending the last chunk");
+
+ result = CAMakeRemainDataSegment(dataSegment,
+ data,
+ remainingLen,
+ dataLimit,
+ dataHeader);
+
+ if (CA_STATUS_OK != result)
+ {
+ OIC_LOG_V(ERROR, CALEADAPTER_TAG,
+ "Making data segment failed, result [%d]", result);
+ return result;
+ }
+
+ result = CAUpdateCharacteristicsToAllGattClients(
+ dataSegment,
+ remainingLen + CA_BLE_HEADER_SIZE);
+
+ if (CA_STATUS_OK != result)
+ {
+ OIC_LOG(ERROR, CALEADAPTER_TAG, "Update characteristics failed");
+ return result;
+ }
+ CALEDoEvents();
+ }
+
+ return result;
+}
+#endif
+
static CAResult_t CAInitLEAdapterMutex()
{
OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN - CAInitLEAdapterMutex");
return CA_STATUS_FAILED;
}
- CAResult_t result = CA_STATUS_OK;
- const uint32_t dataLimit = dataLen / CA_SUPPORTED_BLE_MTU_SIZE;
- for (uint32_t iter = 0; iter < dataLimit; iter++)
- {
- result =
- CAUpdateCharacteristicsToAllGattClients(
- data + (iter * CA_SUPPORTED_BLE_MTU_SIZE),
- CA_SUPPORTED_BLE_MTU_SIZE);
-
- if (CA_STATUS_OK != result)
- {
- OIC_LOG(ERROR, CALEADAPTER_TAG, "Update characteristics failed");
- return CA_STATUS_FAILED;
- }
-
- CALEDoEvents();
- }
-
- const uint32_t remainingLen = dataLen % CA_SUPPORTED_BLE_MTU_SIZE;
- if (remainingLen)
+ CAResult_t result = CALEServerSendDataSingleThread(data, dataLen);
+ if (CA_STATUS_OK != result)
{
- result =
- CAUpdateCharacteristicsToAllGattClients(
- data + (dataLimit * CA_SUPPORTED_BLE_MTU_SIZE),
- remainingLen);
- if (CA_STATUS_OK != result)
- {
- OIC_LOG(ERROR, CALEADAPTER_TAG, "Update characteristics failed");
- return CA_STATUS_FAILED;
- }
- CALEDoEvents();
+ OIC_LOG(ERROR, CALEADAPTER_TAG, "CALEServerSendDataSingleThread failed");
+ return CA_STATUS_FAILED;
}
#else
VERIFY_NON_NULL_RET(g_bleServerSendQueueHandle, CALEADAPTER_TAG,
VERIFY_NON_NULL(sentLength, CALEADAPTER_TAG, "Sent data length holder is null");
#ifdef SINGLE_THREAD
- if(g_networkPacketReceivedCallback)
- {
- // will be filled by upper layer
- const CASecureEndpoint_t endpoint =
- { .endpoint = { .adapter = CA_ADAPTER_GATT_BTLE } };
+ CALEDataReceiverHandlerSingleThread(data, dataLength);
+ if (g_singleThreadReceiveData->totalDataLen == g_singleThreadReceiveData->recvDataLen)
+ {
+ if(g_networkPacketReceivedCallback)
+ {
+ // will be filled by upper layer
+ const CASecureEndpoint_t endpoint =
+ { .endpoint = { .adapter = CA_ADAPTER_GATT_BTLE } };
- g_networkPacketReceivedCallback(&endpoint, data, dataLength);
+ g_networkPacketReceivedCallback(&endpoint,
+ g_singleThreadReceiveData->defragData,
+ g_singleThreadReceiveData->recvDataLen);
+ }
+ g_singleThreadReceiveData->remoteEndpoint = NULL;
+ g_singleThreadReceiveData->defragData = NULL;
+ OICFree(g_singleThreadReceiveData);
+ g_singleThreadReceiveData = NULL;
}
#else
VERIFY_NON_NULL_RET(g_bleReceiverQueue,
CABLESenderInfo_t *senderInfo = NULL;
uint32_t senderIndex = 0;
- if(CA_STATUS_OK == CALEGetSenderInfo(address, dataInfoList, &senderInfo,
- &senderIndex))
+ u_arraylist_t *portList = u_arraylist_create();
+ if (CA_STATUS_OK == CALEGetPortsFromSenderInfo(address, dataInfoList, portList))
+ {
+ uint32_t arrayLength = u_arraylist_length(portList);
+ for (int i = 0; i < arrayLength; i++)
+ {
+ uint16_t port = u_arraylist_get(portList, i);
+ OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "port : %X", port);
+
+ if (CA_STATUS_OK == CALEGetSenderInfo(address, port,
+ 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");
+ }
+ else
+ {
+ OIC_LOG(DEBUG, CALEADAPTER_TAG, "SenderInfo doesn't exist");
+ }
+ }
+ }
+ u_arraylist_destroy(portList);
+}
+
+static CAResult_t CALEGetPortsFromSenderInfo(const char *leAddress,
+ u_arraylist_t *senderInfoList,
+ u_arraylist_t *portList)
+{
+ VERIFY_NON_NULL(leAddress,
+ CALEADAPTER_TAG,
+ "NULL BLE address argument");
+
+ const uint32_t listLength = u_arraylist_length(senderInfoList);
+ const uint32_t addrLength = strlen(leAddress);
+
+ for (uint32_t index = 0; index < listLength; index++)
{
- u_arraylist_remove(dataInfoList, senderIndex);
- OICFree(senderInfo->defragData);
- OICFree(senderInfo->remoteEndpoint);
- OICFree(senderInfo);
+ CABLESenderInfo_t *info = (CABLESenderInfo_t *) u_arraylist_get(senderInfoList, index);
+ if (!info || !(info->remoteEndpoint))
+ {
+ continue;
+ }
- OIC_LOG(DEBUG, CALEADAPTER_TAG, "SenderInfo is removed for disconnection");
+ if (!strncmp(info->remoteEndpoint->addr, leAddress, addrLength))
+ {
+ u_arraylist_add(portList, (void *) info->remoteEndpoint->port);
+ }
+ }
+
+ if (u_arraylist_length(portList) != 0)
+ {
+ return CA_STATUS_OK;
}
else
{
- OIC_LOG(DEBUG, CALEADAPTER_TAG, "SenderInfo doesn't exist");
+ return CA_STATUS_FAILED;
}
}
#endif