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 ******************************************************************/
21 #include "caleclient.h"
26 #include <arpa/inet.h>
27 #include <sys/types.h>
28 #include <sys/socket.h>
29 #include <netinet/in.h>
34 #include "uarraylist.h"
35 #include "caqueueingthread.h"
36 #include "caadapterutils.h"
37 #include "cagattservice.h"
38 #include "oic_string.h"
39 #include "oic_malloc.h"
42 * Logging tag for module name.
44 #define TAG "OIC_CA_LE_CLIENT"
46 #define MICROSECS_PER_SEC 1000000
47 #define WAIT_TIME_WRITE_CHARACTERISTIC 10 * MICROSECS_PER_SEC
49 //For custom uuid ble server
50 #define CA_GATT_CUSTOM_UUID "4209"
51 #define CA_GATT_CUSTOM_UUID2 "4204"
52 #define CUSTOM_UUID_LEN 4
54 static const int samsung_code = 117;
56 uint64_t const TIMEOUT = 30 * MICROSECS_PER_SEC;
59 * Flag to check if scanning is in progress
61 static bool g_isScanningInProgress = false;
64 * Mutex to synchronize access to g_isScanningInProgress
66 static oc_mutex g_isScanningInProgressMutex = NULL;
69 * Flag to check if connection is in progress
71 static bool g_isConnectionInProgress = false;
74 * Mutex to synchronize access to g_isConnectionInProgress
76 static oc_mutex g_isConnectionInProgressMutex = NULL;
79 * Flag to check if multicast is already in progress.
81 static bool g_isMulticastInProgress = false;
84 * Flag to check if unicast scan is in progress
86 static bool g_isUnicastScanInProgress = false;
89 * Mutex to synchronize access to g_isMulticastInProgress
90 * and g_isUnicastScanInProgress
92 static oc_mutex g_scanMutex = NULL;
95 * Pending multicast data list to be sent.
97 static u_arraylist_t *g_multicastDataList = NULL;
100 * Mutex to synchronize the access to Pending multicast data list.
102 static oc_mutex g_multicastDataListMutex = NULL;
105 * Condition to start the timer for scanning.
107 static oc_cond g_startTimerCond = NULL;
110 * Condition for scanning Time interval.
112 static oc_cond g_scanningTimeCond = NULL;
115 * This contains the list of OIC services a client connect tot.
117 static LEServerInfoList *g_LEServerList = NULL;
120 * Mutex to synchronize access to BleServiceList.
122 static oc_mutex g_LEServerListMutex = NULL;
125 * Boolean variable to keep the state of the GATT Client.
127 static bool g_isLEGattClientStarted = false;
130 * Mutex to synchronize access to the requestResponse callback to be called
131 * when the data needs to be sent from GATTClient.
133 static oc_mutex g_LEReqRespClientCbMutex = NULL;
136 * Mutex to synchronize access to the requestResponse callback to be called
137 * when the data needs to be sent from GATTClient.
139 static oc_mutex g_LEClientConnectMutex = NULL;
142 * Mutex to synchronize the calls to be done to the platform from GATTClient
143 * interfaces from different threads.
145 static oc_mutex g_LEClientStateMutex = NULL;
148 * Mutex to synchronize the task to be pushed to thread pool.
150 static oc_mutex g_LEClientThreadPoolMutex = NULL;
153 * Mutex to synchronize the task to write characteristic one packet after another.
155 static oc_mutex g_threadWriteCharacteristicMutex = NULL;
158 * Condition for Writing characteristic.
160 static oc_cond g_threadWriteCharacteristicCond = NULL;
163 * Mutex to synchronize the task for MTU Changed.
165 static oc_mutex g_threadMTUChangedMutex = NULL;
168 * Condition for MTU Changed.
170 static oc_cond g_threadMTUChangedCond = NULL;
173 * Flag to check status of write characteristic.
175 static bool g_isSignalSetFlag = false;
178 * Maintains the callback to be notified on receival of network packets from other
181 static CABLEDataReceivedCallback g_LEClientDataReceivedCallback = NULL;
184 * callback to update the error to le adapter
186 static CABLEErrorHandleCallback g_clientErrorCallback;
189 * gmainLoop to manage the threads to receive the callback from the platfrom.
191 static GMainLoop *g_eventLoop = NULL;
194 * Reference to threadpool
196 static ca_thread_pool_t g_LEClientThreadPool = NULL;
198 void CALEGattCharacteristicChangedCb(bt_gatt_h characteristic,
200 int valueLen, void *userData)
202 (void)characteristic;
204 OIC_LOG(DEBUG, TAG, "IN");
205 OIC_LOG_V(DEBUG, TAG, "Changed characteristic value length [%d]", valueLen);
207 oc_mutex_lock(g_LEReqRespClientCbMutex);
208 if (NULL == g_LEClientDataReceivedCallback)
210 OIC_LOG(ERROR, TAG, "Request response callback is not set");
211 oc_mutex_unlock(g_LEReqRespClientCbMutex);
215 uint32_t sentLength = 0;
216 g_LEClientDataReceivedCallback(userData, (uint8_t *)value, valueLen, &sentLength);
218 OIC_LOG_V(DEBUG, TAG, "Recv data Length is %d", sentLength);
220 oc_mutex_unlock(g_LEReqRespClientCbMutex);
222 OIC_LOG(DEBUG, TAG, "OUT");
225 void CALEGattClientMTUChangedCb(bt_gatt_client_h client_handle, const bt_gatt_client_att_mtu_info_s *mtu_info, void *user_data)
227 OIC_LOG(DEBUG, TAG, "IN");
228 oc_mutex_lock(g_threadMTUChangedMutex);
229 OIC_LOG(DEBUG, TAG, "MTU changed signal");
230 oc_cond_signal(g_threadMTUChangedCond);
231 oc_mutex_unlock(g_threadMTUChangedMutex);
232 OIC_LOG(DEBUG, TAG, "OUT");
236 void CALEGattCharacteristicWriteCb(int result, bt_gatt_h reqHandle, void *userData)
241 OIC_LOG(DEBUG, TAG, "IN ");
243 if (BT_ERROR_NONE != result)
245 CALogSendStateInfo(CA_ADAPTER_GATT_BTLE, "", 0, -1,
246 false, "writeChar failure");
248 OIC_LOG(ERROR, TAG, "Write failed Need Retry ");
249 //Need to Implement retry mechanism
253 oc_mutex_lock(g_threadWriteCharacteristicMutex);
254 OIC_LOG(DEBUG, TAG, "g_isSignalSetFlag is set true and signal");
255 g_isSignalSetFlag = true;
256 oc_cond_signal(g_threadWriteCharacteristicCond);
257 oc_mutex_unlock(g_threadWriteCharacteristicMutex);
259 CALogSendStateInfo(CA_ADAPTER_GATT_BTLE, "", 0, -1,
260 true, "writeChar success");
263 OIC_LOG(DEBUG, TAG, "OUT ");
266 CAResult_t CALEGattInitiateConnection(const char *remoteAddress)
268 OIC_LOG(DEBUG, TAG, "IN");
270 oc_mutex_lock(g_isConnectionInProgressMutex);
271 if (g_isConnectionInProgress)
273 oc_mutex_unlock(g_isConnectionInProgressMutex);
274 OIC_LOG(DEBUG, TAG, "Connection already in progress, cannot initiate new connection");
275 return CA_STATUS_FAILED;
277 g_isConnectionInProgress = true;
278 oc_mutex_unlock(g_isConnectionInProgressMutex);
280 // Pause the scanning
281 CALEGattStopDeviceScanning();
283 OIC_LOG_V(DEBUG, TAG,
284 "Trying to do Gatt connection to [%s]", remoteAddress);
286 oc_mutex_lock(g_LEClientThreadPoolMutex);
287 if (NULL == g_LEClientThreadPool)
289 oc_mutex_unlock(g_LEClientThreadPoolMutex);
290 OIC_LOG(ERROR, TAG, "g_LEClientThreadPool is NULL");
291 return CA_STATUS_FAILED;
294 char *addr = OICStrdup(remoteAddress);
297 oc_mutex_unlock(g_LEClientThreadPoolMutex);
298 OIC_LOG(ERROR, TAG, "OICStrdup failed");
299 return CA_STATUS_FAILED;
302 CAResult_t res = ca_thread_pool_add_task(g_LEClientThreadPool, CAGattConnectThread, addr, NULL);
303 oc_mutex_unlock(g_LEClientThreadPoolMutex);
304 if (CA_STATUS_OK != res)
306 OIC_LOG_V(ERROR, TAG,
307 "ca_thread_pool_add_task failed with ret [%d]", res);
309 return CA_STATUS_FAILED;
311 OIC_LOG(DEBUG, TAG, "OUT");
315 void CALEGattConnectionStateChanged(bool connected, const char *remoteAddress)
317 OIC_LOG(DEBUG, TAG, "IN ");
319 VERIFY_NON_NULL_VOID(remoteAddress, TAG, "remote address is NULL");
323 OIC_LOG_V(DEBUG, TAG, "DisConnected from [%s] ", remoteAddress);
324 oc_mutex_lock(g_LEServerListMutex);
325 CARemoveLEServerInfoFromList(&g_LEServerList, remoteAddress);
326 oc_mutex_unlock(g_LEServerListMutex);
330 OIC_LOG_V(DEBUG, TAG, "Connected to [%s] ", remoteAddress);
332 oc_mutex_lock(g_isConnectionInProgressMutex);
333 g_isConnectionInProgress = false;
334 oc_mutex_unlock(g_isConnectionInProgressMutex);
336 LEServerInfo *serverInfo = NULL;
337 oc_mutex_lock(g_LEServerListMutex);
338 if (CA_STATUS_OK != CAGetLEServerInfo(g_LEServerList, remoteAddress, &serverInfo))
340 oc_mutex_unlock(g_LEServerListMutex);
341 OIC_LOG_V(ERROR, TAG, "Could not get server info for [%s]", remoteAddress);
345 serverInfo->status = LE_STATUS_CONNECTED;
346 oc_mutex_unlock(g_LEServerListMutex);
348 oc_mutex_lock(g_LEClientThreadPoolMutex);
349 if (NULL == g_LEClientThreadPool)
351 oc_mutex_unlock(g_LEClientThreadPoolMutex);
352 OIC_LOG(ERROR, TAG, "g_LEClientThreadPool is NULL");
356 char *addr = OICStrdup(remoteAddress);
359 oc_mutex_unlock(g_LEClientThreadPoolMutex);
360 OIC_LOG(ERROR, TAG, "addr is NULL");
364 CAResult_t ret = ca_thread_pool_add_task(g_LEClientThreadPool, CADiscoverLEServicesThread,
366 oc_mutex_unlock(g_LEClientThreadPoolMutex);
367 if (CA_STATUS_OK != ret)
369 OIC_LOG_V(ERROR, TAG, "ca_thread_pool_add_task failed with ret [%d]", ret);
373 OIC_LOG(DEBUG, TAG, "OUT");
376 static bool CALEIsHaveServiceImpl(bt_adapter_le_device_scan_result_info_s *scanInfo,
377 const char *service_uuid,
378 bt_adapter_le_packet_type_e pkt_type)
385 result = bt_adapter_le_get_scan_result_service_uuids(scanInfo,
386 pkt_type, &uuids, &count);
387 if (result == BT_ERROR_NONE && NULL != uuids)
389 for (int i = 0; i < count; i++)
391 if (0 == strcasecmp(uuids[i], service_uuid))
393 OIC_LOG_V(DEBUG, TAG, "Service[%s] Found in %s",
394 uuids[i], scanInfo->remote_address);
403 char *man_data = NULL;
406 result = bt_adapter_le_get_scan_result_manufacturer_data(scanInfo,
407 pkt_type, &man_id, &man_data, &man_data_len);
409 if (result == BT_ERROR_NONE && NULL != man_data)
411 char *compare_man_data = OICMalloc((man_data_len*2)+1);
413 for(int i=0;i<man_data_len;i++){
414 pos += sprintf(compare_man_data+pos, "%.2x", man_data[i]);
416 compare_man_data[(man_data_len*2)+1]='\0';
417 OIC_LOG_V(DEBUG, TAG, "Manufacture Id %d Manufacture Data[%s]" ,man_id,compare_man_data);
418 if (man_id == samsung_code && 0 == strncasecmp(compare_man_data, service_uuid, CUSTOM_UUID_LEN))
420 OIC_LOG_V(DEBUG, TAG, "Manufacture Data[%s] Found in %s",
421 compare_man_data, scanInfo->remote_address);
424 OICFree(compare_man_data);
431 static bool CALEIsHaveService(bt_adapter_le_device_scan_result_info_s *scanInfo,
432 const char *service_uuid)
435 // For arduino servers, scan response will give the UUIDs advertised.
436 CALEIsHaveServiceImpl(scanInfo, service_uuid,
437 BT_ADAPTER_LE_PACKET_SCAN_RESPONSE) ||
438 // For android/tizen servers, advertising packet will give the UUIDs.
439 CALEIsHaveServiceImpl(scanInfo, service_uuid,
440 BT_ADAPTER_LE_PACKET_ADVERTISING);
443 void CALEAdapterScanResultCb(int result, bt_adapter_le_device_scan_result_info_s *scanInfo,
448 OIC_LOG(DEBUG, TAG, "IN");
450 VERIFY_NON_NULL_VOID(scanInfo, TAG, "scanInfo");
451 VERIFY_NON_NULL_VOID(scanInfo->remote_address, TAG, "scanInfo->remote_address");
453 OIC_LOG_V(DEBUG, TAG, "Remote Address [%s]", scanInfo->remote_address);
454 OIC_LOG_V(DEBUG, TAG, "Scan Result [%d]", result);
455 OIC_LOG_V(DEBUG, TAG,
456 " Adv data len [%d] Scan data len[%d]RSSI [%d] Addr_type [%d] ",
457 scanInfo->adv_data_len, scanInfo->scan_data_len, scanInfo->rssi,
458 scanInfo->address_type);
460 // Check if scanning was stopped (since this callback is
461 // being triggered even after stopping the scan)
462 oc_mutex_lock(g_isScanningInProgressMutex);
463 if (!g_isScanningInProgress)
465 oc_mutex_unlock(g_isScanningInProgressMutex);
466 OIC_LOG(DEBUG, TAG, "Scanning not in progress, so ignoring callback");
469 oc_mutex_unlock(g_isScanningInProgressMutex);
471 if (CALEIsHaveService(scanInfo, CA_GATT_SERVICE_UUID) ||
472 CALEIsHaveService(scanInfo, CA_GATT_CUSTOM_UUID)||
473 CALEIsHaveService(scanInfo, CA_GATT_CUSTOM_UUID2))
475 OIC_LOG_V(DEBUG, TAG, "Device [%s] supports OIC or custom service", scanInfo->remote_address);
477 LEServerInfo *serverInfo = NULL;
478 oc_mutex_lock(g_LEServerListMutex);
479 CAResult_t ret = CAGetLEServerInfo(g_LEServerList, scanInfo->remote_address, &serverInfo);
480 if (CA_STATUS_OK != ret)
482 OIC_LOG_V(DEBUG, TAG,
483 "Newly discovered device with address [%s] ", scanInfo->remote_address);
485 char *addr = OICStrdup(scanInfo->remote_address);
488 oc_mutex_unlock(g_LEServerListMutex);
489 OIC_LOG(ERROR, TAG, "Device address is NULL");
492 serverInfo = (LEServerInfo *)OICCalloc(1, sizeof(LEServerInfo));
493 if (NULL == serverInfo)
495 oc_mutex_unlock(g_LEServerListMutex);
496 OIC_LOG(ERROR, TAG, "Calloc failed");
500 serverInfo->remoteAddress = addr;
501 serverInfo->status = LE_STATUS_DISCOVERED;
503 if (CA_STATUS_OK != CAAddLEServerInfoToList(&g_LEServerList, serverInfo))
505 oc_mutex_unlock(g_LEServerListMutex);
506 OIC_LOG_V(ERROR, TAG, "Could not add [%s] to server list", scanInfo->remote_address);
507 CAFreeLEServerInfo(serverInfo);
511 OIC_LOG_V(DEBUG, TAG,
512 "Device Present with address [%s] ", scanInfo->remote_address);
514 if(serverInfo->status == LE_STATUS_UNICAST_PENDING){
515 bt_gatt_client_h clientHandle = NULL;
516 int32_t ret = bt_gatt_client_create(serverInfo->remoteAddress, &clientHandle);
517 if (BT_ERROR_NONE != ret || NULL == clientHandle)
519 OIC_LOG_V(ERROR, TAG,
520 "bt_gatt_client_create Failed with ret value [%s] ", CALEGetErrorMsg(ret));
521 CALEGattDisConnect(serverInfo->remoteAddress);
522 oc_mutex_unlock(g_LEServerListMutex);
525 serverInfo->clientHandle = clientHandle;
527 serverInfo->status = LE_STATUS_CONNECTION_INITIATED;
528 if (CA_STATUS_OK != CALEGattInitiateConnection(serverInfo->remoteAddress))
530 OIC_LOG_V(ERROR, TAG, "Could not initiate connection to [%s]", serverInfo->remoteAddress);
531 serverInfo->status = LE_STATUS_DISCOVERED;
532 CADestroyLEDataList(&serverInfo->pendingDataList);
533 oc_mutex_unlock(g_LEServerListMutex);
540 oc_mutex_unlock(g_LEServerListMutex);
541 OIC_LOG(DEBUG, TAG, "OUT");
544 void CASetLEClientThreadPoolHandle(ca_thread_pool_t handle)
546 OIC_LOG(DEBUG, TAG, "IN");
548 oc_mutex_lock(g_LEClientThreadPoolMutex);
549 g_LEClientThreadPool = handle;
550 oc_mutex_unlock(g_LEClientThreadPoolMutex);
552 OIC_LOG(DEBUG, TAG, "OUT");
555 void CASetLEReqRespClientCallback(CABLEDataReceivedCallback callback)
557 OIC_LOG(DEBUG, TAG, "IN");
559 oc_mutex_lock(g_LEReqRespClientCbMutex);
561 g_LEClientDataReceivedCallback = callback;
563 oc_mutex_unlock(g_LEReqRespClientCbMutex);
565 OIC_LOG(DEBUG, TAG, "OUT");
568 void CASetBLEClientErrorHandleCallback(CABLEErrorHandleCallback callback)
570 g_clientErrorCallback = callback;
573 CAResult_t CAStartLEGattClient()
575 OIC_LOG(DEBUG, TAG, "IN");
577 oc_mutex_lock(g_LEClientStateMutex);
578 if (true == g_isLEGattClientStarted)
580 OIC_LOG(ERROR, TAG, "Gatt Client is already running!!");
581 oc_mutex_unlock(g_LEClientStateMutex);
582 return CA_STATUS_FAILED;
585 CAResult_t result = CALEGattSetCallbacks();
586 if (CA_STATUS_OK != result)
588 OIC_LOG(ERROR, TAG, "CABleGattSetCallbacks Failed");
589 oc_mutex_unlock(g_LEClientStateMutex);
590 CATerminateLEGattClient();
591 return CA_STATUS_FAILED;
594 g_isLEGattClientStarted = true;
595 oc_mutex_unlock(g_LEClientStateMutex);
597 oc_mutex_lock(g_LEClientThreadPoolMutex);
598 if (NULL == g_LEClientThreadPool)
600 OIC_LOG(ERROR, TAG, "gBleServerThreadPool is NULL");
601 CATerminateGattClientMutexVariables();
602 oc_mutex_unlock(g_LEClientThreadPoolMutex);
603 return CA_STATUS_FAILED;
606 result = ca_thread_pool_add_task(g_LEClientThreadPool, CAStartTimerThread,
608 if (CA_STATUS_OK != result)
610 OIC_LOG(ERROR, TAG, "ca_thread_pool_add_task failed");
611 CATerminateGattClientMutexVariables();
612 oc_mutex_unlock(g_LEClientThreadPoolMutex);
613 return CA_STATUS_FAILED;
615 oc_mutex_unlock(g_LEClientThreadPoolMutex);
617 OIC_LOG(DEBUG, TAG, "OUT");
621 void CAStartTimerThread(void *data)
625 OIC_LOG(DEBUG, TAG, "IN");
626 while (g_isLEGattClientStarted)
628 oc_mutex_lock(g_scanMutex);
629 if (!g_isMulticastInProgress && !g_isUnicastScanInProgress)
631 OIC_LOG(DEBUG, TAG, "waiting....");
632 oc_cond_wait(g_startTimerCond, g_scanMutex);
633 OIC_LOG(DEBUG, TAG, "Wake up");
636 // Timed conditional wait for stopping the scan.
637 OCWaitResult_t ret = oc_cond_wait_for(g_scanningTimeCond, g_scanMutex,
639 if (OC_WAIT_TIMEDOUT == ret)
641 OIC_LOG(DEBUG, TAG, "Scan is timed Out");
643 CALEGattStopDeviceScanning();
645 if (g_isMulticastInProgress)
647 oc_mutex_lock(g_multicastDataListMutex);
648 // Clear the data list and device list.
649 u_arraylist_destroy(g_multicastDataList);
650 g_multicastDataList = NULL;
651 oc_mutex_unlock(g_multicastDataListMutex);
652 g_isMulticastInProgress = false;
654 g_isUnicastScanInProgress = false;
656 oc_mutex_unlock(g_scanMutex);
659 OIC_LOG(DEBUG, TAG, "OUT");
662 void CAStopLEGattClient()
664 OIC_LOG(DEBUG, TAG, "IN");
666 oc_mutex_lock(g_LEClientStateMutex);
668 if (false == g_isLEGattClientStarted)
670 OIC_LOG(ERROR, TAG, "Gatt Client is not running to stop");
671 oc_mutex_unlock(g_LEClientStateMutex);
675 CALEGattUnSetCallbacks();
677 CALEGattStopDeviceScanning();
679 g_isLEGattClientStarted = false;
681 // Signal the conditions waiting in Start timer.
682 oc_cond_signal(g_startTimerCond);
683 oc_cond_signal(g_scanningTimeCond);
685 // Destroy the multicast data list and device list if not empty.
686 if (NULL != g_multicastDataList)
688 oc_mutex_lock(g_multicastDataListMutex);
689 u_arraylist_destroy(g_multicastDataList);
690 g_multicastDataList = NULL;
691 oc_mutex_unlock(g_multicastDataListMutex);
694 oc_mutex_lock(g_LEServerListMutex);
695 CAFreeLEServerList(g_LEServerList);
696 g_LEServerList = NULL;
697 oc_mutex_unlock(g_LEServerListMutex);
699 oc_mutex_lock(g_threadWriteCharacteristicMutex);
700 oc_cond_signal(g_threadWriteCharacteristicCond);
701 oc_mutex_unlock(g_threadWriteCharacteristicMutex);
703 GMainContext *context_event_loop = NULL;
704 // Required for waking up the thread which is running in gmain loop
705 if (NULL != g_eventLoop)
707 context_event_loop = g_main_loop_get_context(g_eventLoop);
709 if (context_event_loop)
711 OIC_LOG_V(DEBUG, TAG, "g_eventLoop context %p", (void *)context_event_loop);
712 g_main_context_wakeup(context_event_loop);
714 // Kill g main loops and kill threads.
715 g_main_loop_quit(g_eventLoop);
719 OIC_LOG(ERROR, TAG, "g_eventLoop context is NULL");
722 oc_mutex_unlock(g_LEClientStateMutex);
724 OIC_LOG(DEBUG, TAG, "OUT");
727 CAResult_t CAInitializeLEGattClient()
729 OIC_LOG(DEBUG, TAG, "Initialize GATT Client");
730 CAResult_t res = CAInitGattClientMutexVariables();
731 if (CA_STATUS_OK != res)
733 OIC_LOG(ERROR, TAG, "CAInitGattClientMutexVariables failed!");
734 CATerminateGattClientMutexVariables();
735 return CA_STATUS_FAILED;
740 void CATerminateLEGattClient()
742 OIC_LOG(DEBUG, TAG, "IN");
744 CATerminateGattClientMutexVariables();
746 OIC_LOG(DEBUG, TAG, "OUT");
749 CAResult_t CAInitGattClientMutexVariables()
751 OIC_LOG(DEBUG, TAG, "IN");
752 if (NULL == g_LEClientStateMutex)
754 g_LEClientStateMutex = oc_mutex_new();
755 if (NULL == g_LEClientStateMutex)
757 OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
758 return CA_STATUS_FAILED;
762 if (NULL == g_LEServerListMutex)
764 g_LEServerListMutex = oc_mutex_new();
765 if (NULL == g_LEServerListMutex)
767 OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
768 return CA_STATUS_FAILED;
772 if (NULL == g_LEReqRespClientCbMutex)
774 g_LEReqRespClientCbMutex = oc_mutex_new();
775 if (NULL == g_LEReqRespClientCbMutex)
777 OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
778 return CA_STATUS_FAILED;
782 if (NULL == g_LEClientThreadPoolMutex)
784 g_LEClientThreadPoolMutex = oc_mutex_new();
785 if (NULL == g_LEClientThreadPoolMutex)
787 OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
788 return CA_STATUS_FAILED;
792 if (NULL == g_LEClientConnectMutex)
794 g_LEClientConnectMutex = oc_mutex_new();
795 if (NULL == g_LEClientConnectMutex)
797 OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
798 return CA_STATUS_FAILED;
802 if (NULL == g_isScanningInProgressMutex)
804 g_isScanningInProgressMutex = oc_mutex_new();
805 if (NULL == g_isScanningInProgressMutex)
807 OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
808 return CA_STATUS_FAILED;
812 if (NULL == g_isConnectionInProgressMutex)
814 g_isConnectionInProgressMutex = oc_mutex_new();
815 if (NULL == g_isConnectionInProgressMutex)
817 OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
818 return CA_STATUS_FAILED;
822 if (NULL == g_multicastDataListMutex)
824 g_multicastDataListMutex = oc_mutex_new();
825 if (NULL == g_multicastDataListMutex)
827 OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
828 return CA_STATUS_FAILED;
832 if (NULL == g_scanMutex)
834 g_scanMutex = oc_mutex_new();
835 if (NULL == g_scanMutex)
837 OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
838 return CA_STATUS_FAILED;
842 if (NULL == g_threadWriteCharacteristicMutex)
844 g_threadWriteCharacteristicMutex = oc_mutex_new();
845 if (NULL == g_threadWriteCharacteristicMutex)
847 OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
848 return CA_STATUS_FAILED;
852 if (NULL == g_threadMTUChangedMutex)
854 g_threadMTUChangedMutex = oc_mutex_new();
855 if (NULL == g_threadMTUChangedMutex)
857 OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
858 return CA_STATUS_FAILED;
862 if (NULL == g_startTimerCond)
864 g_startTimerCond = oc_cond_new();
865 if (NULL == g_startTimerCond)
867 OIC_LOG(ERROR, TAG, "oc_cond_new failed");
868 return CA_STATUS_FAILED;
872 if (NULL == g_scanningTimeCond)
874 g_scanningTimeCond = oc_cond_new();
875 if (NULL == g_scanningTimeCond)
877 OIC_LOG(ERROR, TAG, "oc_cond_new failed");
878 return CA_STATUS_FAILED;
882 if (NULL == g_threadWriteCharacteristicCond)
884 g_threadWriteCharacteristicCond = oc_cond_new();
885 if (NULL == g_threadWriteCharacteristicCond)
887 OIC_LOG(ERROR, TAG, "oc_cond_new failed");
888 return CA_STATUS_FAILED;
892 if (NULL == g_threadMTUChangedCond)
894 g_threadMTUChangedCond = oc_cond_new();
895 if (NULL == g_threadMTUChangedCond)
897 OIC_LOG(ERROR, TAG, "oc_cond_new failed");
898 return CA_STATUS_FAILED;
903 OIC_LOG(DEBUG, TAG, "OUT");
907 void CATerminateGattClientMutexVariables()
909 OIC_LOG(DEBUG, TAG, "IN");
911 oc_mutex_free(g_LEClientStateMutex);
912 g_LEClientStateMutex = NULL;
914 oc_mutex_free(g_LEServerListMutex);
915 g_LEServerListMutex = NULL;
917 oc_mutex_free(g_LEReqRespClientCbMutex);
918 g_LEReqRespClientCbMutex = NULL;
920 oc_mutex_free(g_LEClientConnectMutex);
921 g_LEClientConnectMutex = NULL;
923 oc_mutex_free(g_LEClientThreadPoolMutex);
924 g_LEClientThreadPoolMutex = NULL;
926 oc_mutex_free(g_isScanningInProgressMutex);
927 g_isScanningInProgressMutex = NULL;
929 oc_mutex_free(g_isConnectionInProgressMutex);
930 g_isConnectionInProgressMutex = NULL;
932 oc_mutex_free(g_multicastDataListMutex);
933 g_multicastDataListMutex = NULL;
935 oc_mutex_free(g_scanMutex);
938 oc_mutex_free(g_threadWriteCharacteristicMutex);
939 g_threadWriteCharacteristicMutex = NULL;
941 oc_mutex_free(g_threadMTUChangedMutex);
942 g_threadMTUChangedMutex = NULL;
944 oc_cond_free(g_startTimerCond);
945 g_startTimerCond = NULL;
947 oc_cond_free(g_scanningTimeCond);
948 g_scanningTimeCond = NULL;
950 oc_cond_free(g_threadWriteCharacteristicCond);
951 g_threadWriteCharacteristicCond = NULL;
952 g_isSignalSetFlag = false;
954 oc_cond_free(g_threadMTUChangedCond);
955 g_threadMTUChangedCond = NULL;
957 OIC_LOG(DEBUG, TAG, "OUT");
960 CAResult_t CALEGattSetCallbacks()
962 OIC_LOG(DEBUG, TAG, "IN");
964 OIC_LOG(DEBUG, TAG, "OUT");
968 void CALEGattUnSetCallbacks()
970 OIC_LOG(DEBUG, TAG, "IN");
972 bt_gatt_unset_connection_state_changed_cb();
974 oc_mutex_lock(g_LEServerListMutex);
975 LEServerInfoList *curNode = g_LEServerList;
978 LEServerInfo *serverInfo = curNode->serverInfo;
979 if (serverInfo->status >= LE_STATUS_SERVICES_DISCOVERED)
981 bt_gatt_client_unset_characteristic_value_changed_cb(serverInfo->readChar);
983 curNode = curNode->next;
985 oc_mutex_unlock(g_LEServerListMutex);
987 OIC_LOG(DEBUG, TAG, "OUT");
990 CAResult_t CALEGattStartDeviceScanning()
992 OIC_LOG(DEBUG, TAG, "IN");
994 oc_mutex_lock(g_isScanningInProgressMutex);
995 if (!g_isScanningInProgress)
997 int ret = bt_adapter_le_start_scan(CALEAdapterScanResultCb, NULL);
998 if (BT_ERROR_NONE != ret)
1000 oc_mutex_unlock(g_isScanningInProgressMutex);
1001 OIC_LOG_V(ERROR, TAG, "bt_adapter_le_start_scan failed[%s]",
1002 CALEGetErrorMsg(ret));
1003 return CA_STATUS_FAILED;
1005 g_isScanningInProgress = true;
1009 OIC_LOG(DEBUG, TAG, "Ignore, scanning already in progress");
1011 oc_mutex_unlock(g_isScanningInProgressMutex);
1013 OIC_LOG(DEBUG, TAG, "OUT");
1014 return CA_STATUS_OK;
1017 void CALEGattStopDeviceScanning()
1019 OIC_LOG(DEBUG, TAG, "IN");
1021 oc_mutex_lock(g_isScanningInProgressMutex);
1022 if (g_isScanningInProgress)
1024 int ret = bt_adapter_le_stop_scan();
1025 if (BT_ERROR_NONE != ret)
1027 oc_mutex_unlock(g_isScanningInProgressMutex);
1028 OIC_LOG_V(ERROR, TAG, "bt_adapter_le_stop_scan failed[%s]",
1029 CALEGetErrorMsg(ret));
1032 g_isScanningInProgress = false;
1033 g_isUnicastScanInProgress= false;
1037 OIC_LOG(DEBUG, TAG, "Ignore, scanning not in progress");
1039 oc_mutex_unlock(g_isScanningInProgressMutex);
1041 OIC_LOG(DEBUG, TAG, "OUT");
1044 void CAGattConnectThread (void *remoteAddress)
1046 OIC_LOG(DEBUG, TAG, "IN ");
1048 VERIFY_NON_NULL_VOID(remoteAddress, TAG, "remote address is NULL");
1050 char *address = (char *)remoteAddress;
1052 OIC_LOG_V(DEBUG, TAG, "remote address is [%s]", address);
1054 CAResult_t result = CALEGattConnect(address);
1056 if (CA_STATUS_OK != result)
1058 OIC_LOG_V(ERROR, TAG, "bt_gatt_connect failed for [%s]", address);
1063 OIC_LOG(DEBUG, TAG, "OUT");
1066 CAResult_t CALEGattConnect(const char *remoteAddress)
1068 OIC_LOG(DEBUG, TAG, "IN");
1070 VERIFY_NON_NULL_RET(remoteAddress, TAG,
1071 "remote address is NULL", CA_STATUS_FAILED);
1073 oc_mutex_lock(g_LEClientConnectMutex);
1074 CAResult_t result = CA_STATUS_OK;
1076 int ret = bt_gatt_connect(remoteAddress, false);
1077 if (BT_ERROR_NONE != ret)
1079 OIC_LOG_V(ERROR, TAG, "bt_gatt_connect Failed with ret value [%s] ",
1080 CALEGetErrorMsg(ret));
1081 oc_mutex_unlock(g_LEClientConnectMutex);
1082 return CA_STATUS_FAILED;
1085 oc_mutex_unlock(g_LEClientConnectMutex);
1087 OIC_LOG(DEBUG, TAG, "OUT");
1091 CAResult_t CALEGattDisConnect(const char *remoteAddress)
1093 OIC_LOG(DEBUG, TAG, "IN");
1095 VERIFY_NON_NULL_RET(remoteAddress, TAG,
1096 "remote address is NULL", CA_STATUS_FAILED);
1098 int ret = bt_gatt_disconnect(remoteAddress);
1100 if (BT_ERROR_NONE != ret)
1102 OIC_LOG_V(ERROR, TAG, "bt_gatt_disconnect Failed with ret value [%s] ",
1103 CALEGetErrorMsg(ret));
1104 return CA_STATUS_FAILED;
1107 OIC_LOG(DEBUG, TAG, "OUT");
1108 return CA_STATUS_OK;
1111 CAResult_t CAUpdateCharacteristicsToGattServerImpl(LEServerInfo *serverInfo,
1112 const uint8_t *data, const uint32_t dataLen)
1114 OIC_LOG(DEBUG, TAG, "IN");
1116 VERIFY_NON_NULL(serverInfo, TAG, "Server Info is NULL");
1118 CALEGattStopDeviceScanning();
1120 OIC_LOG_V(DEBUG, TAG, "Updating the data of length [%d] to [%s] ", dataLen,
1121 serverInfo->remoteAddress);
1123 int result = bt_gatt_set_value(serverInfo->writeChar, (char *)data, dataLen);
1125 if (BT_ERROR_NONE != result)
1127 OIC_LOG_V(ERROR, TAG,
1128 "bt_gatt_set_value Failed with return val [%s]",
1129 CALEGetErrorMsg(result));
1133 result = bt_gatt_client_write_value(serverInfo->writeChar, CALEGattCharacteristicWriteCb,
1135 if (BT_ERROR_NONE != result)
1137 OIC_LOG_V(ERROR, TAG,
1138 "bt_gatt_client_write_value Failed with return val [%s]",
1139 CALEGetErrorMsg(result));
1143 // wait for callback for write Characteristic with success to sent data
1144 OIC_LOG_V(DEBUG, TAG, "callback flag is %d", g_isSignalSetFlag);
1145 oc_mutex_lock(g_threadWriteCharacteristicMutex);
1146 if (!g_isSignalSetFlag)
1148 OIC_LOG(DEBUG, TAG, "wait for callback to notify writeCharacteristic is success");
1149 if (OC_WAIT_SUCCESS != oc_cond_wait_for(g_threadWriteCharacteristicCond,
1150 g_threadWriteCharacteristicMutex,
1151 WAIT_TIME_WRITE_CHARACTERISTIC))
1153 g_isSignalSetFlag = false;
1154 oc_mutex_unlock(g_threadWriteCharacteristicMutex);
1155 OIC_LOG(ERROR, TAG, "there is no response. write has failed");
1159 // reset flag set by writeCharacteristic Callback
1160 g_isSignalSetFlag = false;
1161 oc_mutex_unlock(g_threadWriteCharacteristicMutex);
1163 oc_mutex_lock(g_scanMutex);
1164 if (g_isMulticastInProgress || g_isUnicastScanInProgress)
1166 if (CA_STATUS_OK != CALEGattStartDeviceScanning())
1168 OIC_LOG(ERROR, TAG, "Could not start device scanning");
1171 oc_mutex_unlock(g_scanMutex);
1172 OIC_LOG(DEBUG, TAG, "OUT");
1173 return CA_STATUS_OK;
1176 oc_mutex_lock(g_scanMutex);
1177 if (g_isMulticastInProgress || g_isUnicastScanInProgress)
1179 if (CA_STATUS_OK != CALEGattStartDeviceScanning())
1181 OIC_LOG(ERROR, TAG, "Could not start device scanning");
1184 oc_mutex_unlock(g_scanMutex);
1186 OIC_LOG(DEBUG, TAG, "OUT");
1187 return CA_STATUS_FAILED;
1190 void CADiscoverLEServicesThread(void *remoteAddress)
1192 OIC_LOG(DEBUG, TAG, "IN");
1194 VERIFY_NON_NULL_VOID(remoteAddress, TAG, "remote address is NULL");
1196 char *address = (char *)remoteAddress;
1198 CAResult_t result = CALEGattDiscoverServices(address);
1199 if (CA_STATUS_OK != result)
1201 OIC_LOG(ERROR, TAG, "CALEGattDiscoverServices failed");
1205 OIC_LOG(DEBUG, TAG, "OUT");
1208 CAResult_t CALEGattDiscoverServices(const char *remoteAddress)
1210 OIC_LOG(DEBUG, TAG, "IN");
1212 VERIFY_NON_NULL_RET(remoteAddress, TAG,
1213 "remote address is NULL", CA_STATUS_FAILED);
1215 LEServerInfo *serverInfo = NULL;
1216 unsigned int mtu_size;
1217 oc_mutex_lock(g_LEServerListMutex);
1218 if (CA_STATUS_OK != CAGetLEServerInfo(g_LEServerList, remoteAddress, &serverInfo))
1220 oc_mutex_unlock(g_LEServerListMutex);
1221 OIC_LOG_V(ERROR, TAG, "Could not get server info for [%s]", remoteAddress);
1222 CALEGattDisConnect(remoteAddress);
1223 return CA_STATUS_FAILED;
1226 bt_gatt_h serviceHandle = NULL;
1227 int32_t ret = bt_gatt_client_get_service(serverInfo->clientHandle, CA_GATT_SERVICE_UUID, &serviceHandle);
1228 if (BT_ERROR_NONE != ret || NULL == serviceHandle)
1230 OIC_LOG_V(ERROR, TAG,
1231 "bt_gatt_client_get_service Failed with ret value [%s] ", CALEGetErrorMsg(ret));
1235 // Server will read data on this characteristic.
1236 bt_gatt_h writeChrHandle = NULL;
1237 ret = bt_gatt_service_get_characteristic(serviceHandle, CA_GATT_REQUEST_CHRC_UUID,
1239 if (BT_ERROR_NONE != ret || NULL == writeChrHandle)
1241 OIC_LOG_V(ERROR, TAG,
1242 "bt_gatt_service_get_characteristic Failed with ret value [%s] ",
1243 CALEGetErrorMsg(ret));
1247 // Server will notify data on this characteristic.
1248 bt_gatt_h readChrHandle = NULL;
1249 ret = bt_gatt_service_get_characteristic(serviceHandle, CA_GATT_RESPONSE_CHRC_UUID,
1251 if (BT_ERROR_NONE != ret || NULL == readChrHandle)
1253 OIC_LOG_V(ERROR, TAG,
1254 "bt_gatt_service_get_characteristic Failed with ret value [%s] ",
1255 CALEGetErrorMsg(ret));
1260 //TODO: This data has to be freed while unsetting the callback.
1261 char *addr = OICStrdup(remoteAddress);
1264 OIC_LOG(ERROR, TAG, "addr is NULL");
1268 ret = bt_gatt_client_set_characteristic_value_changed_cb(readChrHandle,
1269 CALEGattCharacteristicChangedCb,
1271 if (BT_ERROR_NONE != ret)
1273 OIC_LOG_V(ERROR, TAG,
1274 "bt_gatt_client_set_characteristic_value_changed_cb Failed with ret value [%s]",
1275 CALEGetErrorMsg(ret));
1279 ret = bt_gatt_client_set_att_mtu_changed_cb(serverInfo->clientHandle,
1280 CALEGattClientMTUChangedCb,
1281 (void *)serverInfo->remoteAddress);
1282 if (BT_ERROR_NONE != ret)
1284 OIC_LOG_V(ERROR, TAG,
1285 "bt_gatt_client_set_att_mtu_changed_cb Failed with ret value [%s]",
1286 CALEGetErrorMsg(ret));
1290 oc_mutex_lock(g_threadMTUChangedMutex);
1291 ret = bt_gatt_client_request_att_mtu_change(serverInfo->clientHandle, CA_SUPPORTED_BLE_MTU_SIZE - CA_BLE_MTU_HEADER_SIZE);
1292 if (BT_ERROR_NONE != ret)
1294 OIC_LOG_V(ERROR, TAG,
1295 "bt_gatt_client_request_att_mtu_change Failed with ret value [%s]",
1296 CALEGetErrorMsg(ret));
1297 oc_mutex_unlock(g_threadMTUChangedMutex);
1301 OIC_LOG(DEBUG, TAG, "wait for callback to notify MTU Changed Callback");
1302 oc_cond_wait(g_threadMTUChangedCond, g_threadMTUChangedMutex);
1303 oc_mutex_unlock(g_threadMTUChangedMutex);
1305 OIC_LOG(DEBUG, TAG, "Done MTU");
1306 ret = bt_gatt_client_get_att_mtu(serverInfo->clientHandle, &mtu_size);
1307 if (BT_ERROR_NONE != ret)
1309 OIC_LOG_V(ERROR, TAG,
1310 "bt_gatt_client_get_att_mtu Failed with ret value [%s]",
1311 CALEGetErrorMsg(ret));
1314 OIC_LOG_V(DEBUG, TAG,"Negotiated MTU Size %d",mtu_size);
1316 serverInfo->serviceHandle = serviceHandle;
1317 serverInfo->readChar = readChrHandle;
1318 serverInfo->writeChar = writeChrHandle;
1319 serverInfo->status = LE_STATUS_SERVICES_DISCOVERED;
1320 serverInfo->mtu_size = mtu_size;
1322 while (serverInfo->pendingDataList)
1324 LEData *leData = serverInfo->pendingDataList->data;
1325 if (CA_STATUS_OK != CAUpdateCharacteristicsToGattServerImpl(
1326 serverInfo, leData->data, leData->dataLength))
1328 OIC_LOG_V(ERROR, TAG, "Failed to send pending data to [%s]",
1329 serverInfo->remoteAddress);
1331 CADestroyLEDataList(&serverInfo->pendingDataList);
1334 CARemoveLEDataFromList(&serverInfo->pendingDataList);
1336 oc_mutex_unlock(g_LEServerListMutex);
1338 OIC_LOG(DEBUG, TAG, "OUT");
1339 return CA_STATUS_OK;
1342 bt_gatt_client_destroy(serverInfo->clientHandle);
1343 serverInfo->clientHandle = NULL;
1344 oc_mutex_unlock(g_LEServerListMutex);
1345 CALEGattDisConnect(remoteAddress);
1346 return CA_STATUS_FAILED;
1349 CAResult_t CAUpdateCharacteristicsToGattServer(const char *remoteAddress,
1350 const uint8_t *data, const uint32_t dataLen,
1351 CALETransferType_t type, const int32_t position)
1353 OIC_LOG(DEBUG, TAG, "IN");
1355 VERIFY_NON_NULL(data, TAG, "data is NULL");
1359 OIC_LOG(ERROR, TAG, "dataLen is less than or equal zero. Invalid input!");
1360 return CA_STATUS_INVALID_PARAM;
1363 LEServerInfo *serverInfo = NULL;
1364 oc_mutex_lock(g_LEServerListMutex);
1365 if (LE_UNICAST == type)
1367 if (CA_STATUS_OK != CAGetLEServerInfo(g_LEServerList, remoteAddress, &serverInfo))
1369 OIC_LOG_V(DEBUG, TAG,
1370 "Device with address [%s] not yet found, initiating scan",
1373 char *addr = OICStrdup(remoteAddress);
1376 oc_mutex_unlock(g_LEServerListMutex);
1377 OIC_LOG(ERROR, TAG, "Device address is NULL");
1378 return CA_STATUS_FAILED;
1381 serverInfo = (LEServerInfo *)OICCalloc(1, sizeof(LEServerInfo));
1382 if (NULL == serverInfo)
1384 oc_mutex_unlock(g_LEServerListMutex);
1385 OIC_LOG(ERROR, TAG, "Calloc failed");
1387 return CA_STATUS_FAILED;
1390 serverInfo->remoteAddress = addr;
1391 serverInfo->status = LE_STATUS_UNICAST_PENDING;
1393 if (CA_STATUS_OK != CAAddLEServerInfoToList(&g_LEServerList, serverInfo))
1395 oc_mutex_unlock(g_LEServerListMutex);
1396 OIC_LOG_V(ERROR, TAG, "Could not add [%s] to server list", remoteAddress);
1397 CAFreeLEServerInfo(serverInfo);
1398 return CA_STATUS_FAILED;
1401 if (CA_STATUS_OK != CAAddLEDataToList(&serverInfo->pendingDataList, data, dataLen))
1403 oc_mutex_unlock(g_LEServerListMutex);
1404 OIC_LOG(ERROR, TAG, "Could not add data to pending list");
1405 return CA_STATUS_FAILED;
1409 if(serverInfo->status == LE_STATUS_UNICAST_PENDING)
1411 oc_mutex_lock(g_scanMutex);
1412 if (!g_isMulticastInProgress && !g_isUnicastScanInProgress)
1414 CAResult_t result = CALEGattStartDeviceScanning();
1415 if (CA_STATUS_OK != result)
1417 oc_mutex_unlock(g_scanMutex);
1418 OIC_LOG(ERROR, TAG, "CALEGattStartDeviceScanning failed");
1419 return CA_STATUS_FAILED;
1421 g_isUnicastScanInProgress = true;
1423 oc_cond_signal(g_startTimerCond);
1427 g_isUnicastScanInProgress = true;
1429 oc_cond_signal(g_scanningTimeCond);
1431 oc_mutex_unlock(g_scanMutex);
1435 if (serverInfo->status == LE_STATUS_DISCOVERED)
1437 if (CA_STATUS_OK != CAAddLEDataToList(&serverInfo->pendingDataList, data, dataLen))
1439 oc_mutex_unlock(g_LEServerListMutex);
1440 OIC_LOG(ERROR, TAG, "Could not add data to pending list");
1441 return CA_STATUS_FAILED;
1444 bt_gatt_client_h clientHandle = NULL;
1445 int32_t ret = bt_gatt_client_create(serverInfo->remoteAddress, &clientHandle);
1446 if (BT_ERROR_NONE != ret || NULL == clientHandle)
1448 OIC_LOG_V(ERROR, TAG,
1449 "bt_gatt_client_create Failed with ret value [%s] ", CALEGetErrorMsg(ret));
1450 CALEGattDisConnect(serverInfo->remoteAddress);
1451 return CA_STATUS_FAILED;
1453 serverInfo->clientHandle = clientHandle;
1455 serverInfo->status = LE_STATUS_CONNECTION_INITIATED;
1456 if (CA_STATUS_OK != CALEGattInitiateConnection(serverInfo->remoteAddress))
1458 OIC_LOG_V(ERROR, TAG, "Could not initiate connection to [%s]", serverInfo->remoteAddress);
1459 serverInfo->status = LE_STATUS_DISCOVERED;
1460 CADestroyLEDataList(&serverInfo->pendingDataList);
1461 oc_mutex_unlock(g_LEServerListMutex);
1462 return CA_STATUS_FAILED;
1465 else if (serverInfo->status < LE_STATUS_SERVICES_DISCOVERED)
1467 if (CA_STATUS_OK != CAAddLEDataToList(&serverInfo->pendingDataList, data, dataLen))
1469 oc_mutex_unlock(g_LEServerListMutex);
1470 OIC_LOG(ERROR, TAG, "Could not add data to pending list");
1471 return CA_STATUS_FAILED;
1476 if (CA_STATUS_OK != CAUpdateCharacteristicsToGattServerImpl(serverInfo, data, dataLen))
1478 OIC_LOG_V(ERROR, TAG, "Could not update characteristic to gatt server [%s]",
1479 serverInfo->remoteAddress);
1480 oc_mutex_unlock(g_LEServerListMutex);
1481 return CA_STATUS_FAILED;
1485 else if (LE_MULTICAST == type)
1487 OIC_LOG(ERROR, TAG, "LE_MULTICAST type Not used");
1489 oc_mutex_unlock(g_LEServerListMutex);
1490 OIC_LOG(DEBUG, TAG, "OUT");
1491 return CA_STATUS_OK;
1494 CAResult_t CAUpdateCharacteristicsToAllGattServers(const uint8_t *data, uint32_t dataLen)
1496 OIC_LOG(DEBUG, TAG, "IN");
1498 VERIFY_NON_NULL(data, TAG, "data is NULL");
1502 OIC_LOG(ERROR, TAG, "dataLen is less than or equal zero. Invalid input !");
1503 return CA_STATUS_INVALID_PARAM;
1506 oc_mutex_lock(g_LEServerListMutex);
1507 LEServerInfoList *curNode = g_LEServerList;
1510 LEServerInfo *serverInfo = curNode->serverInfo;
1511 if (serverInfo->status == LE_STATUS_SERVICES_DISCOVERED)
1513 if (CA_STATUS_OK != CAUpdateCharacteristicsToGattServerImpl(serverInfo, data, dataLen))
1515 OIC_LOG_V(ERROR, TAG, "Failed to update characteristics to gatt server [%s]",
1516 serverInfo->remoteAddress);
1519 else if (serverInfo->status != LE_STATUS_INVALID)
1521 if (CA_STATUS_OK != CAAddLEDataToList(&serverInfo->pendingDataList, data, dataLen))
1523 OIC_LOG(ERROR, TAG, "Failed to add to pending list");
1526 curNode = curNode->next;
1528 oc_mutex_unlock(g_LEServerListMutex);
1530 // Add the data to pending list.
1531 LEData *multicastData = (LEData *)OICCalloc(1, sizeof(LEData));
1532 if (NULL == multicastData)
1534 OIC_LOG(ERROR, TAG, "Calloc failed");
1537 multicastData->data = OICCalloc(1, dataLen);
1538 if (NULL == multicastData->data)
1540 OIC_LOG(ERROR, TAG, "Calloc failed");
1543 memcpy(multicastData->data, data, dataLen);
1544 multicastData->dataLength = dataLen;
1546 oc_mutex_lock(g_multicastDataListMutex);
1547 if (NULL == g_multicastDataList)
1549 g_multicastDataList = u_arraylist_create();
1551 u_arraylist_add(g_multicastDataList, (void *)multicastData);
1552 oc_mutex_unlock(g_multicastDataListMutex);
1554 // Start the scanning, if not started, else reset timer
1555 oc_mutex_lock(g_scanMutex);
1556 if (!g_isMulticastInProgress && !g_isUnicastScanInProgress)
1558 CAResult_t result = CALEGattStartDeviceScanning();
1559 if (CA_STATUS_OK != result)
1561 oc_mutex_unlock(g_scanMutex);
1562 OIC_LOG(ERROR, TAG, "CALEGattStartDeviceScanning Failed");
1565 g_isMulticastInProgress = true;
1566 // Start the timer by signalling it
1567 oc_cond_signal(g_startTimerCond);
1571 g_isMulticastInProgress = true;
1573 oc_cond_signal(g_scanningTimeCond);
1575 oc_mutex_unlock(g_scanMutex);
1578 OIC_LOG(DEBUG, TAG, "OUT ");
1579 return CA_STATUS_OK;
1582 uint16_t CALEClientGetMtuSize(const char* remote_address)
1584 LEServerInfo *serverInfo = NULL;
1585 oc_mutex_lock(g_LEServerListMutex);
1586 if (CA_STATUS_OK == CAGetLEServerInfo(g_LEServerList, remote_address, &serverInfo))
1588 if (serverInfo->status == LE_STATUS_SERVICES_DISCOVERED){
1589 OIC_LOG_V(DEBUG, TAG, "Mtu Size [%d]", serverInfo->mtu_size);
1590 oc_mutex_unlock(g_LEServerListMutex);
1591 OIC_LOG_V(INFO, TAG, "Returning Mtu Size [%d]", serverInfo->mtu_size - CA_BLE_MTU_HEADER_SIZE);
1592 return serverInfo->mtu_size - CA_BLE_MTU_HEADER_SIZE;
1595 oc_mutex_unlock(g_LEServerListMutex);
1596 return CA_DEFAULT_BLE_MTU_SIZE;
1600 bool CALEClientIsConnected(const char* address)
1607 CAResult_t CALEClientSetMtuSize(const char* address, uint16_t mtuSize)
1611 VERIFY_NON_NULL(address, TAG, "address is null");
1613 //it should be implemented after update Tizen 3.0
1614 return CA_NOT_SUPPORTED;
1617 CAResult_t CALEClientSendNegotiationMessage(const char* address)
1619 OIC_LOG_V(DEBUG, TAG, "CALEClientSendNegotiationMessage(%s)", address);
1621 //it will be implemented when tizen public 3.0 is released.
1622 return CA_NOT_SUPPORTED;