4 #include <android/log.h>
5 #include "caleserver.h"
8 #include "oic_malloc.h"
9 #include "uthreadpool.h"
10 #include "uarraylist.h"
11 #include "com_iotivity_jar_CALeInterface.h"
13 #define TAG PCF("CA_LE_SERVER")
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__)
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
24 static jobject gContext;
25 static jobject gBluetoothGattServer;
26 static jobject gBluetoothGattServerCallback;
27 static jobject gLeAdvertiseCallback;
29 static CAPacketReceiveCallback gPacketReceiveCallback = NULL;
30 static u_arraylist_t *gConnectedDeviceList = NULL;
31 static u_thread_pool_t gThreadPoolHandle = NULL;
33 static jboolean gIsStartServer;
34 static jboolean gIsSendingMulticastData;
37 void CALEServerJNISetContext(JNIEnv *env, jobject context)
39 OIC_LOG_V(DEBUG, TAG, "CALEServerJNISetContext");
42 OIC_LOG_V(DEBUG, TAG, "context is null");
44 gContext = (*env)->NewGlobalRef(env, context);
48 void CALeServerJniInit(JNIEnv *env, JavaVM *jvm)
50 OIC_LOG_V(DEBUG, TAG, "CALeServerJniInit");
54 jobject CANativeLEServerSetResponseData(JNIEnv *env, jbyteArray responseData)
56 if(!CALEIsEnableBTAdapter(env))
58 OIC_LOG(DEBUG, TAG, "[BLE][Native] BT adpater is not enable");
62 OIC_LOG_V(DEBUG, TAG, "CALEServerSetResponseData");
64 jclass jni_cid_bluetoothGattServer = (*env)->FindClass(env,
65 "android/bluetooth/BluetoothGattServer");
67 jclass jni_cid_bluetoothGattService = (*env)->FindClass(env,
68 "android/bluetooth/BluetoothGattService");
70 jclass jni_cid_bluetoothGattCharacteristic = (*env)->FindClass(env,
71 "android/bluetooth/BluetoothGattCharacteristic");
73 jmethodID jni_mid_getService = (*env)->GetMethodID(env,
74 jni_cid_bluetoothGattServer, "getService",
75 "(Ljava/util/UUID;)Landroid/bluetooth/BluetoothGattService;");
77 jobject jni_obj_serviceUUID = CALEGetUuidFromString(env, OIC_GATT_SERVICE_UUID);
79 if (!gBluetoothGattServer)
81 OIC_LOG_V(DEBUG, TAG, "Check BluetoothGattServer status");
84 jobject jni_obj_bluetoothGattService = (*env)->CallObjectMethod(env,
85 gBluetoothGattServer, jni_mid_getService, jni_obj_serviceUUID);
87 jmethodID jni_mid_getCharacteristic =
88 (*env)->GetMethodID(env, jni_cid_bluetoothGattService,
90 "(Ljava/util/UUID;)Landroid/bluetooth/BluetoothGattCharacteristic;");
92 jobject jni_obj_responseUUID = CALEGetUuidFromString(env,
93 OIC_GATT_CHARACTERISTIC_RESPONSE_UUID);
95 jobject jni_obj_bluetoothGattCharacteristic = (*env)->CallObjectMethod(env,
96 jni_obj_bluetoothGattService, jni_mid_getCharacteristic,
97 jni_obj_responseUUID);
99 jmethodID jni_mid_setValue = (*env)->GetMethodID(env,
100 jni_cid_bluetoothGattCharacteristic, "setValue",
103 jboolean jni_boolean_setValue = (*env)->CallBooleanMethod(env,
104 jni_obj_bluetoothGattCharacteristic, jni_mid_setValue,
107 if (jni_boolean_setValue == JNI_FALSE) {
108 OIC_LOG_V(DEBUG, TAG, "Fail to set response data");
111 return jni_obj_bluetoothGattCharacteristic;
114 jboolean CANativeLEServerSendResponseData(JNIEnv *env, jobject device, jobject responseData)
117 if(!CALEIsEnableBTAdapter(env))
119 OIC_LOG(DEBUG, TAG, "[BLE][Native] BT adpater is not enable");
123 OIC_LOG_V(DEBUG, TAG, "CALEServerSendResponseData");
125 jclass jni_cid_bluetoothGattServer = (*env)->FindClass(env,
126 "android/bluetooth/BluetoothGattServer");
128 jmethodID jni_mid_notifyCharacteristicChanged =
129 (*env)->GetMethodID(env, jni_cid_bluetoothGattServer,
130 "notifyCharacteristicChanged",
131 "(Landroid/bluetooth/BluetoothDevice;Landroid/bluetooth/BluetoothGattCharacteristic;Z)Z");
133 jboolean jni_boolean_notifyCharacteristicChanged =
134 (*env)->CallBooleanMethod(env, gBluetoothGattServer,
135 jni_mid_notifyCharacteristicChanged, device, responseData,
138 if (jni_boolean_notifyCharacteristicChanged == JNI_FALSE) {
139 OIC_LOG_V(DEBUG, TAG, "Fail to notify characteristic");
142 return jni_boolean_notifyCharacteristicChanged;
145 jboolean CANativeLEServerSendResponse(JNIEnv *env, jobject device, jint requestId, jint status,
146 jint offset, jbyteArray value)
149 if(!CALEIsEnableBTAdapter(env))
151 OIC_LOG(DEBUG, TAG, "[BLE][Native] BT adpater is not enable");
155 OIC_LOG_V(DEBUG, TAG, "CALEServerSendResponse");
157 jclass jni_cid_bluetoothGattServer = (*env)->FindClass(env,
158 "android/bluetooth/BluetoothGattServer");
160 jmethodID jni_mid_sendResponse = (*env)->GetMethodID(env,
161 jni_cid_bluetoothGattServer, "sendResponse",
162 "(Landroid/bluetooth/BluetoothDevice;III[B)Z");
164 jboolean jni_boolean_sendResponse = (*env)->CallBooleanMethod(env, gBluetoothGattServer,
165 jni_mid_sendResponse, device, requestId, status, offset, value);
167 if (jni_boolean_sendResponse == JNI_FALSE) {
168 OIC_LOG_V(DEBUG, TAG, "Fail to send response for gatt characteristic write request");
171 return jni_boolean_sendResponse;
174 void CANativeLEServerStartAdvertise(JNIEnv *env, jobject advertiseCallback)
177 OIC_LOG_V(DEBUG, TAG, "LEServerStartAdvertise");
179 if(!CALEIsEnableBTAdapter(env))
181 OIC_LOG(DEBUG, TAG, "[BLE][Native] BT adpater is not enable");
185 jclass jni_cid_AdvertiseSettings = (*env)->FindClass(env,
186 "android/bluetooth/le/AdvertiseSettings$Builder");
188 jclass jni_cid_AdvertiseDataBuilder = (*env)->FindClass(env,
189 "android/bluetooth/le/AdvertiseData$Builder");
191 jclass jni_cid_BTAdapter = (*env)->FindClass(env,
192 "android/bluetooth/BluetoothAdapter");
194 jclass jni_cid_leAdvertiser = (*env)->FindClass(env,
195 "android/bluetooth/le/BluetoothLeAdvertiser");
197 jmethodID jni_mid_AdvertiseSettings = (*env)->GetMethodID(env,
198 jni_cid_AdvertiseSettings, "<init>", "()V");
200 jmethodID jni_mid_setAdvertiseMode = (*env)->GetMethodID(env,
201 jni_cid_AdvertiseSettings, "setAdvertiseMode",
202 "(I)Landroid/bluetooth/le/AdvertiseSettings$Builder;");
204 jmethodID jni_mid_setConnectable = (*env)->GetMethodID(env,
205 jni_cid_AdvertiseSettings, "setConnectable",
206 "(Z)Landroid/bluetooth/le/AdvertiseSettings$Builder;");
208 jmethodID jni_mid_setTimeout = (*env)->GetMethodID(env,
209 jni_cid_AdvertiseSettings, "setTimeout",
210 "(I)Landroid/bluetooth/le/AdvertiseSettings$Builder;");
212 jmethodID jni_mid_AdvertiseDataBuilder = (*env)->GetMethodID(env,
213 jni_cid_AdvertiseDataBuilder, "<init>", "()V");
215 jmethodID jni_mid_addServiceUuid =
216 (*env)->GetMethodID(env, jni_cid_AdvertiseDataBuilder,
218 "(Landroid/os/ParcelUuid;)Landroid/bluetooth/le/AdvertiseData$Builder;");
220 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env,
221 jni_cid_BTAdapter, "getDefaultAdapter",
222 "()Landroid/bluetooth/BluetoothAdapter;");
224 jmethodID jni_mid_getBluetoothLeAdvertiser = (*env)->GetMethodID(env,
225 jni_cid_BTAdapter, "getBluetoothLeAdvertiser",
226 "()Landroid/bluetooth/le/BluetoothLeAdvertiser;");
228 jmethodID jni_mid_build_LeAdvertiseSettings = (*env)->GetMethodID(env,
229 jni_cid_AdvertiseSettings, "build",
230 "()Landroid/bluetooth/le/AdvertiseSettings;");
232 jmethodID jni_mid_build_LeAdvertiseData = (*env)->GetMethodID(env,
233 jni_cid_AdvertiseDataBuilder, "build",
234 "()Landroid/bluetooth/le/AdvertiseData;");
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");
240 jobject jni_AdvertiseSettings = (*env)->NewObject(env,
241 jni_cid_AdvertiseSettings, jni_mid_AdvertiseSettings);
243 jobject jni_obj_setAdvertiseMode = (*env)->CallObjectMethod(env,
244 jni_AdvertiseSettings, jni_mid_setAdvertiseMode, 0); // 0: Low power, 1: Balanced
246 jobject jni_obj_setConnectable = (*env)->CallObjectMethod(env,
247 jni_AdvertiseSettings, jni_mid_setConnectable, JNI_TRUE);
249 jobject jni_obj_setTimeout = (*env)->CallObjectMethod(env,
250 jni_AdvertiseSettings, jni_mid_setTimeout, 0); //A value of 0 will disable the time limit
252 jobject jni_AdvertiseDataBuilder = (*env)->NewObject(env,
253 jni_cid_AdvertiseDataBuilder, jni_mid_AdvertiseDataBuilder);
255 jobject jni_obj_serviceUUID = CALEGetUuidFromString(env, OIC_GATT_SERVICE_UUID);
257 jobject jni_ParcelUuid = CALEGetParcelUuid(env, jni_obj_serviceUUID);
259 jobject jni_obj_addServiceUuid = (*env)->CallObjectMethod(env,
260 jni_AdvertiseDataBuilder, jni_mid_addServiceUuid, jni_ParcelUuid);
262 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env,
263 jni_cid_BTAdapter, jni_mid_getDefaultAdapter);
265 jobject jni_obj_getBluetoothLeAdvertiser = (*env)->CallObjectMethod(env,
266 jni_obj_BTAdapter, jni_mid_getBluetoothLeAdvertiser);
268 jobject jni_obj_build_LeAdvertiseSettings = (*env)->CallObjectMethod(env,
269 jni_AdvertiseSettings, jni_mid_build_LeAdvertiseSettings);
271 jobject jni_obj_build_LeAdvertiseData = (*env)->CallObjectMethod(env,
272 jni_AdvertiseDataBuilder, jni_mid_build_LeAdvertiseData);
274 (*env)->CallVoidMethod(env, jni_obj_getBluetoothLeAdvertiser,
275 jni_mid_startAdvertising, jni_obj_build_LeAdvertiseSettings,
276 jni_obj_build_LeAdvertiseData, advertiseCallback);
278 OIC_LOG_V(DEBUG, TAG, "Advertising started!!");
281 void CANativeLEServerStopAdvertise(JNIEnv *env, jobject advertiseCallback)
284 OIC_LOG_V(DEBUG, TAG, "LEServerStopAdvertise");
286 if(!CALEIsEnableBTAdapter(env))
288 OIC_LOG(DEBUG, TAG, "[BLE][Native] BT adpater is not enable");
292 jclass jni_cid_BTAdapter = (*env)->FindClass(env,
293 "android/bluetooth/BluetoothAdapter");
295 jclass jni_cid_leAdvertiser = (*env)->FindClass(env,
296 "android/bluetooth/le/BluetoothLeAdvertiser");
298 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env,
299 jni_cid_BTAdapter, "getDefaultAdapter",
300 "()Landroid/bluetooth/BluetoothAdapter;");
302 jmethodID jni_mid_getBluetoothLeAdvertiser = (*env)->GetMethodID(env,
303 jni_cid_BTAdapter, "getBluetoothLeAdvertiser",
304 "()Landroid/bluetooth/le/BluetoothLeAdvertiser;");
306 jmethodID jni_mid_stopAdvertising =
307 (*env)->GetMethodID(env, jni_cid_leAdvertiser, "stopAdvertising",
308 "(Landroid/bluetooth/le/AdvertiseCallback;)V");
310 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env,
311 jni_cid_BTAdapter, jni_mid_getDefaultAdapter);
313 jobject jni_obj_getBluetoothLeAdvertiser = (*env)->CallObjectMethod(env,
314 jni_obj_BTAdapter, jni_mid_getBluetoothLeAdvertiser);
316 (*env)->CallVoidMethod(env, jni_obj_getBluetoothLeAdvertiser,
317 jni_mid_stopAdvertising, advertiseCallback);
319 OIC_LOG_V(DEBUG, TAG, "Advertising stopped!!");
322 jboolean CALEStartGattServer(JNIEnv *env, jobject gattServerCallback)
325 OIC_LOG_V(DEBUG, TAG, "CALEStartGattServer");
327 if(!CALEIsEnableBTAdapter(env))
329 OIC_LOG(DEBUG, TAG, "[BLE][Native] BT adpater is not enable");
334 OIC_LOG_V(DEBUG, TAG, "Gatt server already started");
336 gBluetoothGattServerCallback = (*env)->NewGlobalRef(env, gattServerCallback);
339 jobject bluetoothGattServer = CANativeLEServerOpenGattServer(env);
340 if(!bluetoothGattServer)
342 OIC_LOG_V(DEBUG, TAG, "bluetoothGattServer is null");
346 gBluetoothGattServer = (*env)->NewGlobalRef(env, bluetoothGattServer);
348 // create gatt service
349 jobject bluetoothGattService = CANativeLEServerCreateGattService(env);
352 return CANativeLEServerAddGattService(env, gBluetoothGattServer, bluetoothGattService);
355 jobject CANativeLEServerOpenGattServer(JNIEnv *env)
358 OIC_LOG_V(DEBUG, TAG, "CALEServerOpenGattServer");
360 if(!CALEIsEnableBTAdapter(env))
362 OIC_LOG(DEBUG, TAG, "[BLE][Native] BT adpater is not enable");
366 jclass jni_cid_context = (*env)->FindClass(env, "android/content/Context");
368 jclass jni_cid_bluetoothManager = (*env)->FindClass(env,
369 "android/bluetooth/BluetoothManager");
371 jfieldID jni_fid_bluetoothService = (*env)->GetStaticFieldID(env,
372 jni_cid_context, "BLUETOOTH_SERVICE", "Ljava/lang/String;");
374 jmethodID jni_mid_getSystemService = (*env)->GetMethodID(env,
375 jni_cid_context, "getSystemService",
376 "(Ljava/lang/String;)Ljava/lang/Object;");
378 jmethodID jni_mid_openGattServer =
379 (*env)->GetMethodID(env, jni_cid_bluetoothManager, "openGattServer",
380 "(Landroid/content/Context;Landroid/bluetooth/BluetoothGattServerCallback;)Landroid/bluetooth/BluetoothGattServer;");
382 jobject jni_obj_bluetoothService = (*env)->GetStaticObjectField(env,
383 jni_cid_context, jni_fid_bluetoothService);
384 if(!jni_obj_bluetoothService)
386 OIC_LOG_V(DEBUG, TAG, "jni_obj_bluetoothService is null");
391 jobject jni_obj_bluetoothManager = (*env)->CallObjectMethod(env, gContext,
392 jni_mid_getSystemService, jni_obj_bluetoothService);
393 if(!jni_obj_bluetoothManager)
395 OIC_LOG_V(DEBUG, TAG, "jni_obj_bluetoothManager is null");
399 jobject jni_obj_bluetoothGattServer = (*env)->CallObjectMethod(env,
400 jni_obj_bluetoothManager, jni_mid_openGattServer, gContext,
401 gBluetoothGattServerCallback);
402 if(!jni_obj_bluetoothGattServer)
404 OIC_LOG_V(DEBUG, TAG, "jni_obj_bluetoothGattServer is null");
408 return jni_obj_bluetoothGattServer;
411 jobject CANativeLEServerCreateGattService(JNIEnv *env)
414 OIC_LOG_V(DEBUG, TAG, "CALEServerCreateGattService");
416 if(!CALEIsEnableBTAdapter(env))
418 OIC_LOG(DEBUG, TAG, "[BLE][Native] BT adpater is not enable");
422 jclass jni_cid_bluetoothGattService = (*env)->FindClass(env,
423 "android/bluetooth/BluetoothGattService");
425 jclass jni_cid_bluetoothGattCharacteristic = (*env)->FindClass(env,
426 "android/bluetooth/BluetoothGattCharacteristic");
428 jfieldID jni_fid_serviceType = (*env)->GetStaticFieldID(env,
429 jni_cid_bluetoothGattService, "SERVICE_TYPE_PRIMARY", "I");
431 jfieldID jni_fid_readProperties = (*env)->GetStaticFieldID(env,
432 jni_cid_bluetoothGattCharacteristic, "PROPERTY_READ", "I");
434 jfieldID jni_fid_writeProperties = (*env)->GetStaticFieldID(env,
435 jni_cid_bluetoothGattCharacteristic, "PROPERTY_WRITE", "I");
437 jfieldID jni_fid_readPermissions = (*env)->GetStaticFieldID(env,
438 jni_cid_bluetoothGattCharacteristic, "PERMISSION_READ", "I");
440 jfieldID jni_fid_writePermissions = (*env)->GetStaticFieldID(env,
441 jni_cid_bluetoothGattCharacteristic, "PERMISSION_WRITE", "I");
443 jmethodID jni_mid_bluetoothGattService = (*env)->GetMethodID(env,
444 jni_cid_bluetoothGattService, "<init>", "(Ljava/util/UUID;I)V");
446 jmethodID jni_mid_addCharacteristic = (*env)->GetMethodID(env,
447 jni_cid_bluetoothGattService, "addCharacteristic",
448 "(Landroid/bluetooth/BluetoothGattCharacteristic;)Z");
450 jmethodID jni_mid_bluetoothGattCharacteristic = (*env)->GetMethodID(env,
451 jni_cid_bluetoothGattCharacteristic, "<init>",
452 "(Ljava/util/UUID;II)V");
454 jobject jni_obj_serviceUUID = CALEGetUuidFromString(env, OIC_GATT_SERVICE_UUID);
456 jobject jni_obj_serviceType = (*env)->GetStaticObjectField(env,
457 jni_cid_bluetoothGattService, jni_fid_serviceType);
459 jobject jni_bluetoothGattService = (*env)->NewObject(env,
460 jni_cid_bluetoothGattService, jni_mid_bluetoothGattService,
461 jni_obj_serviceUUID, jni_obj_serviceType);
463 jobject jni_obj_readUuid = CALEGetUuidFromString(env,
464 OIC_GATT_CHARACTERISTIC_RESPONSE_UUID);
466 jint jni_int_readProperties = (*env)->GetStaticIntField(env,
467 jni_cid_bluetoothGattCharacteristic, jni_fid_readProperties);
469 jint jni_int_readPermissions = (*env)->GetStaticIntField(env,
470 jni_cid_bluetoothGattCharacteristic, jni_fid_readPermissions);
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);
477 jboolean jni_boolean_addReadCharacteristic = (*env)->CallBooleanMethod(env,
478 jni_bluetoothGattService, jni_mid_addCharacteristic,
479 jni_readCharacteristic);
481 jobject jni_obj_writeUuid = CALEGetUuidFromString(env,
482 OIC_GATT_CHARACTERISTIC_REQUEST_UUID);
484 jint jni_int_writeProperties = (*env)->GetStaticIntField(env,
485 jni_cid_bluetoothGattCharacteristic, jni_fid_writeProperties);
487 jint jni_int_writePermissions = (*env)->GetStaticIntField(env,
488 jni_cid_bluetoothGattCharacteristic, jni_fid_writePermissions);
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);
495 jboolean jni_boolean_addWriteCharacteristic = (*env)->CallBooleanMethod(env,
496 jni_bluetoothGattService, jni_mid_addCharacteristic,
497 jni_writeCharacteristic);
499 if (jni_boolean_addWriteCharacteristic == JNI_FALSE)
501 OIC_LOG_V(DEBUG, TAG, "Fail to add jni_boolean_addReadCharacteristic");
505 return jni_bluetoothGattService;
508 jboolean CANativeLEServerAddGattService(JNIEnv *env, jobject bluetoothGattServer,
509 jobject bluetoothGattService)
512 OIC_LOG_V(DEBUG, TAG, "CALEServerAddGattService");
514 if(!CALEIsEnableBTAdapter(env))
516 OIC_LOG(DEBUG, TAG, "[BLE][Native] BT adpater is not enable");
520 jclass jni_cid_bluetoothGattServer = (*env)->FindClass(env,
521 "android/bluetooth/BluetoothGattServer");
523 jmethodID jni_mid_addService = (*env)->GetMethodID(env,
524 jni_cid_bluetoothGattServer, "addService",
525 "(Landroid/bluetooth/BluetoothGattService;)Z");
527 jboolean jni_boolean_addService = (*env)->CallBooleanMethod(env, bluetoothGattServer,
528 jni_mid_addService, bluetoothGattService);
530 if (jni_boolean_addService == JNI_FALSE)
532 OIC_LOG_V(DEBUG, TAG, "Fail to add gatt service");
535 return jni_boolean_addService;
538 jboolean CANativeLEServerConnect(JNIEnv *env, jobject bluetoothDevice)
541 OIC_LOG_V(DEBUG, TAG, "CALEConnect");
543 if(!CALEIsEnableBTAdapter(env))
545 OIC_LOG(DEBUG, TAG, "[BLE][Native] BT adpater is not enable");
549 jclass jni_cid_bluetoothGattServer = (*env)->FindClass(env,
550 "android/bluetooth/BluetoothGattServer");
552 jmethodID jni_mid_connect = (*env)->GetMethodID(env,
553 jni_cid_bluetoothGattServer, "connect",
554 "(Landroid/bluetooth/BluetoothDevice;Z)Z");
556 jboolean jni_boolean_connect = (*env)->CallBooleanMethod(env,
557 gBluetoothGattServer, jni_mid_connect, bluetoothDevice, JNI_FALSE);
559 if(jni_boolean_connect == JNI_FALSE) {
560 OIC_LOG_V(DEBUG, TAG, "Fail to connect");
563 return jni_boolean_connect;
566 void CANativeLEServerDisconnect(JNIEnv *env, jobject bluetoothDevice)
569 OIC_LOG_V(DEBUG, TAG, "CALEDisconnect");
571 if(!CALEIsEnableBTAdapter(env))
573 OIC_LOG(DEBUG, TAG, "[BLE][Native] BT adpater is not enable");
577 jclass jni_cid_bluetoothGattServer = (*env)->FindClass(env,
578 "android/bluetooth/BluetoothGattServer");
580 jmethodID jni_mid_cancelConnection = (*env)->GetMethodID(env,
581 jni_cid_bluetoothGattServer, "cancelConnection",
582 "(Landroid/bluetooth/BluetoothDevice;)V");
584 (*env)->CallVoidMethod(env, gBluetoothGattServer, jni_mid_cancelConnection,
588 jboolean CALEServerSend(JNIEnv *env, jobject bluetoothDevice, jbyteArray responseData)
591 OIC_LOG_V(DEBUG, TAG, "CALESend");
593 if(!CALEIsEnableBTAdapter(env))
595 OIC_LOG(DEBUG, TAG, "[BLE][Native] BT adpater is not enable");
599 jobject responseChar = CANativeLEServerSetResponseData(env, responseData);
601 jboolean result = CANativeLEServerSendResponseData(env, bluetoothDevice, responseChar);
603 if(result == JNI_FALSE)
605 OIC_LOG_V(DEBUG, TAG, "Fail to send response data");
611 void CALeServerCreateJniInterfaceObject()
613 OIC_LOG_V(DEBUG, TAG, "CALeServerCreateJniInterfaceObject");
615 jboolean isAttached = FALSE;
617 jint res = (*g_jvm)->GetEnv(g_jvm, (void**)&env, JNI_VERSION_1_6);
620 OIC_LOG_V(DEBUG, TAG, "Could not get JNIEnv pointer");
621 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
625 OIC_LOG_V(DEBUG, TAG, "AttachCurrentThread failed");
631 // initialize le server
634 (*g_jvm)->DetachCurrentThread(g_jvm);
637 void CALEServerInitialize(u_thread_pool_t handle)
639 OIC_LOG(DEBUG, TAG, "CALEServerInitialize");
641 gThreadPoolHandle = handle;
643 gIsSendingMulticastData = FALSE;
645 CALEServerCreateCachedDeviceList();
648 void CALEServerTerminate()
650 OIC_LOG(DEBUG, TAG, "CALEServerTerminate");
652 jboolean isAttached = FALSE;
654 jint res = (*g_jvm)->GetEnv(g_jvm, (void**)&env, JNI_VERSION_1_6);
657 OIC_LOG_V(DEBUG, TAG, "Could not get JNIEnv pointer");
658 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
662 OIC_LOG_V(DEBUG, TAG, "AttachCurrentThread failed");
668 CALEServerStopMulticastServer(0);
670 CALEServerRemoveAllDevices(env);
672 if(gLeAdvertiseCallback)
674 (*env)->DeleteGlobalRef(env, gLeAdvertiseCallback);
677 if(gBluetoothGattServer)
679 (*env)->DeleteGlobalRef(env, gBluetoothGattServer);
682 if(gBluetoothGattServerCallback)
684 (*env)->DeleteGlobalRef(env, gBluetoothGattServerCallback);
689 (*env)->DeleteGlobalRef(env, gContext);
692 gIsStartServer = FALSE;
695 (*g_jvm)->DetachCurrentThread(g_jvm);
698 int32_t CALEServerSendUnicastMessage(const char* address, const char* data, uint32_t dataLen)
700 OIC_LOG_V(DEBUG, TAG, "CALEServerSendUnicastMessage(%s, %s)", address, data);
702 jboolean isAttached = FALSE;
704 jint res = (*g_jvm)->GetEnv(g_jvm, (void**)&env, JNI_VERSION_1_6);
707 OIC_LOG_V(DEBUG, TAG, "Could not get JNIEnv pointer");
708 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
712 OIC_LOG_V(DEBUG, TAG, "AttachCurrentThread failed");
718 CALEServerSendUnicastMessageImpl(env, address, data, dataLen);
721 (*g_jvm)->DetachCurrentThread(g_jvm);
726 int32_t CALEServerSendMulticastMessage(const char* data, uint32_t dataLen)
728 OIC_LOG_V(DEBUG, TAG, "CALEServerSendMulticastMessage(%s)", data);
730 jboolean isAttached = FALSE;
732 jint res = (*g_jvm)->GetEnv(g_jvm, (void**)&env, JNI_VERSION_1_6);
735 OIC_LOG_V(DEBUG, TAG, "Could not get JNIEnv pointer");
736 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
740 OIC_LOG_V(DEBUG, TAG, "AttachCurrentThread failed");
746 CALEServerSendMulticastMessageImpl(env, data, dataLen);
749 (*g_jvm)->DetachCurrentThread(g_jvm);
754 int32_t CALEServerStartUnicastServer(const char* address)
756 OIC_LOG_V(DEBUG, TAG, "CALEServerStartUnicastServer(%s)", address);
761 int32_t CALEServerStartMulticastServer()
763 OIC_LOG_V(DEBUG, TAG, "CALEServerStartMulticastServer");
767 OIC_LOG_V(DEBUG, TAG, "server is already started..it will be skipped");
771 jboolean isAttached = FALSE;
773 jint res = (*g_jvm)->GetEnv(g_jvm, (void**)&env, JNI_VERSION_1_6);
776 OIC_LOG_V(DEBUG, TAG, "Could not get JNIEnv pointer");
777 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
781 OIC_LOG_V(DEBUG, TAG, "AttachCurrentThread failed");
787 gIsStartServer = TRUE;
790 if( CALEStartGattServer(env, gBluetoothGattServerCallback) == JNI_FALSE) {
791 OIC_LOG_V(DEBUG, TAG, "Fail to start gatt server");
796 CANativeLEServerStartAdvertise(env, gLeAdvertiseCallback);
799 (*g_jvm)->DetachCurrentThread(g_jvm);
804 int32_t CALEServerStopUnicastServer(int32_t serverID)
806 OIC_LOG(DEBUG, TAG, "CALEServerStopUnicastServer");
811 int32_t CALEServerStopMulticastServer(int32_t serverID)
813 OIC_LOG(DEBUG, TAG, "CALEServerStopMulticastServer");
815 if(gIsStartServer == FALSE)
817 OIC_LOG_V(DEBUG, TAG, "server is already stopped..it will be skipped");
821 jboolean isAttached = FALSE;
823 jint res = (*g_jvm)->GetEnv(g_jvm, (void**)&env, JNI_VERSION_1_6);
826 OIC_LOG_V(DEBUG, TAG, "Could not get JNIEnv pointer");
827 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
831 OIC_LOG_V(DEBUG, TAG, "AttachCurrentThread failed");
837 CANativeLEServerStopAdvertise(env, gLeAdvertiseCallback);
839 gIsStartServer = FALSE;
842 (*g_jvm)->DetachCurrentThread(g_jvm);
847 void CALEServerSetCallback(CAPacketReceiveCallback callback)
849 OIC_LOG(DEBUG, TAG, "CALEServerSetCallback");
850 gPacketReceiveCallback = callback;
853 void CALEServerGetInterfaceInfo(CALocalConnectivity_t **info, uint32_t* size)
855 OIC_LOG(DEBUG, TAG, "CALEServerGetInterfaceInfo");
859 void CALEServerGetLocalAddress(char* address)
861 OIC_LOG(DEBUG, TAG, "CALEServerGetLocalAddress");
863 jboolean isAttached = FALSE;
865 jint res = (*g_jvm)->GetEnv(g_jvm, (void**)&env, JNI_VERSION_1_6);
868 OIC_LOG_V(DEBUG, TAG, "Could not get JNIEnv pointer");
869 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
872 OIC_LOG_V(DEBUG, TAG, "AttachCurrentThread failed");
878 jstring jni_address = CALEGetLocalDeviceAddress(env);
879 const char* localAddress = (*env)->GetStringUTFChars(env, jni_address, NULL);
880 memcpy(address, localAddress, strlen(localAddress));
882 OIC_LOG_V(DEBUG, TAG, "Local Address : %s", address);
884 (*g_jvm)->DetachCurrentThread(g_jvm);
887 int32_t CALEServerSendUnicastMessageImpl(JNIEnv *env, const char* address, const char* data,
890 OIC_LOG_V(DEBUG, TAG, "CALEServerSendUnicastMessageImpl, address: %s, data: %s", address, data);
892 // 1. get device object with address from cache
893 // 2. connect to the gatt client device
894 // 3. write a characteristic for response
898 jobject jni_obj_bluetoothDevice = NULL;
900 if(gConnectedDeviceList == NULL)
902 OIC_LOG(DEBUG, TAG, "gConnectedDeviceList is null");
905 if(gConnectedDeviceList)
908 for (index = 0; index < u_arraylist_length(gConnectedDeviceList); index++)
910 OIC_LOG(DEBUG, TAG, "check device address");
911 jobject jarrayObj = (jobject) u_arraylist_get(gConnectedDeviceList, index);
914 OIC_LOG(DEBUG, TAG, "jarrayObj is null");
918 jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
921 OIC_LOG(DEBUG, TAG, "jni_setAddress is null");
924 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
926 if(jarrayObj == NULL) {
927 OIC_LOG(DEBUG, TAG, "jarrayObj is null");
930 if(!strcmp(setAddress, address))
932 OIC_LOG(DEBUG, TAG, "device address matched");
933 jni_obj_bluetoothDevice = jarrayObj;
936 jni_obj_bluetoothDevice = jarrayObj;
939 if(jni_obj_bluetoothDevice)
941 jbyteArray jni_bytearr_data = (*env)->NewByteArray(env, dataLen);
942 (*env)->SetByteArrayRegion(env, jni_bytearr_data, 0, dataLen, (jbyte*)data);
944 CALEServerSend(env, jni_obj_bluetoothDevice, jni_bytearr_data);
947 OIC_LOG(DEBUG, TAG, "jni_obj_bluetoothDevice is null");
953 int32_t CALEServerSendMulticastMessageImpl(JNIEnv *env, const char* data, uint32_t dataLen)
955 OIC_LOG_V(DEBUG, TAG, "CALEServerSendMulticastMessageImpl, send to, data: %s", data);
957 if(!gConnectedDeviceList)
959 OIC_LOG(DEBUG, TAG, "gConnectedDeviceList is null");
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
970 for (index = 0; index < u_arraylist_length(gConnectedDeviceList); index++)
972 jobject jarrayObj = (jobject) u_arraylist_get(gConnectedDeviceList, index);
975 OIC_LOG(DEBUG, TAG, "jarrayObj is null");
979 gIsSendingMulticastData = TRUE;
980 CANativeLEServerConnect(env, jarrayObj);
988 JNIEXPORT void JNICALL Java_com_iotivity_jar_CALeInterface_CARegisterLeGattServerCallback
989 (JNIEnv *env, jobject obj, jobject callback)
991 OIC_LOG_V(DEBUG, TAG, "CALeInterface - Register Le Gatt Server Callback");
993 gBluetoothGattServerCallback = (*env)->NewGlobalRef(env, callback);
996 JNIEXPORT void JNICALL Java_com_iotivity_jar_CALeInterface_CARegisterBluetoothLeAdvertiseCallback
997 (JNIEnv *env, jobject obj, jobject callback)
999 OIC_LOG_V(DEBUG, TAG, "CALeInterface - Register Le Advertise Callback");
1001 gLeAdvertiseCallback = (*env)->NewGlobalRef(env, callback);
1004 JNIEXPORT void JNICALL Java_com_iotivity_jar_CALeInterface_CALeGattServerConnectionStateChangeCallback
1005 (JNIEnv *env, jobject obj, jobject device, jint status, jint newState)
1007 OIC_LOG_V(DEBUG, TAG, "CALeInterface - Gatt Server ConnectionStateChange Callback");
1009 OIC_LOG_V(DEBUG, TAG, "New connection State: %d", newState);
1013 OIC_LOG(DEBUG, TAG, "device is null");
1017 jclass jni_cid_bluetoothProfile = (*env)->FindClass(env,
1018 "android/bluetooth/BluetoothProfile");
1020 jfieldID jni_fid_state_connected = (*env)->GetStaticFieldID(env,
1021 jni_cid_bluetoothProfile, "STATE_CONNECTED", "I");
1023 jfieldID jni_fid_state_disconnected = (*env)->GetStaticFieldID(env,
1024 jni_cid_bluetoothProfile, "STATE_DISCONNECTED", "I");
1027 jint jni_int_state_connected = (*env)->GetStaticIntField(env,
1028 jni_cid_bluetoothProfile, jni_fid_state_connected);
1030 // STATE_DISCONNECTED
1031 jint jni_int_state_disconnected = (*env)->GetStaticIntField(env,
1032 jni_cid_bluetoothProfile, jni_fid_state_disconnected);
1034 if(newState == jni_int_state_connected)
1037 OIC_LOG_V(DEBUG, TAG, "LE CONNECTED");
1039 jstring jni_remoteAddress = CALEGetAddressFromBTDevice(env, device);
1040 if (!jni_remoteAddress)
1042 OIC_LOG(DEBUG, TAG, "jni_remoteAddress is null");
1046 const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
1048 if (gConnectedDeviceList == NULL)
1050 OIC_LOG_V(DEBUG, TAG, "gConnectedDeviceList is null");
1053 if(CALEServerIsDeviceInList(env, remoteAddress) == JNI_FALSE)
1055 OIC_LOG_V(DEBUG, TAG, "add connected device to cache");
1056 CALEServerAddDeviceToList(env, device);
1060 // if(gIsSendingMulticastData)
1062 // OIC_LOG_V(DEBUG, TAG, "send data");
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;
1074 else if(newState == jni_int_state_disconnected)
1076 OIC_LOG_V(DEBUG, TAG, "LE DISCONNECTED");
1080 void CALEServerCreateCachedDeviceList()
1082 OIC_LOG(DEBUG, TAG, "CALEServerCreateCachedDeviceList");
1084 // create new object array
1085 if (gConnectedDeviceList == NULL)
1087 OIC_LOG_V(DEBUG, TAG, "Create device list");
1089 gConnectedDeviceList = u_arraylist_create();
1093 jboolean CALEServerIsDeviceInList(JNIEnv *env, const char* remoteAddress)
1095 OIC_LOG(DEBUG, TAG, "CALEServerIsDeviceInList");
1097 if(gConnectedDeviceList == NULL)
1098 OIC_LOG(DEBUG, TAG, "list is null");
1100 uint32_t len = u_arraylist_length(gConnectedDeviceList);
1103 for (index = 0; index < u_arraylist_length(gConnectedDeviceList); index++)
1105 jobject jarrayObj = (jobject) u_arraylist_get(gConnectedDeviceList, index);
1109 OIC_LOG(DEBUG, TAG, "jarrayObj is null");
1113 jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
1114 if (!jni_setAddress)
1116 OIC_LOG(DEBUG, TAG, "jni_setAddress is null");
1120 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress,
1123 if (!strcmp(remoteAddress, setAddress))
1125 OIC_LOG_V(DEBUG, TAG, "the device is already set");
1134 OIC_LOG_V(DEBUG, TAG, "no device in list");
1138 void CALEServerAddDeviceToList(JNIEnv *env, jobject device)
1142 OIC_LOG(DEBUG, TAG, "device is null");
1146 if (gConnectedDeviceList == NULL)
1148 OIC_LOG(DEBUG, TAG, "list is null");
1152 jstring jni_remoteAddress = CALEGetAddressFromBTDevice(env, device);
1153 if (!jni_remoteAddress)
1155 OIC_LOG(DEBUG, TAG, "jni_remoteAddress is null");
1159 const char* remoteAddress = (*env)->GetStringUTFChars(env,
1160 jni_remoteAddress, NULL);
1162 if (CALEServerIsDeviceInList(env, remoteAddress) == JNI_FALSE)
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");
1170 void CALEServerRemoveAllDevices(JNIEnv *env)
1172 OIC_LOG_V(DEBUG, TAG, "CALEServerRemoveAllDevices");
1174 if (!gConnectedDeviceList)
1176 OIC_LOG(DEBUG, TAG, "no deviceList");
1181 for (index = 0; index < u_arraylist_length(gConnectedDeviceList); index++)
1183 jobject jarrayObj = (jobject) u_arraylist_get(gConnectedDeviceList, index);
1187 (*env)->DeleteGlobalRef(env, jarrayObj);
1191 OICFree(gConnectedDeviceList);
1192 gConnectedDeviceList = NULL;
1196 void CALEServerRemoveDevice(JNIEnv *env, jstring address)
1198 OIC_LOG_V(DEBUG, TAG, "CALEServerRemoveDevice");
1200 if (!gConnectedDeviceList)
1202 OIC_LOG(DEBUG, TAG, "no deviceList");
1207 for (index = 0; index < u_arraylist_length(gConnectedDeviceList); index++)
1209 jobject jarrayObj = (jobject) u_arraylist_get(gConnectedDeviceList, index);
1213 jstring jni_setAddress = CALEGetAddressFromBTDevice(env, jarrayObj);
1214 if (!jni_setAddress)
1216 OIC_LOG(DEBUG, TAG, "wrong device address");
1219 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress,
1221 const char* remoteAddress = (*env)->GetStringUTFChars(env, address,
1224 if (!strcmp(setAddress, remoteAddress))
1226 OIC_LOG_V(DEBUG, TAG, "device address : %s", remoteAddress);
1227 (*env)->DeleteGlobalRef(env, jarrayObj);
1229 CALEServerReorderinglist(index);
1234 OIC_LOG(DEBUG, TAG, "no target object");
1238 void CALEServerReorderinglist(uint32_t index)
1240 if (index >= gConnectedDeviceList->length)
1243 if (index < gConnectedDeviceList->length - 1)
1245 memmove(&gConnectedDeviceList->data[index], &gConnectedDeviceList->data[index + 1],
1246 (gConnectedDeviceList->length - index - 1) * sizeof(void *));
1249 gConnectedDeviceList->size--;
1250 gConnectedDeviceList->length--;
1253 JNIEXPORT void JNICALL
1254 Java_com_iotivity_jar_CALeInterface_CALeGattServerServiceAddedCallback
1255 (JNIEnv *env, jobject obj, jint status, jobject gattService)
1257 OIC_LOG_V(DEBUG, TAG, "CALeInterface - Gatt Service Added Callback(%d)", status);
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)
1264 OIC_LOG_V(DEBUG, TAG, "CALeInterface - Gatt Server Characteristic Read Request Callback");
1266 CANativeLEServerSendResponse(env, device, requestId, 0, offset, NULL);
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)
1274 OIC_LOG_V(DEBUG, TAG, "CALeInterface - Gatt Server Characteristic Write Request Callback");
1276 CANativeLEServerSendResponse(env, device, requestId, 0, offset, value);
1280 OIC_LOG_V(DEBUG, TAG, "Reqeust data is null");
1284 // get Byte Array and covert to char*
1285 jint length = (*env)->GetArrayLength(env, data);
1288 jbyte *jni_byte_requestData = (char*)(*env)->GetByteArrayElements(env, data, &isCopy);
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);
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);
1301 gPacketReceiveCallback(address, requestData);
1304 JNIEXPORT void JNICALL
1305 Java_com_iotivity_jar_CALeInterface_CALeGattServerDescriptorReadRequestCallback
1306 (JNIEnv *env, jobject obj, jobject device, jint requestId, jint offset, jobject descriptor)
1308 OIC_LOG_V(DEBUG, TAG, "CALeInterface_CALeGattServerDescriptorReadRequestCallback");
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)
1316 OIC_LOG_V(DEBUG, TAG, "CALeInterface_CALeGattServerDescriptorWriteRequestCallback");
1319 JNIEXPORT void JNICALL
1320 Java_com_iotivity_jar_CALeInterface_CALeGattServerExecuteWriteCallback
1321 (JNIEnv *env, jobject obj, jobject device, jint requestId, jboolean execute)
1323 OIC_LOG_V(DEBUG, TAG, "CALeInterface_CALeGattServerExecuteWriteCallback");
1325 CANativeLEServerSendResponse(env, device, requestId, 0, 0, NULL);
1328 JNIEXPORT void JNICALL
1329 Java_com_iotivity_jar_CALeInterface_CALeGattServerNotificationSentCallback
1330 (JNIEnv *env, jobject obj, jobject device, jint status)
1332 OIC_LOG_V(DEBUG, TAG, "CALeInterface - Gatt Server Notification Sent Callback");
1335 JNIEXPORT void JNICALL
1336 Java_com_iotivity_jar_CALeInterface_CALeAdvertiseStartSuccessCallback
1337 (JNIEnv *env, jobject obj, jobject settingsInEffect)
1339 OIC_LOG_V(DEBUG, TAG, "CALeInterface - LE Advertise Start Success Callback");
1342 JNIEXPORT void JNICALL
1343 Java_com_iotivity_jar_CALeInterface_CALeAdvertiseStartFailureCallback
1344 (JNIEnv *env, jobject obj, jint errorCode)
1346 OIC_LOG_V(DEBUG, TAG, "CALeInterface - LE Advertise Start Failure Callback(%)", errorCode);