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