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