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