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