CoAP over TCP transmission over BT support for Tizen 39/4739/10
authorkoushik.girijala <g.koushik@samsung.com>
Wed, 30 Dec 2015 05:37:57 +0000 (11:07 +0530)
committerJon A. Cruz <jonc@osg.samsung.com>
Tue, 23 Feb 2016 18:53:08 +0000 (18:53 +0000)
currently, CoAP/UDP message format is used over BT-RFCOMM.
but BT-RFCOMM data transmission requires dedicated session
between devices and guarantees reliable data transmission
by its MAC & PHY layer. So, CoAP/TCP message format might
be more efficient for Bluetooth

Change-Id: Ifd4e47174734cf21de7245d3e6a055f8952ce730
Signed-off-by: koushik.girijala <g.koushik@samsung.com>
Reviewed-on: https://gerrit.iotivity.org/gerrit/4739
Tested-by: jenkins-iotivity <jenkins-iotivity@opendaylight.org>
Reviewed-by: Jon A. Cruz <jonc@osg.samsung.com>
resource/csdk/connectivity/src/SConscript [changed mode: 0755->0644]
resource/csdk/connectivity/src/bt_edr_adapter/android/caedrutils.h
resource/csdk/connectivity/src/bt_edr_adapter/tizen/caedrclient.c
resource/csdk/connectivity/src/bt_edr_adapter/tizen/caedrutils.c
resource/csdk/connectivity/src/bt_edr_adapter/tizen/caedrutils.h

old mode 100755 (executable)
new mode 100644 (file)
index 85b4a52..7d1601e 100644 (file)
@@ -27,7 +27,6 @@
 
 #include "cacommon.h"
 #include "cathreadpool.h"
-#include "uarraylist.h"
 #include "caedrinterface.h"
 #include "jni.h"
 
index fcd1db9..38f5945 100644 (file)
 
 #define MICROSECS_PER_SEC 1000000
 
+/**
+ * Maximum CoAP over TCP header length
+ * to know the total data length.
+ */
+#define EDR_MAX_HEADER_LEN  6
+
 /**
  * Mutex to synchronize the access to Bluetooth device information list.
  */
@@ -947,18 +953,95 @@ void CAEDRDataRecvCallback(bt_socket_received_data_s *data, void *userData)
     }
     ca_mutex_unlock(g_edrDeviceListMutex);
 
+    //: TODO Need to check if 'check required for socket still connected or not'
     if (!device)
     {
         OIC_LOG(ERROR, EDR_ADAPTER_TAG, "There is no device!");
         return;
     }
 
-    uint32_t sentLength = 0;
+    CAConnectedDeviceInfo_t *deviceInfo =
+        (CAConnectedDeviceInfo_t *) CAEDRGetDeviceInfoFromAddress(device->remoteAddress);
+
+    if (!deviceInfo)
+    {
+        OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "Received Data from new device");
+        deviceInfo = (CAConnectedDeviceInfo_t *) OICCalloc(1, sizeof(*deviceInfo));
+        if (!deviceInfo)
+        {
+            OIC_LOG(ERROR, EDR_ADAPTER_TAG, "Out of memory");
+            return;
+        }
+
+        deviceInfo->state = STATE_CONNECTED;
+        deviceInfo->recvData = NULL;
+        deviceInfo->recvDataLen = 0;
+        deviceInfo->totalDataLen = 0;
+        result = CAEDRAddDeviceInfoToList(device->remoteAddress, deviceInfo);
+        if (CA_STATUS_OK != result)
+        {
+            OIC_LOG(ERROR, EDR_ADAPTER_TAG, "Could not add device info to list!");
+            OICFree(deviceInfo);
+            return;
+        }
+    }
+
+    if (!deviceInfo->recvData)
+    {
+        OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "Callocing deviceInfo->recvData");
+        deviceInfo->recvData = OICCalloc(data->data_size, sizeof(uint8_t));
+        if (!deviceInfo->recvData)
+        {
+            OIC_LOG(ERROR, EDR_ADAPTER_TAG, "out of memory");
+            return;
+        }
+    }
+
+    memcpy(deviceInfo->recvData + deviceInfo->recvDataLen, (const char*)data->data,
+           data->data_size);
+    deviceInfo->recvDataLen += data->data_size;
+
+    if (!deviceInfo->totalDataLen)
+    {
+        coap_transport_type transport = coap_get_tcp_header_type_from_initbyte(
+                ((unsigned char *)deviceInfo->recvData)[0] >> 4);
+        size_t headerLen = coap_get_tcp_header_length_for_transport(transport);
+
+        if (deviceInfo->recvDataLen >= headerLen)
+        {
+            // get actual data length from coap over tcp header
+            deviceInfo->totalDataLen = coap_get_total_message_length(deviceInfo->recvData,
+                                                                     deviceInfo->recvDataLen);
+            OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG, "total data length [%d] bytes", deviceInfo->totalDataLen);
+
+            uint8_t *newBuf = OICRealloc(deviceInfo->recvData, deviceInfo->totalDataLen);
+            if (!newBuf)
+            {
+                OIC_LOG(ERROR, EDR_ADAPTER_TAG, "out of memory");
+                //Memory free
+                return;
+            }
+            deviceInfo->recvData = newBuf;
+        }
+    }
+
+    if (deviceInfo->totalDataLen == deviceInfo->recvDataLen)
+    {
+        if (g_edrPacketReceivedCallback)
+        {
+            OIC_LOG_V(DEBUG, EDR_ADAPTER_TAG,"data will be sent to callback routine: %s, %d",
+                      deviceInfo->recvData, deviceInfo->recvDataLen);
+
+            uint32_t sentLength = 0;
+            g_edrPacketReceivedCallback(device->remoteAddress, (void*) deviceInfo->recvData,
+                                        deviceInfo->recvDataLen, &sentLength);
 
-    g_edrPacketReceivedCallback(device->remoteAddress,
-                                (uint8_t *) data->data,
-                                (uint32_t) data->data_size,
-                                &sentLength);
+            OICFree(deviceInfo->recvData);
+            deviceInfo->recvData = NULL;
+            deviceInfo->recvDataLen = 0;
+            deviceInfo->totalDataLen = 0;
+        }
+    }
 
     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "OUT");
 }
