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