Fixed klockwork memory leaks and modified the logs
[platform/upstream/iotivity.git] / resource / csdk / connectivity / src / bt_le_adapter / android / caleserver.c
1 #include <jni.h>
2 #include <stdio.h>
3 #include <string.h>
4 #include <android/log.h>
5 #include "caleserver.h"
6 #include "caleutils.h"
7 #include "logger.h"
8 #include "oic_malloc.h"
9 #include "uthreadpool.h"
10 #include "uarraylist.h"
11 #include "com_iotivity_jar_CALeInterface.h"
12
13 #define TAG PCF("CA_LE_SERVER")
14
15 #define  LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
16 #define  LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)
17
18 /* Service UUID */
19 static const char *OIC_GATT_SERVICE_UUID = "713d0000-503e-4c75-ba94-3148f18d941e";
20 static const char *OIC_GATT_CHARACTERISTIC_RESPONSE_UUID = "713d0002-503e-4c75-ba94-3148f18d941e"; //read
21 static const char *OIC_GATT_CHARACTERISTIC_REQUEST_UUID = "713d0003-503e-4c75-ba94-3148f18d941e"; //write
22
23 static JavaVM *g_jvm;
24 static jobject gContext;
25 static jobject gBluetoothGattServer;
26 static jobject gBluetoothGattServerCallback;
27 static jobject gLeAdvertiseCallback;
28
29 static CAPacketReceiveCallback gPacketReceiveCallback = NULL;
30 static u_arraylist_t *gConnectedDeviceList = NULL;
31 static u_thread_pool_t gThreadPoolHandle = NULL;
32
33 static jboolean gIsStartServer;
34 static jboolean gIsSendingMulticastData;
35
36 //getting context
37 void CALEServerJNISetContext(JNIEnv *env, jobject context)
38 {
39     OIC_LOG_V(DEBUG, TAG, "CALEServerJNISetContext");
40
41     if(context == NULL)
42         OIC_LOG_V(DEBUG, TAG, "context is null");
43
44     gContext = (*env)->NewGlobalRef(env, context);
45 }
46
47 //getting jvm
48 void CALeServerJniInit(JNIEnv *env, JavaVM *jvm)
49 {
50     OIC_LOG_V(DEBUG, TAG, "CALeServerJniInit");
51     g_jvm = jvm;
52 }
53
54 jobject CANativeLEServerSetResponseData(JNIEnv *env, jbyteArray responseData)
55 {
56     if(!CALEIsEnableBTAdapter(env))
57     {
58         OIC_LOG(DEBUG, TAG, "[BLE][Native] BT adpater is not enable");
59         return NULL;
60     }
61
62     OIC_LOG_V(DEBUG, TAG, "CALEServerSetResponseData");
63
64     jclass jni_cid_bluetoothGattServer = (*env)->FindClass(env,
65             "android/bluetooth/BluetoothGattServer");
66
67     jclass jni_cid_bluetoothGattService = (*env)->FindClass(env,
68             "android/bluetooth/BluetoothGattService");
69
70     jclass jni_cid_bluetoothGattCharacteristic = (*env)->FindClass(env,
71             "android/bluetooth/BluetoothGattCharacteristic");
72
73     jmethodID jni_mid_getService = (*env)->GetMethodID(env,
74             jni_cid_bluetoothGattServer, "getService",
75             "(Ljava/util/UUID;)Landroid/bluetooth/BluetoothGattService;");
76
77     jobject jni_obj_serviceUUID = CALEGetUuidFromString(env, OIC_GATT_SERVICE_UUID);
78
79     if (!gBluetoothGattServer)
80     {
81         OIC_LOG_V(DEBUG, TAG, "Check BluetoothGattServer status");
82         return NULL;
83     }
84     jobject jni_obj_bluetoothGattService = (*env)->CallObjectMethod(env,
85             gBluetoothGattServer, jni_mid_getService, jni_obj_serviceUUID);
86
87     jmethodID jni_mid_getCharacteristic =
88             (*env)->GetMethodID(env, jni_cid_bluetoothGattService,
89                     "getCharacteristic",
90                     "(Ljava/util/UUID;)Landroid/bluetooth/BluetoothGattCharacteristic;");
91
92     jobject jni_obj_responseUUID = CALEGetUuidFromString(env,
93             OIC_GATT_CHARACTERISTIC_RESPONSE_UUID);
94
95     jobject jni_obj_bluetoothGattCharacteristic = (*env)->CallObjectMethod(env,
96             jni_obj_bluetoothGattService, jni_mid_getCharacteristic,
97             jni_obj_responseUUID);
98
99     jmethodID jni_mid_setValue = (*env)->GetMethodID(env,
100             jni_cid_bluetoothGattCharacteristic, "setValue",
101             "([B)Z");
102
103     jboolean jni_boolean_setValue = (*env)->CallBooleanMethod(env,
104             jni_obj_bluetoothGattCharacteristic, jni_mid_setValue,
105             responseData);
106
107     if (jni_boolean_setValue == JNI_FALSE) {
108         OIC_LOG_V(DEBUG, TAG, "Fail to set response data");
109     }
110
111     return jni_obj_bluetoothGattCharacteristic;
112 }
113
114 jboolean CANativeLEServerSendResponseData(JNIEnv *env, jobject device, jobject responseData)
115 {
116
117     if(!CALEIsEnableBTAdapter(env))
118     {
119         OIC_LOG(DEBUG, TAG, "[BLE][Native] BT adpater is not enable");
120         return JNI_FALSE;
121     }
122
123     OIC_LOG_V(DEBUG, TAG, "CALEServerSendResponseData");
124
125     jclass jni_cid_bluetoothGattServer = (*env)->FindClass(env,
126             "android/bluetooth/BluetoothGattServer");
127
128     jmethodID jni_mid_notifyCharacteristicChanged =
129             (*env)->GetMethodID(env, jni_cid_bluetoothGattServer,
130                     "notifyCharacteristicChanged",
131                     "(Landroid/bluetooth/BluetoothDevice;Landroid/bluetooth/BluetoothGattCharacteristic;Z)Z");
132
133     jboolean jni_boolean_notifyCharacteristicChanged =
134             (*env)->CallBooleanMethod(env, gBluetoothGattServer,
135                     jni_mid_notifyCharacteristicChanged, device, responseData,
136                     JNI_TRUE);
137
138     if (jni_boolean_notifyCharacteristicChanged == JNI_FALSE) {
139         OIC_LOG_V(DEBUG, TAG, "Fail to notify characteristic");
140     }
141
142     return jni_boolean_notifyCharacteristicChanged;
143 }
144
145 jboolean CANativeLEServerSendResponse(JNIEnv *env, jobject device, jint requestId, jint status,
146         jint offset, jbyteArray value)
147 {
148
149     if(!CALEIsEnableBTAdapter(env))
150     {
151         OIC_LOG(DEBUG, TAG, "[BLE][Native] BT adpater is not enable");
152         return JNI_FALSE;
153     }
154
155     OIC_LOG_V(DEBUG, TAG, "CALEServerSendResponse");
156
157     jclass jni_cid_bluetoothGattServer = (*env)->FindClass(env,
158             "android/bluetooth/BluetoothGattServer");
159
160     jmethodID jni_mid_sendResponse = (*env)->GetMethodID(env,
161             jni_cid_bluetoothGattServer, "sendResponse",
162             "(Landroid/bluetooth/BluetoothDevice;III[B)Z");
163
164     jboolean jni_boolean_sendResponse = (*env)->CallBooleanMethod(env, gBluetoothGattServer,
165             jni_mid_sendResponse, device, requestId, status, offset, value);
166
167     if (jni_boolean_sendResponse == JNI_FALSE) {
168         OIC_LOG_V(DEBUG, TAG, "Fail to send response for gatt characteristic write request");
169     }
170
171     return jni_boolean_sendResponse;
172 }
173
174 void CANativeLEServerStartAdvertise(JNIEnv *env, jobject advertiseCallback)
175 {
176
177     OIC_LOG_V(DEBUG, TAG, "LEServerStartAdvertise");
178
179     if(!CALEIsEnableBTAdapter(env))
180     {
181         OIC_LOG(DEBUG, TAG, "[BLE][Native] BT adpater is not enable");
182         return;
183     }
184
185     jclass jni_cid_AdvertiseSettings = (*env)->FindClass(env,
186             "android/bluetooth/le/AdvertiseSettings$Builder");
187
188     jclass jni_cid_AdvertiseDataBuilder = (*env)->FindClass(env,
189             "android/bluetooth/le/AdvertiseData$Builder");
190
191     jclass jni_cid_BTAdapter = (*env)->FindClass(env,
192             "android/bluetooth/BluetoothAdapter");
193
194     jclass jni_cid_leAdvertiser = (*env)->FindClass(env,
195             "android/bluetooth/le/BluetoothLeAdvertiser");
196
197     jmethodID jni_mid_AdvertiseSettings = (*env)->GetMethodID(env,
198             jni_cid_AdvertiseSettings, "<init>", "()V");
199
200     jmethodID jni_mid_setAdvertiseMode = (*env)->GetMethodID(env,
201             jni_cid_AdvertiseSettings, "setAdvertiseMode",
202                 "(I)Landroid/bluetooth/le/AdvertiseSettings$Builder;");
203
204     jmethodID jni_mid_setConnectable = (*env)->GetMethodID(env,
205             jni_cid_AdvertiseSettings, "setConnectable",
206             "(Z)Landroid/bluetooth/le/AdvertiseSettings$Builder;");
207
208     jmethodID jni_mid_setTimeout = (*env)->GetMethodID(env,
209             jni_cid_AdvertiseSettings, "setTimeout",
210             "(I)Landroid/bluetooth/le/AdvertiseSettings$Builder;");
211
212     jmethodID jni_mid_AdvertiseDataBuilder = (*env)->GetMethodID(env,
213             jni_cid_AdvertiseDataBuilder, "<init>", "()V");
214
215     jmethodID jni_mid_addServiceUuid =
216             (*env)->GetMethodID(env, jni_cid_AdvertiseDataBuilder,
217                     "addServiceUuid",
218                     "(Landroid/os/ParcelUuid;)Landroid/bluetooth/le/AdvertiseData$Builder;");
219
220     jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env,
221             jni_cid_BTAdapter, "getDefaultAdapter",
222             "()Landroid/bluetooth/BluetoothAdapter;");
223
224     jmethodID jni_mid_getBluetoothLeAdvertiser = (*env)->GetMethodID(env,
225             jni_cid_BTAdapter, "getBluetoothLeAdvertiser",
226             "()Landroid/bluetooth/le/BluetoothLeAdvertiser;");
227
228     jmethodID jni_mid_build_LeAdvertiseSettings = (*env)->GetMethodID(env,
229             jni_cid_AdvertiseSettings, "build",
230             "()Landroid/bluetooth/le/AdvertiseSettings;");
231
232     jmethodID jni_mid_build_LeAdvertiseData = (*env)->GetMethodID(env,
233             jni_cid_AdvertiseDataBuilder, "build",
234             "()Landroid/bluetooth/le/AdvertiseData;");
235
236     jmethodID jni_mid_startAdvertising =
237             (*env)->GetMethodID(env, jni_cid_leAdvertiser, "startAdvertising",
238                     "(Landroid/bluetooth/le/AdvertiseSettings;Landroid/bluetooth/le/AdvertiseData;Landroid/bluetooth/le/AdvertiseCallback;)V");
239
240     jobject jni_AdvertiseSettings = (*env)->NewObject(env,
241             jni_cid_AdvertiseSettings, jni_mid_AdvertiseSettings);
242
243     jobject jni_obj_setAdvertiseMode = (*env)->CallObjectMethod(env,
244                 jni_AdvertiseSettings, jni_mid_setAdvertiseMode, 0); // 0: Low power, 1: Balanced
245
246     jobject jni_obj_setConnectable = (*env)->CallObjectMethod(env,
247             jni_AdvertiseSettings, jni_mid_setConnectable, JNI_TRUE);
248
249     jobject jni_obj_setTimeout = (*env)->CallObjectMethod(env,
250             jni_AdvertiseSettings, jni_mid_setTimeout, 0); //A value of 0 will disable the time limit
251
252     jobject jni_AdvertiseDataBuilder = (*env)->NewObject(env,
253             jni_cid_AdvertiseDataBuilder, jni_mid_AdvertiseDataBuilder);
254
255     jobject jni_obj_serviceUUID = CALEGetUuidFromString(env, OIC_GATT_SERVICE_UUID);
256
257     jobject jni_ParcelUuid = CALEGetParcelUuid(env, jni_obj_serviceUUID);
258
259     jobject jni_obj_addServiceUuid = (*env)->CallObjectMethod(env,
260             jni_AdvertiseDataBuilder, jni_mid_addServiceUuid, jni_ParcelUuid);
261
262     jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env,
263             jni_cid_BTAdapter, jni_mid_getDefaultAdapter);
264
265     jobject jni_obj_getBluetoothLeAdvertiser = (*env)->CallObjectMethod(env,
266             jni_obj_BTAdapter, jni_mid_getBluetoothLeAdvertiser);
267
268     jobject jni_obj_build_LeAdvertiseSettings = (*env)->CallObjectMethod(env,
269             jni_AdvertiseSettings, jni_mid_build_LeAdvertiseSettings);
270
271     jobject jni_obj_build_LeAdvertiseData = (*env)->CallObjectMethod(env,
272             jni_AdvertiseDataBuilder, jni_mid_build_LeAdvertiseData);
273
274     (*env)->CallVoidMethod(env, jni_obj_getBluetoothLeAdvertiser,
275             jni_mid_startAdvertising, jni_obj_build_LeAdvertiseSettings,
276             jni_obj_build_LeAdvertiseData, advertiseCallback);
277
278     OIC_LOG_V(DEBUG, TAG, "Advertising started!!");
279 }
280
281 void CANativeLEServerStopAdvertise(JNIEnv *env, jobject advertiseCallback)
282 {
283
284     OIC_LOG_V(DEBUG, TAG, "LEServerStopAdvertise");
285
286     if(!CALEIsEnableBTAdapter(env))
287     {
288         OIC_LOG(DEBUG, TAG, "[BLE][Native] BT adpater is not enable");
289         return;
290     }
291
292     jclass jni_cid_BTAdapter = (*env)->FindClass(env,
293             "android/bluetooth/BluetoothAdapter");
294
295     jclass jni_cid_leAdvertiser = (*env)->FindClass(env,
296             "android/bluetooth/le/BluetoothLeAdvertiser");
297
298     jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env,
299             jni_cid_BTAdapter, "getDefaultAdapter",
300             "()Landroid/bluetooth/BluetoothAdapter;");
301
302     jmethodID jni_mid_getBluetoothLeAdvertiser = (*env)->GetMethodID(env,
303             jni_cid_BTAdapter, "getBluetoothLeAdvertiser",
304             "()Landroid/bluetooth/le/BluetoothLeAdvertiser;");
305
306     jmethodID jni_mid_stopAdvertising =
307             (*env)->GetMethodID(env, jni_cid_leAdvertiser, "stopAdvertising",
308                     "(Landroid/bluetooth/le/AdvertiseCallback;)V");
309
310     jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env,
311             jni_cid_BTAdapter, jni_mid_getDefaultAdapter);
312
313     jobject jni_obj_getBluetoothLeAdvertiser = (*env)->CallObjectMethod(env,
314             jni_obj_BTAdapter, jni_mid_getBluetoothLeAdvertiser);
315
316     (*env)->CallVoidMethod(env, jni_obj_getBluetoothLeAdvertiser,
317             jni_mid_stopAdvertising, advertiseCallback);
318
319     OIC_LOG_V(DEBUG, TAG, "Advertising stopped!!");
320 }
321
322 jboolean CALEStartGattServer(JNIEnv *env, jobject gattServerCallback)
323 {
324
325     OIC_LOG_V(DEBUG, TAG, "CALEStartGattServer");
326
327     if(!CALEIsEnableBTAdapter(env))
328     {
329         OIC_LOG(DEBUG, TAG, "[BLE][Native] BT adpater is not enable");
330         return JNI_FALSE;
331     }
332
333     if(gIsStartServer)
334         OIC_LOG_V(DEBUG, TAG, "Gatt server already started");
335
336     gBluetoothGattServerCallback = (*env)->NewGlobalRef(env, gattServerCallback);
337
338     // open gatt server
339     jobject bluetoothGattServer = CANativeLEServerOpenGattServer(env);
340     if(!bluetoothGattServer)
341     {
342         OIC_LOG_V(DEBUG, TAG, "bluetoothGattServer is null");
343         return JNI_FALSE;
344     }
345
346     gBluetoothGattServer = (*env)->NewGlobalRef(env, bluetoothGattServer);
347
348     // create gatt service
349     jobject bluetoothGattService = CANativeLEServerCreateGattService(env);
350
351     // add gatt service
352     return CANativeLEServerAddGattService(env, gBluetoothGattServer, bluetoothGattService);
353 }
354
355 jobject CANativeLEServerOpenGattServer(JNIEnv *env)
356 {
357
358     OIC_LOG_V(DEBUG, TAG, "CALEServerOpenGattServer");
359
360     if(!CALEIsEnableBTAdapter(env))
361     {
362         OIC_LOG(DEBUG, TAG, "[BLE][Native] BT adpater is not enable");
363         return NULL;
364     }
365
366     jclass jni_cid_context = (*env)->FindClass(env, "android/content/Context");
367
368     jclass jni_cid_bluetoothManager = (*env)->FindClass(env,
369             "android/bluetooth/BluetoothManager");
370
371     jfieldID jni_fid_bluetoothService = (*env)->GetStaticFieldID(env,
372             jni_cid_context, "BLUETOOTH_SERVICE", "Ljava/lang/String;");
373
374     jmethodID jni_mid_getSystemService = (*env)->GetMethodID(env,
375             jni_cid_context, "getSystemService",
376             "(Ljava/lang/String;)Ljava/lang/Object;");
377
378     jmethodID jni_mid_openGattServer =
379             (*env)->GetMethodID(env, jni_cid_bluetoothManager, "openGattServer",
380                     "(Landroid/content/Context;Landroid/bluetooth/BluetoothGattServerCallback;)Landroid/bluetooth/BluetoothGattServer;");
381
382     jobject jni_obj_bluetoothService = (*env)->GetStaticObjectField(env,
383             jni_cid_context, jni_fid_bluetoothService);
384     if(!jni_obj_bluetoothService)
385     {
386         OIC_LOG_V(DEBUG, TAG, "jni_obj_bluetoothService is null");
387         return JNI_FALSE;
388     }
389
390
391     jobject jni_obj_bluetoothManager = (*env)->CallObjectMethod(env, gContext,
392             jni_mid_getSystemService, jni_obj_bluetoothService);
393     if(!jni_obj_bluetoothManager)
394     {
395         OIC_LOG_V(DEBUG, TAG, "jni_obj_bluetoothManager is null");
396         return JNI_FALSE;
397     }
398
399     jobject jni_obj_bluetoothGattServer = (*env)->CallObjectMethod(env,
400             jni_obj_bluetoothManager, jni_mid_openGattServer, gContext,
401             gBluetoothGattServerCallback);
402     if(!jni_obj_bluetoothGattServer)
403     {
404         OIC_LOG_V(DEBUG, TAG, "jni_obj_bluetoothGattServer is null");
405         return JNI_FALSE;
406     }
407
408     return jni_obj_bluetoothGattServer;
409 }
410
411 jobject CANativeLEServerCreateGattService(JNIEnv *env)
412 {
413
414     OIC_LOG_V(DEBUG, TAG, "CALEServerCreateGattService");
415
416     if(!CALEIsEnableBTAdapter(env))
417     {
418         OIC_LOG(DEBUG, TAG, "[BLE][Native] BT adpater is not enable");
419         return NULL;
420     }
421
422     jclass jni_cid_bluetoothGattService = (*env)->FindClass(env,
423             "android/bluetooth/BluetoothGattService");
424
425     jclass jni_cid_bluetoothGattCharacteristic = (*env)->FindClass(env,
426             "android/bluetooth/BluetoothGattCharacteristic");
427
428     jfieldID jni_fid_serviceType = (*env)->GetStaticFieldID(env,
429             jni_cid_bluetoothGattService, "SERVICE_TYPE_PRIMARY", "I");
430
431     jfieldID jni_fid_readProperties = (*env)->GetStaticFieldID(env,
432             jni_cid_bluetoothGattCharacteristic, "PROPERTY_READ", "I");
433
434     jfieldID jni_fid_writeProperties = (*env)->GetStaticFieldID(env,
435             jni_cid_bluetoothGattCharacteristic, "PROPERTY_WRITE", "I");
436
437     jfieldID jni_fid_readPermissions = (*env)->GetStaticFieldID(env,
438             jni_cid_bluetoothGattCharacteristic, "PERMISSION_READ", "I");
439
440     jfieldID jni_fid_writePermissions = (*env)->GetStaticFieldID(env,
441             jni_cid_bluetoothGattCharacteristic, "PERMISSION_WRITE", "I");
442
443     jmethodID jni_mid_bluetoothGattService = (*env)->GetMethodID(env,
444             jni_cid_bluetoothGattService, "<init>", "(Ljava/util/UUID;I)V");
445
446     jmethodID jni_mid_addCharacteristic = (*env)->GetMethodID(env,
447             jni_cid_bluetoothGattService, "addCharacteristic",
448             "(Landroid/bluetooth/BluetoothGattCharacteristic;)Z");
449
450     jmethodID jni_mid_bluetoothGattCharacteristic = (*env)->GetMethodID(env,
451             jni_cid_bluetoothGattCharacteristic, "<init>",
452             "(Ljava/util/UUID;II)V");
453
454     jobject jni_obj_serviceUUID = CALEGetUuidFromString(env, OIC_GATT_SERVICE_UUID);
455
456     jobject jni_obj_serviceType = (*env)->GetStaticObjectField(env,
457             jni_cid_bluetoothGattService, jni_fid_serviceType);
458
459     jobject jni_bluetoothGattService = (*env)->NewObject(env,
460             jni_cid_bluetoothGattService, jni_mid_bluetoothGattService,
461             jni_obj_serviceUUID, jni_obj_serviceType);
462
463     jobject jni_obj_readUuid = CALEGetUuidFromString(env,
464             OIC_GATT_CHARACTERISTIC_RESPONSE_UUID);
465
466     jint jni_int_readProperties = (*env)->GetStaticIntField(env,
467             jni_cid_bluetoothGattCharacteristic, jni_fid_readProperties);
468
469     jint jni_int_readPermissions = (*env)->GetStaticIntField(env,
470             jni_cid_bluetoothGattCharacteristic, jni_fid_readPermissions);
471
472     jobject jni_readCharacteristic = (*env)->NewObject(env,
473             jni_cid_bluetoothGattCharacteristic,
474             jni_mid_bluetoothGattCharacteristic, jni_obj_readUuid,
475             jni_int_readProperties, jni_int_readPermissions);
476
477     jboolean jni_boolean_addReadCharacteristic = (*env)->CallBooleanMethod(env,
478             jni_bluetoothGattService, jni_mid_addCharacteristic,
479             jni_readCharacteristic);
480
481     jobject jni_obj_writeUuid = CALEGetUuidFromString(env,
482             OIC_GATT_CHARACTERISTIC_REQUEST_UUID);
483
484     jint jni_int_writeProperties = (*env)->GetStaticIntField(env,
485             jni_cid_bluetoothGattCharacteristic, jni_fid_writeProperties);
486
487     jint jni_int_writePermissions = (*env)->GetStaticIntField(env,
488             jni_cid_bluetoothGattCharacteristic, jni_fid_writePermissions);
489
490     jobject jni_writeCharacteristic = (*env)->NewObject(env,
491             jni_cid_bluetoothGattCharacteristic,
492             jni_mid_bluetoothGattCharacteristic, jni_obj_writeUuid,
493             jni_int_writeProperties, jni_int_writePermissions);
494
495     jboolean jni_boolean_addWriteCharacteristic = (*env)->CallBooleanMethod(env,
496             jni_bluetoothGattService, jni_mid_addCharacteristic,
497             jni_writeCharacteristic);
498
499     if (jni_boolean_addWriteCharacteristic == JNI_FALSE)
500     {
501         OIC_LOG_V(DEBUG, TAG, "Fail to add jni_boolean_addReadCharacteristic");
502         return NULL;
503     }
504
505     return jni_bluetoothGattService;
506 }
507
508 jboolean CANativeLEServerAddGattService(JNIEnv *env, jobject bluetoothGattServer,
509         jobject bluetoothGattService)
510 {
511
512     OIC_LOG_V(DEBUG, TAG, "CALEServerAddGattService");
513
514     if(!CALEIsEnableBTAdapter(env))
515     {
516         OIC_LOG(DEBUG, TAG, "[BLE][Native] BT adpater is not enable");
517         return JNI_FALSE;
518     }
519
520     jclass jni_cid_bluetoothGattServer = (*env)->FindClass(env,
521             "android/bluetooth/BluetoothGattServer");
522
523     jmethodID jni_mid_addService = (*env)->GetMethodID(env,
524             jni_cid_bluetoothGattServer, "addService",
525             "(Landroid/bluetooth/BluetoothGattService;)Z");
526
527     jboolean jni_boolean_addService = (*env)->CallBooleanMethod(env, bluetoothGattServer,
528             jni_mid_addService, bluetoothGattService);
529
530     if (jni_boolean_addService == JNI_FALSE)
531     {
532         OIC_LOG_V(DEBUG, TAG, "Fail to add gatt service");
533     }
534
535     return jni_boolean_addService;
536 }
537
538 jboolean CANativeLEServerConnect(JNIEnv *env, jobject bluetoothDevice)
539 {
540
541     OIC_LOG_V(DEBUG, TAG, "CALEConnect");
542
543     if(!CALEIsEnableBTAdapter(env))
544     {
545         OIC_LOG(DEBUG, TAG, "[BLE][Native] BT adpater is not enable");
546         return JNI_FALSE;
547     }
548
549     jclass jni_cid_bluetoothGattServer = (*env)->FindClass(env,
550             "android/bluetooth/BluetoothGattServer");
551
552     jmethodID jni_mid_connect = (*env)->GetMethodID(env,
553             jni_cid_bluetoothGattServer, "connect",
554             "(Landroid/bluetooth/BluetoothDevice;Z)Z");
555
556     jboolean jni_boolean_connect = (*env)->CallBooleanMethod(env,
557             gBluetoothGattServer, jni_mid_connect, bluetoothDevice, JNI_FALSE);
558
559     if(jni_boolean_connect == JNI_FALSE) {
560         OIC_LOG_V(DEBUG, TAG, "Fail to connect");
561     }
562
563     return jni_boolean_connect;
564 }
565
566 void CANativeLEServerDisconnect(JNIEnv *env, jobject bluetoothDevice)
567 {
568
569     OIC_LOG_V(DEBUG, TAG, "CALEDisconnect");
570
571     if(!CALEIsEnableBTAdapter(env))
572     {
573         OIC_LOG(DEBUG, TAG, "[BLE][Native] BT adpater is not enable");
574         return;
575     }
576
577     jclass jni_cid_bluetoothGattServer = (*env)->FindClass(env,
578             "android/bluetooth/BluetoothGattServer");
579
580     jmethodID jni_mid_cancelConnection = (*env)->GetMethodID(env,
581             jni_cid_bluetoothGattServer, "cancelConnection",
582             "(Landroid/bluetooth/BluetoothDevice;)V");
583
584     (*env)->CallVoidMethod(env, gBluetoothGattServer, jni_mid_cancelConnection,
585             bluetoothDevice);
586 }
587
588 jboolean CALEServerSend(JNIEnv *env, jobject bluetoothDevice, jbyteArray responseData)
589 {
590
591     OIC_LOG_V(DEBUG, TAG, "CALESend");
592
593     if(!CALEIsEnableBTAdapter(env))
594     {
595         OIC_LOG(DEBUG, TAG, "[BLE][Native] BT adpater is not enable");
596         return JNI_FALSE;
597     }
598
599     jobject responseChar = CANativeLEServerSetResponseData(env, responseData);
600
601     jboolean result = CANativeLEServerSendResponseData(env, bluetoothDevice, responseChar);
602
603     if(result == JNI_FALSE)
604     {
605         OIC_LOG_V(DEBUG, TAG, "Fail to send response data");
606     }
607
608     return result;
609 }
610
611 void CALeServerCreateJniInterfaceObject()
612 {
613     OIC_LOG_V(DEBUG, TAG, "CALeServerCreateJniInterfaceObject");
614
615     jboolean isAttached = FALSE;
616     JNIEnv* env;
617     jint res = (*g_jvm)->GetEnv(g_jvm, (void**)&env, JNI_VERSION_1_6);
618     if(res != JNI_OK)
619     {
620         OIC_LOG_V(DEBUG, TAG, "Could not get JNIEnv pointer");
621         res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
622
623         if(res != JNI_OK)
624         {
625             OIC_LOG_V(DEBUG, TAG, "AttachCurrentThread failed");
626             return;
627         }
628         isAttached = TRUE;
629     }
630
631     // initialize le server
632
633     if(isAttached)
634         (*g_jvm)->DetachCurrentThread(g_jvm);
635 }
636
637 void CALEServerInitialize(u_thread_pool_t handle)
638 {
639     OIC_LOG(DEBUG, TAG, "CALEServerInitialize");
640
641     gThreadPoolHandle = handle;
642
643     gIsSendingMulticastData = FALSE;
644
645     CALEServerCreateCachedDeviceList();
646 }
647
648 void CALEServerTerminate()
649 {
650     OIC_LOG(DEBUG, TAG, "CALEServerTerminate");
651
652     jboolean isAttached = FALSE;
653     JNIEnv* env;
654     jint res = (*g_jvm)->GetEnv(g_jvm, (void**)&env, JNI_VERSION_1_6);
655     if(res != JNI_OK)
656     {
657         OIC_LOG_V(DEBUG, TAG, "Could not get JNIEnv pointer");
658         res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
659
660         if(res != JNI_OK)
661         {
662             OIC_LOG_V(DEBUG, TAG, "AttachCurrentThread failed");
663             return;
664         }
665         isAttached = TRUE;
666     }
667
668     CALEServerStopMulticastServer(0);
669
670     CALEServerRemoveAllDevices(env);
671
672     if(gLeAdvertiseCallback)
673     {
674         (*env)->DeleteGlobalRef(env, gLeAdvertiseCallback);
675     }
676
677     if(gBluetoothGattServer)
678     {
679         (*env)->DeleteGlobalRef(env, gBluetoothGattServer);
680     }
681
682     if(gBluetoothGattServerCallback)
683     {
684         (*env)->DeleteGlobalRef(env, gBluetoothGattServerCallback);
685     }
686
687     if(gContext)
688     {
689         (*env)->DeleteGlobalRef(env, gContext);
690     }
691
692     gIsStartServer = FALSE;
693
694     if(isAttached)
695         (*g_jvm)->DetachCurrentThread(g_jvm);
696 }
697
698 int32_t CALEServerSendUnicastMessage(const char* address, const char* data, uint32_t dataLen)
699 {
700     OIC_LOG_V(DEBUG, TAG, "CALEServerSendUnicastMessage(%s, %s)", address, data);
701
702     jboolean isAttached = FALSE;
703     JNIEnv* env;
704     jint res = (*g_jvm)->GetEnv(g_jvm, (void**)&env, JNI_VERSION_1_6);
705     if(res != JNI_OK)
706     {
707         OIC_LOG_V(DEBUG, TAG, "Could not get JNIEnv pointer");
708         res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
709
710         if(res != JNI_OK)
711         {
712             OIC_LOG_V(DEBUG, TAG, "AttachCurrentThread failed");
713             return -1;
714         }
715         isAttached = TRUE;
716     }
717
718     CALEServerSendUnicastMessageImpl(env, address, data, dataLen);
719
720     if(isAttached)
721         (*g_jvm)->DetachCurrentThread(g_jvm);
722
723     return 0;
724 }
725
726 int32_t CALEServerSendMulticastMessage(const char* data, uint32_t dataLen)
727 {
728     OIC_LOG_V(DEBUG, TAG, "CALEServerSendMulticastMessage(%s)", data);
729
730     jboolean isAttached = FALSE;
731     JNIEnv* env;
732     jint res = (*g_jvm)->GetEnv(g_jvm, (void**)&env, JNI_VERSION_1_6);
733     if(res != JNI_OK)
734     {
735         OIC_LOG_V(DEBUG, TAG, "Could not get JNIEnv pointer");
736         res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
737
738         if(res != JNI_OK)
739         {
740             OIC_LOG_V(DEBUG, TAG, "AttachCurrentThread failed");
741             return -1;
742         }
743         isAttached = TRUE;
744     }
745
746     CALEServerSendMulticastMessageImpl(env, data, dataLen);
747
748     if(isAttached)
749         (*g_jvm)->DetachCurrentThread(g_jvm);
750
751     return 0;
752 }
753
754 int32_t CALEServerStartUnicastServer(const char* address)
755 {
756     OIC_LOG_V(DEBUG, TAG, "CALEServerStartUnicastServer(%s)", address);
757
758     return 0;
759 }
760
761 int32_t CALEServerStartMulticastServer()
762 {
763     OIC_LOG_V(DEBUG, TAG, "CALEServerStartMulticastServer");
764
765     if(gIsStartServer)
766     {
767         OIC_LOG_V(DEBUG, TAG, "server is already started..it will be skipped");
768         return 0;
769     }
770
771     jboolean isAttached = FALSE;
772     JNIEnv* env;
773     jint res = (*g_jvm)->GetEnv(g_jvm, (void**)&env, JNI_VERSION_1_6);
774     if(res != JNI_OK)
775     {
776         OIC_LOG_V(DEBUG, TAG, "Could not get JNIEnv pointer");
777         res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
778
779         if(res != JNI_OK)
780         {
781             OIC_LOG_V(DEBUG, TAG, "AttachCurrentThread failed");
782             return -1;
783         }
784         isAttached = TRUE;
785     }
786
787     gIsStartServer = TRUE;
788
789     // start gatt server
790     if( CALEStartGattServer(env, gBluetoothGattServerCallback) == JNI_FALSE) {
791         OIC_LOG_V(DEBUG, TAG, "Fail to start gatt server");
792         return -1;
793     }
794
795     // start advertise
796     CANativeLEServerStartAdvertise(env, gLeAdvertiseCallback);
797
798     if(isAttached)
799         (*g_jvm)->DetachCurrentThread(g_jvm);
800
801     return 0;
802 }
803
804 int32_t CALEServerStopUnicastServer(int32_t serverID)
805 {
806     OIC_LOG(DEBUG, TAG, "CALEServerStopUnicastServer");
807
808     return 0;
809 }
810
811 int32_t CALEServerStopMulticastServer(int32_t serverID)
812 {
813     OIC_LOG(DEBUG, TAG, "CALEServerStopMulticastServer");
814
815     if(gIsStartServer == FALSE)
816     {
817         OIC_LOG_V(DEBUG, TAG, "server is already stopped..it will be skipped");
818         return 0;
819     }
820
821     jboolean isAttached = FALSE;
822     JNIEnv* env;
823     jint res = (*g_jvm)->GetEnv(g_jvm, (void**)&env, JNI_VERSION_1_6);
824     if(res != JNI_OK)
825     {
826         OIC_LOG_V(DEBUG, TAG, "Could not get JNIEnv pointer");
827         res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
828
829         if(res != JNI_OK)
830         {
831             OIC_LOG_V(DEBUG, TAG, "AttachCurrentThread failed");
832             return -1;
833         }
834         isAttached = TRUE;
835     }
836
837     CANativeLEServerStopAdvertise(env, gLeAdvertiseCallback);
838
839     gIsStartServer = FALSE;
840
841     if(isAttached)
842         (*g_jvm)->DetachCurrentThread(g_jvm);
843
844     return 0;
845 }
846
847 void CALEServerSetCallback(CAPacketReceiveCallback callback)
848 {
849     OIC_LOG(DEBUG, TAG, "CALEServerSetCallback");
850     gPacketReceiveCallback = callback;
851 }
852
853 void CALEServerGetInterfaceInfo(CALocalConnectivity_t **info, uint32_t* size)
854 {
855     OIC_LOG(DEBUG, TAG, "CALEServerGetInterfaceInfo");
856     return;
857 }
858
859 void CALEServerGetLocalAddress(char* address)
860 {
861     OIC_LOG(DEBUG, TAG, "CALEServerGetLocalAddress");
862
863     jboolean isAttached = FALSE;
864     JNIEnv* env;
865     jint res = (*g_jvm)->GetEnv(g_jvm, (void**)&env, JNI_VERSION_1_6);
866     if(res != JNI_OK)
867     {
868         OIC_LOG_V(DEBUG, TAG, "Could not get JNIEnv pointer");
869         res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
870         if(res != JNI_OK)
871         {
872             OIC_LOG_V(DEBUG, TAG, "AttachCurrentThread failed");
873             return;
874         }
875         isAttached = TRUE;
876     }
877
878     jstring jni_address = CALEGetLocalDeviceAddress(env);
879     const char* localAddress = (*env)->GetStringUTFChars(env, jni_address, NULL);
880     memcpy(address, localAddress, strlen(localAddress));
881
882     OIC_LOG_V(DEBUG, TAG, "Local Address : %s", address);
883     if(isAttached)
884         (*g_jvm)->DetachCurrentThread(g_jvm);
885 }
886
887 int32_t CALEServerSendUnicastMessageImpl(JNIEnv *env, const char* address, const char* data,
888         uint32_t dataLen)
889 {
890     OIC_LOG_V(DEBUG, TAG, "CALEServerSendUnicastMessageImpl, address: %s, data: %s", address, data);
891
892     // 1. get device object with address from cache
893     // 2. connect to the gatt client device
894     // 3. write a characteristic for response
895     // 4. notify it
896     // 5. disconnect
897
898     jobject jni_obj_bluetoothDevice = NULL;
899
900     if(gConnectedDeviceList == NULL)
901     {
902         OIC_LOG(DEBUG, TAG, "gConnectedDeviceList is null");
903     }
904
905     if(gConnectedDeviceList)
906     {
907         jint index;
908         for (index = 0; index < u_arraylist_length(gConnectedDeviceList); index++)
909         {
910             OIC_LOG(DEBUG, TAG, "check device address");
911             jobject jarrayObj = (jobject) u_arraylist_get(gConnectedDeviceList, index);
912             if(!jarrayObj)
913             {
914                 OIC_LOG(DEBUG, TAG, "jarrayObj is null");
915                 return -1;
916             }
917
918             jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
919             if(!jni_setAddress)
920             {
921                 OIC_LOG(DEBUG, TAG, "jni_setAddress is null");
922                 return -1;
923             }
924             const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
925
926             if(!strcmp(setAddress, address))
927             {
928                 OIC_LOG(DEBUG, TAG, "device address matched");
929                 jni_obj_bluetoothDevice = jarrayObj;
930                 break;
931             }
932             jni_obj_bluetoothDevice = jarrayObj;
933         }
934
935         if(jni_obj_bluetoothDevice)
936         {
937             jbyteArray jni_bytearr_data = (*env)->NewByteArray(env, dataLen);
938             (*env)->SetByteArrayRegion(env, jni_bytearr_data, 0, dataLen, (jbyte*)data);
939
940             CALEServerSend(env, jni_obj_bluetoothDevice, jni_bytearr_data);
941
942         } else {
943             OIC_LOG(DEBUG, TAG, "jni_obj_bluetoothDevice is null");
944         }
945     }
946     return 0;
947 }
948
949 int32_t CALEServerSendMulticastMessageImpl(JNIEnv *env, const char* data, uint32_t dataLen)
950 {
951     OIC_LOG_V(DEBUG, TAG, "CALEServerSendMulticastMessageImpl, send to, data: %s", data);
952
953     if(!gConnectedDeviceList)
954     {
955         OIC_LOG(DEBUG, TAG, "gConnectedDeviceList is null");
956         return 0;
957     }
958
959     // 1. get all the device objects from cache
960     // 2. connect to the gatt client devices
961     // 3. write a characteristic for response
962     // 4. notify it to every devices
963     // 5. disconnect
964
965     jint index;
966     for (index = 0; index < u_arraylist_length(gConnectedDeviceList); index++)
967     {
968         jobject jarrayObj = (jobject) u_arraylist_get(gConnectedDeviceList, index);
969         if(!jarrayObj)
970         {
971             OIC_LOG(DEBUG, TAG, "jarrayObj is null");
972             return -1;
973         }
974
975         gIsSendingMulticastData = TRUE;
976         CANativeLEServerConnect(env, jarrayObj);
977
978         sleep(1);
979     }
980
981     return 0;
982 }
983
984 JNIEXPORT void JNICALL Java_com_iotivity_jar_CALeInterface_CARegisterLeGattServerCallback
985   (JNIEnv *env, jobject obj, jobject callback)
986 {
987     OIC_LOG_V(DEBUG, TAG, "CALeInterface - Register Le Gatt Server Callback");
988
989     gBluetoothGattServerCallback = (*env)->NewGlobalRef(env, callback);
990 }
991
992 JNIEXPORT void JNICALL Java_com_iotivity_jar_CALeInterface_CARegisterBluetoothLeAdvertiseCallback
993   (JNIEnv *env, jobject obj, jobject callback)
994 {
995     OIC_LOG_V(DEBUG, TAG, "CALeInterface - Register Le Advertise Callback");
996
997     gLeAdvertiseCallback = (*env)->NewGlobalRef(env, callback);
998 }
999
1000 JNIEXPORT void JNICALL Java_com_iotivity_jar_CALeInterface_CALeGattServerConnectionStateChangeCallback
1001   (JNIEnv *env, jobject obj, jobject device, jint status, jint newState)
1002 {
1003     OIC_LOG_V(DEBUG, TAG, "CALeInterface - Gatt Server ConnectionStateChange Callback");
1004
1005     OIC_LOG_V(DEBUG, TAG, "New connection State: %d", newState);
1006
1007     if (!device)
1008     {
1009         OIC_LOG(DEBUG, TAG, "device is null");
1010         return;
1011     }
1012
1013     jclass jni_cid_bluetoothProfile = (*env)->FindClass(env,
1014             "android/bluetooth/BluetoothProfile");
1015
1016     jfieldID jni_fid_state_connected = (*env)->GetStaticFieldID(env,
1017             jni_cid_bluetoothProfile, "STATE_CONNECTED", "I");
1018
1019     jfieldID jni_fid_state_disconnected = (*env)->GetStaticFieldID(env,
1020                 jni_cid_bluetoothProfile, "STATE_DISCONNECTED", "I");
1021
1022     // STATE_CONNECTED
1023     jint jni_int_state_connected = (*env)->GetStaticIntField(env,
1024             jni_cid_bluetoothProfile, jni_fid_state_connected);
1025
1026     // STATE_DISCONNECTED
1027     jint jni_int_state_disconnected = (*env)->GetStaticIntField(env,
1028                 jni_cid_bluetoothProfile, jni_fid_state_disconnected);
1029
1030     if(newState == jni_int_state_connected)
1031     {
1032
1033         OIC_LOG_V(DEBUG, TAG, "LE CONNECTED");
1034
1035         jstring jni_remoteAddress = CALEGetAddressFromBTDevice(env, device);
1036         if (!jni_remoteAddress)
1037         {
1038             OIC_LOG(DEBUG, TAG, "jni_remoteAddress is null");
1039             return;
1040         }
1041
1042         const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
1043
1044         if (gConnectedDeviceList == NULL)
1045         {
1046             OIC_LOG_V(DEBUG, TAG, "gConnectedDeviceList is null");
1047         }
1048
1049         if(CALEServerIsDeviceInList(env, remoteAddress) == JNI_FALSE)
1050         {
1051             OIC_LOG_V(DEBUG, TAG, "add connected device to cache");
1052             CALEServerAddDeviceToList(env, device);
1053         }
1054
1055 //        // temp data
1056 //        if(gIsSendingMulticastData)
1057 //        {
1058 //            OIC_LOG_V(DEBUG, TAG, "send data");
1059 //
1060 //            const char* data = "HelloWorld~";
1061 //            uint32_t dataLen =  strlen(data);
1062 //            jbyteArray jni_bytearr_data = (*env)->NewByteArray(env, dataLen);
1063 //            (*env)->SetByteArrayRegion(env, jni_bytearr_data, 0, dataLen, (jbyte*)data);
1064 //            CALEServerSend(env, device, jni_bytearr_data);
1065 //            gIsSendingMulticastData = FALSE;
1066 //        }
1067
1068
1069     }
1070     else if(newState == jni_int_state_disconnected)
1071     {
1072         OIC_LOG_V(DEBUG, TAG, "LE DISCONNECTED");
1073     }
1074 }
1075
1076 void CALEServerCreateCachedDeviceList()
1077 {
1078     OIC_LOG(DEBUG, TAG, "CALEServerCreateCachedDeviceList");
1079
1080     // create new object array
1081     if (gConnectedDeviceList == NULL)
1082     {
1083         OIC_LOG_V(DEBUG, TAG, "Create device list");
1084
1085         gConnectedDeviceList = u_arraylist_create();
1086     }
1087 }
1088
1089 jboolean CALEServerIsDeviceInList(JNIEnv *env, const char* remoteAddress)
1090 {
1091     OIC_LOG(DEBUG, TAG, "CALEServerIsDeviceInList");
1092
1093     if(gConnectedDeviceList == NULL)
1094         OIC_LOG(DEBUG, TAG, "list is null");
1095
1096     uint32_t len = u_arraylist_length(gConnectedDeviceList);
1097
1098     uint32_t index;
1099     for (index = 0; index < u_arraylist_length(gConnectedDeviceList); index++)
1100     {
1101         jobject jarrayObj = (jobject) u_arraylist_get(gConnectedDeviceList, index);
1102
1103         if (!jarrayObj)
1104         {
1105             OIC_LOG(DEBUG, TAG, "jarrayObj is null");
1106             return JNI_TRUE;
1107         }
1108
1109         jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
1110         if (!jni_setAddress)
1111         {
1112             OIC_LOG(DEBUG, TAG, "jni_setAddress is null");
1113             return JNI_TRUE;
1114         }
1115
1116         const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress,
1117                 NULL);
1118
1119         if (!strcmp(remoteAddress, setAddress))
1120         {
1121             OIC_LOG_V(DEBUG, TAG, "the device is already set");
1122             return JNI_TRUE;
1123         }
1124         else
1125         {
1126             continue;
1127         }
1128     }
1129
1130     OIC_LOG_V(DEBUG, TAG, "no device in list");
1131     return JNI_FALSE;
1132 }
1133
1134 void CALEServerAddDeviceToList(JNIEnv *env, jobject device)
1135 {
1136     if (device == NULL)
1137     {
1138         OIC_LOG(DEBUG, TAG, "device is null");
1139         return;
1140     }
1141
1142     if (gConnectedDeviceList == NULL)
1143     {
1144         OIC_LOG(DEBUG, TAG, "list is null");
1145         return;
1146     }
1147
1148     jstring jni_remoteAddress = CALEGetAddressFromBTDevice(env, device);
1149     if (!jni_remoteAddress)
1150     {
1151         OIC_LOG(DEBUG, TAG, "jni_remoteAddress is null");
1152         return;
1153     }
1154
1155     const char* remoteAddress = (*env)->GetStringUTFChars(env,
1156             jni_remoteAddress, NULL);
1157
1158     if (CALEServerIsDeviceInList(env, remoteAddress) == JNI_FALSE)
1159     {
1160         jobject gdevice = (*env)->NewGlobalRef(env, device);
1161         u_arraylist_add(gConnectedDeviceList, gdevice);
1162         OIC_LOG_V(DEBUG, TAG, "Set Object to Array as Element");
1163     }
1164 }
1165
1166 void CALEServerRemoveAllDevices(JNIEnv *env)
1167 {
1168     OIC_LOG_V(DEBUG, TAG, "CALEServerRemoveAllDevices");
1169
1170     if (!gConnectedDeviceList)
1171     {
1172         OIC_LOG(DEBUG, TAG, "no deviceList");
1173         return;
1174     }
1175
1176     uint32_t index;
1177     for (index = 0; index < u_arraylist_length(gConnectedDeviceList); index++)
1178     {
1179         jobject jarrayObj = (jobject) u_arraylist_get(gConnectedDeviceList, index);
1180
1181         if (jarrayObj)
1182         {
1183             (*env)->DeleteGlobalRef(env, jarrayObj);
1184         }
1185     }
1186
1187     OICFree(gConnectedDeviceList);
1188     gConnectedDeviceList = NULL;
1189     return;
1190 }
1191
1192 void CALEServerRemoveDevice(JNIEnv *env, jstring address)
1193 {
1194     OIC_LOG_V(DEBUG, TAG, "CALEServerRemoveDevice");
1195
1196     if (!gConnectedDeviceList)
1197     {
1198         OIC_LOG(DEBUG, TAG, "no deviceList");
1199         return;
1200     }
1201
1202     uint32_t index;
1203     for (index = 0; index < u_arraylist_length(gConnectedDeviceList); index++)
1204     {
1205         jobject jarrayObj = (jobject) u_arraylist_get(gConnectedDeviceList, index);
1206
1207         if (jarrayObj)
1208         {
1209             jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
1210             if (!jni_setAddress)
1211             {
1212                 OIC_LOG(DEBUG, TAG, "wrong device address");
1213                 continue;
1214             }
1215             const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress,
1216                     NULL);
1217             const char* remoteAddress = (*env)->GetStringUTFChars(env, address,
1218                     NULL);
1219
1220             if (!strcmp(setAddress, remoteAddress))
1221             {
1222                 OIC_LOG_V(DEBUG, TAG, "device address : %s", remoteAddress);
1223                 (*env)->DeleteGlobalRef(env, jarrayObj);
1224
1225                 CALEServerReorderinglist(index);
1226                 return;
1227             }
1228         }
1229     }
1230     OIC_LOG(DEBUG, TAG, "no target object");
1231     return;
1232 }
1233
1234 void CALEServerReorderinglist(uint32_t index)
1235 {
1236     if (index >= gConnectedDeviceList->length)
1237         return;
1238
1239     if (index < gConnectedDeviceList->length - 1)
1240     {
1241         memmove(&gConnectedDeviceList->data[index], &gConnectedDeviceList->data[index + 1],
1242                 (gConnectedDeviceList->length - index - 1) * sizeof(void *));
1243     }
1244
1245     gConnectedDeviceList->size--;
1246     gConnectedDeviceList->length--;
1247 }
1248
1249 JNIEXPORT void JNICALL
1250 Java_com_iotivity_jar_CALeInterface_CALeGattServerServiceAddedCallback
1251 (JNIEnv *env, jobject obj, jint status, jobject gattService)
1252 {
1253     OIC_LOG_V(DEBUG, TAG, "CALeInterface - Gatt Service Added Callback(%d)", status);
1254 }
1255
1256 JNIEXPORT void JNICALL
1257 Java_com_iotivity_jar_CALeInterface_CALeGattServerCharacteristicReadRequestCallback
1258 (JNIEnv *env, jobject obj, jobject device, jint requestId, jint offset, jobject characteristic, jbyteArray data)
1259 {
1260     OIC_LOG_V(DEBUG, TAG, "CALeInterface - Gatt Server Characteristic Read Request Callback");
1261
1262     CANativeLEServerSendResponse(env, device, requestId, 0, offset, NULL);
1263 }
1264
1265 JNIEXPORT void JNICALL
1266 Java_com_iotivity_jar_CALeInterface_CALeGattServerCharacteristicWriteRequestCallback
1267 (JNIEnv *env, jobject obj, jobject device, jint requestId, jobject characteristic, jbyteArray data,
1268         jboolean preparedWrite, jboolean responseNeeded, jint offset, jbyteArray value)
1269 {
1270     OIC_LOG_V(DEBUG, TAG, "CALeInterface - Gatt Server Characteristic Write Request Callback");
1271
1272     CANativeLEServerSendResponse(env, device, requestId, 0, offset, value);
1273
1274     if(data == NULL)
1275     {
1276         OIC_LOG_V(DEBUG, TAG, "Reqeust data is null");
1277         return;
1278     }
1279
1280     // get Byte Array and covert to char*
1281     jint length = (*env)->GetArrayLength(env, data);
1282
1283     jboolean isCopy;
1284     jbyte *jni_byte_requestData = (char*)(*env)->GetByteArrayElements(env, data, &isCopy);
1285
1286     char* requestData = NULL;
1287     requestData = (char*) OICMalloc (length + 1);
1288     memset(requestData, 0, length + 1);
1289     strncpy(requestData, (char*)jni_byte_requestData, length);
1290     requestData[length] = '\0';
1291     (*env)->ReleaseByteArrayElements(env, data, jni_byte_requestData, JNI_ABORT);
1292
1293     jstring jni_address = CALEGetAddressFromBTDevice(env, device);
1294     const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
1295     OIC_LOG_V(DEBUG, TAG, "remote device address : %s", address);
1296
1297     gPacketReceiveCallback(address, requestData);
1298 }
1299
1300 JNIEXPORT void JNICALL
1301 Java_com_iotivity_jar_CALeInterface_CALeGattServerDescriptorReadRequestCallback
1302 (JNIEnv *env, jobject obj, jobject device, jint requestId, jint offset, jobject descriptor)
1303 {
1304     OIC_LOG_V(DEBUG, TAG, "CALeInterface_CALeGattServerDescriptorReadRequestCallback");
1305 }
1306
1307 JNIEXPORT void JNICALL
1308 Java_com_iotivity_jar_CALeInterface_CALeGattServerDescriptorWriteRequestCallback
1309 (JNIEnv *env, jobject obj, jobject device, jint requestId, jobject descriptor,
1310         jboolean preparedWrite, jboolean responseNeeded, jint offset, jbyteArray value)
1311 {
1312     OIC_LOG_V(DEBUG, TAG, "CALeInterface_CALeGattServerDescriptorWriteRequestCallback");
1313 }
1314
1315 JNIEXPORT void JNICALL
1316 Java_com_iotivity_jar_CALeInterface_CALeGattServerExecuteWriteCallback
1317 (JNIEnv *env, jobject obj, jobject device, jint requestId, jboolean execute)
1318 {
1319     OIC_LOG_V(DEBUG, TAG, "CALeInterface_CALeGattServerExecuteWriteCallback");
1320
1321     CANativeLEServerSendResponse(env, device, requestId, 0, 0, NULL);
1322 }
1323
1324 JNIEXPORT void JNICALL
1325 Java_com_iotivity_jar_CALeInterface_CALeGattServerNotificationSentCallback
1326 (JNIEnv *env, jobject obj, jobject device, jint status)
1327 {
1328     OIC_LOG_V(DEBUG, TAG, "CALeInterface - Gatt Server Notification Sent Callback");
1329 }
1330
1331 JNIEXPORT void JNICALL
1332 Java_com_iotivity_jar_CALeInterface_CALeAdvertiseStartSuccessCallback
1333 (JNIEnv *env, jobject obj, jobject settingsInEffect)
1334 {
1335     OIC_LOG_V(DEBUG, TAG, "CALeInterface - LE Advertise Start Success Callback");
1336 }
1337
1338 JNIEXPORT void JNICALL
1339 Java_com_iotivity_jar_CALeInterface_CALeAdvertiseStartFailureCallback
1340 (JNIEnv *env, jobject obj, jint errorCode)
1341 {
1342     OIC_LOG_V(DEBUG, TAG, "CALeInterface - LE Advertise Start Failure Callback(%)", errorCode);
1343 }
1344