replace : iotivity -> iotivity-sec
[platform/upstream/iotivity.git] / resource / csdk / connectivity / src / bt_le_adapter / ios / caleserver.m
1 /******************************************************************
2  *
3  * Copyright 2017 Samsung Electronics All Rights Reserved.
4  *
5  *
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  ******************************************************************/
20
21 #include <stdio.h>
22 #include <string.h>
23 #include <unistd.h>
24 #include "caleserver.h"
25 #include "caleutils.h"
26 #include "caleinterface.h"
27 #include "caadapterutils.h"
28
29 #include "logger.h"
30 #include "oic_malloc.h"
31 #include "cathreadpool.h"
32 #include "octhread.h"
33 #include "uarraylist.h"
34
35 #define TAG PCF("OIC_CA_LE_SERVER")
36
37 #define WAIT_TIME_WRITE_CHARACTERISTIC 10000000
38
39 static CAPacketReceiveCallback g_packetReceiveCallback = NULL;
40 static CABLEErrorHandleCallback g_serverErrorCallback;
41
42 static u_arraylist_t *g_connectedDeviceList = NULL;
43
44 static bool g_isStartServer = false;
45 static bool g_isInitializedServer = false;
46
47 static CABLEDataReceivedCallback g_CABLEServerDataReceivedCallback = NULL;
48 static oc_mutex g_bleReqRespCbMutex = NULL;
49 static oc_mutex g_bleClientBDAddressMutex = NULL;
50 static oc_mutex g_connectedDeviceListMutex = NULL;
51
52 static oc_cond g_transmitQueueCond = NULL;
53 static oc_mutex g_transmitQueueMutex = NULL;
54
55 static bool g_isStartAdvertising = false;
56 static bool isEnableGattServer = true;
57
58 static id cbPeripheralIf;
59
60 @interface CBPeripheralIfClass:NSObject <CBPeripheralManagerDelegate>
61 @end
62
63 NSMutableArray *peripheralMgrs;
64 static CBMutableCharacteristic *readCharacteristic = nil;
65 static CBMutableCharacteristic *writeCharacteristic = nil;
66 NSMutableDictionary *cbCentrals;
67 NSMutableDictionary *cbCentralsConnInfo;
68
69 @implementation CBPeripheralIfClass
70 static CBPeripheralManager *peripheralMgr = nil;
71
72 - (void) createPeripheralManager{
73     OIC_LOG(DEBUG, TAG, "[CBPrl] create peripheral manager");
74     peripheralMgr = [[CBPeripheralManager alloc] initWithDelegate:self
75                     queue:nil options:nil];
76     peripheralMgrs = [NSMutableArray new];
77     cbCentrals = [[NSMutableDictionary alloc] init];
78     cbCentralsConnInfo = [[NSMutableDictionary alloc] init];
79 }
80
81 - (void) setCharacteristic{
82     OIC_LOG(DEBUG, TAG, "[CBPrl] set Characteristic");
83     readCharacteristic = [[CBMutableCharacteristic alloc]
84             initWithType:[CBUUID UUIDWithString:
85                           [NSString stringWithUTF8String:OIC_GATT_CHARACTERISTIC_RESPONSE_UUID]]
86             properties:CBCharacteristicPropertyNotify | CBCharacteristicPropertyRead
87             value: nil
88             permissions:CBAttributePermissionsReadable];
89     writeCharacteristic = [[CBMutableCharacteristic alloc]
90             initWithType:[CBUUID UUIDWithString:
91                           [NSString stringWithUTF8String:OIC_GATT_CHARACTERISTIC_REQUEST_UUID]]
92             properties: CBCharacteristicPropertyWrite | CBCharacteristicPropertyWriteWithoutResponse
93             value:nil
94             permissions:CBAttributePermissionsWriteable];
95 }
96
97 - (CBMutableService *) setService{
98     OIC_LOG(DEBUG, TAG, "PeripheralInterface: set Service");
99     CBMutableService *leService = [[CBMutableService alloc]
100             initWithType:[CBUUID UUIDWithString:
101                           [NSString stringWithUTF8String:OIC_GATT_SERVICE_UUID]]
102             primary:YES];
103
104     return leService;
105 }
106
107 - (void) addService:(CBMutableService *) leService :(CBPeripheralManager *)peripheral{
108     OIC_LOG(DEBUG, TAG, "PeripheralInterface: add Service");
109     leService.characteristics = @[readCharacteristic, writeCharacteristic];
110     [peripheral addService:leService];
111 }
112
113 - (void) startAdvertising: (CBPeripheralManager *)peripheral{
114     [self setCharacteristic];
115     [self addService:[self setService]:peripheral];
116
117     NSString *beaconName = @"IoTivity Service";
118
119     if (!g_isStartAdvertising){
120         OIC_LOG(DEBUG, TAG, "PeripheralInterface: startAdvertising 1");
121         [peripheral startAdvertising:@{
122             CBAdvertisementDataLocalNameKey: beaconName,
123             CBAdvertisementDataServiceUUIDsKey:
124             @[[CBUUID UUIDWithString:[NSString stringWithUTF8String:OIC_GATT_SERVICE_UUID]]]}
125         ];
126         g_isStartAdvertising = true;
127     }
128 }
129
130 - (void) stopAdvertising{
131     OIC_LOG(DEBUG, TAG, "PeripheralInterface: stopAdvertising");
132     [peripheralMgr stopAdvertising];
133 }
134
135 - (CAResult_t) sendData:(CBCentral *) connCentral :(NSData *)data{
136     if (peripheralMgr != nil){
137         if (connCentral != nil){
138             OIC_LOG_V(DEBUG, TAG, "central: %s, senddata updateValue",
139                       [[connCentral.identifier UUIDString] UTF8String]);
140             NSUInteger tLen = [data length];
141             uint8_t *tData = (uint8_t *)malloc(tLen);
142             memcpy(tData, [data bytes], tLen);
143             OIC_LOG_BUFFER(DEBUG, TAG, tData, tLen);
144             free(tData);
145             bool result = [peripheralMgr updateValue: data
146                     forCharacteristic:readCharacteristic
147                     onSubscribedCentrals:@[connCentral]];
148             if (result){
149                 OIC_LOG(DEBUG, TAG, "CBCI: sending success");
150                 return CA_STATUS_OK;
151             }else{
152                 OIC_LOG(ERROR, TAG, "CBCI: transmit queue is full! --> wait");
153
154                 oc_mutex_lock(g_transmitQueueMutex);
155                 oc_cond_wait(g_transmitQueueCond, g_transmitQueueMutex);
156                 oc_mutex_unlock(g_transmitQueueMutex);
157
158                 [peripheralMgr updateValue: data
159                         forCharacteristic:readCharacteristic
160                         onSubscribedCentrals:@[connCentral]];
161                 return CA_STATUS_OK;
162             }
163         }else{
164             OIC_LOG(ERROR, TAG, "CBCI: connectedCentral ERROR");
165             return CA_STATUS_FAILED;
166         }
167     }
168     return CA_STATUS_FAILED;
169 }
170
171 - (NSString *) createCentralUUID{
172     CFUUIDRef theUUID = CFUUIDCreate(NULL);
173     CFStringRef uuidString = CFUUIDCreateString(NULL, theUUID);
174     NSString *uuid = (NSString *)CFStringCreateCopy(NULL, uuidString);
175     CFRelease(theUUID);
176     CFRelease(uuidString);
177     return [uuid autorelease];
178 }
179
180 #pragma mark - CBPeripheralManagerDelegate
181
182 - (void) peripheralManagerDidUpdateState:(CBPeripheralManager *)peripheral{
183     if (peripheral.state == CBPeripheralManagerStatePoweredOn){
184         OIC_LOG(DEBUG, TAG, "PeripheralInterface: update state --> POWERED ON");
185         peripheralMgr = peripheral;
186         [peripheralMgrs addObject:peripheralMgr];
187
188         CALEServerSetFlagBTAdapter(true);
189
190         if (!g_isStartAdvertising){
191             CALEServerStartAdvertise();
192         }
193     }else {
194         OIC_LOG(DEBUG, TAG, "PeripheralInterface: update state --> ! powered on");
195         [peripheralMgrs removeObject: peripheral];
196         CALEServerSetFlagBTAdapter(false);
197
198         return;
199     }
200 }
201
202 - (void)peripheralManager:(CBPeripheralManager *)peripheral
203         didAddService:(CBService *)service error:(NSError *)error{
204     OIC_LOG_V(INFO, TAG, "didAddService:%s", [[service.UUID UUIDString] UTF8String]);
205     if (error){
206         OIC_LOG_V(ERROR, TAG, "didAddService:%s,  error:%s",
207                 [[service.UUID UUIDString] UTF8String], [[error localizedDescription] UTF8String]);
208     }
209 }
210
211 - (void)peripheralManagerDidStartAdvertising:(CBPeripheralManager *)peripheral
212         error:(NSError *)error{
213     if ([[error localizedDescription] isEqualToString:@"null"]
214             || [[error localizedDescription] isEqualToString:@"<null>"]
215             || [[error localizedDescription] isEqualToString:@"(null)"]
216             || [[error localizedDescription] length] != 0){
217
218         OIC_LOG_V(ERROR, TAG, "peripheralManagerDidStartAdvertising : error:%s",
219                 [[error localizedDescription] UTF8String]);
220     }
221 }
222
223 - (void)peripheralManager: (CBPeripheralManager *)peripheral
224         didReceiveReadRequest:(CBATTRequest *)request{
225     OIC_LOG(DEBUG, TAG, "didReceiveReadRequest");
226 }
227
228 - (void)peripheralManager:(CBPeripheralManager *)peripheral
229         central:(CBCentral *)central
230         didSubscribeToCharacteristic:(CBCharacteristic *)characteristic{
231     OIC_LOG(DEBUG, TAG, "PeripheralInterface: connected");
232     OIC_LOG_V(DEBUG, TAG, "connected characteristic %s",
233                 [[characteristic.UUID UUIDString] UTF8String]);
234
235     bool hasCentral = false;
236     for (CBCentral *key in cbCentrals){
237         if ([key isEqual:central]){
238             hasCentral = true;
239             OIC_LOG_V(DEBUG, TAG, "tuuid %s", [[cbCentrals objectForKey:key] UTF8String]);
240         }
241     }
242
243     if (!hasCentral){
244         OIC_LOG(DEBUG, TAG, "set Central Object");
245         [cbCentrals setObject:[cbPeripheralIf createCentralUUID] forKey:central];
246     }
247
248     const char *address = [CALEServerGetAddressFromGattObj(central) UTF8String];
249     if (false == CALEServerIsDeviceInList(address)){
250         OIC_LOG_V(DEBUG, TAG, "add connected Central obj to cache: %s", address);
251         CALEServerAddDeviceToList(central);
252     }
253
254     [cbCentralsConnInfo setObject:[NSNumber numberWithInteger:(int)STATE_CONNECTED] forKey:central];
255 }
256
257 - (void)peripheralManager:(CBPeripheralManager *)peripheral
258         central:(CBCentral *)central
259         didUnsubscribeFromCharacteristic:(CBCharacteristic *)characteristic{
260     OIC_LOG(DEBUG, TAG, "PeripheralInterface: disconnected");
261
262     const char *address = [CALEServerGetAddressFromGattObj(central) UTF8String];
263     if (true == CALEServerIsDeviceInList(address)){
264         OIC_LOG_V(DEBUG, TAG, "remove connected Central obj to cache: %s", address);
265         CALEServerRemoveDevice(address);
266     }
267
268     [cbCentralsConnInfo setObject:[NSNumber numberWithInteger:
269                                    (int)STATE_DISCONNECTED] forKey:central];
270 }
271
272 - (void)peripheralManager:(CBPeripheralManager *)peripheral
273         didReceiveWriteRequests: (NSArray *)requests{
274     NSMutableData *nsData = [[NSMutableData alloc] init];
275     for (CBATTRequest *request in requests){
276         if ([request.characteristic.UUID isEqual:
277                 [CBUUID UUIDWithString:
278                  [NSString stringWithUTF8String:OIC_GATT_CHARACTERISTIC_REQUEST_UUID]]]){
279             OIC_LOG_V(DEBUG, TAG, "Received data from central %s",
280                       [[request.central.identifier UUIDString] UTF8String]);
281
282             const char* address = [CALEServerGetAddressFromGattObj(request.central) UTF8String];
283             if (!address){
284                 OIC_LOG(ERROR, TAG, "address is not available");
285                 return;
286             }
287
288             OIC_LOG_V(DEBUG, TAG, "------------- received data (size:%lu)----------------",
289                     request.value.length);
290             [nsData appendData:request.value];
291             uint32_t len = [nsData length];
292             uint8_t *data = (uint8_t*)OICMalloc(len);
293             uint32_t sentLength = 0;
294
295             memcpy(data, (const uint8_t*)[nsData bytes], len);
296
297             OIC_LOG_BUFFER(DEBUG, TAG, data, len);
298
299             oc_mutex_lock(g_bleClientBDAddressMutex);
300             g_CABLEServerDataReceivedCallback(address, data, len, &sentLength);
301             oc_mutex_unlock(g_bleClientBDAddressMutex);
302         }
303     }
304 }
305
306 - (void)peripheralManagerIsReadyToUpdateSubscribers:(CBPeripheralManager *) peripheral{
307     oc_mutex_lock(g_transmitQueueMutex);
308     OIC_LOG(DEBUG, TAG, "transmit queue is ready to update subscribers");
309     oc_cond_signal(g_transmitQueueCond);
310     oc_mutex_unlock(g_transmitQueueMutex);
311 }
312
313 @end
314
315
316 /**
317  * get the current connection state of the gatt profile to the remote device.
318  * @param[in]   device           bluetooth device object
319  * @return  state of the profile connection.
320  */
321 static int CALEServerGetConnectionState(CBCentral *central)
322 {
323     OIC_LOG(DEBUG, TAG, "CALEServerGetConnectionState");
324
325     int connState = [[cbCentralsConnInfo objectForKey:central] intValue];
326     OIC_LOG_V(INFO, TAG, "connection state is %d", connState);
327     return connState;
328 }
329
330 CAResult_t CALEStartAdvertise()
331 {
332     CAResult_t ret = CALEServerStartAdvertise();
333     if (CA_STATUS_OK != ret)
334     {
335         OIC_LOG(ERROR, TAG, "CALEServerStartAdvertise has failed");
336     }
337
338     return ret;
339 }
340
341 CAResult_t CALEServerStartAdvertise()
342 {
343     OIC_LOG(DEBUG, TAG, "IN - CALEServerStartAdvertise");
344
345     if (!CALEServerIsEnableBTAdapter())
346     {
347         OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
348         return CA_ADAPTER_NOT_ENABLED;
349     }
350
351     if ([peripheralMgrs count] != 0 && caglobals.serverFlags){
352         [cbPeripheralIf startAdvertising: peripheralMgrs[0]];
353     }else{
354         return CA_STATUS_FAILED;
355     }
356
357     OIC_LOG(DEBUG, TAG, "Advertising started!!");
358
359     OIC_LOG(DEBUG, TAG, "OUT - CALEServerStartAdvertise");
360     return CA_STATUS_OK;
361
362 }
363
364 CAResult_t CALEServerStopAdvertise()
365 {
366     OIC_LOG(DEBUG, TAG, "LEServerStopAdvertise");
367
368     if (!CALEServerIsEnableBTAdapter())
369     {
370         OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
371         return CA_ADAPTER_NOT_ENABLED;
372     }
373
374     [cbPeripheralIf stopAdvertising];
375
376     OIC_LOG(DEBUG, TAG, "Advertising stopped!!");
377     return CA_STATUS_OK;
378 }
379
380 CAResult_t CALEServerStartGattServer()
381 {
382     OIC_LOG(DEBUG, TAG, "IN - CALEServerStartGattServer");
383
384     if (!CALEServerIsEnableBTAdapter())
385     {
386         OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
387         return CA_ADAPTER_NOT_ENABLED;
388     }
389
390     if (g_isStartServer)
391     {
392         OIC_LOG(DEBUG, TAG, "Gatt server already started");
393     }
394
395     OIC_LOG(DEBUG,TAG, "OUT - CALEServerStartGattServer");
396     return CA_STATUS_OK;
397 }
398
399 CAResult_t CALEServerSend(CBCentral *central, const uint8_t *data, const uint32_t dataLen)
400 {
401     OIC_LOG(DEBUG, TAG, "IN - CALEServerSend");
402
403     if (!CALEServerIsEnableBTAdapter())
404     {
405         OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
406         return CA_ADAPTER_NOT_ENABLED;
407     }
408
409     NSData *nsData = [NSData dataWithBytes:(const uint8_t*)data length:dataLen];
410     OIC_LOG(DEBUG, TAG, "send data");
411     OIC_LOG_BUFFER(DEBUG, TAG, data, dataLen);
412
413     CAResult_t result = [cbPeripheralIf sendData: central: nsData];
414
415     if (CA_STATUS_OK != result)
416     {
417         OIC_LOG(ERROR, TAG, "Fail to send response data");
418         return result;
419     }
420
421     OIC_LOG(DEBUG, TAG, "OUT - CALEServerSend");
422     return result;
423 }
424
425 CAResult_t CALEServerInitialize()
426 {
427     OIC_LOG(DEBUG, TAG, "IN - CALEServerInitialize");
428
429     cbPeripheralIf = [[CBPeripheralIfClass alloc] init];
430     [cbPeripheralIf createPeripheralManager];
431
432     CAResult_t ret = CA_STATUS_FAILED;
433     g_transmitQueueCond = oc_cond_new();
434
435     ret = CALEServerInitMutexVaraibles();
436     if (CA_STATUS_OK != ret)
437     {
438         OIC_LOG(ERROR, TAG, "CALEServerInitMutexVaraibles has failed");
439
440         return CA_STATUS_FAILED;
441     }
442     CALEServerCreateCachedDeviceList();
443
444     g_isInitializedServer = true;
445     OIC_LOG(DEBUG, TAG, "OUT - CALEServerInitialize");
446     return CA_STATUS_OK;
447 }
448
449 void CALEServerTerminate()
450 {
451     OIC_LOG(DEBUG, TAG, "IN - CALEServerTerminate");
452
453     CALEServerTerminateMutexVaraibles();
454     CALEServerTerminateConditionVaraibles();
455
456     g_isInitializedServer = false;
457
458     oc_cond_free(g_transmitQueueCond);
459     g_transmitQueueCond = NULL;
460
461     OIC_LOG(DEBUG, TAG, "OUT - CALEServerTerminate");
462 }
463
464 CAResult_t CALEServerSendUnicastMessage(const char* address, const uint8_t* data, uint32_t dataLen)
465 {
466     OIC_LOG_V(DEBUG, TAG, "CALEServerSendUnicastMessage(%s, %p)", address, data);
467     VERIFY_NON_NULL(address, TAG, "address is null");
468     VERIFY_NON_NULL(data, TAG, "data is null");
469
470     CAResult_t ret = CALEServerSendUnicastMessageImpl(address, data, dataLen);
471     if (CA_STATUS_OK != ret)
472     {
473         OIC_LOG(ERROR, TAG, "CALEServerSendUnicastMessageImpl has failed");
474     }
475
476     return ret;
477 }
478
479 CAResult_t CALEServerSendMulticastMessage(const uint8_t* data, uint32_t dataLen)
480 {
481     OIC_LOG_V(DEBUG, TAG, "CALEServerSendMulticastMessage(%p)", data);
482     VERIFY_NON_NULL(data, TAG, "data is null");
483
484     CAResult_t ret = CALEServerSendMulticastMessageImpl(data, dataLen);
485     if (CA_STATUS_OK != ret)
486     {
487         OIC_LOG(ERROR, TAG, "CALEServerSendMulticastMessageImpl has failed");
488     }
489
490     return ret;
491 }
492
493 CAResult_t CALEServerStartMulticastServer()
494 {
495     OIC_LOG(DEBUG, TAG, "IN - CALEServerStartMulticastServer");
496
497     if (!g_isInitializedServer)
498     {
499         OIC_LOG(INFO, TAG, "server is not initialized");
500         return CA_STATUS_FAILED;
501     }
502
503     if (g_isStartServer)
504     {
505         OIC_LOG(INFO, TAG, "server is already started..it will be skipped");
506         return CA_STATUS_FAILED;
507     }
508
509     g_isStartServer = true;
510
511     CAResult_t ret = CALEServerStartGattServer();
512     if (CA_STATUS_OK != ret)
513     {
514         OIC_LOG(ERROR, TAG, "Fail to start gatt server");
515         return ret;
516     }
517
518     if(!CALEServerIsEnableBTAdapter())
519     {
520         OIC_LOG(DEBUG, TAG, "Cannot start advertise. Not powered on yet.");
521         return ret;
522     }
523     if(!g_isStartAdvertising)
524         ret = CALEServerStartAdvertise();
525     else
526     {
527         OIC_LOG(DEBUG, TAG, "skipped cause already advertising.");
528     }
529     if (CA_STATUS_OK != ret)
530     {
531         OIC_LOG(ERROR, TAG, "CALEServerStartAdvertise has failed");
532     }
533
534     OIC_LOG(DEBUG, TAG, "OUT - CALEServerStartMulticastServer");
535     return ret;
536 }
537
538 CAResult_t CALEServerStopMulticastServer()
539 {
540     OIC_LOG(DEBUG, TAG, "IN - CALEServerStopMulticastServer");
541
542     if (false == g_isStartServer)
543     {
544         OIC_LOG(INFO, TAG, "server is already stopped..it will be skipped");
545         return CA_STATUS_FAILED;
546     }
547
548     CAResult_t ret = CALEServerStopAdvertise();
549     if (CA_STATUS_OK != ret)
550     {
551         OIC_LOG(ERROR, TAG, "CALEServerStopAdvertise has failed");
552     }
553
554     g_isStartServer = false;
555
556     OIC_LOG(DEBUG, TAG, "OUT - CALEServerStopMulticastServer");
557     return ret;
558 }
559
560 void CALEServerSetCallback(CAPacketReceiveCallback callback)
561 {
562     OIC_LOG(DEBUG, TAG, "CALEServerSetCallback");
563     g_packetReceiveCallback = callback;
564 }
565
566 CAResult_t CALEServerSendUnicastMessageImpl(const char* address, const uint8_t* data,
567                                             uint32_t dataLen)
568 {
569     OIC_LOG_V(DEBUG, TAG, "CALEServerSendUnicastMessageImpl, address: %s, data: %p, size: %u",
570             address, data, dataLen);
571     OIC_LOG_BUFFER(DEBUG, TAG, data, dataLen);
572     VERIFY_NON_NULL(address, TAG, "address is null");
573     VERIFY_NON_NULL(data, TAG, "data is null");
574
575     if (!g_connectedDeviceList)
576     {
577         OIC_LOG(ERROR, TAG, "g_connectedDeviceList is null");
578         return CA_STATUS_FAILED;
579     }
580
581
582     uint32_t length = u_arraylist_length(g_connectedDeviceList);
583     for (uint32_t index = 0; index < length; index++)
584     {
585         OIC_LOG(DEBUG, TAG, "check device address");
586         CBCentral *tCentral = (CBCentral *) u_arraylist_get(g_connectedDeviceList, index);
587         if (!tCentral)
588         {
589             OIC_LOG(ERROR, TAG, "tCentral is null");
590             return CA_SEND_FAILED;
591         }
592
593         const char *setAddress = [CALEServerGetAddressFromGattObj(tCentral) UTF8String];
594         if (!setAddress)
595         {
596             OIC_LOG(ERROR, TAG, "setAddress is null");
597             return CA_SEND_FAILED;
598         }
599
600         OIC_LOG_V(DEBUG, TAG, "setAddress : %s", setAddress);
601         OIC_LOG_V(DEBUG, TAG, "address : %s", address);
602
603         if (!strcmp(setAddress, address))
604         {
605             OIC_LOG_V(DEBUG, TAG, "found the device: %s", setAddress);
606
607             CAResult_t res = CALEServerSend(tCentral, data, dataLen);
608             if (CA_STATUS_OK != res)
609             {
610                 OIC_LOG(ERROR, TAG, "send has failed");
611                 return CA_SEND_FAILED;
612             }
613             break;
614         }
615     }
616
617     OIC_LOG(INFO, TAG, "unicast - send request is successful");
618     return CA_STATUS_OK;
619 }
620
621 CAResult_t CALEServerSendMulticastMessageImpl(const uint8_t *data, uint32_t dataLen)
622 {
623     OIC_LOG_V(DEBUG, TAG, "CALEServerSendMulticastMessageImpl, send to, data: %s", data);
624     VERIFY_NON_NULL(data, TAG, "data is null");
625
626     if (!g_connectedDeviceList)
627     {
628         OIC_LOG(ERROR, TAG, "g_connectedDeviceList is null");
629         return CA_STATUS_FAILED;
630     }
631
632     uint32_t length = u_arraylist_length(g_connectedDeviceList);
633     for (uint32_t index = 0; index < length; index++)
634     {
635         CBCentral *tCentral = (CBCentral *) u_arraylist_get(g_connectedDeviceList, index);
636         if (!tCentral)
637         {
638             OIC_LOG(ERROR, TAG, "central is null");
639             continue;
640         }
641
642         const char *addr = [CALEServerGetAddressFromGattObj(tCentral) UTF8String];
643         CAResult_t res = CALEServerSend(tCentral, data, dataLen);
644         if (CA_STATUS_OK != res)
645         {
646             OIC_LOG_V(ERROR, TAG, "Send failed: %s", addr);
647         }
648
649         OIC_LOG_V(INFO, TAG, "unicast - send request is successful for a device[%s]", addr);
650     }
651
652     return CA_STATUS_OK;
653 }
654
655 void CALEServerCreateCachedDeviceList()
656 {
657     oc_mutex_lock(g_connectedDeviceListMutex);
658     if (!g_connectedDeviceList)
659     {
660         OIC_LOG(DEBUG, TAG, "Create device list");
661         g_connectedDeviceList = u_arraylist_create();
662     }
663     oc_mutex_unlock(g_connectedDeviceListMutex);
664 }
665
666 bool CALEServerIsDeviceInList(const char* remoteAddress)
667 {
668     VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", false);
669
670     if (!g_connectedDeviceList)
671     {
672         OIC_LOG(ERROR, TAG, "list is null");
673         return false;
674     }
675
676     uint32_t length = u_arraylist_length(g_connectedDeviceList);
677     for (uint32_t index = 0; index < length; index++)
678     {
679         CBCentral *central = (CBCentral *) u_arraylist_get(g_connectedDeviceList, index);
680
681         if (!central)
682         {
683             OIC_LOG(ERROR, TAG, "connectedDevice is not available");
684             return false;
685         }
686
687         const char* setAddress = [CALEServerGetAddressFromGattObj(central) UTF8String];
688         if (!setAddress)
689         {
690             OIC_LOG(ERROR, TAG, "setAddress is null");
691             return false;
692         }
693
694         if (!strcmp(remoteAddress, setAddress))
695         {
696             OIC_LOG(ERROR, TAG, "the device is already set");
697             return true;
698         }
699     }
700
701     OIC_LOG(DEBUG, TAG, "there are no device in the list");
702     return false;
703 }
704
705 CAResult_t CALEServerAddDeviceToList(CBCentral *central)
706 {
707     OIC_LOG(DEBUG, TAG, "IN - CALEServerAddDeviceToList");
708     VERIFY_NON_NULL(central, TAG, "central is null");
709
710     oc_mutex_lock(g_connectedDeviceListMutex);
711
712     if (!g_connectedDeviceList)
713     {
714         OIC_LOG(ERROR, TAG, "list is null");
715         oc_mutex_unlock(g_connectedDeviceListMutex);
716         return CA_STATUS_FAILED;
717     }
718
719     const char *remoteAddress = [CALEServerGetAddressFromGattObj(central) UTF8String];
720     if (!remoteAddress)
721     {
722         OIC_LOG(ERROR, TAG, "remoteAddress is null");
723         oc_mutex_unlock(g_connectedDeviceListMutex);
724         return CA_STATUS_FAILED;
725     }
726
727     if (false == CALEServerIsDeviceInList(remoteAddress))
728     {
729         u_arraylist_add(g_connectedDeviceList, central);
730         OIC_LOG_V(DEBUG, TAG, "Set the object to ArrayList as Element : %s", remoteAddress);
731     }
732
733     oc_mutex_unlock(g_connectedDeviceListMutex);
734     OIC_LOG(DEBUG, TAG, "OUT - CALEServerAddDeviceToList");
735     return CA_STATUS_OK;
736 }
737
738 CAResult_t CALEServerRemoveAllDevices()
739 {
740     OIC_LOG(DEBUG, TAG, "IN - CALEServerRemoveAllDevices");
741
742     oc_mutex_lock(g_connectedDeviceListMutex);
743     if (!g_connectedDeviceList)
744     {
745         OIC_LOG(ERROR, TAG, "g_connectedDeviceList is null");
746         oc_mutex_unlock(g_connectedDeviceListMutex);
747         return CA_STATUS_FAILED;
748     }
749
750     uint32_t length = u_arraylist_length(g_connectedDeviceList);
751     for (uint32_t index = 0; index < length; index++)
752     {
753         CBCentral *central = (CBCentral *)u_arraylist_get(g_connectedDeviceList, index);
754         [cbCentrals removeObjectForKey: central];
755         if (NULL == u_arraylist_remove(g_connectedDeviceList, index)){
756             oc_mutex_unlock(g_connectedDeviceListMutex);
757             return CA_STATUS_FAILED;
758         }
759     }
760
761     OICFree(g_connectedDeviceList);
762     g_connectedDeviceList = NULL;
763     oc_mutex_unlock(g_connectedDeviceListMutex);
764
765     OIC_LOG(DEBUG, TAG, "OUT - CALEServerRemoveAllDevices");
766     return CA_STATUS_OK;
767 }
768
769 CAResult_t CALEServerRemoveDevice(const char *remoteAddress)
770 {
771     OIC_LOG(DEBUG, TAG, "IN CALEServerRemoveDevice");
772
773     oc_mutex_lock(g_connectedDeviceListMutex);
774     if (!g_connectedDeviceList)
775     {
776         OIC_LOG(ERROR, TAG, "no deviceList");
777         oc_mutex_unlock(g_connectedDeviceListMutex);
778         return CA_STATUS_FAILED;
779     }
780
781     uint32_t length = u_arraylist_length(g_connectedDeviceList);
782     for (uint32_t index = 0; index < length; index++)
783     {
784         CBCentral *central = (CBCentral *)u_arraylist_get(g_connectedDeviceList, index);
785
786         if (central)
787         {
788             const char* setAddress = [CALEServerGetAddressFromGattObj(central) UTF8String];
789             if (!setAddress)
790             {
791                 OIC_LOG(ERROR, TAG, "setAddress is null");
792                 continue;
793             }
794
795             if (!strcmp(setAddress, remoteAddress))
796             {
797                 OIC_LOG_V(DEBUG, TAG, "device address : %s", remoteAddress);
798
799                 if (NULL == u_arraylist_remove(g_connectedDeviceList, index))
800                 {
801                     OIC_LOG(ERROR, TAG, "List removal failed.");
802                     oc_mutex_unlock(g_connectedDeviceListMutex);
803                     return CA_STATUS_FAILED;
804                 }
805                 [cbCentrals removeObjectForKey: central];
806                 oc_mutex_unlock(g_connectedDeviceListMutex);
807                 return CA_STATUS_OK;
808             }
809         }
810     }
811
812     oc_mutex_unlock(g_connectedDeviceListMutex);
813
814     OIC_LOG(DEBUG, TAG, "there are no device in the device list");
815
816     OIC_LOG(DEBUG, TAG, "IN CALEServerRemoveDevice");
817     return CA_STATUS_FAILED;
818 }
819
820
821 /**
822  * adapter common
823  */
824
825 CAResult_t CAStartLEGattServer()
826 {
827     CALEServerStartMulticastServer();
828
829     return CA_STATUS_OK;
830 }
831
832 CAResult_t CAStopLEGattServer()
833 {
834     OIC_LOG(DEBUG, TAG, "CAStopLEGattServer");
835
836     CAResult_t ret = CALEServerRemoveAllDevices();
837     if (CA_STATUS_OK != ret)
838     {
839         OIC_LOG(ERROR, TAG, "CALEServerRemoveAllDevices has failed");
840         return CA_STATUS_FAILED;
841     }
842
843     g_isStartServer = false;
844
845     return CA_STATUS_OK;
846 }
847
848 CAResult_t CAInitializeLEGattServer()
849 {
850     OIC_LOG(DEBUG, TAG, "Initialize Gatt Server");
851     return CALEServerInitialize();
852 }
853
854 void CATerminateLEGattServer()
855 {
856     OIC_LOG(DEBUG, TAG, "Terminate Gatt Server");
857     CALEServerTerminate();
858 }
859
860 void CASetLEReqRespServerCallback(CABLEDataReceivedCallback callback)
861 {
862     oc_mutex_lock(g_bleReqRespCbMutex);
863     g_CABLEServerDataReceivedCallback = callback;
864     oc_mutex_unlock(g_bleReqRespCbMutex);
865 }
866
867 void CASetBLEServerErrorHandleCallback(CABLEErrorHandleCallback callback)
868 {
869     g_serverErrorCallback = callback;
870 }
871
872 CAResult_t CAUpdateCharacteristicsToGattClient(const char *address,
873                                                const uint8_t *charValue,
874                                                uint32_t charValueLen)
875 {
876     CAResult_t result = CA_SEND_FAILED;
877     VERIFY_NON_NULL(charValue, TAG, "charValue is null");
878
879     if (address)
880     {
881         result = CALEServerSendUnicastMessage(address, charValue, charValueLen);
882     }
883
884     return result;
885 }
886
887 CAResult_t CAUpdateCharacteristicsToAllGattClients(const uint8_t *charValue,
888                                                    uint32_t charValueLen)
889 {
890     VERIFY_NON_NULL(charValue, TAG, "device is null");
891
892     CAResult_t result = CALEServerSendMulticastMessage(charValue, charValueLen);
893
894     return result;
895 }
896
897 void CASetLEServerThreadPoolHandle(ca_thread_pool_t handle)
898 {
899     OIC_LOG(INFO, TAG, "CASetLEServerThreadPoolHandle is not support");
900     (void)handle;
901 }
902
903 CAResult_t CALEServerInitMutexVaraibles()
904 {
905     if (NULL == g_bleReqRespCbMutex)
906     {
907         g_bleReqRespCbMutex = oc_mutex_new();
908         if (NULL == g_bleReqRespCbMutex)
909         {
910             OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
911             return CA_STATUS_FAILED;
912         }
913     }
914
915     if (NULL == g_bleClientBDAddressMutex)
916     {
917         g_bleClientBDAddressMutex = oc_mutex_new();
918         if (NULL == g_bleClientBDAddressMutex)
919         {
920             OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
921             return CA_STATUS_FAILED;
922         }
923     }
924
925     if (NULL == g_connectedDeviceListMutex)
926     {
927         g_connectedDeviceListMutex = oc_mutex_new();
928         if (NULL == g_connectedDeviceListMutex)
929         {
930             OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
931             return CA_STATUS_FAILED;
932         }
933     }
934
935     if (NULL == g_transmitQueueMutex){
936         g_transmitQueueMutex = oc_mutex_new();
937         if (NULL == g_transmitQueueMutex){
938             OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
939             return CA_STATUS_FAILED;
940         }
941     }
942
943     return CA_STATUS_OK;
944 }
945
946 void CALEServerTerminateMutexVaraibles()
947 {
948     oc_mutex_free(g_bleReqRespCbMutex);
949     g_bleReqRespCbMutex = NULL;
950
951     oc_mutex_free(g_bleClientBDAddressMutex);
952     g_bleClientBDAddressMutex = NULL;
953
954     oc_mutex_free(g_connectedDeviceListMutex);
955     g_connectedDeviceListMutex = NULL;
956
957     oc_mutex_free(g_transmitQueueMutex);
958     g_transmitQueueMutex = NULL;
959 }
960
961 void CALEServerTerminateConditionVaraibles()
962 {
963     OIC_LOG(DEBUG, TAG, "this method is not supported");
964 }
965
966 NSString *CALEServerGetAddressFromGattObj(CBCentral *central){
967     VERIFY_NON_NULL_RET(central, TAG, "central is null", NULL);
968     NSString *address = [cbCentrals objectForKey: central];
969     if (!address){
970         OIC_LOG(ERROR, TAG, "address isn't available");
971         return NULL;
972     }
973     return address;
974 }
975
976 void CALEServerSetFlagBTAdapter(bool state){
977     isEnableGattServer = state;
978 }
979
980 bool CALEServerIsEnableBTAdapter(){
981     return isEnableGattServer;
982 }