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