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