1 /******************************************************************
3 * Copyright 2017 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 ******************************************************************/
25 #include "caleclient.h"
26 #include "caleserver.h"
27 #include "caleutils.h"
28 #include "caleinterface.h"
29 #include "caadapterutils.h"
32 #include "oic_malloc.h"
33 #include "oic_string.h"
34 #include "cathreadpool.h" /* for thread pool */
36 #include "uarraylist.h"
38 #define TAG PCF("OIC_CA_LE_CLIENT")
40 #define MICROSECS_PER_SEC 1000000
41 #define WAIT_TIME_WRITE_CHARACTERISTIC 10 * MICROSECS_PER_SEC
43 #define TV_ADV_DATA_MIN_LEN 26
45 #define TV_ADV_COMPANY_ID_INDEX1 0
46 #define TV_ADV_COMPANY_ID_INDEX2 1
47 #define TV_ADV_VERSION_INDEX 2
48 #define TV_ADV_SERVICE_TYPE_INDEX 3
49 #define PON_ADV_DEVICE_TYPE_INDEX 4
50 #define OOB_AV_ADV_DEVICE_TYPE_INDEX 4
51 #define OOB_TV_ADV_DEVICE_TYPE_INDEX 10
52 #define TV_ADV_SCAN_RESP_LEN_INDEX 4
53 #define TV_ADV_DEVICE_STATUS_INDEX 5
55 #define TV_ADV_PON_MAC_BYTE_1 7
56 #define TV_ADV_PON_MAC_BYTE_2 8
57 #define TV_ADV_PON_MAC_BYTE_3 9
58 #define TV_ADV_PON_MAC_BYTE_4 10
59 #define TV_ADV_PON_MAC_BYTE_5 11
60 #define TV_ADV_PON_MAC_BYTE_6 12
62 #define AV_ADV_OOB_MAC_BYTE_1 7
63 #define AV_ADV_OOB_MAC_BYTE_2 8
64 #define AV_ADV_OOB_MAC_BYTE_3 9
65 #define AV_ADV_OOB_MAC_BYTE_4 10
66 #define AV_ADV_OOB_MAC_BYTE_5 11
67 #define AV_ADV_OOB_MAC_BYTE_6 12
69 #define PON_TV_AV_DIFF 3 // TV mac is 7-12 bytes, av mac is 10-15 bytes
71 #define TV_ADV_BD_ADDRTYPE_INDEX 19
73 #define TV_ADV_OOB_MAC_BYTE_1 20
74 #define TV_ADV_OOB_MAC_BYTE_2 21
75 #define TV_ADV_OOB_MAC_BYTE_3 22
76 #define TV_ADV_OOB_MAC_BYTE_4 23
77 #define TV_ADV_OOB_MAC_BYTE_5 24
78 #define TV_ADV_OOB_MAC_BYTE_6 25
80 #define TV_ADV_COMPANY_ID1 0x75
81 #define TV_ADV_COMPANY_ID2 0x00
82 #define TV_ADV_VERSION 0x42
84 #define TV_ADV_SERVICE_ID_POWER 0x04
85 #define TV_ADV_SERVICE_ID_OOB 0x09
87 #define TV_ADV_DEVICE_TV 0x01
88 #define TV_ADV_DEVICE_STATUS_ON 0x01
89 #define TV_ADV_DEVICE_STATUS_UNKNOWN 0x20
91 #define TV_ADV_BD_ADDR_ID 0x01
92 #define TV_ADV_SCAN_RESP_LEN 0x06
94 #define DEVICE_TYPE_TV 1
95 #define DEVICE_TYPE_AV 3
99 static ca_thread_pool_t g_threadPoolHandle = NULL;
101 static u_arraylist_t *g_deviceList = NULL; // device list to have same UUID
102 static u_arraylist_t *g_gattObjectList = NULL;
103 static u_arraylist_t *g_deviceStateList = NULL;
105 static CAPacketReceiveCallback g_packetReceiveCallback = NULL;
106 static CABLEErrorHandleCallback g_clientErrorCallback;
108 static CAManagerAdapterStateChangeCallback g_caManagerAdapterStateChangeCallback = NULL;
109 static CAManagerConnectionCallback g_caManagerConnectionCallback = NULL;
110 static CAManagerServiceDiscoveredCallback g_caManagerServiceDiscoveredCallback = NULL;
111 static dispatch_queue_t g_caManagerQueue = NULL;
113 static NSString *mac_ref = @"AB:CD:EF:15:";
116 static bool g_isStartedLEClient = false;
117 static bool g_isStartedScan = false;
119 static NSData* g_sendBuffer = nil;
120 static uint32_t g_targetCnt = 0;
121 static uint32_t g_currentSentCnt = 0;
122 static bool g_isFinishedSendData = false;
123 static oc_mutex g_SendFinishMutex = NULL;
124 static oc_mutex g_threadMutex = NULL;
125 static oc_cond g_threadCond = NULL;
126 static oc_cond g_deviceDescCond = NULL;
128 static oc_mutex g_threadSendMutex = NULL;
129 static oc_mutex g_threadWriteCharacteristicMutex = NULL;
130 static oc_cond g_threadWriteCharacteristicCond = NULL;
131 static bool g_isSignalSetFlag = false;
133 static oc_mutex g_bleReqRespClientCbMutex = NULL;
134 static oc_mutex g_bleServerBDAddressMutex = NULL;
136 static oc_mutex g_deviceListMutex = NULL;
137 static oc_mutex g_gattObjectMutex = NULL;
138 static oc_mutex g_deviceStateListMutex = NULL;
140 static oc_mutex g_deviceScanRetryDelayMutex = NULL;
141 static oc_cond g_deviceScanRetryDelayCond = NULL;
143 static oc_mutex g_scanMutex = NULL;
144 static oc_mutex waitMutex = NULL;
146 static oc_mutex g_initializeMutex = NULL;
147 static oc_cond g_initializeCond = NULL;
149 static CABLEDataReceivedCallback g_CABLEClientDataReceivedCallback = NULL;
151 @interface CBCentralIfClass:NSObject <CBCentralManagerDelegate>
153 static id cbCentralIf;
154 NSMutableArray *centralMgrs;
155 NSMutableDictionary *cbPeripherals;
156 NSMutableDictionary *cbServices;
157 NSMutableDictionary *requestCharacs;
158 NSMutableDictionary *responseCharacs;
159 NSArray<CBUUID *> *g_uuidList;
161 @implementation CBCentralIfClass
162 static CBCentralManager *centralMgr = nil;
164 - (void) CALEClientCreateCentralManager{
165 centralMgr = [[CBCentralManager alloc] initWithDelegate:self queue:nil
166 options:[NSDictionary dictionaryWithObject:
167 [NSNumber numberWithInt:0]
168 forKey:CBCentralManagerOptionShowPowerAlertKey]];
170 centralMgrs = [NSMutableArray new];
172 cbPeripherals = [[NSMutableDictionary alloc] init];
173 cbServices = [[NSMutableDictionary alloc] init];
174 requestCharacs = [[NSMutableDictionary alloc] init];
175 responseCharacs = [[NSMutableDictionary alloc] init];
178 - (CAResult_t) CALEClientStartScanImpl{
179 OIC_LOG(DEBUG, TAG, "[CBCtrl] In - CALEClientStartScanImpl");
180 if ([centralMgrs count] == 0){
181 OIC_LOG(ERROR, TAG, "[CBCtrl] central manager is not available");
182 return CA_ADAPTER_NOT_ENABLED;
184 CALEClientSetScanFlag(true);
186 [centralMgr scanForPeripheralsWithServices:nil
187 options:@{CBCentralManagerScanOptionAllowDuplicatesKey:@NO}];
192 - (CAResult_t) CALEClientStartScanWithUUIDImpl: (NSArray<CBUUID*> *)uuids{
193 OIC_LOG(DEBUG, TAG, "[CBCtrl] In - CALEClientStartScanWithUUIDImpl");
194 if ([centralMgrs count] == 0){
195 OIC_LOG(ERROR, TAG, "[CBCtrl] central manager is not available");
196 return CA_ADAPTER_NOT_ENABLED;
198 CALEClientSetScanFlag(true);
199 [centralMgr scanForPeripheralsWithServices:uuids
200 options:@{CBCentralManagerScanOptionAllowDuplicatesKey:@YES}];
205 - (CAResult_t) CALEClientStopScanImpl{
206 OIC_LOG(DEBUG, TAG, "[CBCtrl] In - CALEClientStopScanImpl");
207 if ([centralMgrs count] == 0){
208 OIC_LOG(ERROR, TAG, "[CBCtrl] central manager is not available");
209 return CA_ADAPTER_NOT_ENABLED;
211 CALEClientSetScanFlag(false);
212 [centralMgr stopScan];
217 - (CAResult_t) CALEClientConnectImpl: (CBPeripheral *)peripheral{
218 if (peripheral == (id) [NSNull null]){
219 OIC_LOG(ERROR, TAG, "[CBCtrl] In - CALEClientConnectImpl: peripheral is null");
221 OIC_LOG(DEBUG, TAG, "[CBCtrl] In - CALEClientConnectImpl");
222 OIC_LOG_V(INFO, TAG, "peripheral name = %s", [[peripheral name] UTF8String]);
224 [centralMgr connectPeripheral: peripheral options:nil];
227 return CA_STATUS_FAILED;
230 - (CAResult_t) CALEClientDiscoverServices: (CBPeripheral *)peripheral{
231 if (peripheral == (id) [NSNull null]){
232 OIC_LOG(ERROR, TAG, "[CBCtrl] In - CALEClientDiscoverServices: peripheral is null");
234 OIC_LOG_V(DEBUG, TAG, "[CBCtrl] In - CALEClientDiscoverServices: %s",
235 [[cbPeripherals objectForKey:peripheral] UTF8String] );
236 OIC_LOG_V(INFO, TAG, "peripheral name = %s", [[peripheral name] UTF8String]);
238 [peripheral discoverServices:
239 @[[CBUUID UUIDWithString:[NSString stringWithUTF8String:OIC_GATT_SERVICE_UUID]]]];
242 return CA_STATUS_FAILED;
245 -(CAResult_t) CALEClientSetNotifyCharacteristic: (CBPeripheral *)peripheral
246 : (CBCharacteristic *)characteristic{
247 if ((peripheral == (id) [NSNull null]) || (characteristic == (id) [NSNull null])){
248 OIC_LOG(ERROR, TAG, "[CBCtrl] CALEClientSetNotifyCharacteristic: parameter is null");
250 OIC_LOG(DEBUG, TAG, "[CBCtrl] CALEClientSetNotifyCharacteristic");
251 [peripheral setNotifyValue:YES forCharacteristic:characteristic];
254 return CA_STATUS_FAILED;
257 - (void) CALEClientCancelPeripheralConnection: (CBPeripheral *)peripheral{
258 [centralMgr cancelPeripheralConnection:peripheral];
261 - (CAResult_t) CALEClientWriteValue:(CBPeripheral *)peripheral :(CBCharacteristic *)characteristic{
262 OIC_LOG(DEBUG, TAG, "[CBCtrl] CALEClientWriteRequest");
263 if ([characteristic.UUID isEqual: [CBUUID UUIDWithString:
264 [NSString stringWithUTF8String:OIC_GATT_CHARACTERISTIC_REQUEST_UUID]]]){
265 if (g_sendBuffer == nil || g_sendBuffer == NULL || [g_sendBuffer length] <= 0){
266 OIC_LOG(ERROR, TAG, "[CBCtrl] g_sendbuffer size is 0!!!");
267 return CA_STATUS_FAILED;
269 NSUInteger len = [g_sendBuffer length];
270 OIC_LOG_V(DEBUG, TAG, "[CBCtrl] write data: size(%lu)", len);
271 uint8_t *data = (uint8_t*)malloc(len);
272 memcpy(data, [g_sendBuffer bytes], len);
273 OIC_LOG_BUFFER(DEBUG, TAG, data, len);
275 [peripheral writeValue:g_sendBuffer
276 forCharacteristic:characteristic type:CBCharacteristicWriteWithResponse];
280 OIC_LOG(ERROR, TAG, "[CBCtrl] requestUUID is different");
282 return CA_STATUS_FAILED;
286 - (NSString *) CALEClientGetMAC : (NSData*) data{
288 if([data length] >= TV_ADV_DATA_MIN_LEN)
290 const unsigned char *bytes = (unsigned char *)data.bytes;
292 int b1 = (int)bytes[TV_ADV_COMPANY_ID_INDEX1];
293 int b2 = (int)bytes[TV_ADV_COMPANY_ID_INDEX2];
294 int b4 = (int)bytes[TV_ADV_SERVICE_TYPE_INDEX]; //service type Power ON/OFF
296 if((b1 == TV_ADV_COMPANY_ID1) && (b2 == TV_ADV_COMPANY_ID2)
297 && (b4 == TV_ADV_SERVICE_ID_POWER))
299 // samsung && power service
300 int b5 = (int)bytes[PON_ADV_DEVICE_TYPE_INDEX]; //devive type, 1 = TV, 3 = AV
301 int index_offset = (b5 == DEVICE_TYPE_TV)? 0 : PON_TV_AV_DIFF;
302 NSMutableString* mac_address = [NSMutableString stringWithFormat:@""];
303 [mac_address appendFormat:@"%02x:%02x:%02x:%02x:%02x:%02x",
304 (int)bytes[TV_ADV_PON_MAC_BYTE_1 + index_offset],
305 (int)bytes[TV_ADV_PON_MAC_BYTE_2 + index_offset],
306 (int)bytes[TV_ADV_PON_MAC_BYTE_3 + index_offset],
307 (int)bytes[TV_ADV_PON_MAC_BYTE_4 + index_offset],
308 (int)bytes[TV_ADV_PON_MAC_BYTE_5 + index_offset],
309 (int)bytes[TV_ADV_PON_MAC_BYTE_6 + index_offset]];
311 OIC_LOG_V(INFO, TAG, "TV Power on/off MAC = %s", [mac_address UTF8String]);
316 if((b1 == TV_ADV_COMPANY_ID1) && (b2 == TV_ADV_COMPANY_ID2)
317 && (b4 == TV_ADV_SERVICE_ID_OOB))
320 int b5 = (int)bytes[OOB_AV_ADV_DEVICE_TYPE_INDEX]; //devive type, 3 = AV // for TV this bit is in fact version number which is always 1 at this moment.
321 //at this moment, there is no definitive way to detect TV or AV from OOB advertisement.
322 NSMutableString* mac_address = [NSMutableString stringWithFormat:@""];
324 if(b5 == DEVICE_TYPE_AV)
326 [mac_address appendFormat:@"%02x:%02x:%02x:%02x:%02x:%02x",
327 (int)bytes[AV_ADV_OOB_MAC_BYTE_1],
328 (int)bytes[AV_ADV_OOB_MAC_BYTE_2],
329 (int)bytes[AV_ADV_OOB_MAC_BYTE_3],
330 (int)bytes[AV_ADV_OOB_MAC_BYTE_4],
331 (int)bytes[AV_ADV_OOB_MAC_BYTE_5],
332 (int)bytes[AV_ADV_OOB_MAC_BYTE_6]];
334 OIC_LOG_V(INFO, TAG, "AV OOB MAC = %s", [mac_address UTF8String]);
338 [mac_address appendFormat:@"%02x:%02x:%02x:%02x:%02x:%02x",
339 (int)bytes[TV_ADV_OOB_MAC_BYTE_1],
340 (int)bytes[TV_ADV_OOB_MAC_BYTE_2],
341 (int)bytes[TV_ADV_OOB_MAC_BYTE_3],
342 (int)bytes[TV_ADV_OOB_MAC_BYTE_4],
343 (int)bytes[TV_ADV_OOB_MAC_BYTE_5],
344 (int)bytes[TV_ADV_OOB_MAC_BYTE_6]];
346 OIC_LOG_V(INFO, TAG, "TV OOB MAC = %s", [mac_address UTF8String]);
353 NSString *Hex = [NSString stringWithFormat:@"0x%X", mac_add];
354 NSString *Hex_add = [Hex substringFromIndex:2];
355 NSString *first_add = [Hex_add substringToIndex:2];
356 NSString *second_add = [Hex_add substringFromIndex:2];
357 NSString *comma = @":";
360 MAC = [NSString stringWithString:mac_ref];
361 MAC = [MAC stringByAppendingString:first_add];
362 MAC = [MAC stringByAppendingString:comma];
363 MAC = [MAC stringByAppendingString:second_add];
365 OIC_LOG_V(INFO, TAG, "MAC: %s", [MAC UTF8String]);
367 if(mac_add == 65535){
376 - (NSString *) CALEGetAddressFromBTDevice: (CBPeripheral *)peripheral{
377 if (peripheral == (id) [NSNull null]){
378 OIC_LOG(ERROR, TAG, "[CBCtrl] In - CALEGetAddressFromBTDevice: peripheral is null");
380 return [cbPeripherals objectForKey: peripheral];
385 #pragma mark - CBCentralManagerDelegate
386 - (void)centralManagerDidUpdateState:(CBCentralManager *)central{
387 switch(central.state){
388 case CBCentralManagerStatePoweredOn:
389 OIC_LOG(DEBUG, TAG, "CBCentralManager update state --> Powered ON");
391 //if state callback is called before bt le client initialize done, wait signal.
392 if (!g_isStartedLEClient) {
393 OIC_LOG(INFO, TAG, "wait for finishing initialize..");
395 if (NULL == g_initializeMutex)
397 g_initializeMutex = oc_mutex_new();
398 if (NULL == g_initializeMutex)
400 OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
404 oc_mutex_lock(g_initializeMutex);
405 oc_cond_wait(g_initializeCond, g_initializeMutex);
406 oc_mutex_unlock(g_initializeMutex);
409 if (![centralMgrs containsObject: centralMgr]) {
410 centralMgr = central;
411 [centralMgrs addObject: centralMgr];
414 CALEClientSetFlagBTAdapter(true);
415 CALEClientNWStateChangeCallback(CALE_STATE_ON);
418 case CBCentralManagerStateResetting:
419 OIC_LOG(DEBUG, TAG, "CBCentralManager update state --> StateResetting");
421 case CBCentralManagerStateUnsupported:
422 case CBCentralManagerStateUnauthorized:
423 case CBCentralManagerStatePoweredOff:
425 OIC_LOG(DEBUG, TAG, "CBCentralManager update state --> Not Available");
426 CALEClientSetFlagBTAdapter(false);
427 CALEClientResetDeviceStateForAll();
429 CALEClientRemoveAllGattObjs();
435 dispatch_async(g_caManagerQueue, ^{
437 if(g_caManagerAdapterStateChangeCallback)
439 g_caManagerAdapterStateChangeCallback(central);
445 - (void)centralManager:(CBCentralManager *)central
446 didDiscoverPeripheral:(CBPeripheral *)peripheral
447 advertisementData:(NSDictionary<NSString*, id> *) advertisementData
448 RSSI:(NSNumber *) RSSI{
449 if (g_isStartedLEClient){
450 OIC_LOG_V(INFO, TAG, "[CBCtrl] didDiscoverPeripheral : peripheral name = %s", [[peripheral name] UTF8String]);
452 if([cbPeripherals objectForKey:peripheral] == nil && [self isValidUUID:advertisementData])
455 if ([cbPeripherals count] > 0){
456 OIC_LOG(DEBUG, TAG, "new peripheral");
457 [cbPeripherals setObject:[cbCentralIf CALEClientGetMAC:
458 [advertisementData objectForKey:
459 CBAdvertisementDataManufacturerDataKey]]
461 CALEClientAddScanDeviceToList(peripheral);
463 if (nil != cbCentralIf){
464 OIC_LOG(DEBUG, TAG, "1st discovered peripheral");
465 [cbPeripherals setObject:[cbCentralIf CALEClientGetMAC:
466 [advertisementData objectForKey:
467 CBAdvertisementDataManufacturerDataKey]]
469 CALEClientAddScanDeviceToList(peripheral);
474 OIC_LOG(DEBUG, TAG, "[CBCtrl] g_isStertedLEClient == false");
478 - (void)centralManager:(CBCentralManager*)central
479 didConnectPeripheral:(CBPeripheral *)peripheral {
480 peripheral.delegate = self;
482 const char *address = [[cbCentralIf CALEGetAddressFromBTDevice: peripheral] UTF8String];
483 OIC_LOG_V(DEBUG, TAG, "[CBCtrl] didConnectPeripheral : connected peripheral = %s", address);
485 CALEState_t* curState = CALEClientGetStateInfo(address);
486 if (curState == NULL || curState->connectedState != STATE_CONNECTED) {
487 CALEClientUpdateDeviceState(address, STATE_CONNECTED,
488 STATE_CHARACTER_UNSET,STATE_SEND_NONE);
490 [cbCentralIf CALEClientDiscoverServices: peripheral];
495 dispatch_async(g_caManagerQueue, ^{
497 if(g_caManagerConnectionCallback)
499 g_caManagerConnectionCallback(peripheral, address, true, nil);
506 - (void)centralManager: (CBCentralManager *)central
507 didFailToConnectPeripheral: (CBPeripheral *)peripheral
508 error:(NSError *)error{
510 OIC_LOG(ERROR, TAG, "[CBCtrl] didFailToConnectPeripheral & start scan");
512 OIC_LOG_V(ERROR, TAG, "didFailToConnectPeripheral, error desc = %s",
513 [[error localizedDescription] UTF8String]);
516 CAResult_t res = CALEClientStartScan();
517 if (CA_STATUS_OK != res){
518 OIC_LOG(ERROR, TAG, "start scan error");
519 CALEClientSendFinish(peripheral);
523 char *address = (char*)[[cbCentralIf CALEGetAddressFromBTDevice: peripheral] UTF8String];
525 CALEClientSendFinish(peripheral);
528 res = CALEClientRemoveDeviceState(address);
529 if (CA_STATUS_OK != res){
530 OIC_LOG(ERROR, TAG, "removedevicestate error");
531 CALEClientSendFinish(peripheral);
537 - (void)centralManager:(CBCentralManager *)central
538 didDisconnectPeripheral:(CBPeripheral *)peripheral
539 error:(NSError *)error{
542 OIC_LOG_V(ERROR, TAG, "didDisconnectPeripheral, error desc = %s",
543 [[error localizedDescription] UTF8String]);
546 NSString *nsAddr = [cbPeripherals objectForKey:peripheral];
547 const char *address = [nsAddr UTF8String];
550 CALEClientUpdateDeviceState(address, STATE_DISCONNECTED,
551 STATE_CHARACTER_UNSET,STATE_SEND_NONE);
552 OIC_LOG_V(DEBUG, TAG, "[CBCtrl] didDisconnectPeripheral : Peripheral address = %s", address);
556 dispatch_async(g_caManagerQueue, ^{
558 if(g_caManagerConnectionCallback)
560 g_caManagerConnectionCallback(peripheral, address, false, error);
565 CALEClientUpdateSendCnt();
567 if ( false == CALEClientGetAutoConnectFlag(address) )
569 CALEClientRemoveDeviceInScanDeviceList(nsAddr);
574 - (void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error {
576 OIC_LOG_V(ERROR, TAG, "didDiscoverServices, error desc = %s",
577 [[error localizedDescription] UTF8String]);
578 CALEClientSendFinish(peripheral);
581 const char *address = [CALEClientGetAddressFromGattObj(peripheral) UTF8String];
583 OIC_LOG_V(INFO, TAG, "found service for - %s %s", address, [[peripheral name] UTF8String]);
586 CALEClientSendFinish(peripheral);
590 if (!CALEClientIsSetCharacteristic(address)){
591 char *serviceUUID = NULL;
593 OIC_LOG_V(ERROR, TAG, "didDiscoverServices, #services = %lu",[peripheral.services count]);
595 if ([peripheral.services count] == 0) {
596 OIC_LOG(ERROR, TAG, "didDiscoverServices, no service found from peripheral");
597 CALEClientSendFinish(peripheral);
601 for (CBService *service in peripheral.services){
602 [cbServices setObject:service forKey:peripheral];
604 OIC_LOG(INFO, TAG, "discover characteristics");
606 [peripheral discoverCharacteristics:
607 @[[CBUUID UUIDWithString:
608 [NSString stringWithUTF8String:OIC_GATT_CHARACTERISTIC_REQUEST_UUID]],
609 [CBUUID UUIDWithString:
610 [NSString stringWithUTF8String:OIC_GATT_CHARACTERISTIC_RESPONSE_UUID]]]
615 OIC_LOG(DEBUG, TAG, "already set characteristics");
617 if ( g_sendBuffer != nil ) {
618 CAResult_t res = CALEClientWriteCharacteristic(peripheral);
619 if (CA_STATUS_OK != res){
620 OIC_LOG(ERROR, TAG, "CALEClientWriteCharacteristic failed");
621 CALEClientSendFinish(peripheral);
626 if(g_caManagerQueue){
627 OIC_LOG(DEBUG, TAG, "Call caManagerServiceDiscoveredCallback");
628 dispatch_async(g_caManagerQueue, ^{
630 if(g_caManagerServiceDiscoveredCallback)
632 g_caManagerServiceDiscoveredCallback(peripheral, address, error);
639 - (void)peripheral: (CBPeripheral *)peripheral
640 didDiscoverCharacteristicsForService: (CBService *)service
641 error:(NSError *)error{
644 OIC_LOG_V(ERROR, TAG, "[CBCtrl] didDiscoverCharacteristicsForService: error = %s",
645 [[error localizedDescription] UTF8String]);
648 OIC_LOG(DEBUG, TAG, "[CBCtrl] didDiscoverCharacteristicsForService");
649 const char *address = [[cbCentralIf CALEGetAddressFromBTDevice: peripheral] UTF8String];
651 for (CBCharacteristic *characteristic in service.characteristics){
652 if (!CALEClientIsSetCharacteristic(address)){
653 if ([characteristic.UUID isEqual:
654 [CBUUID UUIDWithString:
655 [NSString stringWithUTF8String:OIC_GATT_CHARACTERISTIC_RESPONSE_UUID]]]){
656 OIC_LOG_V(DEBUG, TAG, "[CBCtrl] find RESPONSE characteristic @%s", address);
657 [responseCharacs setObject:characteristic forKey:peripheral];
659 CAResult_t res = CALEClientSetCharacteristicNotification(peripheral,
661 if (CA_STATUS_OK != res){
662 OIC_LOG(ERROR, TAG, "CALEClientSetCharacteristicNotification has failed");
663 CALEClientSendFinish(peripheral);
668 if ([characteristic.UUID isEqual:
669 [CBUUID UUIDWithString:
670 [NSString stringWithUTF8String:OIC_GATT_CHARACTERISTIC_REQUEST_UUID]]]){
671 OIC_LOG_V(DEBUG, TAG, "[CBCtrl] find REQUEST characteristic @%s", address);
672 [requestCharacs setObject:characteristic forKey:peripheral];
674 CAResult_t res = CALEClientUpdateDeviceState(address, STATE_CONNECTED,
675 STATE_CHARACTER_SET, STATE_SEND_NONE);
677 if (CA_STATUS_OK != res){
678 OIC_LOG(ERROR, TAG, "CALEClientUpdataeDeviceState has failed");
679 CALEClientSendFinish(peripheral);
683 res = CALEClientAddGattobjToList(peripheral);
684 if (CA_STATUS_OK != res){
685 OIC_LOG(ERROR, TAG, "CALEClientAddGattobjToList has failed");
686 CALEClientSendFinish(peripheral);
690 if ( g_sendBuffer != nil ) {
691 res = CALEClientWriteCharacteristic(peripheral);
692 if (CA_STATUS_OK != res){
693 OIC_LOG(ERROR, TAG, "CALEClientWriteCharacteristic has failed");
694 CALEClientSendFinish(peripheral);
700 CAResult_t res = CALEClientWriteCharacteristic(peripheral);
701 if (CA_STATUS_OK != res){
702 OIC_LOG(ERROR, TAG, "CALEClientWriteCharacteristic has failed");
703 CALEClientSendFinish(peripheral);
712 OIC_LOG(DEBUG, TAG, "Call caManagerServiceDiscoveredCallback");
713 dispatch_async(g_caManagerQueue, ^{
715 if(g_caManagerServiceDiscoveredCallback)
717 g_caManagerServiceDiscoveredCallback(peripheral, address, error);
724 - (void)peripheral: (CBPeripheral *)peripheral didUpdateNotificationStateForCharacteristic
725 :(CBCharacteristic *)characteristic error:(NSError *)error{
727 OIC_LOG_V(ERROR, TAG, "didUpdateNotificationStateForCharacteristic error = %s",
728 [[error localizedDescription] UTF8String]);
730 OIC_LOG(INFO, TAG, "didUpdateNotificationStateForCharacteristic");
734 - (void)peripheral: (CBPeripheral *)peripheral
735 didUpdateValueForCharacteristic: (CBCharacteristic *)characteristic
736 error:(NSError *)error{
738 OIC_LOG_V(ERROR, TAG, "[CBCtrl] didUpdateValueForCharacteristic: ERROR = %s",
739 [[error localizedDescription] UTF8String]);
743 const char *address = [[cbPeripherals objectForKey: peripheral] UTF8String];
744 OIC_LOG_V(INFO, TAG, "[CBctrl] Update Value address: %s", address);
746 NSMutableData *nsData = [[NSMutableData alloc] init];
747 [nsData appendData:characteristic.value];
748 uint32_t len = [nsData length];
749 uint8_t *data = (uint8_t*) OICMalloc(len);
750 uint32_t sentLength = 0;
751 memcpy(data, (const uint8_t*)[nsData bytes], len);
753 OIC_LOG_BUFFER(DEBUG, TAG, data, len);
754 oc_mutex_lock(g_bleServerBDAddressMutex);
755 g_CABLEClientDataReceivedCallback(address, data, len, &sentLength);
756 oc_mutex_unlock(g_bleServerBDAddressMutex);
759 -(bool) isValidUUID:(NSDictionary<NSString*, id> *) dict
761 NSData* dat = [dict objectForKey:CBAdvertisementDataManufacturerDataKey];
762 if([dat length] >= TV_ADV_DATA_MIN_LEN)
764 const unsigned char *bytes = (unsigned char *)dat.bytes;
766 int b1 = (int)bytes[TV_ADV_COMPANY_ID_INDEX1];
767 int b2 = (int)bytes[TV_ADV_COMPANY_ID_INDEX2];
768 int b3 = (int)bytes[TV_ADV_VERSION_INDEX];
769 int b4 = (int)bytes[TV_ADV_SERVICE_TYPE_INDEX];
771 if((b1 == TV_ADV_COMPANY_ID1) && (b2 == TV_ADV_COMPANY_ID2) && (b3 == TV_ADV_VERSION) &&
772 (b4 == TV_ADV_SERVICE_ID_POWER || b4 == TV_ADV_SERVICE_ID_OOB))
775 int b6 = (int)bytes[TV_ADV_DEVICE_STATUS_INDEX];
776 if((b4 == TV_ADV_SERVICE_ID_POWER) && (b6 == TV_ADV_DEVICE_STATUS_UNKNOWN))
778 OIC_LOG(INFO, TAG, "discarded mode 4"); /*mac not available, dev status unknown
779 discard now to receive next adv_ind with status*/
783 int b5 = (int)bytes[TV_ADV_SCAN_RESP_LEN_INDEX];
784 int b20 = (int)bytes[TV_ADV_BD_ADDRTYPE_INDEX]; //address type
785 if(b4 == TV_ADV_SERVICE_ID_OOB &&
786 (b5 == TV_ADV_SCAN_RESP_LEN || b20 == TV_ADV_DEVICE_STATUS_UNKNOWN))
788 OIC_LOG_V(INFO, TAG, "discarded mode 9, b5 = %d", b5); /*mac not avilable
789 this is scan resp, discard now to receive next adv_ind*/
793 OIC_LOG_V(INFO, TAG, "Custom advertisement with mac, service type = %d", b4);
798 NSArray* arr = [dict objectForKey:CBAdvertisementDataServiceUUIDsKey];
801 for(CBUUID *serv in arr) {
802 if([serv isEqual:[CBUUID UUIDWithString:
803 [NSString stringWithUTF8String:OIC_GATT_SERVICE_UUID]]]){
805 OIC_LOG(INFO, TAG, "IoTivity Service Advertisement");
817 int ishexdigit(char var)
847 int isMAC(const char *address)
850 * Check if the provided MAC address is valid.
851 * 1. The length of MAC address should always be 17.
852 * 2. Hyphens are expected at positions {3, 6, 9, 12, 15}.
853 * 3. The rest characters should be simple xdigits.
855 int hyphens[5] = {3, 6, 9, 12, 15};
856 if (strlen(address) != 17)
858 return 0;//Oops. The lenth doesn't match.
861 for (int i = 0, counter = 0; i < 17; i ++)
863 char var = address[i];
864 if (i == hyphens[counter] - 1)// Check if a hyphen is expected here.
866 // Yep. We need a hyphen here.
869 return 0;// Oops. The character is not a hyphen.
873 counter++;// Move on to the next expected hyphen position.
878 // Nope. The character here should be a simple xdigit
879 if (ishexdigit(var) == 0)
881 return 0;// Oops. The current character is not a hyphen.
885 return 1;// Seen'em all!
888 CAResult_t CALEClientInitialize()
890 OIC_LOG(DEBUG, TAG, "IN - CALEClientInitialize");
892 CAResult_t ret = CALEClientInitGattMutexVaraibles();
893 if (CA_STATUS_OK != ret){
894 OIC_LOG(ERROR, TAG, "CALEClientInitGattMutexVaraibles has failed!");
895 CALEClientTerminateGattMutexVariables();
900 // init cond for initialize logic
901 if (g_initializeCond == NULL) {
902 g_initializeCond = oc_cond_new();
905 cbCentralIf = [[CBCentralIfClass alloc] init];
906 [cbCentralIf CALEClientCreateCentralManager];
908 g_deviceDescCond = oc_cond_new();
910 // init mutex for send logic
911 g_threadCond = oc_cond_new();
912 g_threadWriteCharacteristicCond = oc_cond_new();
913 g_deviceScanRetryDelayCond = oc_cond_new();
915 CALEClientCreateDeviceList();
917 g_isStartedLEClient = true;
919 oc_cond_signal(g_initializeCond);
924 void CALEClientTerminate()
926 OIC_LOG(DEBUG, TAG, "IN - CALEClientTerminate");
928 if (g_sendBuffer != nil){
932 CAResult_t ret = CALEClientRemoveAllDeviceState();
933 if (CA_STATUS_OK != ret)
935 OIC_LOG(ERROR, TAG, "CALEClientRemoveAllDeviceState has failed");
938 ret = CALEClientRemoveAllScanDevices();
939 if (CA_STATUS_OK != ret)
941 OIC_LOG(ERROR, TAG, "CALEClientRemoveAllScanDevices has failed");
944 ret = CALEClientRemoveAllGattObjs();
945 if (CA_STATUS_OK != ret)
947 OIC_LOG(ERROR, TAG, "CALEClientRemoveAllGattObjs has failed");
950 CALEClientSetScanFlag(false);
951 CALEClientSetSendFinishFlag(true);
953 CALEClientTerminateGattMutexVariables();
955 oc_cond_free(g_deviceDescCond);
956 oc_cond_free(g_threadCond);
957 oc_cond_free(g_threadWriteCharacteristicCond);
958 oc_cond_free(g_deviceScanRetryDelayCond);
959 oc_cond_free(g_initializeCond);
961 g_deviceDescCond = NULL;
963 g_threadWriteCharacteristicCond = NULL;
964 g_deviceScanRetryDelayCond = NULL;
965 g_initializeCond = NULL;
967 g_isSignalSetFlag = false;
969 centralMgr.delegate = nil;
970 if ([centralMgrs count] != 0) {
971 for (CBCentralManager *mgr in centralMgrs){
972 [centralMgrs removeObject:mgr];
976 [cbCentralIf release];
979 OIC_LOG(DEBUG, TAG, "OUT - CALEClientTerminate");
982 void CALEClientSendFinish(CBPeripheral *peripheral)
984 OIC_LOG(DEBUG, TAG, "CALEClientSendFinish");
988 CAResult_t res = CALEClientDisconnect(peripheral);
989 if (CA_STATUS_OK != res)
991 OIC_LOG(ERROR, TAG, "CALEClientDisconnect has failed");
994 CALEClientUpdateSendCnt();
997 CAResult_t CALEClientSendUnicastMessage(const char* address,
999 const uint32_t dataLen)
1001 OIC_LOG_V(DEBUG, TAG, "CALEClientSendUnicastMessage(%s, %p)", address, data);
1002 VERIFY_NON_NULL(address, TAG, "address is null");
1003 VERIFY_NON_NULL(data, TAG, "data is null");
1005 return CALEClientSendUnicastMessageImpl(address, data, dataLen);
1008 CAResult_t CALEClientSendMulticastMessage(const uint8_t* data,
1009 const uint32_t dataLen)
1011 OIC_LOG_V(DEBUG, TAG, "CALEClientSendMulticastMessage(%p)", data);
1012 VERIFY_NON_NULL(data, TAG, "data is null");
1014 CAResult_t ret = CALEClientSendMulticastMessageImpl(data, dataLen);
1015 if (CA_STATUS_OK != ret)
1017 OIC_LOG(ERROR, TAG, "CALEClientSendMulticastMessageImpl has failed");
1023 CAResult_t CALEClientStartUnicastServer(const char* address)
1025 OIC_LOG_V(DEBUG, TAG, "it is not needed in this platform (%s)", address);
1027 return CA_NOT_SUPPORTED;
1030 CAResult_t CALEClientStartMulticastServer()
1032 OIC_LOG(DEBUG, TAG, "it is not needed in this platform");
1034 return CA_NOT_SUPPORTED;
1037 void CALEClientStopUnicastServer()
1039 OIC_LOG(DEBUG, TAG, "CALEClientStopUnicastServer");
1042 void CALEClientStopMulticastServer()
1044 OIC_LOG(DEBUG, TAG, "CALEClientStopMulticastServer");
1047 void CALEClientSetCallback(CAPacketReceiveCallback callback)
1049 g_packetReceiveCallback = callback;
1052 void CALEClientSetCAManagerCallback(CAManagerAdapterStateChangeCallback adapterStateChangeCB,
1053 CAManagerConnectionCallback connectionCB,
1054 CAManagerServiceDiscoveredCallback serviceDiscoverdCB)
1056 VERIFY_NON_NULL_VOID(adapterStateChangeCB, TAG, "adapterStateChangeCB is null");
1057 VERIFY_NON_NULL_VOID(connectionCB, TAG, "connectionCB is null");
1058 VERIFY_NON_NULL_VOID(serviceDiscoverdCB, TAG, "serviceDiscoverdCB is null");
1060 if (!g_caManagerQueue) {
1061 g_caManagerQueue = dispatch_queue_create("com.caManager", DISPATCH_QUEUE_SERIAL);
1064 g_caManagerAdapterStateChangeCallback = adapterStateChangeCB;
1065 g_caManagerConnectionCallback = connectionCB;
1066 g_caManagerServiceDiscoveredCallback = serviceDiscoverdCB;
1070 void CASetBLEClientErrorHandleCallback(CABLEErrorHandleCallback callback)
1072 g_clientErrorCallback = callback;
1075 CAResult_t CALEClientIsThereScannedDevices(const char* address)
1079 OIC_LOG(ERROR, TAG, "CALEClientIsThereScannedDevices g_deviceList is null");
1080 return CA_STATUS_FAILED;
1083 if (0 == u_arraylist_length(g_deviceList) // multicast
1084 || (address && !CALEClientIsDeviceInScanDeviceList(address))) // unicast
1086 // Wait for LE peripherals to be discovered.
1088 // Number of times to wait for discovery to complete.
1089 static size_t const RETRIES = 7;
1091 static uint64_t const TIMEOUT =
1092 3 * MICROSECS_PER_SEC; // Microseconds
1094 bool devicesDiscovered = false;
1095 for (size_t i = 0; i < RETRIES; ++i)
1097 OIC_LOG(DEBUG, TAG, "waiting for target device");
1098 if (oc_cond_wait_for(g_deviceDescCond,
1100 TIMEOUT) == OC_WAIT_SUCCESS)
1102 oc_mutex_lock(g_deviceListMutex);
1103 size_t scannedDeviceLen = u_arraylist_length(g_deviceList);
1104 oc_mutex_unlock(g_deviceListMutex);
1106 if (0 < scannedDeviceLen)
1108 if (!address // multicast
1109 || (address && CALEClientIsDeviceInScanDeviceList(address))) // unicast
1111 devicesDiscovered = true;
1118 OIC_LOG(INFO, TAG, "waiting..");
1120 oc_mutex_lock(g_deviceScanRetryDelayMutex);
1121 if (oc_cond_wait_for(g_deviceScanRetryDelayCond,
1122 g_deviceScanRetryDelayMutex,
1123 MICROSECS_PER_SEC) == OC_WAIT_SUCCESS)
1125 OIC_LOG(INFO, TAG, "finish to waiting for target device");
1126 oc_mutex_unlock(g_deviceScanRetryDelayMutex);
1129 oc_mutex_unlock(g_deviceScanRetryDelayMutex);
1132 // checking whether a target device is found while waiting for time-out.
1133 if (CALEClientIsDeviceInScanDeviceList(address))
1135 devicesDiscovered = true;
1144 // time out for scanning devices
1145 if (!devicesDiscovered)
1147 return CA_STATUS_FAILED;
1151 return CA_STATUS_OK;
1155 CAResult_t CALEClientSendUnicastMessageImpl(const char* address,
1156 const uint8_t* data,
1157 const uint32_t dataLen)
1159 OIC_LOG_V(DEBUG, TAG, "CALEClientSendUnicastMessageImpl: \n address: %s, data: %p",
1161 VERIFY_NON_NULL(address, TAG, "address is null");
1162 VERIFY_NON_NULL(data, TAG, "data is null");
1164 oc_mutex_lock(g_threadSendMutex);
1166 CALEClientSetSendFinishFlag(false);
1168 CAResult_t ret = CALEClientIsThereScannedDevices(address);
1169 if (CA_STATUS_OK != ret)
1171 OIC_LOG(INFO, TAG, "there is no scanned device");
1175 const char *founded_address = NULL;
1176 uint32_t length = u_arraylist_length(g_deviceList);
1177 OIC_LOG_V(DEBUG, TAG, "g_deviceList : %d", length);
1178 int is_mac = isMAC(address);
1179 for (uint32_t index = 0; index < length; index++)
1181 CBPeripheral *peripheral = (CBPeripheral *)u_arraylist_get(g_deviceList, index);
1184 OIC_LOG(ERROR, TAG, "devicelist is empty");
1188 const char *setAddress = NULL;
1191 setAddress = [[[peripheral identifier] UUIDString] UTF8String];
1195 setAddress = [[cbCentralIf CALEGetAddressFromBTDevice: peripheral] UTF8String];
1200 OIC_LOG(ERROR, TAG, "setAddress is null");
1201 if(is_mac == 0) { continue; }
1202 else { goto error_exit; }
1205 OIC_LOG_V(DEBUG, TAG, "remote device address is %s, scanned peripheral = %s", setAddress,
1206 [[peripheral name] UTF8String]);
1208 if (!strcmp(setAddress, address))
1210 founded_address = [[cbCentralIf CALEGetAddressFromBTDevice: peripheral] UTF8String];
1212 // connect to gatt server
1213 OIC_LOG(DEBUG, TAG, "CALEClientSendUnicastMessageImpl --> stop scan");
1214 ret = CALEClientStopScan();
1215 if (CA_STATUS_OK != ret)
1217 OIC_LOG(ERROR, TAG, "CALEClientStopScan has failed");
1221 if (g_sendBuffer != nil ){
1224 g_sendBuffer = [NSData dataWithBytes:(const uint8_t*)data length:dataLen];
1226 OIC_LOG_V(DEBUG,TAG, "unicast send data size: %lu", [g_sendBuffer length]);
1227 OIC_LOG_BUFFER(DEBUG,TAG,data,dataLen);
1229 ret = CALEClientSendData(peripheral);
1230 if (CA_STATUS_OK != ret)
1232 OIC_LOG(ERROR, TAG, "CALEClientSendData in unicast is failed");
1236 OIC_LOG(INFO, TAG, "wake up");
1241 OIC_LOG(DEBUG, TAG, "connection routine is finished for unicast");
1243 // wait for finish to send data through "CALeGattServicesDiscoveredCallback"
1244 // if there is no connection state.
1245 oc_mutex_lock(g_threadMutex);
1246 if (!g_isFinishedSendData)
1248 OIC_LOG(DEBUG, TAG, "waiting send finish signal");
1249 oc_cond_wait(g_threadCond, g_threadMutex);
1250 OIC_LOG(DEBUG, TAG, "the data was sent");
1252 oc_mutex_unlock(g_threadMutex);
1254 // start LE Scan again
1255 ret = CALEClientStartScan();
1256 if (CA_STATUS_OK != ret)
1258 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
1259 oc_mutex_unlock(g_threadSendMutex);
1263 oc_mutex_unlock(g_threadSendMutex);
1264 OIC_LOG(INFO, TAG, "unicast - send logic has finished");
1265 return CALECheckSendState(founded_address);
1270 // start LE Scan again
1271 if (!CALEClientStartScan())
1273 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
1274 oc_mutex_unlock(g_threadSendMutex);
1275 return CA_STATUS_FAILED;
1278 if (g_clientErrorCallback)
1280 g_clientErrorCallback(address, data, dataLen, CA_SEND_FAILED);
1282 oc_mutex_unlock(g_threadSendMutex);
1283 return CA_SEND_FAILED;
1286 CAResult_t CALEClientSendMulticastMessageImpl(const uint8_t* data,
1287 const uint32_t dataLen)
1289 OIC_LOG_V(DEBUG, TAG, "CASendMulticastMessageImpl, send to, data: %p, %u", data, dataLen);
1290 VERIFY_NON_NULL(data, TAG, "data is null");
1294 OIC_LOG(ERROR, TAG, "g_deviceList is null");
1295 return CA_STATUS_FAILED;
1298 uint32_t length = 0;
1299 oc_cond waitCond = NULL;
1301 oc_mutex_lock(g_threadSendMutex);
1303 CALEClientSetSendFinishFlag(false);
1305 OIC_LOG(DEBUG, TAG, "set byteArray for data");
1307 CAResult_t res = CALEClientIsThereScannedDevices(NULL);
1308 if (CA_STATUS_OK != res)
1310 OIC_LOG(INFO, TAG, "there is no scanned device");
1314 // connect to gatt server
1315 OIC_LOG(DEBUG, TAG, "CALEClientSendMulticastMessageImpl --> stop scan");
1316 res = CALEClientStopScan();
1317 if (CA_STATUS_OK != res)
1319 OIC_LOG(ERROR, TAG, "CALEClientStopScan has failed");
1320 oc_mutex_unlock(g_threadSendMutex);
1323 length = u_arraylist_length(g_deviceList);
1324 g_targetCnt = length;
1326 if ( g_sendBuffer != nil ){
1330 g_sendBuffer = [NSData dataWithBytes:(const uint8_t*)data length:dataLen];
1332 OIC_LOG_V(DEBUG,TAG, "unicast send data size: %lu", [g_sendBuffer length]);
1333 OIC_LOG_BUFFER(DEBUG,TAG,data,dataLen);
1335 for (uint32_t index = 0; index < length; index++)
1337 OIC_LOG_V(DEBUG, TAG, "target cnt: %d/%d", index+1,length);
1338 CBPeripheral *peripheral = (CBPeripheral *)u_arraylist_get(g_deviceList, index);
1341 OIC_LOG(ERROR, TAG, "peripheral is not available");
1345 CALEClientSendData(peripheral);
1348 OIC_LOG(DEBUG, TAG, "connection routine is finished for multicast");
1350 // wait for finish to send data through "CALeGattServicesDiscoveredCallback"
1351 oc_mutex_lock(g_threadMutex);
1352 if (!g_isFinishedSendData)
1354 OIC_LOG(DEBUG, TAG, "waiting send finish signal");
1355 oc_cond_wait(g_threadCond, g_threadMutex);
1356 OIC_LOG(DEBUG, TAG, "the data was sent");
1358 oc_mutex_unlock(g_threadMutex);
1360 // start LE Scan again
1361 res = CALEClientStartScan();
1362 if (CA_STATUS_OK != res)
1364 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
1365 oc_mutex_unlock(g_threadSendMutex);
1369 oc_mutex_unlock(g_threadSendMutex);
1370 OIC_LOG(DEBUG, TAG, "OUT - CALEClientSendMulticastMessageImpl");
1371 return CA_STATUS_OK;
1374 res = CALEClientStartScan();
1375 if (CA_STATUS_OK != res)
1377 OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
1378 oc_mutex_unlock(g_threadSendMutex);
1382 oc_mutex_unlock(g_threadSendMutex);
1383 OIC_LOG(DEBUG, TAG, "OUT - CALEClientSendMulticastMessageImpl");
1384 return CA_SEND_FAILED;
1387 CAResult_t CALECheckSendState(const char* address)
1389 VERIFY_NON_NULL(address, TAG, "address is null");
1391 oc_mutex_lock(g_deviceStateListMutex);
1392 CALEState_t* state = CALEClientGetStateInfo(address);
1395 OIC_LOG(ERROR, TAG, "state is null");
1396 oc_mutex_unlock(g_deviceStateListMutex);
1397 return CA_SEND_FAILED;
1400 if (STATE_SEND_SUCCESS != state->sendState)
1402 OIC_LOG(ERROR, TAG, "sendstate is not STATE_SEND_SUCCESS");
1403 oc_mutex_unlock(g_deviceStateListMutex);
1404 return CA_SEND_FAILED;
1407 OIC_LOG(INFO, TAG, "sendstate is STATE_SEND_SUCCESS");
1408 oc_mutex_unlock(g_deviceStateListMutex);
1409 return CA_STATUS_OK;
1412 CAResult_t CALEClientSendData(CBPeripheral *peripheral)//, CBService *service)
1414 OIC_LOG(DEBUG, TAG, "IN - CALEClientSendData");
1416 // get BLE address from bluetooth device object.
1417 CALEState_t* state = NULL;
1418 char *address = (char*)[[cbCentralIf CALEGetAddressFromBTDevice: peripheral] UTF8String];
1421 OIC_LOG(ERROR, TAG, "address is not available");
1422 return CA_STATUS_FAILED;
1424 oc_mutex_lock(g_deviceStateListMutex);
1425 state = CALEClientGetStateInfo(address);
1426 oc_mutex_unlock(g_deviceStateListMutex);
1430 OIC_LOG(DEBUG, TAG, "state is empty..start to connect LE");
1432 // cancel previous connection request before connection
1433 // if there is gatt object in g_gattObjectList.
1435 // connection request
1436 CAResult_t ret = CALEClientConnect(peripheral, false);
1437 if (CA_STATUS_OK != ret){
1438 OIC_LOG(ERROR, TAG, "CALEClientConnect failed");
1444 if (STATE_CONNECTED == state->connectedState)
1446 OIC_LOG(INFO, TAG, "GATT has already connected");
1448 CBPeripheral *tPeripheral = CALEClientGetGattObjInList(address);
1451 OIC_LOG(ERROR, TAG, "CALEClientGetGattObjInList has failed");
1452 //return CA_STATUS_FAILED;
1456 CAResult_t ret = CALEClientWriteCharacteristic(peripheral);
1457 //CAResult_t ret = CALESetValueAndWriteCharacteristic(peripheral, service);
1458 if (CA_STATUS_OK != ret)
1460 OIC_LOG(ERROR, TAG, "WriteCharacteristic has failed");
1466 OIC_LOG(INFO, TAG, "STATE_DISCONNECTED - start to connect LE");
1468 // cancel previous connection request before connection
1469 // if there is gatt object in g_gattObjectList.
1471 OIC_LOG(DEBUG, TAG, "start to connect LE");
1472 CAResult_t ret = CALEClientConnect(peripheral, CALEClientGetAutoConnectFlag(address));
1473 if (CA_STATUS_OK != ret){
1474 OIC_LOG(ERROR, TAG, "CALEClientConnect failed");
1480 return CA_STATUS_OK;
1482 return CA_STATUS_OK;
1485 NSString *CALEClientGetAddressFromGattObj(CBPeripheral *peripheral)
1487 VERIFY_NON_NULL_RET(peripheral, TAG, "peripheral is null", NULL);
1489 return [cbPeripherals objectForKey: peripheral];
1495 CAResult_t CALEClientGattClose(CBPeripheral *peripheral)
1498 OIC_LOG(DEBUG, TAG, "Gatt Close");
1499 [cbCentralIf CALEClientCancelPeripheralConnection:peripheral];
1500 return CA_STATUS_OK;
1503 CAResult_t CALEClientStartScan()
1505 if (!CALEClientIsEnableBTAdapter())
1507 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1508 return CA_ADAPTER_NOT_ENABLED;
1511 if (!g_isStartedLEClient)
1513 OIC_LOG(ERROR, TAG, "LE client is not started");
1514 return CA_STATUS_FAILED;
1517 if (g_isStartedScan)
1519 OIC_LOG(INFO, TAG, "scanning is already started");
1520 return CA_STATUS_OK;
1523 OIC_LOG(DEBUG, TAG, "CALEClientStartScan");
1525 CAResult_t ret = CA_STATUS_OK;
1528 ret = CA_ADAPTER_NOT_ENABLE;
1530 ret = [cbCentralIf CALEClientStartScanImpl];
1532 if (CA_STATUS_OK != ret)
1534 if (CA_ADAPTER_NOT_ENABLED == ret)
1536 OIC_LOG(DEBUG, TAG, "Adapter is disabled");
1540 OIC_LOG(ERROR, TAG, "start scan has failed");
1547 CAResult_t CALEClientStopScan()
1549 if (!g_isStartedScan)
1551 OIC_LOG(INFO, TAG, "scanning is already stopped");
1552 return CA_STATUS_OK;
1555 CAResult_t ret = [cbCentralIf CALEClientStopScanImpl];
1556 if (CA_STATUS_OK != ret)
1558 if (CA_ADAPTER_NOT_ENABLED == ret)
1560 OIC_LOG(DEBUG, TAG, "Adapter is disabled");
1564 OIC_LOG(ERROR, TAG, "CALEClientStopScanImpl has failed");
1569 CALEClientSetScanFlag(false);
1575 void CALEClientSetScanFlag(bool flag)
1577 oc_mutex_lock(g_scanMutex);
1578 g_isStartedScan = flag;
1579 oc_mutex_unlock(g_scanMutex);
1582 CAResult_t CALEClientSetAutoConnectFlag(const char *address, bool flag)
1584 OIC_LOG(DEBUG, TAG, "IN - CALEClientSetAutoConnectFlag");
1586 oc_mutex_lock(g_deviceStateListMutex);
1590 OIC_LOG(ERROR, TAG, "address is not available");
1591 return CA_STATUS_FAILED;
1594 if (CALEClientIsDeviceInList(address))
1596 CALEState_t* curState = CALEClientGetStateInfo(address);
1599 OIC_LOG(ERROR, TAG, "curState is null");
1600 oc_mutex_unlock(g_deviceStateListMutex);
1601 return CA_STATUS_FAILED;
1603 OIC_LOG_V(INFO, TAG, "auto connect flag is set %d", flag);
1605 curState->autoConnectFlag = flag;
1608 oc_mutex_unlock(g_deviceStateListMutex);
1609 OIC_LOG(DEBUG, TAG, "OUT - CALEClientSetAutoConnectFlag");
1610 return CA_STATUS_OK;
1613 bool CALEClientGetAutoConnectFlag(const char *address)
1615 OIC_LOG(DEBUG, TAG, "IN - CALEClientGetAutoConnectFlag");
1617 oc_mutex_lock(g_deviceStateListMutex);
1621 OIC_LOG(ERROR, TAG, "address is not available");
1625 CALEState_t* curState = CALEClientGetStateInfo(address);
1628 OIC_LOG(INFO, TAG, "there is no information. auto connect flag is false");
1629 oc_mutex_unlock(g_deviceStateListMutex);
1632 OIC_LOG_V(INFO, TAG, "auto connect flag is %d", curState->autoConnectFlag);
1634 oc_mutex_unlock(g_deviceStateListMutex);
1636 OIC_LOG(DEBUG, TAG, "OUT - CALEClientGetAutoConnectFlag");
1637 return curState->autoConnectFlag;
1640 CAResult_t CALEClientConnect(CBPeripheral *peripheral, bool autoconnect)
1642 OIC_LOG(DEBUG, TAG, "CALEClientConnect");
1644 return [cbCentralIf CALEClientConnectImpl:peripheral];
1647 CAResult_t CALEClientDisconnect(CBPeripheral *peripheral)
1649 OIC_LOG(DEBUG, TAG, "GATT DISCONNECT");
1651 [cbCentralIf CALEClientCancelPeripheralConnection: peripheral];
1652 return CA_STATUS_OK;
1655 CAResult_t CALEClientConnectCancel(CBPeripheral *peripheral)
1657 OIC_LOG(DEBUG, TAG, "GATT CONNECT CENCEL");
1659 [cbCentralIf CALEClientCancelPeripheralConnection: peripheral];
1660 return CA_STATUS_OK;
1663 CAResult_t CALEClientDisconnectAll()
1665 OIC_LOG(DEBUG, TAG, "CALEClientDisconnectAll");
1667 if (!g_gattObjectList)
1669 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
1670 return CA_STATUS_OK;
1673 uint32_t length = u_arraylist_length(g_gattObjectList);
1674 OIC_LOG_V(DEBUG, TAG, "list length : %d", length);
1675 for (uint32_t index = 0; index < length; index++)
1677 OIC_LOG(DEBUG, TAG, "start CALEClientDisconnectAll");
1678 CBPeripheral *tPeripheral = (CBPeripheral *) u_arraylist_get(g_gattObjectList, index);
1680 CAResult_t res = CALEClientDisconnect(tPeripheral);
1681 if (CA_STATUS_OK != res)
1683 OIC_LOG(ERROR, TAG, "CALEClientDisconnect has failed");
1688 return CA_STATUS_OK;
1691 CAResult_t CALEClientDisconnectforAddress(const char *remote_address)
1693 OIC_LOG(DEBUG, TAG, "IN-CALEClientDisconnectforAddress");
1695 if (!g_gattObjectList)
1697 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
1698 return CA_STATUS_OK;
1701 uint32_t length = u_arraylist_length(g_gattObjectList);
1702 for (uint32_t index = 0; index < length; index++)
1704 CBPeripheral *tPeripheral = (CBPeripheral *) u_arraylist_get(g_gattObjectList, index);
1706 const char* setAddress = [[cbCentralIf CALEGetAddressFromBTDevice: tPeripheral] UTF8String];
1709 OIC_LOG(ERROR, TAG, "setAddress is null");
1710 return CA_STATUS_FAILED;
1713 if (!strcmp(remote_address, setAddress))
1715 CAResult_t res = CALEClientDisconnect(tPeripheral);
1716 if (CA_STATUS_OK != res)
1718 OIC_LOG(ERROR, TAG, "CALEClientDisconnect failed");
1719 return CA_STATUS_FAILED;
1723 OIC_LOG(DEBUG, TAG, "OUT-CALEClientDisconnectforAddress");
1724 return CA_STATUS_OK;
1727 CAResult_t CALEClientWriteCharacteristic(CBPeripheral *peripheral)
1729 OIC_LOG(DEBUG, TAG, "IN - CALEClientWriteCharacteristic");
1731 CBService *service = [cbServices objectForKey:peripheral];
1732 if (service == NULL){
1733 OIC_LOG(ERROR, TAG, "can't find service obj");
1734 return CA_STATUS_FAILED;
1736 CBCharacteristic *requestCharacteristic = [requestCharacs objectForKey:peripheral];
1737 if (requestCharacteristic == NULL){
1738 OIC_LOG(ERROR, TAG, "can't find request characteristic obj");
1739 return CA_STATUS_FAILED;
1741 CAResult_t ret = CALEClientWriteCharacteristicImpl(peripheral, requestCharacteristic);
1742 if (CA_STATUS_OK != ret){
1743 CALEClientSendFinish(peripheral);
1744 return CA_STATUS_FAILED;
1749 OIC_LOG(DEBUG, TAG, "OUT - CALEClientWriteCharacteristic");
1750 return CA_STATUS_OK;
1753 CAResult_t CALEClientWriteCharacteristicImpl(CBPeripheral *peripheral,
1754 CBCharacteristic *requestCharc)
1756 OIC_LOG(DEBUG, TAG, "WRITE GATT CHARACTERISTIC");
1758 if (!CALEClientIsEnableBTAdapter())
1760 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1761 return CA_STATUS_FAILED;
1764 CAResult_t ret = [cbCentralIf CALEClientWriteValue: peripheral: requestCharc];
1766 const char *address = [CALEClientGetAddressFromGattObj(peripheral) UTF8String];
1767 if (CA_STATUS_OK != ret){
1768 OIC_LOG(ERROR, TAG, "write characteristic failed");
1769 CALEClientUpdateDeviceState(address, STATE_CONNECTED, STATE_CHARACTER_SET,
1772 CALEClientSendFinish(peripheral);
1773 return CA_STATUS_FAILED;
1775 OIC_LOG(DEBUG, TAG, "writeCharacteristic is called successfully");
1776 CALEClientUpdateDeviceState(address, STATE_CONNECTED, STATE_CHARACTER_SET,
1777 STATE_SEND_SUCCESS);
1778 CALEClientUpdateSendCnt();
1781 return CA_STATUS_OK;
1784 CAResult_t CALEClientSetCharacteristicNotification(CBPeripheral *peripheral,
1785 CBCharacteristic *responsCharc)
1787 if (!CALEClientIsEnableBTAdapter())
1789 OIC_LOG(INFO, TAG, "BT adapter is not enabled");
1790 return CA_ADAPTER_NOT_ENABLED;
1793 [cbCentralIf CALEClientSetNotifyCharacteristic: peripheral: responsCharc];
1795 return CA_STATUS_OK;
1798 void CALEClientCreateScanDeviceList()
1800 OIC_LOG(DEBUG, TAG, "CALEClientCreateScanDeviceList");
1802 oc_mutex_lock(g_deviceListMutex);
1803 // create new object array
1804 if (g_deviceList == NULL)
1806 OIC_LOG(DEBUG, TAG, "Create device list");
1808 g_deviceList = u_arraylist_create();
1810 oc_mutex_unlock(g_deviceListMutex);
1813 CAResult_t CALEClientAddScanDeviceToList(CBPeripheral *peripheral)
1815 oc_mutex_lock(g_deviceListMutex);
1819 OIC_LOG(ERROR, TAG, "gdevice_list is null");
1821 CALEClientSetScanFlag(false);
1822 OIC_LOG(DEBUG, TAG, "CALEClientAddScanDeviceToList --> stop scan");
1823 if(CA_STATUS_OK != CALEClientStopScan())
1825 OIC_LOG(ERROR, TAG, "CALEClientStopScan has failed");
1828 oc_mutex_unlock(g_deviceListMutex);
1829 return CA_STATUS_FAILED;
1832 const char *remoteAddress = [[cbCentralIf CALEGetAddressFromBTDevice: peripheral] UTF8String];
1835 OIC_LOG(ERROR, TAG, "remoteAddress is null");
1836 oc_mutex_unlock(g_deviceListMutex);
1837 return CA_STATUS_FAILED;
1840 if (!CALEClientIsDeviceInScanDeviceList(remoteAddress))
1842 u_arraylist_add(g_deviceList, peripheral);
1843 oc_cond_signal(g_deviceDescCond);
1844 OIC_LOG_V(DEBUG, TAG, "Added this BT Device[%s] in the List", remoteAddress);
1847 oc_mutex_unlock(g_deviceListMutex);
1849 return CA_STATUS_OK;
1852 bool CALEClientIsDeviceInScanDeviceList(const char* remoteAddress)
1854 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", true);
1858 OIC_LOG(DEBUG, TAG, "g_deviceList is null");
1862 uint32_t length = u_arraylist_length(g_deviceList);
1863 int is_mac = isMAC(remoteAddress);
1864 for (uint32_t index = 0; index < length; index++)
1866 CBPeripheral *tPeripheral = (CBPeripheral *) u_arraylist_get(g_deviceList, index);
1870 const char* setAddress = [[cbCentralIf CALEGetAddressFromBTDevice:
1871 tPeripheral] UTF8String];
1873 if (!strcmp(remoteAddress, setAddress))
1880 OIC_LOG(DEBUG, TAG, "this is uuid unicast!");
1881 const char* localUuid = [[[tPeripheral identifier] UUIDString] UTF8String];
1883 if(localUuid == NULL)
1888 if(!strcmp(remoteAddress, localUuid))
1890 OIC_LOG(DEBUG, TAG, "find same one!!!!");
1896 OIC_LOG(DEBUG, TAG, "there are no the device in list. we can add");
1901 CAResult_t CALEClientRemoveAllScanDevices()
1903 OIC_LOG(DEBUG, TAG, "CALEClientRemoveAllScanDevices");
1905 oc_mutex_lock(g_deviceListMutex);
1909 OIC_LOG(ERROR, TAG, "g_deviceList is null");
1910 oc_mutex_unlock(g_deviceListMutex);
1911 return CA_STATUS_FAILED;
1914 uint32_t length = u_arraylist_length(g_deviceList);
1915 for (uint32_t index = 0; index < length; index++)
1917 CBPeripheral *tPeripheral = (CBPeripheral *) u_arraylist_get(g_deviceList, 0);
1918 tPeripheral.delegate = nil;
1919 [cbPeripherals removeObjectForKey: tPeripheral];
1920 u_arraylist_remove(g_deviceList, 0);
1923 OICFree(g_deviceList);
1924 g_deviceList = NULL;
1926 oc_mutex_unlock(g_deviceListMutex);
1927 return CA_STATUS_OK;
1930 CAResult_t CALEClientRemoveDeviceInScanDeviceList(NSString *address)
1932 OIC_LOG(DEBUG, TAG, "CALEClientRemoveDeviceInScanDeviceList");
1933 VERIFY_NON_NULL(address, TAG, "address is null");
1934 if (nil == address){
1935 OIC_LOG(INFO, TAG, "CALEClientRemoveDeviceInScanDeviceList address == nil");
1936 return CA_STATUS_FAILED;
1939 oc_mutex_lock(g_deviceListMutex);
1943 OIC_LOG(ERROR, TAG, "g_deviceList is null");
1944 oc_mutex_unlock(g_deviceListMutex);
1945 return CA_STATUS_FAILED;
1948 uint32_t length = u_arraylist_length(g_deviceList);
1949 for (uint32_t index = 0; index < length; index++)
1951 CBPeripheral *tPeripheral = (CBPeripheral *) u_arraylist_get(g_deviceList, index);
1953 NSString *setAddress = [cbCentralIf CALEGetAddressFromBTDevice: tPeripheral];
1955 OIC_LOG_V(DEBUG, TAG, "removedeviceinscandevicelist -address: %s-setaddr: %s",
1956 [address UTF8String], [setAddress UTF8String]);
1958 if ([address isEqualToString:setAddress])
1960 [cbPeripherals removeObjectForKey: tPeripheral];
1961 if (NULL == u_arraylist_remove(g_deviceList, index))
1963 OIC_LOG(ERROR, TAG, "List removal failed.");
1964 oc_mutex_unlock(g_deviceListMutex);
1965 return CA_STATUS_FAILED;
1967 oc_mutex_unlock(g_deviceListMutex);
1968 return CA_STATUS_OK;
1972 oc_mutex_unlock(g_deviceListMutex);
1973 OIC_LOG(DEBUG, TAG, "There are no object in the device list");
1975 return CA_STATUS_OK;
1982 CAResult_t CALEClientAddGattobjToList(CBPeripheral *peripheral)
1984 OIC_LOG(INFO, TAG, "CALEClientAddGattobjToList");
1986 oc_mutex_lock(g_gattObjectMutex);
1988 if (!g_gattObjectList)
1990 OIC_LOG(ERROR, TAG, "g_gattObjectList is not available");
1991 oc_mutex_unlock(g_gattObjectMutex);
1992 return CA_STATUS_FAILED;
1995 NSString *remoteAddress = CALEClientGetAddressFromGattObj(peripheral);
1996 if (remoteAddress == nil || [remoteAddress isEqualToString:@"<null>"]
1997 || [remoteAddress isEqualToString:@"null"] || remoteAddress == (id)[NSNull null]
1998 || [[remoteAddress stringByTrimmingCharactersInSet:
1999 [NSCharacterSet whitespaceAndNewlineCharacterSet]] isEqualToString:@""]){
2000 OIC_LOG(ERROR, TAG, "remoteAddress is null");
2001 oc_mutex_unlock(g_gattObjectMutex);
2002 return CA_STATUS_FAILED;
2005 const char *remoteAddr = [remoteAddress UTF8String];
2006 OIC_LOG_V(INFO, TAG, "remote address : %s", remoteAddr);
2007 if (!CALEClientIsGattObjInList(remoteAddr))
2009 u_arraylist_add(g_gattObjectList, peripheral);
2010 OIC_LOG(INFO, TAG, "Set GATT Object to Array as Element");
2013 oc_mutex_unlock(g_gattObjectMutex);
2014 return CA_STATUS_OK;
2017 bool CALEClientIsGattObjInList(const char* remoteAddress)
2019 OIC_LOG(DEBUG, TAG, "CALEClientIsGattObjInList");
2021 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", true);
2023 uint32_t length = u_arraylist_length(g_gattObjectList);
2024 for (uint32_t index = 0; index < length; index++)
2027 CBPeripheral *tPeripheral = (CBPeripheral *) u_arraylist_get(g_gattObjectList, index);
2030 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2034 NSString *setAddress = CALEClientGetAddressFromGattObj(tPeripheral);
2035 if (setAddress == nil || [setAddress isEqualToString:@"<null>"]
2036 || [setAddress isEqualToString:@"null"] || setAddress == (id)[NSNull null]
2037 || [[setAddress stringByTrimmingCharactersInSet:
2038 [NSCharacterSet whitespaceAndNewlineCharacterSet]] isEqualToString:@""]){
2039 OIC_LOG(ERROR, TAG, "setAddress is null");
2043 const char* setAddr = [setAddress UTF8String];
2046 OIC_LOG(ERROR, TAG, "setAddress is null");
2050 if (!strcmp(remoteAddress, setAddr))
2052 OIC_LOG(DEBUG, TAG, "the device is already set");
2061 OIC_LOG(DEBUG, TAG, "There are no GATT object in list. it can be added");
2065 CBPeripheral *CALEClientGetGattObjInList(const char* remoteAddress)
2067 OIC_LOG(DEBUG, TAG, "CALEClientGetGattObjInList");
2068 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", NULL);
2070 oc_mutex_lock(g_gattObjectMutex);
2071 uint32_t length = u_arraylist_length(g_gattObjectList);
2072 for (uint32_t index = 0; index < length; index++)
2074 CBPeripheral *tPeripheral = (CBPeripheral *) u_arraylist_get(g_gattObjectList, index);
2077 OIC_LOG(ERROR, TAG, "peripheral is null");
2078 oc_mutex_unlock(g_gattObjectMutex);
2082 NSString *setAddress = CALEClientGetAddressFromGattObj(tPeripheral);
2083 if (setAddress == nil || [setAddress isEqualToString:@"<null>"]
2084 || [setAddress isEqualToString:@"null"] || setAddress == (id)[NSNull null]
2085 || [[setAddress stringByTrimmingCharactersInSet:
2086 [NSCharacterSet whitespaceAndNewlineCharacterSet]] isEqualToString:@""]){
2087 OIC_LOG(ERROR, TAG, "setAddress is null");
2088 oc_mutex_unlock(g_gattObjectMutex);
2092 const char* setAddr = [setAddress UTF8String];
2095 OIC_LOG(ERROR, TAG, "setAddress is null");
2096 oc_mutex_unlock(g_gattObjectMutex);
2100 if (!strcmp(remoteAddress, setAddr))
2102 OIC_LOG(DEBUG, TAG, "the device is already set");
2103 oc_mutex_unlock(g_gattObjectMutex);
2108 oc_mutex_unlock(g_gattObjectMutex);
2109 OIC_LOG(DEBUG, TAG, "There are no the gatt object in list");
2113 CAResult_t CALEClientRemoveAllGattObjs()
2115 OIC_LOG(DEBUG, TAG, "CALEClientRemoveAllGattObjs");
2117 oc_mutex_lock(g_gattObjectMutex);
2118 if (!g_gattObjectList)
2120 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
2121 oc_mutex_unlock(g_gattObjectMutex);
2122 return CA_STATUS_OK;
2125 uint32_t length = u_arraylist_length(g_gattObjectList);
2126 for (uint32_t index = 0; index < length; index++)
2128 CBPeripheral *tPeripheral = (CBPeripheral *) u_arraylist_get(g_gattObjectList, index);
2131 OIC_LOG(ERROR, TAG, "tPeripheral is null");
2134 if (NULL == u_arraylist_remove(g_gattObjectList, index))
2136 OIC_LOG(ERROR, TAG, "List removal failed.");
2137 oc_mutex_unlock(g_gattObjectMutex);
2138 return CA_STATUS_FAILED;
2143 OICFree(g_gattObjectList);
2144 g_gattObjectList = NULL;
2145 OIC_LOG(INFO, TAG, "g_gattObjectList is removed");
2146 oc_mutex_unlock(g_gattObjectMutex);
2147 return CA_STATUS_OK;
2150 CAResult_t CALEClientRemoveGattObj(CBPeripheral *peripheral)
2152 OIC_LOG(DEBUG, TAG, "CALEClientRemoveGattObj");
2154 oc_mutex_lock(g_gattObjectMutex);
2155 if (!g_gattObjectList)
2157 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
2158 oc_mutex_unlock(g_gattObjectMutex);
2159 return CA_STATUS_OK;
2162 uint32_t length = u_arraylist_length(g_gattObjectList);
2163 for (uint32_t index = 0; index < length; index++)
2165 CBPeripheral *tPeripheral = (CBPeripheral *) u_arraylist_get(g_gattObjectList, index);
2166 if ([peripheral isEqual:tPeripheral]){
2167 if (NULL == u_arraylist_remove(g_gattObjectList, index))
2169 OIC_LOG(ERROR, TAG, "List removal failed.");
2170 oc_mutex_unlock(g_gattObjectMutex);
2171 return CA_STATUS_FAILED;
2176 oc_mutex_unlock(g_gattObjectMutex);
2177 OIC_LOG(DEBUG, TAG, "there are no target object");
2178 return CA_STATUS_OK;
2181 CAResult_t CALEClientRemoveGattObjForAddr(const char* remoteAddr)
2183 OIC_LOG(DEBUG, TAG, "CALEClientRemoveGattObjForAddr");
2184 VERIFY_NON_NULL(remoteAddr, TAG, "addr is null");
2186 oc_mutex_lock(g_gattObjectMutex);
2187 if (!g_gattObjectList)
2189 OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
2190 oc_mutex_unlock(g_gattObjectMutex);
2191 return CA_STATUS_OK;
2194 uint32_t length = u_arraylist_length(g_gattObjectList);
2195 for (uint32_t index = 0; index < length; index++)
2197 CBPeripheral *tPeripheral = (CBPeripheral *) u_arraylist_get(g_gattObjectList, index);
2200 OIC_LOG(ERROR, TAG, "tPeripheral is null");
2201 oc_mutex_unlock(g_gattObjectMutex);
2202 return CA_STATUS_FAILED;
2205 NSString *setAddress = CALEClientGetAddressFromGattObj(tPeripheral);
2206 if (setAddress == nil || [setAddress isEqualToString:@"<null>"]
2207 || [setAddress isEqualToString:@"null"] || setAddress == (id)[NSNull null]
2208 || [[setAddress stringByTrimmingCharactersInSet:
2209 [NSCharacterSet whitespaceAndNewlineCharacterSet]] isEqualToString:@""]){
2210 OIC_LOG(ERROR, TAG, "setAddress is null");
2211 oc_mutex_unlock(g_gattObjectMutex);
2212 return CA_STATUS_FAILED;
2215 const char* setAddr = [setAddress UTF8String];
2218 OIC_LOG(ERROR, TAG, "setAddress is null");
2219 oc_mutex_unlock(g_gattObjectMutex);
2220 return CA_STATUS_FAILED;
2223 if (!strcmp(setAddr, remoteAddr))
2225 OIC_LOG_V(DEBUG, TAG, "remove object : %s", remoteAddr);
2226 if (NULL == u_arraylist_remove(g_gattObjectList, index))
2228 OIC_LOG(ERROR, TAG, "List removal failed.");
2229 oc_mutex_unlock(g_gattObjectMutex);
2230 return CA_STATUS_FAILED;
2232 oc_mutex_unlock(g_gattObjectMutex);
2233 return CA_STATUS_OK;
2237 oc_mutex_unlock(g_gattObjectMutex);
2238 OIC_LOG(DEBUG, TAG, "there are no target object");
2239 return CA_STATUS_FAILED;
2246 CAResult_t CALEClientUpdateDeviceState(const char* address,
2247 uint32_t connectedState,
2248 uint16_t notificationState,
2251 VERIFY_NON_NULL(address, TAG, "address is null");
2253 CALEState_t *newstate = (CALEState_t*) OICCalloc(1, sizeof(*newstate));
2256 OIC_LOG(ERROR, TAG, "out of memory");
2257 return CA_MEMORY_ALLOC_FAILED;
2260 if (strlen(address) > CA_MACADDR_SIZE)
2262 OIC_LOG(ERROR, TAG, "address is not proper");
2264 return CA_STATUS_FAILED;
2267 OICStrcpy(newstate->address, sizeof(newstate->address), address);
2268 newstate->connectedState = connectedState;
2269 newstate->notificationState = notificationState;
2270 newstate->sendState = sendState;
2271 return CALEClientAddDeviceStateToList(newstate);
2274 CAResult_t CALEClientAddDeviceStateToList(CALEState_t* state)
2276 VERIFY_NON_NULL(state, TAG, "state is null");
2278 oc_mutex_lock(g_deviceStateListMutex);
2280 if (!g_deviceStateList)
2282 OIC_LOG(ERROR, TAG, "gdevice_list is null");
2283 oc_mutex_unlock(g_deviceStateListMutex);
2284 return CA_STATUS_FAILED;
2287 if (CALEClientIsDeviceInList(state->address))
2289 CALEState_t* curState = CALEClientGetStateInfo(state->address);
2292 OIC_LOG(ERROR, TAG, "curState is null");
2293 oc_mutex_unlock(g_deviceStateListMutex);
2294 return CA_STATUS_FAILED;
2297 if (STATE_CHARACTER_NO_CHANGE == state->notificationState)
2299 state->notificationState = curState->notificationState;
2301 state->autoConnectFlag = curState->autoConnectFlag;
2303 // delete previous state for update new state
2304 CAResult_t res = CALEClientRemoveDeviceState(state->address);
2305 if (CA_STATUS_OK != res)
2307 OIC_LOG(ERROR, TAG, "CALEClientRemoveDeviceState has failed");
2308 oc_mutex_unlock(g_deviceStateListMutex);
2312 u_arraylist_add(g_deviceStateList, state); // update new state
2313 OIC_LOG_V(INFO, TAG, "Set State Info to List : %d, %d, %s, %d",
2314 state->connectedState, state->notificationState,
2315 state->address, state->autoConnectFlag);
2317 oc_mutex_unlock(g_deviceStateListMutex);
2318 return CA_STATUS_OK;
2321 bool CALEClientIsDeviceInList(const char* remoteAddress)
2323 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", false);
2325 if (!g_deviceStateList)
2327 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
2331 uint32_t length = u_arraylist_length(g_deviceStateList);
2332 for (uint32_t index = 0; index < length; index++)
2334 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
2337 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
2341 if (!strcmp(remoteAddress, state->address))
2343 OIC_LOG(DEBUG, TAG, "the device is already set");
2348 OIC_LOG(DEBUG, TAG, "there are no the device in list.");
2352 CAResult_t CALEClientRemoveAllDeviceState()
2354 OIC_LOG(DEBUG, TAG, "CALEClientRemoveAllDeviceState");
2356 oc_mutex_lock(g_deviceStateListMutex);
2357 if (!g_deviceStateList)
2359 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
2360 oc_mutex_unlock(g_deviceStateListMutex);
2361 return CA_STATUS_FAILED;
2364 uint32_t length = u_arraylist_length(g_deviceStateList);
2365 for (uint32_t index = 0; index < length; index++)
2367 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
2370 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2373 u_arraylist_remove(g_deviceStateList, index);
2378 OICFree(g_deviceStateList);
2379 g_deviceStateList = NULL;
2380 oc_mutex_unlock(g_deviceStateListMutex);
2382 return CA_STATUS_OK;
2385 CAResult_t CALEClientResetDeviceStateForAll()
2387 OIC_LOG(DEBUG, TAG, "CALEClientResetDeviceStateForAll");
2389 oc_mutex_lock(g_deviceStateListMutex);
2390 if (!g_deviceStateList)
2392 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
2393 oc_mutex_unlock(g_deviceStateListMutex);
2394 return CA_STATUS_FAILED;
2397 size_t length = u_arraylist_length(g_deviceStateList);
2398 for (size_t index = 0; index < length; index++)
2400 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
2403 OIC_LOG(ERROR, TAG, "jarrayObj is null");
2407 // autoConnectFlag value will be not changed,
2408 // since it has reset only termination case.
2409 state->connectedState = STATE_DISCONNECTED;
2410 state->notificationState = STATE_CHARACTER_UNSET;
2411 state->sendState = STATE_SEND_NONE;
2413 oc_mutex_unlock(g_deviceStateListMutex);
2415 return CA_STATUS_OK;
2418 CAResult_t CALEClientRemoveDeviceState(const char* remoteAddress)
2420 OIC_LOG(DEBUG, TAG, "CALEClientRemoveDeviceState");
2421 VERIFY_NON_NULL(remoteAddress, TAG, "remoteAddress is null");
2423 if (!g_deviceStateList)
2425 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
2426 return CA_STATUS_FAILED;
2429 uint32_t length = u_arraylist_length(g_deviceStateList);
2430 for (uint32_t index = 0; index < length; index++)
2432 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
2435 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
2439 if (!strcmp(state->address, remoteAddress))
2441 OIC_LOG_V(DEBUG, TAG, "remove state : %s", state->address);
2443 CALEState_t* targetState = (CALEState_t*)u_arraylist_remove(g_deviceStateList,
2445 if (NULL == targetState)
2447 OIC_LOG(ERROR, TAG, "List removal failed.");
2448 return CA_STATUS_FAILED;
2451 OICFree(targetState);
2452 return CA_STATUS_OK;
2456 return CA_STATUS_OK;
2459 CALEState_t* CALEClientGetStateInfo(const char* remoteAddress)
2461 OIC_LOG(DEBUG, TAG, "CALEClientGetStateInfo");
2462 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", NULL);
2464 if (!g_deviceStateList)
2466 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
2470 uint32_t length = u_arraylist_length(g_deviceStateList);
2471 OIC_LOG_V(DEBUG, TAG, "CALEClientGetStateInfo : %d", length);
2473 for (uint32_t index = 0; index < length; index++)
2475 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
2478 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
2482 OIC_LOG_V(DEBUG, TAG, "target address : %s", remoteAddress);
2483 OIC_LOG_V(DEBUG, TAG, "state address : %s", state->address);
2485 if (!strcmp(state->address, remoteAddress))
2487 OIC_LOG_V(DEBUG, TAG, "get state : %s", remoteAddress);
2494 bool CALEClientIsConnectedDevice(const char* remoteAddress)
2496 OIC_LOG(DEBUG, TAG, "CALEClientIsConnectedDevice");
2497 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", false);
2499 oc_mutex_lock(g_deviceStateListMutex);
2500 if (!g_deviceStateList)
2502 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
2503 oc_mutex_unlock(g_deviceStateListMutex);
2507 uint32_t length = u_arraylist_length(g_deviceStateList);
2508 for (uint32_t index = 0; index < length; index++)
2510 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
2513 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
2517 if (!strcmp(state->address, remoteAddress))
2519 OIC_LOG(DEBUG, TAG, "check whether it is connected or not");
2521 if (STATE_CONNECTED == state->connectedState)
2523 oc_mutex_unlock(g_deviceStateListMutex);
2528 oc_mutex_unlock(g_deviceStateListMutex);
2533 oc_mutex_unlock(g_deviceStateListMutex);
2537 bool CALEClientIsSetCharacteristic(const char* remoteAddress)//, const char* serviceId)
2539 OIC_LOG(DEBUG, TAG, "CALEClientIsSetCharacteristic");
2540 VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", false);
2542 oc_mutex_lock(g_deviceStateListMutex);
2543 if (!g_deviceStateList)
2545 OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
2546 oc_mutex_unlock(g_deviceStateListMutex);
2550 uint32_t length = u_arraylist_length(g_deviceStateList);
2551 for (uint32_t index = 0; index < length; index++)
2553 CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
2556 OIC_LOG(ERROR, TAG, "CALEState_t object is null");
2560 if (!strcmp(state->address, remoteAddress))
2562 OIC_LOG_V(DEBUG, TAG, "check whether it was set or not:%d", state->notificationState);
2564 if (STATE_CHARACTER_SET == state->notificationState)
2566 oc_mutex_unlock(g_deviceStateListMutex);
2567 OIC_LOG(DEBUG, TAG, "state->notificationState was set");
2572 oc_mutex_unlock(g_deviceStateListMutex);
2573 OIC_LOG(DEBUG, TAG, "state->notificationState was not set");
2579 oc_mutex_unlock(g_deviceStateListMutex);
2583 void CALEClientCreateDeviceList()
2585 OIC_LOG(DEBUG, TAG, "CALEClientCreateDeviceList");
2587 // create new object array
2588 if (!g_gattObjectList)
2590 OIC_LOG(DEBUG, TAG, "Create g_gattObjectList");
2592 g_gattObjectList = u_arraylist_create();
2595 if (!g_deviceStateList)
2597 OIC_LOG(DEBUG, TAG, "Create g_deviceStateList");
2599 g_deviceStateList = u_arraylist_create();
2604 OIC_LOG(DEBUG, TAG, "Create g_deviceList");
2606 g_deviceList = u_arraylist_create();
2611 * Check Sent Count for remove g_sendBuffer
2613 void CALEClientUpdateSendCnt()
2615 OIC_LOG(DEBUG, TAG, "CALEClientUpdateSendCnt");
2618 oc_mutex_lock(g_threadMutex);
2622 if (g_targetCnt <= g_currentSentCnt)
2625 g_currentSentCnt = 0;
2628 if (g_sendBuffer != nil ){//|| g_sendBuffer != NULL || [g_sendBuffer length] > 0){
2629 //[g_sendBuffer release];
2633 // notity the thread
2634 oc_cond_signal(g_threadCond);
2636 CALEClientSetSendFinishFlag(true);
2638 OIC_LOG(DEBUG, TAG, "set signal for send data");
2641 oc_mutex_unlock(g_threadMutex);
2644 CAResult_t CALEClientInitGattMutexVaraibles()
2646 if (NULL == g_bleReqRespClientCbMutex)
2648 g_bleReqRespClientCbMutex = oc_mutex_new();
2649 if (NULL == g_bleReqRespClientCbMutex)
2651 OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
2652 return CA_STATUS_FAILED;
2656 if (NULL == g_bleServerBDAddressMutex)
2658 g_bleServerBDAddressMutex = oc_mutex_new();
2659 if (NULL == g_bleServerBDAddressMutex)
2661 OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
2662 return CA_STATUS_FAILED;
2666 if (NULL == g_threadMutex)
2668 g_threadMutex = oc_mutex_new();
2669 if (NULL == g_threadMutex)
2671 OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
2672 return CA_STATUS_FAILED;
2676 if (NULL == g_threadSendMutex)
2678 g_threadSendMutex = oc_mutex_new();
2679 if (NULL == g_threadSendMutex)
2681 OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
2682 return CA_STATUS_FAILED;
2686 if (NULL == g_deviceListMutex)
2688 g_deviceListMutex = oc_mutex_new();
2689 if (NULL == g_deviceListMutex)
2691 OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
2692 return CA_STATUS_FAILED;
2696 if (NULL == g_gattObjectMutex)
2698 g_gattObjectMutex = oc_mutex_new();
2699 if (NULL == g_gattObjectMutex)
2701 OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
2702 return CA_STATUS_FAILED;
2706 if (NULL == g_deviceStateListMutex)
2708 g_deviceStateListMutex = oc_mutex_new();
2709 if (NULL == g_deviceStateListMutex)
2711 OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
2712 return CA_STATUS_FAILED;
2716 if (NULL == g_SendFinishMutex)
2718 g_SendFinishMutex = oc_mutex_new();
2719 if (NULL == g_SendFinishMutex)
2721 OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
2722 return CA_STATUS_FAILED;
2726 if (NULL == g_scanMutex)
2728 g_scanMutex = oc_mutex_new();
2729 if (NULL == g_scanMutex)
2731 OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
2732 return CA_STATUS_FAILED;
2736 if (NULL == waitMutex){
2737 waitMutex = oc_mutex_new();
2740 if (NULL == g_threadWriteCharacteristicMutex)
2742 g_threadWriteCharacteristicMutex = oc_mutex_new();
2743 if (NULL == g_threadWriteCharacteristicMutex)
2745 OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
2746 return CA_STATUS_FAILED;
2750 if (NULL == g_deviceScanRetryDelayMutex)
2752 g_deviceScanRetryDelayMutex = oc_mutex_new();
2753 if (NULL == g_deviceScanRetryDelayMutex)
2755 OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
2756 return CA_STATUS_FAILED;
2760 if (NULL == g_initializeMutex)
2762 g_initializeMutex = oc_mutex_new();
2763 if (NULL == g_initializeMutex)
2765 OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
2766 return CA_STATUS_FAILED;
2770 return CA_STATUS_OK;
2773 void CALEClientTerminateGattMutexVariables()
2775 oc_mutex_free(g_bleReqRespClientCbMutex);
2776 g_bleReqRespClientCbMutex = NULL;
2778 oc_mutex_free(g_bleServerBDAddressMutex);
2779 g_bleServerBDAddressMutex = NULL;
2781 oc_mutex_free(g_threadMutex);
2782 g_threadMutex = NULL;
2784 oc_mutex_free(g_threadSendMutex);
2785 g_threadSendMutex = NULL;
2787 oc_mutex_free(g_deviceListMutex);
2788 g_deviceListMutex = NULL;
2790 oc_mutex_free(g_SendFinishMutex);
2791 g_SendFinishMutex = NULL;
2793 oc_mutex_free(g_scanMutex);
2796 oc_mutex_free(waitMutex);
2799 oc_mutex_free(g_threadWriteCharacteristicMutex);
2800 g_threadWriteCharacteristicMutex = NULL;
2802 oc_mutex_free(g_deviceScanRetryDelayMutex);
2803 g_deviceScanRetryDelayMutex = NULL;
2805 oc_mutex_free(g_initializeMutex);
2806 g_initializeMutex = NULL;
2809 void CALEClientSetSendFinishFlag(bool flag)
2811 OIC_LOG_V(DEBUG, TAG, "g_isFinishedSendData is %d", flag);
2813 oc_mutex_lock(g_SendFinishMutex);
2814 g_isFinishedSendData = flag;
2815 oc_mutex_unlock(g_SendFinishMutex);
2822 CAResult_t CAStartLEGattClient()
2824 // init mutex for send logic
2825 if (!g_deviceDescCond)
2827 g_deviceDescCond = oc_cond_new();
2832 g_threadCond = oc_cond_new();
2835 if (!g_threadWriteCharacteristicCond)
2837 g_threadWriteCharacteristicCond = oc_cond_new();
2840 g_isStartedLEClient = true;
2841 return CA_STATUS_OK;
2844 void CAStopLEGattClient()
2846 OIC_LOG(DEBUG, TAG, "CAStopBLEGattClient");
2848 g_isStartedLEClient = false;
2850 CAResult_t ret = CALEClientDisconnectAll();
2851 if (CA_STATUS_OK != ret)
2853 OIC_LOG(ERROR, TAG, "CALEClientDisconnectAll has failed");
2856 ret = CALEClientStopScan();
2857 if(CA_STATUS_OK != ret)
2859 OIC_LOG(ERROR, TAG, "CALEClientStopScan has failed");
2862 oc_mutex_lock(g_threadMutex);
2863 OIC_LOG(DEBUG, TAG, "signal - connection cond");
2864 oc_cond_signal(g_threadCond);
2865 CALEClientSetSendFinishFlag(true);
2866 oc_mutex_unlock(g_threadMutex);
2868 oc_mutex_lock(g_threadWriteCharacteristicMutex);
2869 OIC_LOG(DEBUG, TAG, "signal - WriteCharacteristic cond");
2870 oc_cond_signal(g_threadWriteCharacteristicCond);
2871 oc_mutex_unlock(g_threadWriteCharacteristicMutex);
2873 oc_mutex_lock(g_deviceScanRetryDelayMutex);
2874 OIC_LOG(DEBUG, TAG, "signal - delay cond");
2875 oc_cond_signal(g_deviceScanRetryDelayCond);
2876 oc_mutex_unlock(g_deviceScanRetryDelayMutex);
2878 oc_cond_signal(g_deviceDescCond); //change
2880 oc_cond_free(g_deviceDescCond);
2881 oc_cond_free(g_threadCond);
2882 oc_cond_free(g_threadWriteCharacteristicCond);
2883 oc_cond_free(g_deviceScanRetryDelayCond);
2885 g_deviceDescCond = NULL;
2886 g_threadCond = NULL;
2887 g_threadWriteCharacteristicCond = NULL;
2888 g_deviceScanRetryDelayCond = NULL;
2891 CAResult_t CAInitializeLEGattClient()
2893 OIC_LOG(DEBUG, TAG, "Initialize GATT Client");
2894 CALEClientInitialize();
2895 return CA_STATUS_OK;
2898 void CATerminateLEGattClient()
2900 OIC_LOG(DEBUG, TAG, "Terminate GATT Client");
2901 CAStopLEGattClient();
2902 CALEClientTerminate();
2905 CAResult_t CAUpdateCharacteristicsToGattServer(const char *remoteAddress,
2906 const uint8_t *data,
2908 CALETransferType_t type,
2911 OIC_LOG(DEBUG, TAG, "call CALEClientSendUnicastMessage");
2912 VERIFY_NON_NULL(data, TAG, "data is null");
2913 VERIFY_NON_NULL(remoteAddress, TAG, "remoteAddress is null");
2915 if (LE_UNICAST != type || position < 0)
2917 OIC_LOG(ERROR, TAG, "this request is not unicast");
2918 return CA_STATUS_INVALID_PARAM;
2921 return CALEClientSendUnicastMessage(remoteAddress, data, dataLen);
2924 CAResult_t CAUpdateCharacteristicsToAllGattServers(const uint8_t *data, uint32_t dataLen)
2926 OIC_LOG(DEBUG, TAG, "call CALEClientSendMulticastMessage");
2927 VERIFY_NON_NULL(data, TAG, "data is null");
2929 return CALEClientSendMulticastMessage(data, dataLen);
2932 void CASetLEReqRespClientCallback(CABLEDataReceivedCallback callback)
2934 oc_mutex_lock(g_bleReqRespClientCbMutex);
2935 g_CABLEClientDataReceivedCallback = callback;
2936 oc_mutex_unlock(g_bleReqRespClientCbMutex);
2939 void CASetLEClientThreadPoolHandle(ca_thread_pool_t handle)
2941 g_threadPoolHandle = handle;
2944 CAResult_t CAGetLEAddress(char **local_address){
2945 return CA_NOT_SUPPORTED;
2948 void CALEClientSetFlagBTAdapter(bool state){
2949 isEnableBtAdapter = state;
2952 bool CALEClientIsEnableBTAdapter(){
2953 return isEnableBtAdapter;