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