Update snapshot(2018-01-10)
[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             bt_gatt_server_deinitialize();
606             return CA_STATUS_FAILED;
607         }
608     }
609
610     OIC_LOG(DEBUG, TAG, "OUT");
611     return CA_STATUS_OK;
612 }
613
614 CAResult_t CADeInitLEGattServer()
615 {
616     OIC_LOG(DEBUG, TAG, "IN");
617
618     int ret = bt_gatt_server_unregister_all_services(g_gattServer);
619     if (0 != ret)
620     {
621         OIC_LOG_V(ERROR, TAG, "bt_gatt_server_unregister_all_services failed with ret[%s]",
622                   CALEGetErrorMsg(ret));
623         // CONPRO-1181 continue even bt API fails during DeInit
624         //return CA_STATUS_FAILED;
625     }
626
627     ret = bt_gatt_server_destroy(g_gattServer);
628     if (0 != ret)
629     {
630         OIC_LOG_V(ERROR, TAG, "bt_gatt_server_destroy failed with ret[%s]",
631                   CALEGetErrorMsg(ret));
632         // CONPRO-1181 continue even bt API fails during DeInit
633         //return CA_STATUS_FAILED;
634     }
635     g_gattServer = NULL;
636
637     ret =  bt_gatt_server_deinitialize();
638     if (0 != ret)
639     {
640         OIC_LOG_V(ERROR, TAG, "bt_gatt_server_deinitialize failed with ret[%s]",
641                   CALEGetErrorMsg(ret));
642         // CONPRO-1181 continue even bt API fails during DeInit
643         //return CA_STATUS_FAILED;
644     }
645
646     OIC_LOG(DEBUG, TAG, "OUT");
647     return CA_STATUS_OK;
648 }
649
650 void CASetLEServerThreadPoolHandle(ca_thread_pool_t handle)
651 {
652     OIC_LOG(DEBUG, TAG, "IN");
653     oc_mutex_lock(g_leServerThreadPoolMutex);
654     g_leServerThreadPool = handle;
655     oc_mutex_unlock(g_leServerThreadPoolMutex);
656     OIC_LOG(DEBUG, TAG, "OUT");
657 }
658
659 CAResult_t CAAddNewLEServiceInGattServer(const char *serviceUUID)
660 {
661     OIC_LOG(DEBUG, TAG, "IN");
662
663     VERIFY_NON_NULL(serviceUUID, TAG, "serviceUUID");
664
665     OIC_LOG_V(DEBUG, TAG, "service uuid %s", serviceUUID);
666
667     bt_gatt_service_type_e type = BT_GATT_SERVICE_TYPE_PRIMARY;
668
669     oc_mutex_lock(g_leServiceMutex);
670     int ret = bt_gatt_service_create(serviceUUID, type, &g_gattSvcPath);
671     if (0 != ret)
672     {
673         oc_mutex_unlock(g_leServiceMutex);
674         OIC_LOG_V(ERROR, TAG, "bt_gatt_service_create failed with ret [%s]",
675                     CALEGetErrorMsg(ret));
676         return CA_STATUS_FAILED;
677     }
678     oc_mutex_unlock(g_leServiceMutex);
679
680     if (g_gattSvcPath)
681     {
682         OIC_LOG_V(DEBUG, TAG, "ServicePath obtained is %s", (char *)g_gattSvcPath);
683     }
684
685     OIC_LOG(DEBUG, TAG, "OUT");
686     return CA_STATUS_OK;
687 }
688
689 #ifdef BLE_TIZEN_30
690 void CALEGattRemoteCharacteristicWriteCb(const char *remoteAddress, int request_id,
691                                          bt_gatt_server_h server, bt_gatt_h gatt_handle,
692                                          bool response_needed, int offset, const char *charValue,
693                                          int charLen, void *userData)
694 #else
695 void CALEGattRemoteCharacteristicWriteCb(char *remoteAddress, bt_gatt_server_h server,
696                                          bt_gatt_h gatt_handle, int offset, char *charValue,
697                                          int charLen, void *userData)
698 #endif
699 {
700     (void)server;
701     (void)gatt_handle;
702     (void)userData;
703
704     OIC_LOG(INFO, TAG, "IN - WriteCharCB");
705
706     if (NULL == charValue || NULL == remoteAddress)
707     {
708         OIC_LOG(ERROR, TAG, "Param callback values are NULL");
709         return;
710     }
711
712     OIC_LOG_V(DEBUG, TAG, "len [%d]", charLen);
713
714     uint8_t *data = OICMalloc(charLen);
715     if (NULL == data)
716     {
717         OIC_LOG(ERROR, TAG, "Malloc failed!");
718         return;
719     }
720
721     memcpy(data, charValue, charLen);
722
723     oc_mutex_lock(g_leReqRespCbMutex);
724     if (NULL == g_leServerDataReceivedCallback)
725     {
726         OIC_LOG(ERROR, TAG, "gReqRespCallback is NULL!");
727         oc_mutex_unlock(g_leReqRespCbMutex);
728         OICFree(data);
729         return;
730     }
731
732     OIC_LOG(INFO, TAG, "Sending data up !");
733     uint32_t sentLength = 0;
734     g_leServerDataReceivedCallback(remoteAddress, data, charLen,
735                                     &sentLength);
736     oc_mutex_unlock(g_leReqRespCbMutex);
737     OICFree(data);
738
739 #ifdef BLE_TIZEN_30
740     //response
741     OIC_LOG_V(INFO, TAG, "response_needed flag : %d", response_needed);
742     if (response_needed)
743     {
744         OIC_LOG(INFO, TAG, "send response to remote client");
745         bt_gatt_server_send_response(request_id,
746                 BT_GATT_REQUEST_TYPE_WRITE, offset,
747                 BT_ERROR_NONE, NULL, 0);
748     }
749 #endif
750
751     OIC_LOG(INFO, TAG, "OUT - WriteCharCB");
752 }
753
754 CAResult_t CARegisterLEServicewithGattServer(const bt_gatt_h svcPath)
755 {
756     OIC_LOG(DEBUG, TAG, "IN");
757
758     VERIFY_NON_NULL(svcPath, TAG, "svcPath");
759
760     OIC_LOG_V(DEBUG, TAG, "svcPath: %s", (char *)svcPath);
761
762     int ret = bt_gatt_server_register_service(g_gattServer, svcPath);
763     if (0 != ret)
764     {
765         OIC_LOG_V(ERROR, TAG, "bt_gatt_server_register_service failed with ret[%s]",
766                   CALEGetErrorMsg(ret));
767         return CA_STATUS_FAILED;
768     }
769
770 #ifdef BLE_TIZEN_30
771     ret = bt_gatt_server_start();
772     if (0 != ret)
773     {
774         OIC_LOG_V(ERROR, TAG, "bt_gatt_server_start failed with ret[%s]",
775                 CALEGetErrorMsg(ret));
776         return CA_STATUS_FAILED;
777     }
778 #endif
779
780 #ifdef BLE_TIZEN_30
781     ret = bt_gatt_server_set_write_value_requested_cb(g_gattWriteCharPath,
782 #else
783     ret = bt_gatt_server_set_value_changed_cb(g_gattWriteCharPath,
784 #endif
785                                               CALEGattRemoteCharacteristicWriteCb, NULL);
786
787     if (0 != ret)
788     {
789         OIC_LOG_V(ERROR, TAG, "bt_gatt_server_set_value_changed_cb failed with ret[%s]",
790                   CALEGetErrorMsg(ret));
791         return CA_STATUS_FAILED;
792     }
793
794     OIC_LOG(DEBUG, TAG, "OUT");
795     return CA_STATUS_OK;
796 }
797
798 CAResult_t CAAddNewCharacteristicsToGattServer(const bt_gatt_h svcPath, const char *charUUID,
799                                                const char *charValue, int charValueLen, bool read)
800 {
801
802     OIC_LOG(DEBUG, TAG, "IN");
803
804     int permissions = BT_GATT_PERMISSION_READ | BT_GATT_PERMISSION_WRITE;
805     int properties;
806     if (read)
807     {
808         properties = BT_GATT_PROPERTY_INDICATE | BT_GATT_PROPERTY_READ;
809     }
810     else
811     {
812         properties = BT_GATT_PROPERTY_WRITE | BT_GATT_PROPERTY_READ;
813     }
814
815     bt_gatt_h charPath = NULL;
816
817     int ret = bt_gatt_characteristic_create(charUUID, permissions, properties, charValue,
818                                             charValueLen, &charPath);
819
820     if (0 != ret || NULL == charPath)
821     {
822         OIC_LOG_V(ERROR, TAG,
823                   "bt_gatt_add_characteristic  failed with ret [%s]", CALEGetErrorMsg(ret));
824         return CA_STATUS_FAILED;
825     }
826
827     OIC_LOG_V(DEBUG, TAG,
828               "bt_gatt_characteristic_create charPath obtained: %s", (char *)charPath);
829
830     if (read)
831     {
832 #ifdef BLE_TIZEN_30
833         ret = bt_gatt_server_set_characteristic_notification_state_change_cb(charPath,
834                                                                              CALENotificationCb,
835                                                                              NULL);
836 #else
837         ret = bt_gatt_server_set_notification_state_change_cb(charPath, CALENotificationCb, NULL);
838 #endif
839         if (0 != ret)
840         {
841             OIC_LOG_V(ERROR, TAG,
842 #ifdef BLE_TIZEN_30
843                       "bt_gatt_server_set_characteristic_notification_state_change_cb failed with ret[%s]",
844 #else
845                       "bt_gatt_server_set_notification_state_change_cb  failed with ret[%s]",
846 #endif
847                       CALEGetErrorMsg(ret));
848             return CA_STATUS_FAILED;
849         }
850     }
851
852     ret =  bt_gatt_service_add_characteristic(svcPath, charPath);
853     if (0 != ret)
854     {
855         OIC_LOG_V(ERROR, TAG,
856                   "bt_gatt_service_add_characteristic  failed with ret[%s]",
857                   CALEGetErrorMsg(ret));
858         return CA_STATUS_FAILED;
859     }
860
861     oc_mutex_lock(g_leCharacteristicMutex);
862
863     if (read)
864     {
865         g_gattReadCharPath = charPath;
866     }
867     else
868     {
869         char desc_value[2] = {0, 0};  // Notification enabled.
870         bt_gatt_h descriptor = NULL;
871         permissions = BT_GATT_PERMISSION_READ | BT_GATT_PERMISSION_WRITE;
872         ret = bt_gatt_descriptor_create(CA_GATT_CONFIGURATION_DESC_UUID, permissions,
873                                         desc_value, sizeof(desc_value),
874                                         &descriptor);
875         if (0 != ret)
876         {
877             oc_mutex_unlock(g_leCharacteristicMutex);
878             OIC_LOG_V(ERROR, TAG,
879                       "bt_gatt_descriptor_create  failed with ret[%s]",
880                       CALEGetErrorMsg(ret));
881             return CA_STATUS_FAILED;
882         }
883
884         ret = bt_gatt_characteristic_add_descriptor(charPath, descriptor);
885         if (0 != ret)
886         {
887             oc_mutex_unlock(g_leCharacteristicMutex);
888             OIC_LOG_V(ERROR, TAG,
889                       "bt_gatt_characteristic_add_descriptor  failed with ret[%s]",
890                       CALEGetErrorMsg(ret));
891             return CA_STATUS_FAILED;
892         }
893         g_gattWriteCharPath = charPath;
894     }
895
896     oc_mutex_unlock(g_leCharacteristicMutex);
897
898     OIC_LOG(DEBUG, TAG, "OUT");
899     return CA_STATUS_OK;
900 }
901
902 CAResult_t CAUpdateCharacteristicsToGattClient(const char *address, const uint8_t *charValue,
903                                                uint32_t charValueLen)
904 {
905     OIC_LOG(DEBUG, TAG, "IN");
906
907     VERIFY_NON_NULL(charValue, TAG, "charValue");
908     VERIFY_NON_NULL(address, TAG, "address");
909
910     OIC_LOG_V(DEBUG, TAG, "Client's Unicast address for sending data [%s]", address);
911
912     oc_mutex_lock(g_leCharacteristicMutex);
913
914     if (!g_LEConnectedState)
915     {
916         OIC_LOG(ERROR, TAG, "g_LEConnectedState is false");
917         oc_mutex_unlock(g_leCharacteristicMutex);
918         return CA_STATUS_FAILED;
919     }
920
921     if (NULL  == g_gattReadCharPath)
922     {
923         OIC_LOG(ERROR, TAG, "g_gattReadCharPath is NULL");
924         oc_mutex_unlock(g_leCharacteristicMutex);
925         return CA_STATUS_FAILED;
926     }
927
928     int ret = bt_gatt_set_value(g_gattReadCharPath, (char *)charValue, charValueLen);
929     if (0 != ret)
930     {
931         OIC_LOG_V(ERROR, TAG,
932                   "bt_gatt_set_value failed with return [%s]", CALEGetErrorMsg(ret));
933         oc_mutex_unlock(g_leCharacteristicMutex);
934         return CA_STATUS_FAILED;
935     }
936
937 #ifdef BLE_TIZEN_30
938     ret = bt_gatt_server_notify_characteristic_changed_value(g_gattReadCharPath,
939                                                              CALEServerNotificationSentCB,
940                                                              address, NULL);
941 #else
942     ret = bt_gatt_server_notify(g_gattReadCharPath, false, CALEServerNotificationSentCB,
943                                 NULL);
944 #endif
945
946     if (0 != ret)
947     {
948         OIC_LOG_V(ERROR, TAG,
949 #ifdef BLE_TIZEN_30
950                   "bt_gatt_server_notify_characteristic_changed_value failed with return [%s]",
951 #else
952                   "bt_gatt_server_notify failed with return [%s]",
953 #endif
954                   CALEGetErrorMsg(ret));
955         oc_mutex_unlock(g_leCharacteristicMutex);
956         return CA_STATUS_FAILED;
957     }
958
959     oc_mutex_unlock(g_leCharacteristicMutex);
960
961     OIC_LOG(DEBUG, TAG, "OUT");
962     return CA_STATUS_OK;
963 }
964
965 CAResult_t CAUpdateCharacteristicsToAllGattClients(const uint8_t *charValue, uint32_t charValueLen)
966 {
967     OIC_LOG(DEBUG, TAG, "IN");
968
969     VERIFY_NON_NULL(charValue, TAG, "charValue");
970
971     oc_mutex_lock(g_leCharacteristicMutex);
972
973     if (!g_LEConnectedState)
974     {
975         OIC_LOG(ERROR, TAG, "g_LEConnectedState is false");
976         oc_mutex_unlock(g_leCharacteristicMutex);
977         return CA_STATUS_FAILED;
978     }
979
980     if (NULL  == g_gattReadCharPath)
981     {
982         OIC_LOG(ERROR, TAG, "g_gattReadCharPath is NULL");
983         oc_mutex_unlock(g_leCharacteristicMutex);
984         return CA_STATUS_FAILED;
985     }
986
987     int ret = bt_gatt_set_value(g_gattReadCharPath, (char *)charValue, charValueLen);
988     if (0 != ret)
989     {
990         OIC_LOG_V(ERROR, TAG, "bt_gatt_set_value failed with return[%s]", CALEGetErrorMsg(ret));
991         oc_mutex_unlock(g_leCharacteristicMutex);
992         return CA_STATUS_FAILED;
993     }
994
995 #ifdef BLE_TIZEN_30
996     ret = bt_gatt_server_notify_characteristic_changed_value(g_gattReadCharPath,
997                                                              CALEServerNotificationSentCB,
998                                                              NULL, NULL);
999 #else
1000     ret = bt_gatt_server_notify(g_gattReadCharPath, false, CALEServerNotificationSentCB,
1001                                 NULL);
1002 #endif
1003     if (0 != ret)
1004     {
1005         OIC_LOG_V(ERROR, TAG,
1006 #ifdef BLE_TIZEN_30
1007                   "bt_gatt_server_notify_characteristic_changed_value failed with return[%s]",
1008 #else
1009                   "bt_gatt_server_notify failed with return[%s]",
1010 #endif
1011                   CALEGetErrorMsg(ret));
1012         oc_mutex_unlock(g_leCharacteristicMutex);
1013         return CA_STATUS_FAILED;
1014     }
1015
1016     oc_mutex_unlock(g_leCharacteristicMutex);
1017
1018     OIC_LOG(DEBUG, TAG, "OUT");
1019     return CA_STATUS_OK;
1020 }
1021
1022 void CASetLEReqRespServerCallback(CABLEDataReceivedCallback callback)
1023 {
1024     OIC_LOG(DEBUG, TAG, "IN");
1025
1026     oc_mutex_lock(g_leReqRespCbMutex);
1027     g_leServerDataReceivedCallback = callback;
1028     oc_mutex_unlock(g_leReqRespCbMutex);
1029
1030     OIC_LOG(DEBUG, TAG, "OUT");
1031 }
1032
1033 void CASetBLEServerErrorHandleCallback(CABLEErrorHandleCallback callback)
1034 {
1035     g_serverErrorCallback = callback;
1036 }
1037
1038 bool CALEServerIsConnected(const char* address)
1039 {
1040     (void)address;
1041     //@Todo
1042     return true;
1043 }
1044
1045 uint16_t CALEServerGetMtuSize(const char* address)
1046 {
1047     OIC_LOG(DEBUG, TAG, "IN");
1048     VERIFY_NON_NULL_RET(address, TAG, "address is null", CA_DEFAULT_BLE_MTU_SIZE);
1049
1050     unsigned int mtu;
1051     int ret = bt_device_get_att_mtu(address, &mtu);
1052     if (0 != ret)
1053     {
1054         OIC_LOG_V(ERROR, TAG,
1055                   "bt_device_get_att_mtu failed with return [%s]", CALEGetErrorMsg(ret));
1056         return CA_DEFAULT_BLE_MTU_SIZE;
1057     }
1058     OIC_LOG_V(INFO, TAG, "mtu size(including header) from bt_device_get_att_mtu is %d", mtu);
1059     OIC_LOG(DEBUG, TAG, "OUT");
1060     return mtu - CA_BLE_MTU_HEADER_SIZE;
1061 }