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