replace : iotivity -> iotivity-sec
[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  * Initial buffer size for Gatt Server.
38  */
39 #define CA_LE_INITIAL_BUF_SIZE 512
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  * Callback register with LE adapter.  This callback is called on reception of any
68  * data from the remote device.
69  */
70 static CABLEDataReceivedCallback g_leServerDataReceivedCallback = NULL;
71
72 /**
73  * Callback to notify any error in LE adapter.
74  */
75 static CABLEErrorHandleCallback g_serverErrorCallback = NULL;
76
77 /**
78  * To keep the state of GATT server if started or not.
79  */
80 static bool g_isLEGattServerStarted = false;
81
82 /**
83  * Mutex to synchronize the calls to start and stop server.
84  */
85 static oc_mutex g_leServerStateMutex = NULL;
86
87 /**
88  * Mutex to synchronize writing operations on the characteristics.
89  */
90 static  oc_mutex g_leCharacteristicMutex = NULL;
91
92 /**
93  * Mutex to synchronize to creation of OIC service.
94  */
95 static  oc_mutex g_leServiceMutex = NULL;
96
97 /**
98  * Mutex to synchronize access to the requestResponse callback to be called
99  * when the data needs to be sent from GATTClient.
100  */
101 static  oc_mutex g_leReqRespCbMutex = NULL;
102
103 /**
104  * Mutex to synchronize the task to be pushed to thread pool.
105  */
106 static oc_mutex g_leServerThreadPoolMutex = NULL;
107
108 /**
109  * Reference to threadpool.
110  */
111 static ca_thread_pool_t g_leServerThreadPool = NULL;
112
113 /**
114  * GmainLoop to manage the threads to receive the callback from the platfrom.
115  */
116 static GMainLoop *g_eventLoop = NULL;
117
118 /**
119  * This contains the list of OIC clients connected to the server.
120  */
121 static LEClientInfoList *g_LEClientList = NULL;
122
123 /**
124  * Mutex to synchronize access to LE ClientList.
125  */
126 static oc_mutex g_LEClientListMutex = NULL;
127
128 static const int samsung_code = 117;
129
130 static bool cutom_adv_flag = false;
131 static char *custom_adv_data = NULL;
132 static int custom_adv_data_length = 0;
133
134 static bool cutom_scanrsp_flag = false;
135 static char *custom_scanrsp_data = NULL;
136 static int custom_scanrsp_data_length = 0;
137
138 CAResult_t CAsetServerAdvertisementData(const char *data, int length)
139 {
140     int res = 0;
141     CAResult_t ret = CA_STATUS_OK;
142
143     OIC_LOG(DEBUG, TAG, "IN");
144
145     if(!data || strlen(data) <= 0 || length <=0 )
146     {
147         OIC_LOG(ERROR, TAG, "Invalid param is passed");
148         return CA_STATUS_INVALID_PARAM;
149     }
150
151     oc_mutex_lock(g_leServerStateMutex);
152
153     cutom_adv_flag = true;
154     custom_adv_data = data;
155     custom_adv_data_length = length;
156
157     oc_mutex_unlock(g_leServerStateMutex);
158
159     OIC_LOG_V(DEBUG, TAG, "Custom advertise value has set as [%s]", custom_adv_data);
160     OIC_LOG(DEBUG, TAG, "OUT");
161
162     return ret;
163 }
164
165 CAResult_t CAsetServerSanResponseData(const char *data, int length)
166 {
167     int res = 0;
168     CAResult_t ret = CA_STATUS_OK;
169
170     OIC_LOG(DEBUG, TAG, "IN");
171
172     if(!data || strlen(data) <= 0 || length <=0 )
173     {
174         OIC_LOG(ERROR, TAG, "Invalid param is passed");
175         return CA_STATUS_INVALID_PARAM;
176     }
177
178     oc_mutex_lock(g_leServerStateMutex);
179
180     cutom_scanrsp_flag = true;
181     custom_scanrsp_data = data;
182     custom_scanrsp_data_length = length;
183
184     oc_mutex_unlock(g_leServerStateMutex);
185
186     OIC_LOG_V(DEBUG, TAG, "Custom scan response value has set as [%s]", custom_scanrsp_data);
187     OIC_LOG(DEBUG, TAG, "OUT");
188
189     return ret;
190 }
191
192 void CALEGattServerConnectionStateChanged(bool connected, const char *remoteAddress)
193 {
194     VERIFY_NON_NULL_VOID(remoteAddress, TAG, "remote address");
195
196     CAResult_t res = CA_STATUS_OK;
197     if (connected)
198     {
199         OIC_LOG_V(DEBUG, TAG, "Connected to [%s]", remoteAddress);
200         char *addr = OICStrdup(remoteAddress);
201         oc_mutex_lock(g_LEClientListMutex);
202         res  = CAAddLEClientInfoToList(&g_LEClientList, addr);
203         if (CA_STATUS_OK != res)
204         {
205             OIC_LOG(ERROR, TAG, "CAAddLEClientInfoToList failed");
206             oc_mutex_unlock(g_LEClientListMutex);
207             OICFree(addr);
208             return;
209         }
210         oc_mutex_unlock(g_LEClientListMutex);
211
212         res = CALEStopAdvertise();
213         if (CA_STATUS_OK != res)
214         {
215             OIC_LOG_V(ERROR, TAG, "Failed to stop advertising [%d]", res);
216             return;
217         }
218     }
219     else
220     {
221         OIC_LOG_V(DEBUG, TAG, "Disconnected from [%s]", remoteAddress);
222         oc_mutex_lock(g_LEClientListMutex);
223         CARemoveLEClientInfoFromList(&g_LEClientList, remoteAddress);
224         oc_mutex_unlock(g_LEClientListMutex);
225
226         res = CALEStartAdvertise();
227         if (CA_STATUS_OK != res)
228         {
229             OIC_LOG_V(ERROR, TAG, "Failed to start advertising [%d]", res);
230             return;
231         }
232     }
233 }
234
235 #ifdef BLE_TIZEN_30
236 void CALEServerNotificationSentCB(int result, const char *remote_address, bt_gatt_server_h server,
237                                   bt_gatt_h characteristic, bool completed, void *user_data)
238 #else
239 void CALEServerNotificationSentCB(int result, char *remote_address, bt_gatt_server_h server,
240                                   bt_gatt_h characteristic, bool completed, void *user_data)
241 #endif
242 {
243     OIC_LOG_V(DEBUG, TAG, "Notification to the device[%s] result[%d]", remote_address, result);
244 }
245
246 CAResult_t CAStartLEGattServer()
247 {
248     OIC_LOG(DEBUG, TAG, "IN");
249
250     oc_mutex_lock(g_leServerStateMutex);
251     if (true == g_isLEGattServerStarted)
252     {
253         OIC_LOG(ERROR, TAG, "Gatt Server is already running");
254         oc_mutex_unlock(g_leServerStateMutex);
255         return CA_STATUS_OK;
256     }
257
258     CAResult_t ret = CAInitLEGattServer();
259     if (CA_STATUS_OK != ret)
260     {
261         OIC_LOG_V(ERROR, TAG, "CAInitLEGattServer failed[%d]", ret);
262         oc_mutex_unlock(g_leServerStateMutex);
263         CATerminateLEGattServer();
264         return CA_STATUS_FAILED;
265     }
266
267     ret  = CAAddNewLEServiceInGattServer(CA_GATT_SERVICE_UUID);
268     if (CA_STATUS_OK != ret)
269     {
270         OIC_LOG_V(ERROR, TAG, "CAAddNewLEServiceInGattServer failed[%d]", ret);
271         oc_mutex_unlock(g_leServerStateMutex);
272         CATerminateLEGattServer();
273         return CA_STATUS_FAILED;
274     }
275
276     static const char charReadUUID[] = CA_GATT_RESPONSE_CHRC_UUID;
277     char charReadValue[] = {33, 44, 55, 66}; // These are initial random values
278
279     // For Read Characteristics.
280     ret = CAAddNewCharacteristicsToGattServer(g_gattSvcPath, charReadUUID, charReadValue,
281                                               CA_LE_INITIAL_BUF_SIZE, true);
282     if (CA_STATUS_OK != ret)
283     {
284         OIC_LOG_V(ERROR, TAG, "CAAddNewCharacteristicsToGattServer failed[%d]", ret);
285         oc_mutex_unlock(g_leServerStateMutex);
286         CATerminateLEGattServer();
287         return CA_STATUS_FAILED;
288     }
289
290     static const char charWriteUUID[] = CA_GATT_REQUEST_CHRC_UUID;
291     char charWriteValue[] = {33, 44, 55, 66}; // These are initial random values
292
293
294     ret = CAAddNewCharacteristicsToGattServer(g_gattSvcPath, charWriteUUID, charWriteValue,
295             CA_LE_INITIAL_BUF_SIZE, false); // For Write Characteristics.
296     if (CA_STATUS_OK != ret )
297     {
298         OIC_LOG_V(ERROR, TAG, "CAAddNewCharacteristicsToGattServer failed[%d]", ret);
299         oc_mutex_unlock(g_leServerStateMutex);
300         CATerminateLEGattServer();
301         return CA_STATUS_FAILED;
302     }
303
304     ret = CARegisterLEServicewithGattServer(g_gattSvcPath);
305     if (CA_STATUS_OK != ret )
306     {
307         OIC_LOG_V(ERROR, TAG, "CARegisterLEServicewithGattServer failed[%d]", ret);
308         oc_mutex_unlock(g_leServerStateMutex);
309         CATerminateLEGattServer();
310         return CA_STATUS_FAILED;
311     }
312
313     ret = CALEStartAdvertise();
314     if (CA_STATUS_OK != ret)
315     {
316         OIC_LOG_V(ERROR, TAG, "CALEStartAdvertise failed[%d]", ret);
317         oc_mutex_unlock(g_leServerStateMutex);
318         CATerminateLEGattServer();
319         return CA_STATUS_FAILED;
320     }
321
322     g_isLEGattServerStarted = true;
323
324     oc_mutex_unlock(g_leServerStateMutex);
325
326     OIC_LOG(DEBUG, TAG, "OUT");
327     return CA_STATUS_OK;
328 }
329
330 void CALENotificationCb(bool notify, bt_gatt_server_h server, bt_gatt_h gatt_handle,
331                         void *user_data)
332 {
333     OIC_LOG(DEBUG, TAG, "IN");
334     if (notify)
335     {
336         OIC_LOG(DEBUG, TAG, "Notification is subscribed by the client");
337         CALogSendStateInfo(CA_ADAPTER_GATT_BTLE, "", 0, -1,
338                            true, "notifyChar success");
339     }
340     else
341     {
342         CALogSendStateInfo(CA_ADAPTER_GATT_BTLE, "", 0, -1,
343                            false, "notifyChar failure");
344     }
345     OIC_LOG(DEBUG, TAG, "OUT");
346 }
347
348 CAResult_t CALEStartAdvertise()
349 {
350     OIC_LOG(DEBUG, TAG, "IN");
351
352     CAResult_t res = CALEStartAdvertiseImpl(CA_GATT_SERVICE_UUID);
353     if (CA_STATUS_OK != res)
354     {
355         OIC_LOG_V(ERROR, TAG, "CALEStartAdvertiseImpl failed[%d]", res);
356     }
357
358     OIC_LOG(DEBUG, TAG, "OUT");
359     return res;
360 }
361
362 CAResult_t CALEStartAdvertiseImpl(const char *serviceUUID)
363 {
364     OIC_LOG(DEBUG, TAG, "IN");
365
366     int length;
367
368     int res = bt_adapter_le_create_advertiser(&g_hAdvertiser);
369     if (NULL == g_hAdvertiser || BT_ERROR_NONE != res)
370     {
371         OIC_LOG_V(ERROR, TAG, "g_hAdvertiser is NULL/ Result is %d", res);
372         return CA_STATUS_FAILED;
373     }
374
375     if (cutom_adv_flag == false) // Advertise with Default Service UUID
376     {
377         OIC_LOG(DEBUG, TAG, "Advertise with default Service UUID");
378
379         res = bt_adapter_le_add_advertising_service_uuid(g_hAdvertiser,
380                                                          BT_ADAPTER_LE_PACKET_ADVERTISING,
381                                                          serviceUUID);
382         if (BT_ERROR_NONE != res)
383         {
384             OIC_LOG_V(ERROR, TAG, "bt_adapter_le_add_advertising_service_uuid failed with ret[%s]",
385                       CALEGetErrorMsg(res));
386             return CA_STATUS_FAILED;
387         }
388     }
389     else // Advertise with custom advertise data
390     {
391         OIC_LOG(DEBUG, TAG, "Advertise with custom advertise data");
392
393         res = bt_adapter_le_add_advertising_manufacturer_data(g_hAdvertiser,BT_ADAPTER_LE_PACKET_ADVERTISING, samsung_code, custom_adv_data, custom_adv_data_length);
394         if (BT_ERROR_NONE != res)
395         {
396             OIC_LOG_V(ERROR, TAG, "bt_adapter_le_add_advertising_manufacturer_data failed(BT_ADAPTER_LE_PACKET_ADVERTISING) with ret[%s]",
397                       CALEGetErrorMsg(res));
398             return CA_STATUS_FAILED;
399         }
400
401     }
402
403     if(cutom_scanrsp_flag == false)
404     {
405         OIC_LOG(DEBUG, TAG, "Advertise with default scan response data");
406
407         res = bt_adapter_le_set_advertising_device_name(g_hAdvertiser,
408                                                         BT_ADAPTER_LE_PACKET_SCAN_RESPONSE, true);
409         if (BT_ERROR_NONE != res)
410         {
411             OIC_LOG_V(ERROR, TAG, "bt_adapter_le_set_advertising_device_name failed with ret[%s]",
412                       CALEGetErrorMsg(res));
413             return CA_STATUS_FAILED;
414         }
415     }
416     else // Advertise with custom advertise data
417     {
418         OIC_LOG(DEBUG, TAG, "Advertise with custom scan response data");
419
420         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);
421         if (BT_ERROR_NONE != res)
422         {
423             OIC_LOG_V(ERROR, TAG, "bt_adapter_le_add_advertising_manufacturer_data(BT_ADAPTER_LE_PACKET_SCAN_RESPONSE) failed with ret[%s]",
424                       CALEGetErrorMsg(res));
425             return CA_STATUS_FAILED;
426         }
427
428     }
429
430     res = bt_adapter_le_start_advertising_new(g_hAdvertiser, NULL, NULL);
431     if (BT_ERROR_NONE != res)
432     {
433         OIC_LOG_V(ERROR, TAG, "bt_adapter_le_start_advertising_new failed with ret[%s]",
434                   CALEGetErrorMsg(res));
435         return CA_STATUS_FAILED;
436     }
437
438     OIC_LOG(DEBUG, TAG, "OUT");
439     return CA_STATUS_OK;
440 }
441
442 CAResult_t CALEStopAdvertise()
443 {
444     OIC_LOG(DEBUG, TAG, "IN");
445     if (NULL != g_hAdvertiser)
446     {
447         int ret  = bt_adapter_le_stop_advertising(g_hAdvertiser);
448         if (0 != ret)
449         {
450             OIC_LOG_V(ERROR, TAG,
451                       "bt_adapter_le_stop_advertising failed with ret[%s]", CALEGetErrorMsg(ret));
452         }
453
454         ret = bt_adapter_le_destroy_advertiser(g_hAdvertiser);
455         if (0 != ret)
456         {
457             OIC_LOG_V(ERROR, TAG,
458                       "bt_adapter_le_destroy_advertiser failed with ret[%s]", CALEGetErrorMsg(ret));
459         }
460         g_hAdvertiser = NULL;
461     }
462     else
463     {
464         OIC_LOG(ERROR, TAG, "Advertising is not running");
465         return CA_STATUS_FAILED;
466     }
467
468     OIC_LOG(DEBUG, TAG, "OUT");
469     return CA_STATUS_OK;
470 }
471
472 CAResult_t CAStopLEGattServer()
473 {
474     OIC_LOG(DEBUG, TAG, "IN");
475
476     oc_mutex_lock(g_leServerStateMutex);
477
478     if (false == g_isLEGattServerStarted)
479     {
480         OIC_LOG(ERROR, TAG, "Gatt Server is not running to stop");
481         oc_mutex_unlock(g_leServerStateMutex);
482         return CA_STATUS_OK;
483     }
484
485     g_isLEGattServerStarted = false;
486     cutom_adv_flag = false;
487     custom_adv_data = NULL;
488     custom_adv_data_length = 0;
489     cutom_scanrsp_flag = false;
490     custom_scanrsp_data = NULL;
491     custom_scanrsp_data_length = 0;
492
493     oc_mutex_lock(g_LEClientListMutex);
494     CADisconnectAllClient(g_LEClientList);
495     g_LEClientList = NULL;
496     oc_mutex_unlock(g_LEClientListMutex);
497
498     CAResult_t res = CALEStopAdvertise();
499     {
500         OIC_LOG_V(ERROR, TAG, "CALEStopAdvertise failed with ret[%d]", res);
501     }
502
503     res = CADeInitLEGattServer();
504     if (CA_STATUS_OK != res)
505     {
506         OIC_LOG_V(ERROR, TAG, "CADeInitLEGattService failed with ret[%d]", res);
507     }
508
509     GMainContext  *context_event_loop = NULL;
510     // Required for waking up the thread which is running in gmain loop
511     if (NULL != g_eventLoop)
512     {
513         context_event_loop = g_main_loop_get_context(g_eventLoop);
514
515         if (context_event_loop)
516         {
517             OIC_LOG_V(DEBUG,  TAG, "g_eventLoop context %x", context_event_loop);
518             g_main_context_wakeup(context_event_loop);
519
520             // Kill g main loops and kill threads
521             g_main_loop_quit(g_eventLoop);
522         }
523         g_eventLoop = NULL;
524     }
525     else
526     {
527         OIC_LOG(ERROR, TAG, "g_eventLoop context is NULL");
528     }
529
530     oc_mutex_unlock(g_leServerStateMutex);
531
532     OIC_LOG(DEBUG, TAG, "OUT");
533     return CA_STATUS_OK;
534 }
535
536 CAResult_t CAInitializeLEGattServer()
537 {
538     OIC_LOG(DEBUG, TAG, "IN");
539
540     CAResult_t ret = CAInitGattServerMutexVariables();
541     if (CA_STATUS_OK != ret )
542     {
543         OIC_LOG(ERROR, TAG, "CAInitGattServerMutexVariables failed!");
544         CATerminateGattServerMutexVariables();
545         return CA_SERVER_NOT_STARTED;
546     }
547     OIC_LOG(DEBUG, TAG, "OUT");
548     return ret;
549 }
550
551 void CATerminateLEGattServer()
552 {
553     OIC_LOG(DEBUG, TAG, "IN");
554
555     // Service and characteristics path will be freed by the platform.
556     oc_mutex_lock(g_leServiceMutex);
557     g_gattSvcPath = NULL;
558     oc_mutex_unlock(g_leServiceMutex);
559
560     oc_mutex_lock(g_leCharacteristicMutex);
561     g_gattReadCharPath = NULL;
562     g_gattWriteCharPath = NULL;
563     oc_mutex_unlock(g_leCharacteristicMutex);
564
565     oc_mutex_lock(g_leServerThreadPoolMutex);
566     g_leServerThreadPool = NULL;
567     oc_mutex_unlock(g_leServerThreadPoolMutex);
568
569     // Terminating all mutex variables.
570     CATerminateGattServerMutexVariables();
571     OIC_LOG(DEBUG, TAG, "OUT");
572 }
573
574 CAResult_t CAInitGattServerMutexVariables()
575 {
576     OIC_LOG(DEBUG, TAG, "IN");
577     if (NULL == g_leServerStateMutex)
578     {
579         g_leServerStateMutex = oc_mutex_new();
580         if (NULL == g_leServerStateMutex)
581         {
582             OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
583             return CA_STATUS_FAILED;
584         }
585     }
586
587     if (NULL == g_leServiceMutex)
588     {
589         g_leServiceMutex = oc_mutex_new();
590         if (NULL == g_leServiceMutex)
591         {
592             OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
593             return CA_STATUS_FAILED;
594         }
595     }
596
597     if (NULL == g_leCharacteristicMutex)
598     {
599         g_leCharacteristicMutex = oc_mutex_new();
600         if (NULL == g_leCharacteristicMutex)
601         {
602             OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
603             return CA_STATUS_FAILED;
604         }
605     }
606
607     if (NULL == g_leReqRespCbMutex)
608     {
609         g_leReqRespCbMutex = oc_mutex_new();
610         if (NULL == g_leReqRespCbMutex)
611         {
612             OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
613             return CA_STATUS_FAILED;
614         }
615     }
616
617     if (NULL == g_leServerThreadPoolMutex)
618     {
619         g_leServerThreadPoolMutex = oc_mutex_new();
620         if (NULL == g_leServerThreadPoolMutex)
621         {
622             OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
623             return CA_STATUS_FAILED;
624         }
625     }
626
627     if (NULL == g_LEClientListMutex)
628     {
629         g_LEClientListMutex = oc_mutex_new();
630         if (NULL == g_LEClientListMutex)
631         {
632             OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
633             return CA_STATUS_FAILED;
634         }
635     }
636
637     OIC_LOG(DEBUG, TAG, "OUT");
638     return CA_STATUS_OK;
639 }
640
641 void CATerminateGattServerMutexVariables()
642 {
643     OIC_LOG(DEBUG, TAG, "IN");
644     oc_mutex_free(g_leServerStateMutex);
645     g_leServerStateMutex = NULL;
646
647     oc_mutex_free(g_leServiceMutex);
648     g_leServiceMutex = NULL;
649
650     oc_mutex_free(g_leCharacteristicMutex);
651     g_leCharacteristicMutex = NULL;
652
653     oc_mutex_free(g_leReqRespCbMutex);
654     g_leReqRespCbMutex = NULL;
655
656     oc_mutex_free(g_leServerThreadPoolMutex);
657     g_leServerThreadPoolMutex = NULL;
658
659     oc_mutex_free(g_LEClientListMutex);
660     g_LEClientListMutex = NULL;
661
662     OIC_LOG(DEBUG, TAG, "OUT");
663 }
664
665 CAResult_t CAInitLEGattServer()
666 {
667     OIC_LOG(DEBUG, TAG, "IN");
668
669     int ret =  bt_gatt_server_initialize();
670     if (0 != ret)
671     {
672         OIC_LOG_V(ERROR, TAG, "bt_gatt_server_initialize failed with ret[%s]",
673                   CALEGetErrorMsg(ret));
674         return CA_STATUS_FAILED;
675     }
676
677     if (!g_gattServer)
678     {
679         OIC_LOG(DEBUG, TAG, "g_gattServer is NULL. create gatt server..");
680         ret = bt_gatt_server_create(&g_gattServer);
681         if (0 != ret)
682         {
683             OIC_LOG_V(ERROR, TAG, "bt_gatt_server_create failed with ret[%s]",
684                       CALEGetErrorMsg(ret));
685             return CA_STATUS_FAILED;
686         }
687     }
688
689     OIC_LOG(DEBUG, TAG, "OUT");
690     return CA_STATUS_OK;
691 }
692
693 CAResult_t CADeInitLEGattServer()
694 {
695     OIC_LOG(DEBUG, TAG, "IN");
696
697     int ret = bt_gatt_server_unregister_all_services(g_gattServer);
698     if (0 != ret)
699     {
700         OIC_LOG_V(ERROR, TAG, "bt_gatt_server_unregister_all_services failed with ret[%s]",
701                   CALEGetErrorMsg(ret));
702         return CA_STATUS_FAILED;
703     }
704
705     ret = bt_gatt_server_destroy(g_gattServer);
706     if (0 != ret)
707     {
708         OIC_LOG_V(ERROR, TAG, "bt_gatt_server_destroy failed with ret[%s]",
709                   CALEGetErrorMsg(ret));
710         return CA_STATUS_FAILED;
711     }
712     g_gattServer = NULL;
713
714     ret =  bt_gatt_server_deinitialize();
715     if (0 != ret)
716     {
717         OIC_LOG_V(ERROR, TAG, "bt_gatt_server_deinitialize failed with ret[%s]",
718                   CALEGetErrorMsg(ret));
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 }