aboutsummaryrefslogtreecommitdiffstats
path: root/java
diff options
context:
space:
mode:
Diffstat (limited to 'java')
-rw-r--r--java/direct_bt/tinyb/DBTAdapter.java132
-rw-r--r--java/jni/direct_bt/DBTAdapter.cxx128
-rw-r--r--java/org/tinyb/AdapterSettings.java138
-rw-r--r--java/org/tinyb/BluetoothAdapter.java6
-rw-r--r--java/org/tinyb/BluetoothAdapterStatusListener.java (renamed from java/org/tinyb/BluetoothDeviceStatusListener.java)13
-rw-r--r--java/org/tinyb/EIRDataType.java124
-rw-r--r--java/org/tinyb/EIRDataTypeSet.java128
-rw-r--r--java/tinyb/dbus/DBusAdapter.java4
8 files changed, 449 insertions, 224 deletions
diff --git a/java/direct_bt/tinyb/DBTAdapter.java b/java/direct_bt/tinyb/DBTAdapter.java
index b5abf5c1..270fded3 100644
--- a/java/direct_bt/tinyb/DBTAdapter.java
+++ b/java/direct_bt/tinyb/DBTAdapter.java
@@ -32,14 +32,15 @@ import java.util.List;
import java.util.UUID;
import java.util.concurrent.atomic.AtomicInteger;
+import org.tinyb.AdapterSettings;
import org.tinyb.BluetoothAdapter;
import org.tinyb.BluetoothDevice;
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.EIRDataTypeSet;
+import org.tinyb.BluetoothAdapterStatusListener;
import org.tinyb.TransportType;
public class DBTAdapter extends DBTObject implements BluetoothAdapter
@@ -53,10 +54,13 @@ public class DBTAdapter extends DBTObject implements BluetoothAdapter
private final Object stateLock = new Object();
private final Object discoveredDevicesLock = new Object();
- private volatile BluetoothDeviceStatusListener userDeviceStatusListener = null;
- private volatile long discoveringCBHandle = 0;
+ private volatile BluetoothAdapterStatusListener userStatusListener = null;
private volatile boolean isDiscovering = false;
- private volatile long poweredCBHandle = 0;
+ private final long discoveringNotificationRef = 0;
+
+ private BluetoothNotification<Boolean> discoverableNotification = null;
+ private BluetoothNotification<Boolean> poweredNotification = null;
+ private BluetoothNotification<Boolean> pairableNotification = null;
private boolean isOpen = false;
private List<BluetoothDevice> discoveredDevices = new ArrayList<BluetoothDevice>();
@@ -66,12 +70,17 @@ public class DBTAdapter extends DBTObject implements BluetoothAdapter
super(nativeInstance, compHash(address, name));
this.address = address;
this.name = name;
- initImpl(this.deviceDiscoveryListener);
+ initImpl(this.adapterStatusListener);
}
@Override
public synchronized void close() {
stopDiscovery();
+ setStatusListener(null);
+ disableDiscoverableNotifications();
+ disableDiscoveringNotifications();
+ disablePairableNotifications();
+ disablePoweredNotifications();
isOpen = false;
super.close();
}
@@ -149,28 +158,13 @@ public class DBTAdapter extends DBTObject implements BluetoothAdapter
@Override
public synchronized void enablePoweredNotifications(final BluetoothNotification<Boolean> callback) {
- if( 0 != poweredCBHandle ) {
- removePoweredNotificationsImpl(poweredCBHandle);
- poweredCBHandle = 0;
- }
- poweredCBHandle = addPoweredNotificationsImpl(callback);
- if( 0 == poweredCBHandle ) {
- throw new InternalError("addPoweredNotificationsImpl(..) == 0");
- }
+ poweredNotification = callback;
}
- private native long addPoweredNotificationsImpl(final BluetoothNotification<Boolean> callback);
@Override
public synchronized void disablePoweredNotifications() {
- if( 0 != poweredCBHandle ) {
- int count;
- if( 1 != ( count = removePoweredNotificationsImpl(poweredCBHandle) ) ) {
- throw new InternalError("removePoweredNotificationsImpl(0x"+Long.toHexString(poweredCBHandle)+") != 1, but "+count);
- }
- poweredCBHandle = 0;
- }
+ poweredNotification = null;
}
- private native int removePoweredNotificationsImpl(final long callbackHandle);
@Override
public native void setPowered(boolean value);
@@ -179,10 +173,14 @@ public class DBTAdapter extends DBTObject implements BluetoothAdapter
public native boolean getDiscoverable();
@Override
- public native void enableDiscoverableNotifications(BluetoothNotification<Boolean> callback);
+ public synchronized void enableDiscoverableNotifications(final BluetoothNotification<Boolean> callback) {
+ discoverableNotification = callback;
+ }
@Override
- public native void disableDiscoverableNotifications();
+ public synchronized void disableDiscoverableNotifications() {
+ discoverableNotification = null;
+ }
@Override
public native void setDiscoverable(boolean value);
@@ -200,10 +198,14 @@ public class DBTAdapter extends DBTObject implements BluetoothAdapter
public native boolean getPairable();
@Override
- public native void enablePairableNotifications(BluetoothNotification<Boolean> callback);
+ public synchronized void enablePairableNotifications(final BluetoothNotification<Boolean> callback) {
+ pairableNotification = callback;
+ }
@Override
- public native void disablePairableNotifications();
+ public synchronized void disablePairableNotifications() {
+ pairableNotification = null;
+ }
@Override
public native void setPairable(boolean value);
@@ -222,7 +224,7 @@ public class DBTAdapter extends DBTObject implements BluetoothAdapter
/* internal */
- private native void initImpl(final BluetoothDeviceStatusListener l);
+ private native void initImpl(final BluetoothAdapterStatusListener l);
private synchronized void open() {
if( !isOpen ) {
@@ -287,34 +289,15 @@ public class DBTAdapter extends DBTObject implements BluetoothAdapter
public boolean getDiscovering() { return isDiscovering; }
@Override
- public synchronized void setDeviceStatusListener(final BluetoothDeviceStatusListener l) {
- userDeviceStatusListener = l;
+ public synchronized void setStatusListener(final BluetoothAdapterStatusListener l) {
+ userStatusListener = l;
}
@Override
- public synchronized void enableDiscoveringNotifications(final BluetoothNotification<Boolean> callback) {
- if( 0 != discoveringCBHandle ) {
- removeDiscoveringNotificationsImpl(discoveringCBHandle);
- discoveringCBHandle = 0;
- }
- discoveringCBHandle = addDiscoveringNotificationsImpl(callback);
- if( 0 == discoveringCBHandle ) {
- throw new InternalError("addDiscoveringNotificationsImpl(..) == 0");
- }
- }
- private native long addDiscoveringNotificationsImpl(final BluetoothNotification<Boolean> callback);
+ public native void enableDiscoveringNotifications(final BluetoothNotification<Boolean> callback);
@Override
- public synchronized void disableDiscoveringNotifications() {
- if( 0 != discoveringCBHandle ) {
- int count;
- if( 1 != ( count = removeDiscoveringNotificationsImpl(discoveringCBHandle) ) ) {
- throw new InternalError("removeDiscoveringNotificationsImpl(0x"+Long.toHexString(discoveringCBHandle)+") != 1, but "+count);
- }
- discoveringCBHandle = 0;
- }
- }
- private native int removeDiscoveringNotificationsImpl(final long callbackHandle);
+ public native void disableDiscoveringNotifications();
@Override
public void setDiscoveryFilter(final List<UUID> uuids, final int rssi, final int pathloss, final TransportType transportType) {
@@ -333,11 +316,38 @@ public class DBTAdapter extends DBTObject implements BluetoothAdapter
////////////////////////////////////
- private final BluetoothDeviceStatusListener deviceDiscoveryListener = new BluetoothDeviceStatusListener() {
+ private final BluetoothAdapterStatusListener adapterStatusListener = new BluetoothAdapterStatusListener() {
+ @Override
+ public void adapterSettingsChanged(final BluetoothAdapter a, final AdapterSettings oldmask, final AdapterSettings newmask,
+ final AdapterSettings changedmask, final long timestamp) {
+ final BluetoothAdapterStatusListener l = userStatusListener;
+ System.err.println("Adapter.StatusListener.settings: "+oldmask+" -> "+newmask+", changed "+changedmask+" on "+a);
+ if( null != l ) {
+ l.adapterSettingsChanged(a, oldmask, newmask, changedmask, timestamp);
+ }
+ {
+ final BluetoothNotification<Boolean> _poweredNotification = poweredNotification;
+ if( null != _poweredNotification && changedmask.isSet(AdapterSettings.SettingType.POWERED) ) {
+ _poweredNotification.run(newmask.isSet(AdapterSettings.SettingType.POWERED));
+ }
+ }
+ {
+ final BluetoothNotification<Boolean> _discoverableNotification = discoverableNotification;
+ if( null != _discoverableNotification && changedmask.isSet(AdapterSettings.SettingType.DISCOVERABLE) ) {
+ _discoverableNotification.run(newmask.isSet(AdapterSettings.SettingType.DISCOVERABLE));
+ }
+ }
+ {
+ final BluetoothNotification<Boolean> _pairableNotification = pairableNotification;
+ if( null != _pairableNotification && changedmask.isSet(AdapterSettings.SettingType.BONDABLE) ) {
+ _pairableNotification.run(newmask.isSet(AdapterSettings.SettingType.BONDABLE));
+ }
+ }
+ }
@Override
public void deviceFound(final BluetoothAdapter a, final BluetoothDevice device, final long timestamp) {
- final BluetoothDeviceStatusListener l = userDeviceStatusListener;
- System.err.println("DBTAdapter.DeviceStatusListener.found: "+device+" on "+a);
+ final BluetoothAdapterStatusListener l = userStatusListener;
+ System.err.println("Adapter.StatusListener.found: "+device+" on "+a);
synchronized(discoveredDevicesLock) {
discoveredDevices.add(device);
}
@@ -347,24 +357,24 @@ public class DBTAdapter extends DBTObject implements BluetoothAdapter
}
@Override
- 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);
+ public void deviceUpdated(final BluetoothAdapter a, final BluetoothDevice device, final long timestamp, final EIRDataTypeSet updateMask) {
+ System.err.println("Adapter.StatusListener.updated: "+updateMask+" of "+device+" on "+a);
// nop on discoveredDevices
- userDeviceStatusListener.deviceUpdated(a, device, timestamp, updateMask);
+ userStatusListener.deviceUpdated(a, device, timestamp, updateMask);
}
@Override
public void deviceConnected(final BluetoothAdapter a, final BluetoothDevice device, final long timestamp) {
- final BluetoothDeviceStatusListener l = userDeviceStatusListener;
- System.err.println("DBTAdapter.DeviceStatusListener.connected: "+device+" on "+a);
+ final BluetoothAdapterStatusListener l = userStatusListener;
+ System.err.println("Adapter.StatusListener.connected: "+device+" on "+a);
if( null != l ) {
l.deviceConnected(a, device, timestamp);
}
}
@Override
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);
+ final BluetoothAdapterStatusListener l = userStatusListener;
+ System.err.println("Adapter.StatusListener.disconnected: "+device+" on "+a);
if( null != l ) {
l.deviceDisconnected(a, device, timestamp);
}
diff --git a/java/jni/direct_bt/DBTAdapter.cxx b/java/jni/direct_bt/DBTAdapter.cxx
index 4085dcc4..03ab2d00 100644
--- a/java/jni/direct_bt/DBTAdapter.cxx
+++ b/java/jni/direct_bt/DBTAdapter.cxx
@@ -36,55 +36,80 @@
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 _adapterSettingsClassName("org/tinyb/AdapterSettings");
+static const std::string _adapterSettingsClazzCtorArgs("(I)V");
+static const std::string _eirDataTypeSetClassName("org/tinyb/EIRDataTypeSet");
+static const std::string _eirDataTypeSetClazzCtorArgs("(I)V");
static const std::string _deviceClazzCtorArgs("(JLdirect_bt/tinyb/DBTAdapter;Ljava/lang/String;Ljava/lang/String;J)V");
+static const std::string _adapterSettingsChangedMethodArgs("(Lorg/tinyb/BluetoothAdapter;Lorg/tinyb/AdapterSettings;Lorg/tinyb/AdapterSettings;Lorg/tinyb/AdapterSettings;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");
+static const std::string _deviceStatusUpdateMethodArgs("(Lorg/tinyb/BluetoothAdapter;Lorg/tinyb/BluetoothDevice;JLorg/tinyb/EIRDataTypeSet;)V");
-class DeviceStatusCallbackListener : public DBTDeviceStatusListener {
+class AdapterStatusCallbackListener : public DBTAdapterStatusListener {
public:
/**
package org.tinyb;
- public interface BluetoothDeviceStatusListener {
+ public interface BluetoothAdapterStatusListener {
+ public void adapterSettingsChanged(final BluetoothAdapter adapter,
+ final AdapterSetting oldmask, final AdapterSetting newmask,
+ final AdapterSetting changedmask, final long timestamp);
public void deviceFound(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> adapterSettingsClazzRef;
+ jmethodID adapterSettingsClazzCtor;
+ std::unique_ptr<JNIGlobalRef> eirDataTypeSetClazzRef;
+ jmethodID eirDataTypeSetClazzCtor;
std::unique_ptr<JNIGlobalRef> deviceClazzRef;
jmethodID deviceClazzCtor;
jfieldID deviceClazzTSUpdateField;
std::unique_ptr<JNIGlobalRef> listenerObjRef;
std::unique_ptr<JNIGlobalRef> listenerClazzRef;
+ jmethodID mAdapterSettingsChanged = nullptr;
jmethodID mDeviceFound = nullptr;
jmethodID mDeviceUpdated = nullptr;
jmethodID mDeviceConnected = nullptr;
jmethodID mDeviceDisconnected = nullptr;
- DeviceStatusCallbackListener(JNIEnv *env, DBTAdapter *adapter, jobject deviceDiscoveryListener) {
+ AdapterStatusCallbackListener(JNIEnv *env, DBTAdapter *adapter, jobject deviceDiscoveryListener) {
adapterObjRef = adapter->getJavaObject();
JavaGlobalObj::check(adapterObjRef, E_FILE_LINE);
- // eirDataTypeClazzRef, eirDataTypeClazzCreate
+ // adapterSettingsClazzRef, adapterSettingsClazzCtor
{
- jclass eirDataTypeClazz = search_class(env, _eirDataTypeClassName.c_str());
+ jclass adapterSettingsClazz = search_class(env, _adapterSettingsClassName.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);
+ if( nullptr == adapterSettingsClazz ) {
+ throw InternalError("DBTDevice::java_class not found: "+_adapterSettingsClassName, E_FILE_LINE);
}
- eirDataTypeClazzRef = std::unique_ptr<JNIGlobalRef>(new JNIGlobalRef(eirDataTypeClazz));
- env->DeleteLocalRef(eirDataTypeClazz);
+ adapterSettingsClazzRef = std::unique_ptr<JNIGlobalRef>(new JNIGlobalRef(adapterSettingsClazz));
+ env->DeleteLocalRef(adapterSettingsClazz);
}
- eirDataTypeClazzCreate = search_method(env, eirDataTypeClazzRef->getClass(), "create", _eirDataTypeClazzCreateArgs.c_str(), true);
+ adapterSettingsClazzCtor = search_method(env, adapterSettingsClazzRef->getClass(), "<init>", _adapterSettingsClazzCtorArgs.c_str(), false);
java_exception_check_and_throw(env, E_FILE_LINE);
- if( nullptr == eirDataTypeClazzCreate ) {
- throw InternalError("EIRDataType ctor not found: "+_eirDataTypeClassName+".create"+_eirDataTypeClazzCreateArgs, E_FILE_LINE);
+ if( nullptr == adapterSettingsClazzCtor ) {
+ throw InternalError("AdapterSettings ctor not found: "+_adapterSettingsClassName+".<init>"+_adapterSettingsClazzCtorArgs, E_FILE_LINE);
+ }
+
+ // eirDataTypeSetClazzRef, eirDataTypeSetClazzCtor
+ {
+ jclass eirDataTypeSetClazz = search_class(env, _eirDataTypeSetClassName.c_str());
+ java_exception_check_and_throw(env, E_FILE_LINE);
+ if( nullptr == eirDataTypeSetClazz ) {
+ throw InternalError("DBTDevice::java_class not found: "+_eirDataTypeSetClassName, E_FILE_LINE);
+ }
+ eirDataTypeSetClazzRef = std::unique_ptr<JNIGlobalRef>(new JNIGlobalRef(eirDataTypeSetClazz));
+ env->DeleteLocalRef(eirDataTypeSetClazz);
+ }
+ eirDataTypeSetClazzCtor = search_method(env, eirDataTypeSetClazzRef->getClass(), "<init>", _eirDataTypeSetClazzCtorArgs.c_str(), false);
+ java_exception_check_and_throw(env, E_FILE_LINE);
+ if( nullptr == eirDataTypeSetClazzCtor ) {
+ throw InternalError("EIRDataType ctor not found: "+_eirDataTypeSetClassName+".<init>"+_eirDataTypeSetClazzCtorArgs, E_FILE_LINE);
}
// deviceClazzRef, deviceClazzCtor
@@ -113,30 +138,70 @@ class DeviceStatusCallbackListener : public DBTDeviceStatusListener {
jclass listenerClazz = search_class(env, listenerObjRef->getObject());
java_exception_check_and_throw(env, E_FILE_LINE);
if( nullptr == listenerClazz ) {
- throw InternalError("BluetoothDeviceDiscoveryListener not found", E_FILE_LINE);
+ throw InternalError("BluetoothAdapterStatusListener not found", E_FILE_LINE);
}
listenerClazzRef = std::unique_ptr<JNIGlobalRef>(new JNIGlobalRef(listenerClazz));
env->DeleteLocalRef(listenerClazz);
}
+
+
+ mAdapterSettingsChanged = search_method(env, listenerClazzRef->getClass(), "adapterSettingsChanged", _adapterSettingsChangedMethodArgs.c_str(), false);
+ java_exception_check_and_throw(env, E_FILE_LINE);
+ if( nullptr == mAdapterSettingsChanged ) {
+ throw InternalError("BluetoothAdapterStatusListener has no adapterSettingsChanged"+_adapterSettingsChangedMethodArgs+" method, for "+adapter->toString(), E_FILE_LINE);
+ }
mDeviceFound = search_method(env, listenerClazzRef->getClass(), "deviceFound", _deviceStatusMethodArgs.c_str(), false);
java_exception_check_and_throw(env, E_FILE_LINE);
if( nullptr == mDeviceFound ) {
- throw InternalError("BluetoothDeviceDiscoveryListener has no deviceFound"+_deviceStatusMethodArgs+" method, for "+adapter->toString(), E_FILE_LINE);
+ throw InternalError("BluetoothAdapterStatusListener has no deviceFound"+_deviceStatusMethodArgs+" method, for "+adapter->toString(), E_FILE_LINE);
}
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);
+ throw InternalError("BluetoothAdapterStatusListener has no deviceUpdated"+_deviceStatusMethodArgs+" method, for "+adapter->toString(), E_FILE_LINE);
}
mDeviceConnected = search_method(env, listenerClazzRef->getClass(), "deviceConnected", _deviceStatusMethodArgs.c_str(), false);
java_exception_check_and_throw(env, E_FILE_LINE);
if( nullptr == mDeviceConnected ) {
- throw InternalError("BluetoothDeviceDiscoveryListener has no deviceConnected"+_deviceStatusMethodArgs+" method, for "+adapter->toString(), E_FILE_LINE);
+ throw InternalError("BluetoothAdapterStatusListener has no deviceConnected"+_deviceStatusMethodArgs+" method, for "+adapter->toString(), E_FILE_LINE);
}
mDeviceDisconnected = search_method(env, listenerClazzRef->getClass(), "deviceDisconnected", _deviceStatusMethodArgs.c_str(), false);
java_exception_check_and_throw(env, E_FILE_LINE);
if( nullptr == mDeviceDisconnected ) {
- throw InternalError("BluetoothDeviceDiscoveryListener has no deviceDisconnected"+_deviceStatusMethodArgs+" method, for "+adapter->toString(), E_FILE_LINE);
+ throw InternalError("BluetoothAdapterStatusListener has no deviceDisconnected"+_deviceStatusMethodArgs+" method, for "+adapter->toString(), E_FILE_LINE);
+ }
+ }
+
+ void adapterSettingsChanged(DBTAdapter const &a, const AdapterSetting oldmask, const AdapterSetting newmask,
+ const AdapterSetting changedmask, const uint64_t timestamp) override {
+ JNIEnv *env = *jni_env;
+ try {
+ #ifdef VERBOSE_ON
+ fprintf(stderr, "****** Native Adapter SETTINGS_CHANGED: %s -> %s, changed %s\n",
+ direct_bt::adapterSettingsToString(oldmask).c_str(),
+ direct_bt::adapterSettingsToString(newmask).c_str(),
+ direct_bt::adapterSettingsToString(changedmask).c_str());
+ fprintf(stderr, "Status DBTAdapter:\n");
+ fprintf(stderr, "%s\n", a.toString().c_str());
+ #endif
+ (void)a;
+ jobject adapterSettingOld = env->NewObject(adapterSettingsClazzRef->getClass(), adapterSettingsClazzCtor, (jint)oldmask);
+ if( java_exception_check(env, E_FILE_LINE) ) { return; }
+ JNIGlobalRef::check(adapterSettingOld, E_FILE_LINE);
+
+ jobject adapterSettingNew = env->NewObject(adapterSettingsClazzRef->getClass(), adapterSettingsClazzCtor, (jint)newmask);
+ if( java_exception_check(env, E_FILE_LINE) ) { return; }
+ JNIGlobalRef::check(adapterSettingNew, E_FILE_LINE);
+
+ jobject adapterSettingChanged = env->NewObject(adapterSettingsClazzRef->getClass(), adapterSettingsClazzCtor, (jint)changedmask);
+ if( java_exception_check(env, E_FILE_LINE) ) { return; }
+ JNIGlobalRef::check(adapterSettingChanged, E_FILE_LINE);
+
+ env->CallVoidMethod(listenerObjRef->getObject(), mAdapterSettingsChanged,
+ JavaGlobalObj::GetObject(adapterObjRef), adapterSettingOld, adapterSettingNew, adapterSettingChanged, (jlong)timestamp);
+ if( java_exception_check(env, E_FILE_LINE) ) { return; }
+ } catch(...) {
+ rethrow_and_raise_java_exception(env);
}
}
@@ -181,10 +246,13 @@ 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);
+
+ jobject eirDataTypeSet = env->NewObject(eirDataTypeSetClazzRef->getClass(), eirDataTypeSetClazzCtor, (jint)updateMask);
if( java_exception_check(env, E_FILE_LINE) ) { return; }
+ JNIGlobalRef::check(eirDataTypeSet, E_FILE_LINE);
+
env->CallVoidMethod(listenerObjRef->getObject(), mDeviceUpdated,
- JavaGlobalObj::GetObject(adapterObjRef), JavaGlobalObj::GetObject(jDeviceRef), (jlong)timestamp, eirDataType);
+ JavaGlobalObj::GetObject(adapterObjRef), JavaGlobalObj::GetObject(jDeviceRef), (jlong)timestamp, eirDataTypeSet);
if( java_exception_check(env, E_FILE_LINE) ) { return; }
} catch(...) {
rethrow_and_raise_java_exception(env);
@@ -232,16 +300,16 @@ class DeviceStatusCallbackListener : public DBTDeviceStatusListener {
}
};
-void Java_direct_1bt_tinyb_DBTAdapter_initImpl(JNIEnv *env, jobject obj, jobject deviceDiscoveryListener)
+void Java_direct_1bt_tinyb_DBTAdapter_initImpl(JNIEnv *env, jobject obj, jobject statusListener)
{
- // org.tinyb.BluetoothDeviceDiscoveryListener
+ // org.tinyb.BluetoothAdapterStatusListener
try {
DBTAdapter *adapter = getInstance<DBTAdapter>(env, obj);
JavaGlobalObj::check(adapter->getJavaObject(), E_FILE_LINE);
// set our callback discovery listener.
- DeviceStatusCallbackListener *l = new DeviceStatusCallbackListener(env, adapter, deviceDiscoveryListener);
- adapter->setDeviceStatusListener(std::shared_ptr<DBTDeviceStatusListener>(l));
+ AdapterStatusCallbackListener *l = new AdapterStatusCallbackListener(env, adapter, statusListener);
+ adapter->setStatusListener(std::shared_ptr<DBTAdapterStatusListener>(l));
} catch(...) {
rethrow_and_raise_java_exception(env);
}
@@ -267,7 +335,7 @@ void Java_direct_1bt_tinyb_DBTAdapter_deleteImpl(JNIEnv *env, jobject obj)
try {
DBTAdapter *adapter = getInstance<DBTAdapter>(env, obj);
DBG_PRINT("Java_direct_1bt_tinyb_DBTAdapter_deleteImpl %s", adapter->toString().c_str());
- adapter->setDeviceStatusListener(nullptr);
+ adapter->setStatusListener(nullptr);
delete adapter;
} catch(...) {
rethrow_and_raise_java_exception(env);
diff --git a/java/org/tinyb/AdapterSettings.java b/java/org/tinyb/AdapterSettings.java
new file mode 100644
index 00000000..0fab7fd5
--- /dev/null
+++ b/java/org/tinyb/AdapterSettings.java
@@ -0,0 +1,138 @@
+/**
+ * Author: Sven Gothel <[email protected]>
+ * Copyright (c) 2020 Gothel Software e.K.
+ * Copyright (c) 2020 ZAFENA AB
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+package org.tinyb;
+
+public class AdapterSettings {
+
+ public enum SettingType {
+ NONE ( 0),
+ POWERED (0x00000001),
+ CONNECTABLE (0x00000002),
+ FAST_CONNECTABLE (0x00000004),
+ DISCOVERABLE (0x00000008),
+ BONDABLE (0x00000010),
+ LINK_SECURITY (0x00000020),
+ SSP (0x00000040),
+ BREDR (0x00000080),
+ HS (0x00000100),
+ LE (0x00000200),
+ ADVERTISING (0x00000400),
+ SECURE_CONN (0x00000800),
+ DEBUG_KEYS (0x00001000),
+ PRIVACY (0x00002000),
+ CONFIGURATION (0x00004000),
+ STATIC_ADDRESS (0x00008000),
+ PHY_CONFIGURATION (0x00010000);
+
+ SettingType(final int v) { value = v; }
+ public final int value;
+ }
+
+ public int mask;
+
+ public AdapterSettings(final int v) {
+ mask = v;
+ }
+
+ public boolean isSet(final SettingType bit) { return 0 != ( mask & bit.value ); }
+ public void set(final SettingType bit) { mask = mask | bit.value; }
+
+ public String toString() {
+ int count = 0;
+ final StringBuilder out = new StringBuilder();
+ if( isSet(SettingType.POWERED) ) {
+ out.append(SettingType.POWERED.name()); count++;
+ }
+ if( isSet(SettingType.CONNECTABLE) ) {
+ if( 0 < count ) { out.append(", "); }
+ out.append(SettingType.CONNECTABLE.name()); count++;
+ }
+ if( isSet(SettingType.FAST_CONNECTABLE) ) {
+ if( 0 < count ) { out.append(", "); }
+ out.append(SettingType.FAST_CONNECTABLE.name()); count++;
+ }
+ if( isSet(SettingType.DISCOVERABLE) ) {
+ if( 0 < count ) { out.append(", "); }
+ out.append(SettingType.DISCOVERABLE.name()); count++;
+ }
+ if( isSet(SettingType.BONDABLE) ) {
+ if( 0 < count ) { out.append(", "); }
+ out.append(SettingType.BONDABLE.name()); count++;
+ }
+ if( isSet(SettingType.LINK_SECURITY) ) {
+ if( 0 < count ) { out.append(", "); }
+ out.append(SettingType.LINK_SECURITY.name()); count++;
+ }
+ if( isSet(SettingType.SSP) ) {
+ if( 0 < count ) { out.append(", "); }
+ out.append(SettingType.SSP.name()); count++;
+ }
+ if( isSet(SettingType.BREDR) ) {
+ if( 0 < count ) { out.append(", "); }
+ out.append(SettingType.BREDR.name()); count++;
+ }
+ if( isSet(SettingType.HS) ) {
+ if( 0 < count ) { out.append(", "); }
+ out.append(SettingType.HS.name()); count++;
+ }
+ if( isSet(SettingType.LE) ) {
+ if( 0 < count ) { out.append(", "); }
+ out.append(SettingType.LE.name()); count++;
+ }
+ if( isSet(SettingType.ADVERTISING) ) {
+ if( 0 < count ) { out.append(", "); }
+ out.append(SettingType.ADVERTISING.name()); count++;
+ }
+ if( isSet(SettingType.SECURE_CONN) ) {
+ if( 0 < count ) { out.append(", "); }
+ out.append(SettingType.SECURE_CONN.name()); count++;
+ }
+ if( isSet(SettingType.DEBUG_KEYS) ) {
+ if( 0 < count ) { out.append(", "); }
+ out.append(SettingType.DEBUG_KEYS.name()); count++;
+ }
+ if( isSet(SettingType.PRIVACY) ) {
+ if( 0 < count ) { out.append(", "); }
+ out.append(SettingType.PRIVACY.name()); count++;
+ }
+ if( isSet(SettingType.CONFIGURATION) ) {
+ if( 0 < count ) { out.append(", "); }
+ out.append(SettingType.CONFIGURATION.name()); count++;
+ }
+ if( isSet(SettingType.STATIC_ADDRESS) ) {
+ if( 0 < count ) { out.append(", "); }
+ out.append(SettingType.STATIC_ADDRESS.name()); count++;
+ }
+ if( isSet(SettingType.PHY_CONFIGURATION) ) {
+ if( 0 < count ) { out.append(", "); }
+ out.append(SettingType.PHY_CONFIGURATION.name()); count++;
+ }
+ if( 1 < count ) {
+ out.insert(0, "[");
+ out.append("]");
+ }
+ return out.toString();
+ }
+}
diff --git a/java/org/tinyb/BluetoothAdapter.java b/java/org/tinyb/BluetoothAdapter.java
index 4a989500..bf608e90 100644
--- a/java/org/tinyb/BluetoothAdapter.java
+++ b/java/org/tinyb/BluetoothAdapter.java
@@ -242,10 +242,10 @@ public interface BluetoothAdapter extends BluetoothObject
public boolean getDiscovering();
/**
- * Sets the {@link BluetoothDeviceStatusListener} for the respective device status events.
- * @param listener A {@link BluetoothDeviceStatusListener} instance, or {@code null} to disable notifications.
+ * Sets the {@link BluetoothAdapterStatusListener} for the respective device status events.
+ * @param listener A {@link BluetoothAdapterStatusListener} instance, or {@code null} to disable notifications.
*/
- public void setDeviceStatusListener(final BluetoothDeviceStatusListener listener);
+ public void setStatusListener(final BluetoothAdapterStatusListener listener);
/**
* Enables notifications for the discovering property and calls run function of the
diff --git a/java/org/tinyb/BluetoothDeviceStatusListener.java b/java/org/tinyb/BluetoothAdapterStatusListener.java
index 3220d106..b6262a1e 100644
--- a/java/org/tinyb/BluetoothDeviceStatusListener.java
+++ b/java/org/tinyb/BluetoothAdapterStatusListener.java
@@ -26,17 +26,22 @@
package org.tinyb;
/**
- * {@link BluetoothDevice} listener for the respective {@link BluetoothDevice} discovery events: Added, updated and removed.
+ * {@link BluetoothAdapter} status listener for {@link BluetoothDevice} discovery events: Added, updated and removed;
+ * as well as for certain {@link BluetoothAdapter} events.
* <p>
* A listener instance may be attached to a {@link BluetoothAdapter} via
- * {@link BluetoothAdapter#setDeviceStatusListener(BluetoothDeviceDiscoveryListener)}.
+ * {@link BluetoothAdapter#setStatusListener(BluetoothDeviceDiscoveryListener)}.
* </p>
*/
-public interface BluetoothDeviceStatusListener {
+public interface BluetoothAdapterStatusListener {
+ /** A {@link BluetoothAdapter} setting has been changed. */
+ public void adapterSettingsChanged(final BluetoothAdapter adapter,
+ final AdapterSettings oldmask, final AdapterSettings newmask,
+ final AdapterSettings changedmask, final long timestamp);
/** 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, final EIRDataType updateMask);
+ public void deviceUpdated(final BluetoothAdapter adapter, final BluetoothDevice device, final long timestamp, final EIRDataTypeSet updateMask);
/** {@link BluetoothDevice} has been connected. */
public void deviceConnected(final BluetoothAdapter adapter, final BluetoothDevice device, final long timestamp);
/** {@link BluetoothDevice} has been disconnected. */
diff --git a/java/org/tinyb/EIRDataType.java b/java/org/tinyb/EIRDataType.java
deleted file mode 100644
index 8134b20e..00000000
--- a/java/org/tinyb/EIRDataType.java
+++ /dev/null
@@ -1,124 +0,0 @@
-/**
- * Author: Sven Gothel <[email protected]>
- * Copyright (c) 2020 Gothel Software e.K.
- * Copyright (c) 2020 ZAFENA AB
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
- * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
- * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-package org.tinyb;
-
-public enum EIRDataType {
- NONE ( 0),
- EVT_TYPE (1 << 0),
- BDADDR_TYPE (1 << 1),
- BDADDR (1 << 2),
- FLAGS (1 << 3),
- NAME (1 << 4),
- NAME_SHORT (1 << 5),
- RSSI (1 << 6),
- TX_POWER (1 << 7),
- MANUF_DATA (1 << 8),
- DEVICE_CLASS (1 << 9),
- APPEARANCE (1 << 10),
- HASH (1 << 11),
- RANDOMIZER (1 << 12),
- DEVICE_ID (1 << 13),
- SERVICE_UUID (1 << 30);
-
- EIRDataType(final int v) { mask = v; }
- public static EIRDataType create(final int v) {
- final EIRDataType r = NONE;
- r.mask = v;
- return r;
- }
-
- public int mask;
- public boolean isSet(final EIRDataType bit) { return 0 != ( mask & bit.mask ); }
- public void set(final EIRDataType bit) { mask = mask | bit.mask; }
-
- public String toString() {
- int count = 0;
- final StringBuilder out = new StringBuilder();
- if( isSet(EVT_TYPE) ) {
- out.append(EVT_TYPE.name()); count++;
- }
- if( isSet(BDADDR_TYPE) ) {
- if( 0 < count ) { out.append(", "); }
- out.append(BDADDR_TYPE.name()); count++;
- }
- if( isSet(BDADDR) ) {
- if( 0 < count ) { out.append(", "); }
- out.append(BDADDR.name()); count++;
- }
- if( isSet(FLAGS) ) {
- if( 0 < count ) { out.append(", "); }
- out.append(FLAGS.name()); count++;
- }
- if( isSet(NAME) ) {
- if( 0 < count ) { out.append(", "); }
- out.append(NAME.name()); count++;
- }
- if( isSet(NAME_SHORT) ) {
- if( 0 < count ) { out.append(", "); }
- out.append(NAME_SHORT.name()); count++;
- }
- if( isSet(RSSI) ) {
- if( 0 < count ) { out.append(", "); }
- out.append(RSSI.name()); count++;
- }
- if( isSet(TX_POWER) ) {
- if( 0 < count ) { out.append(", "); }
- out.append(TX_POWER.name()); count++;
- }
- if( isSet(MANUF_DATA) ) {
- if( 0 < count ) { out.append(", "); }
- out.append(MANUF_DATA.name()); count++;
- }
- if( isSet(DEVICE_CLASS) ) {
- if( 0 < count ) { out.append(", "); }
- out.append(DEVICE_CLASS.name()); count++;
- }
- if( isSet(APPEARANCE) ) {
- if( 0 < count ) { out.append(", "); }
- out.append(APPEARANCE.name()); count++;
- }
- if( isSet(HASH) ) {
- if( 0 < count ) { out.append(", "); }
- out.append(HASH.name()); count++;
- }
- if( isSet(RANDOMIZER) ) {
- if( 0 < count ) { out.append(", "); }
- out.append(RANDOMIZER.name()); count++;
- }
- if( isSet(DEVICE_ID) ) {
- if( 0 < count ) { out.append(", "); }
- out.append(DEVICE_ID.name()); count++;
- }
- if( isSet(SERVICE_UUID) ) {
- if( 0 < count ) { out.append(", "); }
- out.append(SERVICE_UUID.name()); count++;
- }
- if( 1 < count ) {
- out.insert(0, "[");
- out.append("]");
- }
- return out.toString();
- }
-}
diff --git a/java/org/tinyb/EIRDataTypeSet.java b/java/org/tinyb/EIRDataTypeSet.java
new file mode 100644
index 00000000..258066d8
--- /dev/null
+++ b/java/org/tinyb/EIRDataTypeSet.java
@@ -0,0 +1,128 @@
+/**
+ * Author: Sven Gothel <[email protected]>
+ * Copyright (c) 2020 Gothel Software e.K.
+ * Copyright (c) 2020 ZAFENA AB
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+package org.tinyb;
+
+public class EIRDataTypeSet {
+
+ public enum DataType {
+ NONE ( 0),
+ EVT_TYPE (1 << 0),
+ BDADDR_TYPE (1 << 1),
+ BDADDR (1 << 2),
+ FLAGS (1 << 3),
+ NAME (1 << 4),
+ NAME_SHORT (1 << 5),
+ RSSI (1 << 6),
+ TX_POWER (1 << 7),
+ MANUF_DATA (1 << 8),
+ DEVICE_CLASS (1 << 9),
+ APPEARANCE (1 << 10),
+ HASH (1 << 11),
+ RANDOMIZER (1 << 12),
+ DEVICE_ID (1 << 13),
+ SERVICE_UUID (1 << 30);
+
+ DataType(final int v) { value = v; }
+ public final int value;
+ }
+
+ public int mask;
+
+ public EIRDataTypeSet(final int v) {
+ mask = v;
+ }
+
+ public boolean isSet(final DataType bit) { return 0 != ( mask & bit.value ); }
+ public void set(final DataType bit) { mask = mask | bit.value; }
+
+ public String toString() {
+ int count = 0;
+ final StringBuilder out = new StringBuilder();
+ if( isSet(DataType.EVT_TYPE) ) {
+ out.append(DataType.EVT_TYPE.name()); count++;
+ }
+ if( isSet(DataType.BDADDR_TYPE) ) {
+ if( 0 < count ) { out.append(", "); }
+ out.append(DataType.BDADDR_TYPE.name()); count++;
+ }
+ if( isSet(DataType.BDADDR) ) {
+ if( 0 < count ) { out.append(", "); }
+ out.append(DataType.BDADDR.name()); count++;
+ }
+ if( isSet(DataType.FLAGS) ) {
+ if( 0 < count ) { out.append(", "); }
+ out.append(DataType.FLAGS.name()); count++;
+ }
+ if( isSet(DataType.NAME) ) {
+ if( 0 < count ) { out.append(", "); }
+ out.append(DataType.NAME.name()); count++;
+ }
+ if( isSet(DataType.NAME_SHORT) ) {
+ if( 0 < count ) { out.append(", "); }
+ out.append(DataType.NAME_SHORT.name()); count++;
+ }
+ if( isSet(DataType.RSSI) ) {
+ if( 0 < count ) { out.append(", "); }
+ out.append(DataType.RSSI.name()); count++;
+ }
+ if( isSet(DataType.TX_POWER) ) {
+ if( 0 < count ) { out.append(", "); }
+ out.append(DataType.TX_POWER.name()); count++;
+ }
+ if( isSet(DataType.MANUF_DATA) ) {
+ if( 0 < count ) { out.append(", "); }
+ out.append(DataType.MANUF_DATA.name()); count++;
+ }
+ if( isSet(DataType.DEVICE_CLASS) ) {
+ if( 0 < count ) { out.append(", "); }
+ out.append(DataType.DEVICE_CLASS.name()); count++;
+ }
+ if( isSet(DataType.APPEARANCE) ) {
+ if( 0 < count ) { out.append(", "); }
+ out.append(DataType.APPEARANCE.name()); count++;
+ }
+ if( isSet(DataType.HASH) ) {
+ if( 0 < count ) { out.append(", "); }
+ out.append(DataType.HASH.name()); count++;
+ }
+ if( isSet(DataType.RANDOMIZER) ) {
+ if( 0 < count ) { out.append(", "); }
+ out.append(DataType.RANDOMIZER.name()); count++;
+ }
+ if( isSet(DataType.DEVICE_ID) ) {
+ if( 0 < count ) { out.append(", "); }
+ out.append(DataType.DEVICE_ID.name()); count++;
+ }
+ if( isSet(DataType.SERVICE_UUID) ) {
+ if( 0 < count ) { out.append(", "); }
+ out.append(DataType.SERVICE_UUID.name()); count++;
+ }
+ if( 1 < count ) {
+ out.insert(0, "[");
+ out.append("]");
+ }
+ return out.toString();
+ }
+}
diff --git a/java/tinyb/dbus/DBusAdapter.java b/java/tinyb/dbus/DBusAdapter.java
index b49e9fc7..0fa8b787 100644
--- a/java/tinyb/dbus/DBusAdapter.java
+++ b/java/tinyb/dbus/DBusAdapter.java
@@ -35,7 +35,7 @@ import java.util.UUID;
import org.tinyb.BluetoothAdapter;
import org.tinyb.BluetoothDevice;
-import org.tinyb.BluetoothDeviceStatusListener;
+import org.tinyb.BluetoothAdapterStatusListener;
import org.tinyb.BluetoothException;
import org.tinyb.BluetoothManager;
import org.tinyb.BluetoothNotification;
@@ -149,7 +149,7 @@ public class DBusAdapter extends DBusObject implements BluetoothAdapter
public native boolean getDiscovering();
@Override
- public void setDeviceStatusListener(final BluetoothDeviceStatusListener l) {
+ public void setStatusListener(final BluetoothAdapterStatusListener l) {
throw new UnsupportedOperationException(); // FIXME
}