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