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