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