Changing logic of fetching MTU size in server 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 #include <glib.h>
31
32 /**
33  * Logging tag for module name
34  */
35 #define TAG "OIC_CA_LE_SERVER"
36
37 /**
38  * The handle of the OIC server.
39  */
40 static bt_gatt_server_h g_gattServer = NULL;
41
42 /**
43  * The handle of the OIC service.
44  */
45 static bt_gatt_h g_gattSvcPath = NULL;
46
47 /**
48  * The handle of the OIC read characteristics.
49  */
50 static bt_gatt_h g_gattReadCharPath = NULL;
51
52 /**
53  * The handle of the OIC write characteristics.
54  */
55 static bt_gatt_h g_gattWriteCharPath = NULL;
56
57 /**
58  * The handle to control Bluetooth LE advertising.
59  */
60 static bt_advertiser_h g_hAdvertiser = NULL;
61
62 /**
63  * Callback register with LE adapter.  This callback is called on reception of any
64  * data from the remote device.
65  */
66 static CABLEDataReceivedCallback g_leServerDataReceivedCallback = NULL;
67
68 /**
69  * Callback to notify any error in LE adapter.
70  */
71 static CABLEErrorHandleCallback g_serverErrorCallback = NULL;
72
73 /**
74  * To keep the state of GATT server if started or not.
75  */
76 static bool g_isLEGattServerStarted = false;
77
78 /**
79  * Mutex to synchronize the calls to start and stop server.
80  */
81 static oc_mutex g_leServerStateMutex = NULL;
82
83 /**
84  * Mutex to synchronize writing operations on the characteristics.
85  */
86 static  oc_mutex g_leCharacteristicMutex = NULL;
87
88 /**
89  * Mutex to synchronize to creation of OIC service.
90  */
91 static  oc_mutex g_leServiceMutex = NULL;
92
93 /**
94  * Mutex to synchronize access to the requestResponse callback to be called
95  * when the data needs to be sent from GATTClient.
96  */
97 static  oc_mutex g_leReqRespCbMutex = NULL;
98
99 /**
100  * Mutex to synchronize the task to be pushed to thread pool.
101  */
102 static oc_mutex g_leServerThreadPoolMutex = NULL;
103
104 /**
105  * Reference to threadpool.
106  */
107 static ca_thread_pool_t g_leServerThreadPool = NULL;
108
109 /**
110  * GmainLoop to manage the threads to receive the callback from the platfrom.
111  */
112 static GMainLoop *g_eventLoop = NULL;
113
114 /**
115  * This contains the list of OIC clients connected to the server.
116  */
117 static LEClientInfoList *g_LEClientList = NULL;
118
119 /**
120  * Mutex to synchronize access to LE ClientList.
121  */
122 static oc_mutex g_LEClientListMutex = NULL;
123
124 void CALEGattServerConnectionStateChanged(bool connected, const char *remoteAddress)
125 {
126     VERIFY_NON_NULL_VOID(remoteAddress, TAG, "remote address");
127
128     CAResult_t res = CA_STATUS_OK;
129     if (connected)
130     {
131         OIC_LOG_V(DEBUG, TAG, "Connected to [%s]", remoteAddress);
132         char *addr = OICStrdup(remoteAddress);
133         oc_mutex_lock(g_LEClientListMutex);
134         res  = CAAddLEClientInfoToList(&g_LEClientList, addr);
135         if (CA_STATUS_OK != res)
136         {
137             OIC_LOG(ERROR, TAG, "CAAddLEClientInfoToList failed");
138             oc_mutex_unlock(g_LEClientListMutex);
139             OICFree(addr);
140             return;
141         }
142         oc_mutex_unlock(g_LEClientListMutex);
143
144         res = CALEStopAdvertise();
145         if (CA_STATUS_OK != res)
146         {
147             OIC_LOG_V(ERROR, TAG, "Failed to stop advertising [%d]", res);
148             return;
149         }
150     }
151     else
152     {
153         OIC_LOG_V(DEBUG, TAG, "Disconnected from [%s]", remoteAddress);
154         oc_mutex_lock(g_LEClientListMutex);
155         CARemoveLEClientInfoFromList(&g_LEClientList, remoteAddress);
156         oc_mutex_unlock(g_LEClientListMutex);
157
158         res = CALEStartAdvertise();
159         if (CA_STATUS_OK != res)
160         {
161             OIC_LOG_V(ERROR, TAG, "Failed to start advertising [%d]", res);
162             return;
163         }
164     }
165 }
166
167 void CALEServerNotificationSentCB(int result, const char *remote_address, bt_gatt_server_h server,
168                                   bt_gatt_h characteristic, bool completed, void *user_data)
169 {
170     OIC_LOG_V(DEBUG, TAG, "Notification to the device[%s] result[%d]", remote_address, result);
171 }
172
173 CAResult_t CAStartLEGattServer()
174 {
175     OIC_LOG(DEBUG, TAG, "IN");
176
177     oc_mutex_lock(g_leServerStateMutex);
178     if (true == g_isLEGattServerStarted)
179     {
180         OIC_LOG(ERROR, TAG, "Gatt Server is already running");
181         oc_mutex_unlock(g_leServerStateMutex);
182         return CA_STATUS_OK;
183     }
184
185     CAResult_t ret = CAInitLEGattServer();
186     if (CA_STATUS_OK != ret)
187     {
188         OIC_LOG_V(ERROR, TAG, "CAInitLEGattServer failed[%d]", ret);
189         oc_mutex_unlock(g_leServerStateMutex);
190         CATerminateLEGattServer();
191         return CA_STATUS_FAILED;
192     }
193
194     ret  = CAAddNewLEServiceInGattServer(CA_GATT_SERVICE_UUID);
195     if (CA_STATUS_OK != ret)
196     {
197         OIC_LOG_V(ERROR, TAG, "CAAddNewLEServiceInGattServer failed[%d]", ret);
198         oc_mutex_unlock(g_leServerStateMutex);
199         CATerminateLEGattServer();
200         return CA_STATUS_FAILED;
201     }
202
203     static const char charReadUUID[] = CA_GATT_RESPONSE_CHRC_UUID;
204     char charReadValue[] = {33, 44, 55, 66}; // These are initial random values
205
206     // For Read Characteristics.
207     ret = CAAddNewCharacteristicsToGattServer(g_gattSvcPath, charReadUUID, charReadValue,
208                                               sizeof(charReadValue), true);
209     if (CA_STATUS_OK != ret)
210     {
211         OIC_LOG_V(ERROR, TAG, "CAAddNewCharacteristicsToGattServer failed[%d]", ret);
212         oc_mutex_unlock(g_leServerStateMutex);
213         CATerminateLEGattServer();
214         return CA_STATUS_FAILED;
215     }
216
217     static const char charWriteUUID[] = CA_GATT_REQUEST_CHRC_UUID;
218     char charWriteValue[] = {33, 44, 55, 66}; // These are initial random values
219
220
221     ret = CAAddNewCharacteristicsToGattServer(g_gattSvcPath, charWriteUUID, charWriteValue,
222             sizeof(charWriteValue), false); // For Write Characteristics.
223     if (CA_STATUS_OK != ret )
224     {
225         OIC_LOG_V(ERROR, TAG, "CAAddNewCharacteristicsToGattServer failed[%d]", ret);
226         oc_mutex_unlock(g_leServerStateMutex);
227         CATerminateLEGattServer();
228         return CA_STATUS_FAILED;
229     }
230
231     ret = CARegisterLEServicewithGattServer(g_gattSvcPath);
232     if (CA_STATUS_OK != ret )
233     {
234         OIC_LOG_V(ERROR, TAG, "CARegisterLEServicewithGattServer failed[%d]", ret);
235         oc_mutex_unlock(g_leServerStateMutex);
236         CATerminateLEGattServer();
237         return CA_STATUS_FAILED;
238     }
239
240     ret = CALEStartAdvertise();
241     if (CA_STATUS_OK != ret)
242     {
243         OIC_LOG_V(ERROR, TAG, "CALEStartAdvertise failed[%d]", ret);
244         oc_mutex_unlock(g_leServerStateMutex);
245         CATerminateLEGattServer();
246         return CA_STATUS_FAILED;
247     }
248
249     g_isLEGattServerStarted = true;
250
251     oc_mutex_unlock(g_leServerStateMutex);
252
253     OIC_LOG(DEBUG, TAG, "OUT");
254     return CA_STATUS_OK;
255 }
256
257 void CALENotificationCb(bool notify, bt_gatt_server_h server, bt_gatt_h gatt_handle,
258                         void *user_data)
259 {
260     OIC_LOG(DEBUG, TAG, "IN");
261     if (notify)
262     {
263         OIC_LOG(DEBUG, TAG, "Notification is subscribed by the client");
264         CALogSendStateInfo(CA_ADAPTER_GATT_BTLE, "", 0, -1,
265                            true, "notifyChar success");
266     }
267     else
268     {
269         CALogSendStateInfo(CA_ADAPTER_GATT_BTLE, "", 0, -1,
270                            false, "notifyChar failure");
271     }
272     OIC_LOG(DEBUG, TAG, "OUT");
273 }
274
275 CAResult_t CALEStartAdvertise()
276 {
277     OIC_LOG(DEBUG, TAG, "IN");
278
279     CAResult_t res = CALEStartAdvertiseImpl(CA_GATT_SERVICE_UUID);
280     if (CA_STATUS_OK != res)
281     {
282         OIC_LOG_V(ERROR, TAG, "CALEStartAdvertiseImpl failed[%d]", res);
283     }
284
285     OIC_LOG(DEBUG, TAG, "OUT");
286     return res;
287 }
288
289 CAResult_t CALEStartAdvertiseImpl(const char *serviceUUID)
290 {
291     OIC_LOG(DEBUG, TAG, "IN");
292
293     int res = bt_adapter_le_create_advertiser(&g_hAdvertiser);
294     if (NULL == g_hAdvertiser || BT_ERROR_NONE != res)
295     {
296         OIC_LOG_V(ERROR, TAG, "g_hAdvertiser is NULL/ Result is %d", res);
297         return CA_STATUS_FAILED;
298     }
299
300     res = bt_adapter_le_add_advertising_service_uuid(g_hAdvertiser,
301                                                      BT_ADAPTER_LE_PACKET_ADVERTISING,
302                                                      serviceUUID);
303     if (BT_ERROR_NONE != res)
304     {
305         OIC_LOG_V(ERROR, TAG, "bt_adapter_le_add_advertising_service_uuid failed with ret[%s]",
306                   CALEGetErrorMsg(res));
307         return CA_STATUS_FAILED;
308     }
309
310     res = bt_adapter_le_set_advertising_device_name(g_hAdvertiser,
311                                                     BT_ADAPTER_LE_PACKET_SCAN_RESPONSE, true);
312     if (BT_ERROR_NONE != res)
313     {
314         OIC_LOG_V(ERROR, TAG, "bt_adapter_le_set_advertising_device_name failed with ret[%s]",
315                   CALEGetErrorMsg(res));
316         return CA_STATUS_FAILED;
317     }
318
319     res = bt_adapter_le_start_advertising_new(g_hAdvertiser, NULL, NULL);
320     if (BT_ERROR_NONE != res)
321     {
322         OIC_LOG_V(ERROR, TAG, "bt_adapter_le_start_advertising_new failed with ret[%s]",
323                   CALEGetErrorMsg(res));
324         return CA_STATUS_FAILED;
325     }
326
327     OIC_LOG(DEBUG, TAG, "OUT");
328     return CA_STATUS_OK;
329 }
330
331 CAResult_t CALEStopAdvertise()
332 {
333     OIC_LOG(DEBUG, TAG, "IN");
334     if (NULL != g_hAdvertiser)
335     {
336         int ret  = bt_adapter_le_stop_advertising(g_hAdvertiser);
337         if (0 != ret)
338         {
339             OIC_LOG_V(ERROR, TAG,
340                       "bt_adapter_le_stop_advertising failed with ret[%s]", CALEGetErrorMsg(ret));
341         }
342
343         ret = bt_adapter_le_destroy_advertiser(g_hAdvertiser);
344         if (0 != ret)
345         {
346             OIC_LOG_V(ERROR, TAG,
347                       "bt_adapter_le_destroy_advertiser failed with ret[%s]", CALEGetErrorMsg(ret));
348         }
349         g_hAdvertiser = NULL;
350     }
351     else
352     {
353         OIC_LOG(ERROR, TAG, "Advertising is not running");
354         return CA_STATUS_FAILED;
355     }
356
357     OIC_LOG(DEBUG, TAG, "OUT");
358     return CA_STATUS_OK;
359 }
360
361 CAResult_t CAStopLEGattServer()
362 {
363     OIC_LOG(DEBUG, TAG, "IN");
364
365     oc_mutex_lock(g_leServerStateMutex);
366
367     if (false == g_isLEGattServerStarted)
368     {
369         OIC_LOG(ERROR, TAG, "Gatt Server is not running to stop");
370         oc_mutex_unlock(g_leServerStateMutex);
371         return CA_STATUS_OK;
372     }
373
374     g_isLEGattServerStarted = false;
375
376     oc_mutex_lock(g_LEClientListMutex);
377     CADisconnectAllClient(g_LEClientList);
378     g_LEClientList = NULL;
379     oc_mutex_unlock(g_LEClientListMutex);
380
381     CAResult_t res = CALEStopAdvertise();
382     {
383         OIC_LOG_V(ERROR, TAG, "CALEStopAdvertise failed with ret[%d]", res);
384     }
385
386     res = CADeInitLEGattServer();
387     if (CA_STATUS_OK != res)
388     {
389         OIC_LOG_V(ERROR, TAG, "CADeInitLEGattService failed with ret[%d]", res);
390     }
391
392     GMainContext  *context_event_loop = NULL;
393     // Required for waking up the thread which is running in gmain loop
394     if (NULL != g_eventLoop)
395     {
396         context_event_loop = g_main_loop_get_context(g_eventLoop);
397
398         if (context_event_loop)
399         {
400             OIC_LOG_V(DEBUG,  TAG, "g_eventLoop context %x", context_event_loop);
401             g_main_context_wakeup(context_event_loop);
402
403             // Kill g main loops and kill threads
404             g_main_loop_quit(g_eventLoop);
405         }
406         g_eventLoop = NULL;
407     }
408     else
409     {
410         OIC_LOG(ERROR, TAG, "g_eventLoop context is NULL");
411     }
412
413     oc_mutex_unlock(g_leServerStateMutex);
414
415     OIC_LOG(DEBUG, TAG, "OUT");
416     return CA_STATUS_OK;
417 }
418
419 CAResult_t CAInitializeLEGattServer()
420 {
421     OIC_LOG(DEBUG, TAG, "IN");
422
423     CAResult_t ret = CAInitGattServerMutexVariables();
424     if (CA_STATUS_OK != ret )
425     {
426         OIC_LOG(ERROR, TAG, "CAInitGattServerMutexVariables failed!");
427         CATerminateGattServerMutexVariables();
428         return CA_SERVER_NOT_STARTED;
429     }
430     OIC_LOG(DEBUG, TAG, "OUT");
431     return ret;
432 }
433
434 void CATerminateLEGattServer()
435 {
436     OIC_LOG(DEBUG, TAG, "IN");
437
438     // Service and characteristics path will be freed by the platform.
439     oc_mutex_lock(g_leServiceMutex);
440     g_gattSvcPath = NULL;
441     oc_mutex_unlock(g_leServiceMutex);
442
443     oc_mutex_lock(g_leCharacteristicMutex);
444     g_gattReadCharPath = NULL;
445     g_gattWriteCharPath = NULL;
446     oc_mutex_unlock(g_leCharacteristicMutex);
447
448     oc_mutex_lock(g_leServerThreadPoolMutex);
449     g_leServerThreadPool = NULL;
450     oc_mutex_unlock(g_leServerThreadPoolMutex);
451
452     // Terminating all mutex variables.
453     CATerminateGattServerMutexVariables();
454     OIC_LOG(DEBUG, TAG, "OUT");
455 }
456
457 CAResult_t CAInitGattServerMutexVariables()
458 {
459     OIC_LOG(DEBUG, TAG, "IN");
460     if (NULL == g_leServerStateMutex)
461     {
462         g_leServerStateMutex = oc_mutex_new();
463         if (NULL == g_leServerStateMutex)
464         {
465             OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
466             return CA_STATUS_FAILED;
467         }
468     }
469
470     if (NULL == g_leServiceMutex)
471     {
472         g_leServiceMutex = oc_mutex_new();
473         if (NULL == g_leServiceMutex)
474         {
475             OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
476             return CA_STATUS_FAILED;
477         }
478     }
479
480     if (NULL == g_leCharacteristicMutex)
481     {
482         g_leCharacteristicMutex = oc_mutex_new();
483         if (NULL == g_leCharacteristicMutex)
484         {
485             OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
486             return CA_STATUS_FAILED;
487         }
488     }
489
490     if (NULL == g_leReqRespCbMutex)
491     {
492         g_leReqRespCbMutex = oc_mutex_new();
493         if (NULL == g_leReqRespCbMutex)
494         {
495             OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
496             return CA_STATUS_FAILED;
497         }
498     }
499
500     if (NULL == g_leServerThreadPoolMutex)
501     {
502         g_leServerThreadPoolMutex = oc_mutex_new();
503         if (NULL == g_leServerThreadPoolMutex)
504         {
505             OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
506             return CA_STATUS_FAILED;
507         }
508     }
509
510     if (NULL == g_LEClientListMutex)
511     {
512         g_LEClientListMutex = oc_mutex_new();
513         if (NULL == g_LEClientListMutex)
514         {
515             OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
516             return CA_STATUS_FAILED;
517         }
518     }
519
520     OIC_LOG(DEBUG, TAG, "OUT");
521     return CA_STATUS_OK;
522 }
523
524 void CATerminateGattServerMutexVariables()
525 {
526     OIC_LOG(DEBUG, TAG, "IN");
527     oc_mutex_free(g_leServerStateMutex);
528     g_leServerStateMutex = NULL;
529
530     oc_mutex_free(g_leServiceMutex);
531     g_leServiceMutex = NULL;
532
533     oc_mutex_free(g_leCharacteristicMutex);
534     g_leCharacteristicMutex = NULL;
535
536     oc_mutex_free(g_leReqRespCbMutex);
537     g_leReqRespCbMutex = NULL;
538
539     oc_mutex_free(g_leServerThreadPoolMutex);
540     g_leServerThreadPoolMutex = NULL;
541
542     oc_mutex_free(g_LEClientListMutex);
543     g_LEClientListMutex = NULL;
544
545     OIC_LOG(DEBUG, TAG, "OUT");
546 }
547
548 CAResult_t CAInitLEGattServer()
549 {
550     OIC_LOG(DEBUG, TAG, "IN");
551
552     int ret =  bt_gatt_server_initialize();
553     if (0 != ret)
554     {
555         OIC_LOG_V(ERROR, TAG, "bt_gatt_server_initialize failed with ret[%s]",
556                   CALEGetErrorMsg(ret));
557         return CA_STATUS_FAILED;
558     }
559
560     if (!g_gattServer)
561     {
562         OIC_LOG(DEBUG, TAG, "g_gattServer is NULL. create gatt server..");
563         ret = bt_gatt_server_create(&g_gattServer);
564         if (0 != ret)
565         {
566             OIC_LOG_V(ERROR, TAG, "bt_gatt_server_create failed with ret[%s]",
567                       CALEGetErrorMsg(ret));
568             bt_gatt_server_deinitialize();
569             return CA_STATUS_FAILED;
570         }
571     }
572
573     OIC_LOG(DEBUG, TAG, "OUT");
574     return CA_STATUS_OK;
575 }
576
577 CAResult_t CADeInitLEGattServer()
578 {
579     OIC_LOG(DEBUG, TAG, "IN");
580
581     int ret = bt_gatt_server_unregister_all_services(g_gattServer);
582     if (0 != ret)
583     {
584         OIC_LOG_V(ERROR, TAG, "bt_gatt_server_unregister_all_services failed with ret[%s]",
585                   CALEGetErrorMsg(ret));
586         // CONPRO-1181 continue even bt API fails during DeInit
587         //return CA_STATUS_FAILED;
588     }
589
590     ret = bt_gatt_server_destroy(g_gattServer);
591     if (0 != ret)
592     {
593         OIC_LOG_V(ERROR, TAG, "bt_gatt_server_destroy failed with ret[%s]",
594                   CALEGetErrorMsg(ret));
595         // CONPRO-1181 continue even bt API fails during DeInit
596         //return CA_STATUS_FAILED;
597     }
598     g_gattServer = NULL;
599
600     ret =  bt_gatt_server_deinitialize();
601     if (0 != ret)
602     {
603         OIC_LOG_V(ERROR, TAG, "bt_gatt_server_deinitialize failed with ret[%s]",
604                   CALEGetErrorMsg(ret));
605         // CONPRO-1181 continue even bt API fails during DeInit
606         //return CA_STATUS_FAILED;
607     }
608
609     OIC_LOG(DEBUG, TAG, "OUT");
610     return CA_STATUS_OK;
611 }
612
613 void CASetLEServerThreadPoolHandle(ca_thread_pool_t handle)
614 {
615     OIC_LOG(DEBUG, TAG, "IN");
616     oc_mutex_lock(g_leServerThreadPoolMutex);
617     g_leServerThreadPool = handle;
618     oc_mutex_unlock(g_leServerThreadPoolMutex);
619     OIC_LOG(DEBUG, TAG, "OUT");
620 }
621
622 CAResult_t CAAddNewLEServiceInGattServer(const char *serviceUUID)
623 {
624     OIC_LOG(DEBUG, TAG, "IN");
625
626     VERIFY_NON_NULL(serviceUUID, TAG, "serviceUUID");
627
628     OIC_LOG_V(DEBUG, TAG, "service uuid %s", serviceUUID);
629
630     bt_gatt_service_type_e type = BT_GATT_SERVICE_TYPE_PRIMARY;
631
632     oc_mutex_lock(g_leServiceMutex);
633     int ret = bt_gatt_service_create(serviceUUID, type, &g_gattSvcPath);
634     if (0 != ret)
635     {
636         oc_mutex_unlock(g_leServiceMutex);
637         OIC_LOG_V(ERROR, TAG, "bt_gatt_service_create failed with ret [%s]",
638                     CALEGetErrorMsg(ret));
639         return CA_STATUS_FAILED;
640     }
641     oc_mutex_unlock(g_leServiceMutex);
642
643     if (g_gattSvcPath)
644     {
645         OIC_LOG_V(DEBUG, TAG, "ServicePath obtained is %s", (char *)g_gattSvcPath);
646     }
647
648     OIC_LOG(DEBUG, TAG, "OUT");
649     return CA_STATUS_OK;
650 }
651
652 void CALEGattRemoteCharacteristicWriteCb(const char *remoteAddress, int request_id,
653                                          bt_gatt_server_h server, bt_gatt_h charPath,
654                                          bool response_needed, int offset, const char *charValue,
655                                          int charValueLen, void *userData)
656 {
657     OIC_LOG(INFO, TAG, "IN - WriteCharCB");
658
659     if (NULL == charValue || NULL == remoteAddress)
660     {
661         OIC_LOG(ERROR, TAG, "Param callback values are NULL");
662         return;
663     }
664
665     OIC_LOG_V(DEBUG, TAG, "charPath = [%s] charValue = [%s] len [%d]", (char *)charPath,
666               charValue, charValueLen);
667
668     uint8_t *data = OICMalloc(charValueLen);
669     if (NULL == data)
670     {
671         OIC_LOG(ERROR, TAG, "Malloc failed!");
672         return;
673     }
674
675     memcpy(data, charValue, charValueLen);
676
677     oc_mutex_lock(g_leReqRespCbMutex);
678     if (NULL == g_leServerDataReceivedCallback)
679     {
680         OIC_LOG(ERROR, TAG, "gReqRespCallback is NULL!");
681         oc_mutex_unlock(g_leReqRespCbMutex);
682         OICFree(data);
683         return;
684     }
685
686     OIC_LOG(INFO, TAG, "Sending data up !");
687     uint32_t sentLength = 0;
688     g_leServerDataReceivedCallback(remoteAddress, data, charValueLen,
689                                     &sentLength);
690     oc_mutex_unlock(g_leReqRespCbMutex);
691     OICFree(data);
692
693     OIC_LOG_V(INFO, TAG, "response needed flag: %d", response_needed);
694     if (response_needed)
695     {
696         OIC_LOG(INFO, TAG, "send response to remote client");
697         bt_gatt_server_send_response(request_id,
698                                      BT_GATT_REQUEST_TYPE_WRITE, offset,
699                                      BT_ERROR_NONE, NULL, 0);
700     }
701
702     OIC_LOG(INFO, TAG, "OUT - WriteCharCB");
703 }
704
705 CAResult_t CARegisterLEServicewithGattServer(const bt_gatt_h svcPath)
706 {
707     OIC_LOG(DEBUG, TAG, "IN");
708
709     VERIFY_NON_NULL(svcPath, TAG, "svcPath");
710
711     OIC_LOG_V(DEBUG, TAG, "svcPath:%s", svcPath);
712
713     int ret = bt_gatt_server_register_service(g_gattServer, svcPath);
714     if (0 != ret)
715     {
716         OIC_LOG_V(ERROR, TAG, "bt_gatt_server_register_service failed with ret[%s]",
717                   CALEGetErrorMsg(ret));
718         return CA_STATUS_FAILED;
719     }
720
721     ret = bt_gatt_server_start();
722     if (0 != ret)
723     {
724         OIC_LOG_V(ERROR, TAG, "bt_gatt_server_start failed with ret[%s]",
725                   CALEGetErrorMsg(ret));
726         return CA_STATUS_FAILED;
727     }
728
729     ret = bt_gatt_server_set_write_value_requested_cb(g_gattWriteCharPath,
730                                                       CALEGattRemoteCharacteristicWriteCb, NULL);
731
732     if (0 != ret)
733     {
734         OIC_LOG_V(ERROR, TAG, "bt_gatt_server_set_write_value_requested_cb failed with ret[%s]",
735                   CALEGetErrorMsg(ret));
736         return CA_STATUS_FAILED;
737     }
738
739     OIC_LOG(DEBUG, TAG, "OUT");
740     return CA_STATUS_OK;
741 }
742
743 CAResult_t CAAddNewCharacteristicsToGattServer(const bt_gatt_h svcPath, const char *charUUID,
744                                                const char *charValue, int charValueLen, bool read)
745 {
746
747     OIC_LOG(DEBUG, TAG, "IN");
748
749     int permissions = BT_GATT_PERMISSION_READ | BT_GATT_PERMISSION_WRITE;
750     int properties;
751     if (read)
752     {
753         properties = BT_GATT_PROPERTY_INDICATE | BT_GATT_PROPERTY_READ;
754     }
755     else
756     {
757         properties = BT_GATT_PROPERTY_WRITE | BT_GATT_PROPERTY_READ;
758     }
759
760     bt_gatt_h charPath = NULL;
761
762     int ret = bt_gatt_characteristic_create(charUUID, permissions, properties, charValue,
763                                             charValueLen, &charPath);
764
765     if (0 != ret || NULL == charPath)
766     {
767         OIC_LOG_V(ERROR, TAG,
768                   "bt_gatt_add_characteristic  failed with ret [%s]", CALEGetErrorMsg(ret));
769         return CA_STATUS_FAILED;
770     }
771
772     OIC_LOG_V(DEBUG, TAG,
773               "bt_gatt_characteristic_create charPath obtained: %s", (char *)charPath);
774
775     if (read)
776     {
777         ret = bt_gatt_server_set_characteristic_notification_state_change_cb(charPath,
778                                                                              CALENotificationCb,
779                                                                              NULL);
780         if (0 != ret)
781         {
782             OIC_LOG_V(ERROR, TAG,
783                       "bt_gatt_server_set_characteristic_notification_state_change_cb  failed with ret[%s]",
784                       CALEGetErrorMsg(ret));
785             return CA_STATUS_FAILED;
786         }
787     }
788
789     ret =  bt_gatt_service_add_characteristic(svcPath, charPath);
790     if (0 != ret)
791     {
792         OIC_LOG_V(ERROR, TAG,
793                   "bt_gatt_service_add_characteristic  failed with ret[%s]",
794                   CALEGetErrorMsg(ret));
795         return CA_STATUS_FAILED;
796     }
797
798     oc_mutex_lock(g_leCharacteristicMutex);
799
800     if (read)
801     {
802         char desc_value[2] = {1, 0};  // Notification enabled.
803         bt_gatt_h descriptor = NULL;
804         permissions = BT_GATT_PERMISSION_READ | BT_GATT_PERMISSION_WRITE;
805         ret = bt_gatt_descriptor_create(CA_GATT_CONFIGURATION_DESC_UUID, permissions,
806                                         desc_value, sizeof(desc_value),
807                                         &descriptor);
808         if (0 != ret)
809         {
810             oc_mutex_unlock(g_leCharacteristicMutex);
811             OIC_LOG_V(ERROR, TAG,
812                       "bt_gatt_descriptor_create  failed with ret[%s]",
813                       CALEGetErrorMsg(ret));
814             return CA_STATUS_FAILED;
815         }
816
817         ret = bt_gatt_characteristic_add_descriptor(charPath, descriptor);
818         if (0 != ret)
819         {
820             oc_mutex_unlock(g_leCharacteristicMutex);
821             OIC_LOG_V(ERROR, TAG,
822                       "bt_gatt_characteristic_add_descriptor  failed with ret[%s]",
823                       CALEGetErrorMsg(ret));
824             return CA_STATUS_FAILED;
825         }
826
827         g_gattReadCharPath = charPath;
828     }
829     else
830     {
831         g_gattWriteCharPath = charPath;
832     }
833
834     oc_mutex_unlock(g_leCharacteristicMutex);
835
836     OIC_LOG(DEBUG, TAG, "OUT");
837     return CA_STATUS_OK;
838 }
839
840 CAResult_t CAUpdateCharacteristicsToGattClient(const char *address, const uint8_t *charValue,
841                                                uint32_t charValueLen)
842 {
843     OIC_LOG(DEBUG, TAG, "IN");
844
845     VERIFY_NON_NULL(charValue, TAG, "charValue");
846     VERIFY_NON_NULL(address, TAG, "address");
847
848     OIC_LOG_V(DEBUG, TAG, "Client's Unicast address for sending data [%s]", address);
849
850     oc_mutex_lock(g_leCharacteristicMutex);
851
852     if (NULL  == g_gattReadCharPath)
853     {
854         OIC_LOG(ERROR, TAG, "g_gattReadCharPath is NULL");
855         oc_mutex_unlock(g_leCharacteristicMutex);
856         return CA_STATUS_FAILED;
857     }
858
859     int ret = bt_gatt_set_value(g_gattReadCharPath, (char *)charValue, charValueLen);
860     if (0 != ret)
861     {
862         OIC_LOG_V(ERROR, TAG,
863                   "bt_gatt_set_value failed with return [%s]", CALEGetErrorMsg(ret));
864         oc_mutex_unlock(g_leCharacteristicMutex);
865         return CA_STATUS_FAILED;
866     }
867
868     ret = bt_gatt_server_notify_characteristic_changed_value(g_gattReadCharPath,
869                                                              CALEServerNotificationSentCB,
870                                                              address, NULL);
871     if (0 != ret)
872     {
873         OIC_LOG_V(ERROR, TAG,
874                   "bt_gatt_server_notify_characteristic_changed_value failed with return [%s]", CALEGetErrorMsg(ret));
875         oc_mutex_unlock(g_leCharacteristicMutex);
876         return CA_STATUS_FAILED;
877     }
878
879     oc_mutex_unlock(g_leCharacteristicMutex);
880
881     OIC_LOG(DEBUG, TAG, "OUT");
882     return CA_STATUS_OK;
883 }
884
885 CAResult_t CAUpdateCharacteristicsToAllGattClients(const uint8_t *charValue, uint32_t charValueLen)
886 {
887     OIC_LOG(DEBUG, TAG, "IN");
888
889     VERIFY_NON_NULL(charValue, TAG, "charValue");
890
891     oc_mutex_lock(g_leCharacteristicMutex);
892
893     if (NULL  == g_gattReadCharPath)
894     {
895         OIC_LOG(ERROR, TAG, "g_gattReadCharPath is NULL");
896         oc_mutex_unlock(g_leCharacteristicMutex);
897         return CA_STATUS_FAILED;
898     }
899
900     int ret = bt_gatt_set_value(g_gattReadCharPath, (char *)charValue, charValueLen);
901     if (0 != ret)
902     {
903         OIC_LOG_V(ERROR, TAG, "bt_gatt_set_value failed with return[%s]", CALEGetErrorMsg(ret));
904         oc_mutex_unlock(g_leCharacteristicMutex);
905         return CA_STATUS_FAILED;
906     }
907
908     ret = bt_gatt_server_notify_characteristic_changed_value(g_gattReadCharPath,
909                                                              CALEServerNotificationSentCB,
910                                                              NULL, NULL);
911     if (0 != ret)
912     {
913         OIC_LOG_V(ERROR, TAG,
914                   "bt_gatt_server_notify_characteristic_changed_value failed with return[%s]", CALEGetErrorMsg(ret));
915         oc_mutex_unlock(g_leCharacteristicMutex);
916         return CA_STATUS_FAILED;
917     }
918
919     oc_mutex_unlock(g_leCharacteristicMutex);
920
921     OIC_LOG(DEBUG, TAG, "OUT");
922     return CA_STATUS_OK;
923 }
924
925 void CASetLEReqRespServerCallback(CABLEDataReceivedCallback callback)
926 {
927     OIC_LOG(DEBUG, TAG, "IN");
928
929     oc_mutex_lock(g_leReqRespCbMutex);
930     g_leServerDataReceivedCallback = callback;
931     oc_mutex_unlock(g_leReqRespCbMutex);
932
933     OIC_LOG(DEBUG, TAG, "OUT");
934 }
935
936 void CASetBLEServerErrorHandleCallback(CABLEErrorHandleCallback callback)
937 {
938     g_serverErrorCallback = callback;
939 }
940
941 bool CALEServerIsConnected(const char* address)
942 {
943     //@Todo
944     return true;
945 }
946
947 uint16_t CALEServerGetMtuSize(const char* address)
948 {
949     OIC_LOG(DEBUG, TAG, "IN");
950     VERIFY_NON_NULL_RET(address, TAG, "address is null",
951                         CA_SUPPORTED_BLE_MTU_SIZE - CA_BLE_MTU_HEADER_SIZE);
952
953     unsigned int mtu = CA_DEFAULT_BLE_MTU_SIZE;
954     int ret = 0;
955
956     bt_gatt_client_h client = NULL;
957     ret = bt_gatt_client_create(address, &client);
958     if (0 != ret)
959     {
960         OIC_LOG_V(ERROR, TAG,
961                   "bt_gatt_client_create failed with return [%s]", CALEGetErrorMsg(ret));
962         return CA_DEFAULT_BLE_MTU_SIZE;
963     }
964
965     ret = bt_gatt_client_get_att_mtu(client, &mtu);
966     if (0 != ret)
967     {
968         OIC_LOG_V(ERROR, TAG,
969                   "bt_gatt_client_get_att_mtu failed with return [%s]", CALEGetErrorMsg(ret));
970         return CA_DEFAULT_BLE_MTU_SIZE;
971     }
972
973     ret = bt_gatt_client_destroy(client);
974     if (0 != ret)
975     {
976         OIC_LOG_V(ERROR, TAG,
977                   "bt_gatt_client_destroy failed with return [%s]", CALEGetErrorMsg(ret));
978         return CA_DEFAULT_BLE_MTU_SIZE;
979     }
980
981     OIC_LOG_V(INFO, TAG, "mtu size(including header) from bt_device_get_att_mtu is %d", mtu);
982     return mtu - CA_BLE_MTU_HEADER_SIZE;
983 }