[ARDUINO] Fixed heap corruption and build issues
[platform/upstream/iotivity.git] / resource / csdk / connectivity / src / bt_le_adapter / arduino / cableserver.cpp
index 1720fe1..74f9b14 100644 (file)
 *
 ******************************************************************/
 
+
+//logger.h included first to avoid conflict with RBL library PROGMEM attribute
+#include "logger.h"
+
 #include "cableserver.h"
 
 #include <Arduino.h>
 #include <SPI.h>
 #include <boards.h>
 #include <RBL_nRF8001.h>
-#include <services.h>
 
-#include <logger.h>
+#include "caleinterface.h"
 #include "oic_malloc.h"
 #include "caadapterutils.h"
+#include "cafragmentation.h"
 
 #define TAG "LES"
 
-CAResult_t CAInitializeBle()
+/**
+ * @var    g_bleServerDataReceivedCallback
+ * @brief  Maintains the callback to be notified on receival of network packets from other
+ *           BLE devices
+ */
+static CABLEServerDataReceivedCallback g_bleServerDataReceivedCallback = NULL;
+
+/**
+ * @def MAX_EVENT_COUNT
+ * @brief Maximum number of tries to get the event on BLE Shield address.
+ */
+#define MAX_EVENT_COUNT 20
+
+static bool g_serverRunning = false;
+static char *g_coapBuffer = NULL;
+
+/**
+ * @var g_receivedDataLen
+ * @brief Actual length of data received.
+ */
+static uint32_t g_receivedDataLen = 0;
+
+/**
+ * @var g_packetDataLen
+ * @brief Total Length of data that is being fragmented.
+ */
+static uint32_t g_packetDataLen = 0;
+
+void CACheckLEDataInternal()
+{
+    CALEDoEvents();
+
+    if (CAIsLEDataAvailable())
+    {
+        // Allocate Memory for COAP Buffer and do ParseHeader
+        if (NULL == g_coapBuffer)
+        {
+            OIC_LOG(DEBUG, TAG, "IN");
+            char headerArray[CA_HEADER_LENGTH] = "";
+            while (CAIsLEDataAvailable() && g_receivedDataLen < CA_HEADER_LENGTH)
+            {
+                headerArray[g_receivedDataLen++] = CALEReadData();
+            }
+
+            g_packetDataLen = CAParseHeader(headerArray);
+
+            if (g_packetDataLen > COAP_MAX_PDU_SIZE)
+            {
+                OIC_LOG(ERROR, TAG, "len > pdu_size");
+                return;
+            }
+
+            g_coapBuffer = (char *)OICCalloc((size_t)g_packetDataLen, sizeof(char));
+            if (NULL == g_coapBuffer)
+            {
+                OIC_LOG(ERROR, TAG, "malloc");
+                return;
+            }
+
+            OIC_LOG(DEBUG, TAG, "OUT");
+            g_receivedDataLen = 0;
+        }
+
+        OIC_LOG(DEBUG, TAG, "IN");
+        while (CAIsLEDataAvailable())
+        {
+            OIC_LOG(DEBUG, TAG, "In While loop");
+            g_coapBuffer[g_receivedDataLen++] = CALEReadData();
+            if (g_receivedDataLen == g_packetDataLen)
+            {
+                OIC_LOG(DEBUG, TAG, "Read Comp BLE Pckt");
+                g_coapBuffer[g_receivedDataLen] = '\0';
+                if (g_receivedDataLen > 0)
+                {
+                    OIC_LOG_V(DEBUG, TAG, "recv dataLen=%d", g_receivedDataLen);
+                    uint32_t sentLength = 0;
+                    // g_coapBuffer getting freed by CAMesssageHandler
+                    g_bleServerDataReceivedCallback("", "", g_coapBuffer,
+                                                    g_receivedDataLen, &sentLength);
+                }
+
+                g_receivedDataLen = 0;
+                g_coapBuffer = NULL;
+                break;
+            }
+        }
+        OIC_LOG(DEBUG, TAG, "OUT");
+    }
+    else
+    {
+        OIC_LOG(DEBUG, TAG, "NoData");
+    }
+    return;
+}
+
+CAResult_t CALEInitialize()
 {
     OIC_LOG(DEBUG, TAG, "IN");
 
     // Set your BLE Shield name here, max. length 10
-    ble_set_name("SAMSUNG");
+    ble_set_name(__OIC_DEVICE_NAME__);
 
     OIC_LOG(DEBUG, TAG, "LEName Set");
 
@@ -45,72 +144,103 @@ CAResult_t CAInitializeBle()
 
     OIC_LOG(DEBUG, TAG, "OUT");
     return CA_STATUS_OK;
-
 }
 