index 70073ae..72df325 100644 (file)
 #include <bluetooth.h>
 
 #include "logger.h"
+#include "uarraylist.h"
+
+/**
+ * Pending devices list for data transfer.
+ */
+static u_arraylist_t *g_deviceStateList = NULL;
 
 bool CAEDRIsServiceSupported(const char **serviceUUID, int32_t serviceCount,
                                  const char *matchService)
@@ -54,5 +60,69 @@ bool CAEDRIsServiceSupported(const char **serviceUUID, int32_t serviceCount,
     return false;
 }
 
+CAConnectedDeviceInfo_t *CAEDRGetDeviceInfoFromAddress(const char *remoteAddress)
+{
+    OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "CAEDRGetDeviceInfoFromAddress");
 
+    if (!remoteAddress)
+    {
+        OIC_LOG(ERROR, EDR_ADAPTER_TAG, "remoteAddress is null");
+        return NULL;
+    }
+
+    uint32_t length = u_arraylist_length(g_deviceStateList);
+    for (uint32_t index = 0; index < length; index++)
+    {
+        CAConnectedDeviceInfo_t* deviceInfo =
+                (CAConnectedDeviceInfo_t*) u_arraylist_get(g_deviceStateList, index);
+        if (!deviceInfo)
+        {
+            OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "deviceInfo object is null");
+            continue;
+        }
+
+        if (!strcmp((const char*) deviceInfo->address, remoteAddress))
+        {
+            return deviceInfo;
+        }
+    }
+    return NULL;
+}
+
+CAResult_t CAEDRAddDeviceInfoToList(const char *remoteAddress, CAConnectedDeviceInfo_t *deviceInfo)
+{
+    if (!remoteAddress)
+    {
+        OIC_LOG(ERROR, EDR_ADAPTER_TAG, "remoteAddress is null");
+        return CA_STATUS_INVALID_PARAM;
+    }
+
+    if (!deviceInfo)
+    {
+        OIC_LOG(ERROR, EDR_ADAPTER_TAG, "deviceInfo is null");
+        return CA_STATUS_INVALID_PARAM;
+    }
+
+    for (int i = 0; i < CA_MACADDR_SIZE; i++)
+    {
+        deviceInfo->address[i] = (uint8_t) remoteAddress[i];
+    }
+
+    if (!g_deviceStateList)
+    {
+        g_deviceStateList = u_arraylist_create();
+        if (!g_deviceStateList)
+        {
+            OIC_LOG(ERROR, EDR_ADAPTER_TAG, "Failed to create Device list");
+            return CA_STATUS_FAILED;
+        }
+    }
+
+    if (!u_arraylist_add(g_deviceStateList, (void *) deviceInfo))
+    {
+        OIC_LOG(ERROR, EDR_ADAPTER_TAG, "Failed to Add Device to list");
+        return CA_STATUS_FAILED;
+    }
 
+    return CA_STATUS_OK;
+}
\ No newline at end of file
index 6a7d706..c3afe31 100644 (file)
@@ -32,6 +32,7 @@
 
 #include "cacommon.h"
 #include "oic_malloc.h"
+#include "caedrinterface.h"
 
 /**
  * Logging tag for module name.
@@ -58,6 +59,21 @@ extern "C"
 bool CAEDRIsServiceSupported(const char **serviceUUID, int32_t serviceCount,
                             const char *matchService);
 
+/**
+ * Get device information from list.
+ * @param[in]   remoteAddress   remote address.
+ * @return  Device information object or NULL.
+ */
+CAConnectedDeviceInfo_t *CAEDRGetDeviceInfoFromAddress(const char *remoteAddress);
+
+/**
+ * Add device information to list.
+ * @param[in]   remoteAddress   remote address.
+ * @param[in]   deviceInfo      device information.
+ * @return ::CA_STATUS_OK or Appropriate error code.
+ */
+CAResult_t CAEDRAddDeviceInfoToList(const char *remoteAddress, CAConnectedDeviceInfo_t *deviceInfo);
+
 #ifdef __cplusplus
 } /* extern "C" */
 #endif