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 "camsgparser.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_LE);
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 CARemoteEndpoint_t *endpoint, const void *data,
155 OIC_LOG(DEBUG, TAG, "IN");
156 OIC_LOG(DEBUG, TAG, "OUT");
160 int32_t CASendLEUnicastData(const CARemoteEndpoint_t *remoteEndpoint, const void *data,
163 OIC_LOG(DEBUG, TAG, "IN");
164 if (NULL == remoteEndpoint || NULL == data || dataLen == 0)
166 OIC_LOG(ERROR, TAG, "i/p null");
169 OIC_LOG(DEBUG, TAG, "OUT");
170 return CASendLEData(data, dataLen);
173 int32_t CASendLEMulticastData(const void *data, uint32_t dataLen)
175 OIC_LOG(DEBUG, TAG, "IN");
176 if (NULL == data || 0 == dataLen)
178 OIC_LOG(ERROR, TAG, "i/p null");
182 OIC_LOG(DEBUG, TAG, "OUT");
183 return CASendLEData(data, dataLen);
186 CAResult_t CAGetLEInterfaceInformation(CALocalConnectivity_t **info, uint32_t *size)
188 OIC_LOG(DEBUG, TAG, "IN");
190 if (NULL == info || NULL == size)
192 OIC_LOG(ERROR, TAG, "i/p null");
193 return CA_STATUS_INVALID_PARAM;
196 char *leAddress = NULL;
197 CAResult_t res = CAGetLEAddress(&leAddress);
198 if (CA_STATUS_OK != res)
200 OIC_LOG(ERROR, TAG, "CAGetLEAddress has failed");
204 if (NULL == leAddress)
206 OIC_LOG(ERROR, TAG, "Failed to get Le addr");
207 return CA_STATUS_FAILED;
210 OIC_LOG_V(DEBUG, TAG, "leAddress = %s", leAddress);
213 * Create local endpoint using util function
215 (*info) = CAAdapterCreateLocalEndpoint(CA_LE, leAddress);
218 OIC_LOG(ERROR, TAG, "malloc fail");
219 return CA_MEMORY_ALLOC_FAILED;
227 OIC_LOG(DEBUG, TAG, "OUT");
231 CAResult_t CAReadLEData()
233 if (true == g_serverRunning)
240 CAResult_t CAStopLE()
242 OIC_LOG(DEBUG, TAG, "IN");
243 CAStopBleGattServer();
244 OIC_LOG(DEBUG, TAG, "OUT");
250 OIC_LOG(DEBUG, TAG, "IN");
251 g_respCallback = NULL;
252 LERegisterNetworkNotifications(NULL);
253 CAResult_t result = CATerminateBle();
254 if (CA_STATUS_OK != result)
256 OIC_LOG(ERROR, TAG, "ble terminate fail");
260 CALETerminateNetworkMonitor();
261 g_serverRunning = false;
262 OIC_LOG(DEBUG, TAG, "OUT");
266 CAResult_t LERegisterNetworkNotifications(CANetworkChangeCallback netCallback)
268 OIC_LOG(DEBUG, TAG, "IN");
269 g_networkCallback = netCallback;
270 OIC_LOG(DEBUG, TAG, "OUT");
274 CAResult_t CAStartBleGattServer()
276 OIC_LOG(DEBUG, TAG, "IN");
277 // Done at time of setup i.e. in initializeBle api
278 OIC_LOG(DEBUG, TAG, "OUT");
282 CAResult_t CAStopBleGattServer()
284 OIC_LOG(DEBUG, TAG, "IN");
285 // There is no server running to stop.
286 OIC_LOG(DEBUG, TAG, "OUT");
290 void CANotifyCallback(const void *data, int32_t dataLen, const char *senderAdrs, int32_t senderPort)
292 OIC_LOG(DEBUG, TAG, "IN");
296 /* Cannot get Address as of now */
297 CARemoteEndpoint_t endPoint;
298 endPoint.resourceUri = ""; // will be filled by upper layer
299 endPoint.transportType= CA_LE;
301 g_respCallback(&endPoint, data, dataLen);
303 OIC_LOG(DEBUG, TAG, "OUT");
310 if (CAIsBleDataAvailable())
312 // Allocate Memory for COAP Buffer and do ParseHeader
313 if (NULL == g_coapBuffer)
315 OIC_LOG(DEBUG, TAG, "IN");
316 char headerArray[CA_HEADER_LENGTH] = "";
317 while (CAIsBleDataAvailable() && g_dataLen < CA_HEADER_LENGTH)
319 headerArray[g_dataLen++] = CAReadBleData();
322 g_packetDataLen = CAParseHeader(headerArray);
324 if (g_packetDataLen > COAP_MAX_PDU_SIZE)
326 OIC_LOG(ERROR, TAG, "len > pdu_size");
330 g_coapBuffer = (char *)OICCalloc((size_t)g_packetDataLen, sizeof(char));
331 if (NULL == g_coapBuffer)
333 OIC_LOG(ERROR, TAG, "malloc");
337 OIC_LOG(DEBUG, TAG, "OUT");
341 OIC_LOG(DEBUG, TAG, "IN");
342 while (CAIsBleDataAvailable())
344 OIC_LOG(DEBUG, TAG, "In While loop");
345 g_coapBuffer[g_dataLen++] = CAReadBleData();
346 if (g_dataLen == g_packetDataLen)
348 OIC_LOG(DEBUG, TAG, "Read Comp BLE Pckt");
349 g_coapBuffer[g_dataLen] = '\0';
352 OIC_LOG_V(DEBUG, TAG, "recv dataLen=%d", g_dataLen);
353 CANotifyCallback((void *)g_coapBuffer, g_dataLen, "", 0);
356 OICFree(g_coapBuffer);
361 OIC_LOG(DEBUG, TAG, "OUT");
365 OIC_LOG(DEBUG, TAG, "NoData");
370 int32_t CASendLEData(const void *data, uint32_t dataLen)
372 OIC_LOG(DEBUG, TAG, "IN");
373 char header[CA_HEADER_LENGTH] = {0};
375 CAResult_t result = CAGenerateHeader(header, dataLen);
377 if (CA_STATUS_OK != result)
379 OIC_LOG(ERROR, TAG, "Generate header failed");
383 if (!CAIsBleConnected())
385 OIC_LOG(ERROR, TAG, "le not conn");
389 result = CAUpdateCharacteristicsToAllGattClients(header, CA_HEADER_LENGTH);
390 if (CA_STATUS_OK != result)
392 OIC_LOG(ERROR, TAG, "Update characteristics failed");
396 int32_t dataLimit = dataLen / CA_SUPPORTED_BLE_MTU_SIZE;
397 for (int32_t iter = 0; iter < dataLimit; iter++)
399 result = CAUpdateCharacteristicsToAllGattClients((data +
400 (iter * CA_SUPPORTED_BLE_MTU_SIZE)),
401 CA_SUPPORTED_BLE_MTU_SIZE);
402 if (CA_STATUS_OK != result)
404 OIC_LOG(ERROR, TAG, "Update characteristics failed");
410 uint8_t remainingLen = dataLen % CA_SUPPORTED_BLE_MTU_SIZE;
413 result = CAUpdateCharacteristicsToAllGattClients((data +
414 (dataLimit * CA_SUPPORTED_BLE_MTU_SIZE)),
416 if (CA_STATUS_OK != result)
418 OIC_LOG(ERROR, TAG, "Update characteristics failed");
424 OIC_LOG(DEBUG, TAG, "writebytes done");
425 OIC_LOG(DEBUG, TAG, "OUT");
426 // Arduino BLEWrite doesnot return value. So, Return the received DataLength