-CAResult_t CAAddNewBleServiceInGattServer(const char *service_uuid)
+void CASetLEServerThreadPoolHandle(ca_thread_pool_t handle)
 {
-    // Not Supported - Done at compile time
-    return CA_STATUS_OK;
+    OIC_LOG(DEBUG, TAG, "IN");
+    OIC_LOG(DEBUG, TAG, "OUT");
 }
 
-CAResult_t CARemoveBleServiceFromGattServer(const char *svc_path)
+void CASetBLEServerErrorHandleCallback(CABLEErrorHandleCallback callback)
 {
-    // Not Supported - Done at compile time
-    return CA_STATUS_OK;
+    OIC_LOG(DEBUG, TAG, "IN");
+    OIC_LOG(DEBUG, TAG, "OUT");
 }
 
-CAResult_t CARemoveAllBleServicesFromGattServer()
+unsigned char CAIsLEDataAvailable()
 {
-    // Not Supported
-    return CA_STATUS_OK;
+    return ble_available();
 }
 
-CAResult_t CARegisterBleServicewithGattServer(const char *svc_path)
+unsigned char CAIsLEConnected()
 {
-    // Not Supported - Done at compile time
-    return CA_STATUS_OK;
+    return ble_connected();
+}
+char CALEReadData()
+{
+    return (char)ble_read();
 }
 
-CAResult_t CAAddNewCharacteristicsToGattServer(const char *svc_path,
-        const char *char_uuid,
-        const char *char_value,
-        int char_value_len,
-        int read)
+CAResult_t CALEDoEvents()
 {
-    // Not Supported - Done at compile time
+    ble_do_events();
     return CA_STATUS_OK;
 }
 
-CAResult_t CARemoveCharacteristicsFromGattServer(const char *char_path)
+CAResult_t CAUpdateCharacteristicsToAllGattClients(const char *char_value,
+                                                   uint32_t valueLength)
 {
-    // Not Supported
+    // ble_write_bytes() api can send only max of 255 bytes at a time
+    // This function shall never be called to send more than 255 bytes by the fragmentation logic.
+    // Currently ble_write_bytes api returns void.
+    ble_write_bytes((unsigned char *)char_value, (unsigned char)valueLength);
     return CA_STATUS_OK;
 }
 
-unsigned char CAIsBleDataAvailable()
+void CASetLEReqRespServerCallback(CABLEServerDataReceivedCallback callback)
 {
-    return ble_available();
+    OIC_LOG(DEBUG, TAG, "IN");
+    g_bleServerDataReceivedCallback = callback;
+    OIC_LOG(DEBUG, TAG, "OUT");
 }
 
-unsigned char CAIsBleConnected()
+CAResult_t CAStartLEGattServer()
 {
-    return ble_connected();
+    OIC_LOG(DEBUG, TAG, "IN");
+    CAResult_t result = CALEInitialize();
+    if (CA_STATUS_OK != result)
+    {
+        OIC_LOG_V(ERROR, TAG, "ble init fail: %d", result);
+        return CA_STATUS_FAILED;
+    }
+    /**
+     * Below for loop is to process the BLE Events received from BLE Shield.
+     * BLE Events includes BLE Shield Address Added as a patch to RBL Library.
+     */
+    for (int iter = 0; iter < MAX_EVENT_COUNT; iter++)
+    {
+        CACheckLEDataInternal();
+    }
+
+    g_serverRunning = true;
+    OIC_LOG(DEBUG, TAG, "OUT");
+    return CA_STATUS_OK;
 }
-char CAReadBleData()
+
+CAResult_t CAStopLEGattServer()
 {
-    return (char)ble_read();
+    OIC_LOG(DEBUG, TAG, "IN");
+    // There is no server running to stop.
+    OIC_LOG(DEBUG, TAG, "OUT");
+    return CA_STATUS_OK;
 }
 
-CAResult_t CABleDoEvents()
+void CATerminateLEGattServer()
 {
-    ble_do_events();
-    return CA_STATUS_OK;
+    OIC_LOG(DEBUG, TAG, "IN");
+    ble_radio_reset();
+    g_serverRunning = false;
+    OIC_LOG(DEBUG, TAG, "OUT");
+    return;
 }
 
-CAResult_t CAWriteBleData(unsigned char *data, uint8_t len)
+void CACheckLEData()
 {
-    // Currently ble_write_bytes api returns void.
-    ble_write_bytes(data, len);
-    return CA_STATUS_OK;
-}
\ No newline at end of file
+    if (false == g_serverRunning)
+    {
+        OIC_LOG(ERROR, TAG, "Server is not running");
+        return;
+    }
+    CACheckLEDataInternal();
+}