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