Tizen, Android BT , BLE optimization - making similar to wifi, eth adapters
[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(jarrayObj == NULL) {
927                 OIC_LOG(DEBUG, TAG, "jarrayObj is null");
928             }
929
930             if(!strcmp(setAddress, address))
931             {
932                 OIC_LOG(DEBUG, TAG, "device address matched");
933                 jni_obj_bluetoothDevice = jarrayObj;
934                 break;
935             }
936             jni_obj_bluetoothDevice = jarrayObj;
937         }
938
939         if(jni_obj_bluetoothDevice)
940         {
941             jbyteArray jni_bytearr_data = (*env)->NewByteArray(env, dataLen);
942             (*env)->SetByteArrayRegion(env, jni_bytearr_data, 0, dataLen, (jbyte*)data);
943
944             CALEServerSend(env, jni_obj_bluetoothDevice, jni_bytearr_data);
945
946         } else {
947             OIC_LOG(DEBUG, TAG, "jni_obj_bluetoothDevice is null");
948         }
949     }
950     return 0;
951 }
952
953 int32_t CALEServerSendMulticastMessageImpl(JNIEnv *env, const char* data, uint32_t dataLen)
954 {
955     OIC_LOG_V(DEBUG, TAG, "CALEServerSendMulticastMessageImpl, send to, data: %s", data);
956
957     if(!gConnectedDeviceList)
958     {
959         OIC_LOG(DEBUG, TAG, "gConnectedDeviceList is null");
960         return 0;
961     }
962
963     // 1. get all the device objects from cache
964     // 2. connect to the gatt client devices
965     // 3. write a characteristic for response
966     // 4. notify it to every devices
967     // 5. disconnect
968
969     jint index;
970     for (index = 0; index < u_arraylist_length(gConnectedDeviceList); index++)
971     {
972         jobject jarrayObj = (jobject) u_arraylist_get(gConnectedDeviceList, index);
973         if(!jarrayObj)
974         {
975             OIC_LOG(DEBUG, TAG, "jarrayObj is null");
976             return -1;
977         }
978
979         gIsSendingMulticastData = TRUE;
980         CANativeLEServerConnect(env, jarrayObj);
981
982         sleep(1);
983     }
984
985     return 0;
986 }
987
988 JNIEXPORT void JNICALL Java_com_iotivity_jar_CALeInterface_CARegisterLeGattServerCallback
989   (JNIEnv *env, jobject obj, jobject callback)
990 {
991     OIC_LOG_V(DEBUG, TAG, "CALeInterface - Register Le Gatt Server Callback");
992
993     gBluetoothGattServerCallback = (*env)->NewGlobalRef(env, callback);
994 }
995
996 JNIEXPORT void JNICALL Java_com_iotivity_jar_CALeInterface_CARegisterBluetoothLeAdvertiseCallback
997   (JNIEnv *env, jobject obj, jobject callback)
998 {
999     OIC_LOG_V(DEBUG, TAG, "CALeInterface - Register Le Advertise Callback");
1000
1001     gLeAdvertiseCallback = (*env)->NewGlobalRef(env, callback);
1002 }
1003
1004 JNIEXPORT void JNICALL Java_com_iotivity_jar_CALeInterface_CALeGattServerConnectionStateChangeCallback
1005   (JNIEnv *env, jobject obj, jobject device, jint status, jint newState)
1006 {
1007     OIC_LOG_V(DEBUG, TAG, "CALeInterface - Gatt Server ConnectionStateChange Callback");
1008
1009     OIC_LOG_V(DEBUG, TAG, "New connection State: %d", newState);
1010
1011     if (!device)
1012     {
1013         OIC_LOG(DEBUG, TAG, "device is null");
1014         return;
1015     }
1016
1017     jclass jni_cid_bluetoothProfile = (*env)->FindClass(env,
1018             "android/bluetooth/BluetoothProfile");
1019
1020     jfieldID jni_fid_state_connected = (*env)->GetStaticFieldID(env,
1021             jni_cid_bluetoothProfile, "STATE_CONNECTED", "I");
1022
1023     jfieldID jni_fid_state_disconnected = (*env)->GetStaticFieldID(env,
1024                 jni_cid_bluetoothProfile, "STATE_DISCONNECTED", "I");
1025
1026     // STATE_CONNECTED
1027     jint jni_int_state_connected = (*env)->GetStaticIntField(env,
1028             jni_cid_bluetoothProfile, jni_fid_state_connected);
1029
1030     // STATE_DISCONNECTED
1031     jint jni_int_state_disconnected = (*env)->GetStaticIntField(env,
1032                 jni_cid_bluetoothProfile, jni_fid_state_disconnected);
1033
1034     if(newState == jni_int_state_connected)
1035     {
1036
1037         OIC_LOG_V(DEBUG, TAG, "LE CONNECTED");
1038
1039         jstring jni_remoteAddress = CALEGetAddressFromBTDevice(env, device);
1040         if (!jni_remoteAddress)
1041         {
1042             OIC_LOG(DEBUG, TAG, "jni_remoteAddress is null");
1043             return;
1044         }
1045
1046         const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
1047
1048         if (gConnectedDeviceList == NULL)
1049         {
1050             OIC_LOG_V(DEBUG, TAG, "gConnectedDeviceList is null");
1051         }
1052
1053         if(CALEServerIsDeviceInList(env, remoteAddress) == JNI_FALSE)
1054         {
1055             OIC_LOG_V(DEBUG, TAG, "add connected device to cache");
1056             CALEServerAddDeviceToList(env, device);
1057         }
1058
1059 //        // temp data
1060 //        if(gIsSendingMulticastData)
1061 //        {
1062 //            OIC_LOG_V(DEBUG, TAG, "send data");
1063 //
1064 //            const char* data = "HelloWorld~";
1065 //            uint32_t dataLen =  strlen(data);
1066 //            jbyteArray jni_bytearr_data = (*env)->NewByteArray(env, dataLen);
1067 //            (*env)->SetByteArrayRegion(env, jni_bytearr_data, 0, dataLen, (jbyte*)data);
1068 //            CALEServerSend(env, device, jni_bytearr_data);
1069 //            gIsSendingMulticastData = FALSE;
1070 //        }
1071
1072
1073     }
1074     else if(newState == jni_int_state_disconnected)
1075     {
1076         OIC_LOG_V(DEBUG, TAG, "LE DISCONNECTED");
1077     }
1078 }
1079
1080 void CALEServerCreateCachedDeviceList()
1081 {
1082     OIC_LOG(DEBUG, TAG, "CALEServerCreateCachedDeviceList");
1083
1084     // create new object array
1085     if (gConnectedDeviceList == NULL)
1086     {
1087         OIC_LOG_V(DEBUG, TAG, "Create device list");
1088
1089         gConnectedDeviceList = u_arraylist_create();
1090     }
1091 }
1092
1093 jboolean CALEServerIsDeviceInList(JNIEnv *env, const char* remoteAddress)
1094 {
1095     OIC_LOG(DEBUG, TAG, "CALEServerIsDeviceInList");
1096
1097     if(gConnectedDeviceList == NULL)
1098         OIC_LOG(DEBUG, TAG, "list is null");
1099
1100     uint32_t len = u_arraylist_length(gConnectedDeviceList);
1101
1102     uint32_t index;
1103     for (index = 0; index < u_arraylist_length(gConnectedDeviceList); index++)
1104     {
1105         jobject jarrayObj = (jobject) u_arraylist_get(gConnectedDeviceList, index);
1106
1107         if (!jarrayObj)
1108         {
1109             OIC_LOG(DEBUG, TAG, "jarrayObj is null");
1110             return JNI_TRUE;
1111         }
1112
1113         jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
1114         if (!jni_setAddress)
1115         {
1116             OIC_LOG(DEBUG, TAG, "jni_setAddress is null");
1117             return JNI_TRUE;
1118         }
1119
1120         const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress,
1121                 NULL);
1122
1123         if (!strcmp(remoteAddress, setAddress))
1124         {
1125             OIC_LOG_V(DEBUG, TAG, "the device is already set");
1126             return JNI_TRUE;
1127         }
1128         else
1129         {
1130             continue;
1131         }
1132     }
1133
1134     OIC_LOG_V(DEBUG, TAG, "no device in list");
1135     return JNI_FALSE;
1136 }
1137
1138 void CALEServerAddDeviceToList(JNIEnv *env, jobject device)
1139 {
1140     if (device == NULL)
1141     {
1142         OIC_LOG(DEBUG, TAG, "device is null");
1143         return;
1144     }
1145
1146     if (gConnectedDeviceList == NULL)
1147     {
1148         OIC_LOG(DEBUG, TAG, "list is null");
1149         return;
1150     }
1151
1152     jstring jni_remoteAddress = CALEGetAddressFromBTDevice(env, device);
1153     if (!jni_remoteAddress)
1154     {
1155         OIC_LOG(DEBUG, TAG, "jni_remoteAddress is null");
1156         return;
1157     }
1158
1159     const char* remoteAddress = (*env)->GetStringUTFChars(env,
1160             jni_remoteAddress, NULL);
1161
1162     if (CALEServerIsDeviceInList(env, remoteAddress) == JNI_FALSE)
1163     {
1164         jobject gdevice = (*env)->NewGlobalRef(env, device);
1165         u_arraylist_add(gConnectedDeviceList, gdevice);
1166         OIC_LOG_V(DEBUG, TAG, "Set Object to Array as Element");
1167     }
1168 }
1169
1170 void CALEServerRemoveAllDevices(JNIEnv *env)
1171 {
1172     OIC_LOG_V(DEBUG, TAG, "CALEServerRemoveAllDevices");
1173
1174     if (!gConnectedDeviceList)
1175     {
1176         OIC_LOG(DEBUG, TAG, "no deviceList");
1177         return;
1178     }
1179
1180     uint32_t index;
1181     for (index = 0; index < u_arraylist_length(gConnectedDeviceList); index++)
1182     {
1183         jobject jarrayObj = (jobject) u_arraylist_get(gConnectedDeviceList, index);
1184
1185         if (jarrayObj)
1186         {
1187             (*env)->DeleteGlobalRef(env, jarrayObj);
1188         }
1189     }
1190
1191     OICFree(gConnectedDeviceList);
1192     gConnectedDeviceList = NULL;
1193     return;
1194 }
1195
1196 void CALEServerRemoveDevice(JNIEnv *env, jstring address)
1197 {
1198     OIC_LOG_V(DEBUG, TAG, "CALEServerRemoveDevice");
1199
1200     if (!gConnectedDeviceList)
1201     {
1202         OIC_LOG(DEBUG, TAG, "no deviceList");
1203         return;
1204     }
1205
1206     uint32_t index;
1207     for (index = 0; index < u_arraylist_length(gConnectedDeviceList); index++)
1208     {
1209         jobject jarrayObj = (jobject) u_arraylist_get(gConnectedDeviceList, index);
1210
1211         if (jarrayObj)
1212         {
1213             jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
1214             if (!jni_setAddress)
1215             {
1216                 OIC_LOG(DEBUG, TAG, "wrong device address");
1217                 continue;
1218             }
1219             const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress,
1220                     NULL);
1221             const char* remoteAddress = (*env)->GetStringUTFChars(env, address,
1222                     NULL);
1223
1224             if (!strcmp(setAddress, remoteAddress))
1225             {
1226                 OIC_LOG_V(DEBUG, TAG, "device address : %s", remoteAddress);
1227                 (*env)->DeleteGlobalRef(env, jarrayObj);
1228
1229                 CALEServerReorderinglist(index);
1230                 return;
1231             }
1232         }
1233     }
1234     OIC_LOG(DEBUG, TAG, "no target object");
1235     return;
1236 }
1237
1238 void CALEServerReorderinglist(uint32_t index)
1239 {
1240     if (index >= gConnectedDeviceList->length)
1241         return;
1242
1243     if (index < gConnectedDeviceList->length - 1)
1244     {
1245         memmove(&gConnectedDeviceList->data[index], &gConnectedDeviceList->data[index + 1],
1246                 (gConnectedDeviceList->length - index - 1) * sizeof(void *));
1247     }
1248
1249     gConnectedDeviceList->size--;
1250     gConnectedDeviceList->length--;
1251 }
1252
1253 JNIEXPORT void JNICALL
1254 Java_com_iotivity_jar_CALeInterface_CALeGattServerServiceAddedCallback
1255 (JNIEnv *env, jobject obj, jint status, jobject gattService)
1256 {
1257     OIC_LOG_V(DEBUG, TAG, "CALeInterface - Gatt Service Added Callback(%d)", status);
1258 }
1259
1260 JNIEXPORT void JNICALL
1261 Java_com_iotivity_jar_CALeInterface_CALeGattServerCharacteristicReadRequestCallback
1262 (JNIEnv *env, jobject obj, jobject device, jint requestId, jint offset, jobject characteristic, jbyteArray data)
1263 {
1264     OIC_LOG_V(DEBUG, TAG, "CALeInterface - Gatt Server Characteristic Read Request Callback");
1265
1266     CANativeLEServerSendResponse(env, device, requestId, 0, offset, NULL);
1267 }
1268
1269 JNIEXPORT void JNICALL
1270 Java_com_iotivity_jar_CALeInterface_CALeGattServerCharacteristicWriteRequestCallback
1271 (JNIEnv *env, jobject obj, jobject device, jint requestId, jobject characteristic, jbyteArray data,
1272         jboolean preparedWrite, jboolean responseNeeded, jint offset, jbyteArray value)
1273 {
1274     OIC_LOG_V(DEBUG, TAG, "CALeInterface - Gatt Server Characteristic Write Request Callback");
1275
1276     CANativeLEServerSendResponse(env, device, requestId, 0, offset, value);
1277
1278     if(data == NULL)
1279     {
1280         OIC_LOG_V(DEBUG, TAG, "Reqeust data is null");
1281         return;
1282     }
1283
1284     // get Byte Array and covert to char*
1285     jint length = (*env)->GetArrayLength(env, data);
1286
1287     jboolean isCopy;
1288     jbyte *jni_byte_requestData = (char*)(*env)->GetByteArrayElements(env, data, &isCopy);
1289
1290     char* requestData = NULL;
1291     requestData = (char*) OICMalloc (sizeof(char) * length);
1292     memset(requestData, 0, sizeof(char) * length);
1293     strncpy(requestData, (char*)jni_byte_requestData, length);
1294     requestData[length] = '\0';
1295     (*env)->ReleaseByteArrayElements(env, data, jni_byte_requestData, JNI_ABORT);
1296
1297     jstring jni_address = CALEGetAddressFromBTDevice(env, device);
1298     const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
1299     OIC_LOG_V(DEBUG, TAG, "remote device address : %s", address);
1300
1301     gPacketReceiveCallback(address, requestData);
1302 }
1303
1304 JNIEXPORT void JNICALL
1305 Java_com_iotivity_jar_CALeInterface_CALeGattServerDescriptorReadRequestCallback
1306 (JNIEnv *env, jobject obj, jobject device, jint requestId, jint offset, jobject descriptor)
1307 {
1308     OIC_LOG_V(DEBUG, TAG, "CALeInterface_CALeGattServerDescriptorReadRequestCallback");
1309 }
1310
1311 JNIEXPORT void JNICALL
1312 Java_com_iotivity_jar_CALeInterface_CALeGattServerDescriptorWriteRequestCallback
1313 (JNIEnv *env, jobject obj, jobject device, jint requestId, jobject descriptor,
1314         jboolean preparedWrite, jboolean responseNeeded, jint offset, jbyteArray value)
1315 {
1316     OIC_LOG_V(DEBUG, TAG, "CALeInterface_CALeGattServerDescriptorWriteRequestCallback");
1317 }
1318
1319 JNIEXPORT void JNICALL
1320 Java_com_iotivity_jar_CALeInterface_CALeGattServerExecuteWriteCallback
1321 (JNIEnv *env, jobject obj, jobject device, jint requestId, jboolean execute)
1322 {
1323     OIC_LOG_V(DEBUG, TAG, "CALeInterface_CALeGattServerExecuteWriteCallback");
1324
1325     CANativeLEServerSendResponse(env, device, requestId, 0, 0, NULL);
1326 }
1327
1328 JNIEXPORT void JNICALL
1329 Java_com_iotivity_jar_CALeInterface_CALeGattServerNotificationSentCallback
1330 (JNIEnv *env, jobject obj, jobject device, jint status)
1331 {
1332     OIC_LOG_V(DEBUG, TAG, "CALeInterface - Gatt Server Notification Sent Callback");
1333 }
1334
1335 JNIEXPORT void JNICALL
1336 Java_com_iotivity_jar_CALeInterface_CALeAdvertiseStartSuccessCallback
1337 (JNIEnv *env, jobject obj, jobject settingsInEffect)
1338 {
1339     OIC_LOG_V(DEBUG, TAG, "CALeInterface - LE Advertise Start Success Callback");
1340 }
1341
1342 JNIEXPORT void JNICALL
1343 Java_com_iotivity_jar_CALeInterface_CALeAdvertiseStartFailureCallback
1344 (JNIEnv *env, jobject obj, jint errorCode)
1345 {
1346     OIC_LOG_V(DEBUG, TAG, "CALeInterface - LE Advertise Start Failure Callback(%)", errorCode);
1347 }
1348