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