Update snapshot(2017-11-23)
[platform/upstream/iotivity.git] / resource / csdk / connectivity / src / bt_le_adapter / tizen / caleserver.c
1 /******************************************************************
2 *
3 * Copyright 2014 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 "caleserver.h"
22 #include "cacommon.h"
23 #include "cacommonutil.h"
24 #include "octhread.h"
25 #include "caqueueingthread.h"
26 #include "cagattservice.h"
27 #include "oic_string.h"
28 #include "oic_malloc.h"
29 #include "caleutil.h"
30
31 /**
32  * Logging tag for module name
33  */
34 #define TAG "OIC_CA_LE_SERVER"
35
36 /**
37  * The handle of the OIC server.
38  */
39 static bt_gatt_server_h g_gattServer = NULL;
40
41 /**
42  * The handle of the OIC service.
43  */
44 static bt_gatt_h g_gattSvcPath = NULL;
45
46 /**
47  * The handle of the OIC read characteristics.
48  */
49 static bt_gatt_h g_gattReadCharPath = NULL;
50
51 /**
52  * The handle of the OIC write characteristics.
53  */
54 static bt_gatt_h g_gattWriteCharPath = NULL;
55
56 /**
57  * The handle to control Bluetooth LE advertising.
58  */
59 static bt_advertiser_h g_hAdvertiser = NULL;
60
61 /**
62  * Callback register with LE adapter.  This callback is called on reception of any
63  * data from the remote device.
64  */
65 static CABLEDataReceivedCallback g_leServerDataReceivedCallback = NULL;
66
67 /**
68  * Callback to notify any error in LE adapter.
69  */
70 static CABLEErrorHandleCallback g_serverErrorCallback = NULL;
71
72 /**
73  * To keep the state of GATT server if started or not.
74  */
75 static bool g_isLEGattServerStarted = false;
76
77 /**
78  * Mutex to synchronize the calls to start and stop server.
79  */
80 static oc_mutex g_leServerStateMutex = NULL;
81
82 /**
83  * Mutex to synchronize writing operations on the characteristics.
84  */
85 static  oc_mutex g_leCharacteristicMutex = NULL;
86
87 /**
88  * Mutex to synchronize to creation of OIC service.
89  */
90 static  oc_mutex g_leServiceMutex = NULL;
91
92 /**
93  * Mutex to synchronize access to the requestResponse callback to be called
94  * when the data needs to be sent from GATTClient.
95  */
96 static  oc_mutex g_leReqRespCbMutex = NULL;
97
98 /**
99  * Mutex to synchronize the task to be pushed to thread pool.
100  */
101 static oc_mutex g_leServerThreadPoolMutex = NULL;
102
103 /**
104  * Reference to threadpool.
105  */
106 static ca_thread_pool_t g_leServerThreadPool = NULL;
107
108 /**
109  * GmainLoop to manage the threads to receive the callback from the platfrom.
110  */
111 static GMainLoop *g_eventLoop = NULL;
112
113 /**
114  * This contains the list of OIC clients connected to the server.
115  */
116 static LEClientInfoList *g_LEClientList = NULL;
117
118 /**
119  * Mutex to synchronize access to LE ClientList.
120  */
121 static oc_mutex g_LEClientListMutex = NULL;
122
123 void CALEGattServerConnectionStateChanged(bool connected, const char *remoteAddress)
124 {
125     VERIFY_NON_NULL_VOID(remoteAddress, TAG, "remote address");
126
127     CAResult_t res = CA_STATUS_OK;
128     if (connected)
129     {
130         OIC_LOG_V(DEBUG, TAG, "Connected to [%s]", remoteAddress);
131         char *addr = OICStrdup(remoteAddress);
132         oc_mutex_lock(g_LEClientListMutex);
133         res  = CAAddLEClientInfoToList(&g_LEClientList, addr);
134         if (CA_STATUS_OK != res)
135         {
136             OIC_LOG(ERROR, TAG, "CAAddLEClientInfoToList failed");
137             oc_mutex_unlock(g_LEClientListMutex);
138             OICFree(addr);
139             return;
140         }
141         oc_mutex_unlock(g_LEClientListMutex);
142
143         res = CALEStopAdvertise();
144         if (CA_STATUS_OK != res)
145         {
146             OIC_LOG_V(ERROR, TAG, "Failed to stop advertising [%d]", res);
147             return;
148         }
149     }
150     else
151     {
152         OIC_LOG_V(DEBUG, TAG, "Disconnected from [%s]", remoteAddress);
153         oc_mutex_lock(g_LEClientListMutex);
154         CARemoveLEClientInfoFromList(&g_LEClientList, remoteAddress);
155         oc_mutex_unlock(g_LEClientListMutex);
156
157         res = CALEStartAdvertise();
158         if (CA_STATUS_OK != res)
159         {
160             OIC_LOG_V(ERROR, TAG, "Failed to start advertising [%d]", res);
161             return;
162         }
163     }
164 }
165
166 void CALEServerNotificationSentCB(int result, char *remote_address, bt_gatt_server_h server,
167                                   bt_gatt_h characteristic, bool completed, void *user_data)
168 {
169     OIC_LOG_V(DEBUG, TAG, "Notification to the device[%s] result[%d]", remote_address, result);
170 }
171
172 CAResult_t CAStartLEGattServer()
173 {
174     OIC_LOG(DEBUG, TAG, "IN");
175
176     oc_mutex_lock(g_leServerStateMutex);
177     if (true == g_isLEGattServerStarted)
178     {
179         OIC_LOG(ERROR, TAG, "Gatt Server is already running");
180         oc_mutex_unlock(g_leServerStateMutex);
181         return CA_STATUS_OK;
182     }
183
184     CAResult_t ret = CAInitLEGattServer();
185     if (CA_STATUS_OK != ret)
186     {
187         OIC_LOG_V(ERROR, TAG, "CAInitLEGattServer failed[%d]", ret);
188         oc_mutex_unlock(g_leServerStateMutex);
189         CATerminateLEGattServer();
190         return CA_STATUS_FAILED;
191     }
192
193     ret  = CAAddNewLEServiceInGattServer(CA_GATT_SERVICE_UUID);
194     if (CA_STATUS_OK != ret)
195     {
196         OIC_LOG_V(ERROR, TAG, "CAAddNewLEServiceInGattServer failed[%d]", ret);
197         oc_mutex_unlock(g_leServerStateMutex);
198         CATerminateLEGattServer();
199         return CA_STATUS_FAILED;
200     }
201
202     static const char charReadUUID[] = CA_GATT_RESPONSE_CHRC_UUID;
203     char charReadValue[] = {33, 44, 55, 66}; // These are initial random values
204
205     // For Read Characteristics.
206     ret = CAAddNewCharacteristicsToGattServer(g_gattSvcPath, charReadUUID, charReadValue,
207                                               sizeof(charReadValue), true);
208     if (CA_STATUS_OK != ret)
209     {
210         OIC_LOG_V(ERROR, TAG, "CAAddNewCharacteristicsToGattServer failed[%d]", ret);
211         oc_mutex_unlock(g_leServerStateMutex);
212         CATerminateLEGattServer();
213         return CA_STATUS_FAILED;
214     }
215
216     static const char charWriteUUID[] = CA_GATT_REQUEST_CHRC_UUID;
217     char charWriteValue[] = {33, 44, 55, 66}; // These are initial random values
218
219
220     ret = CAAddNewCharacteristicsToGattServer(g_gattSvcPath, charWriteUUID, charWriteValue,
221             sizeof(charWriteValue), false); // For Write Characteristics.
222     if (CA_STATUS_OK != ret )
223     {
224         OIC_LOG_V(ERROR, TAG, "CAAddNewCharacteristicsToGattServer failed[%d]", ret);
225         oc_mutex_unlock(g_leServerStateMutex);
226         CATerminateLEGattServer();
227         return CA_STATUS_FAILED;
228     }
229
230     ret = CARegisterLEServicewithGattServer(g_gattSvcPath);
231     if (CA_STATUS_OK != ret )
232     {
233         OIC_LOG_V(ERROR, TAG, "CARegisterLEServicewithGattServer failed[%d]", ret);
234         oc_mutex_unlock(g_leServerStateMutex);
235         CATerminateLEGattServer();
236         return CA_STATUS_FAILED;
237     }
238
239     ret = CALEStartAdvertise();
240     if (CA_STATUS_OK != ret)
241     {
242         OIC_LOG_V(ERROR, TAG, "CALEStartAdvertise failed[%d]", ret);
243         oc_mutex_unlock(g_leServerStateMutex);
244         CATerminateLEGattServer();
245         return CA_STATUS_FAILED;
246     }
247
248     g_isLEGattServerStarted = true;
249
250     oc_mutex_unlock(g_leServerStateMutex);
251
252     OIC_LOG(DEBUG, TAG, "OUT");
253     return CA_STATUS_OK;
254 }
255
256 void CALENotificationCb(bool notify, bt_gatt_server_h server, bt_gatt_h gatt_handle,
257                         void *user_data)
258 {
259     OIC_LOG(DEBUG, TAG, "IN");
260     if (notify)
261     {
262         OIC_LOG(DEBUG, TAG, "Notification is subscribed by the client");
263         CALogSendStateInfo(CA_ADAPTER_GATT_BTLE, "", 0, -1,
264                            true, "notifyChar success");
265     }
266     else
267     {
268         CALogSendStateInfo(CA_ADAPTER_GATT_BTLE, "", 0, -1,
269                            false, "notifyChar failure");
270     }
271     OIC_LOG(DEBUG, TAG, "OUT");
272 }
273
274 CAResult_t CALEStartAdvertise()
275 {
276     OIC_LOG(DEBUG, TAG, "IN");
277
278     CAResult_t res = CALEStartAdvertiseImpl(CA_GATT_SERVICE_UUID);
279     if (CA_STATUS_OK != res)
280     {
281         OIC_LOG_V(ERROR, TAG, "CALEStartAdvertiseImpl failed[%d]", res);
282     }
283
284     OIC_LOG(DEBUG, TAG, "OUT");
285     return res;
286 }
287
288 CAResult_t CALEStartAdvertiseImpl(const char *serviceUUID)
289 {
290     OIC_LOG(DEBUG, TAG, "IN");
291
292     int res = bt_adapter_le_create_advertiser(&g_hAdvertiser);
293     if (NULL == g_hAdvertiser || BT_ERROR_NONE != res)
294     {
295         OIC_LOG_V(ERROR, TAG, "g_hAdvertiser is NULL/ Result is %d", res);
296         return CA_STATUS_FAILED;
297     }
298
299     res = bt_adapter_le_add_advertising_service_uuid(g_hAdvertiser,
300                                                      BT_ADAPTER_LE_PACKET_ADVERTISING,
301                                                      serviceUUID);
302     if (BT_ERROR_NONE != res)
303     {
304         OIC_LOG_V(ERROR, TAG, "bt_adapter_le_add_advertising_service_uuid failed with ret[%s]",
305                   CALEGetErrorMsg(res));
306         return CA_STATUS_FAILED;
307     }
308
309     res = bt_adapter_le_set_advertising_device_name(g_hAdvertiser,
310                                                     BT_ADAPTER_LE_PACKET_SCAN_RESPONSE, true);
311     if (BT_ERROR_NONE != res)
312     {
313         OIC_LOG_V(ERROR, TAG, "bt_adapter_le_set_advertising_device_name failed with ret[%s]",
314                   CALEGetErrorMsg(res));
315         return CA_STATUS_FAILED;
316     }
317
318     res = bt_adapter_le_start_advertising_new(g_hAdvertiser, NULL, NULL);
319     if (BT_ERROR_NONE != res)
320     {
321         OIC_LOG_V(ERROR, TAG, "bt_adapter_le_start_advertising_new failed with ret[%s]",
322                   CALEGetErrorMsg(res));
323         return CA_STATUS_FAILED;
324     }
325
326     OIC_LOG(DEBUG, TAG, "OUT");
327     return CA_STATUS_OK;
328 }
329
330 CAResult_t CALEStopAdvertise()
331 {
332     OIC_LOG(DEBUG, TAG, "IN");
333     if (NULL != g_hAdvertiser)
334     {
335         int ret  = bt_adapter_le_stop_advertising(g_hAdvertiser);
336         if (0 != ret)
337         {
338             OIC_LOG_V(ERROR, TAG,
339                       "bt_adapter_le_stop_advertising failed with ret[%s]", CALEGetErrorMsg(ret));
340         }
341
342         ret = bt_adapter_le_destroy_advertiser(g_hAdvertiser);
343         if (0 != ret)
344         {
345             OIC_LOG_V(ERROR, TAG,
346                       "bt_adapter_le_destroy_advertiser failed with ret[%s]", CALEGetErrorMsg(ret));
347         }
348         g_hAdvertiser = NULL;
349     }
350     else
351     {
352         OIC_LOG(ERROR, TAG, "Advertising is not running");
353         return CA_STATUS_FAILED;
354     }
355
356     OIC_LOG(DEBUG, TAG, "OUT");
357     return CA_STATUS_OK;
358 }
359
360 CAResult_t CAStopLEGattServer()
361 {
362     OIC_LOG(DEBUG, TAG, "IN");
363
364     oc_mutex_lock(g_leServerStateMutex);
365
366     if (false == g_isLEGattServerStarted)
367     {
368         OIC_LOG(ERROR, TAG, "Gatt Server is not running to stop");
369         oc_mutex_unlock(g_leServerStateMutex);
370         return CA_STATUS_OK;
371     }
372
373     g_isLEGattServerStarted = false;
374
375     oc_mutex_lock(g_LEClientListMutex);
376     CADisconnectAllClient(g_LEClientList);
377     g_LEClientList = NULL;
378     oc_mutex_unlock(g_LEClientListMutex);
379
380     CAResult_t res = CALEStopAdvertise();
381     {
382         OIC_LOG_V(ERROR, TAG, "CALEStopAdvertise failed with ret[%d]", res);
383     }
384
385     res = CADeInitLEGattServer();
386     if (CA_STATUS_OK != res)
387     {
388         OIC_LOG_V(ERROR, TAG, "CADeInitLEGattService failed with ret[%d]", res);
389     }
390
391     GMainContext  *context_event_loop = NULL;
392     // Required for waking up the thread which is running in gmain loop
393     if (NULL != g_eventLoop)
394     {
395         context_event_loop = g_main_loop_get_context(g_eventLoop);
396
397         if (context_event_loop)
398         {
399             OIC_LOG_V(DEBUG,  TAG, "g_eventLoop context %x", context_event_loop);
400             g_main_context_wakeup(context_event_loop);
401
402             // Kill g main loops and kill threads
403             g_main_loop_quit(g_eventLoop);
404         }
405         g_eventLoop = NULL;
406     }
407     else
408     {
409         OIC_LOG(ERROR, TAG, "g_eventLoop context is NULL");
410     }
411
412     oc_mutex_unlock(g_leServerStateMutex);
413
414     OIC_LOG(DEBUG, TAG, "OUT");
415     return CA_STATUS_OK;
416 }
417
418 CAResult_t CAInitializeLEGattServer()
419 {
420     OIC_LOG(DEBUG, TAG, "IN");
421
422     CAResult_t ret = CAInitGattServerMutexVariables();
423     if (CA_STATUS_OK != ret )
424     {
425         OIC_LOG(ERROR, TAG, "CAInitGattServerMutexVariables failed!");
426         CATerminateGattServerMutexVariables();
427         return CA_SERVER_NOT_STARTED;
428     }
429     OIC_LOG(DEBUG, TAG, "OUT");
430     return ret;
431 }
432
433 void CATerminateLEGattServer()
434 {
435     OIC_LOG(DEBUG, TAG, "IN");
436
437     // Service and characteristics path will be freed by the platform.
438     oc_mutex_lock(g_leServiceMutex);
439     g_gattSvcPath = NULL;
440     oc_mutex_unlock(g_leServiceMutex);
441
442     oc_mutex_lock(g_leCharacteristicMutex);
443     g_gattReadCharPath = NULL;
444     g_gattWriteCharPath = NULL;
445     oc_mutex_unlock(g_leCharacteristicMutex);
446
447     oc_mutex_lock(g_leServerThreadPoolMutex);
448     g_leServerThreadPool = NULL;
449     oc_mutex_unlock(g_leServerThreadPoolMutex);
450
451     // Terminating all mutex variables.
452     CATerminateGattServerMutexVariables();
453     OIC_LOG(DEBUG, TAG, "OUT");
454 }
455
456 CAResult_t CAInitGattServerMutexVariables()
457 {
458     OIC_LOG(DEBUG, TAG, "IN");
459     if (NULL == g_leServerStateMutex)
460     {
461         g_leServerStateMutex = oc_mutex_new();
462         if (NULL == g_leServerStateMutex)
463         {
464             OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
465             return CA_STATUS_FAILED;
466         }
467     }
468
469     if (NULL == g_leServiceMutex)
470     {
471         g_leServiceMutex = oc_mutex_new();
472         if (NULL == g_leServiceMutex)
473         {
474             OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
475             return CA_STATUS_FAILED;
476         }
477     }
478
479     if (NULL == g_leCharacteristicMutex)
480     {
481         g_leCharacteristicMutex = oc_mutex_new();
482         if (NULL == g_leCharacteristicMutex)
483         {
484             OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
485             return CA_STATUS_FAILED;
486         }
487     }
488
489     if (NULL == g_leReqRespCbMutex)
490     {
491         g_leReqRespCbMutex = oc_mutex_new();
492         if (NULL == g_leReqRespCbMutex)
493         {
494             OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
495             return CA_STATUS_FAILED;
496         }
497     }
498
499     if (NULL == g_leServerThreadPoolMutex)
500     {
501         g_leServerThreadPoolMutex = oc_mutex_new();
502         if (NULL == g_leServerThreadPoolMutex)
503         {
504             OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
505             return CA_STATUS_FAILED;
506         }
507     }
508
509     if (NULL == g_LEClientListMutex)
510     {
511         g_LEClientListMutex = oc_mutex_new();
512         if (NULL == g_LEClientListMutex)
513         {
514             OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
515             return CA_STATUS_FAILED;
516         }
517     }
518
519     OIC_LOG(DEBUG, TAG, "OUT");
520     return CA_STATUS_OK;
521 }
522
523 void CATerminateGattServerMutexVariables()
524 {
525     OIC_LOG(DEBUG, TAG, "IN");
526     oc_mutex_free(g_leServerStateMutex);
527     g_leServerStateMutex = NULL;
528
529     oc_mutex_free(g_leServiceMutex);
530     g_leServiceMutex = NULL;
531
532     oc_mutex_free(g_leCharacteristicMutex);
533     g_leCharacteristicMutex = NULL;
534
535     oc_mutex_free(g_leReqRespCbMutex);
536     g_leReqRespCbMutex = NULL;
537
538     oc_mutex_free(g_leServerThreadPoolMutex);
539     g_leServerThreadPoolMutex = NULL;
540
541     oc_mutex_free(g_LEClientListMutex);
542     g_LEClientListMutex = NULL;
543
544     OIC_LOG(DEBUG, TAG, "OUT");
545 }
546
547 CAResult_t CAInitLEGattServer()
548 {
549     OIC_LOG(DEBUG, TAG, "IN");
550
551     int ret =  bt_gatt_server_initialize();
552     if (0 != ret)
553     {
554         OIC_LOG_V(ERROR, TAG, "bt_gatt_server_initialize failed with ret[%s]",
555                   CALEGetErrorMsg(ret));
556         return CA_STATUS_FAILED;
557     }
558
559     if (!g_gattServer)
560     {
561         OIC_LOG(DEBUG, TAG, "g_gattServer is NULL. create gatt server..");
562         ret = bt_gatt_server_create(&g_gattServer);
563         if (0 != ret)
564         {
565             OIC_LOG_V(ERROR, TAG, "bt_gatt_server_create failed with ret[%s]",
566                       CALEGetErrorMsg(ret));
567             return CA_STATUS_FAILED;
568         }
569     }
570
571     OIC_LOG(DEBUG, TAG, "OUT");
572     return CA_STATUS_OK;
573 }
574
575 CAResult_t CADeInitLEGattServer()
576 {
577     OIC_LOG(DEBUG, TAG, "IN");
578
579     int ret = bt_gatt_server_unregister_all_services(g_gattServer);
580     if (0 != ret)
581     {
582         OIC_LOG_V(ERROR, TAG, "bt_gatt_server_unregister_all_services failed with ret[%s]",
583                   CALEGetErrorMsg(ret));
584         return CA_STATUS_FAILED;
585     }
586
587     ret = bt_gatt_server_destroy(g_gattServer);
588     if (0 != ret)
589     {
590         OIC_LOG_V(ERROR, TAG, "bt_gatt_server_destroy failed with ret[%s]",
591                   CALEGetErrorMsg(ret));
592         return CA_STATUS_FAILED;
593     }
594     g_gattServer = NULL;
595
596     ret =  bt_gatt_server_deinitialize();
597     if (0 != ret)
598     {
599         OIC_LOG_V(ERROR, TAG, "bt_gatt_server_deinitialize failed with ret[%s]",
600                   CALEGetErrorMsg(ret));
601         return CA_STATUS_FAILED;
602     }
603
604     OIC_LOG(DEBUG, TAG, "OUT");
605     return CA_STATUS_OK;
606 }
607
608 void CASetLEServerThreadPoolHandle(ca_thread_pool_t handle)
609 {
610     OIC_LOG(DEBUG, TAG, "IN");
611     oc_mutex_lock(g_leServerThreadPoolMutex);
612     g_leServerThreadPool = handle;
613     oc_mutex_unlock(g_leServerThreadPoolMutex);
614     OIC_LOG(DEBUG, TAG, "OUT");
615 }
616
617 CAResult_t CAAddNewLEServiceInGattServer(const char *serviceUUID)
618 {
619     OIC_LOG(DEBUG, TAG, "IN");
620
621     VERIFY_NON_NULL(serviceUUID, TAG, "serviceUUID");
622
623     OIC_LOG_V(DEBUG, TAG, "service uuid %s", serviceUUID);
624
625     bt_gatt_service_type_e type = BT_GATT_SERVICE_TYPE_PRIMARY;
626
627     oc_mutex_lock(g_leServiceMutex);
628     int ret = bt_gatt_service_create(serviceUUID, type, &g_gattSvcPath);
629     if (0 != ret)
630     {
631         oc_mutex_unlock(g_leServiceMutex);
632         OIC_LOG_V(ERROR, TAG, "bt_gatt_service_create failed with ret [%s]",
633                     CALEGetErrorMsg(ret));
634         return CA_STATUS_FAILED;
635     }
636     oc_mutex_unlock(g_leServiceMutex);
637
638     if (g_gattSvcPath)
639     {
640         OIC_LOG_V(DEBUG, TAG, "ServicePath obtained is %s", (char *)g_gattSvcPath);
641     }
642
643     OIC_LOG(DEBUG, TAG, "OUT");
644     return CA_STATUS_OK;
645 }
646
647 void CALEGattRemoteCharacteristicWriteCb(char *remoteAddress, bt_gatt_server_h server,
648                                          bt_gatt_h charPath, int offset, char *charValue,
649                                          int charValueLen, void *userData)
650 {
651     OIC_LOG(INFO, TAG, "IN - WriteCharCB");
652
653     if (NULL == charValue || NULL == remoteAddress)
654     {
655         OIC_LOG(ERROR, TAG, "Param callback values are NULL");
656         return;
657     }
658
659     OIC_LOG_V(DEBUG, TAG, "charPath = [%s] charValue = [%s] len [%d]", (char *)charPath,
660               charValue, charValueLen);
661
662     uint8_t *data = OICMalloc(charValueLen);
663     if (NULL == data)
664     {
665         OIC_LOG(ERROR, TAG, "Malloc failed!");
666         return;
667     }
668
669     memcpy(data, charValue, charValueLen);
670
671     oc_mutex_lock(g_leReqRespCbMutex);
672     if (NULL == g_leServerDataReceivedCallback)
673     {
674         OIC_LOG(ERROR, TAG, "gReqRespCallback is NULL!");
675         oc_mutex_unlock(g_leReqRespCbMutex);
676         OICFree(data);
677         return;
678     }
679
680     OIC_LOG(INFO, TAG, "Sending data up !");
681     uint32_t sentLength = 0;
682     g_leServerDataReceivedCallback(remoteAddress, data, charValueLen,
683                                     &sentLength);
684     oc_mutex_unlock(g_leReqRespCbMutex);
685     OICFree(data);
686     OIC_LOG(INFO, TAG, "OUT - WriteCharCB");
687 }
688
689 CAResult_t CARegisterLEServicewithGattServer(const bt_gatt_h svcPath)
690 {
691     OIC_LOG(DEBUG, TAG, "IN");
692
693     VERIFY_NON_NULL(svcPath, TAG, "svcPath");
694
695     OIC_LOG_V(DEBUG, TAG, "svcPath:%s", svcPath);
696
697     int ret = bt_gatt_server_register_service(g_gattServer, svcPath);
698     if (0 != ret)
699     {
700         OIC_LOG_V(ERROR, TAG, "bt_gatt_server_register_service failed with ret[%s]",
701                   CALEGetErrorMsg(ret));
702         return CA_STATUS_FAILED;
703     }
704
705     ret = bt_gatt_server_set_value_changed_cb(g_gattWriteCharPath,
706                                               CALEGattRemoteCharacteristicWriteCb, NULL);
707
708     if (0 != ret)
709     {
710         OIC_LOG_V(ERROR, TAG, "bt_gatt_server_set_value_changed_cb failed with ret[%s]",
711                   CALEGetErrorMsg(ret));
712         return CA_STATUS_FAILED;
713     }
714
715     OIC_LOG(DEBUG, TAG, "OUT");
716     return CA_STATUS_OK;
717 }
718
719 CAResult_t CAAddNewCharacteristicsToGattServer(const bt_gatt_h svcPath, const char *charUUID,
720                                                const char *charValue, int charValueLen, bool read)
721 {
722
723     OIC_LOG(DEBUG, TAG, "IN");
724
725     int permissions = BT_GATT_PERMISSION_READ | BT_GATT_PERMISSION_WRITE;
726     int properties;
727     if (read)
728     {
729         properties = BT_GATT_PROPERTY_INDICATE | BT_GATT_PROPERTY_READ;
730     }
731     else
732     {
733         properties = BT_GATT_PROPERTY_WRITE | BT_GATT_PROPERTY_READ;
734     }
735
736     bt_gatt_h charPath = NULL;
737
738     int ret = bt_gatt_characteristic_create(charUUID, permissions, properties, charValue,
739                                             charValueLen, &charPath);
740
741     if (0 != ret || NULL == charPath)
742     {
743         OIC_LOG_V(ERROR, TAG,
744                   "bt_gatt_add_characteristic  failed with ret [%s]", CALEGetErrorMsg(ret));
745         return CA_STATUS_FAILED;
746     }
747
748     OIC_LOG_V(DEBUG, TAG,
749               "bt_gatt_characteristic_create charPath obtained: %s", (char *)charPath);
750
751     if (read)
752     {
753         ret = bt_gatt_server_set_notification_state_change_cb(charPath, CALENotificationCb, NULL);
754         if (0 != ret)
755         {
756             OIC_LOG_V(ERROR, TAG,
757                       "bt_gatt_server_set_notification_state_change_cb  failed with ret[%s]",
758                       CALEGetErrorMsg(ret));
759             return CA_STATUS_FAILED;
760         }
761     }
762
763     ret =  bt_gatt_service_add_characteristic(svcPath, charPath);
764     if (0 != ret)
765     {
766         OIC_LOG_V(ERROR, TAG,
767                   "bt_gatt_service_add_characteristic  failed with ret[%s]",
768                   CALEGetErrorMsg(ret));
769         return CA_STATUS_FAILED;
770     }
771
772     oc_mutex_lock(g_leCharacteristicMutex);
773
774     if (read)
775     {
776         char desc_value[2] = {1, 0};  // Notification enabled.
777         bt_gatt_h descriptor = NULL;
778         permissions = BT_GATT_PERMISSION_READ | BT_GATT_PERMISSION_WRITE;
779         ret = bt_gatt_descriptor_create(CA_GATT_CONFIGURATION_DESC_UUID, permissions,
780                                         desc_value, sizeof(desc_value),
781                                         &descriptor);
782         if (0 != ret)
783         {
784             oc_mutex_unlock(g_leCharacteristicMutex);
785             OIC_LOG_V(ERROR, TAG,
786                       "bt_gatt_descriptor_create  failed with ret[%s]",
787                       CALEGetErrorMsg(ret));
788             return CA_STATUS_FAILED;
789         }
790
791         ret = bt_gatt_characteristic_add_descriptor(charPath, descriptor);
792         if (0 != ret)
793         {
794             oc_mutex_unlock(g_leCharacteristicMutex);
795             OIC_LOG_V(ERROR, TAG,
796                       "bt_gatt_characteristic_add_descriptor  failed with ret[%s]",
797                       CALEGetErrorMsg(ret));
798             return CA_STATUS_FAILED;
799         }
800
801         g_gattReadCharPath = charPath;
802     }
803     else
804     {
805         g_gattWriteCharPath = charPath;
806     }
807
808     oc_mutex_unlock(g_leCharacteristicMutex);
809
810     OIC_LOG(DEBUG, TAG, "OUT");
811     return CA_STATUS_OK;
812 }
813
814 CAResult_t CAUpdateCharacteristicsToGattClient(const char *address, const uint8_t *charValue,
815                                                uint32_t charValueLen)
816 {
817     OIC_LOG(DEBUG, TAG, "IN");
818
819     VERIFY_NON_NULL(charValue, TAG, "charValue");
820     VERIFY_NON_NULL(address, TAG, "address");
821
822     OIC_LOG_V(DEBUG, TAG, "Client's Unicast address for sending data [%s]", address);
823
824     oc_mutex_lock(g_leCharacteristicMutex);
825
826     if (NULL  == g_gattReadCharPath)
827     {
828         OIC_LOG(ERROR, TAG, "g_gattReadCharPath is NULL");
829         oc_mutex_unlock(g_leCharacteristicMutex);
830         return CA_STATUS_FAILED;
831     }
832
833     int ret = bt_gatt_set_value(g_gattReadCharPath, (char *)charValue, charValueLen);
834     if (0 != ret)
835     {
836         OIC_LOG_V(ERROR, TAG,
837                   "bt_gatt_set_value failed with return [%s]", CALEGetErrorMsg(ret));
838         oc_mutex_unlock(g_leCharacteristicMutex);
839         return CA_STATUS_FAILED;
840     }
841
842     ret = bt_gatt_server_notify(g_gattReadCharPath, false, CALEServerNotificationSentCB,
843                                 NULL);
844     if (0 != ret)
845     {
846         OIC_LOG_V(ERROR, TAG,
847                   "bt_gatt_server_notify failed with return [%s]", CALEGetErrorMsg(ret));
848         oc_mutex_unlock(g_leCharacteristicMutex);
849         return CA_STATUS_FAILED;
850     }
851
852     oc_mutex_unlock(g_leCharacteristicMutex);
853
854     OIC_LOG(DEBUG, TAG, "OUT");
855     return CA_STATUS_OK;
856 }
857
858 CAResult_t CAUpdateCharacteristicsToAllGattClients(const uint8_t *charValue, uint32_t charValueLen)
859 {
860     OIC_LOG(DEBUG, TAG, "IN");
861
862     VERIFY_NON_NULL(charValue, TAG, "charValue");
863
864     oc_mutex_lock(g_leCharacteristicMutex);
865
866     if (NULL  == g_gattReadCharPath)
867     {
868         OIC_LOG(ERROR, TAG, "g_gattReadCharPath is NULL");
869         oc_mutex_unlock(g_leCharacteristicMutex);
870         return CA_STATUS_FAILED;
871     }
872
873     int ret = bt_gatt_set_value(g_gattReadCharPath, (char *)charValue, charValueLen);
874     if (0 != ret)
875     {
876         OIC_LOG_V(ERROR, TAG, "bt_gatt_set_value failed with return[%s]", CALEGetErrorMsg(ret));
877         oc_mutex_unlock(g_leCharacteristicMutex);
878         return CA_STATUS_FAILED;
879     }
880
881     ret = bt_gatt_server_notify(g_gattReadCharPath, false, CALEServerNotificationSentCB,
882                                 NULL);
883     if (0 != ret)
884     {
885         OIC_LOG_V(ERROR, TAG,
886                   "bt_gatt_server_notify failed with return[%s]", CALEGetErrorMsg(ret));
887         oc_mutex_unlock(g_leCharacteristicMutex);
888         return CA_STATUS_FAILED;
889     }
890
891     oc_mutex_unlock(g_leCharacteristicMutex);
892
893     OIC_LOG(DEBUG, TAG, "OUT");
894     return CA_STATUS_OK;
895 }
896
897 void CASetLEReqRespServerCallback(CABLEDataReceivedCallback callback)
898 {
899     OIC_LOG(DEBUG, TAG, "IN");
900
901     oc_mutex_lock(g_leReqRespCbMutex);
902     g_leServerDataReceivedCallback = callback;
903     oc_mutex_unlock(g_leReqRespCbMutex);
904
905     OIC_LOG(DEBUG, TAG, "OUT");
906 }
907
908 void CASetBLEServerErrorHandleCallback(CABLEErrorHandleCallback callback)
909 {
910     g_serverErrorCallback = callback;
911 }
912
913 bool CALEServerIsConnected(const char* address)
914 {
915     //@Todo
916     return true;
917 }
918
919 uint16_t CALEServerGetMtuSize(const char* address)
920 {
921     OIC_LOG(DEBUG, TAG, "IN");
922     VERIFY_NON_NULL_RET(address, TAG, "address is null",
923                         CA_SUPPORTED_BLE_MTU_SIZE - CA_BLE_MTU_HEADER_SIZE);
924     //@Todo
925     OIC_LOG(INFO, TAG,
926             "bt_device_get_att_mtu is not supported");
927     return CA_SUPPORTED_BLE_MTU_SIZE - CA_BLE_MTU_HEADER_SIZE;
928 }
929