Update snapshot(2017-12-06)
[platform/upstream/iotivity.git] / resource / csdk / connectivity / src / bt_le_adapter / tizen / caleserver_vd.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 "octhread.h"
25 #include "caqueueingthread.h"
26 #include "cagattservice.h"
27 #include "oic_string.h"
28 #include "oic_malloc.h"
29 #include "caleutil.h"
30
31 /**
32  * Logging tag for module name
33  */
34 #define TAG "OIC_CA_LE_SERVER_VD"
35
36 /**
37  * The handle of the OIC server.
38  */
39 static bt_gatt_server_h g_gattServer = NULL;
40
41 /**
42  * The handle of the OIC service.
43  */
44 static bt_gatt_h g_gattSvcPath = NULL;
45
46 /**
47  * The handle of the OIC read characteristics.
48  */
49 static bt_gatt_h g_gattReadCharPath = NULL;
50
51 /**
52  * The handle of the OIC write characteristics.
53  */
54 static bt_gatt_h g_gattWriteCharPath = NULL;
55
56 /**
57  * The handle to control Bluetooth LE advertising.
58  */
59 static bt_advertiser_h g_hAdvertiser = NULL;
60
61 /**
62  * Callback register with LE adapter.  This callback is called on reception of any
63  * data from the remote device.
64  */
65 static CABLEDataReceivedCallback g_leServerDataReceivedCallback = NULL;
66
67 /**
68  * Callback to notify any error in LE adapter.
69  */
70 static CABLEErrorHandleCallback g_serverErrorCallback = NULL;
71
72 /**
73  * To keep the state of GATT server if started or not.
74  */
75 static bool g_isLEGattServerStarted = false;
76
77 /**
78  * Mutex to synchronize the calls to start and stop server.
79  */
80 static oc_mutex g_leServerStateMutex = NULL;
81
82 /**
83  * Mutex to synchronize writing operations on the characteristics.
84  */
85 static  oc_mutex g_leCharacteristicMutex = NULL;
86
87 /**
88  * Mutex to synchronize to creation of OIC service.
89  */
90 static  oc_mutex g_leServiceMutex = NULL;
91
92 /**
93  * Mutex to synchronize access to the requestResponse callback to be called
94  * when the data needs to be sent from GATTClient.
95  */
96 static  oc_mutex g_leReqRespCbMutex = NULL;
97
98 /**
99  * Mutex to synchronize the task to be pushed to thread pool.
100  */
101 static oc_mutex g_leServerThreadPoolMutex = NULL;
102
103 /**
104  * Reference to threadpool.
105  */
106 static ca_thread_pool_t g_leServerThreadPool = NULL;
107
108 /**
109  * GmainLoop to manage the threads to receive the callback from the platfrom.
110  */
111 static GMainLoop *g_eventLoop = NULL;
112
113 /**
114  * This contains the list of OIC clients connected to the server.
115  */
116 static LEClientInfoList *g_LEClientList = NULL;
117
118 /**
119  * Mutex to synchronize access to LE ClientList.
120  */
121 static oc_mutex g_LEClientListMutex = NULL;
122
123 /**
124  * State of connect state
125  */
126 static bool g_LEConnectedState = false;
127
128 void CALEGattServerConnectionStateChanged(bool connected, const char *remoteAddress)
129 {
130     VERIFY_NON_NULL_VOID(remoteAddress, TAG, "remote address");
131
132     CAResult_t res = CA_STATUS_OK;
133     if (connected)
134     {
135         OIC_LOG_V(DEBUG, TAG, "Connected to [%s]", remoteAddress);
136         g_LEConnectedState = true;
137         char *addr = OICStrdup(remoteAddress);
138         oc_mutex_lock(g_LEClientListMutex);
139         res  = CAAddLEClientInfoToList(&g_LEClientList, addr);
140         if (CA_STATUS_OK != res)
141         {
142             OIC_LOG(ERROR, TAG, "CAAddLEClientInfoToList failed");
143             oc_mutex_unlock(g_LEClientListMutex);
144             OICFree(addr);
145             return;
146         }
147         oc_mutex_unlock(g_LEClientListMutex);
148
149         /*
150          * TV Easysetup does not use IoTivity BLE advertisement.
151          */
152
153         // res = CALEStopAdvertise();
154         // if (CA_STATUS_OK != res)
155         // {
156         //     OIC_LOG_V(ERROR, TAG, "Failed to stop advertising [%d]", res);
157         //     return;
158         // }
159     }
160     else
161     {
162         OIC_LOG_V(DEBUG, TAG, "Disconnected from [%s]", remoteAddress);
163         g_LEConnectedState = false;
164         oc_mutex_lock(g_LEClientListMutex);
165         CARemoveLEClientInfoFromList(&g_LEClientList, remoteAddress);
166         oc_mutex_unlock(g_LEClientListMutex);
167
168         /*
169          * TV Easysetup does not use IoTivity BLE advertisement.
170          */
171
172         // res = CALEStartAdvertise();
173         // if (CA_STATUS_OK != res)
174         // {
175         //     OIC_LOG_V(ERROR, TAG, "Failed to start advertising [%d]", res);
176         //     return;
177         // }
178     }
179 }
180
181 #ifdef BLE_TIZEN_30
182 void CALEServerNotificationSentCB(int result, const char *remote_address, bt_gatt_server_h server,
183                                   bt_gatt_h characteristic, bool completed, void *user_data)
184 #else
185 void CALEServerNotificationSentCB(int result, char *remote_address, bt_gatt_server_h server,
186                                   bt_gatt_h characteristic, bool completed, void *user_data)
187 #endif
188 {
189     (void)server;
190     (void)characteristic;
191     (void)completed;
192     (void)user_data;
193
194     OIC_LOG_V(DEBUG, TAG, "Notification to the device[%s] result[%d]", remote_address, result);
195 }
196
197 CAResult_t CAStartLEGattServer()
198 {
199     OIC_LOG(DEBUG, TAG, "IN");
200
201     oc_mutex_lock(g_leServerStateMutex);
202     if (true == g_isLEGattServerStarted)
203     {
204         OIC_LOG(ERROR, TAG, "Gatt Server is already running");
205         oc_mutex_unlock(g_leServerStateMutex);
206         return CA_STATUS_OK;
207     }
208
209     CAResult_t ret = CAInitLEGattServer();
210     if (CA_STATUS_OK != ret)
211     {
212         OIC_LOG_V(ERROR, TAG, "CAInitLEGattServer failed[%d]", ret);
213         oc_mutex_unlock(g_leServerStateMutex);
214         CATerminateLEGattServer();
215         return CA_STATUS_FAILED;
216     }
217
218     ret  = CAAddNewLEServiceInGattServer(CA_GATT_SERVICE_UUID);
219     if (CA_STATUS_OK != ret)
220     {
221         OIC_LOG_V(ERROR, TAG, "CAAddNewLEServiceInGattServer failed[%d]", ret);
222         oc_mutex_unlock(g_leServerStateMutex);
223         CATerminateLEGattServer();
224         return CA_STATUS_FAILED;
225     }
226
227     static const char charReadUUID[] = CA_GATT_RESPONSE_CHRC_UUID;
228     char charReadValue[] = {33, 44, 55, 66}; // These are initial random values
229
230     // For Read Characteristics.
231     ret = CAAddNewCharacteristicsToGattServer(g_gattSvcPath, charReadUUID, charReadValue,
232                                               sizeof(charReadValue), true);
233     if (CA_STATUS_OK != ret)
234     {
235         OIC_LOG_V(ERROR, TAG, "CAAddNewCharacteristicsToGattServer failed[%d]", ret);
236         oc_mutex_unlock(g_leServerStateMutex);
237         CATerminateLEGattServer();
238         return CA_STATUS_FAILED;
239     }
240
241     static const char charWriteUUID[] = CA_GATT_REQUEST_CHRC_UUID;
242     char charWriteValue[] = {33, 44, 55, 66}; // These are initial random values
243
244
245     ret = CAAddNewCharacteristicsToGattServer(g_gattSvcPath, charWriteUUID, charWriteValue,
246             sizeof(charWriteValue), false); // For Write Characteristics.
247     if (CA_STATUS_OK != ret )
248     {
249         OIC_LOG_V(ERROR, TAG, "CAAddNewCharacteristicsToGattServer failed[%d]", ret);
250         oc_mutex_unlock(g_leServerStateMutex);
251         CATerminateLEGattServer();
252         return CA_STATUS_FAILED;
253     }
254
255     ret = CARegisterLEServicewithGattServer(g_gattSvcPath);
256     if (CA_STATUS_OK != ret )
257     {
258         OIC_LOG_V(ERROR, TAG, "CARegisterLEServicewithGattServer failed[%d]", ret);
259         oc_mutex_unlock(g_leServerStateMutex);
260         CATerminateLEGattServer();
261         return CA_STATUS_FAILED;
262     }
263
264     /*
265      * TV Easysetup does not use IoTivity BLE advertisement.
266      */
267
268     // ret = CALEStartAdvertise();
269     // if (CA_STATUS_OK != ret)
270     // {
271     //     OIC_LOG_V(ERROR, TAG, "CALEStartAdvertise failed[%d]", ret);
272     //     oc_mutex_unlock(g_leServerStateMutex);
273     //     CATerminateLEGattServer();
274     //     return CA_STATUS_FAILED;
275     // }
276
277     g_isLEGattServerStarted = true;
278
279     oc_mutex_unlock(g_leServerStateMutex);
280
281     OIC_LOG(DEBUG, TAG, "OUT");
282     return CA_STATUS_OK;
283 }
284
285 void CALENotificationCb(bool notify, bt_gatt_server_h server, bt_gatt_h gatt_handle,
286                         void *user_data)
287 {
288     (void)server;
289     (void)gatt_handle;
290     (void)user_data;
291
292     OIC_LOG(DEBUG, TAG, "IN");
293     if (notify)
294     {
295         OIC_LOG(DEBUG, TAG, "Notification is subscribed by the client");
296         CALogSendStateInfo(CA_ADAPTER_GATT_BTLE, "", 0, -1,
297                            true, "notifyChar success");
298     }
299     else
300     {
301         CALogSendStateInfo(CA_ADAPTER_GATT_BTLE, "", 0, -1,
302                            false, "notifyChar failure");
303     }
304     OIC_LOG(DEBUG, TAG, "OUT");
305 }
306
307 CAResult_t CALEStartAdvertise()
308 {
309     OIC_LOG(DEBUG, TAG, "IN");
310
311     CAResult_t res = CALEStartAdvertiseImpl(CA_GATT_SERVICE_UUID);
312     if (CA_STATUS_OK != res)
313     {
314         OIC_LOG_V(ERROR, TAG, "CALEStartAdvertiseImpl failed[%d]", res);
315     }
316
317     OIC_LOG(DEBUG, TAG, "OUT");
318     return res;
319 }
320
321 CAResult_t CALEStartAdvertiseImpl(const char *serviceUUID)
322 {
323     OIC_LOG(DEBUG, TAG, "IN");
324
325     int res = bt_adapter_le_create_advertiser(&g_hAdvertiser);
326     if (NULL == g_hAdvertiser || BT_ERROR_NONE != res)
327     {
328         OIC_LOG_V(ERROR, TAG, "g_hAdvertiser is NULL/ Result is %d", res);
329         return CA_STATUS_FAILED;
330     }
331
332     res = bt_adapter_le_add_advertising_service_uuid(g_hAdvertiser,
333                                                      BT_ADAPTER_LE_PACKET_ADVERTISING,
334                                                      serviceUUID);
335     if (BT_ERROR_NONE != res)
336     {
337         OIC_LOG_V(ERROR, TAG, "bt_adapter_le_add_advertising_service_uuid failed with ret[%s]",
338                   CALEGetErrorMsg(res));
339         return CA_STATUS_FAILED;
340     }
341
342     res = bt_adapter_le_set_advertising_device_name(g_hAdvertiser,
343                                                     BT_ADAPTER_LE_PACKET_SCAN_RESPONSE, true);
344     if (BT_ERROR_NONE != res)
345     {
346         OIC_LOG_V(ERROR, TAG, "bt_adapter_le_set_advertising_device_name failed with ret[%s]",
347                   CALEGetErrorMsg(res));
348         return CA_STATUS_FAILED;
349     }
350
351     res = bt_adapter_le_start_advertising_new(g_hAdvertiser, NULL, NULL);
352     if (BT_ERROR_NONE != res)
353     {
354         OIC_LOG_V(ERROR, TAG, "bt_adapter_le_start_advertising_new failed with ret[%s]",
355                   CALEGetErrorMsg(res));
356         return CA_STATUS_FAILED;
357     }
358
359     OIC_LOG(DEBUG, TAG, "OUT");
360     return CA_STATUS_OK;
361 }
362
363 CAResult_t CALEStopAdvertise()
364 {
365     OIC_LOG(DEBUG, TAG, "IN");
366     if (NULL != g_hAdvertiser)
367     {
368         int ret  = bt_adapter_le_stop_advertising(g_hAdvertiser);
369         if (0 != ret)
370         {
371             OIC_LOG_V(ERROR, TAG,
372                       "bt_adapter_le_stop_advertising failed with ret[%s]", CALEGetErrorMsg(ret));
373         }
374
375         ret = bt_adapter_le_destroy_advertiser(g_hAdvertiser);
376         if (0 != ret)
377         {
378             OIC_LOG_V(ERROR, TAG,
379                       "bt_adapter_le_destroy_advertiser failed with ret[%s]", CALEGetErrorMsg(ret));
380         }
381         g_hAdvertiser = NULL;
382     }
383     else
384     {
385         OIC_LOG(ERROR, TAG, "Advertising is not running");
386         return CA_STATUS_FAILED;
387     }
388
389     OIC_LOG(DEBUG, TAG, "OUT");
390     return CA_STATUS_OK;
391 }
392
393 CAResult_t CAStopLEGattServer()
394 {
395     OIC_LOG(DEBUG, TAG, "IN");
396
397     oc_mutex_lock(g_leServerStateMutex);
398
399     if (false == g_isLEGattServerStarted)
400     {
401         OIC_LOG(ERROR, TAG, "Gatt Server is not running to stop");
402         oc_mutex_unlock(g_leServerStateMutex);
403         return CA_STATUS_OK;
404     }
405
406     g_isLEGattServerStarted = false;
407
408     oc_mutex_lock(g_LEClientListMutex);
409     CADisconnectAllClient(g_LEClientList);
410     g_LEClientList = NULL;
411     oc_mutex_unlock(g_LEClientListMutex);
412
413     /*
414      * TV Easysetup does not use IoTivity BLE advertisement.
415      */
416
417     // CAResult_t res = CALEStopAdvertise();
418     // {
419     //     OIC_LOG_V(ERROR, TAG, "CALEStopAdvertise failed with ret[%d]", res);
420     // }
421
422     CAResult_t res = CADeInitLEGattServer();
423     if (CA_STATUS_OK != res)
424     {
425         OIC_LOG_V(ERROR, TAG, "CADeInitLEGattService failed with ret[%d]", res);
426     }
427
428     GMainContext  *context_event_loop = NULL;
429     // Required for waking up the thread which is running in gmain loop
430     if (NULL != g_eventLoop)
431     {
432         context_event_loop = g_main_loop_get_context(g_eventLoop);
433
434         if (context_event_loop)
435         {
436             OIC_LOG_V(DEBUG,  TAG, "g_eventLoop context %x", context_event_loop);
437             g_main_context_wakeup(context_event_loop);
438
439             // Kill g main loops and kill threads
440             g_main_loop_quit(g_eventLoop);
441         }
442         g_eventLoop = NULL;
443     }
444     else
445     {
446         OIC_LOG(ERROR, TAG, "g_eventLoop context is NULL");
447     }
448
449     oc_mutex_unlock(g_leServerStateMutex);
450
451     OIC_LOG(DEBUG, TAG, "OUT");
452     return CA_STATUS_OK;
453 }
454
455 CAResult_t CAInitializeLEGattServer()
456 {
457     OIC_LOG(DEBUG, TAG, "IN");
458
459     CAResult_t ret = CAInitGattServerMutexVariables();
460     if (CA_STATUS_OK != ret )
461     {
462         OIC_LOG(ERROR, TAG, "CAInitGattServerMutexVariables failed!");
463         CATerminateGattServerMutexVariables();
464         return CA_SERVER_NOT_STARTED;
465     }
466     OIC_LOG(DEBUG, TAG, "OUT");
467     return ret;
468 }
469
470 void CATerminateLEGattServer()
471 {
472     OIC_LOG(DEBUG, TAG, "IN");
473
474     // Service and characteristics path will be freed by the platform.
475     oc_mutex_lock(g_leServiceMutex);
476     g_gattSvcPath = NULL;
477     oc_mutex_unlock(g_leServiceMutex);
478
479     oc_mutex_lock(g_leCharacteristicMutex);
480     g_gattReadCharPath = NULL;
481     g_gattWriteCharPath = NULL;
482     oc_mutex_unlock(g_leCharacteristicMutex);
483
484     oc_mutex_lock(g_leServerThreadPoolMutex);
485     g_leServerThreadPool = NULL;
486     oc_mutex_unlock(g_leServerThreadPoolMutex);
487
488     // Terminating all mutex variables.
489     CATerminateGattServerMutexVariables();
490     OIC_LOG(DEBUG, TAG, "OUT");
491 }
492
493 CAResult_t CAInitGattServerMutexVariables()
494 {
495     OIC_LOG(DEBUG, TAG, "IN");
496     if (NULL == g_leServerStateMutex)
497     {
498         g_leServerStateMutex = oc_mutex_new();
499         if (NULL == g_leServerStateMutex)
500         {
501             OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
502             return CA_STATUS_FAILED;
503         }
504     }
505
506     if (NULL == g_leServiceMutex)
507     {
508         g_leServiceMutex = oc_mutex_new();
509         if (NULL == g_leServiceMutex)
510         {
511             OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
512             return CA_STATUS_FAILED;
513         }
514     }
515
516     if (NULL == g_leCharacteristicMutex)
517     {
518         g_leCharacteristicMutex = oc_mutex_new();
519         if (NULL == g_leCharacteristicMutex)
520         {
521             OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
522             return CA_STATUS_FAILED;
523         }
524     }
525
526     if (NULL == g_leReqRespCbMutex)
527     {
528         g_leReqRespCbMutex = oc_mutex_new();
529         if (NULL == g_leReqRespCbMutex)
530         {
531             OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
532             return CA_STATUS_FAILED;
533         }
534     }
535
536     if (NULL == g_leServerThreadPoolMutex)
537     {
538         g_leServerThreadPoolMutex = oc_mutex_new();
539         if (NULL == g_leServerThreadPoolMutex)
540         {
541             OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
542             return CA_STATUS_FAILED;
543         }
544     }
545
546     if (NULL == g_LEClientListMutex)
547     {
548         g_LEClientListMutex = oc_mutex_new();
549         if (NULL == g_LEClientListMutex)
550         {
551             OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
552             return CA_STATUS_FAILED;
553         }
554     }
555
556     OIC_LOG(DEBUG, TAG, "OUT");
557     return CA_STATUS_OK;
558 }
559
560 void CATerminateGattServerMutexVariables()
561 {
562     OIC_LOG(DEBUG, TAG, "IN");
563     oc_mutex_free(g_leServerStateMutex);
564     g_leServerStateMutex = NULL;
565
566     oc_mutex_free(g_leServiceMutex);
567     g_leServiceMutex = NULL;
568
569     oc_mutex_free(g_leCharacteristicMutex);
570     g_leCharacteristicMutex = NULL;
571
572     oc_mutex_free(g_leReqRespCbMutex);
573     g_leReqRespCbMutex = NULL;
574
575     oc_mutex_free(g_leServerThreadPoolMutex);
576     g_leServerThreadPoolMutex = NULL;
577
578     oc_mutex_free(g_LEClientListMutex);
579     g_LEClientListMutex = NULL;
580
581     OIC_LOG(DEBUG, TAG, "OUT");
582 }
583
584 CAResult_t CAInitLEGattServer()
585 {
586     OIC_LOG(DEBUG, TAG, "IN");
587
588     int ret =  bt_gatt_server_initialize();
589     if (0 != ret)
590     {
591         OIC_LOG_V(ERROR, TAG, "bt_gatt_server_initialize failed with ret[%s]",
592                   CALEGetErrorMsg(ret));
593         return CA_STATUS_FAILED;
594     }
595
596     if (!g_gattServer)
597     {
598         OIC_LOG(DEBUG, TAG, "g_gattServer is NULL. create gatt server..");
599         ret = bt_gatt_server_create(&g_gattServer);
600         if (0 != ret)
601         {
602             OIC_LOG_V(ERROR, TAG, "bt_gatt_server_create failed with ret[%s]",
603                       CALEGetErrorMsg(ret));
604             return CA_STATUS_FAILED;
605         }
606     }
607
608     OIC_LOG(DEBUG, TAG, "OUT");
609     return CA_STATUS_OK;
610 }
611
612 CAResult_t CADeInitLEGattServer()
613 {
614     OIC_LOG(DEBUG, TAG, "IN");
615
616     int ret = bt_gatt_server_unregister_all_services(g_gattServer);
617     if (0 != ret)
618     {
619         OIC_LOG_V(ERROR, TAG, "bt_gatt_server_unregister_all_services failed with ret[%s]",
620                   CALEGetErrorMsg(ret));
621         return CA_STATUS_FAILED;
622     }
623
624     ret = bt_gatt_server_destroy(g_gattServer);
625     if (0 != ret)
626     {
627         OIC_LOG_V(ERROR, TAG, "bt_gatt_server_destroy failed with ret[%s]",
628                   CALEGetErrorMsg(ret));
629         return CA_STATUS_FAILED;
630     }
631     g_gattServer = NULL;
632
633     ret =  bt_gatt_server_deinitialize();
634     if (0 != ret)
635     {
636         OIC_LOG_V(ERROR, TAG, "bt_gatt_server_deinitialize failed with ret[%s]",
637                   CALEGetErrorMsg(ret));
638         return CA_STATUS_FAILED;
639     }
640
641     OIC_LOG(DEBUG, TAG, "OUT");
642     return CA_STATUS_OK;
643 }
644
645 void CASetLEServerThreadPoolHandle(ca_thread_pool_t handle)
646 {
647     OIC_LOG(DEBUG, TAG, "IN");
648     oc_mutex_lock(g_leServerThreadPoolMutex);
649     g_leServerThreadPool = handle;
650     oc_mutex_unlock(g_leServerThreadPoolMutex);
651     OIC_LOG(DEBUG, TAG, "OUT");
652 }
653
654 CAResult_t CAAddNewLEServiceInGattServer(const char *serviceUUID)
655 {
656     OIC_LOG(DEBUG, TAG, "IN");
657
658     VERIFY_NON_NULL(serviceUUID, TAG, "serviceUUID");
659
660     OIC_LOG_V(DEBUG, TAG, "service uuid %s", serviceUUID);
661
662     bt_gatt_service_type_e type = BT_GATT_SERVICE_TYPE_PRIMARY;
663
664     oc_mutex_lock(g_leServiceMutex);
665     int ret = bt_gatt_service_create(serviceUUID, type, &g_gattSvcPath);
666     if (0 != ret)
667     {
668         oc_mutex_unlock(g_leServiceMutex);
669         OIC_LOG_V(ERROR, TAG, "bt_gatt_service_create failed with ret [%s]",
670                     CALEGetErrorMsg(ret));
671         return CA_STATUS_FAILED;
672     }
673     oc_mutex_unlock(g_leServiceMutex);
674
675     if (g_gattSvcPath)
676     {
677         OIC_LOG_V(DEBUG, TAG, "ServicePath obtained is %s", (char *)g_gattSvcPath);
678     }
679
680     OIC_LOG(DEBUG, TAG, "OUT");
681     return CA_STATUS_OK;
682 }
683
684 #ifdef BLE_TIZEN_30
685 void CALEGattRemoteCharacteristicWriteCb(const char *remoteAddress, int request_id,
686                                          bt_gatt_server_h server, bt_gatt_h gatt_handle,
687                                          bool response_needed, int offset, const char *charValue,
688                                          int charLen, void *userData)
689 #else
690 void CALEGattRemoteCharacteristicWriteCb(char *remoteAddress, bt_gatt_server_h server,
691                                          bt_gatt_h gatt_handle, int offset, char *charValue,
692                                          int charLen, void *userData)
693 #endif
694 {
695     (void)server;
696     (void)gatt_handle;
697     (void)userData;
698
699     OIC_LOG(INFO, TAG, "IN - WriteCharCB");
700
701     if (NULL == charValue || NULL == remoteAddress)
702     {
703         OIC_LOG(ERROR, TAG, "Param callback values are NULL");
704         return;
705     }
706
707     OIC_LOG_V(DEBUG, TAG, "len [%d]", charLen);
708
709     uint8_t *data = OICMalloc(charLen);
710     if (NULL == data)
711     {
712         OIC_LOG(ERROR, TAG, "Malloc failed!");
713         return;
714     }
715
716     memcpy(data, charValue, charLen);
717
718     oc_mutex_lock(g_leReqRespCbMutex);
719     if (NULL == g_leServerDataReceivedCallback)
720     {
721         OIC_LOG(ERROR, TAG, "gReqRespCallback is NULL!");
722         oc_mutex_unlock(g_leReqRespCbMutex);
723         OICFree(data);
724         return;
725     }
726
727     OIC_LOG(INFO, TAG, "Sending data up !");
728     uint32_t sentLength = 0;
729     g_leServerDataReceivedCallback(remoteAddress, data, charLen,
730                                     &sentLength);
731     oc_mutex_unlock(g_leReqRespCbMutex);
732     OICFree(data);
733
734 #ifdef BLE_TIZEN_30
735     //response
736     OIC_LOG_V(INFO, TAG, "response_needed flag : %d", response_needed);
737     if (response_needed)
738     {
739         OIC_LOG(INFO, TAG, "send response to remote client");
740         bt_gatt_server_send_response(request_id,
741                 BT_GATT_REQUEST_TYPE_WRITE, offset,
742                 BT_ERROR_NONE, NULL, 0);
743     }
744 #endif
745
746     OIC_LOG(INFO, TAG, "OUT - WriteCharCB");
747 }
748
749 CAResult_t CARegisterLEServicewithGattServer(const bt_gatt_h svcPath)
750 {
751     OIC_LOG(DEBUG, TAG, "IN");
752
753     VERIFY_NON_NULL(svcPath, TAG, "svcPath");
754
755     OIC_LOG_V(DEBUG, TAG, "svcPath:%s", svcPath);
756
757     int ret = bt_gatt_server_register_service(g_gattServer, svcPath);
758     if (0 != ret)
759     {
760         OIC_LOG_V(ERROR, TAG, "bt_gatt_server_register_service failed with ret[%s]",
761                   CALEGetErrorMsg(ret));
762         return CA_STATUS_FAILED;
763     }
764
765 #ifdef BLE_TIZEN_30
766     ret = bt_gatt_server_start();
767     if (0 != ret)
768     {
769         OIC_LOG_V(ERROR, TAG, "bt_gatt_server_start failed with ret[%s]",
770                 CALEGetErrorMsg(ret));
771         return CA_STATUS_FAILED;
772     }
773 #endif
774
775 #ifdef BLE_TIZEN_30
776     ret = bt_gatt_server_set_write_value_requested_cb(g_gattWriteCharPath,
777 #else
778     ret = bt_gatt_server_set_value_changed_cb(g_gattWriteCharPath,
779 #endif
780                                               CALEGattRemoteCharacteristicWriteCb, NULL);
781
782     if (0 != ret)
783     {
784         OIC_LOG_V(ERROR, TAG, "bt_gatt_server_set_value_changed_cb failed with ret[%s]",
785                   CALEGetErrorMsg(ret));
786         return CA_STATUS_FAILED;
787     }
788
789     OIC_LOG(DEBUG, TAG, "OUT");
790     return CA_STATUS_OK;
791 }
792
793 CAResult_t CAAddNewCharacteristicsToGattServer(const bt_gatt_h svcPath, const char *charUUID,
794                                                const char *charValue, int charValueLen, bool read)
795 {
796
797     OIC_LOG(DEBUG, TAG, "IN");
798
799     int permissions = BT_GATT_PERMISSION_READ | BT_GATT_PERMISSION_WRITE;
800     int properties;
801     if (read)
802     {
803         properties = BT_GATT_PROPERTY_INDICATE | BT_GATT_PROPERTY_READ;
804     }
805     else
806     {
807         properties = BT_GATT_PROPERTY_WRITE | BT_GATT_PROPERTY_READ;
808     }
809
810     bt_gatt_h charPath = NULL;
811
812     int ret = bt_gatt_characteristic_create(charUUID, permissions, properties, charValue,
813                                             charValueLen, &charPath);
814
815     if (0 != ret || NULL == charPath)
816     {
817         OIC_LOG_V(ERROR, TAG,
818                   "bt_gatt_add_characteristic  failed with ret [%s]", CALEGetErrorMsg(ret));
819         return CA_STATUS_FAILED;
820     }
821
822     OIC_LOG_V(DEBUG, TAG,
823               "bt_gatt_characteristic_create charPath obtained: %s", (char *)charPath);
824
825     if (read)
826     {
827 #ifdef BLE_TIZEN_30
828         ret = bt_gatt_server_set_characteristic_notification_state_change_cb(charPath,
829                                                                              CALENotificationCb,
830                                                                              NULL);
831 #else
832         ret = bt_gatt_server_set_notification_state_change_cb(charPath, CALENotificationCb, NULL);
833 #endif
834         if (0 != ret)
835         {
836             OIC_LOG_V(ERROR, TAG,
837 #ifdef BLE_TIZEN_30
838                       "bt_gatt_server_set_characteristic_notification_state_change_cb failed with ret[%s]",
839 #else
840                       "bt_gatt_server_set_notification_state_change_cb  failed with ret[%s]",
841 #endif
842                       CALEGetErrorMsg(ret));
843             return CA_STATUS_FAILED;
844         }
845     }
846
847     ret =  bt_gatt_service_add_characteristic(svcPath, charPath);
848     if (0 != ret)
849     {
850         OIC_LOG_V(ERROR, TAG,
851                   "bt_gatt_service_add_characteristic  failed with ret[%s]",
852                   CALEGetErrorMsg(ret));
853         return CA_STATUS_FAILED;
854     }
855
856     oc_mutex_lock(g_leCharacteristicMutex);
857
858     if (read)
859     {
860         g_gattReadCharPath = charPath;
861     }
862     else
863     {
864         char desc_value[2] = {0, 0};  // Notification enabled.
865         bt_gatt_h descriptor = NULL;
866         permissions = BT_GATT_PERMISSION_READ | BT_GATT_PERMISSION_WRITE;
867         ret = bt_gatt_descriptor_create(CA_GATT_CONFIGURATION_DESC_UUID, permissions,
868                                         desc_value, sizeof(desc_value),
869                                         &descriptor);
870         if (0 != ret)
871         {
872             oc_mutex_unlock(g_leCharacteristicMutex);
873             OIC_LOG_V(ERROR, TAG,
874                       "bt_gatt_descriptor_create  failed with ret[%s]",
875                       CALEGetErrorMsg(ret));
876             return CA_STATUS_FAILED;
877         }
878
879         ret = bt_gatt_characteristic_add_descriptor(charPath, descriptor);
880         if (0 != ret)
881         {
882             oc_mutex_unlock(g_leCharacteristicMutex);
883             OIC_LOG_V(ERROR, TAG,
884                       "bt_gatt_characteristic_add_descriptor  failed with ret[%s]",
885                       CALEGetErrorMsg(ret));
886             return CA_STATUS_FAILED;
887         }
888         g_gattWriteCharPath = charPath;
889     }
890
891     oc_mutex_unlock(g_leCharacteristicMutex);
892
893     OIC_LOG(DEBUG, TAG, "OUT");
894     return CA_STATUS_OK;
895 }
896
897 CAResult_t CAUpdateCharacteristicsToGattClient(const char *address, const uint8_t *charValue,
898                                                uint32_t charValueLen)
899 {
900     OIC_LOG(DEBUG, TAG, "IN");
901
902     VERIFY_NON_NULL(charValue, TAG, "charValue");
903     VERIFY_NON_NULL(address, TAG, "address");
904
905     OIC_LOG_V(DEBUG, TAG, "Client's Unicast address for sending data [%s]", address);
906
907     oc_mutex_lock(g_leCharacteristicMutex);
908
909     if (!g_LEConnectedState)
910     {
911         OIC_LOG(ERROR, TAG, "g_LEConnectedState is false");
912         oc_mutex_unlock(g_leCharacteristicMutex);
913         return CA_STATUS_FAILED;
914     }
915
916     if (NULL  == g_gattReadCharPath)
917     {
918         OIC_LOG(ERROR, TAG, "g_gattReadCharPath is NULL");
919         oc_mutex_unlock(g_leCharacteristicMutex);
920         return CA_STATUS_FAILED;
921     }
922
923     int ret = bt_gatt_set_value(g_gattReadCharPath, (char *)charValue, charValueLen);
924     if (0 != ret)
925     {
926         OIC_LOG_V(ERROR, TAG,
927                   "bt_gatt_set_value failed with return [%s]", CALEGetErrorMsg(ret));
928         oc_mutex_unlock(g_leCharacteristicMutex);
929         return CA_STATUS_FAILED;
930     }
931
932 #ifdef BLE_TIZEN_30
933     ret = bt_gatt_server_notify_characteristic_changed_value(g_gattReadCharPath,
934                                                              CALEServerNotificationSentCB,
935                                                              address, NULL);
936 #else
937     ret = bt_gatt_server_notify(g_gattReadCharPath, false, CALEServerNotificationSentCB,
938                                 NULL);
939 #endif
940
941     if (0 != ret)
942     {
943         OIC_LOG_V(ERROR, TAG,
944 #ifdef BLE_TIZEN_30
945                   "bt_gatt_server_notify_characteristic_changed_value failed with return [%s]",
946 #else
947                   "bt_gatt_server_notify failed with return [%s]",
948 #endif
949                   CALEGetErrorMsg(ret));
950         oc_mutex_unlock(g_leCharacteristicMutex);
951         return CA_STATUS_FAILED;
952     }
953
954     oc_mutex_unlock(g_leCharacteristicMutex);
955
956     OIC_LOG(DEBUG, TAG, "OUT");
957     return CA_STATUS_OK;
958 }
959
960 CAResult_t CAUpdateCharacteristicsToAllGattClients(const uint8_t *charValue, uint32_t charValueLen)
961 {
962     OIC_LOG(DEBUG, TAG, "IN");
963
964     VERIFY_NON_NULL(charValue, TAG, "charValue");
965
966     oc_mutex_lock(g_leCharacteristicMutex);
967
968     if (!g_LEConnectedState)
969     {
970         OIC_LOG(ERROR, TAG, "g_LEConnectedState is false");
971         oc_mutex_unlock(g_leCharacteristicMutex);
972         return CA_STATUS_FAILED;
973     }
974
975     if (NULL  == g_gattReadCharPath)
976     {
977         OIC_LOG(ERROR, TAG, "g_gattReadCharPath is NULL");
978         oc_mutex_unlock(g_leCharacteristicMutex);
979         return CA_STATUS_FAILED;
980     }
981
982     int ret = bt_gatt_set_value(g_gattReadCharPath, (char *)charValue, charValueLen);
983     if (0 != ret)
984     {
985         OIC_LOG_V(ERROR, TAG, "bt_gatt_set_value failed with return[%s]", CALEGetErrorMsg(ret));
986         oc_mutex_unlock(g_leCharacteristicMutex);
987         return CA_STATUS_FAILED;
988     }
989
990 #ifdef BLE_TIZEN_30
991     ret = bt_gatt_server_notify_characteristic_changed_value(g_gattReadCharPath,
992                                                              CALEServerNotificationSentCB,
993                                                              NULL, NULL);
994 #else
995     ret = bt_gatt_server_notify(g_gattReadCharPath, false, CALEServerNotificationSentCB,
996                                 NULL);
997 #endif
998     if (0 != ret)
999     {
1000         OIC_LOG_V(ERROR, TAG,
1001 #ifdef BLE_TIZEN_30
1002                   "bt_gatt_server_notify_characteristic_changed_value failed with return[%s]",
1003 #else
1004                   "bt_gatt_server_notify failed with return[%s]",
1005 #endif
1006                   CALEGetErrorMsg(ret));
1007         oc_mutex_unlock(g_leCharacteristicMutex);
1008         return CA_STATUS_FAILED;
1009     }
1010
1011     oc_mutex_unlock(g_leCharacteristicMutex);
1012
1013     OIC_LOG(DEBUG, TAG, "OUT");
1014     return CA_STATUS_OK;
1015 }
1016
1017 void CASetLEReqRespServerCallback(CABLEDataReceivedCallback callback)
1018 {
1019     OIC_LOG(DEBUG, TAG, "IN");
1020
1021     oc_mutex_lock(g_leReqRespCbMutex);
1022     g_leServerDataReceivedCallback = callback;
1023     oc_mutex_unlock(g_leReqRespCbMutex);
1024
1025     OIC_LOG(DEBUG, TAG, "OUT");
1026 }
1027
1028 void CASetBLEServerErrorHandleCallback(CABLEErrorHandleCallback callback)
1029 {
1030     g_serverErrorCallback = callback;
1031 }
1032
1033 bool CALEServerIsConnected(const char* address)
1034 {
1035     (void)address;
1036     //@Todo
1037     return true;
1038 }
1039
1040 uint16_t CALEServerGetMtuSize(const char* address)
1041 {
1042     OIC_LOG(DEBUG, TAG, "IN");
1043     VERIFY_NON_NULL_RET(address, TAG, "address is null", CA_DEFAULT_BLE_MTU_SIZE);
1044
1045     unsigned int mtu;
1046     int ret = bt_device_get_att_mtu(address, &mtu);
1047     if (0 != ret)
1048     {
1049         OIC_LOG_V(ERROR, TAG,
1050                   "bt_device_get_att_mtu failed with return [%s]", CALEGetErrorMsg(ret));
1051         return CA_DEFAULT_BLE_MTU_SIZE;
1052     }
1053     OIC_LOG_V(INFO, TAG, "mtu size(including header) from bt_device_get_att_mtu is %d", mtu);
1054     OIC_LOG(DEBUG, TAG, "OUT");
1055     return mtu - CA_BLE_MTU_HEADER_SIZE;
1056 }