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