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