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