Update snapshot(2018-01-10)
[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             bt_gatt_server_deinitialize();
568             return CA_STATUS_FAILED;
569         }
570     }
571
572     OIC_LOG(DEBUG, TAG, "OUT");
573     return CA_STATUS_OK;
574 }
575
576 CAResult_t CADeInitLEGattServer()
577 {
578     OIC_LOG(DEBUG, TAG, "IN");
579
580     int ret = bt_gatt_server_unregister_all_services(g_gattServer);
581     if (0 != ret)
582     {
583         OIC_LOG_V(ERROR, TAG, "bt_gatt_server_unregister_all_services failed with ret[%s]",
584                   CALEGetErrorMsg(ret));
585         // CONPRO-1181 continue even bt API fails during DeInit
586         //return CA_STATUS_FAILED;
587     }
588
589     ret = bt_gatt_server_destroy(g_gattServer);
590     if (0 != ret)
591     {
592         OIC_LOG_V(ERROR, TAG, "bt_gatt_server_destroy failed with ret[%s]",
593                   CALEGetErrorMsg(ret));
594         // CONPRO-1181 continue even bt API fails during DeInit
595         //return CA_STATUS_FAILED;
596     }
597     g_gattServer = NULL;
598
599     ret =  bt_gatt_server_deinitialize();
600     if (0 != ret)
601     {
602         OIC_LOG_V(ERROR, TAG, "bt_gatt_server_deinitialize failed with ret[%s]",
603                   CALEGetErrorMsg(ret));
604         // CONPRO-1181 continue even bt API fails during DeInit
605         //return CA_STATUS_FAILED;
606     }
607
608     OIC_LOG(DEBUG, TAG, "OUT");
609     return CA_STATUS_OK;
610 }
611
612 void CASetLEServerThreadPoolHandle(ca_thread_pool_t handle)
613 {
614     OIC_LOG(DEBUG, TAG, "IN");
615     oc_mutex_lock(g_leServerThreadPoolMutex);
616     g_leServerThreadPool = handle;
617     oc_mutex_unlock(g_leServerThreadPoolMutex);
618     OIC_LOG(DEBUG, TAG, "OUT");
619 }
620
621 CAResult_t CAAddNewLEServiceInGattServer(const char *serviceUUID)
622 {
623     OIC_LOG(DEBUG, TAG, "IN");
624
625     VERIFY_NON_NULL(serviceUUID, TAG, "serviceUUID");
626
627     OIC_LOG_V(DEBUG, TAG, "service uuid %s", serviceUUID);
628
629     bt_gatt_service_type_e type = BT_GATT_SERVICE_TYPE_PRIMARY;
630
631     oc_mutex_lock(g_leServiceMutex);
632     int ret = bt_gatt_service_create(serviceUUID, type, &g_gattSvcPath);
633     if (0 != ret)
634     {
635         oc_mutex_unlock(g_leServiceMutex);
636         OIC_LOG_V(ERROR, TAG, "bt_gatt_service_create failed with ret [%s]",
637                     CALEGetErrorMsg(ret));
638         return CA_STATUS_FAILED;
639     }
640     oc_mutex_unlock(g_leServiceMutex);
641
642     if (g_gattSvcPath)
643     {
644         OIC_LOG_V(DEBUG, TAG, "ServicePath obtained is %s", (char *)g_gattSvcPath);
645     }
646
647     OIC_LOG(DEBUG, TAG, "OUT");
648     return CA_STATUS_OK;
649 }
650
651 void CALEGattRemoteCharacteristicWriteCb(char *remoteAddress, bt_gatt_server_h server,
652                                          bt_gatt_h charPath, int offset, char *charValue,
653                                          int charValueLen, void *userData)
654 {
655     OIC_LOG(INFO, TAG, "IN - WriteCharCB");
656
657     if (NULL == charValue || NULL == remoteAddress)
658     {
659         OIC_LOG(ERROR, TAG, "Param callback values are NULL");
660         return;
661     }
662
663     OIC_LOG_V(DEBUG, TAG, "charPath = [%s] charValue = [%s] len [%d]", (char *)charPath,
664               charValue, charValueLen);
665
666     uint8_t *data = OICMalloc(charValueLen);
667     if (NULL == data)
668     {
669         OIC_LOG(ERROR, TAG, "Malloc failed!");
670         return;
671     }
672
673     memcpy(data, charValue, charValueLen);
674
675     oc_mutex_lock(g_leReqRespCbMutex);
676     if (NULL == g_leServerDataReceivedCallback)
677     {
678         OIC_LOG(ERROR, TAG, "gReqRespCallback is NULL!");
679         oc_mutex_unlock(g_leReqRespCbMutex);
680         OICFree(data);
681         return;
682     }
683
684     OIC_LOG(INFO, TAG, "Sending data up !");
685     uint32_t sentLength = 0;
686     g_leServerDataReceivedCallback(remoteAddress, data, charValueLen,
687                                     &sentLength);
688     oc_mutex_unlock(g_leReqRespCbMutex);
689     OICFree(data);
690     OIC_LOG(INFO, TAG, "OUT - WriteCharCB");
691 }
692
693 CAResult_t CARegisterLEServicewithGattServer(const bt_gatt_h svcPath)
694 {
695     OIC_LOG(DEBUG, TAG, "IN");
696
697     VERIFY_NON_NULL(svcPath, TAG, "svcPath");
698
699     OIC_LOG_V(DEBUG, TAG, "svcPath:%s", svcPath);
700
701     int ret = bt_gatt_server_register_service(g_gattServer, svcPath);
702     if (0 != ret)
703     {
704         OIC_LOG_V(ERROR, TAG, "bt_gatt_server_register_service failed with ret[%s]",
705                   CALEGetErrorMsg(ret));
706         return CA_STATUS_FAILED;
707     }
708
709     ret = bt_gatt_server_set_value_changed_cb(g_gattWriteCharPath,
710                                               CALEGattRemoteCharacteristicWriteCb, NULL);
711
712     if (0 != ret)
713     {
714         OIC_LOG_V(ERROR, TAG, "bt_gatt_server_set_value_changed_cb failed with ret[%s]",
715                   CALEGetErrorMsg(ret));
716         return CA_STATUS_FAILED;
717     }
718
719     OIC_LOG(DEBUG, TAG, "OUT");
720     return CA_STATUS_OK;
721 }
722
723 CAResult_t CAAddNewCharacteristicsToGattServer(const bt_gatt_h svcPath, const char *charUUID,
724                                                const char *charValue, int charValueLen, bool read)
725 {
726
727     OIC_LOG(DEBUG, TAG, "IN");
728
729     int permissions = BT_GATT_PERMISSION_READ | BT_GATT_PERMISSION_WRITE;
730     int properties;
731     if (read)
732     {
733         properties = BT_GATT_PROPERTY_INDICATE | BT_GATT_PROPERTY_READ;
734     }
735     else
736     {
737         properties = BT_GATT_PROPERTY_WRITE | BT_GATT_PROPERTY_READ;
738     }
739
740     bt_gatt_h charPath = NULL;
741
742     int ret = bt_gatt_characteristic_create(charUUID, permissions, properties, charValue,
743                                             charValueLen, &charPath);
744
745     if (0 != ret || NULL == charPath)
746     {
747         OIC_LOG_V(ERROR, TAG,
748                   "bt_gatt_add_characteristic  failed with ret [%s]", CALEGetErrorMsg(ret));
749         return CA_STATUS_FAILED;
750     }
751
752     OIC_LOG_V(DEBUG, TAG,
753               "bt_gatt_characteristic_create charPath obtained: %s", (char *)charPath);
754
755     if (read)
756     {
757         ret = bt_gatt_server_set_notification_state_change_cb(charPath, CALENotificationCb, NULL);
758         if (0 != ret)
759         {
760             OIC_LOG_V(ERROR, TAG,
761                       "bt_gatt_server_set_notification_state_change_cb  failed with ret[%s]",
762                       CALEGetErrorMsg(ret));
763             return CA_STATUS_FAILED;
764         }
765     }
766
767     ret =  bt_gatt_service_add_characteristic(svcPath, charPath);
768     if (0 != ret)
769     {
770         OIC_LOG_V(ERROR, TAG,
771                   "bt_gatt_service_add_characteristic  failed with ret[%s]",
772                   CALEGetErrorMsg(ret));
773         return CA_STATUS_FAILED;
774     }
775
776     oc_mutex_lock(g_leCharacteristicMutex);
777
778     if (read)
779     {
780         char desc_value[2] = {1, 0};  // Notification enabled.
781         bt_gatt_h descriptor = NULL;
782         permissions = BT_GATT_PERMISSION_READ | BT_GATT_PERMISSION_WRITE;
783         ret = bt_gatt_descriptor_create(CA_GATT_CONFIGURATION_DESC_UUID, permissions,
784                                         desc_value, sizeof(desc_value),
785                                         &descriptor);
786         if (0 != ret)
787         {
788             oc_mutex_unlock(g_leCharacteristicMutex);
789             OIC_LOG_V(ERROR, TAG,
790                       "bt_gatt_descriptor_create  failed with ret[%s]",
791                       CALEGetErrorMsg(ret));
792             return CA_STATUS_FAILED;
793         }
794
795         ret = bt_gatt_characteristic_add_descriptor(charPath, descriptor);
796         if (0 != ret)
797         {
798             oc_mutex_unlock(g_leCharacteristicMutex);
799             OIC_LOG_V(ERROR, TAG,
800                       "bt_gatt_characteristic_add_descriptor  failed with ret[%s]",
801                       CALEGetErrorMsg(ret));
802             return CA_STATUS_FAILED;
803         }
804
805         g_gattReadCharPath = charPath;
806     }
807     else
808     {
809         g_gattWriteCharPath = charPath;
810     }
811
812     oc_mutex_unlock(g_leCharacteristicMutex);
813
814     OIC_LOG(DEBUG, TAG, "OUT");
815     return CA_STATUS_OK;
816 }
817
818 CAResult_t CAUpdateCharacteristicsToGattClient(const char *address, const uint8_t *charValue,
819                                                uint32_t charValueLen)
820 {
821     OIC_LOG(DEBUG, TAG, "IN");
822
823     VERIFY_NON_NULL(charValue, TAG, "charValue");
824     VERIFY_NON_NULL(address, TAG, "address");
825
826     OIC_LOG_V(DEBUG, TAG, "Client's Unicast address for sending data [%s]", address);
827
828     oc_mutex_lock(g_leCharacteristicMutex);
829
830     if (NULL  == g_gattReadCharPath)
831     {
832         OIC_LOG(ERROR, TAG, "g_gattReadCharPath is NULL");
833         oc_mutex_unlock(g_leCharacteristicMutex);
834         return CA_STATUS_FAILED;
835     }
836
837     int ret = bt_gatt_set_value(g_gattReadCharPath, (char *)charValue, charValueLen);
838     if (0 != ret)
839     {
840         OIC_LOG_V(ERROR, TAG,
841                   "bt_gatt_set_value failed with return [%s]", CALEGetErrorMsg(ret));
842         oc_mutex_unlock(g_leCharacteristicMutex);
843         return CA_STATUS_FAILED;
844     }
845
846     ret = bt_gatt_server_notify(g_gattReadCharPath, false, CALEServerNotificationSentCB,
847                                 NULL);
848     if (0 != ret)
849     {
850         OIC_LOG_V(ERROR, TAG,
851                   "bt_gatt_server_notify failed with return [%s]", CALEGetErrorMsg(ret));
852         oc_mutex_unlock(g_leCharacteristicMutex);
853         return CA_STATUS_FAILED;
854     }
855
856     oc_mutex_unlock(g_leCharacteristicMutex);
857
858     OIC_LOG(DEBUG, TAG, "OUT");
859     return CA_STATUS_OK;
860 }
861
862 CAResult_t CAUpdateCharacteristicsToAllGattClients(const uint8_t *charValue, uint32_t charValueLen)
863 {
864     OIC_LOG(DEBUG, TAG, "IN");
865
866     VERIFY_NON_NULL(charValue, TAG, "charValue");
867
868     oc_mutex_lock(g_leCharacteristicMutex);
869
870     if (NULL  == g_gattReadCharPath)
871     {
872         OIC_LOG(ERROR, TAG, "g_gattReadCharPath is NULL");
873         oc_mutex_unlock(g_leCharacteristicMutex);
874         return CA_STATUS_FAILED;
875     }
876
877     int ret = bt_gatt_set_value(g_gattReadCharPath, (char *)charValue, charValueLen);
878     if (0 != ret)
879     {
880         OIC_LOG_V(ERROR, TAG, "bt_gatt_set_value failed with return[%s]", CALEGetErrorMsg(ret));
881         oc_mutex_unlock(g_leCharacteristicMutex);
882         return CA_STATUS_FAILED;
883     }
884
885     ret = bt_gatt_server_notify(g_gattReadCharPath, false, CALEServerNotificationSentCB,
886                                 NULL);
887     if (0 != ret)
888     {
889         OIC_LOG_V(ERROR, TAG,
890                   "bt_gatt_server_notify failed with return[%s]", CALEGetErrorMsg(ret));
891         oc_mutex_unlock(g_leCharacteristicMutex);
892         return CA_STATUS_FAILED;
893     }
894
895     oc_mutex_unlock(g_leCharacteristicMutex);
896
897     OIC_LOG(DEBUG, TAG, "OUT");
898     return CA_STATUS_OK;
899 }
900
901 void CASetLEReqRespServerCallback(CABLEDataReceivedCallback callback)
902 {
903     OIC_LOG(DEBUG, TAG, "IN");
904
905     oc_mutex_lock(g_leReqRespCbMutex);
906     g_leServerDataReceivedCallback = callback;
907     oc_mutex_unlock(g_leReqRespCbMutex);
908
909     OIC_LOG(DEBUG, TAG, "OUT");
910 }
911
912 void CASetBLEServerErrorHandleCallback(CABLEErrorHandleCallback callback)
913 {
914     g_serverErrorCallback = callback;
915 }
916
917 bool CALEServerIsConnected(const char* address)
918 {
919     //@Todo
920     return true;
921 }
922
923 uint16_t CALEServerGetMtuSize(const char* address)
924 {
925     OIC_LOG(DEBUG, TAG, "IN");
926     VERIFY_NON_NULL_RET(address, TAG, "address is null",
927                         CA_SUPPORTED_BLE_MTU_SIZE - CA_BLE_MTU_HEADER_SIZE);
928     //@Todo
929     OIC_LOG(INFO, TAG,
930             "bt_device_get_att_mtu is not supported");
931     return CA_SUPPORTED_BLE_MTU_SIZE - CA_BLE_MTU_HEADER_SIZE;
932 }
933