Update snapshot(2017-11-23)
[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             return CA_STATUS_FAILED;
682         }
683     }
684
685     OIC_LOG(DEBUG, TAG, "OUT");
686     return CA_STATUS_OK;
687 }
688
689 CAResult_t CADeInitLEGattServer()
690 {
691     OIC_LOG(DEBUG, TAG, "IN");
692
693     int ret = bt_gatt_server_unregister_all_services(g_gattServer);
694     if (0 != ret)
695     {
696         OIC_LOG_V(ERROR, TAG, "bt_gatt_server_unregister_all_services failed with ret[%s]",
697                   CALEGetErrorMsg(ret));
698         return CA_STATUS_FAILED;
699     }
700
701     ret = bt_gatt_server_destroy(g_gattServer);
702     if (0 != ret)
703     {
704         OIC_LOG_V(ERROR, TAG, "bt_gatt_server_destroy failed with ret[%s]",
705                   CALEGetErrorMsg(ret));
706         return CA_STATUS_FAILED;
707     }
708     g_gattServer = NULL;
709
710     ret =  bt_gatt_server_deinitialize();
711     if (0 != ret)
712     {
713         OIC_LOG_V(ERROR, TAG, "bt_gatt_server_deinitialize failed with ret[%s]",
714                   CALEGetErrorMsg(ret));
715         return CA_STATUS_FAILED;
716     }
717
718     OIC_LOG(DEBUG, TAG, "OUT");
719     return CA_STATUS_OK;
720 }
721
722 void CASetLEServerThreadPoolHandle(ca_thread_pool_t handle)
723 {
724     OIC_LOG(DEBUG, TAG, "IN");
725     oc_mutex_lock(g_leServerThreadPoolMutex);
726     g_leServerThreadPool = handle;
727     oc_mutex_unlock(g_leServerThreadPoolMutex);
728     OIC_LOG(DEBUG, TAG, "OUT");
729 }
730
731 CAResult_t CAAddNewLEServiceInGattServer(const char *serviceUUID)
732 {
733     OIC_LOG(DEBUG, TAG, "IN");
734
735     VERIFY_NON_NULL(serviceUUID, TAG, "serviceUUID");
736
737     OIC_LOG_V(DEBUG, TAG, "service uuid %s", serviceUUID);
738
739     bt_gatt_service_type_e type = BT_GATT_SERVICE_TYPE_PRIMARY;
740
741     oc_mutex_lock(g_leServiceMutex);
742     int ret = bt_gatt_service_create(serviceUUID, type, &g_gattSvcPath);
743     if (0 != ret)
744     {
745         oc_mutex_unlock(g_leServiceMutex);
746         OIC_LOG_V(ERROR, TAG, "bt_gatt_service_create failed with ret [%s]",
747                     CALEGetErrorMsg(ret));
748         return CA_STATUS_FAILED;
749     }
750     oc_mutex_unlock(g_leServiceMutex);
751
752     if (g_gattSvcPath)
753     {
754         OIC_LOG_V(DEBUG, TAG, "ServicePath obtained is %s", (char *)g_gattSvcPath);
755     }
756
757     OIC_LOG(DEBUG, TAG, "OUT");
758     return CA_STATUS_OK;
759 }
760
761 #ifdef BLE_TIZEN_30
762 void CALEGattRemoteCharacteristicWriteCb(const char *remoteAddress, int request_id,
763                                          bt_gatt_server_h server, bt_gatt_h gatt_handle,
764                                          bool response_needed, int offset, const char *charValue,
765                                          int charLen, void *userData)
766 #else
767 void CALEGattRemoteCharacteristicWriteCb(char *remoteAddress, bt_gatt_server_h server,
768                                          bt_gatt_h gatt_handle, int offset, char *charValue,
769                                          int charLen, void *userData)
770 #endif
771 {
772     OIC_LOG(INFO, TAG, "IN - WriteCharCB");
773
774     if (NULL == charValue || NULL == remoteAddress)
775     {
776         OIC_LOG(ERROR, TAG, "Param callback values are NULL");
777         return;
778     }
779
780     OIC_LOG_V(DEBUG, TAG, "len [%d]", charLen);
781
782     uint8_t *data = OICMalloc(charLen);
783     if (NULL == data)
784     {
785         OIC_LOG(ERROR, TAG, "Malloc failed!");
786         return;
787     }
788
789     memcpy(data, charValue, charLen);
790
791     oc_mutex_lock(g_leReqRespCbMutex);
792     if (NULL == g_leServerDataReceivedCallback)
793     {
794         OIC_LOG(ERROR, TAG, "gReqRespCallback is NULL!");
795         oc_mutex_unlock(g_leReqRespCbMutex);
796         OICFree(data);
797         return;
798     }
799
800     OIC_LOG(INFO, TAG, "Sending data up !");
801     uint32_t sentLength = 0;
802     g_leServerDataReceivedCallback(remoteAddress, data, charLen,
803                                     &sentLength);
804     oc_mutex_unlock(g_leReqRespCbMutex);
805     OICFree(data);
806
807 #ifdef BLE_TIZEN_30
808     //response
809     OIC_LOG_V(INFO, TAG, "response_needed flag : %d", response_needed);
810     if (response_needed)
811     {
812         OIC_LOG(INFO, TAG, "send response to remote client");
813         bt_gatt_server_send_response(request_id,
814                 BT_GATT_REQUEST_TYPE_WRITE, offset,
815                 BT_ERROR_NONE, NULL, 0);
816     }
817 #endif
818
819     OIC_LOG(INFO, TAG, "OUT - WriteCharCB");
820 }
821
822 CAResult_t CARegisterLEServicewithGattServer(const bt_gatt_h svcPath)
823 {
824     OIC_LOG(DEBUG, TAG, "IN");
825
826     VERIFY_NON_NULL(svcPath, TAG, "svcPath");
827
828     OIC_LOG_V(DEBUG, TAG, "svcPath:%s", svcPath);
829
830     int ret = bt_gatt_server_register_service(g_gattServer, svcPath);
831     if (0 != ret)
832     {
833         OIC_LOG_V(ERROR, TAG, "bt_gatt_server_register_service failed with ret[%s]",
834                   CALEGetErrorMsg(ret));
835         return CA_STATUS_FAILED;
836     }
837
838     ret = bt_gatt_server_start();
839     if(0 != ret)
840     {
841         OIC_LOG_V(ERROR, TAG, "bt_gatt_server_start failed with ret[%s]",
842                 CALEGetErrorMsg(ret));
843         return CA_STATUS_FAILED;
844     }
845
846 #ifdef BLE_TIZEN_30
847     ret = bt_gatt_server_set_write_value_requested_cb(g_gattWriteCharPath,
848 #else
849     ret = bt_gatt_server_set_value_changed_cb(g_gattWriteCharPath,
850 #endif
851                                               CALEGattRemoteCharacteristicWriteCb, NULL);
852
853     if (0 != ret)
854     {
855         OIC_LOG_V(ERROR, TAG, "bt_gatt_server_set_value_changed_cb failed with ret[%s]",
856                   CALEGetErrorMsg(ret));
857         return CA_STATUS_FAILED;
858     }
859
860     OIC_LOG(DEBUG, TAG, "OUT");
861     return CA_STATUS_OK;
862 }
863
864 CAResult_t CAAddNewCharacteristicsToGattServer(const bt_gatt_h svcPath, const char *charUUID,
865                                                const char *charValue, int charValueLen, bool read)
866 {
867
868     OIC_LOG(DEBUG, TAG, "IN");
869
870     int permissions = BT_GATT_PERMISSION_READ | BT_GATT_PERMISSION_WRITE;
871     int properties;
872     if (read)
873     {
874         properties = BT_GATT_PROPERTY_INDICATE;
875     }
876     else
877     {
878         properties = BT_GATT_PROPERTY_WRITE;
879     }
880
881     bt_gatt_h charPath = NULL;
882
883     int ret = bt_gatt_characteristic_create(charUUID, permissions, properties, charValue,
884                                             charValueLen, &charPath);
885
886     if (0 != ret || NULL == charPath)
887     {
888         OIC_LOG_V(ERROR, TAG,
889                   "bt_gatt_add_characteristic  failed with ret [%s]", CALEGetErrorMsg(ret));
890         return CA_STATUS_FAILED;
891     }
892
893     OIC_LOG_V(DEBUG, TAG,
894               "bt_gatt_characteristic_create charPath obtained: %s", (char *)charPath);
895
896     if (read)
897     {
898 #ifdef BLE_TIZEN_30
899         ret = bt_gatt_server_set_characteristic_notification_state_change_cb(charPath,
900                                                                              CALENotificationCb,
901                                                                              NULL);
902 #else
903         ret = bt_gatt_server_set_notification_state_change_cb(charPath, CALENotificationCb, NULL);
904 #endif
905         if (0 != ret)
906         {
907             OIC_LOG_V(ERROR, TAG,
908 #ifdef BLE_TIZEN_30
909                       "bt_gatt_server_set_characteristic_notification_state_change_cb failed with ret[%s]",
910 #else
911                       "bt_gatt_server_set_notification_state_change_cb  failed with ret[%s]",
912 #endif
913                       CALEGetErrorMsg(ret));
914             return CA_STATUS_FAILED;
915         }
916     }
917
918     ret =  bt_gatt_service_add_characteristic(svcPath, charPath);
919     if (0 != ret)
920     {
921         OIC_LOG_V(ERROR, TAG,
922                   "bt_gatt_service_add_characteristic  failed with ret[%s]",
923                   CALEGetErrorMsg(ret));
924         return CA_STATUS_FAILED;
925     }
926
927     oc_mutex_lock(g_leCharacteristicMutex);
928
929     if (read)
930     {
931         char desc_value[2] = {1, 0};  // Notification enabled.
932         bt_gatt_h descriptor = NULL;
933         permissions = BT_GATT_PERMISSION_READ | BT_GATT_PERMISSION_WRITE;
934         ret = bt_gatt_descriptor_create(CA_GATT_CONFIGURATION_DESC_UUID, permissions,
935                                         desc_value, sizeof(desc_value),
936                                         &descriptor);
937         if (0 != ret)
938         {
939             oc_mutex_unlock(g_leCharacteristicMutex);
940             OIC_LOG_V(ERROR, TAG,
941                       "bt_gatt_descriptor_create  failed with ret[%s]",
942                       CALEGetErrorMsg(ret));
943             return CA_STATUS_FAILED;
944         }
945
946         ret = bt_gatt_characteristic_add_descriptor(charPath, descriptor);
947         if (0 != ret)
948         {
949             oc_mutex_unlock(g_leCharacteristicMutex);
950             OIC_LOG_V(ERROR, TAG,
951                       "bt_gatt_characteristic_add_descriptor  failed with ret[%s]",
952                       CALEGetErrorMsg(ret));
953             return CA_STATUS_FAILED;
954         }
955
956         g_gattReadCharPath = charPath;
957     }
958     else
959     {
960         g_gattWriteCharPath = charPath;
961     }
962
963     oc_mutex_unlock(g_leCharacteristicMutex);
964
965     OIC_LOG(DEBUG, TAG, "OUT");
966     return CA_STATUS_OK;
967 }
968
969 CAResult_t CAUpdateCharacteristicsToGattClient(const char *address, const uint8_t *charValue,
970                                                uint32_t charValueLen)
971 {
972     OIC_LOG(DEBUG, TAG, "IN");
973
974     VERIFY_NON_NULL(charValue, TAG, "charValue");
975     VERIFY_NON_NULL(address, TAG, "address");
976
977     OIC_LOG_V(DEBUG, TAG, "Client's Unicast address for sending data [%s]", address);
978
979     oc_mutex_lock(g_leCharacteristicMutex);
980
981     if (NULL  == g_gattReadCharPath)
982     {
983         OIC_LOG(ERROR, TAG, "g_gattReadCharPath is NULL");
984         oc_mutex_unlock(g_leCharacteristicMutex);
985         return CA_STATUS_FAILED;
986     }
987
988     int ret = bt_gatt_set_value(g_gattReadCharPath, (char *)charValue, charValueLen);
989     if (0 != ret)
990     {
991         OIC_LOG_V(ERROR, TAG,
992                   "bt_gatt_set_value failed with return [%s]", CALEGetErrorMsg(ret));
993         oc_mutex_unlock(g_leCharacteristicMutex);
994         return CA_STATUS_FAILED;
995     }
996
997 #ifdef BLE_TIZEN_30
998     ret = bt_gatt_server_notify_characteristic_changed_value(g_gattReadCharPath,
999                                                              CALEServerNotificationSentCB,
1000                                                              address, NULL);
1001 #else
1002     ret = bt_gatt_server_notify(g_gattReadCharPath, false, CALEServerNotificationSentCB,
1003                                 address, NULL);
1004 #endif
1005
1006     if (0 != ret)
1007     {
1008         OIC_LOG_V(ERROR, TAG,
1009 #ifdef BLE_TIZEN_30
1010                   "bt_gatt_server_notify_characteristic_changed_value failed with return [%s]",
1011 #else
1012                   "bt_gatt_server_notify failed with return [%s]",
1013 #endif
1014                   CALEGetErrorMsg(ret));
1015         oc_mutex_unlock(g_leCharacteristicMutex);
1016         return CA_STATUS_FAILED;
1017     }
1018
1019     oc_mutex_unlock(g_leCharacteristicMutex);
1020
1021     OIC_LOG(DEBUG, TAG, "OUT");
1022     return CA_STATUS_OK;
1023 }
1024
1025 CAResult_t CAUpdateCharacteristicsToAllGattClients(const uint8_t *charValue, uint32_t charValueLen)
1026 {
1027     OIC_LOG(DEBUG, TAG, "IN");
1028
1029     VERIFY_NON_NULL(charValue, TAG, "charValue");
1030
1031     oc_mutex_lock(g_leCharacteristicMutex);
1032
1033     if (NULL  == g_gattReadCharPath)
1034     {
1035         OIC_LOG(ERROR, TAG, "g_gattReadCharPath is NULL");
1036         oc_mutex_unlock(g_leCharacteristicMutex);
1037         return CA_STATUS_FAILED;
1038     }
1039
1040     int ret = bt_gatt_set_value(g_gattReadCharPath, (char *)charValue, charValueLen);
1041     if (0 != ret)
1042     {
1043         OIC_LOG_V(ERROR, TAG, "bt_gatt_set_value failed with return[%s]", CALEGetErrorMsg(ret));
1044         oc_mutex_unlock(g_leCharacteristicMutex);
1045         return CA_STATUS_FAILED;
1046     }
1047
1048 #ifdef BLE_TIZEN_30
1049     ret = bt_gatt_server_notify_characteristic_changed_value(g_gattReadCharPath,
1050                                                              CALEServerNotificationSentCB,
1051                                                              NULL, NULL);
1052 #else
1053     ret = bt_gatt_server_notify(g_gattReadCharPath, false, CALEServerNotificationSentCB,
1054                                 NULL, NULL);
1055 #endif
1056     if (0 != ret)
1057     {
1058         OIC_LOG_V(ERROR, TAG,
1059 #ifdef BLE_TIZEN_30
1060                   "bt_gatt_server_notify_characteristic_changed_value failed with return[%s]",
1061 #else
1062                   "bt_gatt_server_notify failed with return[%s]",
1063 #endif
1064                   CALEGetErrorMsg(ret));
1065         oc_mutex_unlock(g_leCharacteristicMutex);
1066         return CA_STATUS_FAILED;
1067     }
1068
1069     oc_mutex_unlock(g_leCharacteristicMutex);
1070
1071     OIC_LOG(DEBUG, TAG, "OUT");
1072     return CA_STATUS_OK;
1073 }
1074
1075 void CASetLEReqRespServerCallback(CABLEDataReceivedCallback callback)
1076 {
1077     OIC_LOG(DEBUG, TAG, "IN");
1078
1079     oc_mutex_lock(g_leReqRespCbMutex);
1080     g_leServerDataReceivedCallback = callback;
1081     oc_mutex_unlock(g_leReqRespCbMutex);
1082
1083     OIC_LOG(DEBUG, TAG, "OUT");
1084 }
1085
1086 void CASetBLEServerErrorHandleCallback(CABLEErrorHandleCallback callback)
1087 {
1088     g_serverErrorCallback = callback;
1089 }
1090
1091 bool CALEServerIsConnected(const char* address)
1092 {
1093     //@Todo
1094     return true;
1095 }
1096
1097 uint16_t CALEServerGetMtuSize(const char* address)
1098 {
1099     OIC_LOG(DEBUG, TAG, "IN");
1100     VERIFY_NON_NULL_RET(address, TAG, "address is null", CA_DEFAULT_BLE_MTU_SIZE);
1101
1102     unsigned int mtu;
1103     int ret = bt_device_get_att_mtu(address, &mtu);
1104     if (0 != ret)
1105     {
1106         OIC_LOG_V(ERROR, TAG,
1107                   "bt_device_get_att_mtu failed with return [%s]", CALEGetErrorMsg(ret));
1108         return CA_DEFAULT_BLE_MTU_SIZE;
1109     }
1110     OIC_LOG_V(INFO, TAG, "mtu size(including header) from bt_device_get_att_mtu is %d", mtu);
1111     OIC_LOG(DEBUG, TAG, "OUT");
1112     return mtu - CA_BLE_MTU_HEADER_SIZE;
1113 }