summaryrefslogtreecommitdiffstats
path: root/java
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2020-05-02 03:40:59 +0200
committerSven Gothel <[email protected]>2020-05-02 03:40:59 +0200
commit51fe35b8c9128f9cc46be604a1d5d073c5ac1aca (patch)
tree0f3092334568d846fdf6d63ccf43eb14c2799376 /java
parentbc3784a6950cfd6ea24a27e194540f9e4629d370 (diff)
DBTManager Java: Add getAdapterListImpl()
getAdapterListImpl() JNI code utilizes new convert_vector_to_jobject(..) with given ctor function defined ad-hoc via lambda.
Diffstat (limited to 'java')
-rw-r--r--java/direct_bt/tinyb/DBTAdapter.java51
-rw-r--r--java/direct_bt/tinyb/DBTManager.java1
-rw-r--r--java/jni/direct_bt/DBTAdapter.cxx30
-rw-r--r--java/jni/direct_bt/DBTManager.cxx57
4 files changed, 96 insertions, 43 deletions
diff --git a/java/direct_bt/tinyb/DBTAdapter.java b/java/direct_bt/tinyb/DBTAdapter.java
index 5b2087bc..2bc028b2 100644
--- a/java/direct_bt/tinyb/DBTAdapter.java
+++ b/java/direct_bt/tinyb/DBTAdapter.java
@@ -189,13 +189,23 @@ public class DBTAdapter extends DBTObject implements BluetoothAdapter
private native void initImpl(final BluetoothDeviceStatusListener l);
+ private synchronized void open() {
+ if( !isOpen ) {
+ isOpen = openImpl();
+ }
+ }
+ private native boolean openImpl();
+ boolean isOpen = false;
+
@Override
protected native void deleteImpl();
/* discovery */
@Override
- public boolean startDiscovery() throws BluetoothException {
+ public synchronized boolean startDiscovery() throws BluetoothException {
+ open();
+ removeDevices();
final boolean res = startDiscoveryImpl();
isDiscovering = res;
synchronized( stateLock ) {
@@ -207,7 +217,8 @@ public class DBTAdapter extends DBTObject implements BluetoothAdapter
private native boolean startDiscoveryImpl() throws BluetoothException;
@Override
- public boolean stopDiscovery() throws BluetoothException {
+ public synchronized boolean stopDiscovery() throws BluetoothException {
+ open();
isDiscovering = false;
final boolean res = stopDiscoveryImpl();
synchronized( stateLock ) {
@@ -220,11 +231,16 @@ public class DBTAdapter extends DBTObject implements BluetoothAdapter
@Override
public List<BluetoothDevice> getDevices() {
- return getDiscoveredDevices();
+ synchronized(discoveredDevicesLock) {
+ return new ArrayList<BluetoothDevice>(discoveredDevices);
+ }
}
+ // std::vector<std::shared_ptr<direct_bt::HCIDevice>> discoveredDevices = adapter.getDiscoveredDevices();
+ private native List<BluetoothDevice> getDiscoveredDevicesImpl();
@Override
public int removeDevices() throws BluetoothException {
+ open();
final int cj = removeDiscoveredDevices();
final int cn = removeDevicesImpl();
if( cj != cn ) {
@@ -233,6 +249,13 @@ public class DBTAdapter extends DBTObject implements BluetoothAdapter
return cn;
}
private native int removeDevicesImpl() throws BluetoothException;
+ private int removeDiscoveredDevices() {
+ synchronized(discoveredDevicesLock) {
+ final int n = discoveredDevices.size();
+ discoveredDevices = new ArrayList<BluetoothDevice>();
+ return n;
+ }
+ }
@Override
public boolean getDiscovering() { return isDiscovering; }
@@ -270,9 +293,6 @@ public class DBTAdapter extends DBTObject implements BluetoothAdapter
private native void setDiscoveryFilter(List<String> uuids, int rssi, int pathloss, int transportType);
- // std::vector<std::shared_ptr<direct_bt::HCIDevice>> discoveredDevices = adapter.getDiscoveredDevices();
- private native List<BluetoothDevice> getDiscoveredDevicesImpl();
-
////////////////////////////////////
private final Object stateLock = new Object();
@@ -286,7 +306,7 @@ public class DBTAdapter extends DBTObject implements BluetoothAdapter
@Override
public void deviceFound(final BluetoothAdapter a, final BluetoothDevice device, final long timestamp) {
final BluetoothDeviceStatusListener l = userDeviceStatusListener;
- System.err.println("DBTAdapter.DeviceStatusListener.added: "+device+" on "+a);
+ System.err.println("DBTAdapter.DeviceStatusListener.found: "+device+" on "+a);
synchronized(discoveredDevicesLock) {
discoveredDevices.add(device);
}
@@ -314,32 +334,17 @@ public class DBTAdapter extends DBTObject implements BluetoothAdapter
public void deviceDisconnected(final BluetoothAdapter a, final BluetoothDevice device, final long timestamp) {
final BluetoothDeviceStatusListener l = userDeviceStatusListener;
System.err.println("DBTAdapter.DeviceStatusListener.disconnected: "+device+" on "+a);
- synchronized(discoveredDevicesLock) {
- discoveredDevices.remove(device);
- }
if( null != l ) {
l.deviceDisconnected(a, device, timestamp);
}
}
};
- public void setDiscoveringNotificationCallback(final BluetoothNotification<Boolean> cb) {
+ private void setDiscoveringNotificationCallback(final BluetoothNotification<Boolean> cb) {
synchronized( stateLock ) {
discoveringNotificationCB = cb;
stateLock.notifyAll();
}
}
- public List<BluetoothDevice> getDiscoveredDevices() {
- synchronized(discoveredDevicesLock) {
- return new ArrayList<BluetoothDevice>(discoveredDevices);
- }
- }
- public int removeDiscoveredDevices() {
- synchronized(discoveredDevicesLock) {
- final int n = discoveredDevices.size();
- discoveredDevices = new ArrayList<BluetoothDevice>();
- return n;
- }
- }
private static AtomicInteger globThreadID = new AtomicInteger(0);
private static int discoverTimeoutMS = 100;
}
diff --git a/java/direct_bt/tinyb/DBTManager.java b/java/direct_bt/tinyb/DBTManager.java
index e5f17ad6..4b200da3 100644
--- a/java/direct_bt/tinyb/DBTManager.java
+++ b/java/direct_bt/tinyb/DBTManager.java
@@ -114,6 +114,7 @@ public class DBTManager implements BluetoothManager
* @throws BluetoothException in case adapter is invalid or could not have been opened.
*/
private native DBTAdapter getDefaultAdapterImpl() throws BluetoothException;
+ private native List<BluetoothAdapter> getAdapterListImpl();
private native void initImpl() throws BluetoothException;
private native void deleteImpl();
diff --git a/java/jni/direct_bt/DBTAdapter.cxx b/java/jni/direct_bt/DBTAdapter.cxx
index 9c445639..5b5dff42 100644
--- a/java/jni/direct_bt/DBTAdapter.cxx
+++ b/java/jni/direct_bt/DBTAdapter.cxx
@@ -222,6 +222,21 @@ void Java_direct_1bt_tinyb_DBTAdapter_initImpl(JNIEnv *env, jobject obj, jobject
}
}
+jboolean Java_direct_1bt_tinyb_DBTAdapter_openImpl(JNIEnv *env, jobject obj) {
+ try {
+ DBTAdapter *adapter = getInstance<DBTAdapter>(env, obj);
+ DBG_PRINT("Java_direct_1bt_tinyb_DBTAdapter_deleteImpl %s", adapter->toString().c_str());
+ std::shared_ptr<direct_bt::HCISession> session = adapter->open();
+ if( nullptr == session ) {
+ throw BluetoothException("Couldn't open adapter "+adapter->toString(), E_FILE_LINE);
+ }
+ return JNI_TRUE;
+ } catch(...) {
+ rethrow_and_raise_java_exception(env);
+ }
+ return JNI_FALSE;
+}
+
void Java_direct_1bt_tinyb_DBTAdapter_deleteImpl(JNIEnv *env, jobject obj)
{
try {
@@ -262,13 +277,14 @@ 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) {
- // 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;
- };
+ 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();
diff --git a/java/jni/direct_bt/DBTManager.cxx b/java/jni/direct_bt/DBTManager.cxx
index 9f045d3b..21f01f8f 100644
--- a/java/jni/direct_bt/DBTManager.cxx
+++ b/java/jni/direct_bt/DBTManager.cxx
@@ -80,26 +80,13 @@ jobject Java_direct_1bt_tinyb_DBTManager_getDefaultAdapterImpl(JNIEnv *env, jobj
delete adapter;
throw BluetoothException("Invalid default adapter dev-id "+std::to_string(defAdapterIdx), E_FILE_LINE);
}
- std::shared_ptr<direct_bt::HCISession> session = adapter->open();
- if( nullptr == session ) {
- delete adapter;
- throw BluetoothException("Couldn't open default adapter "+std::to_string(defAdapterIdx), E_FILE_LINE);
- }
// prepare adapter ctor
const jstring addr = from_string_to_jstring(env, adapter->getAddressString());
const jstring name = from_string_to_jstring(env, adapter->getName());
if( java_exception_check(env, E_FILE_LINE) ) { return nullptr; }
const jclass clazz = search_class(env, *adapter);
- if( java_exception_check(env, E_FILE_LINE) ) { return nullptr; }
- if( nullptr == clazz ) {
- throw InternalError("Adapter class not found: "+DBTAdapter::java_class(), E_FILE_LINE);
- }
const jmethodID clazz_ctor = search_method(env, clazz, "<init>", _adapterClazzCtorArgs.c_str(), false);
- if( java_exception_check(env, E_FILE_LINE) ) { return nullptr; }
- if( nullptr == clazz_ctor ) {
- throw InternalError("Adapter ctor not found: "+DBTAdapter::java_class()+".<init>"+_adapterClazzCtorArgs, E_FILE_LINE);
- }
jobject jAdapter = env->NewObject(clazz, clazz_ctor, (jlong)adapter, addr, name);
if( java_exception_check(env, E_FILE_LINE) ) { return nullptr; }
JNIGlobalRef::check(jAdapter, E_FILE_LINE);
@@ -114,3 +101,47 @@ jobject Java_direct_1bt_tinyb_DBTManager_getDefaultAdapterImpl(JNIEnv *env, jobj
return nullptr;
}
+jobject Java_direct_1bt_tinyb_DBTManager_getAdapterListImpl(JNIEnv *env, jobject obj)
+{
+ try {
+ DBTManager *manager = getInstance<DBTManager>(env, obj);
+ DBG_PRINT("Java_direct_1bt_tinyb_DBTManager_getAdapterListImpl: Manager %s", manager->toString().c_str());
+
+ // index == dev_id
+ 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 ) );
+ if( !adapter->isValid() ) {
+ throw BluetoothException("Invalid adapter @ idx "+std::to_string( idx ), E_FILE_LINE);
+ }
+ if( !adapter->hasDevId() ) {
+ throw BluetoothException("Invalid adapter dev-id @ idx "+std::to_string( idx ), E_FILE_LINE);
+ }
+ 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);
+ }
+ 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());
+ if( java_exception_check(env, E_FILE_LINE) ) { return nullptr; }
+ jobject jAdapter = env->NewObject(clazz, clazz_ctor, (jlong)adapter, addr, name);
+ if( java_exception_check(env, E_FILE_LINE) ) { return nullptr; }
+ JNIGlobalRef::check(jAdapter, E_FILE_LINE);
+ std::shared_ptr<JavaAnonObj> jAdapterRef = adapter->getJavaObject();
+ JavaGlobalObj::check(jAdapterRef, E_FILE_LINE);
+
+ DBG_PRINT("Java_direct_1bt_tinyb_DBTManager_getAdapterListImpl: New Adapter %s", adapter->toString().c_str());
+ return JavaGlobalObj::GetObject(jAdapterRef);
+ };
+ return convert_vector_to_jobject<DBTAdapter>(env, adapters, _adapterClazzCtorArgs.c_str(), ctor_adapter);
+ } catch(...) {
+ rethrow_and_raise_java_exception(env);
+ }
+ return nullptr;
+}
+