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