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