Fix packet loss related BLE fragmentation & MTU attr value size
[platform/upstream/iotivity.git] / resource / csdk / connectivity / src / bt_le_adapter / tizen / caleserver.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"
35
36 /**
37  * Initial buffer size(attr value max 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 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         res = CALEStopAdvertise();
149         if (CA_STATUS_OK != res)
150         {
151             OIC_LOG_V(ERROR, TAG, "Failed to stop advertising [%d]", res);
152             return;
153         }
154     }
155     else
156     {
157         OIC_LOG_V(DEBUG, TAG, "Disconnected from [%s]", remoteAddress);
158         oc_mutex_lock(g_LEClientListMutex);
159         CARemoveLEClientInfoFromList(&g_LEClientList, remoteAddress);
160         oc_mutex_unlock(g_LEClientListMutex);
161
162         res = CALEStartAdvertise();
163         if (CA_STATUS_OK != res)
164         {
165             OIC_LOG_V(ERROR, TAG, "Failed to start advertising [%d]", res);
166             return;
167         }
168     }
169 }
170
171 void CALEServerNotificationSentCB(int result, char *remote_address, bt_gatt_server_h server,
172                                   bt_gatt_h characteristic, bool completed, void *user_data)
173 {
174     OIC_LOG_V(DEBUG, TAG, "Notification to the device[%s] result[%d]", remote_address, result);
175 }
176
177 CAResult_t CAStartLEGattServer()
178 {
179     OIC_LOG(DEBUG, TAG, "IN");
180
181     oc_mutex_lock(g_leServerStateMutex);
182     if (true == g_isLEGattServerStarted)
183     {
184         OIC_LOG(ERROR, TAG, "Gatt Server is already running");
185         oc_mutex_unlock(g_leServerStateMutex);
186         return CA_STATUS_OK;
187     }
188
189     CAResult_t ret = CAInitLEGattServer();
190     if (CA_STATUS_OK != ret)
191     {
192         OIC_LOG_V(ERROR, TAG, "CAInitLEGattServer failed[%d]", ret);
193         oc_mutex_unlock(g_leServerStateMutex);
194         CATerminateLEGattServer();
195         return CA_STATUS_FAILED;
196     }
197
198     ret  = CAAddNewLEServiceInGattServer(CA_GATT_SERVICE_UUID);
199     if (CA_STATUS_OK != ret)
200     {
201         OIC_LOG_V(ERROR, TAG, "CAAddNewLEServiceInGattServer failed[%d]", ret);
202         oc_mutex_unlock(g_leServerStateMutex);
203         CATerminateLEGattServer();
204         return CA_STATUS_FAILED;
205     }
206
207     static const char charReadUUID[] = CA_GATT_RESPONSE_CHRC_UUID;
208     char charReadValue[] = {33, 44, 55, 66}; // These are initial random values
209
210     // For Read Characteristics.
211     ret = CAAddNewCharacteristicsToGattServer(g_gattSvcPath, charReadUUID, charReadValue,
212                                               CA_LE_INITIAL_BUF_SIZE, true);
213     if (CA_STATUS_OK != ret)
214     {
215         OIC_LOG_V(ERROR, TAG, "CAAddNewCharacteristicsToGattServer failed[%d]", ret);
216         oc_mutex_unlock(g_leServerStateMutex);
217         CATerminateLEGattServer();
218         return CA_STATUS_FAILED;
219     }
220
221     static const char charWriteUUID[] = CA_GATT_REQUEST_CHRC_UUID;
222     char charWriteValue[] = {33, 44, 55, 66}; // These are initial random values
223
224
225     ret = CAAddNewCharacteristicsToGattServer(g_gattSvcPath, charWriteUUID, charWriteValue,
226             CA_LE_INITIAL_BUF_SIZE, false); // For Write Characteristics.
227     if (CA_STATUS_OK != ret )
228     {
229         OIC_LOG_V(ERROR, TAG, "CAAddNewCharacteristicsToGattServer failed[%d]", ret);
230         oc_mutex_unlock(g_leServerStateMutex);
231         CATerminateLEGattServer();
232         return CA_STATUS_FAILED;
233     }
234
235     ret = CARegisterLEServicewithGattServer(g_gattSvcPath);
236     if (CA_STATUS_OK != ret )
237     {
238         OIC_LOG_V(ERROR, TAG, "CARegisterLEServicewithGattServer failed[%d]", ret);
239         oc_mutex_unlock(g_leServerStateMutex);
240         CATerminateLEGattServer();
241         return CA_STATUS_FAILED;
242     }
243
244     ret = CALEStartAdvertise();
245     if (CA_STATUS_OK != ret)
246     {
247         OIC_LOG_V(ERROR, TAG, "CALEStartAdvertise failed[%d]", ret);
248         oc_mutex_unlock(g_leServerStateMutex);
249         CATerminateLEGattServer();
250         return CA_STATUS_FAILED;
251     }
252
253     g_isLEGattServerStarted = true;
254
255     oc_mutex_unlock(g_leServerStateMutex);
256
257     OIC_LOG(DEBUG, TAG, "OUT");
258     return CA_STATUS_OK;
259 }
260
261 void CALENotificationCb(bool notify, bt_gatt_server_h server, bt_gatt_h gatt_handle,
262                         void *user_data)
263 {
264     OIC_LOG(DEBUG, TAG, "IN");
265     if(notify)
266     {
267         OIC_LOG(DEBUG, TAG, "Notification is subscribed by the client");
268     }
269     OIC_LOG(DEBUG, TAG, "OUT");
270 }
271
272 CAResult_t CALEStartAdvertise()
273 {
274     OIC_LOG(DEBUG, TAG, "IN");
275
276     CAResult_t res = CALEStartAdvertiseImpl(CA_GATT_SERVICE_UUID);
277     if (CA_STATUS_OK != res)
278     {
279         OIC_LOG_V(ERROR, TAG, "CALEStartAdvertiseImpl failed[%d]", res);
280     }
281
282     OIC_LOG(DEBUG, TAG, "OUT");
283     return res;
284 }
285
286 CAResult_t CALEStartAdvertiseImpl(const char *serviceUUID)
287 {
288     OIC_LOG(DEBUG, TAG, "IN");
289
290     int res = bt_adapter_le_create_advertiser(&g_hAdvertiser);
291     if (NULL == g_hAdvertiser || BT_ERROR_NONE != res)
292     {
293         OIC_LOG_V(ERROR, TAG, "g_hAdvertiser is NULL/ Result is %d", res);
294         return CA_STATUS_FAILED;
295     }
296
297     res = bt_adapter_le_add_advertising_service_uuid(g_hAdvertiser,
298                                                      BT_ADAPTER_LE_PACKET_ADVERTISING,
299                                                      serviceUUID);
300     if (BT_ERROR_NONE != res)
301     {
302         OIC_LOG_V(ERROR, TAG, "bt_adapter_le_add_advertising_service_uuid failed with ret[%s]",
303                   CALEGetErrorMsg(res));
304         return CA_STATUS_FAILED;
305     }
306
307     res = bt_adapter_le_set_advertising_device_name(g_hAdvertiser,
308                                                     BT_ADAPTER_LE_PACKET_SCAN_RESPONSE, true);
309     if (BT_ERROR_NONE != res)
310     {
311         OIC_LOG_V(ERROR, TAG, "bt_adapter_le_set_advertising_device_name failed with ret[%s]",
312                   CALEGetErrorMsg(res));
313         return CA_STATUS_FAILED;
314     }
315
316     res = bt_adapter_le_start_advertising_new(g_hAdvertiser, NULL, NULL);
317     if (BT_ERROR_NONE != res)
318     {
319         OIC_LOG_V(ERROR, TAG, "bt_adapter_le_start_advertising_new failed with ret[%s]",
320                   CALEGetErrorMsg(res));
321         return CA_STATUS_FAILED;
322     }
323
324     OIC_LOG(DEBUG, TAG, "OUT");
325     return CA_STATUS_OK;
326 }
327
328 CAResult_t CALEStopAdvertise()
329 {
330     OIC_LOG(DEBUG, TAG, "IN");
331     if (NULL != g_hAdvertiser)
332     {
333         int ret  = bt_adapter_le_stop_advertising(g_hAdvertiser);
334         if (0 != ret)
335         {
336             OIC_LOG_V(ERROR, TAG,
337                       "bt_adapter_le_stop_advertising failed with ret[%s]", CALEGetErrorMsg(ret));
338         }
339
340         ret = bt_adapter_le_destroy_advertiser(g_hAdvertiser);
341         if (0 != ret)
342         {
343             OIC_LOG_V(ERROR, TAG,
344                       "bt_adapter_le_destroy_advertiser failed with ret[%s]", CALEGetErrorMsg(ret));
345         }
346         g_hAdvertiser = NULL;
347     }
348     else
349     {
350         OIC_LOG(ERROR, TAG, "Advertising is not running");
351         return CA_STATUS_FAILED;
352     }
353
354     OIC_LOG(DEBUG, TAG, "OUT");
355     return CA_STATUS_OK;
356 }
357
358 CAResult_t CAStopLEGattServer()
359 {
360     OIC_LOG(DEBUG, TAG, "IN");
361
362     oc_mutex_lock(g_leServerStateMutex);
363
364     if (false == g_isLEGattServerStarted)
365     {
366         OIC_LOG(ERROR, TAG, "Gatt Server is not running to stop");
367         oc_mutex_unlock(g_leServerStateMutex);
368         return CA_STATUS_OK;
369     }
370
371     g_isLEGattServerStarted = false;
372
373     oc_mutex_lock(g_LEClientListMutex);
374     CADisconnectAllClient(g_LEClientList);
375     g_LEClientList = NULL;
376     oc_mutex_unlock(g_LEClientListMutex);
377
378     CAResult_t res = CALEStopAdvertise();
379     {
380         OIC_LOG_V(ERROR, TAG, "CALEStopAdvertise failed with ret[%d]", res);
381     }
382
383     res = CADeInitLEGattServer();
384     if (CA_STATUS_OK != res)
385     {
386         OIC_LOG_V(ERROR, TAG, "CADeInitLEGattService failed with ret[%d]", res);
387     }
388
389     GMainContext  *context_event_loop = NULL;
390     // Required for waking up the thread which is running in gmain loop
391     if (NULL != g_eventLoop)
392     {
393         context_event_loop = g_main_loop_get_context(g_eventLoop);
394
395         if (context_event_loop)
396         {
397             OIC_LOG_V(DEBUG,  TAG, "g_eventLoop context %x", context_event_loop);
398             g_main_context_wakeup(context_event_loop);
399
400             // Kill g main loops and kill threads
401             g_main_loop_quit(g_eventLoop);
402         }
403         g_eventLoop = NULL;
404     }
405     else
406     {
407         OIC_LOG(ERROR, TAG, "g_eventLoop context is NULL");
408     }
409
410     oc_mutex_unlock(g_leServerStateMutex);
411
412     OIC_LOG(DEBUG, TAG, "OUT");
413     return CA_STATUS_OK;
414 }
415
416 CAResult_t CAInitializeLEGattServer()
417 {
418     OIC_LOG(DEBUG, TAG, "IN");
419
420     CAResult_t ret = CAInitGattServerMutexVariables();
421     if (CA_STATUS_OK != ret )
422     {
423         OIC_LOG(ERROR, TAG, "CAInitGattServerMutexVariables failed!");
424         CATerminateGattServerMutexVariables();
425         return CA_SERVER_NOT_STARTED;
426     }
427     OIC_LOG(DEBUG, TAG, "OUT");
428     return ret;
429 }
430
431 void CATerminateLEGattServer()
432 {
433     OIC_LOG(DEBUG, TAG, "IN");
434
435     // Service and characteristics path will be freed by the platform.
436     oc_mutex_lock(g_leServiceMutex);
437     g_gattSvcPath = NULL;
438     oc_mutex_unlock(g_leServiceMutex);
439
440     oc_mutex_lock(g_leCharacteristicMutex);
441     g_gattReadCharPath = NULL;
442     g_gattWriteCharPath = NULL;
443     oc_mutex_unlock(g_leCharacteristicMutex);
444
445     oc_mutex_lock(g_leServerThreadPoolMutex);
446     g_leServerThreadPool = NULL;
447     oc_mutex_unlock(g_leServerThreadPoolMutex);
448
449     // Terminating all mutex variables.
450     CATerminateGattServerMutexVariables();
451     OIC_LOG(DEBUG, TAG, "OUT");
452 }
453
454 CAResult_t CAInitGattServerMutexVariables()
455 {
456     OIC_LOG(DEBUG, TAG, "IN");
457     if (NULL == g_leServerStateMutex)
458     {
459         g_leServerStateMutex = oc_mutex_new();
460         if (NULL == g_leServerStateMutex)
461         {
462             OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
463             return CA_STATUS_FAILED;
464         }
465     }
466
467     if (NULL == g_leServiceMutex)
468     {
469         g_leServiceMutex = oc_mutex_new();
470         if (NULL == g_leServiceMutex)
471         {
472             OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
473             return CA_STATUS_FAILED;
474         }
475     }
476
477     if (NULL == g_leCharacteristicMutex)
478     {
479         g_leCharacteristicMutex = oc_mutex_new();
480         if (NULL == g_leCharacteristicMutex)
481         {
482             OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
483             return CA_STATUS_FAILED;
484         }
485     }
486
487     if (NULL == g_leReqRespCbMutex)
488     {
489         g_leReqRespCbMutex = oc_mutex_new();
490         if (NULL == g_leReqRespCbMutex)
491         {
492             OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
493             return CA_STATUS_FAILED;
494         }
495     }
496
497     if (NULL == g_leServerThreadPoolMutex)
498     {
499         g_leServerThreadPoolMutex = oc_mutex_new();
500         if (NULL == g_leServerThreadPoolMutex)
501         {
502             OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
503             return CA_STATUS_FAILED;
504         }
505     }
506
507     if (NULL == g_LEClientListMutex)
508     {
509         g_LEClientListMutex = oc_mutex_new();
510         if (NULL == g_LEClientListMutex)
511         {
512             OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
513             return CA_STATUS_FAILED;
514         }
515     }
516
517     OIC_LOG(DEBUG, TAG, "OUT");
518     return CA_STATUS_OK;
519 }
520
521 void CATerminateGattServerMutexVariables()
522 {
523     OIC_LOG(DEBUG, TAG, "IN");
524     oc_mutex_free(g_leServerStateMutex);
525     g_leServerStateMutex = NULL;
526
527     oc_mutex_free(g_leServiceMutex);
528     g_leServiceMutex = NULL;
529
530     oc_mutex_free(g_leCharacteristicMutex);
531     g_leCharacteristicMutex = NULL;
532
533     oc_mutex_free(g_leReqRespCbMutex);
534     g_leReqRespCbMutex = NULL;
535
536     oc_mutex_free(g_leServerThreadPoolMutex);
537     g_leServerThreadPoolMutex = NULL;
538
539     oc_mutex_free(g_LEClientListMutex);
540     g_LEClientListMutex = NULL;
541
542     OIC_LOG(DEBUG, TAG, "OUT");
543 }
544
545 CAResult_t CAInitLEGattServer()
546 {
547     OIC_LOG(DEBUG, TAG, "IN");
548
549     int ret =  bt_gatt_server_initialize();
550     if (0 != ret)
551     {
552         OIC_LOG_V(ERROR, TAG, "bt_gatt_server_initialize failed with ret[%s]",
553                   CALEGetErrorMsg(ret));
554         return CA_STATUS_FAILED;
555     }
556
557     if (!g_gattServer)
558     {
559         OIC_LOG(DEBUG, TAG, "g_gattServer is NULL. create gatt server..");
560         ret = bt_gatt_server_create(&g_gattServer);
561         if (0 != ret)
562         {
563             OIC_LOG_V(ERROR, TAG, "bt_gatt_server_create failed with ret[%s]",
564                       CALEGetErrorMsg(ret));
565             return CA_STATUS_FAILED;
566         }
567     }
568
569     OIC_LOG(DEBUG, TAG, "OUT");
570     return CA_STATUS_OK;
571 }
572
573 CAResult_t CADeInitLEGattServer()
574 {
575     OIC_LOG(DEBUG, TAG, "IN");
576
577     int ret = bt_gatt_server_unregister_all_services(g_gattServer);
578     if (0 != ret)
579     {
580         OIC_LOG_V(ERROR, TAG, "bt_gatt_server_unregister_all_services failed with ret[%s]",
581                   CALEGetErrorMsg(ret));
582         return CA_STATUS_FAILED;
583     }
584
585     ret = bt_gatt_server_destroy(g_gattServer);
586     if (0 != ret)
587     {
588         OIC_LOG_V(ERROR, TAG, "bt_gatt_server_destroy failed with ret[%s]",
589                   CALEGetErrorMsg(ret));
590         return CA_STATUS_FAILED;
591     }
592     g_gattServer = NULL;
593
594     ret =  bt_gatt_server_deinitialize();
595     if (0 != ret)
596     {
597         OIC_LOG_V(ERROR, TAG, "bt_gatt_server_deinitialize failed with ret[%s]",
598                   CALEGetErrorMsg(ret));
599         return CA_STATUS_FAILED;
600     }
601
602     OIC_LOG(DEBUG, TAG, "OUT");
603     return CA_STATUS_OK;
604 }
605
606 void CASetLEServerThreadPoolHandle(ca_thread_pool_t handle)
607 {
608     OIC_LOG(DEBUG, TAG, "IN");
609     oc_mutex_lock(g_leServerThreadPoolMutex);
610     g_leServerThreadPool = handle;
611     oc_mutex_unlock(g_leServerThreadPoolMutex);
612     OIC_LOG(DEBUG, TAG, "OUT");
613 }
614
615 CAResult_t CAAddNewLEServiceInGattServer(const char *serviceUUID)
616 {
617     OIC_LOG(DEBUG, TAG, "IN");
618
619     VERIFY_NON_NULL(serviceUUID, TAG, "serviceUUID");
620
621     OIC_LOG_V(DEBUG, TAG, "service uuid %s", serviceUUID);
622
623     bt_gatt_service_type_e type = BT_GATT_SERVICE_TYPE_PRIMARY;
624
625     oc_mutex_lock(g_leServiceMutex);
626     int ret = bt_gatt_service_create(serviceUUID, type, &g_gattSvcPath);
627     if (0 != ret)
628     {
629         oc_mutex_unlock(g_leServiceMutex);
630         OIC_LOG_V(ERROR, TAG, "bt_gatt_service_create failed with ret [%s]",
631                     CALEGetErrorMsg(ret));
632         return CA_STATUS_FAILED;
633     }
634     oc_mutex_unlock(g_leServiceMutex);
635
636     if (g_gattSvcPath)
637     {
638         OIC_LOG_V(DEBUG, TAG, "ServicePath obtained is %s", (char *)g_gattSvcPath);
639     }
640
641     OIC_LOG(DEBUG, TAG, "OUT");
642     return CA_STATUS_OK;
643 }
644
645 void CALEGattRemoteCharacteristicWriteCb(char *remoteAddress, bt_gatt_server_h server,
646                                          bt_gatt_h charPath, int offset, char *charValue,
647                                          int charValueLen, void *userData)
648 {
649     OIC_LOG(DEBUG, TAG, "IN");
650
651     if (NULL == charValue || NULL == remoteAddress)
652     {
653         OIC_LOG(ERROR, TAG, "Param callback values are NULL");
654         return;
655     }
656
657     OIC_LOG_V(DEBUG, TAG, "charPath = [%s] charValue = [%s] len [%d]", (char *)charPath,
658               charValue, charValueLen);
659
660     uint8_t *data = OICMalloc(charValueLen);
661     if (NULL == data)
662     {
663         OIC_LOG(ERROR, TAG, "Malloc failed!");
664         return;
665     }
666
667     memcpy(data, charValue, charValueLen);
668
669     oc_mutex_lock(g_leReqRespCbMutex);
670     if (NULL == g_leServerDataReceivedCallback)
671     {
672         OIC_LOG(ERROR, TAG, "gReqRespCallback is NULL!");
673         oc_mutex_unlock(g_leReqRespCbMutex);
674         OICFree(data);
675         return;
676     }
677
678     OIC_LOG(DEBUG, TAG, "Sending data up !");
679     uint32_t sentLength = 0;
680     g_leServerDataReceivedCallback(remoteAddress, data, charValueLen,
681                                     &sentLength);
682     oc_mutex_unlock(g_leReqRespCbMutex);
683     OICFree(data);
684     OIC_LOG(DEBUG, TAG, "OUT");
685 }
686
687 CAResult_t CARegisterLEServicewithGattServer(const bt_gatt_h svcPath)
688 {
689     OIC_LOG(DEBUG, TAG, "IN");
690
691     VERIFY_NON_NULL(svcPath, TAG, "svcPath");
692
693     OIC_LOG_V(DEBUG, TAG, "svcPath:%s", svcPath);
694
695     int ret = bt_gatt_server_register_service(g_gattServer, svcPath);
696     if (0 != ret)
697     {
698         OIC_LOG_V(ERROR, TAG, "bt_gatt_server_register_service failed with ret[%s]",
699                   CALEGetErrorMsg(ret));
700         return CA_STATUS_FAILED;
701     }
702
703     ret = bt_gatt_server_set_value_changed_cb(g_gattWriteCharPath,
704                                               CALEGattRemoteCharacteristicWriteCb, NULL);
705
706     if (0 != ret)
707     {
708         OIC_LOG_V(ERROR, TAG, "bt_gatt_server_set_value_changed_cb failed with ret[%s]",
709                   CALEGetErrorMsg(ret));
710         return CA_STATUS_FAILED;
711     }
712
713     OIC_LOG(DEBUG, TAG, "OUT");
714     return CA_STATUS_OK;
715 }
716
717 CAResult_t CAAddNewCharacteristicsToGattServer(const bt_gatt_h svcPath, const char *charUUID,
718                                                const char *charValue, int charValueLen, bool read)
719 {
720
721     OIC_LOG(DEBUG, TAG, "IN");
722
723     int permissions = BT_GATT_PERMISSION_READ | BT_GATT_PERMISSION_WRITE;
724     int properties;
725     if (read)
726     {
727         properties = BT_GATT_PROPERTY_INDICATE | BT_GATT_PROPERTY_READ;
728     }
729     else
730     {
731         properties = BT_GATT_PROPERTY_WRITE | BT_GATT_PROPERTY_READ;
732     }
733
734     bt_gatt_h charPath = NULL;
735
736     int ret = bt_gatt_characteristic_create(charUUID, permissions, properties, charValue,
737                                             charValueLen, &charPath);
738
739     if (0 != ret || NULL == charPath)
740     {
741         OIC_LOG_V(ERROR, TAG,
742                   "bt_gatt_add_characteristic  failed with ret [%s]", CALEGetErrorMsg(ret));
743         return CA_STATUS_FAILED;
744     }
745
746     OIC_LOG_V(DEBUG, TAG,
747               "bt_gatt_characteristic_create charPath obtained: %s", (char *)charPath);
748
749     if (read)
750     {
751         ret = bt_gatt_server_set_notification_state_change_cb(charPath, CALENotificationCb, NULL);
752         if (0 != ret)
753         {
754             OIC_LOG_V(ERROR, TAG,
755                       "bt_gatt_server_set_notification_state_change_cb  failed with ret[%s]",
756                       CALEGetErrorMsg(ret));
757             return CA_STATUS_FAILED;
758         }
759     }
760
761     ret =  bt_gatt_service_add_characteristic(svcPath, charPath);
762     if (0 != ret)
763     {
764         OIC_LOG_V(ERROR, TAG,
765                   "bt_gatt_service_add_characteristic  failed with ret[%s]",
766                   CALEGetErrorMsg(ret));
767         return CA_STATUS_FAILED;
768     }
769
770     oc_mutex_lock(g_leCharacteristicMutex);
771
772     if (read)
773     {
774         char desc_value[2] = {1, 0};  // Notification enabled.
775         bt_gatt_h descriptor = NULL;
776         permissions = BT_GATT_PERMISSION_READ | BT_GATT_PERMISSION_WRITE;
777         ret = bt_gatt_descriptor_create(CA_GATT_CONFIGURATION_DESC_UUID, permissions,
778                                         desc_value, sizeof(desc_value),
779                                         &descriptor);
780         if (0 != ret)
781         {
782             oc_mutex_unlock(g_leCharacteristicMutex);
783             OIC_LOG_V(ERROR, TAG,
784                       "bt_gatt_descriptor_create  failed with ret[%s]",
785                       CALEGetErrorMsg(ret));
786             return CA_STATUS_FAILED;
787         }
788
789         ret = bt_gatt_characteristic_add_descriptor(charPath, descriptor);
790         if (0 != ret)
791         {
792             oc_mutex_unlock(g_leCharacteristicMutex);
793             OIC_LOG_V(ERROR, TAG,
794                       "bt_gatt_characteristic_add_descriptor  failed with ret[%s]",
795                       CALEGetErrorMsg(ret));
796             return CA_STATUS_FAILED;
797         }
798
799         g_gattReadCharPath = charPath;
800     }
801     else
802     {
803         g_gattWriteCharPath = charPath;
804     }
805
806     oc_mutex_unlock(g_leCharacteristicMutex);
807
808     OIC_LOG(DEBUG, TAG, "OUT");
809     return CA_STATUS_OK;
810 }
811
812 CAResult_t CAUpdateCharacteristicsToGattClient(const char *address, const uint8_t *charValue,
813                                                uint32_t charValueLen)
814 {
815     OIC_LOG(DEBUG, TAG, "IN");
816
817     VERIFY_NON_NULL(charValue, TAG, "charValue");
818     VERIFY_NON_NULL(address, TAG, "address");
819
820     OIC_LOG_V(DEBUG, TAG, "Client's Unicast address for sending data [%s]", address);
821
822     oc_mutex_lock(g_leCharacteristicMutex);
823
824     if (NULL  == g_gattReadCharPath)
825     {
826         OIC_LOG(ERROR, TAG, "g_gattReadCharPath is NULL");
827         oc_mutex_unlock(g_leCharacteristicMutex);
828         return CA_STATUS_FAILED;
829     }
830
831     int ret = bt_gatt_set_value(g_gattReadCharPath, (char *)charValue, charValueLen);
832     if (0 != ret)
833     {
834         OIC_LOG_V(ERROR, TAG,
835                   "bt_gatt_set_value failed with return [%s]", CALEGetErrorMsg(ret));
836         oc_mutex_unlock(g_leCharacteristicMutex);
837         return CA_STATUS_FAILED;
838     }
839
840     ret = bt_gatt_server_notify(g_gattReadCharPath, false, CALEServerNotificationSentCB,
841                                 NULL);
842     if (0 != ret)
843     {
844         OIC_LOG_V(ERROR, TAG,
845                   "bt_gatt_server_notify failed with return [%s]", CALEGetErrorMsg(ret));
846         oc_mutex_unlock(g_leCharacteristicMutex);
847         return CA_STATUS_FAILED;
848     }
849
850     oc_mutex_unlock(g_leCharacteristicMutex);
851
852     OIC_LOG(DEBUG, TAG, "OUT");
853     return CA_STATUS_OK;
854 }
855
856 CAResult_t CAUpdateCharacteristicsToAllGattClients(const uint8_t *charValue, uint32_t charValueLen)
857 {
858     OIC_LOG(DEBUG, TAG, "IN");
859
860     VERIFY_NON_NULL(charValue, TAG, "charValue");
861
862     oc_mutex_lock(g_leCharacteristicMutex);
863
864     if (NULL  == g_gattReadCharPath)
865     {
866         OIC_LOG(ERROR, TAG, "g_gattReadCharPath is NULL");
867         oc_mutex_unlock(g_leCharacteristicMutex);
868         return CA_STATUS_FAILED;
869     }
870
871     int ret = bt_gatt_set_value(g_gattReadCharPath, (char *)charValue, charValueLen);
872     if (0 != ret)
873     {
874         OIC_LOG_V(ERROR, TAG, "bt_gatt_set_value failed with return[%s]", CALEGetErrorMsg(ret));
875         oc_mutex_unlock(g_leCharacteristicMutex);
876         return CA_STATUS_FAILED;
877     }
878
879     ret = bt_gatt_server_notify(g_gattReadCharPath, false, CALEServerNotificationSentCB,
880                                 NULL);
881     if (0 != ret)
882     {
883         OIC_LOG_V(ERROR, TAG,
884                   "bt_gatt_server_notify failed with return[%s]", CALEGetErrorMsg(ret));
885         oc_mutex_unlock(g_leCharacteristicMutex);
886         return CA_STATUS_FAILED;
887     }
888
889     oc_mutex_unlock(g_leCharacteristicMutex);
890
891     OIC_LOG(DEBUG, TAG, "OUT");
892     return CA_STATUS_OK;
893 }
894
895 void CASetLEReqRespServerCallback(CABLEDataReceivedCallback callback)
896 {
897     OIC_LOG(DEBUG, TAG, "IN");
898
899     oc_mutex_lock(g_leReqRespCbMutex);
900     g_leServerDataReceivedCallback = callback;
901     oc_mutex_unlock(g_leReqRespCbMutex);
902
903     OIC_LOG(DEBUG, TAG, "OUT");
904 }
905
906 void CASetBLEServerErrorHandleCallback(CABLEErrorHandleCallback callback)
907 {
908     g_serverErrorCallback = callback;
909 }
910
911 bool CALEServerIsConnected(const char* address)
912 {
913     //@Todo
914     return true;
915 }
916
917 uint16_t CALEServerGetMtuSize(const char* address)
918 {
919     OIC_LOG(DEBUG, TAG, "IN");
920     VERIFY_NON_NULL_RET(address, TAG, "address is null", CA_DEFAULT_BLE_MTU_SIZE);
921
922     unsigned int mtu = CA_DEFAULT_BLE_MTU_SIZE + CA_BLE_MTU_HEADER_SIZE;
923     int ret = bt_device_get_att_mtu(address, &mtu);
924     if (0 != ret)
925     {
926         OIC_LOG_V(ERROR, TAG,
927                   "bt_device_get_att_mtu failed with return [%s]", CALEGetErrorMsg(ret));
928         return CA_DEFAULT_BLE_MTU_SIZE;
929     }
930     OIC_LOG_V(INFO, TAG, "mtu size(including header) from bt_device_get_att_mtu is %d", mtu);
931     OIC_LOG(DEBUG, TAG, "OUT");
932     return mtu - CA_BLE_MTU_HEADER_SIZE;
933 }
934