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