Updated android BLE code
[platform/upstream/iotivity.git] / resource / csdk / connectivity / src / bt_le_adapter / android / 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 <jni.h>
22 #include <stdio.h>
23 #include <string.h>
24 #include <android/log.h>
25 #include <unistd.h>
26 #include "caleserver.h"
27 #include "caleutils.h"
28 #include "caleinterface.h"
29 #include "caadapterutils.h"
30
31 #include "logger.h"
32 #include "oic_malloc.h"
33 #include "cathreadpool.h"
34 #include "camutex.h"
35 #include "uarraylist.h"
36 #include "org_iotivity_ca_CaLeServerInterface.h"
37
38 #define TAG PCF("CA_LE_SERVER")
39
40 static JavaVM *g_jvm = NULL;
41 static jobject g_context = NULL;
42 static jobject g_bluetoothGattServer = NULL;
43 static jobject g_bluetoothGattServerCallback = NULL;
44 static jobject g_leAdvertiseCallback = NULL;
45
46 static CAPacketReceiveCallback g_packetReceiveCallback = NULL;
47 static CABLEErrorHandleCallback g_serverErrorCallback;
48
49 static u_arraylist_t *g_connectedDeviceList = NULL;
50 static ca_thread_pool_t g_threadPoolHandle = NULL;
51
52 static bool g_isStartServer = false;
53 static bool g_isInitializedServer = false;
54
55 static CABLEServerDataReceivedCallback g_CABLEServerDataReceivedCallback = NULL;
56 static ca_mutex g_bleReqRespCbMutex = NULL;
57 static ca_mutex g_bleClientBDAddressMutex = NULL;
58 static ca_mutex g_connectedDeviceListMutex = NULL;
59
60 void CALEServerJNISetContext()
61 {
62     OIC_LOG(DEBUG, TAG, "CALEServerJNISetContext");
63     g_context = (jobject) CANativeJNIGetContext();
64 }
65
66 void CALeServerJniInit()
67 {
68     OIC_LOG(DEBUG, TAG, "CALeServerJniInit");
69     g_jvm = (JavaVM*) CANativeJNIGetJavaVM();
70 }
71
72 CAResult_t CALEServerCreateJniInterfaceObject()
73 {
74     OIC_LOG(DEBUG, TAG, "CALEServerCreateJniInterfaceObject");
75
76     if (!g_context)
77     {
78         OIC_LOG(ERROR, TAG, "g_context is null");
79         return CA_STATUS_FAILED;
80     }
81
82     if (!g_jvm)
83     {
84         OIC_LOG(ERROR, TAG, "g_jvm is null");
85         return CA_STATUS_FAILED;
86     }
87
88     bool isAttached = false;
89     JNIEnv* env;
90     jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
91     if (JNI_OK != res)
92     {
93         OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
94         res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
95
96         if (JNI_OK != res)
97         {
98             OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
99             return CA_STATUS_FAILED;
100         }
101         isAttached = true;
102     }
103
104     jclass jni_LEInterface = (*env)->FindClass(env, "org/iotivity/ca/CaLeServerInterface");
105     if (!jni_LEInterface)
106     {
107         OIC_LOG(ERROR, TAG, "Could not get CaLeServerInterface class");
108         goto exit;
109     }
110
111     jmethodID LeInterfaceConstructorMethod = (*env)->GetMethodID(env, jni_LEInterface, "<init>",
112                                                                  "()V");
113     if (!LeInterfaceConstructorMethod)
114     {
115         OIC_LOG(ERROR, TAG, "Could not get CaLeServerInterface constructor method");
116         goto exit;
117     }
118
119     (*env)->NewObject(env, jni_LEInterface, LeInterfaceConstructorMethod, g_context);
120     OIC_LOG(DEBUG, TAG, "Create instance for CaLeServerInterface");
121
122     if (isAttached)
123     {
124         (*g_jvm)->DetachCurrentThread(g_jvm);
125     }
126
127     return CA_STATUS_OK;
128
129     exit:
130
131     if (isAttached)
132     {
133         (*g_jvm)->DetachCurrentThread(g_jvm);
134     }
135
136     return CA_STATUS_FAILED;
137 }
138
139 jobject CALEServerSetResponseData(JNIEnv *env, jbyteArray responseData)
140 {
141     OIC_LOG(DEBUG, TAG, "IN - CALEServerSetResponseData");
142     VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
143     VERIFY_NON_NULL_RET(responseData, TAG, "responseData is null", NULL);
144
145     if (!g_bluetoothGattServer)
146     {
147         OIC_LOG(ERROR, TAG, "Check BluetoothGattServer status");
148         return NULL;
149     }
150
151     if (!CALEIsEnableBTAdapter(env))
152     {
153         OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
154         return NULL;
155     }
156
157     OIC_LOG(DEBUG, TAG, "CALEServerSetResponseData");
158
159     jclass jni_cid_bluetoothGattServer = (*env)->FindClass(env,
160                                                            "android/bluetooth/BluetoothGattServer");
161     if (!jni_cid_bluetoothGattServer)
162     {
163         OIC_LOG(ERROR, TAG, "jni_cid_bluetoothGattServer is null");
164         return NULL;
165     }
166
167     jclass jni_cid_bluetoothGattService = (*env)->FindClass(env, "android/bluetooth/"
168                                                             "BluetoothGattService");
169     if (!jni_cid_bluetoothGattService)
170     {
171         OIC_LOG(ERROR, TAG, "jni_cid_bluetoothGattService is null");
172         return NULL;
173     }
174
175     jclass jni_cid_bluetoothGattCharacteristic = (*env)->FindClass(env, "android/bluetooth/"
176                                                                    "BluetoothGattCharacteristic");
177     if (!jni_cid_bluetoothGattService)
178     {
179         OIC_LOG(ERROR, TAG, "jni_cid_bluetoothGattCharacteristic is null");
180         return NULL;
181     }
182
183     jmethodID jni_mid_getService = (*env)->GetMethodID(env, jni_cid_bluetoothGattServer,
184                                                        "getService",
185                                                        "(Ljava/util/UUID;)Landroid/bluetooth/"
186                                                        "BluetoothGattService;");
187     if (!jni_cid_bluetoothGattService)
188     {
189         OIC_LOG(ERROR, TAG, "jni_mid_getService is null");
190         return NULL;
191     }
192
193     jobject jni_obj_serviceUUID = CALEGetUuidFromString(env, OIC_GATT_SERVICE_UUID);
194     if (!jni_obj_serviceUUID)
195     {
196         OIC_LOG(ERROR, TAG, "jni_obj_serviceUUID is null");
197         return NULL;
198     }
199
200     jobject jni_obj_bluetoothGattService = (*env)->CallObjectMethod(env, g_bluetoothGattServer,
201                                                                     jni_mid_getService,
202                                                                     jni_obj_serviceUUID);
203     if (!jni_obj_bluetoothGattService)
204     {
205         OIC_LOG(ERROR, TAG, "jni_obj_bluetoothGattService is null");
206         return NULL;
207     }
208
209     jmethodID jni_mid_getCharacteristic = (*env)->GetMethodID(env, jni_cid_bluetoothGattService,
210                                                               "getCharacteristic",
211                                                               "(Ljava/util/UUID;)"
212                                                               "Landroid/bluetooth/"
213                                                               "BluetoothGattCharacteristic;");
214     if (!jni_mid_getCharacteristic)
215     {
216         OIC_LOG(ERROR, TAG, "jni_mid_getCharacteristic is null");
217         return NULL;
218     }
219
220     jobject jni_obj_responseUUID = CALEGetUuidFromString(env,
221                                                          OIC_GATT_CHARACTERISTIC_RESPONSE_UUID);
222     if (!jni_obj_responseUUID)
223     {
224         OIC_LOG(ERROR, TAG, "jni_obj_responseUUID is null");
225         return NULL;
226     }
227
228     jobject jni_obj_bluetoothGattCharacteristic = (*env)->CallObjectMethod(
229             env, jni_obj_bluetoothGattService, jni_mid_getCharacteristic, jni_obj_responseUUID);
230     if (!jni_obj_bluetoothGattCharacteristic)
231     {
232         OIC_LOG(ERROR, TAG, "jni_obj_bluetoothGattCharacteristic is null");
233         return NULL;
234     }
235
236     jmethodID jni_mid_setValue = (*env)->GetMethodID(env, jni_cid_bluetoothGattCharacteristic,
237                                                      "setValue", "([B)Z");
238     if (!jni_mid_setValue)
239     {
240         OIC_LOG(ERROR, TAG, "jni_mid_setValue is null");
241         return NULL;
242     }
243
244     jboolean jni_boolean_setValue = (*env)->CallBooleanMethod(env,
245                                                               jni_obj_bluetoothGattCharacteristic,
246                                                               jni_mid_setValue, responseData);
247     if (JNI_FALSE == jni_boolean_setValue)
248     {
249         OIC_LOG(ERROR, TAG, "Fail to set response data");
250     }
251
252     OIC_LOG(DEBUG, TAG, "OUT - CALEServerSetResponseData");
253     return jni_obj_bluetoothGattCharacteristic;
254 }
255
256 CAResult_t CALEServerSendResponseData(JNIEnv *env, jobject device, jobject responseData)
257 {
258     OIC_LOG(DEBUG, TAG, "IN - CALEServerSendResponseData");
259     VERIFY_NON_NULL(responseData, TAG, "responseData is null");
260     VERIFY_NON_NULL(device, TAG, "device is null");
261     VERIFY_NON_NULL(env, TAG, "env is null");
262
263     if (!CALEIsEnableBTAdapter(env))
264     {
265         OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
266         return CA_ADAPTER_NOT_ENABLED;
267     }
268
269     jclass jni_cid_bluetoothGattServer = (*env)->FindClass(env,
270                                                            "android/bluetooth/BluetoothGattServer");
271     if (!jni_cid_bluetoothGattServer)
272     {
273         OIC_LOG(ERROR, TAG, "jni_cid_bluetoothGattServer is null");
274         return CA_STATUS_FAILED;
275     }
276
277     jmethodID jni_mid_notifyCharacteristicChanged = (*env)->GetMethodID(
278             env, jni_cid_bluetoothGattServer, "notifyCharacteristicChanged",
279             "(Landroid/bluetooth/BluetoothDevice;"
280             "Landroid/bluetooth/BluetoothGattCharacteristic;Z)Z");
281     if (!jni_mid_notifyCharacteristicChanged)
282     {
283         OIC_LOG(ERROR, TAG, "jni_mid_notifyCharacteristicChanged is null");
284         return CA_STATUS_FAILED;
285     }
286
287     jboolean jni_boolean_notifyCharacteristicChanged = (*env)->CallBooleanMethod(
288             env, g_bluetoothGattServer, jni_mid_notifyCharacteristicChanged, device, responseData,
289             JNI_FALSE);
290     if (JNI_FALSE == jni_boolean_notifyCharacteristicChanged)
291     {
292         OIC_LOG(ERROR, TAG, "Fail to notify characteristic");
293         return CA_SEND_FAILED;
294     }
295
296     OIC_LOG(DEBUG, TAG, "OUT - CALEServerSendResponseData");
297     return CA_STATUS_OK;
298 }
299
300 CAResult_t CALEServerSendResponse(JNIEnv *env, jobject device, jint requestId, jint status,
301                                         jint offset, jbyteArray value)
302 {
303     OIC_LOG(DEBUG, TAG, "IN - CALEServerSendResponse");
304     VERIFY_NON_NULL(env, TAG, "env is null");
305     VERIFY_NON_NULL(device, TAG, "device is null");
306     VERIFY_NON_NULL(value, TAG, "value is null");
307
308     OIC_LOG(DEBUG, TAG, "CALEServerSendResponse");
309
310     if (!CALEIsEnableBTAdapter(env))
311     {
312         OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
313         return CA_ADAPTER_NOT_ENABLED;
314     }
315
316     jclass jni_cid_bluetoothGattServer = (*env)->FindClass(env,
317                                                            "android/bluetooth/BluetoothGattServer");
318     if (!jni_cid_bluetoothGattServer)
319     {
320         OIC_LOG(ERROR, TAG, "jni_cid_bluetoothGattServer is null");
321         return CA_STATUS_FAILED;
322     }
323
324     jmethodID jni_mid_sendResponse = (*env)->GetMethodID(env, jni_cid_bluetoothGattServer,
325                                                          "sendResponse",
326                                                          "(Landroid/bluetooth/BluetoothDevice;"
327                                                          "III[B)Z");
328     if (!jni_mid_sendResponse)
329     {
330         OIC_LOG(ERROR, TAG, "jni_mid_sendResponse is null");
331         return CA_STATUS_FAILED;
332     }
333
334     jboolean jni_boolean_sendResponse = (*env)->CallBooleanMethod(env, g_bluetoothGattServer,
335                                                                   jni_mid_sendResponse, device,
336                                                                   requestId, status, offset,
337                                                                   value);
338     if (JNI_FALSE == jni_boolean_sendResponse)
339     {
340         OIC_LOG(ERROR, TAG, "Fail to send response for gatt characteristic write request");
341         return CA_SEND_FAILED;
342     }
343
344     OIC_LOG(DEBUG, TAG, "OUT - CALEServerSendResponse");
345     return CA_STATUS_OK;
346 }
347
348 CAResult_t CALEServerStartAdvertise(JNIEnv *env, jobject advertiseCallback)
349 {
350     OIC_LOG(DEBUG, TAG, "IN - CALEServerStartAdvertise");
351     VERIFY_NON_NULL(env, TAG, "env is null");
352     VERIFY_NON_NULL(advertiseCallback, TAG, "advertiseCallback is null");
353
354     if (!CALEIsEnableBTAdapter(env))
355     {
356         OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
357         return CA_ADAPTER_NOT_ENABLED;
358     }
359
360     jclass jni_cid_AdvertiseSettings = (*env)->FindClass(env,
361                                                          "android/bluetooth/le/"
362                                                          "AdvertiseSettings$Builder");
363     if (!jni_cid_AdvertiseSettings)
364     {
365         OIC_LOG(ERROR, TAG, "jni_cid_AdvertiseSettings is null");
366         return CA_STATUS_FAILED;
367     }
368
369     jmethodID jni_mid_AdvertiseSettings = (*env)->GetMethodID(env, jni_cid_AdvertiseSettings,
370                                                               "<init>", "()V");
371     if (!jni_mid_AdvertiseSettings)
372     {
373         OIC_LOG(ERROR, TAG, "jni_mid_AdvertiseSettings is null");
374         return CA_STATUS_FAILED;
375     }
376
377     jobject jni_AdvertiseSettings = (*env)->NewObject(env, jni_cid_AdvertiseSettings,
378                                                       jni_mid_AdvertiseSettings);
379     if (!jni_AdvertiseSettings)
380     {
381         OIC_LOG(ERROR, TAG, "jni_AdvertiseSettings is null");
382         return CA_STATUS_FAILED;
383     }
384
385     jmethodID jni_mid_setAdvertiseMode = (*env)->GetMethodID(env, jni_cid_AdvertiseSettings,
386                                                              "setAdvertiseMode",
387                                                              "(I)Landroid/bluetooth/le/"
388                                                              "AdvertiseSettings$Builder;");
389     if (!jni_mid_setAdvertiseMode)
390     {
391         OIC_LOG(ERROR, TAG, "jni_mid_setAdvertiseMode is null");
392         return CA_STATUS_FAILED;
393     }
394
395     // 0: Low power, 1: Balanced
396     jobject jni_obj_setAdvertiseMode = (*env)->CallObjectMethod(env, jni_AdvertiseSettings,
397                                                                 jni_mid_setAdvertiseMode, 0);
398     if (!jni_obj_setAdvertiseMode)
399     {
400         OIC_LOG(ERROR, TAG, "jni_obj_setAdvertiseMode is null");
401         return CA_STATUS_FAILED;
402     }
403
404     jmethodID jni_mid_setConnectable = (*env)->GetMethodID(env, jni_cid_AdvertiseSettings,
405                                                            "setConnectable",
406                                                            "(Z)Landroid/bluetooth/le/"
407                                                            "AdvertiseSettings$Builder;");
408     if (!jni_mid_setConnectable)
409     {
410         OIC_LOG(ERROR, TAG, "jni_mid_setConnectable is null");
411         return CA_STATUS_FAILED;
412     }
413
414     jobject jni_obj_setConnectable = (*env)->CallObjectMethod(env, jni_AdvertiseSettings,
415                                                               jni_mid_setConnectable, JNI_TRUE);
416     if (!jni_obj_setConnectable)
417     {
418         OIC_LOG(ERROR, TAG, "jni_obj_setConnectable is null");
419         return CA_STATUS_FAILED;
420     }
421
422     jmethodID jni_mid_setTimeout = (*env)->GetMethodID(env, jni_cid_AdvertiseSettings, "setTimeout",
423                                                        "(I)Landroid/bluetooth/le/"
424                                                        "AdvertiseSettings$Builder;");
425     if (!jni_mid_setTimeout)
426     {
427         OIC_LOG(ERROR, TAG, "jni_mid_setTimeout is null");
428         return CA_STATUS_FAILED;
429     }
430
431     //A value of 0 will disable the time limit
432     jobject jni_obj_setTimeout = (*env)->CallObjectMethod(env, jni_AdvertiseSettings,
433                                                           jni_mid_setTimeout, 0);
434     if (!jni_obj_setTimeout)
435     {
436         OIC_LOG(ERROR, TAG, "jni_obj_setTimeout is null");
437         return CA_STATUS_FAILED;
438     }
439
440     jclass jni_cid_AdvertiseDataBuilder = (*env)->FindClass(env,
441                                                             "android/bluetooth/le/"
442                                                             "AdvertiseData$Builder");
443     if (!jni_cid_AdvertiseDataBuilder)
444     {
445         OIC_LOG(ERROR, TAG, "jni_cid_AdvertiseDataBuilder is null");
446         return CA_STATUS_FAILED;
447     }
448
449     jmethodID jni_mid_AdvertiseDataBuilder = (*env)->GetMethodID(env, jni_cid_AdvertiseDataBuilder,
450                                                                  "<init>", "()V");
451     if (!jni_mid_AdvertiseDataBuilder)
452     {
453         OIC_LOG(ERROR, TAG, "jni_mid_AdvertiseDataBuilder is null");
454         return CA_STATUS_FAILED;
455     }
456
457     jobject jni_AdvertiseDataBuilder = (*env)->NewObject(env, jni_cid_AdvertiseDataBuilder,
458                                                          jni_mid_AdvertiseDataBuilder);
459     if (!jni_AdvertiseDataBuilder)
460     {
461         OIC_LOG(ERROR, TAG, "jni_AdvertiseDataBuilder is null");
462         return CA_STATUS_FAILED;
463     }
464
465     jobject jni_obj_serviceUUID = CALEGetUuidFromString(env, OIC_GATT_SERVICE_UUID);
466     if (!jni_obj_serviceUUID)
467     {
468         OIC_LOG(ERROR, TAG, "jni_obj_serviceUUID is null");
469         return CA_STATUS_FAILED;
470     }
471
472     jobject jni_ParcelUuid = CALEGetParcelUuid(env, jni_obj_serviceUUID);
473     if (!jni_ParcelUuid)
474     {
475         OIC_LOG(ERROR, TAG, "jni_ParcelUuid is null");
476         return CA_STATUS_FAILED;
477     }
478
479     jmethodID jni_mid_addServiceUuid = (*env)->GetMethodID(env, jni_cid_AdvertiseDataBuilder,
480                                                            "addServiceUuid",
481                                                            "(Landroid/os/ParcelUuid;)Landroid/"
482                                                            "bluetooth/le/AdvertiseData$Builder;");
483     if (!jni_mid_addServiceUuid)
484     {
485         OIC_LOG(ERROR, TAG, "jni_mid_addServiceUuid is null");
486         return CA_STATUS_FAILED;
487     }
488
489     jobject jni_obj_addServiceUuid = (*env)->CallObjectMethod(env, jni_AdvertiseDataBuilder,
490                                                               jni_mid_addServiceUuid,
491                                                               jni_ParcelUuid);
492     if (!jni_obj_addServiceUuid)
493     {
494         OIC_LOG(ERROR, TAG, "jni_obj_addServiceUuid is null");
495         return CA_STATUS_FAILED;
496     }
497
498     jclass jni_cid_BTAdapter = (*env)->FindClass(env, "android/bluetooth/BluetoothAdapter");
499     if (!jni_cid_BTAdapter)
500     {
501         OIC_LOG(ERROR, TAG, "jni_cid_BTAdapter is null");
502         return CA_STATUS_FAILED;
503     }
504
505     jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
506                                                                     "getDefaultAdapter",
507                                                                     "()Landroid/bluetooth/"
508                                                                     "BluetoothAdapter;");
509     if (!jni_mid_getDefaultAdapter)
510     {
511         OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
512         return CA_STATUS_FAILED;
513     }
514
515     jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
516                                                                jni_mid_getDefaultAdapter);
517     if (!jni_obj_BTAdapter)
518     {
519         OIC_LOG(ERROR, TAG, "jni_obj_BTAdapter is null");
520         return CA_STATUS_FAILED;
521     }
522
523     jmethodID jni_mid_getBluetoothLeAdvertiser = (*env)->GetMethodID(env, jni_cid_BTAdapter,
524                                                                      "getBluetoothLeAdvertiser",
525                                                                      "()Landroid/bluetooth/le/"
526                                                                      "BluetoothLeAdvertiser;");
527     if (!jni_mid_getBluetoothLeAdvertiser)
528     {
529         OIC_LOG(ERROR, TAG, "jni_mid_getBluetoothLeAdvertiser is null");
530         return CA_STATUS_FAILED;
531     }
532
533     jobject jni_obj_getBluetoothLeAdvertiser = (*env)->CallObjectMethod(
534             env, jni_obj_BTAdapter, jni_mid_getBluetoothLeAdvertiser);
535     if (!jni_obj_getBluetoothLeAdvertiser)
536     {
537         OIC_LOG(ERROR, TAG, "jni_obj_getBluetoothLeAdvertiser is null");
538         return CA_STATUS_FAILED;
539     }
540
541     jmethodID jni_mid_build_LeAdvertiseSettings = (*env)->GetMethodID(env,
542                                                                       jni_cid_AdvertiseSettings,
543                                                                       "build",
544                                                                       "()Landroid/bluetooth/le/"
545                                                                       "AdvertiseSettings;");
546     if (!jni_mid_build_LeAdvertiseSettings)
547     {
548         OIC_LOG(ERROR, TAG, "jni_mid_build_LeAdvertiseSettings is null");
549         return CA_STATUS_FAILED;
550     }
551
552     jobject jni_obj_build_LeAdvertiseSettings = (*env)->CallObjectMethod(
553             env, jni_AdvertiseSettings, jni_mid_build_LeAdvertiseSettings);
554     if (!jni_obj_build_LeAdvertiseSettings)
555     {
556         OIC_LOG(ERROR, TAG, "jni_obj_build_LeAdvertiseSettings is null");
557         return CA_STATUS_FAILED;
558     }
559
560     jmethodID jni_mid_build_LeAdvertiseData = (*env)->GetMethodID(env, jni_cid_AdvertiseDataBuilder,
561                                                                   "build",
562                                                                   "()Landroid/bluetooth/le/"
563                                                                   "AdvertiseData;");
564     if (!jni_mid_build_LeAdvertiseData)
565     {
566         OIC_LOG(ERROR, TAG, "jni_mid_build_LeAdvertiseData is null");
567         return CA_STATUS_FAILED;
568     }
569
570     jobject jni_obj_build_LeAdvertiseData = (*env)->CallObjectMethod(env, jni_AdvertiseDataBuilder,
571                                                                      jni_mid_build_LeAdvertiseData);
572     if (!jni_obj_build_LeAdvertiseData)
573     {
574         OIC_LOG(ERROR, TAG, "jni_obj_build_LeAdvertiseData is null");
575         return CA_STATUS_FAILED;
576     }
577
578     jclass jni_cid_leAdvertiser = (*env)->FindClass(env,
579                                                     "android/bluetooth/le/BluetoothLeAdvertiser");
580     if (!jni_cid_leAdvertiser)
581     {
582         OIC_LOG(ERROR, TAG, "jni_cid_leAdvertiser is null");
583         return CA_STATUS_FAILED;
584     }
585
586     jmethodID jni_mid_startAdvertising = (*env)->GetMethodID(env, jni_cid_leAdvertiser,
587                                                              "startAdvertising",
588                                                              "(Landroid/bluetooth/le/"
589                                                              "AdvertiseSettings;Landroid/bluetooth/"
590                                                              "le/AdvertiseData;Landroid/bluetooth/"
591                                                              "le/AdvertiseCallback;)V");
592     if (!jni_mid_startAdvertising)
593     {
594         OIC_LOG(ERROR, TAG, "jni_mid_startAdvertising is null");
595         return CA_STATUS_FAILED;
596     }
597
598     (*env)->CallVoidMethod(env, jni_obj_getBluetoothLeAdvertiser, jni_mid_startAdvertising,
599                            jni_obj_build_LeAdvertiseSettings, jni_obj_build_LeAdvertiseData,
600                            advertiseCallback);
601
602     if ((*env)->ExceptionCheck(env))
603     {
604         OIC_LOG(ERROR, TAG, "StartAdvertising has failed");
605         (*env)->ExceptionDescribe(env);
606         (*env)->ExceptionClear(env);
607         return CA_STATUS_FAILED;
608     }
609
610     OIC_LOG(DEBUG, TAG, "Advertising started!!");
611
612     OIC_LOG(DEBUG, TAG, "OUT - CALEServerStartAdvertise");
613     return CA_STATUS_OK;
614 }
615
616 CAResult_t CALEServerStopAdvertise(JNIEnv *env, jobject advertiseCallback)
617 {
618     OIC_LOG(DEBUG, TAG, "IN - LEServerStopAdvertise");
619     VERIFY_NON_NULL(env, TAG, "env is null");
620     VERIFY_NON_NULL(advertiseCallback, TAG, "advertiseCallback is null");
621
622     if (!CALEIsEnableBTAdapter(env))
623     {
624         OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
625         return CA_ADAPTER_NOT_ENABLED;
626     }
627
628     jclass jni_cid_BTAdapter = (*env)->FindClass(env, "android/bluetooth/BluetoothAdapter");
629     if (!jni_cid_BTAdapter)
630     {
631         OIC_LOG(ERROR, TAG, "jni_cid_BTAdapter is null");
632         return CA_STATUS_FAILED;
633     }
634
635     jclass jni_cid_leAdvertiser = (*env)->FindClass(env,
636                                                     "android/bluetooth/le/BluetoothLeAdvertiser");
637     if (!jni_cid_leAdvertiser)
638     {
639         OIC_LOG(ERROR, TAG, "jni_cid_leAdvertiser is null");
640         return CA_STATUS_FAILED;
641     }
642
643     jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
644                                                                     "getDefaultAdapter",
645                                                                     "()Landroid/bluetooth/"
646                                                                     "BluetoothAdapter;");
647     if (!jni_cid_leAdvertiser)
648     {
649         OIC_LOG(ERROR, TAG, "jni_cid_leAdvertiser is null");
650         return CA_STATUS_FAILED;
651     }
652
653     jmethodID jni_mid_getBTLeAdvertiser = (*env)->GetMethodID(env, jni_cid_BTAdapter,
654                                                                      "getBluetoothLeAdvertiser",
655                                                                      "()Landroid/bluetooth/le/"
656                                                                      "BluetoothLeAdvertiser;");
657     if (!jni_mid_getBTLeAdvertiser)
658     {
659         OIC_LOG(ERROR, TAG, "jni_mid_getBTLeAdvertiser is null");
660         return CA_STATUS_FAILED;
661     }
662
663     jmethodID jni_mid_stopAdvertising = (*env)->GetMethodID(env, jni_cid_leAdvertiser,
664                                                             "stopAdvertising",
665                                                             "(Landroid/bluetooth/le/"
666                                                             "AdvertiseCallback;)V");
667     if (!jni_mid_stopAdvertising)
668     {
669         OIC_LOG(ERROR, TAG, "jni_mid_stopAdvertising is null");
670         return CA_STATUS_FAILED;
671     }
672
673     jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
674                                                                jni_mid_getDefaultAdapter);
675     if (!jni_obj_BTAdapter)
676     {
677         OIC_LOG(ERROR, TAG, "jni_obj_BTAdapter is null");
678         return CA_STATUS_FAILED;
679     }
680
681     jobject jni_obj_getBluetoothLeAdvertiser = (*env)->CallObjectMethod(env, jni_obj_BTAdapter,
682                                                                         jni_mid_getBTLeAdvertiser);
683     if (!jni_obj_getBluetoothLeAdvertiser)
684     {
685         OIC_LOG(ERROR, TAG, "jni_obj_getBluetoothLeAdvertiser is null");
686         return CA_STATUS_FAILED;
687     }
688
689     (*env)->CallVoidMethod(env, jni_obj_getBluetoothLeAdvertiser, jni_mid_stopAdvertising,
690                            advertiseCallback);
691     if ((*env)->ExceptionCheck(env))
692     {
693         OIC_LOG(ERROR, TAG, "getBluetoothLeAdvertiser has failed");
694         (*env)->ExceptionDescribe(env);
695         (*env)->ExceptionClear(env);
696         return CA_STATUS_FAILED;
697     }
698
699     OIC_LOG(DEBUG, TAG, "Advertising stopped!!");
700
701     OIC_LOG(DEBUG, TAG, "OUT - LEServerStopAdvertise");
702     return CA_STATUS_OK;
703 }
704
705 CAResult_t CALEServerStartGattServer(JNIEnv *env, jobject gattServerCallback)
706 {
707     OIC_LOG(DEBUG, TAG, "IN - CALEServerStartGattServer");
708     VERIFY_NON_NULL(env, TAG, "env is null");
709     VERIFY_NON_NULL(gattServerCallback, TAG, "gattServerCallback is null");
710
711     if (!CALEIsEnableBTAdapter(env))
712     {
713         OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
714         return CA_ADAPTER_NOT_ENABLED;
715     }
716
717     if (g_isStartServer)
718     {
719         OIC_LOG(DEBUG, TAG, "Gatt server already started");
720     }
721
722     g_bluetoothGattServerCallback = (*env)->NewGlobalRef(env, gattServerCallback);
723
724     // open gatt server
725     jobject bluetoothGattServer = CALEServerOpenGattServer(env);
726     if (!bluetoothGattServer)
727     {
728         OIC_LOG(ERROR, TAG, "bluetoothGattServer is null");
729         return CA_STATUS_FAILED;
730     }
731
732     g_bluetoothGattServer = (*env)->NewGlobalRef(env, bluetoothGattServer);
733     if (!g_bluetoothGattServer)
734     {
735         OIC_LOG(ERROR, TAG, "g_bluetoothGattServer is null");
736         return CA_STATUS_FAILED;
737     }
738
739     // create gatt service
740     jobject bluetoothGattService = CALEServerCreateGattService(env);
741     if (!bluetoothGattService)
742     {
743         OIC_LOG(ERROR, TAG, "bluetoothGattService is null");
744         return CA_STATUS_FAILED;
745     }
746
747     // add gatt service
748     CAResult_t res = CALEServerAddGattService(env, g_bluetoothGattServer,
749                                               bluetoothGattService);
750     if (CA_STATUS_OK != res)
751     {
752         OIC_LOG(ERROR, TAG, "CALEServerAddGattService has failed");
753     }
754     return res;
755 }
756
757 jobject CALEServerOpenGattServer(JNIEnv *env)
758 {
759     OIC_LOG(DEBUG, TAG, "IN - CALEServerOpenGattServer");
760     VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
761
762     if (!CALEIsEnableBTAdapter(env))
763     {
764         OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
765         return NULL;
766     }
767
768     jclass jni_cid_context = (*env)->FindClass(env, "android/content/Context");
769     if (!jni_cid_context)
770     {
771         OIC_LOG(ERROR, TAG, "jni_cid_context is null");
772         return NULL;
773     }
774
775     jclass jni_cid_bluetoothManager = (*env)->FindClass(env, "android/bluetooth/BluetoothManager");
776     if (!jni_cid_bluetoothManager)
777     {
778         OIC_LOG(ERROR, TAG, "jni_cid_bluetoothManager is null");
779         return NULL;
780     }
781
782     jfieldID jni_fid_bluetoothService = (*env)->GetStaticFieldID(env, jni_cid_context,
783                                                                  "BLUETOOTH_SERVICE",
784                                                                  "Ljava/lang/String;");
785     if (!jni_fid_bluetoothService)
786     {
787         OIC_LOG(ERROR, TAG, "jni_fid_bluetoothService is null");
788         return NULL;
789     }
790
791     jmethodID jni_mid_getSystemService = (*env)->GetMethodID(env, jni_cid_context,
792                                                              "getSystemService",
793                                                              "(Ljava/lang/String;)"
794                                                              "Ljava/lang/Object;");
795     if (!jni_mid_getSystemService)
796     {
797         OIC_LOG(ERROR, TAG, "jni_mid_getSystemService is null");
798         return NULL;
799     }
800
801     jmethodID jni_mid_openGattServer = (*env)->GetMethodID(env, jni_cid_bluetoothManager,
802                                                            "openGattServer",
803                                                            "(Landroid/content/Context;"
804                                                            "Landroid/bluetooth/"
805                                                            "BluetoothGattServerCallback;)"
806                                                            "Landroid/bluetooth/"
807                                                            "BluetoothGattServer;");
808     if (!jni_mid_openGattServer)
809     {
810         OIC_LOG(ERROR, TAG, "jni_mid_openGattServer is null");
811         return NULL;
812     }
813
814     jobject jni_obj_bluetoothService = (*env)->GetStaticObjectField(env, jni_cid_context,
815                                                                     jni_fid_bluetoothService);
816     if (!jni_obj_bluetoothService)
817     {
818         OIC_LOG(ERROR, TAG, "jni_obj_bluetoothService is null");
819         return NULL;
820     }
821
822     jobject jni_obj_bluetoothManager = (*env)->CallObjectMethod(env, g_context,
823                                                                 jni_mid_getSystemService,
824                                                                 jni_obj_bluetoothService);
825     if (!jni_obj_bluetoothManager)
826     {
827         OIC_LOG(ERROR, TAG, "jni_obj_bluetoothManager is null");
828         return NULL;
829     }
830
831     jobject jni_obj_bluetoothGattServer = (*env)->CallObjectMethod(env, jni_obj_bluetoothManager,
832                                                                    jni_mid_openGattServer,
833                                                                    g_context,
834                                                                    g_bluetoothGattServerCallback);
835     if (!jni_obj_bluetoothGattServer)
836     {
837         OIC_LOG(ERROR, TAG, "jni_obj_bluetoothGattServer is null");
838         return NULL;
839     }
840
841     OIC_LOG(DEBUG, TAG, "OUT - CALEServerOpenGattServer");
842     return jni_obj_bluetoothGattServer;
843 }
844
845 jobject CALEServerCreateGattService(JNIEnv *env)
846 {
847     OIC_LOG(DEBUG, TAG, "IN - CALEServerCreateGattService");
848     VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
849
850     if (!CALEIsEnableBTAdapter(env))
851     {
852         OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
853         return NULL;
854     }
855
856     jclass jni_cid_bluetoothGattService = (*env)->FindClass(env, "android/bluetooth/"
857                                                             "BluetoothGattService");
858     if (!jni_cid_bluetoothGattService)
859     {
860         OIC_LOG(ERROR, TAG, "jni_cid_bluetoothGattService is null");
861         return NULL;
862     }
863
864     jclass jni_cid_bluetoothGattCharacteristic = (*env)->FindClass(env, "android/bluetooth/"
865                                                                    "BluetoothGattCharacteristic");
866     if (!jni_cid_bluetoothGattCharacteristic)
867     {
868         OIC_LOG(ERROR, TAG, "jni_cid_bluetoothGattCharacteristic is null");
869         return NULL;
870     }
871
872     jfieldID jni_fid_serviceType = (*env)->GetStaticFieldID(env, jni_cid_bluetoothGattService,
873                                                             "SERVICE_TYPE_PRIMARY", "I");
874     if (!jni_fid_serviceType)
875     {
876         OIC_LOG(ERROR, TAG, "jni_fid_serviceType is null");
877         return NULL;
878     }
879
880     jfieldID jni_fid_readProperties = (*env)->GetStaticFieldID(env,
881                                                                jni_cid_bluetoothGattCharacteristic,
882                                                                "PROPERTY_NOTIFY", "I");
883     if (!jni_fid_readProperties)
884     {
885         OIC_LOG(ERROR, TAG, "jni_fid_readProperties is null");
886         return NULL;
887     }
888
889 #ifdef USE_PROPERTY_WRITE_RESPONSE
890     jfieldID jni_fid_writeProperties = (*env)->GetStaticFieldID(env,
891                                                                 jni_cid_bluetoothGattCharacteristic,
892                                                                 "PROPERTY_WRITE", "I");
893 #else
894     jfieldID jni_fid_writeProperties = (*env)->GetStaticFieldID(env,
895                                                                 jni_cid_bluetoothGattCharacteristic,
896                                                                 "PROPERTY_WRITE_NO_RESPONSE", "I");
897 #endif
898
899     if (!jni_fid_writeProperties)
900     {
901         OIC_LOG(ERROR, TAG, "jni_fid_writeProperties is null");
902         return NULL;
903     }
904
905     jfieldID jni_fid_readPermissions = (*env)->GetStaticFieldID(env,
906                                                                 jni_cid_bluetoothGattCharacteristic,
907                                                                 "PERMISSION_READ", "I");
908     if (!jni_fid_readPermissions)
909     {
910         OIC_LOG(ERROR, TAG, "jni_fid_readPermissions is null");
911         return NULL;
912     }
913
914     jfieldID jni_fid_writePermissions = (*env)->GetStaticFieldID(
915             env, jni_cid_bluetoothGattCharacteristic, "PERMISSION_WRITE", "I");
916     if (!jni_fid_writePermissions)
917     {
918         OIC_LOG(ERROR, TAG, "jni_fid_writePermissions is null");
919         return NULL;
920     }
921
922     jmethodID jni_mid_bluetoothGattService = (*env)->GetMethodID(env, jni_cid_bluetoothGattService,
923                                                                  "<init>", "(Ljava/util/UUID;I)V");
924     if (!jni_mid_bluetoothGattService)
925     {
926         OIC_LOG(ERROR, TAG, "jni_mid_bluetoothGattService is null");
927         return NULL;
928     }
929
930     jmethodID jni_mid_addCharacteristic = (*env)->GetMethodID(env, jni_cid_bluetoothGattService,
931                                                               "addCharacteristic",
932                                                               "(Landroid/bluetooth/"
933                                                               "BluetoothGattCharacteristic;)Z");
934     if (!jni_mid_addCharacteristic)
935     {
936         OIC_LOG(ERROR, TAG, "jni_mid_addCharacteristic is null");
937         return NULL;
938     }
939
940     jmethodID jni_mid_bluetoothGattCharacteristic = (*env)->GetMethodID(
941             env, jni_cid_bluetoothGattCharacteristic, "<init>", "(Ljava/util/UUID;II)V");
942     if (!jni_mid_bluetoothGattCharacteristic)
943     {
944         OIC_LOG(ERROR, TAG, "jni_mid_bluetoothGattCharacteristic is null");
945         return NULL;
946     }
947
948     jobject jni_obj_serviceUUID = CALEGetUuidFromString(env, OIC_GATT_SERVICE_UUID);
949     if (!jni_obj_serviceUUID)
950     {
951         OIC_LOG(ERROR, TAG, "jni_obj_serviceUUID is null");
952         return NULL;
953     }
954
955     jint jni_int_serviceType = (*env)->GetStaticIntField(env, jni_cid_bluetoothGattService,
956                                                          jni_fid_serviceType);
957     jobject jni_bluetoothGattService = (*env)->NewObject(env, jni_cid_bluetoothGattService,
958                                                          jni_mid_bluetoothGattService,
959                                                          jni_obj_serviceUUID, jni_int_serviceType);
960     if (!jni_bluetoothGattService)
961     {
962         OIC_LOG(ERROR, TAG, "jni_bluetoothGattService is null");
963         return NULL;
964     }
965
966     jobject jni_obj_readUuid = CALEGetUuidFromString(env, OIC_GATT_CHARACTERISTIC_RESPONSE_UUID);
967     if (!jni_obj_readUuid)
968     {
969         OIC_LOG(ERROR, TAG, "jni_obj_readUuid is null");
970         return NULL;
971     }
972
973     jint jni_int_readProperties = (*env)->GetStaticIntField(env,
974                                                             jni_cid_bluetoothGattCharacteristic,
975                                                             jni_fid_readProperties);
976
977     jint jni_int_readPermissions = (*env)->GetStaticIntField(env,
978                                                              jni_cid_bluetoothGattCharacteristic,
979                                                              jni_fid_readPermissions);
980
981     jint jni_int_writePermissions = (*env)->GetStaticIntField(env,
982                                                               jni_cid_bluetoothGattCharacteristic,
983                                                               jni_fid_writePermissions);
984
985     jobject jni_readCharacteristic = (*env)->NewObject(env, jni_cid_bluetoothGattCharacteristic,
986                                                        jni_mid_bluetoothGattCharacteristic,
987                                                        jni_obj_readUuid, jni_int_readProperties,
988                                                        jni_int_readPermissions|
989                                                        jni_int_writePermissions);
990     if (!jni_readCharacteristic)
991     {
992         OIC_LOG(ERROR, TAG, "jni_readCharacteristic is null");
993         return NULL;
994     }
995
996     jboolean jni_boolean_addReadCharacteristic = (*env)->CallBooleanMethod(
997             env, jni_bluetoothGattService, jni_mid_addCharacteristic, jni_readCharacteristic);
998     if (!jni_boolean_addReadCharacteristic)
999     {
1000         OIC_LOG(ERROR, TAG, "jni_boolean_addReadCharacteristic is null");
1001         return NULL;
1002     }
1003
1004     jobject jni_obj_writeUuid = CALEGetUuidFromString(env, OIC_GATT_CHARACTERISTIC_REQUEST_UUID);
1005     if (!jni_obj_writeUuid)
1006     {
1007         OIC_LOG(ERROR, TAG, "jni_obj_bluetoothGattServer is null");
1008         return NULL;
1009     }
1010
1011     jint jni_int_writeProperties = (*env)->GetStaticIntField(env,
1012                                                              jni_cid_bluetoothGattCharacteristic,
1013                                                              jni_fid_writeProperties);
1014
1015     jobject jni_writeCharacteristic = (*env)->NewObject(env, jni_cid_bluetoothGattCharacteristic,
1016                                                         jni_mid_bluetoothGattCharacteristic,
1017                                                         jni_obj_writeUuid, jni_int_writeProperties,
1018                                                         jni_int_writePermissions);
1019     if (!jni_writeCharacteristic)
1020     {
1021         OIC_LOG(ERROR, TAG, "jni_writeCharacteristic is null");
1022         return NULL;
1023     }
1024
1025     jboolean jni_boolean_addWriteCharacteristic = (*env)->CallBooleanMethod(
1026             env, jni_bluetoothGattService, jni_mid_addCharacteristic, jni_writeCharacteristic);
1027     if (JNI_FALSE == jni_boolean_addWriteCharacteristic)
1028     {
1029         OIC_LOG(ERROR, TAG, "Fail to add jni_boolean_addReadCharacteristic");
1030         return NULL;
1031     }
1032
1033     OIC_LOG(DEBUG, TAG, "OUT - CALEServerCreateGattService");
1034     return jni_bluetoothGattService;
1035 }
1036
1037 CAResult_t CALEServerAddGattService(JNIEnv *env, jobject bluetoothGattServer,
1038                                           jobject bluetoothGattService)
1039 {
1040     OIC_LOG(DEBUG, TAG, "IN - CALEServerAddGattService");
1041     VERIFY_NON_NULL(env, TAG, "env is null");
1042     VERIFY_NON_NULL(bluetoothGattServer, TAG, "bluetoothGattServer is null");
1043     VERIFY_NON_NULL(bluetoothGattService, TAG, "bluetoothGattService is null");
1044
1045     if (!CALEIsEnableBTAdapter(env))
1046     {
1047         OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1048         return CA_ADAPTER_NOT_ENABLED;
1049     }
1050
1051     jclass jni_cid_bluetoothGattServer = (*env)->FindClass(env,
1052                                                            "android/bluetooth/BluetoothGattServer");
1053     if (!jni_cid_bluetoothGattServer)
1054     {
1055         OIC_LOG(ERROR, TAG, "jni_cid_bluetoothGattServer is null");
1056         return CA_STATUS_FAILED;
1057     }
1058
1059     jmethodID jni_mid_addService = (*env)->GetMethodID(env, jni_cid_bluetoothGattServer,
1060                                                        "addService",
1061                                                        "(Landroid/bluetooth/BluetoothGattService;)"
1062                                                        "Z");
1063     if (!jni_mid_addService)
1064     {
1065         OIC_LOG(ERROR, TAG, "jni_mid_addService is null");
1066         return CA_STATUS_FAILED;
1067     }
1068
1069     jboolean jni_boolean_addService = (*env)->CallBooleanMethod(env, bluetoothGattServer,
1070                                                                 jni_mid_addService,
1071                                                                 bluetoothGattService);
1072
1073     if (JNI_FALSE == jni_boolean_addService)
1074     {
1075         OIC_LOG(ERROR, TAG, "Fail to add GATT service");
1076         return CA_STATUS_FAILED;
1077     }
1078
1079     OIC_LOG(DEBUG, TAG, "OUT - CALEServerAddGattService");
1080     return CA_STATUS_OK;
1081 }
1082
1083 CAResult_t CALEServerConnect(JNIEnv *env, jobject bluetoothDevice)
1084 {
1085     OIC_LOG(DEBUG, TAG, "IN - CALEServerConnect");
1086     VERIFY_NON_NULL(env, TAG, "env is null");
1087     VERIFY_NON_NULL(bluetoothDevice, TAG, "bluetoothDevice is null");
1088
1089     if (!CALEIsEnableBTAdapter(env))
1090     {
1091         OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1092         return CA_ADAPTER_NOT_ENABLED;
1093     }
1094
1095     jclass jni_cid_bluetoothGattServer = (*env)->FindClass(env,
1096                                                            "android/bluetooth/BluetoothGattServer");
1097     if (!jni_cid_bluetoothGattServer)
1098     {
1099         OIC_LOG(ERROR, TAG, "jni_cid_bluetoothGattServer is null");
1100         return CA_STATUS_FAILED;
1101     }
1102
1103     jmethodID jni_mid_connect = (*env)->GetMethodID(env, jni_cid_bluetoothGattServer, "connect",
1104                                                     "(Landroid/bluetooth/BluetoothDevice;Z)Z");
1105     if (!jni_mid_connect)
1106     {
1107         OIC_LOG(ERROR, TAG, "jni_mid_connect is null");
1108         return CA_STATUS_FAILED;
1109     }
1110
1111     jboolean jni_boolean_connect = (*env)->CallBooleanMethod(env, g_bluetoothGattServer,
1112                                                              jni_mid_connect, bluetoothDevice,
1113                                                              JNI_FALSE);
1114     if (JNI_FALSE == jni_boolean_connect)
1115     {
1116         OIC_LOG(ERROR, TAG, "Fail to connect");
1117         return CA_STATUS_FAILED;
1118     }
1119
1120     OIC_LOG(DEBUG, TAG, "OUT - CALEServerConnect");
1121     return CA_STATUS_OK;
1122 }
1123
1124 CAResult_t CALEServerDisconnectAllDevices(JNIEnv *env)
1125 {
1126     OIC_LOG(DEBUG, TAG, "IN - CALEServerDisconnectAllDevices");
1127     VERIFY_NON_NULL(env, TAG, "env is null");
1128
1129     ca_mutex_lock(g_connectedDeviceListMutex);
1130     if (!g_connectedDeviceList)
1131     {
1132         OIC_LOG(ERROR, TAG, "g_connectedDeviceList is null");
1133         ca_mutex_unlock(g_connectedDeviceListMutex);
1134         return CA_STATUS_FAILED;
1135     }
1136
1137     uint32_t length = u_arraylist_length(g_connectedDeviceList);
1138     for (uint32_t index = 0; index < length; index++)
1139     {
1140         jobject jarrayObj = (jobject) u_arraylist_get(g_connectedDeviceList, index);
1141         if (!jarrayObj)
1142         {
1143             OIC_LOG_V(ERROR, TAG, "object[%d] is null", index);
1144             continue;
1145         }
1146
1147         // disconnect for device obj
1148         CAResult_t res = CALEServerDisconnect(env, jarrayObj);
1149         if (CA_STATUS_OK != res)
1150         {
1151             OIC_LOG_V(ERROR, TAG, "Disconnect for this device[%d] has failed", index);
1152             continue;
1153         }
1154     }
1155
1156     ca_mutex_unlock(g_connectedDeviceListMutex);
1157     OIC_LOG(DEBUG, TAG, "OUT - CALEServerDisconnectAllDevices");
1158     return CA_STATUS_OK;
1159 }
1160
1161 CAResult_t CALEServerDisconnect(JNIEnv *env, jobject bluetoothDevice)
1162 {
1163     OIC_LOG(DEBUG, TAG, "IN - CALEServerDisconnect");
1164     VERIFY_NON_NULL(env, TAG, "env is null");
1165     VERIFY_NON_NULL(bluetoothDevice, TAG, "bluetoothDevice is null");
1166
1167     if (!CALEIsEnableBTAdapter(env))
1168     {
1169         OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1170         return CA_ADAPTER_NOT_ENABLED;
1171     }
1172
1173     jclass jni_cid_bluetoothGattServer = (*env)->FindClass(env,
1174                                                            "android/bluetooth/BluetoothGattServer");
1175     if (!jni_cid_bluetoothGattServer)
1176     {
1177         OIC_LOG(ERROR, TAG, "jni_cid_bluetoothGattServer is null");
1178         return CA_STATUS_FAILED;
1179     }
1180
1181     jmethodID jni_mid_cancelConnection = (*env)->GetMethodID(env, jni_cid_bluetoothGattServer,
1182                                                              "cancelConnection",
1183                                                              "(Landroid/bluetooth/BluetoothDevice;)"
1184                                                              "V");
1185     if (!jni_mid_cancelConnection)
1186     {
1187         OIC_LOG(ERROR, TAG, "jni_mid_cancelConnection is null");
1188         return CA_STATUS_FAILED;
1189     }
1190
1191     (*env)->CallVoidMethod(env, g_bluetoothGattServer, jni_mid_cancelConnection, bluetoothDevice);
1192
1193     if ((*env)->ExceptionCheck(env))
1194     {
1195         OIC_LOG(ERROR, TAG, "cancelConnection has failed");
1196         (*env)->ExceptionDescribe(env);
1197         (*env)->ExceptionClear(env);
1198         return CA_STATUS_FAILED;
1199     }
1200
1201     OIC_LOG(DEBUG, TAG, "OUT - CALEServerDisconnect");
1202     return CA_STATUS_OK;
1203 }
1204
1205 CAResult_t CALEServerGattClose(JNIEnv *env, jobject bluetoothGattServer)
1206 {
1207     // GATT CLOSE
1208     OIC_LOG(DEBUG, TAG, "GattServer Close");
1209     VERIFY_NON_NULL(bluetoothGattServer, TAG, "bluetoothGattServer is null");
1210     VERIFY_NON_NULL(env, TAG, "env is null");
1211
1212     // get BluetoothGatt class
1213     OIC_LOG(DEBUG, TAG, "get BluetoothGatt class");
1214     jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, "android/bluetooth/BluetoothGattServer");
1215     if (!jni_cid_BluetoothGatt)
1216     {
1217         OIC_LOG(ERROR, TAG, "jni_cid_BluetoothGatt is null");
1218         return CA_STATUS_FAILED;
1219     }
1220
1221     jmethodID jni_mid_closeGatt = (*env)->GetMethodID(env, jni_cid_BluetoothGatt, "close", "()V");
1222     if (!jni_mid_closeGatt)
1223     {
1224         OIC_LOG(ERROR, TAG, "jni_mid_closeGatt is null");
1225         return CA_STATUS_OK;
1226     }
1227
1228     // call disconnect gatt method
1229     OIC_LOG(DEBUG, TAG, "request to close GATT");
1230     (*env)->CallVoidMethod(env, bluetoothGattServer, jni_mid_closeGatt);
1231
1232     if ((*env)->ExceptionCheck(env))
1233     {
1234         OIC_LOG(ERROR, TAG, "closeGATT has failed");
1235         (*env)->ExceptionDescribe(env);
1236         (*env)->ExceptionClear(env);
1237         return CA_STATUS_FAILED;
1238     }
1239
1240     return CA_STATUS_OK;
1241 }
1242
1243 CAResult_t CALEServerSend(JNIEnv *env, jobject bluetoothDevice, jbyteArray responseData)
1244 {
1245     OIC_LOG(DEBUG, TAG, "IN - CALEServerSend");
1246     VERIFY_NON_NULL(env, TAG, "env is null");
1247     VERIFY_NON_NULL(bluetoothDevice, TAG, "bluetoothDevice is null");
1248     VERIFY_NON_NULL(responseData, TAG, "responseData is null");
1249
1250     if (!CALEIsEnableBTAdapter(env))
1251     {
1252         OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
1253         return CA_ADAPTER_NOT_ENABLED;
1254     }
1255
1256     jobject responseChar = CALEServerSetResponseData(env, responseData);
1257     if (!responseChar)
1258     {
1259         OIC_LOG(ERROR, TAG, "responseChar is null");
1260         return CA_STATUS_FAILED;
1261     }
1262
1263     CAResult_t result = CALEServerSendResponseData(env, bluetoothDevice, responseChar);
1264     if (CA_STATUS_OK != result)
1265     {
1266         OIC_LOG(ERROR, TAG, "Fail to send response data");
1267         return result;
1268     }
1269
1270     OIC_LOG(DEBUG, TAG, "OUT - CALEServerSend");
1271     return result;
1272 }
1273
1274 CAResult_t CALEServerInitialize(ca_thread_pool_t handle)
1275 {
1276     OIC_LOG(DEBUG, TAG, "IN - CALEServerInitialize");
1277
1278     CALeServerJniInit();
1279
1280     if (!g_jvm)
1281     {
1282         OIC_LOG(ERROR, TAG, "g_jvm is null");
1283         return CA_STATUS_FAILED;
1284     }
1285
1286     bool isAttached = false;
1287     JNIEnv* env;
1288     jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1289     if (JNI_OK != res)
1290     {
1291         OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
1292         res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1293
1294         if (JNI_OK != res)
1295         {
1296             OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1297             return CA_STATUS_FAILED;
1298         }
1299         isAttached = true;
1300     }
1301
1302     CAResult_t ret = CALECheckPlatformVersion(env, 21);
1303     if (CA_STATUS_OK != ret)
1304     {
1305         OIC_LOG(ERROR, TAG, "it is not supported");
1306
1307         if (isAttached)
1308         {
1309             (*g_jvm)->DetachCurrentThread(g_jvm);
1310         }
1311         return ret;
1312     }
1313
1314     g_threadPoolHandle = handle;
1315
1316     ret = CALEServerInitMutexVaraibles();
1317     if (CA_STATUS_OK != ret)
1318     {
1319         OIC_LOG(ERROR, TAG, "CALEServerInitMutexVaraibles has failed");
1320
1321         if (isAttached)
1322         {
1323             (*g_jvm)->DetachCurrentThread(g_jvm);
1324         }
1325         return CA_STATUS_FAILED;
1326     }
1327
1328     CALEServerJNISetContext();
1329     CALEServerCreateCachedDeviceList();
1330
1331     ret = CALEServerCreateJniInterfaceObject();
1332     if (CA_STATUS_OK != ret)
1333     {
1334         OIC_LOG(ERROR, TAG, "CALEServerCreateJniInterfaceObject has failed");
1335
1336         if (isAttached)
1337         {
1338             (*g_jvm)->DetachCurrentThread(g_jvm);
1339         }
1340         return CA_STATUS_FAILED;
1341     }
1342
1343     if (isAttached)
1344     {
1345         (*g_jvm)->DetachCurrentThread(g_jvm);
1346     }
1347
1348     g_isInitializedServer = true;
1349     OIC_LOG(DEBUG, TAG, "OUT - CALEServerInitialize");
1350     return CA_STATUS_OK;
1351 }
1352
1353 void CALEServerTerminate()
1354 {
1355     OIC_LOG(DEBUG, TAG, "IN - CALEServerTerminate");
1356
1357     if (!g_jvm)
1358     {
1359         OIC_LOG(ERROR, TAG, "g_jvm is null");
1360         return;
1361     }
1362
1363     bool isAttached = false;
1364     JNIEnv* env;
1365     jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1366     if (JNI_OK != res)
1367     {
1368         OIC_LOG(ERROR, TAG, "Could not get JNIEnv pointer");
1369         res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1370
1371         if (JNI_OK != res)
1372         {
1373             OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1374             return;
1375         }
1376         isAttached = true;
1377     }
1378
1379     CAResult_t ret = CALEServerStopMulticastServer(0);
1380     if (CA_STATUS_OK != ret)
1381     {
1382         OIC_LOG(ERROR, TAG, "CALEServerStopMulticastServer has failed");
1383     }
1384
1385     ret = CALEServerDisconnectAllDevices(env);
1386     if (CA_STATUS_OK != ret)
1387     {
1388         OIC_LOG(ERROR, TAG, "CALEServerDisconnectAllDevices has failed");
1389     }
1390
1391     ret = CALEServerRemoveAllDevices(env);
1392     if (CA_STATUS_OK != ret)
1393     {
1394         OIC_LOG(ERROR, TAG, "CALEServerRemoveAllDevices has failed");
1395     }
1396
1397     if (g_leAdvertiseCallback)
1398     {
1399         (*env)->DeleteGlobalRef(env, g_leAdvertiseCallback);
1400     }
1401
1402     if (g_bluetoothGattServer)
1403     {
1404         (*env)->DeleteGlobalRef(env, g_bluetoothGattServer);
1405     }
1406
1407     if (g_bluetoothGattServerCallback)
1408     {
1409         (*env)->DeleteGlobalRef(env, g_bluetoothGattServerCallback);
1410     }
1411
1412     CALEServerTerminateMutexVaraibles();
1413     CALEServerTerminateConditionVaraibles();
1414
1415     g_isStartServer = false;
1416     g_isInitializedServer = false;
1417
1418     if (isAttached)
1419     {
1420         (*g_jvm)->DetachCurrentThread(g_jvm);
1421     }
1422
1423     OIC_LOG(DEBUG, TAG, "OUT - CALEServerTerminate");
1424 }
1425
1426 CAResult_t CALEServerSendUnicastMessage(const char* address, const char* data, uint32_t dataLen)
1427 {
1428     OIC_LOG_V(DEBUG, TAG, "IN - CALEServerSendUnicastMessage(%s, %s)", address, data);
1429     VERIFY_NON_NULL(address, TAG, "address is null");
1430     VERIFY_NON_NULL(data, TAG, "data is null");
1431
1432     if (!g_jvm)
1433     {
1434         OIC_LOG(ERROR, TAG, "g_jvm is null");
1435         return CA_STATUS_FAILED;
1436     }
1437
1438     bool isAttached = false;
1439     JNIEnv* env;
1440     jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1441     if (JNI_OK != res)
1442     {
1443         OIC_LOG(ERROR, TAG, "Could not get JNIEnv pointer");
1444         res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1445
1446         if (JNI_OK != res)
1447         {
1448             OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1449             return CA_STATUS_FAILED;
1450         }
1451         isAttached = true;
1452     }
1453
1454     CAResult_t ret = CALEServerSendUnicastMessageImpl(env, address, data, dataLen);
1455     if (CA_STATUS_OK != ret)
1456     {
1457         OIC_LOG(ERROR, TAG, "CALEServerSendUnicastMessageImpl has failed");
1458     }
1459
1460     if (isAttached)
1461     {
1462         (*g_jvm)->DetachCurrentThread(g_jvm);
1463     }
1464
1465     OIC_LOG(DEBUG, TAG, "OUT - CALEServerSendUnicastMessage");
1466     return ret;
1467 }
1468
1469 CAResult_t CALEServerSendMulticastMessage(const char* data, uint32_t dataLen)
1470 {
1471     OIC_LOG_V(DEBUG, TAG, "IN - CALEServerSendMulticastMessage(%s)", data);
1472     VERIFY_NON_NULL(data, TAG, "data is null");
1473
1474     if (!g_jvm)
1475     {
1476         OIC_LOG(ERROR, TAG, "g_jvm is null");
1477         return CA_STATUS_FAILED;
1478     }
1479
1480     bool isAttached = false;
1481     JNIEnv* env;
1482     jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1483     if (JNI_OK != res)
1484     {
1485         OIC_LOG(ERROR, TAG, "Could not get JNIEnv pointer");
1486         res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1487
1488         if (JNI_OK != res)
1489         {
1490             OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1491             return CA_STATUS_FAILED;
1492         }
1493         isAttached = true;
1494     }
1495
1496     CAResult_t ret = CALEServerSendMulticastMessageImpl(env, data, dataLen);
1497     if (CA_STATUS_OK != ret)
1498     {
1499         OIC_LOG(ERROR, TAG, "CALEServerSendMulticastMessageImpl has failed");
1500     }
1501
1502     if (isAttached)
1503     {
1504         (*g_jvm)->DetachCurrentThread(g_jvm);
1505     }
1506
1507     OIC_LOG(DEBUG, TAG, "OUT - CALEServerSendMulticastMessage");
1508     return ret;
1509 }
1510
1511 CAResult_t CALEServerStartMulticastServer()
1512 {
1513     OIC_LOG(DEBUG, TAG, "IN - CALEServerStartMulticastServer");
1514
1515     if (!g_isInitializedServer)
1516     {
1517         OIC_LOG(INFO, TAG, "server is not initialized");
1518         return CA_STATUS_FAILED;
1519     }
1520
1521     if (g_isStartServer)
1522     {
1523         OIC_LOG(INFO, TAG, "server is already started..it will be skipped");
1524         return CA_STATUS_FAILED;
1525     }
1526
1527     if (!g_jvm)
1528     {
1529         OIC_LOG(ERROR, TAG, "g_jvm is null");
1530         return CA_STATUS_FAILED;
1531     }
1532
1533     bool isAttached = false;
1534     JNIEnv* env;
1535     jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1536     if (JNI_OK != res)
1537     {
1538         OIC_LOG(ERROR, TAG, "Could not get JNIEnv pointer");
1539         res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1540
1541         if (JNI_OK != res)
1542         {
1543             OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1544             return CA_STATUS_FAILED;
1545         }
1546         isAttached = true;
1547     }
1548
1549     g_isStartServer = true;
1550
1551     // start gatt server
1552     CAResult_t ret = CALEServerStartGattServer(env, g_bluetoothGattServerCallback);
1553     if (CA_STATUS_OK != ret)
1554     {
1555         OIC_LOG(ERROR, TAG, "Fail to start gatt server");
1556         return ret;
1557     }
1558
1559     // start advertise
1560     ret = CALEServerStartAdvertise(env, g_leAdvertiseCallback);
1561     if (CA_STATUS_OK != ret)
1562     {
1563         OIC_LOG(ERROR, TAG, "CALEServerStartAdvertise has failed");
1564     }
1565
1566     if (isAttached)
1567     {
1568         (*g_jvm)->DetachCurrentThread(g_jvm);
1569     }
1570
1571     OIC_LOG(DEBUG, TAG, "OUT - CALEServerStartMulticastServer");
1572     return ret;
1573 }
1574
1575 CAResult_t CALEServerStopMulticastServer()
1576 {
1577     OIC_LOG(DEBUG, TAG, "IN - CALEServerStopMulticastServer");
1578
1579     if (false == g_isStartServer)
1580     {
1581         OIC_LOG(INFO, TAG, "server is already stopped..it will be skipped");
1582         return CA_STATUS_FAILED;
1583     }
1584
1585     if (!g_jvm)
1586     {
1587         OIC_LOG(ERROR, TAG, "g_jvm is null");
1588         return CA_STATUS_FAILED;
1589     }
1590
1591     bool isAttached = false;
1592     JNIEnv* env;
1593     jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
1594     if (JNI_OK != res)
1595     {
1596         OIC_LOG(ERROR, TAG, "Could not get JNIEnv pointer");
1597         res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
1598
1599         if (JNI_OK != res)
1600         {
1601             OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
1602             return CA_STATUS_FAILED;
1603         }
1604         isAttached = true;
1605     }
1606
1607     CAResult_t ret = CALEServerStopAdvertise(env, g_leAdvertiseCallback);
1608     if (CA_STATUS_OK != ret)
1609     {
1610         OIC_LOG(ERROR, TAG, "CALEServerStopAdvertise has failed");
1611     }
1612
1613     g_isStartServer = false;
1614
1615     if (isAttached)
1616     {
1617         (*g_jvm)->DetachCurrentThread(g_jvm);
1618     }
1619
1620     OIC_LOG(DEBUG, TAG, "OUT - CALEServerStopMulticastServer");
1621     return ret;
1622 }
1623
1624 void CALEServerSetCallback(CAPacketReceiveCallback callback)
1625 {
1626     OIC_LOG(DEBUG, TAG, "CALEServerSetCallback");
1627     g_packetReceiveCallback = callback;
1628 }
1629
1630 CAResult_t CALEServerSendUnicastMessageImpl(JNIEnv *env, const char* address, const char* data,
1631                                             uint32_t dataLen)
1632 {
1633     OIC_LOG_V(DEBUG, TAG, "IN - CALEServerSendUnicastMessageImpl, address: %s, data: %s",
1634             address, data);
1635     VERIFY_NON_NULL(env, TAG, "env is null");
1636     VERIFY_NON_NULL(address, TAG, "address is null");
1637     VERIFY_NON_NULL(data, TAG, "data is null");
1638
1639     if (!g_connectedDeviceList)
1640     {
1641         OIC_LOG(ERROR, TAG, "g_connectedDeviceList is null");
1642         return CA_STATUS_FAILED;
1643     }
1644
1645     jobject jni_obj_bluetoothDevice = NULL;
1646     uint32_t length = u_arraylist_length(g_connectedDeviceList);
1647     for (uint32_t index = 0; index < length; index++)
1648     {
1649         OIC_LOG(DEBUG, TAG, "check device address");
1650         jobject jarrayObj = (jobject) u_arraylist_get(g_connectedDeviceList, index);
1651         if (!jarrayObj)
1652         {
1653             OIC_LOG(ERROR, TAG, "jarrayObj is null");
1654             return CA_STATUS_FAILED;
1655         }
1656
1657         jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
1658         if (!jni_setAddress)
1659         {
1660             OIC_LOG(ERROR, TAG, "jni_setAddress is null");
1661             return CA_STATUS_FAILED;
1662         }
1663         const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
1664         if (!setAddress)
1665         {
1666             OIC_LOG(ERROR, TAG, "setAddress is null");
1667             return CA_STATUS_FAILED;
1668         }
1669
1670         OIC_LOG_V(DEBUG, TAG, "setAddress : %s", setAddress);
1671         OIC_LOG_V(DEBUG, TAG, "address : %s", address);
1672
1673         if (!strcmp(setAddress, address))
1674         {
1675             OIC_LOG(DEBUG, TAG, "found the device");
1676             jni_obj_bluetoothDevice = jarrayObj;
1677             (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
1678             break;
1679         }
1680         (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
1681     }
1682
1683     if (jni_obj_bluetoothDevice)
1684     {
1685         jbyteArray jni_bytearr_data = (*env)->NewByteArray(env, dataLen);
1686         (*env)->SetByteArrayRegion(env, jni_bytearr_data, 0, dataLen, (jbyte*) data);
1687
1688         CAResult_t res = CALEServerSend(env, jni_obj_bluetoothDevice, jni_bytearr_data);
1689         if (CA_STATUS_OK != res)
1690         {
1691             OIC_LOG(ERROR, TAG, "send has failed");
1692             return CA_SEND_FAILED;
1693         }
1694     }
1695     else
1696     {
1697         OIC_LOG(ERROR, TAG, "There are no device to send in the list");
1698         return CA_STATUS_FAILED;
1699     }
1700
1701     OIC_LOG(DEBUG, TAG, "OUT - CALEServerSendUnicastMessageImpl");
1702     return CA_STATUS_OK;
1703 }
1704
1705 CAResult_t CALEServerSendMulticastMessageImpl(JNIEnv *env, const char *data, uint32_t dataLen)
1706 {
1707     OIC_LOG_V(DEBUG, TAG, "IN - CALEServerSendMulticastMessageImpl, send to, data: %s", data);
1708     VERIFY_NON_NULL(env, TAG, "env is null");
1709     VERIFY_NON_NULL(data, TAG, "data is null");
1710
1711     if (!g_connectedDeviceList)
1712     {
1713         OIC_LOG(ERROR, TAG, "g_connectedDeviceList is null");
1714         return CA_STATUS_FAILED;
1715     }
1716
1717     uint32_t length = u_arraylist_length(g_connectedDeviceList);
1718     for (uint32_t index = 0; index < length; index++)
1719     {
1720         jobject jarrayObj = (jobject) u_arraylist_get(g_connectedDeviceList, index);
1721         if (!jarrayObj)
1722         {
1723             OIC_LOG(ERROR, TAG, "jarrayObj is null");
1724             return CA_STATUS_FAILED;
1725         }
1726
1727         // send data for all device
1728         jbyteArray jni_bytearr_data = (*env)->NewByteArray(env, dataLen);
1729         (*env)->SetByteArrayRegion(env, jni_bytearr_data, 0, dataLen, (jbyte*) data);
1730         CAResult_t res = CALEServerSend(env, jarrayObj, jni_bytearr_data);
1731         if (CA_STATUS_OK != res)
1732         {
1733             OIC_LOG(ERROR, TAG, "send has failed");
1734             return CA_SEND_FAILED;
1735         }
1736     }
1737
1738     OIC_LOG(DEBUG, TAG, "OUT - CALEServerSendMulticastMessageImpl");
1739     return CA_STATUS_OK;
1740 }
1741
1742 void CALEServerCreateCachedDeviceList()
1743 {
1744     OIC_LOG(DEBUG, TAG, "IN - CALEServerCreateCachedDeviceList");
1745
1746     ca_mutex_lock(g_connectedDeviceListMutex);
1747     // create new object array
1748     if (!g_connectedDeviceList)
1749     {
1750         OIC_LOG(DEBUG, TAG, "Create device list");
1751         g_connectedDeviceList = u_arraylist_create();
1752     }
1753     ca_mutex_unlock(g_connectedDeviceListMutex);
1754
1755     OIC_LOG(DEBUG, TAG, "OUT - CALEServerCreateCachedDeviceList");
1756 }
1757
1758 bool CALEServerIsDeviceInList(JNIEnv *env, const char* remoteAddress)
1759 {
1760     OIC_LOG(DEBUG, TAG, "IN - CALEServerIsDeviceInList");
1761     VERIFY_NON_NULL_RET(env, TAG, "env is null", false);
1762     VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", false);
1763
1764     if (!g_connectedDeviceList)
1765     {
1766         OIC_LOG(ERROR, TAG, "list is null");
1767         return false;
1768     }
1769
1770     uint32_t length = u_arraylist_length(g_connectedDeviceList);
1771     for (uint32_t index = 0; index < length; index++)
1772     {
1773         jobject jarrayObj = (jobject) u_arraylist_get(g_connectedDeviceList, index);
1774
1775         if (!jarrayObj)
1776         {
1777             OIC_LOG(ERROR, TAG, "jarrayObj is null");
1778             return false;
1779         }
1780
1781         jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
1782         if (!jni_setAddress)
1783         {
1784             OIC_LOG(ERROR, TAG, "jni_setAddress is null");
1785             return false;
1786         }
1787
1788         const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
1789         if (!setAddress)
1790         {
1791             OIC_LOG(ERROR, TAG, "setAddress is null");
1792             return false;
1793         }
1794
1795         if (!strcmp(remoteAddress, setAddress))
1796         {
1797             OIC_LOG(ERROR, TAG, "the device is already set");
1798             (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
1799             return true;
1800         }
1801         else
1802         {
1803             (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
1804             continue;
1805         }
1806     }
1807
1808     OIC_LOG(DEBUG, TAG, "there are no device in the list");
1809     OIC_LOG(DEBUG, TAG, "OUT - CALEServerCreateCachedDeviceList");
1810     return false;
1811 }
1812
1813 CAResult_t CALEServerAddDeviceToList(JNIEnv *env, jobject device)
1814 {
1815     OIC_LOG(DEBUG, TAG, "IN - CALEServerAddDeviceToList");
1816     VERIFY_NON_NULL(device, TAG, "device is null");
1817     VERIFY_NON_NULL(env, TAG, "env is null");
1818
1819     ca_mutex_lock(g_connectedDeviceListMutex);
1820
1821     if (!g_connectedDeviceList)
1822     {
1823         OIC_LOG(ERROR, TAG, "list is null");
1824         ca_mutex_unlock(g_connectedDeviceListMutex);
1825         return CA_STATUS_FAILED;
1826     }
1827
1828     jstring jni_remoteAddress = CALEGetAddressFromBTDevice(env, device);
1829     if (!jni_remoteAddress)
1830     {
1831         OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
1832         ca_mutex_unlock(g_connectedDeviceListMutex);
1833         return CA_STATUS_FAILED;
1834     }
1835
1836     const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
1837     if (!remoteAddress)
1838     {
1839         OIC_LOG(ERROR, TAG, "remoteAddress is null");
1840         ca_mutex_unlock(g_connectedDeviceListMutex);
1841         return CA_STATUS_FAILED;
1842     }
1843
1844     if (false == CALEServerIsDeviceInList(env, remoteAddress))
1845     {
1846         jobject jni_obj_device = (*env)->NewGlobalRef(env, device);
1847         u_arraylist_add(g_connectedDeviceList, jni_obj_device);
1848         OIC_LOG_V(DEBUG, TAG, "Set the object to ArrayList as Element : %s", remoteAddress);
1849     }
1850
1851     (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
1852     ca_mutex_unlock(g_connectedDeviceListMutex);
1853     OIC_LOG(DEBUG, TAG, "OUT - CALEServerAddDeviceToList");
1854     return CA_STATUS_OK;
1855 }
1856
1857 CAResult_t CALEServerRemoveAllDevices(JNIEnv *env)
1858 {
1859     OIC_LOG(DEBUG, TAG, "IN - CALEServerRemoveAllDevices");
1860     VERIFY_NON_NULL(env, TAG, "env is null");
1861
1862     ca_mutex_lock(g_connectedDeviceListMutex);
1863     if (!g_connectedDeviceList)
1864     {
1865         OIC_LOG(ERROR, TAG, "g_connectedDeviceList is null");
1866         ca_mutex_unlock(g_connectedDeviceListMutex);
1867         return CA_STATUS_FAILED;
1868     }
1869
1870     uint32_t length = u_arraylist_length(g_connectedDeviceList);
1871     for (uint32_t index = 0; index < length; index++)
1872     {
1873         jobject jarrayObj = (jobject) u_arraylist_get(g_connectedDeviceList, index);
1874         if (jarrayObj)
1875         {
1876             (*env)->DeleteGlobalRef(env, jarrayObj);
1877         }
1878     }
1879
1880     OICFree(g_connectedDeviceList);
1881     g_connectedDeviceList = NULL;
1882     ca_mutex_unlock(g_connectedDeviceListMutex);
1883
1884     OIC_LOG(DEBUG, TAG, "OUT - CALEServerRemoveAllDevices");
1885     return CA_STATUS_OK;
1886 }
1887
1888 CAResult_t CALEServerRemoveDevice(JNIEnv *env, jstring address)
1889 {
1890     OIC_LOG(DEBUG, TAG, "IN CALEServerRemoveDevice");
1891     VERIFY_NON_NULL(env, TAG, "env is null");
1892     VERIFY_NON_NULL(address, TAG, "address is null");
1893
1894     ca_mutex_lock(g_connectedDeviceListMutex);
1895     if (!g_connectedDeviceList)
1896     {
1897         OIC_LOG(ERROR, TAG, "no deviceList");
1898         ca_mutex_unlock(g_connectedDeviceListMutex);
1899         return CA_STATUS_FAILED;
1900     }
1901
1902     uint32_t length = u_arraylist_length(g_connectedDeviceList);
1903     for (uint32_t index = 0; index < length; index++)
1904     {
1905         jobject jarrayObj = (jobject) u_arraylist_get(g_connectedDeviceList, index);
1906
1907         if (jarrayObj)
1908         {
1909             jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
1910             if (!jni_setAddress)
1911             {
1912                 OIC_LOG(ERROR, TAG, "wrong device address");
1913                 continue;
1914             }
1915             const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
1916             if (!setAddress)
1917             {
1918                 OIC_LOG(ERROR, TAG, "setAddress is null");
1919                 continue;
1920             }
1921
1922             const char* remoteAddress = (*env)->GetStringUTFChars(env, address, NULL);
1923             if (!remoteAddress)
1924             {
1925                 OIC_LOG(ERROR, TAG, "remoteAddress is null");
1926                 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
1927                 continue;
1928             }
1929
1930             if (!strcmp(setAddress, remoteAddress))
1931             {
1932                 OIC_LOG_V(DEBUG, TAG, "device address : %s", remoteAddress);
1933
1934                 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
1935                 (*env)->ReleaseStringUTFChars(env, address, remoteAddress);
1936                 (*env)->DeleteGlobalRef(env, jarrayObj);
1937
1938                 CAResult_t res = CALEServerReorderinglist(index);
1939                 if (CA_STATUS_OK != res)
1940                 {
1941                     OIC_LOG(ERROR, TAG, "CALEServerReorderinglist has failed");
1942                     ca_mutex_unlock(g_connectedDeviceListMutex);
1943                     return res;
1944                 }
1945                 ca_mutex_unlock(g_connectedDeviceListMutex);
1946                 return CA_STATUS_OK;
1947             }
1948             (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
1949             (*env)->ReleaseStringUTFChars(env, address, remoteAddress);
1950         }
1951     }
1952
1953     ca_mutex_unlock(g_connectedDeviceListMutex);
1954
1955     OIC_LOG(DEBUG, TAG, "there are no device in the device list");
1956
1957     OIC_LOG(DEBUG, TAG, "IN CALEServerRemoveDevice");
1958     return CA_STATUS_FAILED;
1959 }
1960
1961 CAResult_t CALEServerReorderinglist(uint32_t index)
1962 {
1963     if (!g_connectedDeviceList)
1964     {
1965         OIC_LOG(ERROR, TAG, "g_connectedDeviceList is null");
1966         return CA_STATUS_FAILED;
1967     }
1968
1969     if (index >= g_connectedDeviceList->length)
1970     {
1971         OIC_LOG(ERROR, TAG, "index is not available");
1972         return CA_STATUS_FAILED;
1973     }
1974
1975     if (index < g_connectedDeviceList->length - 1)
1976     {
1977         memmove(&g_connectedDeviceList->data[index], &g_connectedDeviceList->data[index + 1],
1978                 (g_connectedDeviceList->length - index - 1) * sizeof(void *));
1979     }
1980
1981     g_connectedDeviceList->size--;
1982     g_connectedDeviceList->length--;
1983
1984     return CA_STATUS_OK;
1985 }
1986
1987 JNIEXPORT void JNICALL
1988 Java_org_iotivity_ca_CaLeServerInterface_caLeRegisterGattServerCallback(JNIEnv *env, jobject obj,
1989                                                                          jobject callback)
1990 {
1991     OIC_LOG(DEBUG, TAG, "CaLeServerInterface - Register Le Gatt Server Callback");
1992     VERIFY_NON_NULL_VOID(env, TAG, "env is null");
1993     VERIFY_NON_NULL_VOID(callback, TAG, "callback is null");
1994
1995     g_bluetoothGattServerCallback = (*env)->NewGlobalRef(env, callback);
1996 }
1997
1998 JNIEXPORT void JNICALL
1999 Java_org_iotivity_ca_CaLeServerInterface_caLeRegisterBluetoothLeAdvertiseCallback(JNIEnv *env,
2000                                                                                   jobject obj,
2001                                                                                   jobject callback)
2002 {
2003     OIC_LOG(DEBUG, TAG, "CaLeServerInterface - Register Le Advertise Callback");
2004     VERIFY_NON_NULL_VOID(env, TAG, "env is null");
2005     VERIFY_NON_NULL_VOID(callback, TAG, "callback is null");
2006
2007     g_leAdvertiseCallback = (*env)->NewGlobalRef(env, callback);
2008 }
2009
2010 JNIEXPORT void JNICALL
2011 Java_org_iotivity_ca_CaLeServerInterface_caLeGattServerConnectionStateChangeCallback(
2012         JNIEnv *env, jobject obj, jobject device, jint status, jint newState)
2013 {
2014     OIC_LOG(DEBUG, TAG, "CaLeServerInterface - Gatt Server ConnectionStateChange Callback");
2015     OIC_LOG_V(DEBUG, TAG, "New connection State: %d", newState);
2016
2017     VERIFY_NON_NULL_VOID(env, TAG, "env is null");
2018     VERIFY_NON_NULL_VOID(device, TAG, "device is null");
2019
2020     jclass jni_cid_bluetoothProfile = (*env)->FindClass(env, "android/bluetooth/BluetoothProfile");
2021     if (!jni_cid_bluetoothProfile)
2022     {
2023         OIC_LOG(ERROR, TAG, "jni_cid_bluetoothProfile is null");
2024         return;
2025     }
2026
2027     jfieldID jni_fid_state_connected = (*env)->GetStaticFieldID(env, jni_cid_bluetoothProfile,
2028                                                                 "STATE_CONNECTED", "I");
2029     if(!jni_fid_state_connected)
2030     {
2031         OIC_LOG(ERROR, TAG, "jni_fid_state_connected is null");
2032         return;
2033     }
2034
2035     jfieldID jni_fid_state_disconnected = (*env)->GetStaticFieldID(env, jni_cid_bluetoothProfile,
2036                                                                    "STATE_DISCONNECTED", "I");
2037     if(!jni_fid_state_disconnected)
2038     {
2039         OIC_LOG(ERROR, TAG, "jni_fid_state_disconnected is null");
2040         return;
2041     }
2042
2043     // STATE_CONNECTED
2044     jint jni_int_state_connected = (*env)->GetStaticIntField(env, jni_cid_bluetoothProfile,
2045                                                              jni_fid_state_connected);
2046
2047     // STATE_DISCONNECTED
2048     jint jni_int_state_disconnected = (*env)->GetStaticIntField(env, jni_cid_bluetoothProfile,
2049                                                                 jni_fid_state_disconnected);
2050
2051     if (newState == jni_int_state_connected)
2052     {
2053
2054         OIC_LOG(DEBUG, TAG, "LE CONNECTED");
2055
2056         jstring jni_remoteAddress = CALEGetAddressFromBTDevice(env, device);
2057         if (!jni_remoteAddress)
2058         {
2059             OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
2060             return;
2061         }
2062
2063         const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
2064         if (!remoteAddress)
2065         {
2066             OIC_LOG(ERROR, TAG, "remoteAddress is null");
2067             return;
2068         }
2069
2070         if (false == CALEServerIsDeviceInList(env, remoteAddress))
2071         {
2072             OIC_LOG(DEBUG, TAG, "add connected device to cache");
2073             CALEServerAddDeviceToList(env, device);
2074         }
2075         (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
2076     }
2077     else if (newState == jni_int_state_disconnected)
2078     {
2079         OIC_LOG(DEBUG, TAG, "LE DISCONNECTED");
2080         CAResult_t res = CALEServerGattClose(env, g_bluetoothGattServer);
2081         if (CA_STATUS_OK != res)
2082         {
2083             OIC_LOG(ERROR, TAG, "CALEServerGattClose has failed");
2084         }
2085     }
2086     else
2087     {
2088         OIC_LOG_V(DEBUG, TAG, "LE Connection state is [newState : %d, status %d]", newState,
2089                 status);
2090     }
2091 }
2092
2093 JNIEXPORT void JNICALL
2094 Java_org_iotivity_ca_CaLeServerInterface_caLeGattServerServiceAddedCallback(JNIEnv *env,
2095                                                                              jobject obj,
2096                                                                              jint status,
2097                                                                              jobject gattService)
2098 {
2099     OIC_LOG_V(DEBUG, TAG, "CaLeServerInterface - Gatt Service Added Callback(%d)", status);
2100 }
2101
2102 JNIEXPORT void JNICALL
2103 Java_org_iotivity_ca_CaLeServerInterface_caLeGattServerCharacteristicReadRequestCallback(
2104         JNIEnv *env, jobject obj, jobject device, jint requestId, jint offset,
2105         jobject characteristic, jbyteArray data)
2106 {
2107     OIC_LOG(DEBUG, TAG, "CaLeServerInterface - Gatt Server Characteristic Read Request Callback");
2108     VERIFY_NON_NULL_VOID(env, TAG, "env is null");
2109     VERIFY_NON_NULL_VOID(device, TAG, "device is null");
2110
2111 #ifdef USE_PROPERTY_WRITE_RESPONSE
2112     CALEServerSendResponse(env, device, requestId, 0, offset, NULL);
2113 #endif
2114
2115 }
2116
2117 JNIEXPORT void JNICALL
2118 Java_org_iotivity_ca_CaLeServerInterface_caLeGattServerCharacteristicWriteRequestCallback(
2119         JNIEnv *env, jobject obj, jobject device, jint requestId, jobject characteristic,
2120         jbyteArray data, jboolean preparedWrite, jboolean responseNeeded, jint offset,
2121         jbyteArray value)
2122 {
2123     OIC_LOG(DEBUG, TAG, "CaLeServerInterface - Gatt Server Characteristic Write Request Callback");
2124     VERIFY_NON_NULL_VOID(env, TAG, "env is null");
2125     VERIFY_NON_NULL_VOID(device, TAG, "device is null");
2126     VERIFY_NON_NULL_VOID(value, TAG, "value is null");
2127     VERIFY_NON_NULL_VOID(data, TAG, "data is null");
2128
2129 #ifdef USE_PROPERTY_WRITE_RESPONSE
2130     CALEServerSendResponse(env, device, requestId, 0, offset, value);
2131 #endif
2132
2133     // get Byte Array and covert to char*
2134     jint length = (*env)->GetArrayLength(env, data);
2135
2136     jboolean isCopy;
2137     jbyte *jni_byte_requestData = (jbyte *) (*env)->GetByteArrayElements(env, data, &isCopy);
2138
2139     char* requestData = NULL;
2140     requestData = (char*) OICMalloc(sizeof(char) * length + 1);
2141     if (!requestData)
2142     {
2143         OIC_LOG(ERROR, TAG, "requestData is null");
2144         return;
2145     }
2146
2147     memcpy(requestData, (const char*) jni_byte_requestData, length);
2148     requestData[length] = '\0';
2149     (*env)->ReleaseByteArrayElements(env, data, jni_byte_requestData, JNI_ABORT);
2150
2151     jstring jni_address = CALEGetAddressFromBTDevice(env, device);
2152     if (!jni_address)
2153     {
2154         OIC_LOG(ERROR, TAG, "jni_address is null");
2155         OICFree(requestData);
2156         return;
2157     }
2158
2159     const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
2160     if (!address)
2161     {
2162         OIC_LOG(ERROR, TAG, "address is null");
2163         OICFree(requestData);
2164         return;
2165     }
2166
2167     OIC_LOG_V(DEBUG, TAG, "remote device address : %s, %s, %d", address, requestData, length);
2168
2169     ca_mutex_lock(g_bleClientBDAddressMutex);
2170     uint32_t sentLength = 0;
2171     g_CABLEServerDataReceivedCallback(address, OIC_GATT_SERVICE_UUID, requestData, length,
2172                                       &sentLength);
2173     ca_mutex_unlock(g_bleClientBDAddressMutex);
2174
2175     (*env)->ReleaseStringUTFChars(env, jni_address, address);
2176 }
2177
2178 JNIEXPORT void JNICALL
2179 Java_org_iotivity_ca_CaLeServerInterface_caLeGattServerDescriptorReadRequestCallback(
2180         JNIEnv *env, jobject obj, jobject device, jint requestId, jint offset, jobject descriptor)
2181 {
2182     OIC_LOG(DEBUG, TAG, "CaLeServerInterface_CALeGattServerDescriptorReadRequestCallback");
2183 }
2184
2185 JNIEXPORT void JNICALL
2186 Java_org_iotivity_ca_CaLeServerInterface_caLeGattServerDescriptorWriteRequestCallback(
2187         JNIEnv *env, jobject obj, jobject device, jint requestId, jobject descriptor,
2188         jboolean preparedWrite, jboolean responseNeeded, jint offset, jbyteArray value)
2189 {
2190     OIC_LOG(DEBUG, TAG, "CaLeServerInterface_CALeGattServerDescriptorWriteRequestCallback");
2191 }
2192
2193 JNIEXPORT void JNICALL
2194 Java_org_iotivity_ca_CaLeServerInterface_caLeGattServerExecuteWriteCallback(JNIEnv *env,
2195                                                                              jobject obj,
2196                                                                              jobject device,
2197                                                                              jint requestId,
2198                                                                              jboolean execute)
2199 {
2200     OIC_LOG(DEBUG, TAG, "CaLeServerInterface_CALeGattServerExecuteWriteCallback");
2201     VERIFY_NON_NULL_VOID(env, TAG, "env is null");
2202     VERIFY_NON_NULL_VOID(device, TAG, "device is null");
2203
2204 //    CALEServerSendResponse(env, device, requestId, 0, 0, NULL);
2205 }
2206
2207 JNIEXPORT void JNICALL
2208 Java_org_iotivity_ca_CaLeServerInterface_caLeGattServerNotificationSentCallback(JNIEnv *env,
2209                                                                                  jobject obj,
2210                                                                                  jobject device,
2211                                                                                  jint status)
2212 {
2213     OIC_LOG(DEBUG, TAG, "CaLeServerInterface - Gatt Server Notification Sent Callback");
2214 }
2215
2216 JNIEXPORT void JNICALL
2217 Java_org_iotivity_ca_CaLeServerInterface_caLeAdvertiseStartSuccessCallback(
2218         JNIEnv *env, jobject obj, jobject settingsInEffect)
2219 {
2220     OIC_LOG(DEBUG, TAG, "CaLeServerInterface - LE Advertise Start Success Callback");
2221 }
2222
2223 JNIEXPORT void JNICALL
2224 Java_org_iotivity_ca_CaLeServerInterface_caLeAdvertiseStartFailureCallback(JNIEnv *env,
2225                                                                             jobject obj,
2226                                                                             jint errorCode)
2227 {
2228     OIC_LOG_V(ERROR, TAG, "CaLeServerInterface - LE Advertise Start Failure Callback(%)",
2229               errorCode);
2230 }
2231
2232 /**
2233  * adapter common
2234  */
2235
2236 CAResult_t CAStartLEGattServer()
2237 {
2238     OIC_LOG(DEBUG, TAG, "IN");
2239
2240     CAResult_t ret = CALEServerInitMutexVaraibles();
2241     if (CA_STATUS_OK != ret)
2242     {
2243         OIC_LOG(ERROR, TAG, "CALEServerInitMutexVaraibles has failed!");
2244         CALEServerTerminateMutexVaraibles();
2245         return CA_SERVER_NOT_STARTED;
2246     }
2247
2248     ret = CALEServerInitConditionVaraibles();
2249     if (CA_STATUS_OK != ret)
2250     {
2251         OIC_LOG(ERROR, TAG, "CALEServerInitConditionVaraibles has failed!");
2252         CALEServerTerminateConditionVaraibles();
2253         return CA_SERVER_NOT_STARTED;
2254     }
2255
2256     // start gatt service
2257     CALEServerStartMulticastServer();
2258
2259     OIC_LOG(DEBUG, TAG, "OUT");
2260     return CA_STATUS_OK;
2261 }
2262
2263 CAResult_t CAStopLEGattServer()
2264 {
2265     OIC_LOG(DEBUG, TAG, "IN");
2266
2267     OIC_LOG(DEBUG, TAG, "OUT");
2268     return CA_STATUS_OK;
2269 }
2270
2271 void CATerminateLEGattServer()
2272 {
2273     OIC_LOG(DEBUG, TAG, "IN");
2274
2275     OIC_LOG(DEBUG, TAG, "Terminat Gatt Server");
2276     CALEServerTerminate();
2277
2278     OIC_LOG(DEBUG, TAG, "OUT");
2279 }
2280
2281 void CASetLEReqRespServerCallback(CABLEServerDataReceivedCallback callback)
2282 {
2283     OIC_LOG(DEBUG, TAG, "IN");
2284
2285     ca_mutex_lock(g_bleReqRespCbMutex);
2286     g_CABLEServerDataReceivedCallback = callback;
2287     ca_mutex_unlock(g_bleReqRespCbMutex);
2288
2289     OIC_LOG(DEBUG, TAG, "OUT");
2290 }
2291
2292 void CASetBLEServerErrorHandleCallback(CABLEErrorHandleCallback callback)
2293 {
2294     g_serverErrorCallback = callback;
2295 }
2296
2297 CAResult_t CAUpdateCharacteristicsToGattClient(const char* address, const char *charValue,
2298                                                const uint32_t charValueLen)
2299 {
2300     CAResult_t result = CA_SEND_FAILED;
2301     OIC_LOG(DEBUG, TAG, "IN");
2302     VERIFY_NON_NULL(address, TAG, "env is null");
2303     VERIFY_NON_NULL(charValue, TAG, "device is null");
2304
2305     if (address)
2306     {
2307         OIC_LOG(DEBUG, TAG, "CALEServerSendUnicastData");
2308         result = CALEServerSendUnicastMessage(address, charValue, charValueLen);
2309     }
2310
2311     OIC_LOG(DEBUG, TAG, "OUT");
2312
2313     return result;
2314 }
2315
2316 CAResult_t CAUpdateCharacteristicsToAllGattClients(const char *charValue,
2317                                                    uint32_t charValueLen)
2318 {
2319     OIC_LOG(DEBUG, TAG, "IN");
2320     VERIFY_NON_NULL(charValue, TAG, "device is null");
2321
2322     OIC_LOG(DEBUG, TAG, "CALEServerSendMulticastMessage");
2323     CAResult_t result = CALEServerSendMulticastMessage(charValue, charValueLen);
2324
2325     OIC_LOG(DEBUG, TAG, "OUT");
2326     return result;
2327 }
2328
2329 void CASetLEServerThreadPoolHandle(ca_thread_pool_t handle)
2330 {
2331     OIC_LOG(DEBUG, TAG, "IN");
2332
2333     CALEServerInitialize(handle);
2334
2335     OIC_LOG(DEBUG, TAG, "OUT");
2336 }
2337
2338 CAResult_t CALEServerInitMutexVaraibles()
2339 {
2340     OIC_LOG(DEBUG, TAG, "IN");
2341     if (NULL == g_bleReqRespCbMutex)
2342     {
2343         g_bleReqRespCbMutex = ca_mutex_new();
2344         if (NULL == g_bleReqRespCbMutex)
2345         {
2346             OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
2347             return CA_STATUS_FAILED;
2348         }
2349     }
2350
2351     if (NULL == g_bleClientBDAddressMutex)
2352     {
2353         g_bleClientBDAddressMutex = ca_mutex_new();
2354         if (NULL == g_bleClientBDAddressMutex)
2355         {
2356             OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
2357             return CA_STATUS_FAILED;
2358         }
2359     }
2360
2361     if (NULL == g_connectedDeviceListMutex)
2362     {
2363         g_connectedDeviceListMutex = ca_mutex_new();
2364         if (NULL == g_connectedDeviceListMutex)
2365         {
2366             OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
2367             return CA_STATUS_FAILED;
2368         }
2369     }
2370
2371     OIC_LOG(DEBUG, TAG, "OUT");
2372     return CA_STATUS_OK;
2373 }
2374
2375 CAResult_t CALEServerInitConditionVaraibles()
2376 {
2377     OIC_LOG(DEBUG, TAG, "this method is not supported");
2378     return CA_STATUS_OK;
2379 }
2380
2381 void CALEServerTerminateMutexVaraibles()
2382 {
2383     OIC_LOG(DEBUG, TAG, "IN");
2384
2385     ca_mutex_free(g_bleReqRespCbMutex);
2386     g_bleReqRespCbMutex = NULL;
2387
2388     ca_mutex_free(g_bleClientBDAddressMutex);
2389     g_bleClientBDAddressMutex = NULL;
2390
2391     ca_mutex_free(g_connectedDeviceListMutex);
2392     g_connectedDeviceListMutex = NULL;
2393
2394     OIC_LOG(DEBUG, TAG, "OUT");
2395 }
2396
2397 void CALEServerTerminateConditionVaraibles()
2398 {
2399     OIC_LOG(DEBUG, TAG, "this method is not supported");
2400 }