diff options
-rw-r--r-- | api/direct_bt/BTTypes.hpp | 2 | ||||
-rw-r--r-- | api/direct_bt/DBTManager.hpp | 1 | ||||
-rw-r--r-- | api/direct_bt/DBTTypes.hpp | 13 | ||||
-rw-r--r-- | api/direct_bt/MgmtTypes.hpp | 107 | ||||
-rw-r--r-- | examples/direct_bt_scanner/dbt_scanner.cpp | 9 | ||||
-rw-r--r-- | examples/java/ScannerTinyB01.java | 38 | ||||
-rw-r--r-- | java/direct_bt/tinyb/DBTAdapter.java | 132 | ||||
-rw-r--r-- | java/jni/direct_bt/DBTAdapter.cxx | 128 | ||||
-rw-r--r-- | java/org/tinyb/AdapterSettings.java | 138 | ||||
-rw-r--r-- | java/org/tinyb/BluetoothAdapter.java | 6 | ||||
-rw-r--r-- | java/org/tinyb/BluetoothAdapterStatusListener.java (renamed from java/org/tinyb/BluetoothDeviceStatusListener.java) | 13 | ||||
-rw-r--r-- | java/org/tinyb/EIRDataType.java | 124 | ||||
-rw-r--r-- | java/org/tinyb/EIRDataTypeSet.java | 128 | ||||
-rw-r--r-- | java/tinyb/dbus/DBusAdapter.java | 4 | ||||
-rw-r--r-- | src/direct_bt/BTTypes.cpp | 93 | ||||
-rw-r--r-- | src/direct_bt/DBTAdapter.cpp | 46 | ||||
-rw-r--r-- | src/direct_bt/DBTManager.cpp | 39 | ||||
-rw-r--r-- | src/direct_bt/MgmtTypes.cpp | 48 |
18 files changed, 658 insertions, 411 deletions
diff --git a/api/direct_bt/BTTypes.hpp b/api/direct_bt/BTTypes.hpp index 4018a102..db70fad5 100644 --- a/api/direct_bt/BTTypes.hpp +++ b/api/direct_bt/BTTypes.hpp @@ -305,9 +305,9 @@ namespace direct_bt { inline bool operator !=(const EIRDataType lhs, const EIRDataType rhs) { return !( lhs == rhs ); } - inline bool isEIRDataTypeSet(const EIRDataType mask, const EIRDataType bit) { return EIRDataType::NONE != ( mask & bit ); } inline void setEIRDataTypeSet(EIRDataType &mask, const EIRDataType bit) { mask = mask | bit; } + std::string eirDataBitToString(const EIRDataType bit); std::string eirDataMaskToString(const EIRDataType mask); /** diff --git a/api/direct_bt/DBTManager.hpp b/api/direct_bt/DBTManager.hpp index f55d4c6c..ff9f0687 100644 --- a/api/direct_bt/DBTManager.hpp +++ b/api/direct_bt/DBTManager.hpp @@ -135,7 +135,6 @@ namespace direct_bt { bool mgmtEvClassOfDeviceChangedCB(std::shared_ptr<MgmtEvent> e); bool mgmtEvLocalNameChangedCB(std::shared_ptr<MgmtEvent> e); bool mgmtEvDeviceDiscoveringCB(std::shared_ptr<MgmtEvent> e); - bool mgmtEvNewSettingsCB(std::shared_ptr<MgmtEvent> e); bool mgmtEvDeviceFoundCB(std::shared_ptr<MgmtEvent> e); bool mgmtEvDeviceDisconnectedCB(std::shared_ptr<MgmtEvent> e); bool mgmtEvDeviceConnectedCB(std::shared_ptr<MgmtEvent> e); diff --git a/api/direct_bt/DBTTypes.hpp b/api/direct_bt/DBTTypes.hpp index c603da05..30f90cd5 100644 --- a/api/direct_bt/DBTTypes.hpp +++ b/api/direct_bt/DBTTypes.hpp @@ -166,13 +166,15 @@ namespace direct_bt { // ************************************************* // ************************************************* - class DBTDeviceStatusListener { + class DBTAdapterStatusListener { public: + virtual void adapterSettingsChanged(DBTAdapter const &a, const AdapterSetting oldmask, const AdapterSetting newmask, + const AdapterSetting changedmask, const uint64_t timestamp) = 0; virtual void deviceFound(DBTAdapter const &a, std::shared_ptr<DBTDevice> device, const uint64_t timestamp) = 0; virtual void deviceUpdated(DBTAdapter const &a, std::shared_ptr<DBTDevice> device, const uint64_t timestamp, const EIRDataType updateMask) = 0; virtual void deviceConnected(DBTAdapter const &a, std::shared_ptr<DBTDevice> device, const uint64_t timestamp) = 0; virtual void deviceDisconnected(DBTAdapter const &a, std::shared_ptr<DBTDevice> device, const uint64_t timestamp) = 0; - virtual ~DBTDeviceStatusListener() {} + virtual ~DBTAdapterStatusListener() {} }; class DBTDevice : public DBTObject @@ -338,7 +340,7 @@ namespace direct_bt { std::shared_ptr<HCISession> session; std::vector<std::shared_ptr<DBTDevice>> discoveredDevices; // all discovered devices - std::shared_ptr<DBTDeviceStatusListener> deviceStatusListener = nullptr; + std::shared_ptr<DBTAdapterStatusListener> statusListener = nullptr; std::recursive_mutex mtx_discoveredDevices; bool validateDevInfo(); @@ -351,6 +353,7 @@ namespace direct_bt { void addDiscoveredDevice(std::shared_ptr<DBTDevice> const &device); bool mgmtEvDeviceDiscoveringCB(std::shared_ptr<MgmtEvent> e); + bool mgmtEvNewSettingsCB(std::shared_ptr<MgmtEvent> e); bool mgmtEvDeviceFoundCB(std::shared_ptr<MgmtEvent> e); bool mgmtEvDeviceConnectedCB(std::shared_ptr<MgmtEvent> e); bool mgmtEvDeviceDisconnectedCB(std::shared_ptr<MgmtEvent> e); @@ -412,9 +415,9 @@ namespace direct_bt { // device discovery aka device scanning /** - * Replaces the DBTDeviceStatusListener with the given instance, returning the replaced one. + * Replaces the DBTAdapterStatusListener with the given instance, returning the replaced one. */ - std::shared_ptr<DBTDeviceStatusListener> setDeviceStatusListener(std::shared_ptr<DBTDeviceStatusListener> l); + std::shared_ptr<DBTAdapterStatusListener> setStatusListener(std::shared_ptr<DBTAdapterStatusListener> l); /** * Starts a new discovery session. diff --git a/api/direct_bt/MgmtTypes.hpp b/api/direct_bt/MgmtTypes.hpp index 48dd38ae..10c31cab 100644 --- a/api/direct_bt/MgmtTypes.hpp +++ b/api/direct_bt/MgmtTypes.hpp @@ -68,28 +68,45 @@ namespace direct_bt { MAX_SHORT_NAME_LENGTH = 10+1 }; - enum MgmtSetting : uint32_t { - MGMT_SETTING_POWERED = 0x00000001, - MGMT_SETTING_CONNECTABLE = 0x00000002, - MGMT_SETTING_FAST_CONNECTABLE = 0x00000004, - MGMT_SETTING_DISCOVERABLE = 0x00000008, - MGMT_SETTING_BONDABLE = 0x00000010, - MGMT_SETTING_LINK_SECURITY = 0x00000020, - MGMT_SETTING_SSP = 0x00000040, - MGMT_SETTING_BREDR = 0x00000080, - MGMT_SETTING_HS = 0x00000100, - MGMT_SETTING_LE = 0x00000200, - MGMT_SETTING_ADVERTISING = 0x00000400, - MGMT_SETTING_SECURE_CONN = 0x00000800, - MGMT_SETTING_DEBUG_KEYS = 0x00001000, - MGMT_SETTING_PRIVACY = 0x00002000, - MGMT_SETTING_CONFIGURATION = 0x00004000, - MGMT_SETTING_STATIC_ADDRESS = 0x00008000, - MGMT_SETTING_PHY_CONFIGURATION = 0x00010000 - }; - - std::string getMgmtSettingBitString(const MgmtSetting settingBit); - std::string getMgmtSettingsString(const MgmtSetting settingBitMask); + enum class AdapterSetting : uint32_t { + 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 + }; + inline AdapterSetting operator ^(const AdapterSetting lhs, const AdapterSetting rhs) { + return static_cast<AdapterSetting> ( static_cast<uint32_t>(lhs) ^ static_cast<uint32_t>(rhs) ); + } + inline AdapterSetting operator |(const AdapterSetting lhs, const AdapterSetting rhs) { + return static_cast<AdapterSetting> ( static_cast<uint32_t>(lhs) | static_cast<uint32_t>(rhs) ); + } + inline AdapterSetting operator &(const AdapterSetting lhs, const AdapterSetting rhs) { + return static_cast<AdapterSetting> ( static_cast<uint32_t>(lhs) & static_cast<uint32_t>(rhs) ); + } + inline bool operator ==(const AdapterSetting lhs, const AdapterSetting rhs) { + return static_cast<uint32_t>(lhs) == static_cast<uint32_t>(rhs); + } + inline bool operator !=(const AdapterSetting lhs, const AdapterSetting rhs) { + return !( lhs == rhs ); + } + inline bool isAdapterSettingSet(const AdapterSetting mask, const AdapterSetting bit) { return AdapterSetting::NONE != ( mask & bit ); } + inline void setAdapterSettingSet(AdapterSetting &mask, const AdapterSetting bit) { mask = mask | bit; } + std::string adapterSettingBitToString(const AdapterSetting settingBit); + std::string adapterSettingsToString(const AdapterSetting settingBitMask); enum MgmtConst : int { MGMT_HEADER_SIZE = 6 @@ -552,7 +569,7 @@ namespace direct_bt { protected: std::string baseString() const override { - return MgmtEvent::baseString()+", settings="+getMgmtSettingsString(getSettings()); + return MgmtEvent::baseString()+", settings="+adapterSettingsToString(getSettings()); } public: @@ -561,7 +578,7 @@ namespace direct_bt { { checkOpcode(getOpcode(), NEW_SETTINGS); } - MgmtSetting getSettings() const { return static_cast<MgmtSetting>( pdu.get_uint32(MGMT_HEADER_SIZE) ); } + AdapterSetting getSettings() const { return static_cast<AdapterSetting>( pdu.get_uint32(MGMT_HEADER_SIZE) ); } int getDataOffset() const override { return MGMT_HEADER_SIZE+4; } int getDataSize() const override { return getParamSize()-4; } @@ -898,7 +915,7 @@ namespace direct_bt { std::string valueString() const override { return getAddress().toString()+", version "+std::to_string(getVersion())+ ", manuf "+std::to_string(getManufacturer())+ - ", settings[sup "+getMgmtSettingsString(getSupportedSetting())+", cur "+getMgmtSettingsString(getCurrentSetting())+ + ", settings[sup "+adapterSettingsToString(getSupportedSetting())+", cur "+adapterSettingsToString(getCurrentSetting())+ "], name '"+getName()+"', shortName '"+getShortName()+"'"; } @@ -914,8 +931,8 @@ namespace direct_bt { const EUI48 getAddress() const { return EUI48(pdu.get_ptr(getDataOffset()+0)); } uint8_t getVersion() const { return pdu.get_uint8(getDataOffset()+6); } uint16_t getManufacturer() const { return pdu.get_uint16(getDataOffset()+7); } - MgmtSetting getSupportedSetting() const { return static_cast<MgmtSetting>( pdu.get_uint32(getDataOffset()+9) ); } - MgmtSetting getCurrentSetting() const { return static_cast<MgmtSetting>( pdu.get_uint32(getDataOffset()+13) ); } + AdapterSetting getSupportedSetting() const { return static_cast<AdapterSetting>( pdu.get_uint32(getDataOffset()+9) ); } + AdapterSetting getCurrentSetting() const { return static_cast<AdapterSetting>( pdu.get_uint32(getDataOffset()+13) ); } uint32_t getDevClass() const { return pdu.get_uint8(getDataOffset()+17) | ( pdu.get_uint8(getDataOffset()+18) << 8 ) | ( pdu.get_uint8(getDataOffset()+19) << 16 ); } @@ -924,46 +941,38 @@ namespace direct_bt { }; class DBTManager; // forward + class DBTAdapter; // forward /** Immutable persistent adapter info */ class AdapterInfo { friend class DBTManager; // top manager + friend class DBTAdapter; // direct manager public: const int dev_id; const EUI48 address; const uint8_t version; const uint16_t manufacturer; - const MgmtSetting supported_setting; + const AdapterSetting supported_setting; private: - MgmtSetting current_setting; + AdapterSetting current_setting; uint32_t dev_class; std::string name; std::string short_name; /** - * Sets the current_setting. - * <p> - * Returns 1 if new_setting is supported and different from current_setting, current_setting updated. - * </p> - * <p> - * Returns 0 if new_setting is supported but _not_ different from current_setting, current_setting _not_ updated. - * </p> - * <p> - * Returns -1 if new_setting is _not_ supported, current_setting _not_ updated. - * </p> + * Sets the current_setting and returns the changed MgmtSetting bit-mask. */ - int setCurrentSetting(const MgmtSetting new_setting) { - if( new_setting != ( new_setting & supported_setting ) ) { - return -1; - } - if( new_setting != current_setting ) { + AdapterSetting setCurrentSetting(AdapterSetting new_setting) { + new_setting = new_setting & supported_setting; + AdapterSetting changes = new_setting ^ current_setting; + + if( AdapterSetting::NONE != changes ) { current_setting = new_setting; - return 1; } - return 0; + return changes; } void setDevClass(const uint32_t v) { dev_class = v; } void setName(const std::string v) { name = v; } @@ -977,10 +986,10 @@ namespace direct_bt { name(s.getName()), short_name(s.getShortName()) { } - bool isSettingSupported(const MgmtSetting setting) const { + bool isSettingSupported(const AdapterSetting setting) const { return setting == ( setting & supported_setting ); } - MgmtSetting getCurrentSetting() const { return current_setting; } + AdapterSetting getCurrentSetting() const { return current_setting; } uint32_t getDevClass() const { return dev_class; } const std::string getName() const { return name; } const std::string getShortName() const { return short_name; } @@ -988,7 +997,7 @@ namespace direct_bt { std::string toString() const { return "Adapter[id "+std::to_string(dev_id)+", address "+address.toString()+", version "+std::to_string(version)+ ", manuf "+std::to_string(manufacturer)+ - ", settings[sup "+getMgmtSettingsString(supported_setting)+", cur "+getMgmtSettingsString(current_setting)+ + ", settings[sup "+adapterSettingsToString(supported_setting)+", cur "+adapterSettingsToString(current_setting)+ "], name '"+name+"', shortName '"+short_name+"']"; } }; diff --git a/examples/direct_bt_scanner/dbt_scanner.cpp b/examples/direct_bt_scanner/dbt_scanner.cpp index c0e76ed6..5ab67437 100644 --- a/examples/direct_bt_scanner/dbt_scanner.cpp +++ b/examples/direct_bt_scanner/dbt_scanner.cpp @@ -40,7 +40,12 @@ std::shared_ptr<direct_bt::DBTDevice> deviceFound = nullptr; std::mutex mtxDeviceFound; std::condition_variable cvDeviceFound; -class DeviceStatusListener : public direct_bt::DBTDeviceStatusListener { +class AdapterStatusListener : public direct_bt::DBTAdapterStatusListener { + void adapterSettingsChanged(DBTAdapter const &a, const AdapterSetting oldmask, const AdapterSetting newmask, + const AdapterSetting changedmask, const uint64_t timestamp) override { + + } + void deviceFound(direct_bt::DBTAdapter const &a, std::shared_ptr<direct_bt::DBTDevice> device, const uint64_t timestamp) override { fprintf(stderr, "****** FOUND__: %s\n", device->toString().c_str()); fprintf(stderr, "Status Adapter:\n"); @@ -164,7 +169,7 @@ int main(int argc, char *argv[]) fprintf(stderr, "Using adapter: device %s, address %s: %s\n", adapter.getName().c_str(), adapter.getAddressString().c_str(), adapter.toString().c_str()); - adapter.setDeviceStatusListener(std::shared_ptr<direct_bt::DBTDeviceStatusListener>(new DeviceStatusListener())); + adapter.setStatusListener(std::shared_ptr<direct_bt::DBTAdapterStatusListener>(new AdapterStatusListener())); const int64_t t0 = direct_bt::getCurrentMilliseconds(); diff --git a/examples/java/ScannerTinyB01.java b/examples/java/ScannerTinyB01.java index 8085902d..3b728f1c 100644 --- a/examples/java/ScannerTinyB01.java +++ b/examples/java/ScannerTinyB01.java @@ -27,9 +27,10 @@ import java.lang.reflect.InvocationTargetException; import java.util.Iterator; import java.util.List; +import org.tinyb.AdapterSettings; import org.tinyb.BluetoothAdapter; import org.tinyb.BluetoothDevice; -import org.tinyb.BluetoothDeviceStatusListener; +import org.tinyb.BluetoothAdapterStatusListener; import org.tinyb.BluetoothException; import org.tinyb.BluetoothFactory; import org.tinyb.BluetoothGattCharacteristic; @@ -38,7 +39,7 @@ import org.tinyb.BluetoothGattService; import org.tinyb.BluetoothManager; import org.tinyb.BluetoothNotification; import org.tinyb.BluetoothUtils; -import org.tinyb.EIRDataType; +import org.tinyb.EIRDataTypeSet; public class ScannerTinyB01 { static { @@ -108,7 +109,15 @@ public class ScannerTinyB01 { final BluetoothDevice[] matchingDiscoveredDeviceBucket = { null }; - final BluetoothDeviceStatusListener deviceDiscListener = new BluetoothDeviceStatusListener() { + final BluetoothAdapterStatusListener deviceDiscListener = new BluetoothAdapterStatusListener() { + @Override + public void adapterSettingsChanged(final BluetoothAdapter adapter, final AdapterSettings oldmask, + final AdapterSettings newmask, final AdapterSettings changedmask, final long timestamp) { + System.err.println("****** SETTINGS: "+oldmask+" -> "+newmask+", changed "+changedmask); + System.err.println("Status Adapter:"); + System.err.println(adapter.toString()); + } + @Override public void deviceFound(final BluetoothAdapter adapter, final BluetoothDevice device, final long timestamp) { final boolean matches = device.getAddress().equals(mac); @@ -125,7 +134,7 @@ public class ScannerTinyB01 { } @Override - public void deviceUpdated(final BluetoothAdapter a, final BluetoothDevice device, final long timestamp, final EIRDataType updateMask) { + public void deviceUpdated(final BluetoothAdapter a, final BluetoothDevice device, final long timestamp, final EIRDataTypeSet updateMask) { final boolean matches = device.getAddress().equals(mac); System.err.println("****** UPDATED: "+updateMask+" of "+device+" - match "+matches); System.err.println("Status Adapter:"); @@ -148,17 +157,29 @@ public class ScannerTinyB01 { System.err.println(adapter.toString()); } }; - adapter.setDeviceStatusListener(deviceDiscListener); + adapter.setStatusListener(deviceDiscListener); + adapter.enableDiscoverableNotifications(new BluetoothNotification<Boolean>() { + @Override + public void run(final Boolean value) { + System.err.println("****** Discoverable: "+value); + } + }); adapter.enableDiscoveringNotifications(new BluetoothNotification<Boolean>() { @Override public void run(final Boolean value) { - System.err.println("****** DiscoveringNotification: "+value); + System.err.println("****** Discovering: "+value); + } + }); + adapter.enablePairableNotifications(new BluetoothNotification<Boolean>() { + @Override + public void run(final Boolean value) { + System.err.println("****** Pairable: "+value); } }); adapter.enablePoweredNotifications(new BluetoothNotification<Boolean>() { @Override public void run(final Boolean value) { - System.err.println("****** PoweredNotification: "+value); + System.err.println("****** Powered: "+value); } }); @@ -260,7 +281,10 @@ public class ScannerTinyB01 { adapter.stopDiscovery(); System.err.println("ScannerTinyB01 02 clear listener etc .. "); + adapter.setStatusListener(null); + adapter.disableDiscoverableNotifications(); adapter.disableDiscoveringNotifications(); + adapter.disablePairableNotifications(); adapter.disablePoweredNotifications(); System.err.println("ScannerTinyB01 03 close: "+adapter); 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 } diff --git a/src/direct_bt/BTTypes.cpp b/src/direct_bt/BTTypes.cpp index ed8b48f8..a2b770f0 100644 --- a/src/direct_bt/BTTypes.cpp +++ b/src/direct_bt/BTTypes.cpp @@ -44,6 +44,7 @@ using namespace direct_bt; X(BDADDR_UNDEFINED) #define CASE_TO_STRING(V) case V: return #V; +#define CASE2_TO_STRING(U,V) case U::V: return #V; std::string direct_bt::getBDAddressTypeString(const BDAddressType type) { switch(type) { @@ -124,67 +125,43 @@ std::string ManufactureSpecificData::toString() const { // ************************************************* // ************************************************* +#define EIRDATATYPE_ENUM(X) \ + X(EIRDataType,NONE) \ + X(EIRDataType,EVT_TYPE) \ + X(EIRDataType,BDADDR_TYPE) \ + X(EIRDataType,BDADDR) \ + X(EIRDataType,FLAGS) \ + X(EIRDataType,NAME) \ + X(EIRDataType,NAME_SHORT) \ + X(EIRDataType,RSSI) \ + X(EIRDataType,TX_POWER) \ + X(EIRDataType,MANUF_DATA) \ + X(EIRDataType,DEVICE_CLASS) \ + X(EIRDataType,APPEARANCE) \ + X(EIRDataType,HASH) \ + X(EIRDataType,RANDOMIZER) \ + X(EIRDataType,DEVICE_ID) \ + X(EIRDataType,SERVICE_UUID) + +std::string direct_bt::eirDataBitToString(const EIRDataType bit) { + switch(bit) { + EIRDATATYPE_ENUM(CASE2_TO_STRING) + default: ; // fall through intended + } + return "Unknown EIRDataType Bit"; +} + std::string direct_bt::eirDataMaskToString(const EIRDataType mask) { + const uint32_t one = 1; bool has_pre = false; std::string out("["); - if( isEIRDataTypeSet(mask, EIRDataType::EVT_TYPE) ) { - out.append("EVT_TYPE"); has_pre = true; - } - if( isEIRDataTypeSet(mask, EIRDataType::BDADDR_TYPE) ) { - if( has_pre ) { out.append(", "); } - out.append("BDADDR_TYPE"); has_pre = true; - } - if( isEIRDataTypeSet(mask, EIRDataType::BDADDR) ) { - if( has_pre ) { out.append(", "); } - out.append("BDADDR"); has_pre = true; - } - if( isEIRDataTypeSet(mask, EIRDataType::FLAGS) ) { - if( has_pre ) { out.append(", "); } - out.append("FLAGS"); has_pre = true; - } - if( isEIRDataTypeSet(mask, EIRDataType::NAME) ) { - if( has_pre ) { out.append(", "); } - out.append("NAME"); has_pre = true; - } - if( isEIRDataTypeSet(mask, EIRDataType::NAME_SHORT) ) { - if( has_pre ) { out.append(", "); } - out.append("NAME_SHORT"); has_pre = true; - } - if( isEIRDataTypeSet(mask, EIRDataType::RSSI) ) { - if( has_pre ) { out.append(", "); } - out.append("RSSI"); has_pre = true; - } - if( isEIRDataTypeSet(mask, EIRDataType::TX_POWER) ) { - if( has_pre ) { out.append(", "); } - out.append("TX_POWER"); has_pre = true; - } - if( isEIRDataTypeSet(mask, EIRDataType::MANUF_DATA) ) { - if( has_pre ) { out.append(", "); } - out.append("MANUF_DATA"); has_pre = true; - } - if( isEIRDataTypeSet(mask, EIRDataType::DEVICE_CLASS) ) { - if( has_pre ) { out.append(", "); } - out.append("DEVICE_CLASS"); has_pre = true; - } - if( isEIRDataTypeSet(mask, EIRDataType::APPEARANCE) ) { - if( has_pre ) { out.append(", "); } - out.append("APPEARANCE"); has_pre = true; - } - if( isEIRDataTypeSet(mask, EIRDataType::HASH) ) { - if( has_pre ) { out.append(", "); } - out.append("HASH"); has_pre = true; - } - if( isEIRDataTypeSet(mask, EIRDataType::RANDOMIZER) ) { - if( has_pre ) { out.append(", "); } - out.append("RANDOMIZER"); has_pre = true; - } - if( isEIRDataTypeSet(mask, EIRDataType::DEVICE_ID) ) { - if( has_pre ) { out.append(", "); } - out.append("DEVICE_ID"); has_pre = true; - } - if( isEIRDataTypeSet(mask, EIRDataType::SERVICE_UUID) ) { - if( has_pre ) { out.append(", "); } - out.append("SERVICE_UUID"); has_pre = true; + for(int i=0; i<32; i++) { + const EIRDataType settingBit = static_cast<EIRDataType>( one << i ); + if( EIRDataType::NONE != ( mask & settingBit ) ) { + if( has_pre ) { out.append(", "); } + out.append(eirDataBitToString(settingBit)); + has_pre = true; + } } out.append("]"); return out; diff --git a/src/direct_bt/DBTAdapter.cpp b/src/direct_bt/DBTAdapter.cpp index 38cefe6d..284f24db 100644 --- a/src/direct_bt/DBTAdapter.cpp +++ b/src/direct_bt/DBTAdapter.cpp @@ -160,6 +160,7 @@ bool DBTAdapter::validateDevInfo() { adapterInfo = mgmt.getAdapterInfo(dev_id); mgmt.addMgmtEventCallback(dev_id, MgmtEvent::Opcode::DISCOVERING, bindMemberFunc(this, &DBTAdapter::mgmtEvDeviceDiscoveringCB)); + mgmt.addMgmtEventCallback(dev_id, MgmtEvent::Opcode::NEW_SETTINGS, bindMemberFunc(this, &DBTAdapter::mgmtEvNewSettingsCB)); mgmt.addMgmtEventCallback(dev_id, MgmtEvent::Opcode::DEVICE_CONNECTED, bindMemberFunc(this, &DBTAdapter::mgmtEvDeviceConnectedCB)); mgmt.addMgmtEventCallback(dev_id, MgmtEvent::Opcode::DEVICE_DISCONNECTED, bindMemberFunc(this, &DBTAdapter::mgmtEvDeviceDisconnectedCB)); mgmt.addMgmtEventCallback(dev_id, MgmtEvent::Opcode::DEVICE_FOUND, bindMemberFunc(this, &DBTAdapter::mgmtEvDeviceFoundCB)); @@ -200,11 +201,11 @@ DBTAdapter::~DBTAdapter() { keepDiscoveringAlive = false; { int count; - if( 4 != ( count = mgmt.removeMgmtEventCallback(dev_id) ) ) { - ERR_PRINT("DBTAdapter removeMgmtEventCallback(DISCOVERING) not 4 but %d", count); + if( 5 != ( count = mgmt.removeMgmtEventCallback(dev_id) ) ) { + ERR_PRINT("DBTAdapter removeMgmtEventCallback(DISCOVERING) not 5 but %d", count); } } - deviceStatusListener = nullptr; + statusListener = nullptr; removeDiscoveredDevices(); @@ -231,10 +232,10 @@ std::shared_ptr<HCISession> DBTAdapter::open() return session; } -std::shared_ptr<DBTDeviceStatusListener> DBTAdapter::setDeviceStatusListener(std::shared_ptr<DBTDeviceStatusListener> l) +std::shared_ptr<DBTAdapterStatusListener> DBTAdapter::setStatusListener(std::shared_ptr<DBTAdapterStatusListener> l) { - std::shared_ptr<DBTDeviceStatusListener> o = deviceStatusListener; - deviceStatusListener = l; + std::shared_ptr<DBTAdapterStatusListener> o = statusListener; + statusListener = l; return o; } @@ -338,6 +339,21 @@ bool DBTAdapter::mgmtEvDeviceDiscoveringCB(std::shared_ptr<MgmtEvent> e) { return true; } +bool DBTAdapter::mgmtEvNewSettingsCB(std::shared_ptr<MgmtEvent> e) { + DBG_PRINT("DBTAdapter::EventCB:NewSettings: %s", e->toString().c_str()); + const MgmtEvtNewSettings &event = *static_cast<const MgmtEvtNewSettings *>(e.get()); + AdapterSetting old_setting = adapterInfo->getCurrentSetting(); + AdapterSetting changes = adapterInfo->setCurrentSetting(event.getSettings()); + DBG_PRINT("DBTAdapter::EventCB:NewSettings: %s -> %s, changes %s", + adapterSettingsToString(old_setting).c_str(), + adapterSettingsToString(adapterInfo->getCurrentSetting()).c_str(), + adapterSettingsToString(changes).c_str() ); + if( nullptr != statusListener ) { + statusListener->adapterSettingsChanged(*this, old_setting, adapterInfo->getCurrentSetting(), changes, event.getTimestamp()); + } + return true; +} + bool DBTAdapter::mgmtEvDeviceConnectedCB(std::shared_ptr<MgmtEvent> e) { const MgmtEvtDeviceConnected &event = *static_cast<const MgmtEvtDeviceConnected *>(e.get()); if( nullptr == session ) { @@ -364,11 +380,11 @@ bool DBTAdapter::mgmtEvDeviceConnectedCB(std::shared_ptr<MgmtEvent> e) { if( new_connect ) { session->connected(device); // track it } - if( nullptr != deviceStatusListener ) { + if( nullptr != statusListener ) { if( EIRDataType::NONE != updateMask ) { - deviceStatusListener->deviceUpdated(*this, device, ad_report.getTimestamp(), updateMask); + statusListener->deviceUpdated(*this, device, ad_report.getTimestamp(), updateMask); } - deviceStatusListener->deviceConnected(*this, device, event.getTimestamp()); + statusListener->deviceConnected(*this, device, event.getTimestamp()); } } else { DBG_PRINT("DBTAdapter::EventCB:DeviceConnected(dev_id %d): %s,\n %s\n -> Device not tracked nor discovered", @@ -385,8 +401,8 @@ bool DBTAdapter::mgmtEvDeviceDisconnectedCB(std::shared_ptr<MgmtEvent> e) { if( nullptr != device ) { DBG_PRINT("DBTAdapter::EventCB:DeviceDisconnected(dev_id %d): %s\n -> %s", dev_id, event.toString().c_str(), device->toString().c_str()); - if( nullptr != deviceStatusListener ) { - deviceStatusListener->deviceDisconnected(*this, device, event.getTimestamp()); + if( nullptr != statusListener ) { + statusListener->deviceDisconnected(*this, device, event.getTimestamp()); } } else { DBG_PRINT("DBTAdapter::EventCB:DeviceDisconnected(dev_id %d): %s\n -> Device not tracked", @@ -413,14 +429,14 @@ bool DBTAdapter::mgmtEvDeviceFoundCB(std::shared_ptr<MgmtEvent> e) { // new device dev = std::shared_ptr<DBTDevice>(new DBTDevice(*this, ad_report)); addDiscoveredDevice(dev); - if( nullptr != deviceStatusListener ) { - deviceStatusListener->deviceFound(*this, dev, ad_report.getTimestamp()); + if( nullptr != statusListener ) { + statusListener->deviceFound(*this, dev, ad_report.getTimestamp()); } } else { // existing device EIRDataType updateMask = dev->update(ad_report); - if( EIRDataType::NONE != updateMask && nullptr != deviceStatusListener ) { - deviceStatusListener->deviceUpdated(*this, dev, ad_report.getTimestamp(), updateMask); + if( EIRDataType::NONE != updateMask && nullptr != statusListener ) { + statusListener->deviceUpdated(*this, dev, ad_report.getTimestamp(), updateMask); } } return true; diff --git a/src/direct_bt/DBTManager.cpp b/src/direct_bt/DBTManager.cpp index 5fca460c..508494ef 100644 --- a/src/direct_bt/DBTManager.cpp +++ b/src/direct_bt/DBTManager.cpp @@ -352,7 +352,6 @@ next1: addMgmtEventCallback(-1, MgmtEvent::Opcode::CLASS_OF_DEV_CHANGED, bindMemberFunc(this, &DBTManager::mgmtEvClassOfDeviceChangedCB)); addMgmtEventCallback(-1, MgmtEvent::Opcode::LOCAL_NAME_CHANGED, bindMemberFunc(this, &DBTManager::mgmtEvLocalNameChangedCB)); addMgmtEventCallback(-1, MgmtEvent::Opcode::DISCOVERING, bindMemberFunc(this, &DBTManager::mgmtEvDeviceDiscoveringCB)); - addMgmtEventCallback(-1, MgmtEvent::Opcode::NEW_SETTINGS, bindMemberFunc(this, &DBTManager::mgmtEvNewSettingsCB)); addMgmtEventCallback(-1, MgmtEvent::Opcode::DEVICE_FOUND, bindMemberFunc(this, &DBTManager::mgmtEvDeviceFoundCB)); addMgmtEventCallback(-1, MgmtEvent::Opcode::DEVICE_DISCONNECTED, bindMemberFunc(this, &DBTManager::mgmtEvDeviceDisconnectedCB)); addMgmtEventCallback(-1, MgmtEvent::Opcode::DEVICE_CONNECTED, bindMemberFunc(this, &DBTManager::mgmtEvDeviceConnectedCB)); @@ -619,11 +618,11 @@ void DBTManager::clearAllMgmtEventCallbacks() { } bool DBTManager::mgmtEvClassOfDeviceChangedCB(std::shared_ptr<MgmtEvent> e) { - DBG_PRINT("DBRManager::EventCB:ClassOfDeviceChanged: %s", e->toString().c_str()); + DBG_PRINT("DBTManager::EventCB:ClassOfDeviceChanged: %s", e->toString().c_str()); return true; } bool DBTManager::mgmtEvLocalNameChangedCB(std::shared_ptr<MgmtEvent> e) { - DBG_PRINT("DBRManager::EventCB:LocalNameChanged: %s", e->toString().c_str()); + DBG_PRINT("DBTManager::EventCB:LocalNameChanged: %s", e->toString().c_str()); const MgmtEvtLocalNameChanged &event = *static_cast<const MgmtEvtLocalNameChanged *>(e.get()); std::shared_ptr<AdapterInfo> adapterInfo = getAdapterInfo(event.getDevID()); std::string old_name = adapterInfo->getName(); @@ -636,7 +635,7 @@ bool DBTManager::mgmtEvLocalNameChangedCB(std::shared_ptr<MgmtEvent> e) { if( shortNameChanged ) { adapterInfo->setShortName(event.getShortName()); } - DBG_PRINT("DBRManager::EventCB:LocalNameChanged: Name: %d: '%s' -> '%s'; ShortName: %d: '%s' -> '%s'", + DBG_PRINT("DBTManager::EventCB:LocalNameChanged: Name: %d: '%s' -> '%s'; ShortName: %d: '%s' -> '%s'", nameChanged, old_name.c_str(), adapterInfo->getName().c_str(), shortNameChanged, old_shortName.c_str(), adapterInfo->getShortName().c_str()); (void)nameChanged; @@ -644,73 +643,61 @@ bool DBTManager::mgmtEvLocalNameChangedCB(std::shared_ptr<MgmtEvent> e) { return true; } bool DBTManager::mgmtEvDeviceDiscoveringCB(std::shared_ptr<MgmtEvent> e) { - DBG_PRINT("DBRManager::EventCB:DeviceDiscovering: %s", e->toString().c_str()); + DBG_PRINT("DBTManager::EventCB:DeviceDiscovering: %s", e->toString().c_str()); const MgmtEvtDiscovering &event = *static_cast<const MgmtEvtDiscovering *>(e.get()); (void)event; return true; } -bool DBTManager::mgmtEvNewSettingsCB(std::shared_ptr<MgmtEvent> e) { - DBG_PRINT("DBRManager::EventCB:NewSettings: %s", e->toString().c_str()); - const MgmtEvtNewSettings &event = *static_cast<const MgmtEvtNewSettings *>(e.get()); - std::shared_ptr<AdapterInfo> adapterInfo = getAdapterInfo(event.getDevID()); - MgmtSetting old_setting = adapterInfo->getCurrentSetting(); - int res = adapterInfo->setCurrentSetting(event.getSettings()); - DBG_PRINT("DBRManager::EventCB:NewSettings: %d: %s -> %s", res, - getMgmtSettingsString(old_setting).c_str(), - getMgmtSettingsString(adapterInfo->getCurrentSetting()).c_str()); - (void)res; - return true; -} bool DBTManager::mgmtEvDeviceFoundCB(std::shared_ptr<MgmtEvent> e) { - DBG_PRINT("DBRManager::EventCB:DeviceFound: %s", e->toString().c_str()); + DBG_PRINT("DBTManager::EventCB:DeviceFound: %s", e->toString().c_str()); const MgmtEvtDeviceFound &event = *static_cast<const MgmtEvtDeviceFound *>(e.get()); (void)event; return true; } bool DBTManager::mgmtEvDeviceDisconnectedCB(std::shared_ptr<MgmtEvent> e) { - DBG_PRINT("DBRManager::EventCB:DeviceDisconnected: %s", e->toString().c_str()); + DBG_PRINT("DBTManager::EventCB:DeviceDisconnected: %s", e->toString().c_str()); const MgmtEvtDeviceDisconnected &event = *static_cast<const MgmtEvtDeviceDisconnected *>(e.get()); (void)event; return true; } bool DBTManager::mgmtEvDeviceConnectedCB(std::shared_ptr<MgmtEvent> e) { - DBG_PRINT("DBRManager::EventCB:DeviceConnected: %s", e->toString().c_str()); + DBG_PRINT("DBTManager::EventCB:DeviceConnected: %s", e->toString().c_str()); const MgmtEvtDeviceConnected &event = *static_cast<const MgmtEvtDeviceConnected *>(e.get()); (void)event; return true; } bool DBTManager::mgmtEvConnectFailedCB(std::shared_ptr<MgmtEvent> e) { - DBG_PRINT("DBRManager::EventCB:ConnectFailed: %s", e->toString().c_str()); + DBG_PRINT("DBTManager::EventCB:ConnectFailed: %s", e->toString().c_str()); const MgmtEvtDeviceConnectFailed &event = *static_cast<const MgmtEvtDeviceConnectFailed *>(e.get()); (void)event; return true; } bool DBTManager::mgmtEvDevicePinCodeRequestCB(std::shared_ptr<MgmtEvent> e) { - DBG_PRINT("DBRManager::EventCB:PinCodeRequest: %s", e->toString().c_str()); + DBG_PRINT("DBTManager::EventCB:PinCodeRequest: %s", e->toString().c_str()); const MgmtEvtPinCodeRequest &event = *static_cast<const MgmtEvtPinCodeRequest *>(e.get()); (void)event; return true; } bool DBTManager::mgmtEvDeviceUnpairedCB(std::shared_ptr<MgmtEvent> e) { - DBG_PRINT("DBRManager::EventCB:DeviceUnpaired: %s", e->toString().c_str()); + DBG_PRINT("DBTManager::EventCB:DeviceUnpaired: %s", e->toString().c_str()); const MgmtEvtDeviceUnpaired &event = *static_cast<const MgmtEvtDeviceUnpaired *>(e.get()); (void)event; return true; } bool DBTManager::mgmtEvNewConnectionParamCB(std::shared_ptr<MgmtEvent> e) { - DBG_PRINT("DBRManager::EventCB:NewConnectionParam: %s", e->toString().c_str()); + DBG_PRINT("DBTManager::EventCB:NewConnectionParam: %s", e->toString().c_str()); const MgmtEvtNewConnectionParam &event = *static_cast<const MgmtEvtNewConnectionParam *>(e.get()); (void)event; return true; } bool DBTManager::mgmtEvDeviceWhitelistAddedCB(std::shared_ptr<MgmtEvent> e) { - DBG_PRINT("DBRManager::EventCB:DeviceAdded: %s", e->toString().c_str()); + DBG_PRINT("DBTManager::EventCB:DeviceAdded: %s", e->toString().c_str()); const MgmtEvtDeviceWhitelistAdded &event = *static_cast<const MgmtEvtDeviceWhitelistAdded *>(e.get()); (void)event; return true; } bool DBTManager::mgmtEvDeviceWhilelistRemovedCB(std::shared_ptr<MgmtEvent> e) { - DBG_PRINT("DBRManager::EventCB:DeviceRemoved: %s", e->toString().c_str()); + DBG_PRINT("DBTManager::EventCB:DeviceRemoved: %s", e->toString().c_str()); const MgmtEvtDeviceWhitelistRemoved &event = *static_cast<const MgmtEvtDeviceWhitelistRemoved *>(e.get()); (void)event; return true; diff --git a/src/direct_bt/MgmtTypes.cpp b/src/direct_bt/MgmtTypes.cpp index 17617762..81070e74 100644 --- a/src/direct_bt/MgmtTypes.cpp +++ b/src/direct_bt/MgmtTypes.cpp @@ -55,43 +55,45 @@ using namespace direct_bt; // ************************************************* #define CASE_TO_STRING(V) case V: return #V; +#define CASE2_TO_STRING(U,V) case U::V: return #V; #define SETTING_ENUM(X) \ - X(MGMT_SETTING_POWERED) \ - X(MGMT_SETTING_CONNECTABLE) \ - X(MGMT_SETTING_FAST_CONNECTABLE) \ - X(MGMT_SETTING_DISCOVERABLE) \ - X(MGMT_SETTING_BONDABLE) \ - X(MGMT_SETTING_LINK_SECURITY) \ - X(MGMT_SETTING_SSP) \ - X(MGMT_SETTING_BREDR) \ - X(MGMT_SETTING_HS) \ - X(MGMT_SETTING_LE) \ - X(MGMT_SETTING_ADVERTISING) \ - X(MGMT_SETTING_SECURE_CONN) \ - X(MGMT_SETTING_DEBUG_KEYS) \ - X(MGMT_SETTING_PRIVACY) \ - X(MGMT_SETTING_CONFIGURATION) \ - X(MGMT_SETTING_STATIC_ADDRESS) \ - X(MGMT_SETTING_PHY_CONFIGURATION) \ + X(AdapterSetting,NONE) \ + X(AdapterSetting,POWERED) \ + X(AdapterSetting,CONNECTABLE) \ + X(AdapterSetting,FAST_CONNECTABLE) \ + X(AdapterSetting,DISCOVERABLE) \ + X(AdapterSetting,BONDABLE) \ + X(AdapterSetting,LINK_SECURITY) \ + X(AdapterSetting,SSP) \ + X(AdapterSetting,BREDR) \ + X(AdapterSetting,HS) \ + X(AdapterSetting,LE) \ + X(AdapterSetting,ADVERTISING) \ + X(AdapterSetting,SECURE_CONN) \ + X(AdapterSetting,DEBUG_KEYS) \ + X(AdapterSetting,PRIVACY) \ + X(AdapterSetting,CONFIGURATION) \ + X(AdapterSetting,STATIC_ADDRESS) \ + X(AdapterSetting,PHY_CONFIGURATION) -std::string direct_bt::getMgmtSettingBitString(const MgmtSetting settingBit) { +std::string direct_bt::adapterSettingBitToString(const AdapterSetting settingBit) { switch(settingBit) { - SETTING_ENUM(CASE_TO_STRING) + SETTING_ENUM(CASE2_TO_STRING) default: ; // fall through intended } return "Unknown Setting Bit"; } -std::string direct_bt::getMgmtSettingsString(const MgmtSetting settingMask) { +std::string direct_bt::adapterSettingsToString(const AdapterSetting settingMask) { const uint32_t one = 1; bool has_pre = false; std::string out("["); for(int i=0; i<32; i++) { - const MgmtSetting settingBit = static_cast<MgmtSetting>( one << i ); - if( 0 != ( settingMask & settingBit ) ) { + const AdapterSetting settingBit = static_cast<AdapterSetting>( one << i ); + if( AdapterSetting::NONE != ( settingMask & settingBit ) ) { if( has_pre ) { out.append(", "); } - out.append(getMgmtSettingBitString(settingBit)); + out.append(adapterSettingBitToString(settingBit)); has_pre = true; } } |