1 /******************************************************************
3 * Copyright 2014 Samsung Electronics All Rights Reserved.
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 ******************************************************************/
20 #include "caleadapter_singlethread.h"
22 #include "caleinterface_singlethread.h"
23 #include "cableserver.h"
25 #include "caadapterutils.h"
26 #include "cafragmentation.h"
31 * @def MAX_EVENT_COUNT
32 * @brief Maximum number of tries to get the event on BLE Shield address.
34 #define MAX_EVENT_COUNT 20
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;
44 * @brief API to register for BLE network notification.
45 * @param net_callback - network notification callback.
46 * @return - Error Code
48 CAResult_t LERegisterNetworkNotifications(CANetworkChangeCallback netCallback);
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
58 void CANotifyCallback(const void *data, int32_t dataLen, const char *senderAdrs,
62 * @brief API to read the data from characteristics and invoke notifyCallback.
68 * @brief API to Send the data.
69 * @return - Number of bytes sent. -1 on error.
71 int32_t CASendLEData(const void *data, uint32_t dataLen);
73 CAResult_t CAInitializeLE(CARegisterConnectivityCallback registerCallback,
74 CANetworkPacketReceivedCallback reqRespCallback,
75 CANetworkChangeCallback netCallback)
77 OIC_LOG(DEBUG, TAG, "IN");
78 if (NULL == registerCallback || NULL == reqRespCallback || NULL == netCallback)
80 OIC_LOG(ERROR, TAG, "i/p null");
81 return CA_STATUS_INVALID_PARAM;
84 CAResult_t result = CALEInitializeNetworkMonitor();
85 if (CA_STATUS_OK != result)
87 OIC_LOG_V(ERROR, TAG, "n/w init fail: %d", result);
88 return CA_STATUS_FAILED;
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");
108 CAResult_t CAStartLE()
110 OIC_LOG(DEBUG, TAG, "IN");
111 OIC_LOG(DEBUG, TAG, "OUT");
115 CAResult_t CAStartLEListeningServer()
117 OIC_LOG(DEBUG, TAG, "IN");
118 CAResult_t result = CAInitializeBle();
119 if (CA_STATUS_OK != result)
121 OIC_LOG_V(ERROR, TAG, "ble init fail: %d", result);
122 return CA_STATUS_FAILED;
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.
128 for (int iter = 0; iter < MAX_EVENT_COUNT; iter++)
133 g_serverRunning = true;
134 OIC_LOG(DEBUG, TAG, "OUT");
138 CAResult_t CAStartLEDiscoveryServer()
140 OIC_LOG(DEBUG, TAG, "IN");
141 OIC_LOG(DEBUG, TAG, "OUT");
145 CAResult_t CAStartLENotifyServer()
147 OIC_LOG(DEBUG, TAG, "IN");
148 OIC_LOG(DEBUG, TAG, "OUT");
152 uint32_t CASendLENotification(const CAEndpoint_t *endpoint, const void *data,
155 OIC_LOG(DEBUG, TAG, "IN");
156 OIC_LOG(DEBUG, TAG, "OUT");
160 int32_t CASendLEUnicastData(const CAEndpoint_t *remoteEndpoint, const void *data, uint32_t dataLen)
162 OIC_LOG(DEBUG, TAG, "IN");
163 if (NULL == remoteEndpoint || NULL == data || dataLen == 0)
165 OIC_LOG(ERROR, TAG, "i/p null");
168 OIC_LOG(DEBUG, TAG, "OUT");
169 return CASendLEData(data, dataLen);
172 int32_t CASendLEMulticastData(const void *data, uint32_t dataLen)
174 OIC_LOG(DEBUG, TAG, "IN");
175 if (NULL == data || 0 == dataLen)
177 OIC_LOG(ERROR, TAG, "i/p null");
181 OIC_LOG(DEBUG, TAG, "OUT");
182 return CASendLEData(data, dataLen);
185 CAResult_t CAGetLEInterfaceInformation(CAEndpoint_t **info, uint32_t *size)
187 OIC_LOG(DEBUG, TAG, "IN");
189 if (NULL == info || NULL == size)
191 OIC_LOG(ERROR, TAG, "i/p null");
192 return CA_STATUS_INVALID_PARAM;
195 char *leAddress = NULL;
196 CAResult_t res = CAGetLEAddress(&leAddress);
197 if (CA_STATUS_OK != res)
199 OIC_LOG(ERROR, TAG, "CAGetLEAddress has failed");
203 if (NULL == leAddress)
205 OIC_LOG(ERROR, TAG, "Failed to get Le addr");
206 return CA_STATUS_FAILED;
209 OIC_LOG_V(DEBUG, TAG, "leAddress = %s", leAddress);
212 * Create local endpoint using util function
214 (*info) = CAAdapterCreateEndpoint(CA_DEFAULT_FLAGS, CA_ADAPTER_GATT_BTLE, leAddress, 0);
217 OIC_LOG(ERROR, TAG, "malloc fail");
218 return CA_MEMORY_ALLOC_FAILED;
226 OIC_LOG(DEBUG, TAG, "OUT");
230 CAResult_t CAReadLEData()
232 if (true == g_serverRunning)
239 CAResult_t CAStopLE()
241 OIC_LOG(DEBUG, TAG, "IN");
242 CAStopBleGattServer();
243 OIC_LOG(DEBUG, TAG, "OUT");
249 OIC_LOG(DEBUG, TAG, "IN");
250 g_respCallback = NULL;
251 LERegisterNetworkNotifications(NULL);
252 CAResult_t result = CATerminateBle();
253 if (CA_STATUS_OK != result)
255 OIC_LOG(ERROR, TAG, "ble terminate fail");
259 CALETerminateNetworkMonitor();
260 g_serverRunning = false;
261 OIC_LOG(DEBUG, TAG, "OUT");
265 CAResult_t LERegisterNetworkNotifications(CANetworkChangeCallback netCallback)
267 OIC_LOG(DEBUG, TAG, "IN");
268 g_networkCallback = netCallback;
269 OIC_LOG(DEBUG, TAG, "OUT");
273 CAResult_t CAStartBleGattServer()
275 OIC_LOG(DEBUG, TAG, "IN");
276 // Done at time of setup i.e. in initializeBle api
277 OIC_LOG(DEBUG, TAG, "OUT");
281 CAResult_t CAStopBleGattServer()
283 OIC_LOG(DEBUG, TAG, "IN");
284 // There is no server running to stop.
285 OIC_LOG(DEBUG, TAG, "OUT");
289 void CANotifyCallback(const void *data, int32_t dataLen, const char *senderAdrs, int32_t senderPort)
291 OIC_LOG(DEBUG, TAG, "IN");
295 /* Cannot get Address as of now */
296 CAEndpoint_t *localEndpoint = CAAdapterCreateLocalEndpoint(CA_IPV4, CA_ADAPTER_GATT_BTLE,
297 senderAdrs, senderPort);
299 g_respCallback(localEndpoint, data, dataLen);
301 OIC_LOG(DEBUG, TAG, "OUT");
308 if (CAIsBleDataAvailable())
310 // Allocate Memory for COAP Buffer and do ParseHeader
311 if (NULL == g_coapBuffer)
313 OIC_LOG(DEBUG, TAG, "IN");
314 char headerArray[CA_HEADER_LENGTH] = "";
315 while (CAIsBleDataAvailable() && g_dataLen < CA_HEADER_LENGTH)
317 headerArray[g_dataLen++] = CAReadBleData();
320 g_packetDataLen = CAParseHeader(headerArray);
322 if (g_packetDataLen > COAP_MAX_PDU_SIZE)
324 OIC_LOG(ERROR, TAG, "len > pdu_size");
328 g_coapBuffer = (char *)OICCalloc((size_t)g_packetDataLen, sizeof(char));
329 if (NULL == g_coapBuffer)
331 OIC_LOG(ERROR, TAG, "malloc");
335 OIC_LOG(DEBUG, TAG, "OUT");
339 OIC_LOG(DEBUG, TAG, "IN");
340 while (CAIsBleDataAvailable())
342 OIC_LOG(DEBUG, TAG, "In While loop");
343 g_coapBuffer[g_dataLen++] = CAReadBleData();
344 if (g_dataLen == g_packetDataLen)
346 OIC_LOG(DEBUG, TAG, "Read Comp BLE Pckt");
347 g_coapBuffer[g_dataLen] = '\0';
350 OIC_LOG_V(DEBUG, TAG, "recv dataLen=%d", g_dataLen);
351 CANotifyCallback((void *)g_coapBuffer, g_dataLen, "", 0);
354 OICFree(g_coapBuffer);
359 OIC_LOG(DEBUG, TAG, "OUT");
363 OIC_LOG(DEBUG, TAG, "NoData");
368 int32_t CASendLEData(const void *data, uint32_t dataLen)
370 OIC_LOG(DEBUG, TAG, "IN");
371 char header[CA_HEADER_LENGTH] = {0};
373 CAResult_t result = CAGenerateHeader(header, dataLen);
375 if (CA_STATUS_OK != result)
377 OIC_LOG(ERROR, TAG, "Generate header failed");
381 if (!CAIsBleConnected())
383 OIC_LOG(ERROR, TAG, "le not conn");
387 result = CAUpdateCharacteristicsToAllGattClients(header, CA_HEADER_LENGTH);
388 if (CA_STATUS_OK != result)
390 OIC_LOG(ERROR, TAG, "Update characteristics failed");
394 int32_t dataLimit = dataLen / CA_SUPPORTED_BLE_MTU_SIZE;
395 for (int32_t iter = 0; iter < dataLimit; iter++)
397 result = CAUpdateCharacteristicsToAllGattClients((data +
398 (iter * CA_SUPPORTED_BLE_MTU_SIZE)),
399 CA_SUPPORTED_BLE_MTU_SIZE);
400 if (CA_STATUS_OK != result)
402 OIC_LOG(ERROR, TAG, "Update characteristics failed");
408 uint8_t remainingLen = dataLen % CA_SUPPORTED_BLE_MTU_SIZE;
411 result = CAUpdateCharacteristicsToAllGattClients((data +
412 (dataLimit * CA_SUPPORTED_BLE_MTU_SIZE)),
414 if (CA_STATUS_OK != result)
416 OIC_LOG(ERROR, TAG, "Update characteristics failed");
422 OIC_LOG(DEBUG, TAG, "writebytes done");
423 OIC_LOG(DEBUG, TAG, "OUT");
424 // Arduino BLEWrite doesnot return value. So, Return the received DataLength