aboutsummaryrefslogtreecommitdiffstats
path: root/java/direct_bt
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2020-05-10 06:03:59 +0200
committerSven Gothel <[email protected]>2020-05-10 06:03:59 +0200
commit0f53fde528dea4470d152d30f33f357dde1b2e10 (patch)
treee504202c2a92bd16299ee1204ed5b2130ecb8aa4 /java/direct_bt
parent7adcc61246e0948041e77c4eb45c75c1f46ea2b4 (diff)
[Bluetooth]AdapterStatusListener: Renamed; Using a list instead of one-shot callback; Mutable callbacks for_each...
[Bluetooth]AdapterStatusListener: - Renamed BluetoothAdapterStatusListener -> AdapterStatusListener - Using a list instead of one-shot callback: Allows utilizing information from multiple actors, which also allows a more efficient implementation of the tinyb interfaces. - Mutable callbacks for_each...: BasicAlgos.hpp adds for_each_idx_mtx(..) template algos, allowing to perform one UnaryFunction via indices and utilizing mutex lock for thread safety. This pattern reduces code complexity, as we need to use the visitor model for the listener multiple times. - Java: DBTDevice's AdapterStatusListener hook performs certain TinyB one-shot callbacks
Diffstat (limited to 'java/direct_bt')
-rw-r--r--java/direct_bt/tinyb/DBTAdapter.java35
-rw-r--r--java/direct_bt/tinyb/DBTDevice.java87
2 files changed, 95 insertions, 27 deletions
diff --git a/java/direct_bt/tinyb/DBTAdapter.java b/java/direct_bt/tinyb/DBTAdapter.java
index 270fded3..11795f28 100644
--- a/java/direct_bt/tinyb/DBTAdapter.java
+++ b/java/direct_bt/tinyb/DBTAdapter.java
@@ -40,7 +40,7 @@ import org.tinyb.BluetoothManager;
import org.tinyb.BluetoothNotification;
import org.tinyb.BluetoothType;
import org.tinyb.EIRDataTypeSet;
-import org.tinyb.BluetoothAdapterStatusListener;
+import org.tinyb.AdapterStatusListener;
import org.tinyb.TransportType;
public class DBTAdapter extends DBTObject implements BluetoothAdapter
@@ -54,7 +54,6 @@ public class DBTAdapter extends DBTObject implements BluetoothAdapter
private final Object stateLock = new Object();
private final Object discoveredDevicesLock = new Object();
- private volatile BluetoothAdapterStatusListener userStatusListener = null;
private volatile boolean isDiscovering = false;
private final long discoveringNotificationRef = 0;
@@ -70,13 +69,13 @@ public class DBTAdapter extends DBTObject implements BluetoothAdapter
super(nativeInstance, compHash(address, name));
this.address = address;
this.name = name;
- initImpl(this.adapterStatusListener);
+ addStatusListener(this.statusListener);
}
@Override
public synchronized void close() {
stopDiscovery();
- setStatusListener(null);
+ removeStatusListener(this.statusListener);
disableDiscoverableNotifications();
disableDiscoveringNotifications();
disablePairableNotifications();
@@ -224,8 +223,6 @@ public class DBTAdapter extends DBTObject implements BluetoothAdapter
/* internal */
- private native void initImpl(final BluetoothAdapterStatusListener l);
-
private synchronized void open() {
if( !isOpen ) {
isOpen = openImpl();
@@ -289,9 +286,10 @@ public class DBTAdapter extends DBTObject implements BluetoothAdapter
public boolean getDiscovering() { return isDiscovering; }
@Override
- public synchronized void setStatusListener(final BluetoothAdapterStatusListener l) {
- userStatusListener = l;
- }
+ public native boolean addStatusListener(final AdapterStatusListener l);
+
+ @Override
+ public native boolean removeStatusListener(final AdapterStatusListener l);
@Override
public native void enableDiscoveringNotifications(final BluetoothNotification<Boolean> callback);
@@ -316,15 +314,11 @@ public class DBTAdapter extends DBTObject implements BluetoothAdapter
////////////////////////////////////
- private final BluetoothAdapterStatusListener adapterStatusListener = new BluetoothAdapterStatusListener() {
+ private final AdapterStatusListener statusListener = new AdapterStatusListener() {
@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) ) {
@@ -346,38 +340,25 @@ public class DBTAdapter extends DBTObject implements BluetoothAdapter
}
@Override
public void deviceFound(final BluetoothAdapter a, final BluetoothDevice device, final long timestamp) {
- final BluetoothAdapterStatusListener l = userStatusListener;
System.err.println("Adapter.StatusListener.found: "+device+" on "+a);
synchronized(discoveredDevicesLock) {
discoveredDevices.add(device);
}
- if( null != l ) {
- l.deviceFound(a, device, timestamp);
- }
}
@Override
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
- userStatusListener.deviceUpdated(a, device, timestamp, updateMask);
}
@Override
public void deviceConnected(final BluetoothAdapter a, final BluetoothDevice device, final long timestamp) {
- 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 BluetoothAdapterStatusListener l = userStatusListener;
System.err.println("Adapter.StatusListener.disconnected: "+device+" on "+a);
- if( null != l ) {
- l.deviceDisconnected(a, device, timestamp);
- }
}
};
}
diff --git a/java/direct_bt/tinyb/DBTDevice.java b/java/direct_bt/tinyb/DBTDevice.java
index e2ef4d70..7e482137 100644
--- a/java/direct_bt/tinyb/DBTDevice.java
+++ b/java/direct_bt/tinyb/DBTDevice.java
@@ -28,6 +28,9 @@ package direct_bt.tinyb;
import java.util.List;
import java.util.Map;
+import org.tinyb.AdapterSettings;
+import org.tinyb.BluetoothAdapter;
+import org.tinyb.AdapterStatusListener;
import org.tinyb.BluetoothDevice;
import org.tinyb.BluetoothException;
import org.tinyb.BluetoothGattService;
@@ -35,6 +38,7 @@ import org.tinyb.BluetoothManager;
import org.tinyb.BluetoothNotification;
import org.tinyb.BluetoothType;
import org.tinyb.BluetoothUtils;
+import org.tinyb.EIRDataTypeSet;
public class DBTDevice extends DBTObject implements BluetoothDevice
{
@@ -44,6 +48,58 @@ public class DBTDevice extends DBTObject implements BluetoothDevice
private final long ts_creation;
long ts_update;
+ private final long connectedNotificationRef = 0;
+ private boolean connected = false;
+ private final Object userCallbackLock = new Object();
+ private BluetoothNotification<Boolean> userConnectedNotificationsCB = null;
+ private BluetoothNotification<Short> userRSSINotificationsCB = null;
+ private BluetoothNotification<Map<Short, byte[]> > userManufDataNotificationsCB = null;
+ private BluetoothNotification<Boolean> userServicesResolvedNotificationsCB = null;
+ private boolean servicesResolved = false;
+ private short appearance = 0;
+
+ final AdapterStatusListener statusListener = new AdapterStatusListener() {
+ @Override
+ public void deviceUpdated(final BluetoothAdapter adapter, final BluetoothDevice device, final long timestamp, final EIRDataTypeSet updateMask) {
+ if( device != DBTDevice.this ) {
+ return;
+ }
+ synchronized(userCallbackLock) {
+ if( updateMask.isSet( EIRDataTypeSet.DataType.RSSI ) && null != userRSSINotificationsCB ) {
+ userRSSINotificationsCB.run(getRSSI());
+ }
+ if( updateMask.isSet( EIRDataTypeSet.DataType.MANUF_DATA ) && null != userManufDataNotificationsCB ) {
+ userManufDataNotificationsCB.run(getManufacturerData());
+ }
+ }
+ }
+ @Override
+ public void deviceConnected(final BluetoothAdapter adapter, final BluetoothDevice device, final long timestamp) {
+ if( device != DBTDevice.this ) {
+ return;
+ }
+ connected = true;
+ synchronized(userCallbackLock) {
+ if( null != userConnectedNotificationsCB ) {
+ userConnectedNotificationsCB.run(true);
+ }
+ }
+ }
+ @Override
+ public void deviceDisconnected(final BluetoothAdapter adapter, final BluetoothDevice device, final long timestamp) {
+ if( device != DBTDevice.this ) {
+ return;
+ }
+ connected = false;
+ synchronized(userCallbackLock) {
+ if( null != userConnectedNotificationsCB ) {
+ userConnectedNotificationsCB.run(false);
+ }
+ }
+ }
+ };
+
+
/* pp */ DBTDevice(final long nativeInstance, final DBTAdapter adptr, final String address, final String name, final long ts_creation)
{
super(nativeInstance, compHash(address, name));
@@ -52,7 +108,38 @@ public class DBTDevice extends DBTObject implements BluetoothDevice
this.name = name;
this.ts_creation = ts_creation;
ts_update = ts_creation;
+ appearance = 0;
initImpl();
+ // this.adapter.addStatusListener(statusListener);
+ this.addStatusListener(statusListener);
+ }
+
+ /**
+ * Special proxy of {@link DBTAdapter#addStatusListener(AdapterStatusListener)}
+ * to be used from out constructor called via native deviceFound callback!
+ * <p>
+ * FIXME: Without this proxy hook, we end up in a crash within the addStatusListener(..).
+ * FIXME: Analyze reason! Triage!
+ * </p>
+ */
+ private native boolean addStatusListener(final AdapterStatusListener l);
+
+ @Override
+ public synchronized void close() {
+ disconnect();
+
+ disableConnectedNotifications();
+ disableRSSINotifications();
+ disableManufacturerDataNotifications();
+ disableServicesResolvedNotifications();
+
+ disableBlockedNotifications();
+ disablePairedNotifications();
+ disableServiceDataNotifications();
+ disableTrustedNotifications();
+
+ this.adapter.removeStatusListener(statusListener);
+ super.close();
}
@Override