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