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