cdedbbdab89f2c72695bce4e8b97a259ecea622c
[platform/upstream/iotivity.git] / resource / csdk / connectivity / src / bt_le_adapter / caleadapter_singlethread.c
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 #include "caleadapter_singlethread.h"
21
22 #include "caleinterface_singlethread.h"
23 #include "cableserver.h"
24 #include "logger.h"
25 #include "caadapterutils.h"
26 #include "cafragmentation.h"
27
28 #define TAG "LAD"
29
30 /**
31  * @def MAX_EVENT_COUNT
32  * @brief Maximum number of tries to get the event on BLE Shield address.
33  */
34 #define MAX_EVENT_COUNT 20
35
36 static CANetworkChangeCallback g_networkCallback = NULL;
37 static bool g_serverRunning = false;
38 static CANetworkPacketReceivedCallback g_respCallback;
39 static char *g_coapBuffer = NULL;
40 static uint32_t g_dataLen = 0;
41 static uint32_t g_packetDataLen = 0;
42
43 /**
44  * @brief API to register for BLE network notification.
45  * @param net_callback - network notification callback.
46  * @return - Error Code
47  */
48 CAResult_t LERegisterNetworkNotifications(CANetworkChangeCallback netCallback);
49
50 /**
51  * @brief API to send received data to upper layer.
52  * @param[in] data - data received from BLE characteristics.
53  * @param[in] dataLen - received data Length.
54  * @param[in] senderAdrs - sender Address.
55  * @param[in] senderPort - sender port.
56  * @return - Error Code
57  */
58 void CANotifyCallback(const void *data, int32_t dataLen, const char *senderAdrs,
59                       int32_t senderPort);
60
61 /**
62  * @brief API to read the data from characteristics and invoke notifyCallback.
63  * @return - void
64  */
65 void CACheckData();
66
67 /**
68  * @brief API to Send the data.
69  * @return - Number of bytes sent. -1 on error.
70  */
71 int32_t CASendLEData(const void *data, uint32_t dataLen);
72
73 CAResult_t CAInitializeLE(CARegisterConnectivityCallback registerCallback,
74                           CANetworkPacketReceivedCallback reqRespCallback,
75                           CANetworkChangeCallback netCallback)
76 {
77     OIC_LOG(DEBUG, TAG, "IN");
78     if (NULL == registerCallback || NULL == reqRespCallback || NULL == netCallback)
79     {
80         OIC_LOG(ERROR, TAG, "i/p null");
81         return CA_STATUS_INVALID_PARAM;
82     }
83
84     CAResult_t result = CALEInitializeNetworkMonitor();
85     if (CA_STATUS_OK != result)
86     {
87         OIC_LOG_V(ERROR, TAG, "n/w init fail: %d", result);
88         return CA_STATUS_FAILED;
89     }
90
91     g_respCallback = reqRespCallback;
92     LERegisterNetworkNotifications(netCallback);
93     CAConnectivityHandler_t connHandler;
94     connHandler.startAdapter = CAStartLE;
95     connHandler.startListenServer = CAStartLEListeningServer;
96     connHandler.startDiscoveryServer = CAStartLEDiscoveryServer;
97     connHandler.sendData = CASendLEUnicastData;
98     connHandler.sendDataToAll = CASendLEMulticastData;
99     connHandler.GetnetInfo = CAGetLEInterfaceInformation;
100     connHandler.readData = CAReadLEData;
101     connHandler.stopAdapter = CAStopLE;
102     connHandler.terminate = CATerminateLE;
103     registerCallback(connHandler, CA_ADAPTER_GATT_BTLE);
104     OIC_LOG(DEBUG, TAG, "OUT");
105     return CA_STATUS_OK;
106 }
107
108 CAResult_t CAStartLE()
109 {
110     OIC_LOG(DEBUG, TAG, "IN");
111     OIC_LOG(DEBUG, TAG, "OUT");
112     return CA_STATUS_OK;
113 }
114
115 CAResult_t CAStartLEListeningServer()
116 {
117     OIC_LOG(DEBUG, TAG, "IN");
118     CAResult_t result = CAInitializeBle();
119     if (CA_STATUS_OK != result)
120     {
121         OIC_LOG_V(ERROR, TAG, "ble init fail: %d", result);
122         return CA_STATUS_FAILED;
123     }
124     /**
125      * Below for loop is to process the BLE Events received from BLE Shield.
126      * BLE Events includes BLE Shield Address Added as a patch to RBL Library.
127      */
128     for (int iter = 0; iter < MAX_EVENT_COUNT; iter++)
129     {
130         CACheckData();
131     }
132
133     g_serverRunning = true;
134     OIC_LOG(DEBUG, TAG, "OUT");
135     return CA_STATUS_OK;
136 }
137
138 CAResult_t CAStartLEDiscoveryServer()
139 {
140     OIC_LOG(DEBUG, TAG, "IN");
141     OIC_LOG(DEBUG, TAG, "OUT");
142     return CA_STATUS_OK;
143 }
144
145 CAResult_t CAStartLENotifyServer()
146 {
147     OIC_LOG(DEBUG, TAG, "IN");
148     OIC_LOG(DEBUG, TAG, "OUT");
149     return CA_STATUS_OK;
150 }
151
152 uint32_t CASendLENotification(const CAEndpoint_t *endpoint, const void *data,
153                               uint32_t dataLen)
154 {
155     OIC_LOG(DEBUG, TAG, "IN");
156     OIC_LOG(DEBUG, TAG, "OUT");
157     return 1;
158 }
159
160 int32_t CASendLEUnicastData(const CAEndpoint_t *remoteEndpoint, const void *data, uint32_t dataLen)
161 {
162     OIC_LOG(DEBUG, TAG, "IN");
163     if (NULL == remoteEndpoint || NULL == data || dataLen == 0)
164     {
165         OIC_LOG(ERROR, TAG, "i/p null");
166         return -1;
167     }
168     OIC_LOG(DEBUG, TAG, "OUT");
169     return CASendLEData(data, dataLen);
170 }
171
172 int32_t CASendLEMulticastData(const void *data, uint32_t dataLen)
173 {
174     OIC_LOG(DEBUG, TAG, "IN");
175     if (NULL == data || 0 == dataLen)
176     {
177         OIC_LOG(ERROR, TAG, "i/p null");
178         return -1;
179     }
180
181     OIC_LOG(DEBUG, TAG, "OUT");
182     return CASendLEData(data, dataLen);
183 }
184
185 CAResult_t CAGetLEInterfaceInformation(CAEndpoint_t **info, uint32_t *size)
186 {
187     OIC_LOG(DEBUG, TAG, "IN");
188
189     if (NULL == info || NULL == size)
190     {
191         OIC_LOG(ERROR, TAG, "i/p null");
192         return CA_STATUS_INVALID_PARAM;
193     }
194
195     char *leAddress = NULL;
196     CAResult_t res = CAGetLEAddress(&leAddress);
197     if (CA_STATUS_OK != res)
198     {
199         OIC_LOG(ERROR, TAG, "CAGetLEAddress has failed");
200         return res;
201     }
202
203     if (NULL == leAddress)
204     {
205         OIC_LOG(ERROR, TAG, "Failed to get Le addr");
206         return CA_STATUS_FAILED;
207     }
208
209     OIC_LOG_V(DEBUG, TAG, "leAddress = %s", leAddress);
210
211     /**
212      * Create local endpoint using util function
213      */
214     (*info) = CAAdapterCreateEndpoint(CA_DEFAULT_FLAGS, CA_ADAPTER_GATT_BTLE, leAddress, 0);
215     if (NULL == (*info))
216     {
217         OIC_LOG(ERROR, TAG, "malloc fail");
218         return CA_MEMORY_ALLOC_FAILED;
219     }
220
221     (*size) = 1;
222     if (*leAddress)
223     {
224         OICFree(leAddress);
225     }
226     OIC_LOG(DEBUG, TAG, "OUT");
227     return CA_STATUS_OK;
228 }
229
230 CAResult_t CAReadLEData()
231 {
232     if (true == g_serverRunning)
233     {
234         CACheckData();
235     }
236     return CA_STATUS_OK;
237 }
238
239 CAResult_t CAStopLE()
240 {
241     OIC_LOG(DEBUG, TAG, "IN");
242     CAStopBleGattServer();
243     OIC_LOG(DEBUG, TAG, "OUT");
244     return CA_STATUS_OK;
245 }
246
247 void CATerminateLE()
248 {
249     OIC_LOG(DEBUG, TAG, "IN");
250     g_respCallback = NULL;
251     LERegisterNetworkNotifications(NULL);
252     CAResult_t result = CATerminateBle();
253     if (CA_STATUS_OK != result)
254     {
255         OIC_LOG(ERROR, TAG, "ble terminate fail");
256         return;
257     }
258
259     CALETerminateNetworkMonitor();
260     g_serverRunning = false;
261     OIC_LOG(DEBUG, TAG, "OUT");
262     return;
263 }
264
265 CAResult_t LERegisterNetworkNotifications(CANetworkChangeCallback netCallback)
266 {
267     OIC_LOG(DEBUG, TAG, "IN");
268     g_networkCallback = netCallback;
269     OIC_LOG(DEBUG, TAG, "OUT");
270     return CA_STATUS_OK;
271 }
272
273 CAResult_t CAStartBleGattServer()
274 {
275     OIC_LOG(DEBUG, TAG, "IN");
276     // Done at time of setup i.e. in initializeBle api
277     OIC_LOG(DEBUG, TAG, "OUT");
278     return CA_STATUS_OK;
279 }
280
281 CAResult_t CAStopBleGattServer()
282 {
283     OIC_LOG(DEBUG, TAG, "IN");
284     // There is no server running to stop.
285     OIC_LOG(DEBUG, TAG, "OUT");
286     return CA_STATUS_OK;
287 }
288
289 void CANotifyCallback(const void *data, int32_t dataLen, const char *senderAdrs, int32_t senderPort)
290 {
291     OIC_LOG(DEBUG, TAG, "IN");
292     if (g_respCallback)
293     {
294
295         /* Cannot get Address as of now */
296         CAEndpoint_t *localEndpoint = CAAdapterCreateLocalEndpoint(CA_IPV4, CA_ADAPTER_GATT_BTLE,
297                                                                    senderAdrs, senderPort);
298
299         g_respCallback(localEndpoint, data, dataLen);
300     }
301     OIC_LOG(DEBUG, TAG, "OUT");
302 }
303
304 void CACheckData()
305 {
306     CABleDoEvents();
307
308     if (CAIsBleDataAvailable())
309     {
310         // Allocate Memory for COAP Buffer and do ParseHeader
311         if (NULL == g_coapBuffer)
312         {
313             OIC_LOG(DEBUG, TAG, "IN");
314             char headerArray[CA_HEADER_LENGTH] = "";
315             while (CAIsBleDataAvailable() && g_dataLen < CA_HEADER_LENGTH)
316             {
317                 headerArray[g_dataLen++] = CAReadBleData();
318             }
319
320             g_packetDataLen = CAParseHeader(headerArray);
321
322             if (g_packetDataLen > COAP_MAX_PDU_SIZE)
323             {
324                 OIC_LOG(ERROR, TAG, "len > pdu_size");
325                 return;
326             }
327
328             g_coapBuffer = (char *)OICCalloc((size_t)g_packetDataLen, sizeof(char));
329             if (NULL == g_coapBuffer)
330             {
331                 OIC_LOG(ERROR, TAG, "malloc");
332                 return;
333             }
334
335             OIC_LOG(DEBUG, TAG, "OUT");
336             g_dataLen = 0;
337         }
338
339         OIC_LOG(DEBUG, TAG, "IN");
340         while (CAIsBleDataAvailable())
341         {
342             OIC_LOG(DEBUG, TAG, "In While loop");
343             g_coapBuffer[g_dataLen++] = CAReadBleData();
344             if (g_dataLen == g_packetDataLen)
345             {
346                 OIC_LOG(DEBUG, TAG, "Read Comp BLE Pckt");
347                 g_coapBuffer[g_dataLen] = '\0';
348                 if (g_dataLen > 0)
349                 {
350                     OIC_LOG_V(DEBUG, TAG, "recv dataLen=%d", g_dataLen);
351                     CANotifyCallback((void *)g_coapBuffer, g_dataLen, "", 0);
352                 }
353                 g_dataLen = 0;
354                 OICFree(g_coapBuffer);
355                 g_coapBuffer = NULL;
356                 break;
357             }
358         }
359         OIC_LOG(DEBUG, TAG, "OUT");
360     }
361     else
362     {
363         OIC_LOG(DEBUG, TAG, "NoData");
364     }
365     return;
366 }
367
368 int32_t CASendLEData(const void *data, uint32_t dataLen)
369 {
370     OIC_LOG(DEBUG, TAG, "IN");
371     char header[CA_HEADER_LENGTH] = {0};
372
373     CAResult_t result = CAGenerateHeader(header, dataLen);
374
375     if (CA_STATUS_OK != result)
376     {
377         OIC_LOG(ERROR, TAG, "Generate header failed");
378         return -1;
379     }
380
381     if (!CAIsBleConnected())
382     {
383         OIC_LOG(ERROR, TAG, "le not conn");
384         return -1;
385     }
386
387     result = CAUpdateCharacteristicsToAllGattClients(header, CA_HEADER_LENGTH);
388     if (CA_STATUS_OK != result)
389     {
390         OIC_LOG(ERROR, TAG, "Update characteristics failed");
391         return -1;
392     }
393
394     int32_t dataLimit = dataLen / CA_SUPPORTED_BLE_MTU_SIZE;
395     for (int32_t iter = 0; iter < dataLimit; iter++)
396     {
397         result = CAUpdateCharacteristicsToAllGattClients((data +
398                                                          (iter * CA_SUPPORTED_BLE_MTU_SIZE)),
399                                                          CA_SUPPORTED_BLE_MTU_SIZE);
400         if (CA_STATUS_OK != result)
401         {
402             OIC_LOG(ERROR, TAG, "Update characteristics failed");
403             return -1;
404         }
405         CABleDoEvents();
406     }
407
408     uint8_t remainingLen = dataLen % CA_SUPPORTED_BLE_MTU_SIZE;
409     if(remainingLen)
410     {
411         result = CAUpdateCharacteristicsToAllGattClients((data +
412                                                          (dataLimit * CA_SUPPORTED_BLE_MTU_SIZE)),
413                                                          remainingLen);
414         if (CA_STATUS_OK != result)
415         {
416             OIC_LOG(ERROR, TAG, "Update characteristics failed");
417             return -1;
418         }
419         CABleDoEvents();
420     }
421
422     OIC_LOG(DEBUG, TAG, "writebytes done");
423     OIC_LOG(DEBUG, TAG, "OUT");
424     // Arduino BLEWrite doesnot return value. So, Return the received DataLength
425     return dataLen;
426 }
427