Imported Upstream version 1.0.0
[platform/upstream/iotivity.git] / resource / csdk / connectivity / src / bt_le_adapter / arduino / cableserver.cpp
1 /******************************************************************
2 *
3 * Copyright 2014 Samsung Electronics All Rights Reserved.
4 *
5 *
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 *      http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 *
19 ******************************************************************/
20
21
22 //logger.h included first to avoid conflict with RBL library PROGMEM attribute
23 #include "logger.h"
24
25 #include "cableserver.h"
26
27 #include <Arduino.h>
28 #include <SPI.h>
29 #include <boards.h>
30 #include <RBL_nRF8001.h>
31
32 #include "caleinterface.h"
33 #include "oic_malloc.h"
34 #include "caadapterutils.h"
35 #include "cafragmentation.h"
36
37 #define TAG "LES"
38
39 /**
40  * @var    g_bleServerDataReceivedCallback
41  * @brief  Maintains the callback to be notified on receival of network packets from other
42  *           BLE devices
43  */
44 static CABLEDataReceivedCallback g_bleServerDataReceivedCallback = NULL;
45
46 /**
47  * @def MAX_EVENT_COUNT
48  * @brief Maximum number of tries to get the event on BLE Shield address.
49  */
50 #define MAX_EVENT_COUNT 20
51
52 static bool g_serverRunning = false;
53 static uint8_t *g_coapBuffer = NULL;
54
55 /**
56  * @var g_receivedDataLen
57  * @brief Actual length of data received.
58  */
59 static uint32_t g_receivedDataLen = 0;
60
61 /**
62  * @var g_packetDataLen
63  * @brief Total Length of data that is being fragmented.
64  */
65 static uint32_t g_packetDataLen = 0;
66
67 void CACheckLEDataInternal()
68 {
69     CALEDoEvents();
70
71     if (CAIsLEDataAvailable())
72     {
73         // Allocate Memory for COAP Buffer and do ParseHeader
74         if (NULL == g_coapBuffer)
75         {
76             OIC_LOG(DEBUG, TAG, "IN");
77             uint8_t headerArray[CA_HEADER_LENGTH];
78             while (CAIsLEDataAvailable() && g_receivedDataLen < CA_HEADER_LENGTH)
79             {
80                 headerArray[g_receivedDataLen++] = CALEReadData();
81             }
82
83             g_packetDataLen = CAParseHeader(headerArray, CA_HEADER_LENGTH);
84
85             if (g_packetDataLen > COAP_MAX_PDU_SIZE)
86             {
87                 OIC_LOG(ERROR, TAG, "len > pdu_size");
88                 return;
89             }
90
91             g_coapBuffer = (uint8_t *)OICCalloc((size_t)g_packetDataLen, 1);
92             if (NULL == g_coapBuffer)
93             {
94                 OIC_LOG(ERROR, TAG, "malloc");
95                 return;
96             }
97
98             OIC_LOG(DEBUG, TAG, "OUT");
99             g_receivedDataLen = 0;
100         }
101
102         OIC_LOG(DEBUG, TAG, "IN");
103         while (CAIsLEDataAvailable())
104         {
105             OIC_LOG(DEBUG, TAG, "In While loop");
106             g_coapBuffer[g_receivedDataLen++] = CALEReadData();
107             if (g_receivedDataLen == g_packetDataLen)
108             {
109                 OIC_LOG(DEBUG, TAG, "Read Comp BLE Pckt");
110                 if (g_receivedDataLen > 0)
111                 {
112                     OIC_LOG_V(DEBUG, TAG, "recv dataLen=%u", g_receivedDataLen);
113                     uint32_t sentLength = 0;
114                     // g_coapBuffer getting freed by CAMesssageHandler
115                     g_bleServerDataReceivedCallback("", g_coapBuffer,
116                                                     g_receivedDataLen, &sentLength);
117                 }
118
119                 g_receivedDataLen = 0;
120                 g_coapBuffer = NULL;
121                 break;
122             }
123         }
124         OIC_LOG(DEBUG, TAG, "OUT");
125     }
126     else
127     {
128         OIC_LOG(DEBUG, TAG, "NoData");
129     }
130     return;
131 }
132
133 CAResult_t CALEInitialize()
134 {
135     OIC_LOG(DEBUG, TAG, "IN");
136
137     // Set your BLE Shield name here, max. length 10
138     ble_set_name(__OIC_DEVICE_NAME__);
139
140     OIC_LOG(DEBUG, TAG, "LEName Set");
141
142     ble_begin();
143
144     OIC_LOG(DEBUG, TAG, "OUT");
145     return CA_STATUS_OK;
146 }
147
148 void CASetLEServerThreadPoolHandle(ca_thread_pool_t handle)
149 {
150     OIC_LOG(DEBUG, TAG, "IN");
151     OIC_LOG(DEBUG, TAG, "OUT");
152 }
153
154 void CASetBLEServerErrorHandleCallback(CABLEErrorHandleCallback callback)
155 {
156     OIC_LOG(DEBUG, TAG, "IN");
157     OIC_LOG(DEBUG, TAG, "OUT");
158 }
159
160 unsigned char CAIsLEDataAvailable()
161 {
162     return ble_available();
163 }
164
165 unsigned char CAIsLEConnected()
166 {
167     return ble_connected();
168 }
169
170 uint8_t CALEReadData()
171 {
172     return (uint8_t)ble_read();
173 }
174
175 CAResult_t CALEDoEvents()
176 {
177     ble_do_events();
178     return CA_STATUS_OK;
179 }
180
181 CAResult_t CAUpdateCharacteristicsToAllGattClients(const uint8_t *char_value,
182                                                    uint32_t valueLength)
183 {
184     // ble_write_bytes() api can send only max of 255 bytes at a time
185     // This function shall never be called to send more than 255 bytes by the fragmentation logic.
186     // Currently ble_write_bytes api returns void.
187     ble_write_bytes((unsigned char *)char_value, (unsigned char)valueLength);
188     return CA_STATUS_OK;
189 }
190
191 void CASetLEReqRespServerCallback(CABLEDataReceivedCallback callback)
192 {
193     OIC_LOG(DEBUG, TAG, "IN");
194     g_bleServerDataReceivedCallback = callback;
195     OIC_LOG(DEBUG, TAG, "OUT");
196 }
197
198 CAResult_t CAStartLEGattServer()
199 {
200     OIC_LOG(DEBUG, TAG, "IN");
201     CAResult_t result = CALEInitialize();
202     if (CA_STATUS_OK != result)
203     {
204         OIC_LOG_V(ERROR, TAG, "ble init fail: %d", result);
205         return CA_STATUS_FAILED;
206     }
207     /**
208      * Below for loop is to process the BLE Events received from BLE Shield.
209      * BLE Events includes BLE Shield Address Added as a patch to RBL Library.
210      */
211     for (int iter = 0; iter < MAX_EVENT_COUNT; iter++)
212     {
213         CACheckLEDataInternal();
214     }
215
216     g_serverRunning = true;
217     OIC_LOG(DEBUG, TAG, "OUT");
218     return CA_STATUS_OK;
219 }
220
221 CAResult_t CAStopLEGattServer()
222 {
223     OIC_LOG(DEBUG, TAG, "IN");
224     // There is no server running to stop.
225     OIC_LOG(DEBUG, TAG, "OUT");
226     return CA_STATUS_OK;
227 }
228
229 void CATerminateLEGattServer()
230 {
231     OIC_LOG(DEBUG, TAG, "IN");
232     ble_radio_reset();
233     g_serverRunning = false;
234     OIC_LOG(DEBUG, TAG, "OUT");
235     return;
236 }
237
238 void CACheckLEData()
239 {
240     if (false == g_serverRunning)
241     {
242         OIC_LOG(ERROR, TAG, "Server is not running");
243         return;
244     }
245     CACheckLEDataInternal();
246 }