X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=resource%2Fcsdk%2Fconnectivity%2Fsrc%2Fbt_le_adapter%2Fcaleadapter.c;h=3176f83c73ffa3550ed52041d64f5e80ff8a5e73;hb=refs%2Ftags%2Ftizen_4.0.m2_release;hp=afd362e33c3e302712ab1b646035e5c37e26ddc4;hpb=7fbee66fa26ef5322bde5734f9362accf7671354;p=platform%2Fupstream%2Fiotivity.git diff --git a/resource/csdk/connectivity/src/bt_le_adapter/caleadapter.c b/resource/csdk/connectivity/src/bt_le_adapter/caleadapter.c old mode 100644 new mode 100755 index afd362e..3176f83 --- a/resource/csdk/connectivity/src/bt_le_adapter/caleadapter.c +++ b/resource/csdk/connectivity/src/bt_le_adapter/caleadapter.c @@ -1,4 +1,4 @@ -/****************************************************************** +/* **************************************************************** * * Copyright 2014 Samsung Electronics All Rights Reserved. * @@ -22,997 +22,1691 @@ #include #include +#include "cafragmentation.h" + #include "caleinterface.h" #include "cacommon.h" -#include "camutex.h" +#include "octhread.h" #include "caadapterutils.h" +#ifdef __WITH_DTLS__ +#include "ca_adapter_net_ssl.h" +#endif #ifndef SINGLE_THREAD #include "caqueueingthread.h" #endif -#include "cafragmentation.h" +#if defined(__TIZEN__) || defined(__ANDROID__) +#include "caleserver.h" +#include "caleclient.h" +#endif #include "oic_malloc.h" #include "oic_string.h" #include "caremotehandler.h" +#include /** - * @var CALEADAPTER_TAG - * @brief Logging tag for module name. + * Logging tag for module name. */ -#define CALEADAPTER_TAG "LAD" +#define CALEADAPTER_TAG "OIC_CA_LE_ADAP" /** - * @var g_networkCallback - * @brief Callback to provide the status of the network change to CA layer. + * Stores information of all the senders. + * + * This structure will be used to track and defragment all incoming data packet. */ -static CANetworkChangeCallback g_networkCallback = NULL; +typedef struct +{ + uint32_t recvDataLen; + uint32_t totalDataLen; + uint8_t *defragData; + CAEndpoint_t *remoteEndpoint; + } CABLESenderInfo_t; + +typedef enum +{ + ADAPTER_EMPTY = 1, + ADAPTER_BOTH_CLIENT_SERVER, + ADAPTER_CLIENT, + ADAPTER_SERVER +} CABLEAdapter_t; /** - * @var g_localBLEAddress - * @brief bleAddress of the local adapter. Value will be initialized to zero, and will - * be updated later. + * mtu size to use in fragmentation logic. + * 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 char g_localBLEAddress[18] = {0}; +static CAAdapterChangeCallback g_networkCallback = NULL; /** - * @var g_isServer - * @brief Variable to differentiate btw GattServer and GattClient. + * Callback to provide the status of the connection change to CA layer. */ -static bool g_isServer = false; +static CAConnectionChangeCallback g_connectionCallback = NULL; /** - * @var g_bleIsServerMutex - * @brief Mutex to synchronize the task to be executed on the GattServer function calls. + * Own port value to identify packet owner. Default port value is 1. */ -static ca_mutex g_bleIsServerMutex = NULL; +static uint8_t g_localBLESourcePort = 1; /** - * @var g_bleNetworkCbMutex - * @brief Mutex to synchronize the callback to be called for the network changes. + * bleAddress of the local adapter. Value will be initialized to zero, + * and will be updated later. */ -static ca_mutex g_bleNetworkCbMutex = NULL; +static char g_localBLEAddress[18] = { 0 }; /** - * @var g_bleLocalAddressMutex - * @brief Mutex to synchronize the updation of the local LE address of the adapter. + * Variable to differentiate btw GattServer and GattClient. */ -static ca_mutex g_bleLocalAddressMutex = NULL; +static CABLEAdapter_t g_adapterType = ADAPTER_EMPTY; + +#ifdef __WITH_DTLS__ +static CADataType_t g_dataType = CA_REQUEST_DATA; +#endif /** - * @var g_bleAdapterThreadPool - * @brief reference to threadpool + * Mutex to synchronize the task to be executed on the GattServer + * function calls. */ -static ca_thread_pool_t g_bleAdapterThreadPool = NULL; +static oc_mutex g_bleIsServerMutex = NULL; + +/** + * Mutex to synchronize the callback to be called for the network + * changes. + */ +static oc_mutex g_bleNetworkCbMutex = NULL; + +/** + * Mutex to synchronize the updates of the local LE address of the + * adapter. + */ +static oc_mutex g_bleLocalAddressMutex = NULL; /** - * @var g_bleAdapterThreadPoolMutex - * @brief Mutex to synchronize the task to be pushed to thread pool. + * Reference to thread pool. */ -static ca_mutex g_bleAdapterThreadPoolMutex = NULL; +static ca_thread_pool_t g_bleAdapterThreadPool = NULL; /** - * @var g_bleClientSendDataMutex - * @brief Mutex to synchronize the queing of the data from SenderQueue. + * Mutex to synchronize the task to be pushed to thread pool. */ -static ca_mutex g_bleClientSendDataMutex = NULL; +static oc_mutex g_bleAdapterThreadPoolMutex = NULL; /** - * @var g_bleClientReceiveDataMutex - * @brief Mutex to synchronize the queing of the data from ReceiverQueue. + * Mutex to synchronize the queing of the data from SenderQueue. */ -static ca_mutex g_bleClientReceiveDataMutex = NULL; +static oc_mutex g_bleClientSendDataMutex = NULL; +/** + * Mutex to synchronize the queing of the data from ReceiverQueue. + */ +static oc_mutex g_bleClientReceiveDataMutex = NULL; /** - * @var g_bleServerSendDataMutex - * @brief Mutex to synchronize the queing of the data from SenderQueue. + * Mutex to synchronize the queing of the data from SenderQueue. */ -static ca_mutex g_bleServerSendDataMutex = NULL; +static oc_mutex g_bleServerSendDataMutex = NULL; /** - * @var g_bleServerReceiveDataMutex - * @brief Mutex to synchronize the queing of the data from ReceiverQueue. + * Mutex to synchronize the queing of the data from ReceiverQueue. */ -static ca_mutex g_bleServerReceiveDataMutex = NULL; +static oc_mutex g_bleServerReceiveDataMutex = NULL; /** - * @var g_bleAdapterReqRespCbMutex - * @brief Mutex to synchronize the callback to be called for the adapterReqResponse. + * Mutex to synchronize the callback to be called for the + * adapterReqResponse. */ -static ca_mutex g_bleAdapterReqRespCbMutex = NULL; +static oc_mutex g_bleAdapterReqRespCbMutex = NULL; /** - * @var g_networkPacketReceivedCallback - * @brief Callback to be called when network packet recieved from either GattServer or GattClient. + * Callback to be called when network packet received from either + * GattServer or GattClient. */ static CANetworkPacketReceivedCallback g_networkPacketReceivedCallback = NULL; /** - * @var g_errorHandler - * @brief Callback to notify error from the BLE adapter + * Callback to notify error from the BLE adapter. */ static CAErrorHandleCallback g_errorHandler = NULL; +#ifdef __WITH_DTLS__ +static void CALESecureReceiveDataCB(const CASecureEndpoint_t *endpoint, + const void *data, size_t dataLength); + +static ssize_t CALESecureSendDataCB(CAEndpoint_t *endpoint, + const void *data, size_t dataLength); +#endif + +#ifdef SINGLE_THREAD /** - * @var g_bleAdapterState - * @brief Storing Adapter state information + * Pointer to defragment received data from single threaded routine. */ -static CAAdapterState_t g_bleAdapterState = CA_ADAPTER_DISABLED; +static CABLESenderInfo_t *g_singleThreadReceiveData = NULL; /** - * @ENUM CALeServerStatus - * @brief status of BLE Server Status - * This ENUM provides information of LE Adapter Server status + * 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. */ -typedef enum -{ - CA_SERVER_NOTSTARTED = 0, - CA_LISTENING_SERVER, - CA_DISCOVERY_SERVER -} CALeServerStatus; - -/** - * @var gLeServerStatus - * @brief structure to maintain the status of the server. - */ -static CALeServerStatus gLeServerStatus = CA_SERVER_NOTSTARTED; - -/** -* @fn CALERegisterNetworkNotifications -* @brief This function is used to register network change notification callback. -* -* @param[in] netCallback CANetworkChangeCallback callback which will be set for the change in nwk. -* -* @return 0 on success otherwise a positive error value. -* @retval CA_STATUS_OK Successful -* @retval CA_STATUS_INVALID_PARAM Invalid input argumets -* @retval CA_STATUS_FAILED Operation failed -* -*/ -CAResult_t CALERegisterNetworkNotifications(CANetworkChangeCallback netCallback); - -/** -* @fn CASetBleAdapterThreadPoolHandle -* @brief Used to Set the gThreadPool handle which is required for spawning new thread. -* -* @param[in] handle - Thread pool handle which is given by above layer for using thread -* creation task. -* -* @return void -* -*/ -void CASetLEAdapterThreadPoolHandle(ca_thread_pool_t handle); - -/** -* @fn CALEDeviceStateChangedCb -* @brief This function is used to call the callback to the upper layer when the device state gets -* changed. -* -* @param[in] adapter_state New state of the adapter to be notified to the upper layer. -* -* @return None. -* -*/ -void CALEDeviceStateChangedCb( CAAdapterState_t adapter_state); - -/** -* @fn CAInitBleAdapterMutex -* @brief Used to initialize all required mutex variable for LE Adapter implementation. -* -* @return 0 on success otherwise a positive error value. -* @retval CA_STATUS_OK Successful -* @retval CA_STATUS_INVALID_PARAM Invalid input argumets -* @retval CA_STATUS_FAILED Operation failed -* -*/ -CAResult_t CAInitLEAdapterMutex(); - -/** -* @fn CATerminateBleAdapterMutex -* @brief Used to terminate all required mutex variable for LE adapter implementation. -* -* @return void -*/ -void CATerminateLEAdapterMutex(); - -/** -* @fn CALEErrorHandler -* @brief prepares and notify error through error callback -* -* @return void -*/ -static void CALEErrorHandler(const char *remoteAddress, const void *data, uint32_t dataLen, +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. + * + * @param[in] netCallback CAAdapterChangeCallback callback which will + * be set for the change in adapter. + * @param[in] connCallback CAConnectionChangeCallback callback which will + * be set for the change in connection. + * + * @return 0 on success otherwise a positive error value. + * @retval ::CA_STATUS_OK Successful. + * @retval ::CA_STATUS_INVALID_PARAM Invalid input arguments. + * @retval ::CA_STATUS_FAILED Operation failed. + * + */ +static CAResult_t CALERegisterNetworkNotifications(CAAdapterChangeCallback netCallback, + CAConnectionChangeCallback connCallback); + +/** + * Set the thread pool handle which is required for spawning new + * thread. + * + * @param[in] handle Thread pool handle which is given by above layer + * for using thread creation task. + * + */ +static void CASetLEAdapterThreadPoolHandle(ca_thread_pool_t handle); + +/** + * Call the callback to the upper layer when the adapter state gets + * changed. + * + * @param[in] adapter_state New state of the adapter to be notified to + * the upper layer. + */ +static void CALEDeviceStateChangedCb(CAAdapterState_t adapter_state); + +/** + * Call the callback to the upper layer when the device connection state gets + * changed. + * + * @param[in] address LE address of the device to be notified to the upper layer. + * @param[in] isConnected whether connection state is connected or not. + */ +static void CALEConnectionStateChangedCb(CATransportAdapter_t adapter, const char* address, + bool isConnected); + +/** + * Used to initialize all required mutex variable for LE Adapter + * implementation. + * + * @return 0 on success otherwise a positive error value. + * @retval ::CA_STATUS_OK Successful. + * @retval ::CA_STATUS_INVALID_PARAM Invalid input arguments. + * @retval ::CA_STATUS_FAILED Operation failed. + * + */ +static CAResult_t CAInitLEAdapterMutex(); + +/** + * Terminate all required mutex variables for LE adapter + * implementation. + */ +static void CATerminateLEAdapterMutex(); + +/** + * Prepares and notify error through error callback. + */ +static void CALEErrorHandler(const char *remoteAddress, + const uint8_t *data, + uint32_t dataLen, CAResult_t result); #ifndef SINGLE_THREAD /** - * @var g_dataReceiverHandlerState - * @brief Stop condition of recvhandler. + * Stop condition of Server recvhandler. */ -static bool g_dataReceiverHandlerState = false; +static bool g_dataBleServerReceiverHandlerState = false; /** - * @var g_bleClientSendQueueHandle - * @brief Queue to process the outgoing packets from GATTClient. + * Stop condition of Client recvhandler. */ -static CAQueueingThread_t *g_bleClientSendQueueHandle = NULL; +static bool g_dataBleClientReceiverHandlerState = false; /** - * @var g_bleClientReceiverQueue - * @brief Queue to process the incoming packets to GATT Client. + * Sender information of Server. */ -static CAQueueingThread_t *g_bleClientReceiverQueue = NULL; +static u_arraylist_t *g_bleServerSenderInfo = NULL; + +/** + * Sender information of Client. + */ +static u_arraylist_t *g_bleClientSenderInfo = NULL; /** - * @var g_bleServerSendQueueHandle - * @brief Queue to process the outgoing packets from GATTServer. + * Queue to process the outgoing packets from GATTServer. */ static CAQueueingThread_t *g_bleServerSendQueueHandle = NULL; /** - * @var g_bleServerReceiverQueue - * @brief Queue to process the incoming packets to GATTServer + * Queue to process the outgoing packets from GATTClient. + */ +static CAQueueingThread_t *g_bleClientSendQueueHandle = NULL; + +/** + * Queue to process the incoming packets from GATTServer. */ static CAQueueingThread_t *g_bleServerReceiverQueue = NULL; /** -* @fn CALEDataDestroyer -* @brief Used to free data -* -* @return void -*/ + * Queue to process the incoming packets from GATTClient. + */ +static CAQueueingThread_t *g_bleClientReceiverQueue = NULL; + +/** + * This function will be associated with the sender queue for + * 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] threadData Data pushed to the queue which contains the + * info about RemoteEndpoint and Data. + */ +static void CALEServerSendDataThread(void *threadData); + +/** + * This function will be associated with the sender queue for + * GattClient. + * + * 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] threadData Data pushed to the queue which contains the + * info about RemoteEndpoint and Data. + */ +static void CALEClientSendDataThread(void *threadData); + +/** + * This function will defragment the received data from each sender + * respectively and will send it up to CA layer. Respective sender's + * header will provide the length of the data sent. + * + * @param[in] threadData Data pushed to the queue which contains the + * info about RemoteEndpoint and Data. + * @param[in] receiverType Whether receiver is server or client. + */ +static void CALEDataReceiverHandler(void *threadData, CABLEAdapter_t receiverType); + +/** + * This function will be associated with the receiver queue for + * GattServer. + * + * This function will call the function CALEDataReceiverHandler() + * with server type to defragment the received data. + * + * @param[in] threadData Data pushed to the queue which contains the + * info about RemoteEndpoint and Data. + */ +static void CALEServerDataReceiverHandler(void *threadData); + +/** + * This function will be associated with the receiver queue for + * GattClient. + * + * This function will call the function CALEDataReceiverHandler() + * with client type to defragment the received data. + * + * @param[in] threadData Data pushed to the queue which contains the + * info about RemoteEndpoint and Data. + */ +static void CALEClientDataReceiverHandler(void *threadData); + +/** + * This function will stop all queues created for GattServer and + * GattClient. All four queues will be be stopped with this function + * invocations. + */ +static void CAStopLEQueues(); + +/** + * This function will terminate all queues created for GattServer and + * GattClient. All four queues will be be terminated with this + * function invocations. + */ +static void CATerminateLEQueues(); + +/** + * This function will initalize the Receiver and Sender queues for + * GattServer. This function will in turn call the functions + * CAInitBleServerReceiverQueue() and CAInitBleServerSenderQueue() to + * initialize the queues. + * + * @return ::CA_STATUS_OK or Appropriate error code. + * @retval ::CA_STATUS_OK Successful. + * @retval ::CA_STATUS_INVALID_PARAM Invalid input arguments. + * @retval ::CA_STATUS_FAILED Operation failed. + */ +static CAResult_t CAInitLEServerQueues(); + +/** + * This function will initalize the Receiver and Sender queues for + * GattClient. This function will inturn call the functions + * CAInitBleClientReceiverQueue() and CAInitBleClientSenderQueue() to + * initialize the queues. + * + * @return ::CA_STATUS_OK or Appropriate error code. + * @retval ::CA_STATUS_OK Successful. + * @retval ::CA_STATUS_INVALID_PARAM Invalid input arguments. + * @retval ::CA_STATUS_FAILED Operation failed. + * + */ +static CAResult_t CAInitLEClientQueues(); + +/** + * This function will initalize the Receiver queue for + * GattServer. This will initialize the queue to process the function + * CABLEServerSendDataThread() when ever the task is added to this + * queue. + * + * @return ::CA_STATUS_OK or Appropriate error code. + * @retval ::CA_STATUS_OK Successful. + * @retval ::CA_STATUS_INVALID_PARAM Invalid input arguments. + * @retval ::CA_STATUS_FAILED Operation failed. + */ +static CAResult_t CAInitLEServerSenderQueue(); + +/** + * This function will initalize the Receiver queue for + * GattClient. This will initialize the queue to process the function + * CABLEClientSendDataThread() when ever the task is added to this + * queue. + * + * @return ::CA_STATUS_OK or Appropriate error code. + * @retval ::CA_STATUS_OK Successful. + * @retval ::CA_STATUS_INVALID_PARAM Invalid input arguments. + * @retval ::CA_STATUS_FAILED Operation failed. + */ +static CAResult_t CAInitLEClientSenderQueue(); + +/** + * This function will initialize the Receiver queue for + * GattServer. This will initialize the queue to process the function + * CALEServerDataReceiverHandler() when ever the task is added to this + * queue. + * + * @return ::CA_STATUS_OK or Appropriate error code + * @retval ::CA_STATUS_OK Successful + * @retval ::CA_STATUS_INVALID_PARAM Invalid input arguments + * @retval ::CA_STATUS_FAILED Operation failed + * + */ +static CAResult_t CAInitLEServerReceiverQueue(); + +/** + * This function will initialize the Receiver queue for + * GattClient. This will initialize the queue to process the function + * CALEClientDataReceiverHandler() when ever the task is added to this + * queue. + * + * @return ::CA_STATUS_OK or Appropriate error code + * @retval ::CA_STATUS_OK Successful + * @retval ::CA_STATUS_INVALID_PARAM Invalid input arguments + * @retval ::CA_STATUS_FAILED Operation failed + * + */ +static CAResult_t CAInitLEClientReceiverQueue(); + +/** + * This function will create the Data required to send it in the + * queue. + * + * @param[in] remoteEndpoint Remote endpoint information of the + * server. + * @param[in] data Data to be transmitted from LE. + * @param[in] dataLength Length of the Data being transmitted. + * + * @return ::CA_STATUS_OK or Appropriate error code. + * @retval ::CA_STATUS_OK Successful. + * @retval ::CA_STATUS_INVALID_PARAM Invalid input arguments. + * @retval ::CA_STATUS_FAILED Operation failed. + */ +static CALEData_t *CACreateLEData(const CAEndpoint_t *remoteEndpoint, + const uint8_t *data, + uint32_t dataLength, + u_arraylist_t *senderInfo); + +/** + * Used to free the BLE information stored in the sender/receiver + * queues. + * + * @param[in] bleData Information for a particular data segment. + */ +static void CAFreeLEData(CALEData_t *bleData); + +/** + * Free data. + */ static void CALEDataDestroyer(void *data, uint32_t size); -void CAInitLEQueues() -{ - OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN"); +#ifndef SINGLE_THREAD +/** + * remove request or response data of send queue. + * + * @param[in] queueHandle queue to process the outgoing packets. + * @param[in] mutex mutex related to sender for client / server. + * @param[in] address target address to remove data in queue. + */ +static void CALERemoveSendQueueData(CAQueueingThread_t *queueHandle, + oc_mutex mutex, + const char* address); - CAResult_t result = CAInitLEServerQueues(); - if (CA_STATUS_OK != result) - { - OIC_LOG(ERROR, CALEADAPTER_TAG, "CAInitBleServerQueues failed"); - return; - } +/** + * remove all received data of data list from receive queue. + * + * @param[in] dataInfoList received data list to remove for client / server. + * @param[in] address target address to remove data in queue. + */ +static void CALERemoveReceiveQueueData(u_arraylist_t *dataInfoList, + const char* address); - result = CAInitLEClientQueues(); - if (CA_STATUS_OK != result) - { - OIC_LOG(ERROR, CALEADAPTER_TAG, "CAInitBleClientQueues failed"); - return; - } +/** + * 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); - OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT"); -} +/** + * 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 -CAResult_t CAInitLEServerQueues() +static CAResult_t CAInitLEServerQueues() { - OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN"); - - ca_mutex_lock(g_bleAdapterThreadPoolMutex); + oc_mutex_lock(g_bleAdapterThreadPoolMutex); CAResult_t result = CAInitLEServerSenderQueue(); if (CA_STATUS_OK != result) { OIC_LOG(ERROR, CALEADAPTER_TAG, "CAInitBleServerSenderQueue failed"); - ca_mutex_unlock(g_bleAdapterThreadPoolMutex); + oc_mutex_unlock(g_bleAdapterThreadPoolMutex); return CA_STATUS_FAILED; } + g_bleServerSenderInfo = u_arraylist_create(); + if (!g_bleServerSenderInfo) + { + OIC_LOG(ERROR, CALEADAPTER_TAG, "memory allocation failed!"); + oc_mutex_unlock(g_bleAdapterThreadPoolMutex); + return CA_MEMORY_ALLOC_FAILED; + } + result = CAInitLEServerReceiverQueue(); if (CA_STATUS_OK != result) { - OIC_LOG(ERROR, CALEADAPTER_TAG, "CAInitBleServerReceiverQueue failed"); - ca_mutex_unlock(g_bleAdapterThreadPoolMutex); + OIC_LOG(ERROR, CALEADAPTER_TAG, "CAInitLEServerReceiverQueue failed"); + u_arraylist_free(&g_bleServerSenderInfo); + oc_mutex_unlock(g_bleAdapterThreadPoolMutex); return CA_STATUS_FAILED; } - g_dataReceiverHandlerState = true; + g_dataBleServerReceiverHandlerState = true; - ca_mutex_unlock(g_bleAdapterThreadPoolMutex); - - OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT"); + oc_mutex_unlock(g_bleAdapterThreadPoolMutex); return CA_STATUS_OK; } -CAResult_t CAInitLEClientQueues() +static CAResult_t CAInitLEClientQueues() { - OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN"); - - ca_mutex_lock(g_bleAdapterThreadPoolMutex); + oc_mutex_lock(g_bleAdapterThreadPoolMutex); CAResult_t result = CAInitLEClientSenderQueue(); if (CA_STATUS_OK != result) { OIC_LOG(ERROR, CALEADAPTER_TAG, "CAInitBleClientSenderQueue failed"); - ca_mutex_unlock(g_bleAdapterThreadPoolMutex); + oc_mutex_unlock(g_bleAdapterThreadPoolMutex); return CA_STATUS_FAILED; } + g_bleClientSenderInfo = u_arraylist_create(); + if (!g_bleClientSenderInfo) + { + OIC_LOG(ERROR, CALEADAPTER_TAG, "memory allocation failed!"); + oc_mutex_unlock(g_bleAdapterThreadPoolMutex); + return CA_MEMORY_ALLOC_FAILED; + } + result = CAInitLEClientReceiverQueue(); if (CA_STATUS_OK != result) { - OIC_LOG(ERROR, CALEADAPTER_TAG, "CAInitBleClientReceiverQueue failed"); - ca_mutex_unlock(g_bleAdapterThreadPoolMutex); + OIC_LOG(ERROR, CALEADAPTER_TAG, "CAInitLEClientReceiverQueue failed"); + u_arraylist_free(&g_bleClientSenderInfo); + oc_mutex_unlock(g_bleAdapterThreadPoolMutex); return CA_STATUS_FAILED; } - g_dataReceiverHandlerState = true; + g_dataBleClientReceiverHandlerState = true; - ca_mutex_unlock(g_bleAdapterThreadPoolMutex); - - OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT"); + oc_mutex_unlock(g_bleAdapterThreadPoolMutex); return CA_STATUS_OK; } -CAResult_t CAInitLEServerSenderQueue() +static CAResult_t CAInitLEServerReceiverQueue() { - OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN"); + OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "%s", __func__); // Check if the message queue is already initialized - if (g_bleServerSendQueueHandle) + if (g_bleServerReceiverQueue) { - OIC_LOG(DEBUG, CALEADAPTER_TAG, "Queue is already initialized!"); + OIC_LOG(DEBUG, CALEADAPTER_TAG, "Already queue is initialized!"); return CA_STATUS_OK; } - // Create send message queue - g_bleServerSendQueueHandle = (CAQueueingThread_t *) OICMalloc(sizeof(CAQueueingThread_t)); - if (!g_bleServerSendQueueHandle) + // Create recv message queue + g_bleServerReceiverQueue = (CAQueueingThread_t *) OICMalloc(sizeof(CAQueueingThread_t)); + if (!g_bleServerReceiverQueue) { OIC_LOG(ERROR, CALEADAPTER_TAG, "Memory allocation failed!"); return CA_MEMORY_ALLOC_FAILED; } - if (CA_STATUS_OK != CAQueueingThreadInitialize(g_bleServerSendQueueHandle, + if (CA_STATUS_OK != CAQueueingThreadInitialize(g_bleServerReceiverQueue, g_bleAdapterThreadPool, - CALEServerSendDataThread, CALEDataDestroyer)) + CALEServerDataReceiverHandler, + CALEDataDestroyer)) { - OIC_LOG(ERROR, CALEADAPTER_TAG, "Failed to Initialize send queue thread"); - OICFree(g_bleServerSendQueueHandle); - g_bleServerSendQueueHandle = NULL; + OIC_LOG(ERROR, CALEADAPTER_TAG, "Failed to Initialize server receiver queue thread"); + OICFree(g_bleServerReceiverQueue); + g_bleServerReceiverQueue = NULL; return CA_STATUS_FAILED; } - if (CA_STATUS_OK != CAQueueingThreadStart(g_bleServerSendQueueHandle)) + if (CA_STATUS_OK != CAQueueingThreadStart(g_bleServerReceiverQueue)) { OIC_LOG(ERROR, CALEADAPTER_TAG, "ca_thread_pool_add_task failed "); - OICFree(g_bleServerSendQueueHandle); - g_bleServerSendQueueHandle = NULL; + OICFree(g_bleServerReceiverQueue); + g_bleServerReceiverQueue = NULL; return CA_STATUS_FAILED; } - OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT"); return CA_STATUS_OK; } -CAResult_t CAInitLEClientSenderQueue() +static CAResult_t CAInitLEClientReceiverQueue() { - OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN"); - - if (g_bleClientSendQueueHandle) + OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "%s", __func__); + // Check if the message queue is already initialized + if (g_bleClientReceiverQueue) { OIC_LOG(DEBUG, CALEADAPTER_TAG, "Already queue is initialized!"); return CA_STATUS_OK; } - // Create send message queue - g_bleClientSendQueueHandle = (CAQueueingThread_t *) OICMalloc(sizeof(CAQueueingThread_t)); - if (!g_bleClientSendQueueHandle) + // Create recv message queue + g_bleClientReceiverQueue = (CAQueueingThread_t *) OICMalloc(sizeof(CAQueueingThread_t)); + if (!g_bleClientReceiverQueue) { OIC_LOG(ERROR, CALEADAPTER_TAG, "Memory allocation failed!"); return CA_MEMORY_ALLOC_FAILED; } - if (CA_STATUS_OK != CAQueueingThreadInitialize(g_bleClientSendQueueHandle, + if (CA_STATUS_OK != CAQueueingThreadInitialize(g_bleClientReceiverQueue, g_bleAdapterThreadPool, - CALEClientSendDataThread, CALEDataDestroyer)) + CALEClientDataReceiverHandler, + CALEDataDestroyer)) { - OIC_LOG(ERROR, CALEADAPTER_TAG, "Failed to Initialize send queue thread"); - OICFree(g_bleClientSendQueueHandle); - g_bleClientSendQueueHandle = NULL; + OIC_LOG(ERROR, CALEADAPTER_TAG, "Failed to Initialize client receiver queue thread"); + OICFree(g_bleClientReceiverQueue); + g_bleClientReceiverQueue = NULL; return CA_STATUS_FAILED; } - if (CA_STATUS_OK != CAQueueingThreadStart(g_bleClientSendQueueHandle)) + if (CA_STATUS_OK != CAQueueingThreadStart(g_bleClientReceiverQueue)) { OIC_LOG(ERROR, CALEADAPTER_TAG, "ca_thread_pool_add_task failed "); - OICFree(g_bleClientSendQueueHandle); - g_bleClientSendQueueHandle = NULL; + OICFree(g_bleClientReceiverQueue); + g_bleClientReceiverQueue = NULL; return CA_STATUS_FAILED; } - OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT"); return CA_STATUS_OK; } -CAResult_t CAInitLEServerReceiverQueue() +static CAResult_t CAInitLEServerSenderQueue() { - OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN"); + OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "%s", __func__); // Check if the message queue is already initialized - if (g_bleServerReceiverQueue) + if (g_bleServerSendQueueHandle) { - OIC_LOG(DEBUG, CALEADAPTER_TAG, "Already queue is initialized!"); + OIC_LOG(DEBUG, CALEADAPTER_TAG, "Queue is already initialized!"); return CA_STATUS_OK; } // Create send message queue - g_bleServerReceiverQueue = (CAQueueingThread_t *) OICMalloc(sizeof(CAQueueingThread_t)); - if (!g_bleServerReceiverQueue) + g_bleServerSendQueueHandle = (CAQueueingThread_t *) OICMalloc(sizeof(CAQueueingThread_t)); + if (!g_bleServerSendQueueHandle) { OIC_LOG(ERROR, CALEADAPTER_TAG, "Memory allocation failed!"); - OICFree(g_bleServerSendQueueHandle); return CA_MEMORY_ALLOC_FAILED; } - if (CA_STATUS_OK != CAQueueingThreadInitialize(g_bleServerReceiverQueue, g_bleAdapterThreadPool, - CALEServerDataReceiverHandler, CALEDataDestroyer)) + if (CA_STATUS_OK != CAQueueingThreadInitialize(g_bleServerSendQueueHandle, + g_bleAdapterThreadPool, + CALEServerSendDataThread, + CALEDataDestroyer)) { OIC_LOG(ERROR, CALEADAPTER_TAG, "Failed to Initialize send queue thread"); - OICFree(g_bleServerReceiverQueue); - g_bleServerReceiverQueue = NULL; - return CA_STATUS_FAILED; - } - - if (CA_STATUS_OK != CAQueueingThreadStart(g_bleServerReceiverQueue)) - { - OIC_LOG(ERROR, CALEADAPTER_TAG, "ca_thread_pool_add_task failed "); - OICFree(g_bleServerReceiverQueue); - g_bleServerReceiverQueue = NULL; + OICFree(g_bleServerSendQueueHandle); + g_bleServerSendQueueHandle = NULL; return CA_STATUS_FAILED; } - OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT"); return CA_STATUS_OK; } -CAResult_t CAInitLEClientReceiverQueue() +static void CALEClearSenderInfoImpl(u_arraylist_t ** list) +{ + const size_t length = u_arraylist_length(*list); + for (size_t i = 0; i < length; ++i) + { + CABLESenderInfo_t * const info = + (CABLESenderInfo_t *) u_arraylist_get(*list, i); + if (info) + { + OICFree(info->defragData); + CAFreeEndpoint(info->remoteEndpoint); + OICFree(info); + } + } + u_arraylist_free(list); +} + +static void CALEClearSenderInfo() { - OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN"); + CALEClearSenderInfoImpl(&g_bleServerSenderInfo); + CALEClearSenderInfoImpl(&g_bleClientSenderInfo); +} - // Check if the message queue is already initialized - if (g_bleClientReceiverQueue) +static CAResult_t CAInitLEClientSenderQueue() +{ + OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "%s", __func__); + + if (g_bleClientSendQueueHandle) { OIC_LOG(DEBUG, CALEADAPTER_TAG, "Already queue is initialized!"); + return CA_STATUS_OK; } - else - { - // Create send message queue - g_bleClientReceiverQueue = (CAQueueingThread_t *) OICMalloc(sizeof(CAQueueingThread_t)); - if (!g_bleClientReceiverQueue) - { - OIC_LOG(ERROR, CALEADAPTER_TAG, "Memory allocation failed!"); - OICFree(g_bleClientSendQueueHandle); - return CA_MEMORY_ALLOC_FAILED; - } - if (CA_STATUS_OK != CAQueueingThreadInitialize(g_bleClientReceiverQueue, - g_bleAdapterThreadPool, - CALEClientDataReceiverHandler, NULL)) - { - OIC_LOG(ERROR, CALEADAPTER_TAG, "Failed to Initialize send queue thread"); - OICFree(g_bleClientSendQueueHandle); - OICFree(g_bleClientReceiverQueue); - g_bleClientReceiverQueue = NULL; - return CA_STATUS_FAILED; - } + // Create send message queue + g_bleClientSendQueueHandle = (CAQueueingThread_t *) OICMalloc(sizeof(CAQueueingThread_t)); + if (!g_bleClientSendQueueHandle) + { + OIC_LOG(ERROR, CALEADAPTER_TAG, "Memory allocation failed!"); + return CA_MEMORY_ALLOC_FAILED; } - if (CA_STATUS_OK != CAQueueingThreadStart(g_bleClientReceiverQueue)) + + if (CA_STATUS_OK != CAQueueingThreadInitialize(g_bleClientSendQueueHandle, + g_bleAdapterThreadPool, + CALEClientSendDataThread, CALEDataDestroyer)) { - OIC_LOG(ERROR, CALEADAPTER_TAG, "ca_thread_pool_add_task failed "); - OICFree(g_bleClientReceiverQueue); - g_bleClientReceiverQueue = NULL; + OIC_LOG(ERROR, CALEADAPTER_TAG, "Failed to Initialize send queue thread"); + OICFree(g_bleClientSendQueueHandle); + g_bleClientSendQueueHandle = NULL; return CA_STATUS_FAILED; } - - OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT"); return CA_STATUS_OK; } -void CAStopLEQueues() +static void CAStopLEQueues() { - OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN"); + OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "IN %s", __func__); - ca_mutex_lock(g_bleClientSendDataMutex); - if (NULL != g_bleClientSendQueueHandle) + oc_mutex_lock(g_bleServerReceiveDataMutex); + if (NULL != g_bleServerReceiverQueue) { - CAQueueingThreadStop(g_bleClientSendQueueHandle); + CAQueueingThreadStop(g_bleServerReceiverQueue); } - ca_mutex_unlock(g_bleClientSendDataMutex); + oc_mutex_unlock(g_bleServerReceiveDataMutex); - ca_mutex_lock(g_bleClientReceiveDataMutex); + oc_mutex_lock(g_bleClientReceiveDataMutex); if (NULL != g_bleClientReceiverQueue) { CAQueueingThreadStop(g_bleClientReceiverQueue); } - ca_mutex_unlock(g_bleClientReceiveDataMutex); - - ca_mutex_lock(g_bleServerSendDataMutex); - if (NULL != g_bleServerSendQueueHandle) - { - CAQueueingThreadStop(g_bleServerSendQueueHandle); - } - ca_mutex_unlock(g_bleServerSendDataMutex); - - ca_mutex_lock(g_bleServerReceiveDataMutex); - if (NULL != g_bleServerReceiverQueue) - { - CAQueueingThreadStop(g_bleServerReceiverQueue); - } - ca_mutex_unlock(g_bleServerReceiveDataMutex); + oc_mutex_unlock(g_bleClientReceiveDataMutex); - OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT"); + OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "OUT %s", __func__); } -void CATerminateLEQueues() +static void CATerminateLEQueues() { - OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN"); - CAQueueingThreadDestroy(g_bleClientSendQueueHandle); OICFree(g_bleClientSendQueueHandle); g_bleClientSendQueueHandle = NULL; - - CAQueueingThreadDestroy(g_bleClientReceiverQueue); - OICFree(g_bleClientReceiverQueue); - g_bleClientReceiverQueue = NULL; - - CAQueueingThreadDestroy(g_bleServerSendQueueHandle); OICFree(g_bleServerSendQueueHandle); g_bleServerSendQueueHandle = NULL; - CAQueueingThreadDestroy(g_bleServerReceiverQueue); OICFree(g_bleServerReceiverQueue); g_bleServerReceiverQueue = NULL; - OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT"); + CAQueueingThreadDestroy(g_bleClientReceiverQueue); + OICFree(g_bleClientReceiverQueue); + g_bleClientReceiverQueue = NULL; + + CALEClearSenderInfo(); } -void CALEServerDataReceiverHandler(void *threadData) +static CAResult_t CALEGetSenderInfo(const char *leAddress, + const uint16_t port, + u_arraylist_t *senderInfoList, + CABLESenderInfo_t **senderInfo, + uint32_t *senderIndex) { - OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN"); + VERIFY_NON_NULL_RET(leAddress, + CALEADAPTER_TAG, + "NULL BLE address argument", + CA_STATUS_INVALID_PARAM); + VERIFY_NON_NULL_RET(senderIndex, + CALEADAPTER_TAG, + "NULL index argument", + CA_STATUS_INVALID_PARAM); + + const uint32_t listLength = u_arraylist_length(senderInfoList); + const uint32_t addrLength = strlen(leAddress); + for (uint32_t index = 0; index < listLength; index++) + { + CABLESenderInfo_t *info = (CABLESenderInfo_t *) u_arraylist_get(senderInfoList, index); + if (!info || !(info->remoteEndpoint)) + { + continue; + } + + if (!strncmp(info->remoteEndpoint->addr, leAddress, addrLength)) + { + if (info->remoteEndpoint->port == port) + { + *senderIndex = index; + if (senderInfo) + { + *senderInfo = info; + } + return CA_STATUS_OK; + } + } + } - static uint32_t recvDataLen = 0; - static uint32_t totalDataLen = 0; - static char *defragData = NULL; - static bool isHeaderAvailable = false; - static CAEndpoint_t *remoteEndpoint = NULL; + return CA_STATUS_FAILED; +} + +static void CALEDataReceiverHandler(void *threadData, CABLEAdapter_t receiverType) +{ + OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "%s", __func__); + + oc_mutex bleReceiveDataMutex = NULL; + bool dataBleReceiverHandlerState = false; + + switch (receiverType) + { + case ADAPTER_CLIENT: + bleReceiveDataMutex = g_bleClientReceiveDataMutex; + dataBleReceiverHandlerState = g_dataBleClientReceiverHandlerState; + break; + case ADAPTER_SERVER: + bleReceiveDataMutex = g_bleServerReceiveDataMutex; + dataBleReceiverHandlerState = g_dataBleServerReceiverHandlerState; + break; + default: + OIC_LOG_V(ERROR, CALEADAPTER_TAG, "Unsupported receiver type : %d", receiverType); + return; + } - ca_mutex_lock(g_bleServerReceiveDataMutex); + oc_mutex_lock(bleReceiveDataMutex); - if (g_dataReceiverHandlerState) + if (dataBleReceiverHandlerState) { - OIC_LOG(DEBUG, CALEADAPTER_TAG, "checking for DE Fragmentation"); - CALEData_t *bleData = (CALEData_t *) threadData; if (!bleData) { OIC_LOG(DEBUG, CALEADAPTER_TAG, "Invalid bleData!"); + oc_mutex_unlock(bleReceiveDataMutex); return; } - OIC_LOG(DEBUG, CALEADAPTER_TAG, "checking for DE Fragmentation"); + if (!(bleData->senderInfo)) + { + OIC_LOG(ERROR, CALEADAPTER_TAG, "sender info is not available"); + oc_mutex_unlock(bleReceiveDataMutex); + return; + } - if (!isHeaderAvailable) + if (!(bleData->remoteEndpoint)) { - OIC_LOG(DEBUG, CALEADAPTER_TAG, "Parsing the header"); - totalDataLen = CAParseHeader((char*)bleData->data); + OIC_LOG(ERROR, CALEADAPTER_TAG, "RemoteEndPoint NULL!!"); + oc_mutex_unlock(bleReceiveDataMutex); + return; + } - OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "Total data to be accumulated [%d] bytes", totalDataLen); - OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "data received in the first packet [%d] bytes", bleData->dataLen); + CABLESenderInfo_t *senderInfo = NULL; + uint32_t senderIndex = 0; - defragData = (char *) OICCalloc(totalDataLen + 1, sizeof(char)); - if (NULL == defragData) - { - OIC_LOG(ERROR, CALEADAPTER_TAG, "defragData is NULL!"); - return; - } + //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; - const char *remoteAddress = bleData->remoteEndpoint->addr; + CAParseHeader(bleData->data, &startFlag, &sourcePort, &secureFlag, &destPort); + OIC_LOG_V(INFO, 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); + oc_mutex_unlock(bleReceiveDataMutex); + return; + } - remoteEndpoint = CACreateEndpointObject(CA_DEFAULT_FLAGS, CA_ADAPTER_GATT_BTLE, - remoteAddress, 0); + bleData->remoteEndpoint->port = sourcePort; - memcpy(defragData + recvDataLen, bleData->data + CA_HEADER_LENGTH, - bleData->dataLen - CA_HEADER_LENGTH); - recvDataLen += bleData->dataLen - CA_HEADER_LENGTH; - isHeaderAvailable = true; + 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 { - OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "Copying the data of length [%d]", bleData->dataLen); - memcpy(defragData + recvDataLen, bleData->data, bleData->dataLen); - recvDataLen += bleData->dataLen ; - OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "totalDatalength [%d] recveived Datalen [%d]", - totalDataLen, recvDataLen); + 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 (totalDataLen == recvDataLen) + + if (!senderInfo) { - ca_mutex_lock(g_bleAdapterReqRespCbMutex); - if (NULL == g_networkPacketReceivedCallback) + uint32_t totalLength = 0; + if (startFlag) { - OIC_LOG(ERROR, CALEADAPTER_TAG, "gReqRespCallback is NULL!"); - ca_mutex_unlock(g_bleAdapterReqRespCbMutex); + CAParseHeaderPayloadLength(bleData->data, CA_BLE_LENGTH_HEADER_SIZE, &totalLength); + } + else + { + OIC_LOG(ERROR, CALEADAPTER_TAG, "This packet is wrong packet! ignore."); + oc_mutex_unlock(bleReceiveDataMutex); return; } - OIC_LOG(DEBUG, CALEADAPTER_TAG, "Sending data up !"); - g_networkPacketReceivedCallback(remoteEndpoint, defragData, recvDataLen); - recvDataLen = 0; - totalDataLen = 0; - isHeaderAvailable = false; - remoteEndpoint = NULL; - defragData = NULL; - ca_mutex_unlock(g_bleAdapterReqRespCbMutex); - } - - if (false == g_dataReceiverHandlerState) - { - OIC_LOG(DEBUG, CALEADAPTER_TAG, "GATTClient is terminating. Cleaning up"); - recvDataLen = 0; - totalDataLen = 0; - isHeaderAvailable = false; - OICFree(defragData); - CAFreeEndpoint(remoteEndpoint); - ca_mutex_unlock(g_bleServerReceiveDataMutex); - return; - } - } - ca_mutex_unlock(g_bleServerReceiveDataMutex); - OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT"); -} - -void CALEClientDataReceiverHandler(void *threadData) -{ - OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN"); - static const char *remoteAddress = NULL; - static uint32_t recvDataLen = 0; - static uint32_t totalDataLen = 0; - static char *defragData = NULL; - static bool isHeaderAvailable = false; - static CAEndpoint_t *remoteEndpoint = NULL; - - ca_mutex_lock(g_bleClientReceiveDataMutex); + CABLESenderInfo_t *newSender = OICMalloc(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; - if (g_dataReceiverHandlerState) - { - OIC_LOG(DEBUG, CALEADAPTER_TAG, "checking for DE Fragmentation"); + OIC_LOG(DEBUG, CALEADAPTER_TAG, "Parsing the header"); - CALEData_t *bleData = (CALEData_t *) threadData; - if (!bleData) - { - OIC_LOG(DEBUG, CALEADAPTER_TAG, "Invalid wifidata!"); - return; - } + newSender->totalDataLen = totalLength; - OIC_LOG(DEBUG, CALEADAPTER_TAG, "checking for DE Fragmentation"); + if (!(newSender->totalDataLen)) + { + OIC_LOG(ERROR, CALEADAPTER_TAG, "Total Data Length is parsed as 0!!!"); + OICFree(newSender); + oc_mutex_unlock(bleReceiveDataMutex); + return; + } - if (!isHeaderAvailable) - { - OIC_LOG(DEBUG, CALEADAPTER_TAG, "Parsing the header"); + size_t dataOnlyLen = + bleData->dataLen - (CA_BLE_HEADER_SIZE + CA_BLE_LENGTH_HEADER_SIZE); + OIC_LOG_V(INFO, CALEADAPTER_TAG, "Total data to be accumulated [%u] bytes", + newSender->totalDataLen); + OIC_LOG_V(INFO, CALEADAPTER_TAG, "data received in the first packet [%zu] bytes", + dataOnlyLen); - totalDataLen = CAParseHeader(bleData->data); - OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "Total data to be accumulated [%d] bytes", - totalDataLen); - OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "Data received in the first packet [%d] bytes", - bleData->dataLen); + newSender->defragData = OICCalloc(newSender->totalDataLen + 1, + sizeof(*newSender->defragData)); - defragData = (char *) OICMalloc(sizeof(char) * totalDataLen); - if (NULL == defragData) + if (NULL == newSender->defragData) { OIC_LOG(ERROR, CALEADAPTER_TAG, "defragData is NULL!"); + OICFree(newSender); + oc_mutex_unlock(bleReceiveDataMutex); return; } + CATransportFlags_t flags = CA_DEFAULT_FLAGS; +#ifdef __WITH_DTLS__ + if (CA_BLE_PACKET_SECURE == secureFlag) + { + flags |= CA_SECURE; + } +#endif - remoteAddress = bleData->remoteEndpoint->addr; + const char *remoteAddress = bleData->remoteEndpoint->addr; + newSender->remoteEndpoint = CACreateEndpointObject(flags, + CA_ADAPTER_GATT_BTLE, + remoteAddress, + bleData->remoteEndpoint->port); - remoteEndpoint = CACreateEndpointObject(CA_DEFAULT_FLAGS, CA_ADAPTER_GATT_BTLE, - remoteAddress, 0); + if (NULL == newSender->remoteEndpoint) + { + OIC_LOG(ERROR, CALEADAPTER_TAG, "remoteEndpoint is NULL!"); + OICFree(newSender->defragData); + OICFree(newSender); + oc_mutex_unlock(bleReceiveDataMutex); + return; + } - memcpy(defragData, bleData->data + CA_HEADER_LENGTH, - bleData->dataLen - CA_HEADER_LENGTH); - recvDataLen += bleData->dataLen - CA_HEADER_LENGTH; - isHeaderAvailable = true; + 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); + oc_mutex_unlock(bleReceiveDataMutex); + return; + } + 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, + newSender->remoteEndpoint->port, + bleData->senderInfo, + NULL, &senderIndex)) + { + OIC_LOG(ERROR, CALEADAPTER_TAG, "Existing sender index not found!!"); + OICFree(newSender->defragData); + CAFreeEndpoint(newSender->remoteEndpoint); + OICFree(newSender); + oc_mutex_unlock(bleReceiveDataMutex); + return; + } + senderInfo = newSender; } else { - OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "Copying the data of length [%d]", bleData->dataLen); - memcpy(defragData + recvDataLen, bleData->data, bleData->dataLen); - recvDataLen += bleData->dataLen ; - OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "totalDatalength [%d] recveived Datalen [%d]", - totalDataLen, recvDataLen); + 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 [%zu] total length [%u]", + senderInfo->recvDataLen + dataOnlyLen, senderInfo->totalDataLen); + u_arraylist_remove(bleData->senderInfo, senderIndex); + OICFree(senderInfo->defragData); + OICFree(senderInfo); + oc_mutex_unlock(bleReceiveDataMutex); + return; + } + OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "Copying the data of length [%zu]", + dataOnlyLen); + memcpy(senderInfo->defragData + senderInfo->recvDataLen, + bleData->data + CA_BLE_HEADER_SIZE, + dataOnlyLen); + senderInfo->recvDataLen += dataOnlyLen; + OIC_LOG_V(INFO, CALEADAPTER_TAG, "totalDatalength [%d] received Datalen [%d]", + senderInfo->totalDataLen, senderInfo->recvDataLen); } - if (totalDataLen == recvDataLen) + + if (senderInfo->totalDataLen == senderInfo->recvDataLen) { - ca_mutex_lock(g_bleAdapterReqRespCbMutex); + oc_mutex_lock(g_bleAdapterReqRespCbMutex); if (NULL == g_networkPacketReceivedCallback) { OIC_LOG(ERROR, CALEADAPTER_TAG, "gReqRespCallback is NULL!"); - ca_mutex_unlock(g_bleAdapterReqRespCbMutex); + + u_arraylist_remove(bleData->senderInfo, senderIndex); + OICFree(senderInfo->defragData); + OICFree(senderInfo); + oc_mutex_unlock(g_bleAdapterReqRespCbMutex); + oc_mutex_unlock(bleReceiveDataMutex); return; } - OIC_LOG(DEBUG, CALEADAPTER_TAG, "Sending data up !"); - g_networkPacketReceivedCallback(remoteEndpoint, defragData, recvDataLen); - recvDataLen = 0; - totalDataLen = 0; - isHeaderAvailable = false; - remoteEndpoint = NULL; - defragData = NULL; - ca_mutex_unlock(g_bleAdapterReqRespCbMutex); - } - - if (false == g_dataReceiverHandlerState) - { - OIC_LOG(DEBUG, CALEADAPTER_TAG, "GATTClient is terminating. Cleaning up"); - OICFree(defragData); - CAFreeEndpoint(remoteEndpoint); - ca_mutex_unlock(g_bleClientReceiveDataMutex); - return; + + OIC_LOG(DEBUG, CALEADAPTER_TAG, "[CALEDataReceiverHandler] Received data up !"); + + const CASecureEndpoint_t tmp = + { + .endpoint = *senderInfo->remoteEndpoint + }; + + OIC_LOG_V(INFO, CALEADAPTER_TAG, "endpoint flags : %d", tmp.endpoint.flags); +#ifdef __WITH_DTLS__ + if (CA_SECURE & tmp.endpoint.flags) + { + OIC_LOG(DEBUG, CALEADAPTER_TAG, "Secure data received"); + switch (receiverType) + { + case ADAPTER_CLIENT: + g_dataType = CA_REQUEST_DATA; + break; + case ADAPTER_SERVER: + g_dataType = CA_RESPONSE_DATA; + break; + default: + OIC_LOG_V(ERROR, CALEADAPTER_TAG, "Unsupported rcvr type:%d",receiverType); + oc_mutex_unlock(g_bleAdapterReqRespCbMutex); + u_arraylist_remove(bleData->senderInfo, senderIndex); + senderInfo->remoteEndpoint = NULL; + senderInfo->defragData = NULL; + OICFree(senderInfo); + oc_mutex_unlock(bleReceiveDataMutex); + return; + } + + if (CA_STATUS_FAILED == CAdecryptSsl(&tmp, + senderInfo->defragData, + senderInfo->recvDataLen)) + { + OIC_LOG(ERROR, CALEADAPTER_TAG, "CAdecryptSsl failed"); + } + else + { + OIC_LOG(DEBUG, CALEADAPTER_TAG, "CAdecryptSsl successed"); + } + OICFree(senderInfo->defragData); + } + else + { +#endif + OIC_LOG(INFO, CALEADAPTER_TAG, "Non-Secure data received"); + g_networkPacketReceivedCallback(&tmp, + senderInfo->defragData, + senderInfo->recvDataLen); +#ifdef __WITH_DTLS__ + } +#endif + + oc_mutex_unlock(g_bleAdapterReqRespCbMutex); + u_arraylist_remove(bleData->senderInfo, senderIndex); + senderInfo->remoteEndpoint = NULL; + senderInfo->defragData = NULL; + OICFree(senderInfo); } } - ca_mutex_unlock(g_bleClientReceiveDataMutex); - OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT"); + oc_mutex_unlock(bleReceiveDataMutex); +} + + +static void CALEServerDataReceiverHandler(void *threadData) +{ + CALEDataReceiverHandler(threadData, ADAPTER_SERVER); } -void CALEServerSendDataThread(void *threadData) +static void CALEClientDataReceiverHandler(void *threadData) { - OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN"); + CALEDataReceiverHandler(threadData, ADAPTER_CLIENT); +} - CALEData_t *bleData = (CALEData_t *) threadData; +static void CALEServerSendDataThread(void *threadData) +{ + OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "IN %s", __func__); + + CALEData_t * const bleData = (CALEData_t *) threadData; if (!bleData) { - OIC_LOG(DEBUG, CALEADAPTER_TAG, "Invalid bledata!"); + OIC_LOG(ERROR, CALEADAPTER_TAG, "Invalid bledata!"); + return; + } + + if (!bleData->remoteEndpoint) + { + OIC_LOG(ERROR, CALEADAPTER_TAG, "Invalid endpoint of bledata!"); return; } - char *header = (char *) OICCalloc(CA_HEADER_LENGTH, sizeof(char)); - VERIFY_NON_NULL_VOID(header, CALEADAPTER_TAG, "Malloc failed"); +#if defined(__TIZEN__) || defined(__ANDROID__) + // get MTU size + g_mtuSize = CALEServerGetMtuSize(bleData->remoteEndpoint->addr); +#endif + OIC_LOG_V(INFO, CALEADAPTER_TAG, "MTU size [%d]", g_mtuSize); + + uint32_t midPacketCount = 0; + size_t remainingLen = 0; + size_t totalLength = 0; + CABLEPacketSecure_t secureFlag = CA_BLE_PACKET_NON_SECURE; - int32_t totalLength = bleData->dataLen + CA_HEADER_LENGTH; + CAResult_t result = CAGenerateVariableForFragmentation(bleData->dataLen, + &midPacketCount, + &remainingLen, + &totalLength, + g_mtuSize); - OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "Server total Data length with header is [%d]", totalLength); - char *dataSegment = (char *) OICCalloc(totalLength + 1, sizeof(char)); - if (NULL == dataSegment) + if (CA_STATUS_OK != result) { - OIC_LOG(ERROR, CALEADAPTER_TAG, "Malloc failed"); - OICFree(header); + OIC_LOG_V(ERROR, CALEADAPTER_TAG, + "CAGenerateVariableForFragmentation failed, result [%d]", result); + g_errorHandler(bleData->remoteEndpoint, bleData->data, bleData->dataLen, result); return; } - CAResult_t result = CAGenerateHeader(header, bleData->dataLen); - if (CA_STATUS_OK != result ) + OIC_LOG_V(DEBUG, CALEADAPTER_TAG, + "Packet info: data size[%d] midPacketCount[%u] remainingLen[%zu] totalLength[%zu]", + bleData->dataLen, midPacketCount, remainingLen, totalLength); + + OIC_LOG_V(DEBUG, + CALEADAPTER_TAG, + "Server total Data length with header is [%zu]", + 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; + + OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "This Packet is secure? %d", secureFlag); + 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); + } + OIC_LOG_V(INFO, CALEADAPTER_TAG, "header info: secureFlag[%X]", secureFlag); + + if (CA_STATUS_OK != result) { - OIC_LOG(ERROR, CALEADAPTER_TAG, "Generate header failed"); - OICFree(header); - OICFree(dataSegment); - return ; + OIC_LOG_V(ERROR, CALEADAPTER_TAG, + "CAGenerateHeader failed, result [%d]", result); + g_errorHandler(bleData->remoteEndpoint, bleData->data, bleData->dataLen, result); + return; } - memcpy(dataSegment, header, CA_HEADER_LENGTH); - OICFree(header); + 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; + } - int32_t length = 0; - if (CA_SUPPORTED_BLE_MTU_SIZE > totalLength) + uint32_t length = 0; + uint32_t dataLen = 0; + if (g_mtuSize > totalLength) { length = totalLength; - memcpy(dataSegment + CA_HEADER_LENGTH, bleData->data, bleData->dataLen); + dataLen = bleData->dataLen; } else { - length = CA_SUPPORTED_BLE_MTU_SIZE; - memcpy(dataSegment + CA_HEADER_LENGTH, bleData->data, - CA_SUPPORTED_BLE_MTU_SIZE - CA_HEADER_LENGTH); + length = g_mtuSize; + dataLen = g_mtuSize - 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; } - int32_t iter = totalLength / CA_SUPPORTED_BLE_MTU_SIZE; - int32_t index = 0; + const uint32_t iter = midPacketCount; + uint32_t index = 0; + // Send the first segment with the header. - if (NULL != bleData->remoteEndpoint) //Sending Unicast Data + if (NULL != bleData->remoteEndpoint) // Sending Unicast Data { OIC_LOG(DEBUG, CALEADAPTER_TAG, "Server Sending Unicast Data"); + result = CAUpdateCharacteristicsToGattClient( bleData->remoteEndpoint->addr, dataSegment, length); + + 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); + return; + } + + OIC_LOG_V(DEBUG, + CALEADAPTER_TAG, + "Server Sent Unicast First Data - data length [%zu]", + length); + + 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, "Update characteristics failed, result [%d]", result); + OIC_LOG_V(ERROR, CALEADAPTER_TAG, + "CAGenerateHeader 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]", length); - for (index = 1; index < iter; index++) + for (index = 0; index < iter; index++) { // Send the remaining header. - OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "Sending the chunk number [%d]", index); - result = CAUpdateCharacteristicsToGattClient( - bleData->remoteEndpoint->addr, - bleData->data + ((index * CA_SUPPORTED_BLE_MTU_SIZE) - CA_HEADER_LENGTH), - CA_SUPPORTED_BLE_MTU_SIZE); + result = CAMakeRemainDataSegment(dataSegment, + g_mtuSize - CA_BLE_HEADER_SIZE, + bleData->data, + bleData->dataLen, + index, + dataHeader, + g_mtuSize); + if (CA_STATUS_OK != result) { OIC_LOG_V(ERROR, CALEADAPTER_TAG, - "Update characteristics failed, result [%d]", result); + "Making data segment 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); - } - int32_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 = CAUpdateCharacteristicsToGattClient( - bleData->remoteEndpoint->addr, - bleData->data + (index * CA_SUPPORTED_BLE_MTU_SIZE) - CA_HEADER_LENGTH, - remainingLen); + result = + CAUpdateCharacteristicsToGattClient( + bleData->remoteEndpoint->addr, + dataSegment, + g_mtuSize); + if (CA_STATUS_OK != result) { - OIC_LOG_V(ERROR, CALEADAPTER_TAG, "Update characteristics failed, result [%d]", - 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]", remainingLen); - } - } - else - { - 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); - CALEErrorHandler(NULL, bleData->data, bleData->dataLen, result); - OICFree(dataSegment); - return; + OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "Server Sent data length [%d]", + g_mtuSize); } - OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "Server Sent data length [%d]", length); - for (index = 1; index < iter; index++) + + if (remainingLen && (totalLength > g_mtuSize)) { - // Send the remaining header. - OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "Sending the chunk number [%d]", index); - result = CAUpdateCharacteristicsToAllGattClients( - bleData->data + ((index * CA_SUPPORTED_BLE_MTU_SIZE) - CA_HEADER_LENGTH), - CA_SUPPORTED_BLE_MTU_SIZE); + // send the last segment of the data (Ex: 22 bytes of 622 + // bytes of data when MTU is 200) + result = CAMakeRemainDataSegment(dataSegment, + remainingLen, + bleData->data, + bleData->dataLen, + index, + dataHeader, + g_mtuSize); + 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); + OIC_LOG_V(ERROR, CALEADAPTER_TAG, + "Making data segment failed, result [%d]", result); + g_errorHandler(bleData->remoteEndpoint, bleData->data, bleData->dataLen, result); return; } - OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "Server Sent data length [%d]", CA_SUPPORTED_BLE_MTU_SIZE); - } - int32_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 = CAUpdateCharacteristicsToAllGattClients( - bleData->data + (index * CA_SUPPORTED_BLE_MTU_SIZE) - CA_HEADER_LENGTH, - remainingLen); + result = CAUpdateCharacteristicsToGattClient( + bleData->remoteEndpoint->addr, + dataSegment, + remainingLen + CA_BLE_HEADER_SIZE); + if (CA_STATUS_OK != result) { - OIC_LOG_V(ERROR, CALEADAPTER_TAG, "Update characteristics failed, result [%d]", + OIC_LOG_V(ERROR, + CALEADAPTER_TAG, + "Update characteristics failed, result [%d]", result); - CALEErrorHandler(NULL, bleData->data, bleData->dataLen, result); - OICFree(dataSegment); + g_errorHandler(bleData->remoteEndpoint, + bleData->data, + bleData->dataLen, + result); return; } - OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "Server Sent data length [%d]", remainingLen); + OIC_LOG_V(DEBUG, + CALEADAPTER_TAG, + "Server Sent Unicast Last Data - data length [%zu]", + remainingLen + CA_BLE_HEADER_SIZE); } + } + else + { + OIC_LOG(DEBUG, CALEADAPTER_TAG, "Server Sending Multicast data"); + OIC_LOG(DEBUG, CALEADAPTER_TAG, "BLE Multicast is not supported"); } - OICFree(dataSegment); - OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT"); + OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "OUT %s", __func__); } -void CALEClientSendDataThread(void *threadData) +static void CALEClientSendDataThread(void *threadData) { - OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN"); + OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "IN %s", __func__); CALEData_t *bleData = (CALEData_t *) threadData; if (!bleData) { - OIC_LOG(DEBUG, CALEADAPTER_TAG, "Invalid bledata!"); + OIC_LOG(ERROR, CALEADAPTER_TAG, "Invalid bledata!"); return; } - char *header = (char *) OICCalloc(CA_HEADER_LENGTH, sizeof(char)); - VERIFY_NON_NULL_VOID(header, CALEADAPTER_TAG, "Malloc failed"); - - uint32_t totalLength = bleData->dataLen + CA_HEADER_LENGTH; - char *dataSegment = (char *) OICCalloc(totalLength + 1, sizeof(char)); - if (NULL == dataSegment) + if (!bleData->remoteEndpoint) { - OIC_LOG(ERROR, CALEADAPTER_TAG, "Malloc failed"); - OICFree(header); + OIC_LOG(ERROR, CALEADAPTER_TAG, "Invalid endpoint of bledata!"); return; } - CAResult_t result = CAGenerateHeader(header, bleData->dataLen); - if (CA_STATUS_OK != result ) +#if defined(__TIZEN__) || defined(__ANDROID__) + // get MTU size + if (false == CALEClientIsConnected(bleData->remoteEndpoint->addr)) { - OIC_LOG(ERROR, CALEADAPTER_TAG, "Generate header failed"); - OICFree(header); - OICFree(dataSegment); - return ; + // triggering to gatt connect and MTU negotiation + CAResult_t res = CALEClientSendNegotiationMessage( + bleData->remoteEndpoint->addr); + + if (CA_STATUS_OK != res) + { + OIC_LOG_V(ERROR, + CALEADAPTER_TAG, + "CALEClientSendNegotiationMessage has failed, result [%d]", + res); + + g_errorHandler(bleData->remoteEndpoint, + bleData->data, + bleData->dataLen, + res); + return; + } } - memcpy(dataSegment, header, CA_HEADER_LENGTH); - OICFree(header); + g_mtuSize = CALEClientGetMtuSize(bleData->remoteEndpoint->addr); +#endif + OIC_LOG_V(INFO, CALEADAPTER_TAG, "MTU size [%d]", g_mtuSize); - uint32_t length = 0; - if (CA_SUPPORTED_BLE_MTU_SIZE > totalLength) + 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, + g_mtuSize); + + if (CA_STATUS_OK != result) { - length = totalLength; - OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "length [%d]", length); - memcpy(dataSegment + CA_HEADER_LENGTH, bleData->data, bleData->dataLen); + OIC_LOG_V(ERROR, CALEADAPTER_TAG, + "CAGenerateVariableForFragmentation failed, result [%d]", result); + g_errorHandler(bleData->remoteEndpoint, bleData->data, bleData->dataLen, result); + return; } - else + + OIC_LOG_V(DEBUG, CALEADAPTER_TAG, + "Packet info: data size[%d] midPacketCount[%u] remainingLen[%zu] totalLength[%zu]", + 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 { - length = CA_SUPPORTED_BLE_MTU_SIZE; - OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "length [%d]", length); - memcpy(dataSegment + CA_HEADER_LENGTH, bleData->data, - CA_SUPPORTED_BLE_MTU_SIZE - CA_HEADER_LENGTH); - } + secureFlag = (bleData->remoteEndpoint->flags & CA_SECURE) ? + CA_BLE_PACKET_SECURE : CA_BLE_PACKET_NON_SECURE; - uint32_t iter = totalLength / CA_SUPPORTED_BLE_MTU_SIZE; - uint32_t index = 0; - if (NULL != bleData->remoteEndpoint) //Sending Unicast Data + OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "This Packet is secure? %d", secureFlag); + result = CAGenerateHeader(dataHeader, + CA_BLE_PACKET_START, + g_localBLESourcePort, + secureFlag, + bleData->remoteEndpoint->port); + } + else //Multicast Data { - OIC_LOG(DEBUG, CALEADAPTER_TAG, "Sending Unicast Data"); - // Send the first segment with the header. - result = CAUpdateCharacteristicsToGattServer(bleData->remoteEndpoint->addr, - dataSegment, - length, - LE_UNICAST, 0); + result = CAGenerateHeader(dataHeader, + CA_BLE_PACKET_START, + g_localBLESourcePort, + secureFlag, + CA_BLE_MULTICAST_PORT); + } - if (CA_STATUS_OK != result) + OIC_LOG_V(INFO, CALEADAPTER_TAG, "header info: secureFlag[%X]", secureFlag); + + 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 (g_mtuSize > totalLength) + { + length = totalLength; + dataLen = bleData->dataLen; + } + else + { + length = g_mtuSize; + dataLen = g_mtuSize - 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; + } + + const uint32_t iter = midPacketCount; + uint32_t index = 0; + if (NULL != bleData->remoteEndpoint) //Sending Unicast Data + { + OIC_LOG(DEBUG, CALEADAPTER_TAG, "Sending Unicast Data"); + // Send the first segment with the header. + result = + CAUpdateCharacteristicsToGattServer( + bleData->remoteEndpoint->addr, + dataSegment, + length, + 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); + return; + } + OIC_LOG_V(DEBUG, + CALEADAPTER_TAG, + "Client Sent Unicast First Data - data length [%zu]", + length); + + 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, "Update characteristics failed, result [%d]", result); + OIC_LOG_V(ERROR, CALEADAPTER_TAG, + "CAGenerateHeader failed, result [%d]", result); g_errorHandler(bleData->remoteEndpoint, bleData->data, bleData->dataLen, result); - OICFree(dataSegment); - return ; + return; } - OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "Client Sent Data length is [%d]", length); - for (index = 1; index < iter; index++) + for (index = 0; index < iter; index++) { + result = CAMakeRemainDataSegment(dataSegment, + g_mtuSize - CA_BLE_HEADER_SIZE, + bleData->data, + bleData->dataLen, + index, + dataHeader, + g_mtuSize); + + 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) - CA_HEADER_LENGTH, - CA_SUPPORTED_BLE_MTU_SIZE, + dataSegment, + g_mtuSize, LE_UNICAST, 0); + if (CA_STATUS_OK != result) { - OIC_LOG_V(ERROR, CALEADAPTER_TAG, "Update characteristics failed, result [%d]", - 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]", - CA_SUPPORTED_BLE_MTU_SIZE); + OIC_LOG_V(DEBUG, + CALEADAPTER_TAG, + "Client Sent Unicast %d Data - data(mtu) length [%zu]", + index + 1, + g_mtuSize); } - uint32_t remainingLen = totalLength % CA_SUPPORTED_BLE_MTU_SIZE; - if (remainingLen && (totalLength > CA_SUPPORTED_BLE_MTU_SIZE)) + if (remainingLen && (totalLength > g_mtuSize)) { - // 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"); + // send the last segment of the data (Ex: 22 bytes of 622 + // bytes of data when MTU is 200) + result = CAMakeRemainDataSegment(dataSegment, + remainingLen, + bleData->data, + bleData->dataLen, + index, + dataHeader, + g_mtuSize); + + 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) - CA_HEADER_LENGTH, - remainingLen, + dataSegment, + remainingLen + CA_BLE_HEADER_SIZE, LE_UNICAST, 0); if (CA_STATUS_OK != result) @@ -1020,75 +1714,31 @@ void CALEClientSendDataThread(void *threadData) 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 Unicast Last Data - data length [%zu]", + remainingLen + CA_BLE_HEADER_SIZE); } } else { //Sending Mulitcast Data - // Send the first segment with the header. - OIC_LOG(DEBUG, CALEADAPTER_TAG, "Sending Multicast Data"); - result = CAUpdateCharacteristicsToAllGattServers(dataSegment, length); - 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]", length); - // Send the remaining header. - for (index = 1; index < iter; index++) - { - result = CAUpdateCharacteristicsToAllGattServers( - bleData->data + (index * CA_SUPPORTED_BLE_MTU_SIZE) - CA_HEADER_LENGTH, - CA_SUPPORTED_BLE_MTU_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]", - 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 = CAUpdateCharacteristicsToAllGattServers( - bleData->data + (index * CA_SUPPORTED_BLE_MTU_SIZE) - CA_HEADER_LENGTH, - remainingLen); - 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(DEBUG, CALEADAPTER_TAG, "Client Sending Multicast Data"); + OIC_LOG(DEBUG, CALEADAPTER_TAG, "BLE Multicast is not supported"); } - OICFree(dataSegment); - - OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT - CABLEClientSendDataThread"); + OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "OUT %s", __func__); } -CALEData_t *CACreateLEData(const CAEndpoint_t *remoteEndpoint, const void *data, - uint32_t dataLength) +static CALEData_t *CACreateLEData(const CAEndpoint_t *remoteEndpoint, + const uint8_t *data, + uint32_t dataLength, + u_arraylist_t *senderInfo) { - CALEData_t *bleData = (CALEData_t *) OICMalloc(sizeof(CALEData_t)); + CALEData_t * const bleData = OICMalloc(sizeof(CALEData_t)); + if (!bleData) { OIC_LOG(ERROR, CALEADAPTER_TAG, "Memory allocation failed!"); @@ -1096,20 +1746,26 @@ CALEData_t *CACreateLEData(const CAEndpoint_t *remoteEndpoint, const void *data, } bleData->remoteEndpoint = CACloneEndpoint(remoteEndpoint); - bleData->data = (void *)OICCalloc(dataLength + 1, 1); + bleData->data = OICCalloc(dataLength + 1, 1); + if (NULL == bleData->data) { OIC_LOG(ERROR, CALEADAPTER_TAG, "Memory allocation failed!"); CAFreeLEData(bleData); return NULL; } + memcpy(bleData->data, data, dataLength); bleData->dataLen = dataLength; + if (senderInfo) + { + bleData->senderInfo = senderInfo; + } return bleData; } -void CAFreeLEData(CALEData_t *bleData) +static void CAFreeLEData(CALEData_t *bleData) { VERIFY_NON_NULL_VOID(bleData, CALEADAPTER_TAG, "Param bleData is NULL"); @@ -1118,34 +1774,338 @@ void CAFreeLEData(CALEData_t *bleData) OICFree(bleData); } -void CALEDataDestroyer(void *data, uint32_t size) +static void CALEDataDestroyer(void *data, uint32_t size) { + if ((size_t)size < sizeof(CALEData_t *)) + { + OIC_LOG_V(DEBUG, CALEADAPTER_TAG, + "Destroy data too small %p %d", data, size); + } CALEData_t *ledata = (CALEData_t *) data; CAFreeLEData(ledata); } #endif -CAResult_t CAInitLEAdapterMutex() +#ifdef SINGLE_THREAD +static void CALEDataReceiverHandlerSingleThread(const uint8_t *data, + uint32_t dataLen) +{ + OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "IN %s", __func__); + + 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(INFO, CALEADAPTER_TAG, "totalDatalength [%d] received Datalen [%d]", + g_singleThreadReceiveData->totalDataLen, g_singleThreadReceiveData->recvDataLen); + } + OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "OUT %s", __func__); +} + +static CAResult_t CALEServerSendDataSingleThread(const uint8_t *data, + uint32_t dataLen) +{ + OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "%s", __func__);); + + 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, + g_mtuSize); + + 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 (g_mtuSize > totalLength) + { + length = totalLength; + dataOnlyLen = dataLen; + } + else + { + length = g_mtuSize; + dataOnlyLen = g_mtuSize - 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, + g_mtuSize - CA_BLE_HEADER_SIZE, + data, + dataLen, + iter, + dataHeader, + g_mtuSize); + + if (CA_STATUS_OK != result) + { + OIC_LOG_V(ERROR, CALEADAPTER_TAG, + "Making data segment failed, result [%d]", result); + return result; + } + + result = CAUpdateCharacteristicsToAllGattClients( + dataSegment, + g_mtuSize); + + if (CA_STATUS_OK != result) + { + OIC_LOG(ERROR, CALEADAPTER_TAG, "Update characteristics failed"); + return result; + } + + CALEDoEvents(); + } + + if (remainingLen && (totalLength > g_mtuSize)) + { + // send the last segment of the data + OIC_LOG(DEBUG, CALEADAPTER_TAG, "Sending the last chunk"); + + result = CAMakeRemainDataSegment(dataSegment, + remainingLen, + data, + dataLen, + dataLimit, + dataHeader, + g_mtuSize); + + 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"); + OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "%s", __func__); if (NULL == g_bleIsServerMutex) { - g_bleIsServerMutex = ca_mutex_new(); + g_bleIsServerMutex = oc_mutex_new(); if (NULL == g_bleIsServerMutex) { - OIC_LOG(ERROR, CALEADAPTER_TAG, "ca_mutex_new failed"); + OIC_LOG(ERROR, CALEADAPTER_TAG, "oc_mutex_new failed"); return CA_STATUS_FAILED; } } if (NULL == g_bleNetworkCbMutex) { - g_bleNetworkCbMutex = ca_mutex_new(); + g_bleNetworkCbMutex = oc_mutex_new(); if (NULL == g_bleNetworkCbMutex) { - OIC_LOG(ERROR, CALEADAPTER_TAG, "ca_mutex_new failed"); + OIC_LOG(ERROR, CALEADAPTER_TAG, "oc_mutex_new failed"); CATerminateLEAdapterMutex(); return CA_STATUS_FAILED; } @@ -1153,10 +2113,10 @@ CAResult_t CAInitLEAdapterMutex() if (NULL == g_bleLocalAddressMutex) { - g_bleLocalAddressMutex = ca_mutex_new(); + g_bleLocalAddressMutex = oc_mutex_new(); if (NULL == g_bleLocalAddressMutex) { - OIC_LOG(ERROR, CALEADAPTER_TAG, "ca_mutex_new failed"); + OIC_LOG(ERROR, CALEADAPTER_TAG, "oc_mutex_new failed"); CATerminateLEAdapterMutex(); return CA_STATUS_FAILED; } @@ -1164,10 +2124,10 @@ CAResult_t CAInitLEAdapterMutex() if (NULL == g_bleAdapterThreadPoolMutex) { - g_bleAdapterThreadPoolMutex = ca_mutex_new(); + g_bleAdapterThreadPoolMutex = oc_mutex_new(); if (NULL == g_bleAdapterThreadPoolMutex) { - OIC_LOG(ERROR, CALEADAPTER_TAG, "ca_mutex_new failed"); + OIC_LOG(ERROR, CALEADAPTER_TAG, "oc_mutex_new failed"); CATerminateLEAdapterMutex(); return CA_STATUS_FAILED; } @@ -1175,32 +2135,32 @@ CAResult_t CAInitLEAdapterMutex() if (NULL == g_bleClientSendDataMutex) { - g_bleClientSendDataMutex = ca_mutex_new(); + g_bleClientSendDataMutex = oc_mutex_new(); if (NULL == g_bleClientSendDataMutex) { - OIC_LOG(ERROR, CALEADAPTER_TAG, "ca_mutex_new failed"); + OIC_LOG(ERROR, CALEADAPTER_TAG, "oc_mutex_new failed"); CATerminateLEAdapterMutex(); return CA_STATUS_FAILED; } } - if (NULL == g_bleClientReceiveDataMutex) + if (NULL == g_bleServerSendDataMutex) { - g_bleClientReceiveDataMutex = ca_mutex_new(); - if (NULL == g_bleClientReceiveDataMutex) + g_bleServerSendDataMutex = oc_mutex_new(); + if (NULL == g_bleServerSendDataMutex) { - OIC_LOG(ERROR, CALEADAPTER_TAG, "ca_mutex_new failed"); + OIC_LOG(ERROR, CALEADAPTER_TAG, "oc_mutex_new failed"); CATerminateLEAdapterMutex(); return CA_STATUS_FAILED; } } - if (NULL == g_bleServerSendDataMutex) + if (NULL == g_bleAdapterReqRespCbMutex) { - g_bleServerSendDataMutex = ca_mutex_new(); - if (NULL == g_bleServerSendDataMutex) + g_bleAdapterReqRespCbMutex = oc_mutex_new(); + if (NULL == g_bleAdapterReqRespCbMutex) { - OIC_LOG(ERROR, CALEADAPTER_TAG, "ca_mutex_new failed"); + OIC_LOG(ERROR, CALEADAPTER_TAG, "oc_mutex_new failed"); CATerminateLEAdapterMutex(); return CA_STATUS_FAILED; } @@ -1208,75 +2168,475 @@ CAResult_t CAInitLEAdapterMutex() if (NULL == g_bleServerReceiveDataMutex) { - g_bleServerReceiveDataMutex = ca_mutex_new(); + g_bleServerReceiveDataMutex = oc_mutex_new(); if (NULL == g_bleServerReceiveDataMutex) { - OIC_LOG(ERROR, CALEADAPTER_TAG, "ca_mutex_new failed"); - CATerminateLEAdapterMutex(); + OIC_LOG(ERROR, CALEADAPTER_TAG, "oc_mutex_new failed"); return CA_STATUS_FAILED; } } - if (NULL == g_bleAdapterReqRespCbMutex) + if (NULL == g_bleClientReceiveDataMutex) { - g_bleAdapterReqRespCbMutex = ca_mutex_new(); - if (NULL == g_bleAdapterReqRespCbMutex) + g_bleClientReceiveDataMutex = oc_mutex_new(); + if (NULL == g_bleClientReceiveDataMutex) { - OIC_LOG(ERROR, CALEADAPTER_TAG, "ca_mutex_new failed"); - CATerminateLEAdapterMutex(); + OIC_LOG(ERROR, CALEADAPTER_TAG, "oc_mutex_new failed"); return CA_STATUS_FAILED; } } - OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT"); return CA_STATUS_OK; } -void CATerminateLEAdapterMutex() +static void CATerminateLEAdapterMutex() { - OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN"); + OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "%s", __func__); - ca_mutex_free(g_bleIsServerMutex); + oc_mutex_free(g_bleIsServerMutex); g_bleIsServerMutex = NULL; - ca_mutex_free(g_bleNetworkCbMutex); + oc_mutex_free(g_bleNetworkCbMutex); g_bleNetworkCbMutex = NULL; - ca_mutex_free(g_bleLocalAddressMutex); + oc_mutex_free(g_bleLocalAddressMutex); g_bleLocalAddressMutex = NULL; - ca_mutex_free(g_bleAdapterThreadPoolMutex); + oc_mutex_free(g_bleAdapterThreadPoolMutex); g_bleAdapterThreadPoolMutex = NULL; - ca_mutex_free(g_bleClientSendDataMutex); + oc_mutex_free(g_bleClientSendDataMutex); g_bleClientSendDataMutex = NULL; - ca_mutex_free(g_bleClientReceiveDataMutex); - g_bleClientReceiveDataMutex = NULL; - - ca_mutex_free(g_bleServerSendDataMutex); + oc_mutex_free(g_bleServerSendDataMutex); g_bleServerSendDataMutex = NULL; - ca_mutex_free(g_bleServerReceiveDataMutex); + oc_mutex_free(g_bleAdapterReqRespCbMutex); + g_bleAdapterReqRespCbMutex = NULL; + + oc_mutex_free(g_bleServerReceiveDataMutex); g_bleServerReceiveDataMutex = NULL; - ca_mutex_free(g_bleAdapterReqRespCbMutex); - g_bleAdapterReqRespCbMutex = NULL; + oc_mutex_free(g_bleClientReceiveDataMutex); + g_bleClientReceiveDataMutex = NULL; +} + +/** + * Starting LE connectivity adapters. + * + * As its peer to peer it does not require to start any servers. + * + * @return ::CA_STATUS_OK or Appropriate error code. + */ +static CAResult_t CAStartLE(); + +/** + * Start listening server for receiving multicast search requests. + * + * Transport Specific Behavior: + * LE Starts GATT Server with prefixed UUID and Characteristics + * per OIC Specification. + * @return ::CA_STATUS_OK or Appropriate error code. + */ +static CAResult_t CAStartLEListeningServer(); + +/** + * Stops listening server from receiving multicast search requests. + * + * Transport Specific Behavior: + * LE Starts GATT Server with prefixed UUID and Characteristics + * per OIC Specification. + * @return ::CA_STATUS_OK or Appropriate error code. + */ +static CAResult_t CAStopLEListeningServer(); + +/** + * Sarting discovery of servers for receiving multicast + * advertisements. + * + * Transport Specific Behavior: + * LE Starts GATT Server with prefixed UUID and Characteristics + * per OIC Specification. + * + * @return ::CA_STATUS_OK or Appropriate error code + */ +static CAResult_t CAStartLEDiscoveryServer(); + +/** + * Send data to the endpoint using the adapter connectivity. + * + * @param[in] endpoint Remote Endpoint information (like MAC address, + * reference URI and connectivity type) to which + * the unicast data has to be sent. + * @param[in] data Data which required to be sent. + * @param[in] dataLen Size of data to be sent. + * + * @note dataLen must be > 0. + * + * @return The number of bytes sent on the network, or -1 on error. + */ +static int32_t CASendLEUnicastData(const CAEndpoint_t *endpoint, + const void *data, + uint32_t dataLen, + CADataType_t dataType); + +/** + * Send multicast data to the endpoint using the LE connectivity. + * + * @param[in] endpoint Remote Endpoint information to which the + * multicast data has to be sent. + * @param[in] data Data which required to be sent. + * @param[in] dataLen Size of data to be sent. + * + * @note dataLen must be > 0. + * + * @return The number of bytes sent on the network, or -1 on error. + */ +static int32_t CASendLEMulticastData(const CAEndpoint_t *endpoint, + const void *data, + uint32_t dataLen, + CADataType_t dataType); + +/** + * Get LE Connectivity network information. + * + * @param[out] info Local connectivity information structures. + * @param[out] size Number of local connectivity structures. + * + * @return ::CA_STATUS_OK or Appropriate error code. + */ +static CAResult_t CAGetLEInterfaceInformation(CAEndpoint_t **info, + uint32_t *size); + +/** + * Read Synchronous API callback. + * + * @return ::CA_STATUS_OK or Appropriate error code. + */ +static CAResult_t CAReadLEData(); + +/** + * Stopping the adapters and close socket connections. + * + * LE Stops all GATT servers and GATT Clients. + * + * @return ::CA_STATUS_OK or Appropriate error code. + */ +static CAResult_t CAStopLE(); + +/** + * Terminate the LE connectivity adapter. + * + * Configuration information will be deleted from further use. + */ +static void CATerminateLE(); + +/** + * This function will receive the data from the GattServer and add the + * data to the Server receiver queue. + * + * @param[in] remoteAddress Remote address of the device from where + * data is received. + * @param[in] data Actual data received from the remote + * device. + * @param[in] dataLength Length of the data received from the + * remote device. + * @param[in] sentLength Length of the data sent from the remote + * device. + * + * @return ::CA_STATUS_OK or Appropriate error code. + * @retval ::CA_STATUS_OK Successful. + * @retval ::CA_STATUS_INVALID_PARAM Invalid input arguments. + * @retval ::CA_STATUS_FAILED Operation failed. + * + */ +static CAResult_t CALEAdapterServerReceivedData(const char *remoteAddress, + const uint8_t *data, + uint32_t dataLength, + uint32_t *sentLength); + +/** + * This function will receive the data from the GattClient and add the + * data into the Client receiver queue. + * + * @param[in] remoteAddress Remote address of the device from where + * data is received. + * @param[in] data Actual data recevied from the remote + * device. + * @param[in] dataLength Length of the data received from the + * remote device. + * @param[in] sentLength Length of the data sent from the remote + * device. + * + * @return ::CA_STATUS_OK or Appropriate error code. + * @retval ::CA_STATUS_OK Successful. + * @retval ::CA_STATUS_INVALID_PARAM Invalid input arguments. + * @retval ::CA_STATUS_FAILED Operation failed. + */ +static CAResult_t CALEAdapterClientReceivedData(const char *remoteAddress, + const uint8_t *data, + uint32_t dataLength, + uint32_t *sentLength); + +/** + * Set the NetworkPacket received callback to CA layer from adapter + * layer. + * + * @param[in] callback Callback handle sent from the upper layer. + */ +static void CASetLEReqRespAdapterCallback(CANetworkPacketReceivedCallback callback); + +/** + * Push the data from CA layer to the Sender processor queue. + * + * @param[in] remoteEndpoint Remote endpoint information of the + * server. + * @param[in] data Data to be transmitted from LE. + * @param[in] dataLen Length of the Data being transmitted. + * + * @return ::CA_STATUS_OK or Appropriate error code. + * @retval ::CA_STATUS_OK Successful. + * @retval ::CA_STATUS_INVALID_PARAM Invalid input arguments. + * @retval ::CA_STATUS_FAILED Operation failed. + */ +static CAResult_t CALEAdapterServerSendData(const CAEndpoint_t *remoteEndpoint, + const uint8_t *data, + uint32_t dataLen); + +/** + * Push the data from CA layer to the Sender processor queue. + * + * @param[in] remoteEndpoint Remote endpoint information of the + * server. + * @param[in] data Data to be transmitted from LE. + * @param[in] dataLen Length of the Data being transmitted. + * + * @return ::CA_STATUS_OK or Appropriate error code. + * @retval ::CA_STATUS_OK Successful. + * @retval ::CA_STATUS_INVALID_PARAM Invalid input arguments. + * @retval ::CA_STATUS_FAILED Operation failed. + */ +static CAResult_t CALEAdapterClientSendData(const CAEndpoint_t *remoteEndpoint, + const uint8_t *data, + uint32_t dataLen); + +static CAResult_t CALEAdapterGattServerStart() +{ + OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "%s", __func__); + + if (caglobals.bleFlags & CA_LE_SERVER_DISABLE) + { + OIC_LOG_V(INFO, CALEADAPTER_TAG, "server flag of configure is disable [%d]", + caglobals.bleFlags); + return CA_STATUS_OK; + } + + CAResult_t result = CAStartLEGattServer(); + +#ifndef SINGLE_THREAD + /* + Don't start the server side sending queue thread until the + server itself has actually started. + */ + if (CA_STATUS_OK == result) + { + oc_mutex_lock(g_bleServerSendDataMutex); + result = CAQueueingThreadStart(g_bleServerSendQueueHandle); + oc_mutex_unlock(g_bleServerSendDataMutex); + + if (CA_STATUS_OK != result) + { + OIC_LOG_V(ERROR, + CALEADAPTER_TAG, + "Unable to start server queuing thread (%d)", + result); + } + } +#endif + + return result; +} - OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT"); +static CAResult_t CALEAdapterGattServerStop() +{ + OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "%s", __func__); + + if (caglobals.bleFlags & CA_LE_SERVER_DISABLE) + { + OIC_LOG_V(INFO, CALEADAPTER_TAG, "server flag of configure is disable [%d]", + caglobals.bleFlags); + return CA_STATUS_OK; + } + +#ifndef SINGLE_THREAD + + oc_mutex_lock(g_bleServerSendDataMutex); + CAResult_t res = CAQueueingThreadStop(g_bleServerSendQueueHandle); + if (CA_STATUS_OK != res) + { + OIC_LOG(ERROR, CALEADAPTER_TAG, "CAQueueingThreadStop has failed"); + } + oc_mutex_unlock(g_bleServerSendDataMutex); + + res = CAStopLEGattServer(); + if (CA_STATUS_OK != res) + { + OIC_LOG(ERROR, CALEADAPTER_TAG, "CAStopLEGattServer has failed"); + } + + return res; +#else + return CAStopLEGattServer(); +#endif +} + +static CAResult_t CALEAdapterGattClientStart() +{ + OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "%s", __func__); + + CAResult_t result = CAStartLEGattClient(); + +#ifndef SINGLE_THREAD + /* + Don't start the client side sending queue thread until the + client itself has actually started. + */ + if (CA_STATUS_OK == result) + { + oc_mutex_lock(g_bleClientSendDataMutex); + result = CAQueueingThreadStart(g_bleClientSendQueueHandle); + oc_mutex_unlock(g_bleClientSendDataMutex); + + if (CA_STATUS_OK != result) + { + OIC_LOG(ERROR, + CALEADAPTER_TAG, + "Unable to start client queuing thread"); + } + } +#endif + + return result; +} + +static CAResult_t CALEAdapterGattClientStop() +{ +#ifndef SINGLE_THREAD + OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "%s", __func__); + CAStopLEGattClient(); + + oc_mutex_lock(g_bleClientSendDataMutex); + CAResult_t result = CAQueueingThreadStop(g_bleClientSendQueueHandle); + oc_mutex_unlock(g_bleClientSendDataMutex); + + return result; +#else + CAStopLEGattClient(); + + return CA_STATUS_OK; +#endif +} + +#ifdef __WITH_DTLS__ +static ssize_t CALESecureSendDataCB(CAEndpoint_t *endpoint, const void *data, size_t dataLen) +{ + 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); + + CAResult_t result; + CADataType_t dataType = g_dataType; + ssize_t ret = 0; + + if (ADAPTER_SERVER == g_adapterType || + (ADAPTER_BOTH_CLIENT_SERVER == g_adapterType && CA_RESPONSE_DATA == dataType)) + { + result = CALEAdapterServerSendData(endpoint, data, dataLen); + if (CA_STATUS_OK != result) + { + OIC_LOG(ERROR, CALEADAPTER_TAG, "Send unicast data for server failed" ); + + if (g_errorHandler) + { + g_errorHandler(endpoint, data, dataLen, result); + } + return ret; + } + ret = (ssize_t)dataLen; + } + else if (ADAPTER_CLIENT == g_adapterType || + (ADAPTER_BOTH_CLIENT_SERVER == g_adapterType && CA_REQUEST_DATA == dataType) || + (ADAPTER_BOTH_CLIENT_SERVER == g_adapterType && CA_RESPONSE_FOR_RES == dataType)) + { + result = CALEAdapterClientSendData(endpoint, data, dataLen); + if (CA_STATUS_OK != result) + { + OIC_LOG(ERROR, CALEADAPTER_TAG, "Send unicast data for client failed" ); + + if (g_errorHandler) + { + g_errorHandler(endpoint, data, dataLen, result); + } + return ret; + } + ret = (ssize_t)dataLen; + } + else + { + OIC_LOG_V(ERROR, CALEADAPTER_TAG, + "Can't Send Message adapterType = %d, dataType = %d", g_adapterType, dataType); + return ret; + } + OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "OUT %s", __func__); + return ret; +} + +void CALESecureReceiveDataCB(const CASecureEndpoint_t *sep, const void *data, + size_t dataLen) +{ + OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "%s", __func__); + + VERIFY_NON_NULL_VOID(sep, CALEADAPTER_TAG, "sep is NULL"); + VERIFY_NON_NULL_VOID(data, CALEADAPTER_TAG, "data is NULL"); + + OIC_LOG_V(DEBUG, CALEADAPTER_TAG, + "Secure Data Receive - decrypted datalen = %d", dataLen); + + if (dataLen <= 0) + { + OIC_LOG(ERROR, CALEADAPTER_TAG, "incorrect dataLen, derecypt fail !"); + return; + } + + OIC_LOG_BUFFER(DEBUG, CALEADAPTER_TAG, data, dataLen); + + if (g_networkPacketReceivedCallback) + { + OIC_LOG_V(DEBUG, CALEADAPTER_TAG, + "[CALESecureReceiveDataCB] Secure flags = %d, %x", + sep->endpoint.flags, sep->endpoint.flags); + OIC_LOG(DEBUG, CALEADAPTER_TAG, + "[CALESecureReceiveDataCB] Received data up !"); + g_networkPacketReceivedCallback(sep, data, dataLen); + } } +#endif CAResult_t CAInitializeLE(CARegisterConnectivityCallback registerCallback, CANetworkPacketReceivedCallback reqRespCallback, - CANetworkChangeCallback netCallback, - CAErrorHandleCallback errorCallback, ca_thread_pool_t handle) + CAAdapterChangeCallback netCallback, + CAConnectionChangeCallback connCallback, + CAErrorHandleCallback errorCallback, + ca_thread_pool_t handle) { - OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN"); + OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "%s", __func__); //Input validation VERIFY_NON_NULL(registerCallback, CALEADAPTER_TAG, "RegisterConnectivity callback is null"); VERIFY_NON_NULL(reqRespCallback, CALEADAPTER_TAG, "PacketReceived Callback is null"); VERIFY_NON_NULL(netCallback, CALEADAPTER_TAG, "NetworkChange Callback is null"); + VERIFY_NON_NULL(connCallback, CALEADAPTER_TAG, "ConnectionChange Callback is null"); CAResult_t result = CA_STATUS_OK; result = CAInitLEAdapterMutex(); @@ -1285,208 +2645,276 @@ CAResult_t CAInitializeLE(CARegisterConnectivityCallback registerCallback, OIC_LOG(ERROR, CALEADAPTER_TAG, "CAInitBleAdapterMutex failed!"); return CA_STATUS_FAILED; } + result = CAInitializeLENetworkMonitor(); if (CA_STATUS_OK != result) { OIC_LOG(ERROR, CALEADAPTER_TAG, "CAInitializeLENetworkMonitor() failed"); return CA_STATUS_FAILED; } - CAInitializeLEAdapter(); + result = CAInitializeLEGattClient(); + if (CA_STATUS_OK != result) + { + OIC_LOG(ERROR, CALEADAPTER_TAG, "CAInitializeLEGattClient() failed"); + return CA_STATUS_FAILED; + } + CASetLEClientThreadPoolHandle(handle); + CASetLEReqRespClientCallback(CALEAdapterClientReceivedData); CASetLEServerThreadPoolHandle(handle); + result = CAInitializeLEGattServer(); + if (CA_STATUS_OK != result) + { + OIC_LOG(ERROR, CALEADAPTER_TAG, "CAInitializeLEGattServer() failed"); + return CA_STATUS_FAILED; + } + CASetLEAdapterThreadPoolHandle(handle); CASetLEReqRespServerCallback(CALEAdapterServerReceivedData); CASetLEReqRespAdapterCallback(reqRespCallback); CASetBLEClientErrorHandleCallback(CALEErrorHandler); CASetBLEServerErrorHandleCallback(CALEErrorHandler); - CALERegisterNetworkNotifications(netCallback); + CALERegisterNetworkNotifications(netCallback, connCallback); g_errorHandler = errorCallback; - CAConnectivityHandler_t connHandler; - connHandler.startAdapter = CAStartLE; - connHandler.stopAdapter = CAStopLE; - connHandler.startListenServer = CAStartLEListeningServer; - connHandler.startDiscoveryServer = CAStartLEDiscoveryServer; - connHandler.sendData = CASendLEUnicastData; - connHandler.sendDataToAll = CASendLEMulticastData; - connHandler.GetnetInfo = CAGetLEInterfaceInformation; - connHandler.readData = CAReadLEData; - connHandler.terminate = CATerminateLE; - registerCallback(connHandler, CA_ADAPTER_GATT_BTLE); - - OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT"); +#ifdef __WITH_DTLS__ + if (CA_STATUS_OK != CAinitSslAdapter()) + { + OIC_LOG(ERROR, CALEADAPTER_TAG, "Failed to init SSL adapter"); + } + else + { + CAsetSslAdapterCallbacks(CALESecureReceiveDataCB, CALESecureSendDataCB, + CA_ADAPTER_GATT_BTLE); + } +#endif + static const CAConnectivityHandler_t connHandler = + { + .startAdapter = CAStartLE, + .stopAdapter = CAStopLE, + .startListenServer = CAStartLEListeningServer, + .stopListenServer = CAStopLEListeningServer, + .startDiscoveryServer = CAStartLEDiscoveryServer, + .sendData = CASendLEUnicastData, + .sendDataToAll = CASendLEMulticastData, + .GetnetInfo = CAGetLEInterfaceInformation, + .readData = CAReadLEData, + .terminate = CATerminateLE, + .cType = CA_ADAPTER_GATT_BTLE + }; + + registerCallback(connHandler); return CA_STATUS_OK; } -CAResult_t CAStartLE() +static CAResult_t CAStartLE() { - OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN"); - OIC_LOG(DEBUG, CALEADAPTER_TAG, "CAStartLE, not implemented"); - OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT"); - return CA_STATUS_OK; + return CAStartLEAdapter(); } -CAResult_t CAStopLE() +static CAResult_t CAStopLE() { - OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN"); +#ifdef __WITH_DTLS__ + CAdeinitSslAdapter(); +#endif + #ifndef SINGLE_THREAD CAStopLEQueues(); #endif - ca_mutex_lock(g_bleIsServerMutex); - if (true == g_isServer) - { - CAStopLEGattServer(); - } - else - { - CAStopLEGattClient(); - } - ca_mutex_unlock(g_bleIsServerMutex); - - OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT"); - - return CA_STATUS_OK; + oc_mutex_lock(g_bleIsServerMutex); + switch (g_adapterType) + { + case ADAPTER_SERVER: + CALEAdapterGattServerStop(); + break; + case ADAPTER_CLIENT: + CALEAdapterGattClientStop(); + break; + case ADAPTER_BOTH_CLIENT_SERVER: + CALEAdapterGattServerStop(); + CALEAdapterGattClientStop(); + break; + default: + break; + } + oc_mutex_unlock(g_bleIsServerMutex); + return CAStopLEAdapter(); } -void CATerminateLE() +static void CATerminateLE() { - OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN"); + OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "%s", __func__); CASetLEReqRespServerCallback(NULL); CASetLEReqRespClientCallback(NULL); - CALERegisterNetworkNotifications(NULL); + CALERegisterNetworkNotifications(NULL, NULL); CASetLEReqRespAdapterCallback(NULL); CATerminateLENetworkMonitor(); - ca_mutex_lock(g_bleIsServerMutex); - if (true == g_isServer) - { - CATerminateLEGattServer(); - } - else - { - CATerminateLEGattClient(); - } - ca_mutex_unlock(g_bleIsServerMutex); + oc_mutex_lock(g_bleIsServerMutex); + switch (g_adapterType) + { + case ADAPTER_SERVER: + CATerminateLEGattServer(); + break; + case ADAPTER_CLIENT: + CATerminateLEGattClient(); + break; + case ADAPTER_BOTH_CLIENT_SERVER: + CATerminateLEGattServer(); + CATerminateLEGattClient(); + break; + default: + break; + } + g_adapterType = ADAPTER_EMPTY; + oc_mutex_unlock(g_bleIsServerMutex); #ifndef SINGLE_THREAD CATerminateLEQueues(); #endif - CATerminateLEAdapterMutex(); - OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT"); +#ifdef __WITH_DTLS__ + CAsetSslAdapterCallbacks(NULL, NULL, CA_ADAPTER_GATT_BTLE); +#endif + + CATerminateLEAdapterMutex(); } -CAResult_t CAStartLEListeningServer() +static CAResult_t CAStartLEListeningServer() { - OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN"); + OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "IN %s", __func__); + + if (caglobals.bleFlags & CA_LE_SERVER_DISABLE) + { + OIC_LOG_V(INFO, CALEADAPTER_TAG, "server flag of configure is disable [%d]", + caglobals.bleFlags); + return CA_STATUS_OK; + } + +#ifndef ROUTING_GATEWAY CAResult_t result = CA_STATUS_OK; #ifndef SINGLE_THREAD result = CAInitLEServerQueues(); if (CA_STATUS_OK != result) { OIC_LOG(ERROR, CALEADAPTER_TAG, "CAInitLEServerQueues failed"); - return CA_STATUS_FAILED; + return result; } #endif - result = CAGetLEAdapterState(); - if (CA_ADAPTER_NOT_ENABLED == result) + oc_mutex_lock(g_bleIsServerMutex); + switch (g_adapterType) { - gLeServerStatus = CA_LISTENING_SERVER; - OIC_LOG(DEBUG, CALEADAPTER_TAG, "Listen Server will be started once BT Adapter is enabled"); - return CA_STATUS_OK; + case ADAPTER_CLIENT: + g_adapterType = ADAPTER_BOTH_CLIENT_SERVER; + break; + case ADAPTER_BOTH_CLIENT_SERVER: + break; + default: + g_adapterType = ADAPTER_SERVER; } + oc_mutex_unlock(g_bleIsServerMutex); - if (CA_STATUS_FAILED == result) + result = CAGetLEAdapterState(); + if (CA_STATUS_OK != result) { - OIC_LOG(ERROR, CALEADAPTER_TAG, "Bluetooth get state failed!"); - return CA_STATUS_FAILED; + if (CA_ADAPTER_NOT_ENABLED == result) + { + OIC_LOG(DEBUG, + CALEADAPTER_TAG, + "Listen Server will be started once BT Adapter is enabled"); + result = CA_STATUS_OK; + } + } + else + { + result = CALEAdapterGattServerStart(); } - CAStartLEGattServer(); - - ca_mutex_lock(g_bleIsServerMutex); - g_isServer = true; - ca_mutex_unlock(g_bleIsServerMutex); + OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "OUT %s", __func__); + return result; +#else + // Routing Gateway only supports BLE client mode. + OIC_LOG(ERROR, CALEADAPTER_TAG, "LE server not supported in Routing Gateway"); + return CA_NOT_SUPPORTED; +#endif +} - OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT"); - return CA_STATUS_OK; +static CAResult_t CAStopLEListeningServer() +{ + OIC_LOG(ERROR, CALEADAPTER_TAG, "Listen server stop not supported."); + return CA_NOT_SUPPORTED; } -CAResult_t CAStartLEDiscoveryServer() +static CAResult_t CAStartLEDiscoveryServer() { - OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN"); + OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "IN %s", __func__); CAResult_t result = CA_STATUS_OK; #ifndef SINGLE_THREAD result = CAInitLEClientQueues(); if (CA_STATUS_OK != result) { OIC_LOG(ERROR, CALEADAPTER_TAG, "CAInitLEClientQueues failed"); - return CA_STATUS_FAILED; + return result; } #endif - result = CAGetLEAdapterState(); - if (CA_ADAPTER_NOT_ENABLED == result) + + oc_mutex_lock(g_bleIsServerMutex); + switch (g_adapterType) { - gLeServerStatus = CA_DISCOVERY_SERVER; - OIC_LOG(DEBUG, CALEADAPTER_TAG, "Listen Server will be started once BT Adapter is enabled"); - return CA_STATUS_OK; + case ADAPTER_SERVER: + g_adapterType = ADAPTER_BOTH_CLIENT_SERVER; + break; + case ADAPTER_BOTH_CLIENT_SERVER: + break; + default: + g_adapterType = ADAPTER_CLIENT; } + oc_mutex_unlock(g_bleIsServerMutex); - if (CA_STATUS_FAILED == result) + result = CAGetLEAdapterState(); + if (CA_STATUS_OK != result) { - OIC_LOG(ERROR, CALEADAPTER_TAG, "Bluetooth get state failed!"); - return CA_STATUS_FAILED; + if (CA_ADAPTER_NOT_ENABLED == result) + { + OIC_LOG(DEBUG, + CALEADAPTER_TAG, + "Discovery Server will be started once BT Adapter is enabled"); + result = CA_STATUS_OK; + } + } + else + { + result = CALEAdapterGattClientStart(); } - CAStartLEGattClient(); - - ca_mutex_lock(g_bleIsServerMutex); - g_isServer = false; - ca_mutex_unlock(g_bleIsServerMutex); - - OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT"); - return CA_STATUS_OK; -} - -CAResult_t CAStartLENotifyServer() -{ - OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN"); - - OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT"); - return CA_STATUS_OK; -} - -uint32_t CASendLENotification(const CAEndpoint_t *endpoint, const void *data, - uint32_t dataLen) -{ - OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN"); - - OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT"); - return 0; + OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "OUT %s", __func__); + return result; } -CAResult_t CAReadLEData() +static CAResult_t CAReadLEData() { - OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN"); #ifdef SINGLE_THREAD CACheckLEData(); #endif - OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT"); return CA_STATUS_OK; } -int32_t CASendLEUnicastData(const CAEndpoint_t *endpoint, const void *data, uint32_t dataLen) +static int32_t CASendLEUnicastData(const CAEndpoint_t *endpoint, + const void *data, + uint32_t dataLen, + CADataType_t dataType) { - OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN"); + OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "IN %s", __func__); + OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "type(%d)", dataType); //Input validation VERIFY_NON_NULL_RET(endpoint, CALEADAPTER_TAG, "Remote endpoint is null", -1); @@ -1494,44 +2922,108 @@ int32_t CASendLEUnicastData(const CAEndpoint_t *endpoint, const void *data, uint CAResult_t result = CA_STATUS_FAILED; - ca_mutex_lock(g_bleIsServerMutex); - if (true == g_isServer) + OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "g_adapterType: %d", g_adapterType); + if (ADAPTER_EMPTY == g_adapterType) { + OIC_LOG(ERROR, CALEADAPTER_TAG, "g_adapterType is Empty"); + } + + oc_mutex_lock(g_bleIsServerMutex); + if (ADAPTER_SERVER == g_adapterType || + (ADAPTER_BOTH_CLIENT_SERVER == g_adapterType && CA_RESPONSE_DATA == dataType)) + { +#ifdef __WITH_DTLS__ + if (endpoint && endpoint->flags & CA_SECURE) + { + OIC_LOG(DEBUG, CALEADAPTER_TAG, + "Response Data or server - secured data send(caadapternetdtlsencrypt) call"); + OIC_LOG_BUFFER(DEBUG, CALEADAPTER_TAG, data, dataLen); + g_dataType = dataType; + oc_mutex_unlock(g_bleIsServerMutex); + + result = CAencryptSsl(endpoint, data, dataLen); + if (CA_STATUS_OK != result) + { + OIC_LOG(ERROR, CALEADAPTER_TAG, "caadapternetdtlsencrypt failed!"); + return -1; + } + return dataLen; + } + else + { + OIC_LOG(DEBUG, CALEADAPTER_TAG, + "server or both - none secured data send(CALEAdapterServerSendData) call"); + result = CALEAdapterServerSendData(endpoint, data, dataLen); + } +#else result = CALEAdapterServerSendData(endpoint, data, dataLen); +#endif if (CA_STATUS_OK != result) { - OIC_LOG(ERROR, CALEADAPTER_TAG, "Send unicast data failed\n"); + oc_mutex_unlock(g_bleIsServerMutex); + OIC_LOG(ERROR, CALEADAPTER_TAG, "Send unicast data for server failed"); if (g_errorHandler) { - g_errorHandler((void *) endpoint, (void *) data, dataLen, result); + g_errorHandler(endpoint, data, dataLen, result); } - ca_mutex_unlock(g_bleIsServerMutex); + return -1; } } - else + else if (ADAPTER_CLIENT == g_adapterType || + (ADAPTER_BOTH_CLIENT_SERVER == g_adapterType && CA_REQUEST_DATA == dataType) || + (ADAPTER_BOTH_CLIENT_SERVER == g_adapterType && CA_RESPONSE_FOR_RES == dataType)) { +#ifdef __WITH_DTLS__ + if (endpoint && endpoint->flags & CA_SECURE) + { + OIC_LOG(DEBUG, CALEADAPTER_TAG, + "Request Data or client - secured data send(caadapternetdtlsencrypt) call"); + OIC_LOG_BUFFER(DEBUG, CALEADAPTER_TAG, data, dataLen); + g_dataType = dataType; + oc_mutex_unlock(g_bleIsServerMutex); + + result = CAencryptSsl(endpoint, data, dataLen); + if (CA_STATUS_OK != result) + { + OIC_LOG(ERROR, CALEADAPTER_TAG, "caadapternetdtlsencrypt failed!"); + return -1; + } + return dataLen; + } + else + { + OIC_LOG(DEBUG, CALEADAPTER_TAG, + "client or both - none secured data send(CALEAdapterClientSendData) call"); + result = CALEAdapterClientSendData(endpoint, data, dataLen); + } +#else result = CALEAdapterClientSendData(endpoint, data, dataLen); +#endif if (CA_STATUS_OK != result) { - OIC_LOG(ERROR, CALEADAPTER_TAG, "Send unicast data failed \n"); + oc_mutex_unlock(g_bleIsServerMutex); + OIC_LOG(ERROR, CALEADAPTER_TAG, "Send unicast data for client failed" ); + if (g_errorHandler) { g_errorHandler(endpoint, data, dataLen, result); } - ca_mutex_unlock(g_bleIsServerMutex); return -1; } } - ca_mutex_unlock(g_bleIsServerMutex); + oc_mutex_unlock(g_bleIsServerMutex); - OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT"); + OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "OUT %s", __func__); return dataLen; } -int32_t CASendLEMulticastData(const CAEndpoint_t *endpoint, const void *data, uint32_t dataLen) +static int32_t CASendLEMulticastData(const CAEndpoint_t *endpoint, + const void *data, + uint32_t dataLen, + CADataType_t dataType) { - OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN"); + OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "IN %s", __func__); //Input validation VERIFY_NON_NULL_RET(data, CALEADAPTER_TAG, "Data is null", -1); @@ -1544,15 +3036,23 @@ int32_t CASendLEMulticastData(const CAEndpoint_t *endpoint, const void *data, ui CAResult_t result = CA_STATUS_FAILED; - ca_mutex_lock(g_bleIsServerMutex); - if (true == g_isServer) + OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "g_adapterType: %d", g_adapterType); + if (ADAPTER_EMPTY == g_adapterType) + { + OIC_LOG(ERROR, CALEADAPTER_TAG, "g_adapterType is Empty"); + } + + oc_mutex_lock(g_bleIsServerMutex); + if (ADAPTER_SERVER == g_adapterType || + (ADAPTER_BOTH_CLIENT_SERVER == g_adapterType && CA_RESPONSE_DATA == dataType)) { result = CALEAdapterServerSendData(NULL, data, dataLen); if (CA_STATUS_OK != result) { - OIC_LOG(ERROR, CALEADAPTER_TAG, "Send multicast data failed" ); + oc_mutex_unlock(g_bleIsServerMutex); + + OIC_LOG(ERROR, CALEADAPTER_TAG, "Send multicast data for server failed" ); - ca_mutex_unlock(g_bleIsServerMutex); if (g_errorHandler) { g_errorHandler(endpoint, data, dataLen, result); @@ -1560,29 +3060,34 @@ int32_t CASendLEMulticastData(const CAEndpoint_t *endpoint, const void *data, ui return -1; } } - else + + if (ADAPTER_CLIENT == g_adapterType || + (ADAPTER_BOTH_CLIENT_SERVER == g_adapterType && CA_REQUEST_DATA == dataType) || + (ADAPTER_BOTH_CLIENT_SERVER == g_adapterType && CA_RESPONSE_FOR_RES == dataType)) { result = CALEAdapterClientSendData(NULL, data, dataLen); if (CA_STATUS_OK != result) { - OIC_LOG(ERROR, CALEADAPTER_TAG, "Send Multicast data failed" ); + oc_mutex_unlock(g_bleIsServerMutex); + + OIC_LOG(ERROR, CALEADAPTER_TAG, "Send Multicast data for client failed" ); + if (g_errorHandler) { g_errorHandler(endpoint, data, dataLen, result); } - ca_mutex_unlock(g_bleIsServerMutex); return -1; } } - ca_mutex_unlock(g_bleIsServerMutex); + oc_mutex_unlock(g_bleIsServerMutex); - OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT"); + OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "OUT %s", __func__); return dataLen; } -CAResult_t CAGetLEInterfaceInformation(CAEndpoint_t **info, uint32_t *size) +static CAResult_t CAGetLEInterfaceInformation(CAEndpoint_t **info, uint32_t *size) { - OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN"); + OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "IN %s", __func__); VERIFY_NON_NULL(info, CALEADAPTER_TAG, "CALocalConnectivity info is null"); @@ -1622,25 +3127,27 @@ CAResult_t CAGetLEInterfaceInformation(CAEndpoint_t **info, uint32_t *size) } OICStrcpy((*info)->addr, sizeof((*info)->addr), local_address); - ca_mutex_lock(g_bleLocalAddressMutex); + oc_mutex_lock(g_bleLocalAddressMutex); OICStrcpy(g_localBLEAddress, sizeof(g_localBLEAddress), local_address); - ca_mutex_unlock(g_bleLocalAddressMutex); + oc_mutex_unlock(g_bleLocalAddressMutex); (*info)->adapter = CA_ADAPTER_GATT_BTLE; *size = 1; OICFree(local_address); - OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT"); + OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "OUT %s", __func__); return CA_STATUS_OK; } -CAResult_t CALERegisterNetworkNotifications(CANetworkChangeCallback netCallback) +static CAResult_t CALERegisterNetworkNotifications(CAAdapterChangeCallback netCallback, + CAConnectionChangeCallback connCallback) { - OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN"); + OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "IN %s", __func__); - ca_mutex_lock(g_bleNetworkCbMutex); + oc_mutex_lock(g_bleNetworkCbMutex); g_networkCallback = netCallback; - ca_mutex_unlock(g_bleNetworkCbMutex); + g_connectionCallback = connCallback; + oc_mutex_unlock(g_bleNetworkCbMutex); CAResult_t res = CA_STATUS_OK; if (netCallback) { @@ -1659,55 +3166,161 @@ CAResult_t CALERegisterNetworkNotifications(CANetworkChangeCallback netCallback) } } - OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT"); + if (g_connectionCallback) + { + res = CASetLENWConnectionStateChangedCb(CALEConnectionStateChangedCb); + if (CA_STATUS_OK != res) + { + OIC_LOG(ERROR, CALEADAPTER_TAG, "CASetLENWConnectionStateChangedCb failed!"); + } + } + else + { + res = CAUnSetLENWConnectionStateChangedCb(); + if (CA_STATUS_OK != res) + { + OIC_LOG(ERROR, CALEADAPTER_TAG, "CAUnSetLENWConnectionStateChangedCb failed!"); + } + } + + OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "OUT %s", __func__); return res; } -void CALEDeviceStateChangedCb( CAAdapterState_t adapter_state) +static void CALEConnectionStateChangedCb(CATransportAdapter_t adapter, const char* address, + bool isConnected) { - OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN"); + OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "IN %s", __func__); + + VERIFY_NON_NULL_VOID(address, CALEADAPTER_TAG, "address"); + (void)adapter; + + CAEndpoint_t localEndpoint = { .adapter = CA_ADAPTER_GATT_BTLE }; + OICStrcpy(localEndpoint.addr, sizeof(localEndpoint.addr), address); + +#ifdef __TIZEN__ + oc_mutex_lock(g_bleIsServerMutex); + switch (g_adapterType) + { + case ADAPTER_SERVER: + CALEGattServerConnectionStateChanged(isConnected, address); + break; + case ADAPTER_CLIENT: + CALEGattConnectionStateChanged(isConnected, address); + break; + case ADAPTER_BOTH_CLIENT_SERVER: + CALEGattConnectionStateChanged(isConnected, address); + CALEGattServerConnectionStateChanged(isConnected, address); + break; + default: + break; + } + oc_mutex_unlock(g_bleIsServerMutex); +#endif + + if(!isConnected) + { +#ifndef SINGLE_THREAD + if(g_bleClientSenderInfo) + { + CALERemoveReceiveQueueData(g_bleClientSenderInfo, address); + } + + if(g_bleServerSenderInfo) + { + CALERemoveReceiveQueueData(g_bleServerSenderInfo, address); + } + + // remove data of send queue. + if (g_bleClientSendQueueHandle) + { + CALERemoveSendQueueData(g_bleClientSendQueueHandle, + g_bleClientSendDataMutex, + address); + } + + if (g_bleServerSendQueueHandle) + { + CALERemoveSendQueueData(g_bleServerSendQueueHandle, + g_bleServerSendDataMutex, + address); + } +#endif + +#ifdef __WITH_DTLS__ + CAcloseSslConnection(&localEndpoint); +#endif + } + + if (g_connectionCallback) + { + g_connectionCallback(&localEndpoint, isConnected); + } - VERIFY_NON_NULL_VOID(g_localBLEAddress, CALEADAPTER_TAG, "g_localBLEAddress is null"); - CAEndpoint_t localEndpoint = {}; + OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "OUT %s", __func__); +} - ca_mutex_lock(g_bleLocalAddressMutex); - OICStrcpy(localEndpoint.addr, sizeof(localEndpoint.addr), g_localBLEAddress); - ca_mutex_unlock(g_bleLocalAddressMutex); +static void CALEDeviceStateChangedCb(CAAdapterState_t adapter_state) +{ + OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "IN %s", __func__); - g_bleAdapterState = adapter_state; - // Start a GattServer/Client if gLeServerStatus is SET - if (CA_LISTENING_SERVER == gLeServerStatus) + if (CA_ADAPTER_ENABLED == adapter_state) { - OIC_LOG(DEBUG, CALEADAPTER_TAG, "Before CAStartLEGattServer"); - CAStartLEGattServer(); + oc_mutex_lock(g_bleIsServerMutex); + switch (g_adapterType) + { + case ADAPTER_SERVER: + CALEAdapterGattServerStart(); + break; + case ADAPTER_CLIENT: + CALEAdapterGattClientStart(); + break; + case ADAPTER_BOTH_CLIENT_SERVER: + CALEAdapterGattServerStart(); + CALEAdapterGattClientStart(); + break; + default: + break; + } + oc_mutex_unlock(g_bleIsServerMutex); } - else if (CA_DISCOVERY_SERVER == gLeServerStatus) + else { - OIC_LOG(DEBUG, CALEADAPTER_TAG, "Before CAStartBleGattClient"); - CAStartLEGattClient(); + oc_mutex_lock(g_bleIsServerMutex); + switch (g_adapterType) + { + case ADAPTER_SERVER: + CALEAdapterGattServerStop(); + break; + case ADAPTER_CLIENT: + CALEAdapterGattClientStop(); + break; + case ADAPTER_BOTH_CLIENT_SERVER: + CALEAdapterGattServerStop(); + CALEAdapterGattClientStop(); + break; + default: + break; + } + oc_mutex_unlock(g_bleIsServerMutex); } - gLeServerStatus = CA_SERVER_NOTSTARTED; - ca_mutex_lock(g_bleNetworkCbMutex); if (NULL != g_networkCallback) { - g_networkCallback(&localEndpoint, adapter_state); + g_networkCallback(CA_ADAPTER_GATT_BTLE, adapter_state); } else { OIC_LOG(ERROR, CALEADAPTER_TAG, "g_networkCallback is NULL"); } - ca_mutex_unlock(g_bleNetworkCbMutex); - OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT"); + OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "OUT %s", __func__); } -CAResult_t CALEAdapterClientSendData(const CAEndpoint_t *remoteEndpoint, - const void *data, - uint32_t dataLen) +static CAResult_t CALEAdapterClientSendData(const CAEndpoint_t *remoteEndpoint, + const uint8_t *data, + uint32_t dataLen) { - OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN"); - VERIFY_NON_NULL(data, CALEADAPTER_TAG, "Param data is NULL"); #ifndef SINGLE_THREAD VERIFY_NON_NULL_RET(g_bleClientSendQueueHandle, CALEADAPTER_TAG, @@ -1717,85 +3330,42 @@ CAResult_t CALEAdapterClientSendData(const CAEndpoint_t *remoteEndpoint, "g_bleClientSendDataMutex is NULL", CA_STATUS_FAILED); - VERIFY_NON_NULL_RET(g_bleClientSendQueueHandle, CALEADAPTER_TAG, "g_bleClientSendQueueHandle", - CA_STATUS_FAILED); - - OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "Data Sending to LE layer [%d]", dataLen); + OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "Data Sending to LE layer [%u]", dataLen); - CALEData_t *bleData = CACreateLEData(remoteEndpoint, data, dataLen); + CALEData_t *bleData = CACreateLEData(remoteEndpoint, data, dataLen, NULL); if (!bleData) { OIC_LOG(ERROR, CALEADAPTER_TAG, "Failed to create bledata!"); return CA_MEMORY_ALLOC_FAILED; } // Add message to send queue - ca_mutex_lock(g_bleClientSendDataMutex); + oc_mutex_lock(g_bleClientSendDataMutex); CAQueueingThreadAddData(g_bleClientSendQueueHandle, bleData, sizeof(CALEData_t)); - ca_mutex_unlock(g_bleClientSendDataMutex); + oc_mutex_unlock(g_bleClientSendDataMutex); #endif - OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT"); return CA_STATUS_OK; } - -CAResult_t CALEAdapterServerSendData(const CAEndpoint_t *remoteEndpoint, - const void *data, - uint32_t dataLen) +static CAResult_t CALEAdapterServerSendData(const CAEndpoint_t *remoteEndpoint, + const uint8_t *data, + uint32_t dataLen) { - OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN"); + OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "IN %s", __func__); VERIFY_NON_NULL(data, CALEADAPTER_TAG, "Param data is NULL"); #ifdef SINGLE_THREAD - char header[CA_HEADER_LENGTH] = {0}; - - CAResult_t result = CAGenerateHeader(header, dataLen); - - if (CA_STATUS_OK != result) - { - OIC_LOG(ERROR, CALEADAPTER_TAG, "Generate header failed"); - return -1; - } - if (!CAIsLEConnected()) { OIC_LOG(ERROR, CALEADAPTER_TAG, "le not conn"); - return -1; + return CA_STATUS_FAILED; } - result = CAUpdateCharacteristicsToAllGattClients(header, CA_HEADER_LENGTH); + CAResult_t result = CALEServerSendDataSingleThread(data, dataLen); if (CA_STATUS_OK != result) { - OIC_LOG(ERROR, CALEADAPTER_TAG, "Update characteristics failed"); - return -1; - } - - int32_t dataLimit = dataLen / CA_SUPPORTED_BLE_MTU_SIZE; - for (int32_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 -1; - } - CALEDoEvents(); - } - - uint8_t remainingLen = dataLen % CA_SUPPORTED_BLE_MTU_SIZE; - if(remainingLen) - { - result = CAUpdateCharacteristicsToAllGattClients((data + - (dataLimit * CA_SUPPORTED_BLE_MTU_SIZE)), - remainingLen); - if (CA_STATUS_OK != result) - { - OIC_LOG(ERROR, CALEADAPTER_TAG, "Update characteristics failed"); - return -1; - } - CALEDoEvents(); + OIC_LOG(ERROR, CALEADAPTER_TAG, "CALEServerSendDataSingleThread failed"); + return CA_STATUS_FAILED; } #else VERIFY_NON_NULL_RET(g_bleServerSendQueueHandle, CALEADAPTER_TAG, @@ -1810,47 +3380,71 @@ CAResult_t CALEAdapterServerSendData(const CAEndpoint_t *remoteEndpoint, OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "Data Sending to LE layer [%d]", dataLen); - CALEData_t *bleData = CACreateLEData(remoteEndpoint, data, dataLen); + CALEData_t * const bleData = + CACreateLEData(remoteEndpoint, data, dataLen, NULL); + if (!bleData) { OIC_LOG(ERROR, CALEADAPTER_TAG, "Failed to create bledata!"); return CA_MEMORY_ALLOC_FAILED; } + // Add message to send queue - ca_mutex_lock(g_bleServerSendDataMutex); - CAQueueingThreadAddData(g_bleServerSendQueueHandle, bleData, sizeof(CALEData_t)); - ca_mutex_unlock(g_bleServerSendDataMutex); + oc_mutex_lock(g_bleServerSendDataMutex); + CAQueueingThreadAddData(g_bleServerSendQueueHandle, + bleData, + sizeof(CALEData_t)); + oc_mutex_unlock(g_bleServerSendDataMutex); #endif - OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT"); + OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "OUT %s", __func__); return CA_STATUS_OK; } -CAResult_t CALEAdapterServerReceivedData(const char *remoteAddress, const char *serviceUUID, - const void *data, uint32_t dataLength, - uint32_t *sentLength) +static CAResult_t CALEAdapterServerReceivedData(const char *remoteAddress, + const uint8_t *data, + uint32_t dataLength, + uint32_t *sentLength) { - OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN"); + OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "IN %s", __func__); //Input validation - VERIFY_NON_NULL(serviceUUID, CALEADAPTER_TAG, "service UUID is null"); VERIFY_NON_NULL(data, CALEADAPTER_TAG, "Data is null"); VERIFY_NON_NULL(sentLength, CALEADAPTER_TAG, "Sent data length holder is null"); #ifdef SINGLE_THREAD - if(g_networkPacketReceivedCallback) + CALEDataReceiverHandlerSingleThread(data, dataLength); + + if (g_singleThreadReceiveData->totalDataLen == g_singleThreadReceiveData->recvDataLen) { - CAEndpoint_t endPoint = { 0 }; // will be filled by upper layer - endPoint.adapter = CA_ADAPTER_GATT_BTLE; - g_networkPacketReceivedCallback(&endPoint, data, dataLength); + if(g_networkPacketReceivedCallback) + { + // will be filled by upper layer + const CASecureEndpoint_t endpoint = + { .endpoint = { .adapter = CA_ADAPTER_GATT_BTLE } }; + + g_networkPacketReceivedCallback(&endpoint, + g_singleThreadReceiveData->defragData, + g_singleThreadReceiveData->recvDataLen); + } + g_singleThreadReceiveData->remoteEndpoint = NULL; + OICFree(g_singleThreadReceiveData->defragData); + g_singleThreadReceiveData->defragData = NULL; + OICFree(g_singleThreadReceiveData); + g_singleThreadReceiveData = NULL; } #else - VERIFY_NON_NULL_RET(g_bleServerReceiverQueue, CALEADAPTER_TAG, "g_bleServerReceiverQueue", + VERIFY_NON_NULL_RET(g_bleServerReceiverQueue, + CALEADAPTER_TAG, + "g_bleServerReceiverQueue", CA_STATUS_FAILED); //Add message to data queue - CAEndpoint_t *remoteEndpoint = CACreateEndpointObject(CA_DEFAULT_FLAGS, - CA_ADAPTER_GATT_BTLE, - remoteAddress, 0); + CAEndpoint_t * const remoteEndpoint = + CACreateEndpointObject(CA_DEFAULT_FLAGS, + CA_ADAPTER_GATT_BTLE, + remoteAddress, + 0); + if (NULL == remoteEndpoint) { OIC_LOG(ERROR, CALEADAPTER_TAG, "Failed to create remote endpoint !"); @@ -1858,9 +3452,14 @@ CAResult_t CALEAdapterServerReceivedData(const char *remoteAddress, const char * } // Create bleData to add to queue - OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "Data received from LE layer [%d]", dataLength); + OIC_LOG_V(DEBUG, + CALEADAPTER_TAG, + "Data received from LE Server layer [%d]", + dataLength); + + CALEData_t * const bleData = + CACreateLEData(remoteEndpoint, data, dataLength, g_bleServerSenderInfo); - CALEData_t *bleData = CACreateLEData(remoteEndpoint, data, dataLength); if (!bleData) { OIC_LOG(ERROR, CALEADAPTER_TAG, "Failed to create bledata!"); @@ -1869,27 +3468,26 @@ CAResult_t CALEAdapterServerReceivedData(const char *remoteAddress, const char * } CAFreeEndpoint(remoteEndpoint); - // Add message to send queue + // Add message to receiver queue CAQueueingThreadAddData(g_bleServerReceiverQueue, bleData, sizeof(CALEData_t)); *sentLength = dataLength; #endif - OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT"); + OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "OUT %s", __func__); return CA_STATUS_OK; } -CAResult_t CALEAdapterClientReceivedData(const char *remoteAddress, const char *serviceUUID, - const void *data, uint32_t dataLength, - uint32_t *sentLength) +static CAResult_t CALEAdapterClientReceivedData(const char *remoteAddress, + const uint8_t *data, + uint32_t dataLength, + uint32_t *sentLength) { - OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN"); - //Input validation - VERIFY_NON_NULL(serviceUUID, CALEADAPTER_TAG, "service UUID is null"); VERIFY_NON_NULL(data, CALEADAPTER_TAG, "Data is null"); VERIFY_NON_NULL(sentLength, CALEADAPTER_TAG, "Sent data length holder is null"); #ifndef SINGLE_THREAD - VERIFY_NON_NULL_RET(g_bleClientReceiverQueue, CALEADAPTER_TAG, "g_bleClientReceiverQueue", + VERIFY_NON_NULL_RET(g_bleClientReceiverQueue, CALEADAPTER_TAG, + "g_bleClientReceiverQueue", CA_STATUS_FAILED); //Add message to data queue @@ -1902,10 +3500,15 @@ CAResult_t CALEAdapterClientReceivedData(const char *remoteAddress, const char * return CA_STATUS_FAILED; } - OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "Data received from LE layer [%d]", dataLength); - // Create bleData to add to queue - CALEData_t *bleData = CACreateLEData(remoteEndpoint, data, dataLength); + OIC_LOG_V(DEBUG, + CALEADAPTER_TAG, + "Data received from LE Client layer [%zu]", + dataLength); + + CALEData_t * const bleData = + CACreateLEData(remoteEndpoint, data, dataLength, g_bleClientSenderInfo); + if (!bleData) { OIC_LOG(ERROR, CALEADAPTER_TAG, "Failed to create bledata!"); @@ -1914,50 +3517,225 @@ CAResult_t CALEAdapterClientReceivedData(const char *remoteAddress, const char * } CAFreeEndpoint(remoteEndpoint); - // Add message to send queue + // Add message to receiver queue CAQueueingThreadAddData(g_bleClientReceiverQueue, bleData, sizeof(CALEData_t)); *sentLength = dataLength; #endif - OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT"); return CA_STATUS_OK; } -void CASetLEAdapterThreadPoolHandle(ca_thread_pool_t handle) +static void CASetLEAdapterThreadPoolHandle(ca_thread_pool_t handle) { - OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN"); - - ca_mutex_unlock(g_bleAdapterThreadPoolMutex); + oc_mutex_lock(g_bleAdapterThreadPoolMutex); g_bleAdapterThreadPool = handle; - ca_mutex_unlock(g_bleAdapterThreadPoolMutex); - - OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT"); + oc_mutex_unlock(g_bleAdapterThreadPoolMutex); } -void CASetLEReqRespAdapterCallback(CANetworkPacketReceivedCallback callback) +static void CASetLEReqRespAdapterCallback(CANetworkPacketReceivedCallback callback) { - OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN"); - - ca_mutex_lock(g_bleAdapterReqRespCbMutex); + oc_mutex_lock(g_bleAdapterReqRespCbMutex); g_networkPacketReceivedCallback = callback; - ca_mutex_unlock(g_bleAdapterReqRespCbMutex); - - OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT"); + oc_mutex_unlock(g_bleAdapterReqRespCbMutex); } -void CALEErrorHandler(const char *remoteAddress, const void *data, uint32_t dataLen, - CAResult_t result) +static void CALEErrorHandler(const char *remoteAddress, + const uint8_t *data, + uint32_t dataLen, + CAResult_t result) { - OIC_LOG(DEBUG, CALEADAPTER_TAG, "CALEErrorHandler IN"); + OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "IN %s", __func__); VERIFY_NON_NULL_VOID(data, CALEADAPTER_TAG, "Data is null"); - CAEndpoint_t *rep = CACreateEndpointObject(CA_DEFAULT_FLAGS, CA_ADAPTER_GATT_BTLE, - remoteAddress, 0); - //if required, will be used to build remote end point + + CAEndpoint_t *rep = CACreateEndpointObject(CA_DEFAULT_FLAGS, + CA_ADAPTER_GATT_BTLE, + remoteAddress, + 0); + + // if required, will be used to build remote endpoint g_errorHandler(rep, data, dataLen, result); CAFreeEndpoint(rep); - OIC_LOG(DEBUG, CALEADAPTER_TAG, "CALEErrorHandler OUT"); + + OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "OUT %s", __func__); +} + +#ifndef SINGLE_THREAD +static void CALERemoveSendQueueData(CAQueueingThread_t *queueHandle, oc_mutex mutex, + const char* address) +{ + OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "%s", __func__); + + VERIFY_NON_NULL_VOID(queueHandle, CALEADAPTER_TAG, "queueHandle"); + VERIFY_NON_NULL_VOID(address, CALEADAPTER_TAG, "address"); + + oc_mutex_lock(mutex); + while (u_queue_get_size(queueHandle->dataQueue) > 0) + { + OIC_LOG(DEBUG, CALEADAPTER_TAG, "get data from queue"); + u_queue_message_t *message = u_queue_get_element(queueHandle->dataQueue); + if (NULL != message) + { + CALEData_t *bleData = (CALEData_t *) message->msg; + if (bleData && bleData->remoteEndpoint) + { + if (!strcasecmp(bleData->remoteEndpoint->addr, address)) + { + OIC_LOG(DEBUG, CALEADAPTER_TAG, "found the message of disconnected device"); + if (NULL != queueHandle->destroy) + { + queueHandle->destroy(message->msg, message->size); + } + else + { + OICFree(message->msg); + } + + OICFree(message); + } + } + } + } + oc_mutex_unlock(mutex); +} + +static void CALERemoveReceiveQueueData(u_arraylist_t *dataInfoList, const char* address) +{ + OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "%s", __func__); + + VERIFY_NON_NULL_VOID(dataInfoList, CALEADAPTER_TAG, "dataInfoList"); + VERIFY_NON_NULL_VOID(address, CALEADAPTER_TAG, "address"); + + CABLESenderInfo_t *senderInfo = NULL; + uint32_t senderIndex = 0; + + u_arraylist_t *portList = u_arraylist_create(); + if (CA_STATUS_OK == CALEGetPortsFromSenderInfo(address, dataInfoList, portList)) + { + uint32_t arrayLength = u_arraylist_length(portList); + for (uint32_t i = 0; i < arrayLength; i++) + { + uint16_t *port = (uint16_t *)u_arraylist_get(portList, i); + if (!port) + { + OIC_LOG(ERROR, CALEADAPTER_TAG, "Failed to get port from sender info !"); + u_arraylist_destroy(portList); + return; + } + + 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++) + { + CABLESenderInfo_t *info = (CABLESenderInfo_t *) u_arraylist_get(senderInfoList, index); + if (!info || !(info->remoteEndpoint)) + { + continue; + } + + if (!strncmp(info->remoteEndpoint->addr, leAddress, addrLength)) + { + uint16_t *port = (uint16_t *)OICMalloc(sizeof(uint16_t)); + if (!port) + { + OIC_LOG(ERROR, CALEADAPTER_TAG, "memory allocation failed!"); + return CA_MEMORY_ALLOC_FAILED; + } + *port = info->remoteEndpoint->port; + u_arraylist_add(portList, (void *)port); + } + } + + if (u_arraylist_length(portList) != 0) + { + return CA_STATUS_OK; + } + else + { + return CA_STATUS_FAILED; + } +} +#endif + +void CALEStartGattServer() +{ + OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "IN %s", __func__); + + oc_mutex_lock(g_bleIsServerMutex); + switch (g_adapterType) + { + case ADAPTER_SERVER: + CALEAdapterGattServerStart(); + break; + case ADAPTER_CLIENT: + CALEAdapterGattClientStart(); + break; + case ADAPTER_BOTH_CLIENT_SERVER: + CALEAdapterGattServerStart(); + CALEAdapterGattClientStart(); + break; + default: + break; + } + oc_mutex_unlock(g_bleIsServerMutex); + OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "OUT %s", __func__); +} + +void CALEStopGattServer() +{ + OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "IN %s", __func__); + + oc_mutex_lock(g_bleIsServerMutex); + switch (g_adapterType) + { + case ADAPTER_SERVER: + CALEAdapterGattServerStop(); + break; + case ADAPTER_CLIENT: + CALEAdapterGattClientStop(); + break; + case ADAPTER_BOTH_CLIENT_SERVER: + CALEAdapterGattServerStop(); + CALEAdapterGattClientStop(); + break; + default: + break; + } + oc_mutex_unlock(g_bleIsServerMutex); + OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "OUT %s", __func__); }