Replace glib threadpool usage with a 'dumb' thread implementation.
[platform/upstream/iotivity.git] / resource / csdk / connectivity / src / bt_le_adapter / tizen / cableserver.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_product.h>
24
25 #include "cableserver.h"
26 #include <pthread.h>
27 #include "cacommon.h"
28 #include "caadapterutils.h"
29 #include <gio/gio.h>
30 #include "camutex.h"
31 #include "caqueueingthread.h"
32 #include "caadapterutils.h"
33 #include "camsgparser.h"
34 #include "cableutil.h"
35 #include "oic_string.h"
36 #include "oic_malloc.h"
37
38 /**
39  * @def TZ_BLE_SERVER_TAG
40  * @brief Logging tag for module name
41  */
42 #define TZ_BLE_SERVER_TAG "TZ_BLE_GATT_SERVER"
43
44 /**
45  * @def CA_BLE_SERVICE_UUID
46  * @brief UUID of OIC service. This UUID is common across all platoform for LE transport.
47  */
48 #define CA_BLE_SERVICE_UUID  "713D0000-503E-4C75-BA94-3148F18D941E"
49
50 /**
51  * @def CA_BLE_READ_CHAR_UUID
52  * @brief UUID of read characteristic. This UUID is common across all platoform for LE transport.
53  */
54 #define CA_BLE_READ_CHAR_UUID "713D0002-503E-4C75-BA94-3148F18D941E"
55
56 /**
57  * @def CA_BLE_WRITE_CHAR_UUID
58  * @brief UUID of write characteristic. This UUID is common across all platoform for LE transport.
59  */
60 #define CA_BLE_WRITE_CHAR_UUID "713D0003-503E-4C75-BA94-3148F18D941E"
61
62 /**
63  * @def CA_BLE_INITIAL_BUF_SIZE
64  * @brief Initial buffer size for Gatt Server.
65  */
66 #define CA_BLE_INITIAL_BUF_SIZE 512
67
68 /**
69  * @var g_gattSvcPath
70  * @brief attribute handler for OIC server attribute.
71  */
72 static char *g_gattSvcPath = NULL;
73
74 /**
75  * @var g_gattReadCharPath
76  * @brief attribute handler for readCharacteristic of OIC server
77  */
78 static char *g_gattReadCharPath = NULL;
79
80 /**
81  * @var g_gattWriteCharPath
82  * @brief attribute handler for writeCharacteristic of OIC server
83  */
84 static char *g_gattWriteCharPath = NULL;
85
86 /**
87  * @var g_hAdvertiser
88  * @brief handler for OIC advertiser.
89  */
90 static bt_advertiser_h g_hAdvertiser = NULL;
91
92 /**
93  * @var    g_bleServerDataReceivedCallback
94  * @brief  Maintains the callback to be notified on receival of network packets from other
95  *           BLE devices
96  */
97 static CABLEServerDataReceivedCallback g_bleServerDataReceivedCallback = NULL;
98
99 /**
100  * @var g_isBleGattServerStarted
101  * @brief Boolean variable to keep the state of the GATTServer
102  */
103 static bool g_isBleGattServerStarted = false;
104
105 /**
106  * @var g_bleServerStateMutex
107  * @brief Mutex to synchronize the calls to be done to the platform from GATTServer
108  *           interfaces from different threads.
109  */
110 static ca_mutex g_bleServerStateMutex = NULL;
111
112 /**
113  * @var g_bleCharacteristicMutex
114  * @brief Mutex to synchronize writing operations on the characteristics.
115  */
116 static  ca_mutex g_bleCharacteristicMutex = NULL;
117
118 /**
119  * @var g_bleServiceMutex
120  * @brief  Mutex to synchronize to create the OIC service..
121  */
122 static  ca_mutex g_bleServiceMutex = NULL;
123
124  /**
125  * @var g_bleClientBDAddressMutex
126  * @brief Mutex to synchronize the client BD Address update on server side.
127  */
128 static ca_mutex g_bleClientBDAddressMutex = NULL;
129
130
131 /**
132  * @var g_bleReqRespCbMutex
133  * @brief Mutex to synchronize access to the requestResponse callback to be called
134  *           when the data needs to be sent from GATTClient.
135  */
136 static  ca_mutex g_bleReqRespCbMutex = NULL;
137
138 /**
139  * @var g_bleServerThreadPoolMutex
140  * @brief Mutex to synchronize the task to be pushed to thread pool.
141  */
142 static ca_mutex g_bleServerThreadPoolMutex = NULL;
143
144 /**
145  * @struct gRemoteAddress
146  * @brief Remote address of Gatt client
147  *
148  */
149 static char *g_remoteClientAddress = NULL;
150
151 /**
152  * @var g_eventLoop
153  * @brief gmainLoop to manage the threads to receive the callback from the platfrom.
154  */
155 static GMainLoop *g_eventLoop = NULL;
156
157 /**
158  * @var g_bleServerThreadPool
159  * @brief reference to threadpool
160  */
161 static ca_thread_pool_t g_bleServerThreadPool = NULL;
162
163 void CABleGattServerConnectionStateChangedCb(int result, bool connected,
164                                        const char *remoteAddress, void *userData)
165 {
166     OIC_LOG(DEBUG, TZ_BLE_SERVER_TAG, "IN");
167
168     OIC_LOG_V(DEBUG, TZ_BLE_SERVER_TAG, "CABleGattConnectionStateChangedCb result[%d]", result);
169
170     VERIFY_NON_NULL_VOID(remoteAddress, TZ_BLE_SERVER_TAG, "remote address is NULL");
171
172     if (connected)
173     {
174         OIC_LOG_V(DEBUG, TZ_BLE_SERVER_TAG, "Connected to [%s]", remoteAddress);
175
176         ca_mutex_lock(g_bleClientBDAddressMutex);
177         g_remoteClientAddress = OICStrdup(remoteAddress);
178         ca_mutex_unlock(g_bleClientBDAddressMutex);
179
180         VERIFY_NON_NULL_VOID(g_remoteClientAddress, TZ_BLE_SERVER_TAG, "Malloc failed");
181     }
182     OIC_LOG(DEBUG, TZ_BLE_SERVER_TAG, "OUT");
183 }
184
185 CAResult_t CAStartBleGattServer()
186 {
187     OIC_LOG(DEBUG, TZ_BLE_SERVER_TAG, "IN");
188
189     CAResult_t ret = CAInitGattServerMutexVariables();
190     if (CA_STATUS_OK != ret )
191     {
192         OIC_LOG(ERROR, TZ_BLE_SERVER_TAG, "CAInitGattServerMutexVariables failed!");
193         CATerminateGattServerMutexVariables();
194         return CA_SERVER_NOT_STARTED;
195     }
196
197     ca_mutex_lock(g_bleServerThreadPoolMutex);
198     if (NULL == g_bleServerThreadPool)
199     {
200         OIC_LOG(ERROR, TZ_BLE_SERVER_TAG, "g_bleServerThreadPool is NULL");
201         ca_mutex_unlock(g_bleServerThreadPoolMutex);
202         return CA_STATUS_FAILED;
203     }
204
205     ret = ca_thread_pool_add_task(g_bleServerThreadPool, CAStartBleGattServerThread,
206                                  NULL);
207     if (CA_STATUS_OK != ret)
208     {
209         OIC_LOG_V(ERROR, TZ_BLE_SERVER_TAG, "ca_thread_pool_add_task failed with ret [%d]", ret);
210         ca_mutex_unlock(g_bleServerThreadPoolMutex);
211         return CA_STATUS_FAILED;
212     }
213
214     ca_mutex_unlock(g_bleServerThreadPoolMutex);
215     OIC_LOG(DEBUG, TZ_BLE_SERVER_TAG, "OUT");
216     return CA_STATUS_OK;
217 }
218
219 void CAStartBleGattServerThread(void *data)
220 {
221     OIC_LOG(DEBUG, TZ_BLE_SERVER_TAG, "IN");
222     ca_mutex_lock(g_bleServerStateMutex);
223     if (true == g_isBleGattServerStarted)
224     {
225         OIC_LOG(ERROR, TZ_BLE_SERVER_TAG, "Gatt Server is already running");
226         ca_mutex_unlock(g_bleServerStateMutex);
227         CATerminateBleGattServer();
228         return;
229     }
230
231     CAResult_t ret  =  CAInitBleGattService();
232     if (CA_STATUS_OK != ret )
233     {
234         OIC_LOG(ERROR, TZ_BLE_SERVER_TAG, "_bt_gatt_init_service failed");
235         ca_mutex_unlock(g_bleServerStateMutex);
236         CATerminateBleGattServer();
237         return;
238     }
239
240     sleep(5); // Sleep is must because of the platform issue.
241
242     char *serviceUUID = CA_BLE_SERVICE_UUID;
243
244     ret  = CAAddNewBleServiceInGattServer(serviceUUID);
245     if (CA_STATUS_OK != ret )
246     {
247         OIC_LOG(ERROR, TZ_BLE_SERVER_TAG, "CAAddNewBleServiceInGattServer failed");
248         ca_mutex_unlock(g_bleServerStateMutex);
249         CATerminateBleGattServer();
250         return;
251     }
252
253     char *charReadUUID = CA_BLE_READ_CHAR_UUID;
254     char charReadValue[] = {33, 44, 55, 66}; // These are initial random values
255
256     ret = CAAddNewCharacteristicsToGattServer(g_gattSvcPath, charReadUUID, charReadValue,
257             CA_BLE_INITIAL_BUF_SIZE, false); // For Read Characteristics.
258     if (CA_STATUS_OK != ret )
259     {
260         OIC_LOG(ERROR, TZ_BLE_SERVER_TAG, "CAAddNewCharacteristicsToGattServer failed");
261         ca_mutex_unlock(g_bleServerStateMutex);
262         CATerminateBleGattServer();
263         return;
264     }
265
266     char *charWriteUUID = CA_BLE_WRITE_CHAR_UUID;
267     char charWriteValue[] = {33, 44, 55, 66}; // These are initial random values
268
269
270     ret = CAAddNewCharacteristicsToGattServer(g_gattSvcPath, charWriteUUID, charWriteValue,
271             CA_BLE_INITIAL_BUF_SIZE, true); // For Write Characteristics.
272     if (CA_STATUS_OK != ret )
273     {
274         OIC_LOG(ERROR, TZ_BLE_SERVER_TAG, "CAAddNewCharacteristicsToGattServer failed");
275         ca_mutex_unlock(g_bleServerStateMutex);
276         CATerminateBleGattServer();
277         return;
278     }
279
280     ret = CARegisterBleServicewithGattServer(g_gattSvcPath);
281     if (CA_STATUS_OK != ret )
282     {
283         OIC_LOG(ERROR, TZ_BLE_SERVER_TAG, "CARegisterBleServicewithGattServer failed");
284         ca_mutex_unlock(g_bleServerStateMutex);
285         CATerminateBleGattServer();
286         return;
287     }
288
289     int res = bt_gatt_set_connection_state_changed_cb(CABleGattServerConnectionStateChangedCb,
290                                                           NULL);
291     if (BT_ERROR_NONE != res)
292     {
293         OIC_LOG_V(ERROR, TZ_BLE_SERVER_TAG,
294                   "bt_gatt_set_connection_state_changed_cb Failed with return as [%s]",
295                   CABTGetErrorMsg(res));
296         return;
297     }
298
299     bt_adapter_le_create_advertiser(&g_hAdvertiser);
300     if (NULL == g_hAdvertiser)
301     {
302         OIC_LOG(ERROR, TZ_BLE_SERVER_TAG, "g_hAdvertiser is NULL");
303         ca_mutex_unlock(g_bleServerStateMutex);
304         CATerminateBleGattServer();
305         return;
306     }
307
308     res = bt_adapter_le_start_advertising(g_hAdvertiser, NULL, NULL, NULL);
309     if (BT_ERROR_NONE != res)
310     {
311         OIC_LOG_V(DEBUG, TZ_BLE_SERVER_TAG, "bt_adapter_le_start_advertising failed with ret [%d] ",
312                   res);
313         ca_mutex_unlock(g_bleServerStateMutex);
314         CATerminateBleGattServer();
315         return;
316     }
317
318     g_isBleGattServerStarted = true;
319
320     ca_mutex_unlock(g_bleServerStateMutex);
321
322     OIC_LOG(DEBUG, TZ_BLE_SERVER_TAG,
323             "LE Server initialization complete.");
324
325     GMainContext *thread_context = NULL;
326
327     thread_context = g_main_context_new();
328
329     g_eventLoop = g_main_loop_new(thread_context, FALSE);
330
331     g_main_context_push_thread_default(thread_context);
332
333     g_main_loop_run(g_eventLoop);
334
335     OIC_LOG(DEBUG, TZ_BLE_SERVER_TAG, "OUT");
336 }
337
338 CAResult_t CAStopBleGattServer()
339 {
340     OIC_LOG(DEBUG, TZ_BLE_SERVER_TAG, "IN");
341
342     ca_mutex_lock(g_bleServerStateMutex);
343
344     if (false == g_isBleGattServerStarted)
345     {
346         OIC_LOG(ERROR, TZ_BLE_SERVER_TAG, "Gatt Server is not running to stop");
347
348         ca_mutex_unlock(g_bleServerStateMutex);
349         return CA_STATUS_OK;
350     }
351     ca_mutex_unlock(g_bleServerStateMutex);
352
353     OIC_LOG(DEBUG, TZ_BLE_SERVER_TAG, "OUT");
354     return CA_STATUS_OK;
355 }
356
357 void CATerminateBleGattServer()
358 {
359     OIC_LOG(DEBUG, TZ_BLE_SERVER_TAG, "IN");
360
361     g_isBleGattServerStarted = false;
362
363     ca_mutex_lock(g_bleServerStateMutex);
364     GMainContext  *context_event_loop = NULL;
365     // Required for waking up the thread which is running in gmain loop
366     if ( NULL != g_eventLoop)
367     {
368         context_event_loop = g_main_loop_get_context(g_eventLoop);
369     }
370     if (context_event_loop)
371     {
372         OIC_LOG_V(DEBUG,  TZ_BLE_SERVER_TAG, "g_eventLoop context %x", context_event_loop);
373         g_main_context_wakeup(context_event_loop);
374
375         // Kill g main loops and kill threads
376         g_main_loop_quit(g_eventLoop);
377     }
378     else
379     {
380         OIC_LOG(ERROR, TZ_BLE_SERVER_TAG, "g_eventLoop context is NULL");
381     }
382
383     if (NULL != g_hAdvertiser )
384     {
385         int ret = 0;
386         ret  = bt_adapter_le_stop_advertising(g_hAdvertiser);
387         if (0 != ret)
388         {
389             OIC_LOG_V(ERROR, TZ_BLE_SERVER_TAG,
390                       "bt_adapter_le_stop_advertising failed with ret [%d]", ret);
391         }
392
393         ret = bt_adapter_le_destroy_advertiser(g_hAdvertiser);
394         if (0 != ret)
395         {
396             OIC_LOG_V(ERROR, TZ_BLE_SERVER_TAG,
397                       "bt_adapter_le_destroy_advertiser failed with ret [%d]", ret);
398         }
399         g_hAdvertiser = NULL;
400     }
401
402     CAResult_t res = CARemoveAllBleServicesFromGattServer();
403     if (CA_STATUS_OK != res)
404     {
405         OIC_LOG(ERROR, TZ_BLE_SERVER_TAG, "removeAllBleServicesFromGattServer failed");
406     }
407
408     res =  CADeInitBleGattService();
409     if (CA_STATUS_OK != res)
410     {
411         OIC_LOG_V(ERROR, TZ_BLE_SERVER_TAG, "_bt_gatt_deinit_service failed with ret [%d]", res);
412     }
413
414     ca_mutex_lock(g_bleClientBDAddressMutex);
415     OICFree(g_remoteClientAddress);
416     ca_mutex_unlock(g_bleClientBDAddressMutex);
417     // free service Path(unique identifier for ble service)
418     ca_mutex_lock(g_bleServiceMutex);
419     OICFree(g_gattSvcPath);
420     g_gattSvcPath = NULL;
421     ca_mutex_unlock(g_bleServiceMutex);
422
423     // freeing characteristics
424     ca_mutex_lock(g_bleCharacteristicMutex);
425     OICFree(g_gattReadCharPath);
426     g_gattReadCharPath = NULL;
427     OICFree(g_gattWriteCharPath);
428     g_gattWriteCharPath = NULL;
429     ca_mutex_unlock(g_bleCharacteristicMutex);
430
431     ca_mutex_unlock(g_bleServerStateMutex);
432
433     // Terminating all mutex variables.
434     CATerminateGattServerMutexVariables();
435     OIC_LOG(DEBUG, TZ_BLE_SERVER_TAG, "OUT");
436 }
437
438 CAResult_t CAInitGattServerMutexVariables()
439 {
440     OIC_LOG(DEBUG, TZ_BLE_SERVER_TAG, "IN");
441     if (NULL == g_bleServerStateMutex)
442     {
443         g_bleServerStateMutex = ca_mutex_new();
444         if (NULL == g_bleServerStateMutex)
445         {
446             OIC_LOG(ERROR, TZ_BLE_SERVER_TAG, "ca_mutex_new failed");
447             return CA_STATUS_FAILED;
448         }
449     }
450
451     if (NULL == g_bleServiceMutex)
452     {
453         g_bleServiceMutex = ca_mutex_new();
454         if (NULL == g_bleServiceMutex)
455         {
456             OIC_LOG(ERROR, TZ_BLE_SERVER_TAG, "ca_mutex_new failed");
457             return CA_STATUS_FAILED;
458         }
459     }
460
461     if (NULL == g_bleCharacteristicMutex)
462     {
463         g_bleCharacteristicMutex = ca_mutex_new();
464         if (NULL == g_bleCharacteristicMutex)
465         {
466             OIC_LOG(ERROR, TZ_BLE_SERVER_TAG, "ca_mutex_new failed");
467             return CA_STATUS_FAILED;
468         }
469     }
470
471     if (NULL == g_bleReqRespCbMutex)
472     {
473         g_bleReqRespCbMutex = ca_mutex_new();
474         if (NULL == g_bleReqRespCbMutex)
475         {
476             OIC_LOG(ERROR, TZ_BLE_SERVER_TAG, "ca_mutex_new failed");
477             return CA_STATUS_FAILED;
478         }
479     }
480
481     if (NULL == g_bleClientBDAddressMutex)
482     {
483         g_bleClientBDAddressMutex = ca_mutex_new();
484         if (NULL == g_bleClientBDAddressMutex)
485         {
486             OIC_LOG(ERROR, TZ_BLE_SERVER_TAG, "ca_mutex_new failed");
487             return CA_STATUS_FAILED;
488         }
489     }
490
491     return CA_STATUS_OK;
492 }
493
494 void CATerminateGattServerMutexVariables()
495 {
496     OIC_LOG(DEBUG, TZ_BLE_SERVER_TAG, "IN");
497     ca_mutex_free(g_bleServerStateMutex);
498     g_bleServerStateMutex = NULL;
499
500     ca_mutex_free(g_bleClientBDAddressMutex);
501     g_bleClientBDAddressMutex = NULL;
502
503     g_bleServerStateMutex = NULL;
504     ca_mutex_free(g_bleServiceMutex);
505     g_bleServiceMutex = NULL;
506     ca_mutex_free(g_bleCharacteristicMutex);
507     g_bleCharacteristicMutex = NULL;
508     ca_mutex_free(g_bleReqRespCbMutex);
509     g_bleReqRespCbMutex = NULL;
510
511     OIC_LOG(DEBUG, TZ_BLE_SERVER_TAG, "OUT");
512 }
513
514 CAResult_t CAInitBleGattService()
515 {
516     OIC_LOG(DEBUG, TZ_BLE_SERVER_TAG, "IN");
517
518     int ret =  _bt_gatt_init_service();
519     if (0 != ret)
520     {
521         OIC_LOG_V(ERROR, TZ_BLE_SERVER_TAG, "_bt_gatt_deinit_service failed with ret [%d]", ret);
522         return CA_STATUS_FAILED;
523     }
524
525     OIC_LOG(DEBUG, TZ_BLE_SERVER_TAG, "OUT");
526     return CA_STATUS_OK;
527 }
528
529 CAResult_t CADeInitBleGattService()
530 {
531     OIC_LOG(DEBUG, TZ_BLE_SERVER_TAG, "IN");
532
533     int ret =  _bt_gatt_deinit_service();
534     if (0 != ret)
535     {
536         OIC_LOG_V(ERROR, TZ_BLE_SERVER_TAG, "_bt_gatt_deinit_service failed with ret [%d]", ret);
537         return CA_STATUS_FAILED;
538     }
539
540     OIC_LOG(DEBUG, TZ_BLE_SERVER_TAG, "OUT");
541     return CA_STATUS_OK;
542 }
543
544 void CASetBleServerThreadPoolHandle(ca_thread_pool_t handle)
545 {
546     OIC_LOG(DEBUG, TZ_BLE_SERVER_TAG, "IN");
547     ca_mutex_lock(g_bleServerThreadPoolMutex);
548     g_bleServerThreadPool = handle;
549     ca_mutex_unlock(g_bleServerThreadPoolMutex);
550     OIC_LOG(DEBUG, TZ_BLE_SERVER_TAG, "OUT");
551 }
552
553 CAResult_t CAAddNewBleServiceInGattServer(const char *serviceUUID)
554 {
555     OIC_LOG(DEBUG, TZ_BLE_SERVER_TAG, "IN");
556
557     VERIFY_NON_NULL(serviceUUID, NULL, "Param serviceUUID is NULL");
558
559     OIC_LOG_V(DEBUG, TZ_BLE_SERVER_TAG, "service uuid %s", serviceUUID);
560
561     char *svcPath = NULL;
562
563     int ret = bt_gatt_add_service(serviceUUID, &svcPath);
564     if (0 != ret)
565     {
566         OIC_LOG_V(ERROR, TZ_BLE_SERVER_TAG, "bt_gatt_add_service failed with ret [%d]", ret);
567         return CA_STATUS_FAILED;
568     }
569
570     if (NULL != svcPath)
571     {
572         OIC_LOG_V(ERROR, TZ_BLE_SERVER_TAG,
573                   "AddNewBleServiceInGattServer ServicePath obtained is %s", svcPath);
574
575         ca_mutex_lock(g_bleServiceMutex);
576
577         if (NULL != g_gattSvcPath)
578         {
579             OICFree(g_gattSvcPath);
580             g_gattSvcPath = NULL;
581         }
582         g_gattSvcPath = svcPath;
583
584         ca_mutex_unlock(g_bleServiceMutex);
585     }
586
587     OIC_LOG(DEBUG, TZ_BLE_SERVER_TAG, "OUT");
588     return CA_STATUS_OK;
589 }
590
591 CAResult_t CARemoveBleServiceFromGattServer(const char *svcPath)
592 {
593     OIC_LOG(DEBUG, TZ_BLE_SERVER_TAG, "IN");
594
595     VERIFY_NON_NULL(svcPath, NULL, "Param svcPath is NULL");
596
597     int ret = bt_gatt_remove_service(svcPath);
598
599     if (0 != ret)
600     {
601         OIC_LOG_V(ERROR, TZ_BLE_SERVER_TAG, "bt_gatt_remove_service failed [%d]", ret);
602         return CA_STATUS_FAILED;
603     }
604
605     OIC_LOG(DEBUG, TZ_BLE_SERVER_TAG, "OUT");
606     return CA_STATUS_OK;
607 }
608
609 CAResult_t CARemoveAllBleServicesFromGattServer()
610 {
611     OIC_LOG(DEBUG, TZ_BLE_SERVER_TAG, "IN");
612     int ret = bt_gatt_delete_services();
613     if (0 != ret)
614     {
615         OIC_LOG_V(ERROR, TZ_BLE_SERVER_TAG, "bt_gatt_delete_services  failed with ret [%d]", ret);
616         return CA_STATUS_FAILED;
617     }
618
619     OIC_LOG(DEBUG, TZ_BLE_SERVER_TAG, "OUT");
620     return CA_STATUS_OK;
621 }
622
623 void CABleGattRemoteCharacteristicWriteCb(char *charPath,
624         unsigned char *charValue,
625         int charValueLen, void *userData)
626 {
627     OIC_LOG(DEBUG, TZ_BLE_SERVER_TAG, "IN");
628
629     if (NULL == charPath || NULL == charValue)
630     {
631         OIC_LOG(ERROR, TZ_BLE_SERVER_TAG, "Param callback values are NULL");
632         return;
633     }
634
635     OIC_LOG_V(DEBUG, TZ_BLE_SERVER_TAG, "charPath = [%s] charValue = [%s] len [%d]", charPath,
636               charValue, charValueLen);
637
638     char *data = (char *)OICMalloc(sizeof(char) * charValueLen);
639     if (NULL == data)
640     {
641         OIC_LOG(ERROR, TZ_BLE_SERVER_TAG, "Malloc failed!");
642         return;
643     }
644
645     strncpy(data, (char *)charValue, charValueLen);
646
647     ca_mutex_lock(g_bleReqRespCbMutex);
648     if (NULL == g_bleServerDataReceivedCallback)
649     {
650         OIC_LOG(ERROR, TZ_BLE_SERVER_TAG, "gReqRespCallback is NULL!");
651         ca_mutex_unlock(g_bleReqRespCbMutex);
652         OICFree(data);
653         return;
654     }
655
656     OIC_LOG(DEBUG, TZ_BLE_SERVER_TAG, "Sending data up !");
657     ca_mutex_lock(g_bleClientBDAddressMutex);
658     uint32_t sentLength = 0;
659     g_bleServerDataReceivedCallback(g_remoteClientAddress, OIC_BLE_SERVICE_ID,
660                                      data, charValueLen, &sentLength);
661     ca_mutex_unlock(g_bleClientBDAddressMutex);
662
663     ca_mutex_unlock(g_bleReqRespCbMutex);
664
665     OICFree(data);
666     OIC_LOG(DEBUG, TZ_BLE_SERVER_TAG, "OUT");
667 }
668
669 CAResult_t CARegisterBleServicewithGattServer(const char *svcPath)
670 {
671     OIC_LOG(DEBUG, TZ_BLE_SERVER_TAG, "IN");
672
673     VERIFY_NON_NULL(svcPath, NULL, "Param svcPath is NULL");
674
675     OIC_LOG_V(DEBUG, TZ_BLE_SERVER_TAG, "svcPath:%s", svcPath);
676
677     int ret = bt_gatt_register_service(svcPath, CABleGattRemoteCharacteristicWriteCb, NULL);
678
679     if (0 != ret)
680     {
681         OIC_LOG_V(ERROR, TZ_BLE_SERVER_TAG, "bt_gatt_register_service failed with ret [%d]", ret);
682         return CA_STATUS_FAILED;
683     }
684
685     OIC_LOG(DEBUG, TZ_BLE_SERVER_TAG, "OUT");
686     return CA_STATUS_OK;
687 }
688
689 CAResult_t CAAddNewCharacteristicsToGattServer(const char *svcPath, const char *charUUID,
690         const char *charValue, int charValueLen, bool read)
691 {
692
693     OIC_LOG(DEBUG, TZ_BLE_SERVER_TAG, "IN");
694
695     static const char *charFlags[] = {"read", "write", "notify", "indicate"};
696
697     static const size_t flagLen = sizeof(charFlags) / sizeof(charFlags[0]);
698
699     char *charPath = NULL;
700     int ret = bt_gatt_add_characteristic(charUUID, charValue, charValueLen, charFlags, flagLen,
701                   svcPath, &charPath);
702
703     if (0 != ret || NULL == charPath)
704     {
705         OIC_LOG_V(ERROR, TZ_BLE_SERVER_TAG,
706                   "bt_gatt_add_characteristic  failed with ret [%d]", ret);
707         return CA_STATUS_FAILED;
708     }
709
710     OIC_LOG_V(DEBUG, TZ_BLE_SERVER_TAG,
711               "bt_gatt_add_characteristic charPath obtained: %s", charPath);
712
713     ca_mutex_lock(g_bleCharacteristicMutex);
714
715     if (!read)
716     {
717         if (NULL != g_gattReadCharPath)
718         {
719             OICFree(g_gattReadCharPath);
720             g_gattReadCharPath = NULL;
721         }
722         g_gattReadCharPath = charPath;
723
724     }
725     else
726     {
727         if (NULL != g_gattWriteCharPath)
728         {
729             OICFree(g_gattWriteCharPath);
730             g_gattWriteCharPath = NULL;
731         }
732         g_gattWriteCharPath = charPath;
733     }
734
735     ca_mutex_unlock(g_bleCharacteristicMutex);
736
737     OIC_LOG(DEBUG, TZ_BLE_SERVER_TAG, "OUT");
738     return CA_STATUS_OK;
739 }
740
741 CAResult_t CARemoveCharacteristicsFromGattServer(const char *charPath)
742 {
743     ///TODO: There is no api provided in bluetooth.h for removing characteristics.
744     return CA_STATUS_OK;
745 }
746
747 CAResult_t CAUpdateCharacteristicsInGattServer(const char *charValue,
748         const uint32_t charValueLen)
749 {
750     OIC_LOG(DEBUG, TZ_BLE_SERVER_TAG, "IN");
751
752     VERIFY_NON_NULL(charValue, NULL, "Param charValue is NULL");
753
754     ca_mutex_lock(g_bleCharacteristicMutex);
755
756     if (NULL  == g_gattWriteCharPath)
757     {
758         OIC_LOG(ERROR, TZ_BLE_SERVER_TAG, "g_gattWriteCharPath is NULL");
759         ca_mutex_unlock(g_bleCharacteristicMutex);
760         return CA_STATUS_FAILED;
761     }
762
763     char *data = (char *) OICMalloc(sizeof(char) * (charValueLen + 1));
764     if (NULL == data)
765     {
766         OIC_LOG(ERROR, TZ_BLE_SERVER_TAG, "malloc failed!");
767         ca_mutex_unlock(g_bleCharacteristicMutex);
768         return CA_STATUS_FAILED;
769     }
770
771     strncpy(data, charValue, charValueLen + 1);
772
773     OIC_LOG_V(DEBUG, TZ_BLE_SERVER_TAG, "updating characteristics char [%s] data [%s] dataLen [%d]",
774               (const char *)g_gattWriteCharPath, data, charValueLen);
775
776     int ret =  bt_gatt_update_characteristic(g_gattWriteCharPath, data, charValueLen);
777     if (0 != ret)
778     {
779         OIC_LOG_V(ERROR, TZ_BLE_SERVER_TAG,
780                   "bt_gatt_update_characteristic failed with return [%d]", ret);
781         OICFree(data);
782         data = NULL;
783         ca_mutex_unlock(g_bleCharacteristicMutex);
784         return CA_STATUS_FAILED;
785     }
786
787     OICFree(data);
788     ca_mutex_unlock(g_bleCharacteristicMutex);
789
790     OIC_LOG(ERROR, TZ_BLE_SERVER_TAG, "OUT");
791     return CA_STATUS_OK;
792 }
793
794 void CASetBLEReqRespServerCallback(CABLEServerDataReceivedCallback callback)
795 {
796     OIC_LOG(DEBUG, TZ_BLE_SERVER_TAG, "IN");
797
798     ca_mutex_lock(g_bleReqRespCbMutex);
799
800     g_bleServerDataReceivedCallback = callback;
801
802     ca_mutex_unlock(g_bleReqRespCbMutex);
803
804     OIC_LOG(DEBUG, TZ_BLE_SERVER_TAG, "OUT");
805 }