diff options
-rw-r--r-- | examples/java/ScannerTinyB01.java | 22 | ||||
-rw-r--r-- | java/direct_bt/tinyb/DBTAdapter.java | 15 | ||||
-rw-r--r-- | java/direct_bt/tinyb/DBTManager.java | 2 | ||||
-rw-r--r-- | java/jni/direct_bt/DBTAdapter.cxx | 48 | ||||
-rw-r--r-- | java/jni/direct_bt/DBTManager.cxx | 12 | ||||
-rw-r--r-- | java/jni/direct_bt/DBTNativeDownlink.cxx | 3 | ||||
-rw-r--r-- | java/jni/helper_base.hpp | 38 | ||||
-rw-r--r-- | java/org/tinyb/BluetoothDeviceStatusListener.java | 2 |
8 files changed, 100 insertions, 42 deletions
diff --git a/examples/java/ScannerTinyB01.java b/examples/java/ScannerTinyB01.java index 3d606121..4005739b 100644 --- a/examples/java/ScannerTinyB01.java +++ b/examples/java/ScannerTinyB01.java @@ -38,6 +38,7 @@ import org.tinyb.BluetoothGattService; import org.tinyb.BluetoothManager; import org.tinyb.BluetoothNotification; import org.tinyb.BluetoothUtils; +import org.tinyb.EIRDataType; public class ScannerTinyB01 { static { @@ -95,6 +96,13 @@ public class ScannerTinyB01 { final BluetoothAdapter adapter; { final List<BluetoothAdapter> adapters = manager.getAdapters(); + for(int i=0; i < adapters.size(); i++) { + System.err.println("Adapter["+i+"]: "+adapters.get(i)); + } + if( adapters.size() <= dev_id ) { + System.err.println("No adapter dev_id "+dev_id+" available, adapter count "+adapters.size()); + System.exit(-1); + } adapter = adapters.get(dev_id); } @@ -104,8 +112,8 @@ public class ScannerTinyB01 { @Override public void deviceFound(final BluetoothAdapter adapter, final BluetoothDevice device, final long timestamp) { final boolean matches = device.getAddress().equals(mac); - System.err.println("****** ADDED__: "+device.toString()+" - match "+matches); - System.err.println("Status HCIAdapter:"); + System.err.println("****** FOUND__: "+device.toString()+" - match "+matches); + System.err.println("Status Adapter:"); System.err.println(adapter.toString()); if( matches ) { @@ -117,10 +125,10 @@ public class ScannerTinyB01 { } @Override - public void deviceUpdated(final BluetoothAdapter adapter, final BluetoothDevice device, final long timestamp) { + public void deviceUpdated(final BluetoothAdapter a, final BluetoothDevice device, final long timestamp, final EIRDataType updateMask) { final boolean matches = device.getAddress().equals(mac); - System.err.println("****** UPDATED: "+device.toString()+" - match "+matches); - System.err.println("Status HCIAdapter:"); + System.err.println("****** UPDATED: "+updateMask+" of "+device+" - match "+matches); + System.err.println("Status Adapter:"); System.err.println(adapter.toString()); } @@ -128,7 +136,7 @@ public class ScannerTinyB01 { public void deviceConnected(final BluetoothAdapter adapter, final BluetoothDevice device, final long timestamp) { final boolean matches = device.getAddress().equals(mac); System.err.println("****** CONNECTED: "+device.toString()+" - match "+matches); - System.err.println("Status HCIAdapter:"); + System.err.println("Status Adapter:"); System.err.println(adapter.toString()); } @@ -136,7 +144,7 @@ public class ScannerTinyB01 { public void deviceDisconnected(final BluetoothAdapter adapter, final BluetoothDevice device, final long timestamp) { final boolean matches = device.getAddress().equals(mac); System.err.println("****** DISCONNECTED: "+device.toString()+" - match "+matches); - System.err.println("Status HCIAdapter:"); + System.err.println("Status Adapter:"); System.err.println(adapter.toString()); } }; diff --git a/java/direct_bt/tinyb/DBTAdapter.java b/java/direct_bt/tinyb/DBTAdapter.java index 2bc028b2..a8b99fbd 100644 --- a/java/direct_bt/tinyb/DBTAdapter.java +++ b/java/direct_bt/tinyb/DBTAdapter.java @@ -38,6 +38,7 @@ import org.tinyb.BluetoothException; import org.tinyb.BluetoothManager; import org.tinyb.BluetoothNotification; import org.tinyb.BluetoothType; +import org.tinyb.EIRDataType; import org.tinyb.BluetoothDeviceStatusListener; import org.tinyb.TransportType; @@ -209,7 +210,9 @@ public class DBTAdapter extends DBTObject implements BluetoothAdapter final boolean res = startDiscoveryImpl(); isDiscovering = res; synchronized( stateLock ) { - discoveringNotificationCB.run(res); + if( null != discoveringNotificationCB ) { + discoveringNotificationCB.run(res); + } stateLock.notifyAll(); } return res; @@ -222,7 +225,9 @@ public class DBTAdapter extends DBTObject implements BluetoothAdapter isDiscovering = false; final boolean res = stopDiscoveryImpl(); synchronized( stateLock ) { - discoveringNotificationCB.run(false); + if( null != discoveringNotificationCB ) { + discoveringNotificationCB.run(false); + } stateLock.notifyAll(); } return res; @@ -316,10 +321,10 @@ public class DBTAdapter extends DBTObject implements BluetoothAdapter } @Override - public void deviceUpdated(final BluetoothAdapter a, final BluetoothDevice device, final long timestamp) { - System.err.println("DBTAdapter.DeviceStatusListener.updated: "+device+" on "+a); + public void deviceUpdated(final BluetoothAdapter a, final BluetoothDevice device, final long timestamp, final EIRDataType updateMask) { + System.err.println("DBTAdapter.DeviceStatusListener.updated: "+updateMask+" of "+device+" on "+a); // nop on discoveredDevices - userDeviceStatusListener.deviceUpdated(a, device, timestamp); + userDeviceStatusListener.deviceUpdated(a, device, timestamp, updateMask); } @Override diff --git a/java/direct_bt/tinyb/DBTManager.java b/java/direct_bt/tinyb/DBTManager.java index 4b200da3..4438c66f 100644 --- a/java/direct_bt/tinyb/DBTManager.java +++ b/java/direct_bt/tinyb/DBTManager.java @@ -122,7 +122,7 @@ public class DBTManager implements BluetoothManager { initImpl(); try { - adapters.add(getDefaultAdapterImpl()); + adapters.addAll(getAdapterListImpl()); } catch (final BluetoothException be) { be.printStackTrace(); } diff --git a/java/jni/direct_bt/DBTAdapter.cxx b/java/jni/direct_bt/DBTAdapter.cxx index 5b5dff42..5e6682d6 100644 --- a/java/jni/direct_bt/DBTAdapter.cxx +++ b/java/jni/direct_bt/DBTAdapter.cxx @@ -25,7 +25,7 @@ #include "direct_bt_tinyb_DBTAdapter.h" -// #define VERBOSE_ON 1 +#define VERBOSE_ON 1 #include <dbt_debug.hpp> #include "JNIMem.hpp" @@ -36,8 +36,11 @@ using namespace direct_bt; +static const std::string _eirDataTypeClassName("org/tinyb/EIRDataType"); +static const std::string _eirDataTypeClazzCreateArgs("(I)Lorg/tinyb/EIRDataType;"); static const std::string _deviceClazzCtorArgs("(JLdirect_bt/tinyb/DBTAdapter;Ljava/lang/String;Ljava/lang/String;J)V"); static const std::string _deviceStatusMethodArgs("(Lorg/tinyb/BluetoothAdapter;Lorg/tinyb/BluetoothDevice;J)V"); +static const std::string _deviceStatusUpdateMethodArgs("(Lorg/tinyb/BluetoothAdapter;Lorg/tinyb/BluetoothDevice;JLorg/tinyb/EIRDataType;)V"); class DeviceStatusCallbackListener : public DBTDeviceStatusListener { public: @@ -46,12 +49,14 @@ class DeviceStatusCallbackListener : public DBTDeviceStatusListener { public interface BluetoothDeviceStatusListener { public void deviceFound(final BluetoothAdapter adapter, final BluetoothDevice device, final long timestamp); - public void deviceUpdated(final BluetoothAdapter adapter, final BluetoothDevice device, final long timestamp); + public void deviceUpdated(final BluetoothAdapter adapter, final BluetoothDevice device, final long timestamp, final EIRDataType updateMask); public void deviceConnected(final BluetoothAdapter adapter, final BluetoothDevice device, final long timestamp); public void deviceDisconnected(final BluetoothAdapter adapter, final BluetoothDevice device, final long timestamp); }; */ std::shared_ptr<JavaAnonObj> adapterObjRef; + std::unique_ptr<JNIGlobalRef> eirDataTypeClazzRef; + jmethodID eirDataTypeClazzCreate; std::unique_ptr<JNIGlobalRef> deviceClazzRef; jmethodID deviceClazzCtor; jfieldID deviceClazzTSUpdateField; @@ -65,6 +70,24 @@ class DeviceStatusCallbackListener : public DBTDeviceStatusListener { DeviceStatusCallbackListener(JNIEnv *env, DBTAdapter *adapter, jobject deviceDiscoveryListener) { adapterObjRef = adapter->getJavaObject(); JavaGlobalObj::check(adapterObjRef, E_FILE_LINE); + + // eirDataTypeClazzRef, eirDataTypeClazzCreate + { + jclass eirDataTypeClazz = search_class(env, _eirDataTypeClassName.c_str()); + java_exception_check_and_throw(env, E_FILE_LINE); + if( nullptr == eirDataTypeClazz ) { + throw InternalError("DBTDevice::java_class not found: "+_eirDataTypeClassName, E_FILE_LINE); + } + eirDataTypeClazzRef = std::unique_ptr<JNIGlobalRef>(new JNIGlobalRef(eirDataTypeClazz)); + env->DeleteLocalRef(eirDataTypeClazz); + } + eirDataTypeClazzCreate = search_method(env, eirDataTypeClazzRef->getClass(), "create", _eirDataTypeClazzCreateArgs.c_str(), true); + java_exception_check_and_throw(env, E_FILE_LINE); + if( nullptr == eirDataTypeClazzCreate ) { + throw InternalError("EIRDataType ctor not found: "+_eirDataTypeClassName+".create"+_eirDataTypeClazzCreateArgs, E_FILE_LINE); + } + + // deviceClazzRef, deviceClazzCtor { jclass deviceClazz = search_class(env, DBTDevice::java_class().c_str()); java_exception_check_and_throw(env, E_FILE_LINE); @@ -100,7 +123,7 @@ class DeviceStatusCallbackListener : public DBTDeviceStatusListener { if( nullptr == mDeviceFound ) { throw InternalError("BluetoothDeviceDiscoveryListener has no deviceFound"+_deviceStatusMethodArgs+" method, for "+adapter->toString(), E_FILE_LINE); } - mDeviceUpdated = search_method(env, listenerClazzRef->getClass(), "deviceUpdated", _deviceStatusMethodArgs.c_str(), false); + mDeviceUpdated = search_method(env, listenerClazzRef->getClass(), "deviceUpdated", _deviceStatusUpdateMethodArgs.c_str(), false); java_exception_check_and_throw(env, E_FILE_LINE); if( nullptr == mDeviceUpdated ) { throw InternalError("BluetoothDeviceDiscoveryListener has no deviceUpdated"+_deviceStatusMethodArgs+" method, for "+adapter->toString(), E_FILE_LINE); @@ -145,11 +168,11 @@ class DeviceStatusCallbackListener : public DBTDeviceStatusListener { rethrow_and_raise_java_exception(env); } } - void deviceUpdated(DBTAdapter const &a, std::shared_ptr<DBTDevice> device, const uint64_t timestamp) override { + void deviceUpdated(DBTAdapter const &a, std::shared_ptr<DBTDevice> device, const uint64_t timestamp, const EIRDataType updateMask) override { JNIEnv *env = *jni_env; try { #ifdef VERBOSE_ON - fprintf(stderr, "****** Native Adapter Device UPDATED: %s\n", device->toString().c_str()); + fprintf(stderr, "****** Native Adapter Device UPDATED: %s of %s\n", direct_bt::eirDataMaskToString(updateMask).c_str(), device->toString().c_str()); fprintf(stderr, "Status DBTAdapter:\n"); fprintf(stderr, "%s\n", a.toString().c_str()); #endif @@ -158,8 +181,10 @@ class DeviceStatusCallbackListener : public DBTDeviceStatusListener { JavaGlobalObj::check(jDeviceRef, E_FILE_LINE); env->SetLongField(JavaGlobalObj::GetObject(jDeviceRef), deviceClazzTSUpdateField, (jlong)timestamp); if( java_exception_check(env, E_FILE_LINE) ) { return; } + jobject eirDataType = env->CallStaticObjectMethod(eirDataTypeClazzRef->getClass(), eirDataTypeClazzCreate, (jint)updateMask); + if( java_exception_check(env, E_FILE_LINE) ) { return; } env->CallVoidMethod(listenerObjRef->getObject(), mDeviceUpdated, - JavaGlobalObj::GetObject(adapterObjRef), JavaGlobalObj::GetObject(jDeviceRef), (jlong)timestamp); + JavaGlobalObj::GetObject(adapterObjRef), JavaGlobalObj::GetObject(jDeviceRef), (jlong)timestamp, eirDataType); if( java_exception_check(env, E_FILE_LINE) ) { return; } } catch(...) { rethrow_and_raise_java_exception(env); @@ -276,17 +301,6 @@ jobject Java_direct_1bt_tinyb_DBTAdapter_getDiscoveredDevicesImpl(JNIEnv *env, j { try { DBTAdapter *adapter = getInstance<DBTAdapter>(env, obj); - /** - std::function<jobject(JNIEnv*, jclass, jmethodID, DBTDevice*)> ctor_device = - [](JNIEnv *env, jclass clazz, jmethodID clazz_ctor, DBTDevice *elem) -> jobject { - // Device(final long nativeInstance, final Adapter adptr, final String address, final String name) - jstring addr = from_string_to_jstring(env, elem->getAddressString()); - jstring name = from_string_to_jstring(env, elem->getName()); - jobject object = env->NewObject(clazz, clazz_ctor, (jlong)elem, obj, addr, name); - return object; - }; - return convert_vector_to_jobject<DBTDevice>(env, array, "(JLdirect_bt/tinyb/Adapter;Ljava/lang/String;Ljava/lang/String;)V", ctor_device); - */ std::vector<std::shared_ptr<DBTDevice>> array = adapter->getDiscoveredDevices(); return convert_vector_to_jobject(env, array); } catch(...) { diff --git a/java/jni/direct_bt/DBTManager.cxx b/java/jni/direct_bt/DBTManager.cxx index 1f24cbb1..eb22bded 100644 --- a/java/jni/direct_bt/DBTManager.cxx +++ b/java/jni/direct_bt/DBTManager.cxx @@ -25,7 +25,7 @@ #include "direct_bt_tinyb_DBTManager.h" -// #define VERBOSE_ON 1 +#define VERBOSE_ON 1 #include <dbt_debug.hpp> #include "JNIMem.hpp" @@ -109,10 +109,10 @@ jobject Java_direct_1bt_tinyb_DBTManager_getAdapterListImpl(JNIEnv *env, jobject DBG_PRINT("Java_direct_1bt_tinyb_DBTManager_getAdapterListImpl: Manager %s", manager->toString().c_str()); // index == dev_id + std::vector<std::unique_ptr<DBTAdapter>> adapters; const int adapterCount = manager->getAdapterCount(); - std::vector<std::shared_ptr<DBTAdapter>> adapters(adapterCount); for(int idx = 0; idx < adapterCount; idx++) { - std::shared_ptr<DBTAdapter> adapter(new DBTAdapter( idx ) ); + std::unique_ptr<DBTAdapter> adapter(new DBTAdapter( idx ) ); if( !adapter->isValid() ) { throw BluetoothException("Invalid adapter @ idx "+std::to_string( idx ), E_FILE_LINE); } @@ -122,10 +122,10 @@ jobject Java_direct_1bt_tinyb_DBTManager_getAdapterListImpl(JNIEnv *env, jobject if( idx != adapter->dev_id ) { // just make sure idx == dev_id throw BluetoothException("Invalid adapter dev-id "+std::to_string( adapter->dev_id )+" != index "+std::to_string( idx ), E_FILE_LINE); } - adapters.push_back(adapter); + adapters.push_back(std::move(adapter)); } - std::function<jobject(JNIEnv*, jclass, jmethodID, DBTAdapter*)> ctor_adapter= - [](JNIEnv *env, jclass clazz, jmethodID clazz_ctor, DBTAdapter *adapter)->jobject { + std::function<jobject(JNIEnv*, jclass, jmethodID, DBTAdapter*)> ctor_adapter = + [](JNIEnv *env, jclass clazz, jmethodID clazz_ctor, DBTAdapter* adapter)->jobject { // prepare adapter ctor const jstring addr = from_string_to_jstring(env, adapter->getAddressString()); const jstring name = from_string_to_jstring(env, adapter->getName()); diff --git a/java/jni/direct_bt/DBTNativeDownlink.cxx b/java/jni/direct_bt/DBTNativeDownlink.cxx index bc5e942d..4aebef7e 100644 --- a/java/jni/direct_bt/DBTNativeDownlink.cxx +++ b/java/jni/direct_bt/DBTNativeDownlink.cxx @@ -25,7 +25,7 @@ #include "direct_bt_tinyb_DBTNativeDownlink.h" -// #define VERBOSE_ON 1 +#define VERBOSE_ON 1 #include <dbt_debug.hpp> #include "JNIMem.hpp" @@ -43,6 +43,7 @@ void Java_direct_1bt_tinyb_DBTNativeDownlink_initNativeJavaObject(JNIEnv *env, j std::shared_ptr<JavaGlobalObj> jobjRef( new JavaGlobalObj(obj) ); javaUplink->setJavaObject( jobjRef ); JavaGlobalObj::check(javaUplink->getJavaObject(), E_FILE_LINE); + DBG_PRINT("Java_direct_1bt_tinyb_DBTNativeDownlink_initNativeJavaObject %s", javaUplink->toString().c_str()); } catch(...) { rethrow_and_raise_java_exception(env); } diff --git a/java/jni/helper_base.hpp b/java/jni/helper_base.hpp index e82df0f5..76a06a54 100644 --- a/java/jni/helper_base.hpp +++ b/java/jni/helper_base.hpp @@ -101,7 +101,7 @@ jobject generic_clone(JNIEnv *env, jobject obj) template <typename T> jobject convert_vector_to_jobject(JNIEnv *env, std::vector<std::unique_ptr<T>>& array, - const char *ctor_prototype) + const char *ctor_prototype) { unsigned int array_size = array.size(); @@ -130,8 +130,38 @@ jobject convert_vector_to_jobject(JNIEnv *env, std::vector<std::unique_ptr<T>>& } template <typename T> -jobject convert_vector_to_jobject(JNIEnv *env, std::vector<std::shared_ptr<T>>& array, - const char *ctor_prototype, std::function<jobject(JNIEnv*, jclass, jmethodID, T*)> ctor) +jobject convert_vector_to_jobject(JNIEnv *env, std::vector<std::unique_ptr<T>>& array, + const char *ctor_prototype, std::function<jobject(JNIEnv*, jclass, jmethodID, T*)> ctor) +{ + unsigned int array_size = array.size(); + + jmethodID arraylist_add; + jobject result = get_new_arraylist(env, array_size, &arraylist_add); + + if (array_size == 0) + { + return result; + } + + jclass clazz = search_class(env, T::java_class().c_str()); + jmethodID clazz_ctor = search_method(env, clazz, "<init>", ctor_prototype, false); + + for (unsigned int i = 0; i < array_size; ++i) + { + T *elem = array.at(i).release(); + jobject object = ctor(env, clazz, clazz_ctor, elem); + if (!object) + { + throw std::runtime_error("cannot create instance of class\n"); + } + env->CallBooleanMethod(result, arraylist_add, object); + } + return result; +} + +template <typename T> +jobject convert_vector_to_shared_jobject(JNIEnv *env, std::vector<std::shared_ptr<T>>& array, + const char *ctor_prototype, std::function<jobject(JNIEnv*, jclass, jmethodID, std::shared_ptr<T>)> ctor) { unsigned int array_size = array.size(); @@ -148,7 +178,7 @@ jobject convert_vector_to_jobject(JNIEnv *env, std::vector<std::shared_ptr<T>>& for (unsigned int i = 0; i < array_size; ++i) { - T *elem = array.at(i).get(); + std::shared_ptr<T> elem = array.at(i); jobject object = ctor(env, clazz, clazz_ctor, elem); if (!object) { diff --git a/java/org/tinyb/BluetoothDeviceStatusListener.java b/java/org/tinyb/BluetoothDeviceStatusListener.java index 184392ea..3220d106 100644 --- a/java/org/tinyb/BluetoothDeviceStatusListener.java +++ b/java/org/tinyb/BluetoothDeviceStatusListener.java @@ -36,7 +36,7 @@ public interface BluetoothDeviceStatusListener { /** A {@link BluetoothDevice} has been newly discovered. */ public void deviceFound(final BluetoothAdapter adapter, final BluetoothDevice device, final long timestamp); /** An already discovered {@link BluetoothDevice} has been updated. */ - public void deviceUpdated(final BluetoothAdapter adapter, final BluetoothDevice device, final long timestamp); + public void deviceUpdated(final BluetoothAdapter adapter, final BluetoothDevice device, final long timestamp, final EIRDataType updateMask); /** {@link BluetoothDevice} has been connected. */ public void deviceConnected(final BluetoothAdapter adapter, final BluetoothDevice device, final long timestamp); /** {@link BluetoothDevice} has been disconnected. */ |