diff options
Diffstat (limited to 'api/direct_bt')
-rw-r--r-- | api/direct_bt/ATTPDUTypes.hpp | 26 | ||||
-rw-r--r-- | api/direct_bt/DBTAdapter.hpp | 65 | ||||
-rw-r--r-- | api/direct_bt/DBTManager.hpp | 76 | ||||
-rw-r--r-- | api/direct_bt/DBTTypes.hpp | 41 | ||||
-rw-r--r-- | api/direct_bt/DirectBT.hpp | 5 | ||||
-rw-r--r-- | api/direct_bt/MgmtTypes.hpp | 2 |
6 files changed, 122 insertions, 93 deletions
diff --git a/api/direct_bt/ATTPDUTypes.hpp b/api/direct_bt/ATTPDUTypes.hpp index 990d5362..b5af035c 100644 --- a/api/direct_bt/ATTPDUTypes.hpp +++ b/api/direct_bt/ATTPDUTypes.hpp @@ -77,17 +77,18 @@ * - - - - - - - - - - - - - - - * * From a user perspective the following hierarchy is provided - * - DBTAdapter has no or more - * - DBTDevice has no or more - * - GATTService has no or more - * - GATTCharacteristic has no or more - * - GATTDescriptor + * - DBTManager has zero or more + * - DBTAdapter has zero or more + * - DBTDevice has zero or more + * - GATTService has zero or more + * - GATTCharacteristic has zero or more + * - GATTDescriptor * * - - - - - - - - - - - - - - - * * Object lifecycle with all instances and marked weak back-references to their owner * - DBTManager singleton instance for all - * - DBTAdapter ownership by user (C++) and BluetoothManager (Java) + * - DBTAdapter ownership by DBTManager * - DBTDevice ownership by DBTAdapter * - GATTHandler ownership by DBTDevice, with weak DBTDevice back-reference * - GATTService ownership by GATTHandler, with weak GATTHandler back-reference @@ -96,6 +97,19 @@ * * - - - - - - - - - - - - - - - * + * Mapped names from C++ implementation to Java implementation and to Java interface: + * + * C++ | Java Implementation | Java Interface | + * :------------------| :---------------------| :---------------------------| + * DBTManager | DBTManager | BluetoothManager | + * DBTAdapter | DBTAdapter | BluetoothAdapter | + * DBTDevice | DBTDevice | BluetoothDevice | + * GATTService | DBTGattService | BluetoothGattService | + * GATTCharacteristic | DBTGattCharacteristic | BluetoothGattCharacteristic | + * GATTDescriptor | DBTGattDescriptor | BluetoothGattDescriptor | + * + * - - - - - - - - - - - - - - - + * * A fully event driven workflow from discovery to GATT programming is supported. * * AdapterStatusListener allows listening to adapter changes and device discovery diff --git a/api/direct_bt/DBTAdapter.hpp b/api/direct_bt/DBTAdapter.hpp index 10735eb6..1ab4fc90 100644 --- a/api/direct_bt/DBTAdapter.hpp +++ b/api/direct_bt/DBTAdapter.hpp @@ -42,11 +42,11 @@ #include "DBTDevice.hpp" #include "HCIHandler.hpp" -#include "DBTManager.hpp" namespace direct_bt { class DBTAdapter; // forward + class DBTManager; // forward /** * {@link DBTAdapter} status listener for {@link DBTDevice} discovery events: Added, updated and removed; @@ -202,8 +202,11 @@ namespace direct_bt { class DBTAdapter : public DBTObject { private: + friend DBTManager; + const bool debug_event, debug_lock; DBTManager& mgmt; + AdapterInfo adapterInfo; public: /** @@ -212,13 +215,12 @@ namespace direct_bt { * The internal device id is constant across the adapter lifecycle, * but may change after its destruction. */ - const int dev_id; + const uint16_t dev_id; private: HCIHandler hci; std::atomic<AdapterSetting> old_settings; - std::shared_ptr<AdapterInfo> adapterInfo; std::atomic<BTMode> btMode = BTMode::NONE; NameAndShortName localName; std::atomic<ScanType> currentMetaScanType; // = ScanType::NONE @@ -248,6 +250,8 @@ namespace direct_bt { static std::shared_ptr<DBTDevice> findDevice(device_list_t & devices, const EUI48 & address, const BDAddressType addressType) noexcept; static std::shared_ptr<DBTDevice> findDevice(device_list_t & devices, DBTDevice const & device) noexcept; + DBTAdapter(DBTManager& mgmt_, const AdapterInfo& adapterInfo_) noexcept; + /** * Closes all device connections, stops discovery and cleans up all references. * <p> @@ -329,35 +333,6 @@ namespace direct_bt { public: - /** - * Using the default adapter device - * <p> - * The default adapter is either the first POWERED adapter, - * or none - in which case this instance !isValid() - * </p> - */ - DBTAdapter() noexcept; - - /** - * Using the identified adapter with given mac address. - * - * @param[in] mac address - */ - DBTAdapter(EUI48 &mac) noexcept; - - /** - * Using the identified adapter with given dev_id, - * or the default adapter device if dev_id < 0. - * <p> - * The default adapter is either the first POWERED adapter, - * or none - in which case this instance !isValid(). - * </p> - * - * @param[in] dev_id an already identified HCI device id - * or use -1 to choose the default adapter. - */ - DBTAdapter(const int dev_id) noexcept; - DBTAdapter(const DBTAdapter&) = delete; void operator=(const DBTAdapter&) = delete; @@ -367,7 +342,8 @@ namespace direct_bt { ~DBTAdapter() noexcept; /** - * Closes this instance, usually being called by destructor or when this adapter is being removed. + * Closes this instance, usually being called by destructor or when this adapter is being removed + * as recognized and handled by DBTManager. * <p> * Renders this adapter's DBTAdapter#isValid() state to false. * </p> @@ -381,8 +357,6 @@ namespace direct_bt { return std::string(JAVA_DBT_PACKAGE "DBTAdapter"); } - bool hasDevId() const noexcept { return 0 <= dev_id; } - /** * Returns whether the adapter is valid, plugged in and powered. * @return true if DBTAdapter::isValid(), HCIHandler::isOpen() and AdapterSetting::POWERED state is set. @@ -390,7 +364,7 @@ namespace direct_bt { * @see #isValid() */ bool isPowered() const noexcept { - return isValid() && hci.isOpen() && adapterInfo->isCurrentSettingBitSet(AdapterSetting::POWERED); + return isValid() && hci.isOpen() && adapterInfo.isCurrentSettingBitSet(AdapterSetting::POWERED); } /** @@ -400,15 +374,15 @@ namespace direct_bt { * @see #isValid() */ bool isSuspended() const noexcept { - return isValid() && hci.isOpen() && !adapterInfo->isCurrentSettingBitSet(AdapterSetting::POWERED); + return isValid() && hci.isOpen() && !adapterInfo.isCurrentSettingBitSet(AdapterSetting::POWERED); } bool hasSecureConnections() const noexcept { - return adapterInfo->isCurrentSettingBitSet(AdapterSetting::SECURE_CONN); + return adapterInfo.isCurrentSettingBitSet(AdapterSetting::SECURE_CONN); } bool hasSecureSimplePairing() const noexcept { - return adapterInfo->isCurrentSettingBitSet(AdapterSetting::SSP); + return adapterInfo.isCurrentSettingBitSet(AdapterSetting::SSP); } /** @@ -422,18 +396,23 @@ namespace direct_bt { return DBTObject::isValid(); } - EUI48 const & getAddress() const noexcept { return adapterInfo->address; } - std::string getAddressString() const noexcept { return adapterInfo->address.toString(); } + /** + * Returns the current BTMode of this adapter. + */ + BTMode getBTMode() const noexcept { return adapterInfo.getCurrentBTMode(); } + + EUI48 const & getAddress() const noexcept { return adapterInfo.address; } + std::string getAddressString() const noexcept { return adapterInfo.address.toString(); } /** * Returns the system name. */ - std::string getName() const noexcept { return adapterInfo->getName(); } + std::string getName() const noexcept { return adapterInfo.getName(); } /** * Returns the short system name. */ - std::string getShortName() const noexcept { return adapterInfo->getShortName(); } + std::string getShortName() const noexcept { return adapterInfo.getShortName(); } /** * Returns the local friendly name and short_name. Contains empty strings if not set. diff --git a/api/direct_bt/DBTManager.hpp b/api/direct_bt/DBTManager.hpp index f158f89d..e538704d 100644 --- a/api/direct_bt/DBTManager.hpp +++ b/api/direct_bt/DBTManager.hpp @@ -45,6 +45,7 @@ #include "OctetTypes.hpp" #include "HCIComm.hpp" #include "MgmtTypes.hpp" +#include "DBTAdapter.hpp" namespace direct_bt { @@ -146,15 +147,20 @@ namespace direct_bt { * The callback is performed on a dedicated thread, * allowing the user to perform complex operations. * </p> + * <p> + * If an adapter is being removed from the system, + * DBTAdapter::close() is being called by DBTManager after issuing all + * ChangedAdapterSetFunc calls. + * </p> * * @param added true if adapter was newly added, otherwise removed from system - * @param adapterInfo the adapter's AdapterInfo, inclusive the dev_id + * @param adapter the shared DBTAdapter reference * @return ignored * @see ChangedAdapterSetCallback * @see DBTManager::addChangedAdapterSetCallback() * @see DBTManager::removeChangedAdapterSetCallback() */ - typedef bool (*ChangedAdapterSetFunc)(bool added, const AdapterInfo& adapterInfo); + typedef bool (*ChangedAdapterSetFunc)(bool added, std::shared_ptr<DBTAdapter>& adapter); /** * Callback jau::FunctionDef to receive change events regarding the system's adapter set, @@ -167,15 +173,20 @@ namespace direct_bt { * The callback is performed on a dedicated thread, * allowing the user to perform complex operations. * </p> + * <p> + * If an adapter is being removed from the system, + * DBTAdapter::close() is being called by DBTManager after issuing all + * ChangedAdapterSetFunc calls. + * </p> * * @param added true if adapter was newly added, otherwise removed from system - * @param adapterInfo the adapter's AdapterInfo, inclusive the dev_id + * @param adapter the shared DBTAdapter reference * @return ignored * @see ChangedAdapterSetFunc * @see DBTManager::addChangedAdapterSetCallback() * @see DBTManager::removeChangedAdapterSetCallback() */ - typedef jau::FunctionDef<bool, bool, const AdapterInfo&> ChangedAdapterSetCallback; + typedef jau::FunctionDef<bool, bool, std::shared_ptr<DBTAdapter>&> ChangedAdapterSetCallback; typedef jau::cow_darray<ChangedAdapterSetCallback> ChangedAdapterSetCallbackList; /** @@ -197,6 +208,8 @@ namespace direct_bt { static const pid_t pidSelf; private: + friend DBTAdapter::~DBTAdapter() noexcept; + static std::mutex mtx_singleton; struct WhitelistElem { @@ -237,8 +250,8 @@ namespace direct_bt { ChangedAdapterSetCallbackList mgmtChangedAdapterSetCallbackList; - typedef jau::cow_darray<std::shared_ptr<AdapterInfo>> adapterInfos_t; - adapterInfos_t adapterInfos; + typedef jau::cow_darray<std::shared_ptr<DBTAdapter>> adapters_t; + adapters_t adapters; /** * Using defaultIOCapability on added AdapterInfo. @@ -267,27 +280,28 @@ namespace direct_bt { void operator=(const DBTManager&) = delete; void setAdapterMode(const uint16_t dev_id, const uint8_t ssp, const uint8_t bredr, const uint8_t le) noexcept; - std::shared_ptr<AdapterInfo> initAdapter(const uint16_t dev_id, const BTMode btMode) noexcept; - void shutdownAdapter(const uint16_t dev_id) noexcept; + std::unique_ptr<AdapterInfo> initAdapter(const uint16_t dev_id, const BTMode btMode) noexcept; + void shutdownAdapter(DBTAdapter& adapter) noexcept; void processAdapterAdded(std::unique_ptr<MgmtEvent> e) noexcept; void processAdapterRemoved(std::unique_ptr<MgmtEvent> e) noexcept; bool mgmtEvNewSettingsCB(const MgmtEvent& e) noexcept; bool mgmtEventAnyCB(const MgmtEvent& e) noexcept; - int findAdapterInfoIndex(const uint16_t dev_id) const noexcept; + std::shared_ptr<DBTAdapter> addAdapter(const AdapterInfo& ai) noexcept; /** - * Adds the given AdapterInfo if representing a new dev_id. - * @return true if newly added dev_id, otherwise false if dev_id already exists. + * Removes the AdapterInfo with the given dev_id + * @return the removed instance or nullptr if not found. */ - bool addAdapterInfo(std::shared_ptr<AdapterInfo> ai) noexcept; + std::shared_ptr<DBTAdapter> removeAdapter(const uint16_t dev_id) noexcept; /** - * Removes the AdapterInfo with the given dev_id - * @return the removed instance or nullptr if not found. + * Removal entry for DBTAdapter::~DBTAdapter + * @param adapter pointer to the dtor'ed adapter + * @return true if contained and removed, otherwise false */ - std::shared_ptr<AdapterInfo> removeAdapterInfo(const uint16_t dev_id) noexcept; + bool removeAdapter(DBTAdapter* adapter) noexcept; public: /** @@ -332,7 +346,7 @@ namespace direct_bt { } std::string toString() const noexcept override { - return "MgmtHandler[BTMode "+getBTModeString(defaultBTMode)+", "+std::to_string(adapterInfos.size())+" adapter, "+javaObjectToString()+"]"; + return "MgmtHandler[BTMode "+getBTModeString(defaultBTMode)+", "+std::to_string(adapters.size())+" adapter, "+javaObjectToString()+"]"; } /** retrieve information gathered at startup */ @@ -340,27 +354,22 @@ namespace direct_bt { /** * Returns AdapterInfo count in list */ - int getAdapterCount() const noexcept { return adapterInfos.size(); } + int getAdapterCount() const noexcept { return adapters.size(); } /** - * Returns the AdapterInfo dev_id with the given address or -1 if not found. + * Returns a list of currently added DBTAdapter. */ - int findAdapterInfoDevId(const EUI48 &mac) const noexcept; + jau::darray<std::shared_ptr<DBTAdapter>> getAdapters() { return *adapters.snapshot(); } /** - * Returns the AdapterInfo with the given address or nullptr if not found. + * Returns the DBTAdapter with the given address or nullptr if not found. */ - std::shared_ptr<AdapterInfo> findAdapterInfo(const EUI48 &mac) const noexcept; + std::shared_ptr<DBTAdapter> getAdapter(const EUI48 &mac) const noexcept; /** - * Returns the AdapterInfo with the given dev_id, or nullptr if not found. + * Returns the DBTAdapter with the given dev_id, or nullptr if not found. */ - std::shared_ptr<AdapterInfo> getAdapterInfo(const uint16_t dev_id) const noexcept; - - /** - * Returns the current BTMode of given adapter dev_idx or BTMode::NONE if dev_id adapter is not available. - */ - BTMode getCurrentBTMode(uint16_t dev_id) const noexcept; + std::shared_ptr<DBTAdapter> getAdapter(const uint16_t dev_id) const noexcept; /** * Returns the default AdapterInfo. @@ -369,16 +378,7 @@ namespace direct_bt { * or function returns nullptr if none is AdapterSetting::POWERED. * </p> */ - std::shared_ptr<AdapterInfo> getDefaultAdapterInfo() const noexcept; - - /** - * Returns the default adapter dev_id (index). - * <p> - * The default adapter is either the first AdapterSetting::POWERED adapter, - * or function returns -1 if none is AdapterSetting::POWERED. - * </p> - */ - int getDefaultAdapterDevID() const noexcept; + std::shared_ptr<DBTAdapter> getDefaultAdapter() const noexcept; bool setIOCapability(const uint16_t dev_id, const SMPIOCapability io_cap, SMPIOCapability& pre_io_cap) noexcept; SMPIOCapability getIOCapability(const uint16_t dev_id) const noexcept; diff --git a/api/direct_bt/DBTTypes.hpp b/api/direct_bt/DBTTypes.hpp index 432cad26..5a81360e 100644 --- a/api/direct_bt/DBTTypes.hpp +++ b/api/direct_bt/DBTTypes.hpp @@ -30,6 +30,7 @@ #include <atomic> #include <jau/java_uplink.hpp> +#include <jau/basic_types.hpp> #include "UUID.hpp" #include "BTAddress.hpp" @@ -185,13 +186,13 @@ namespace direct_bt { friend class DBTAdapter; // direct manager public: - const int dev_id; + const uint16_t dev_id; const EUI48 address; const uint8_t version; const uint16_t manufacturer; - const AdapterSetting supported_setting; private: + AdapterSetting supported_setting; std::atomic<AdapterSetting> current_setting; uint32_t dev_class; std::string name; @@ -212,16 +213,48 @@ namespace direct_bt { void setShortName(const std::string v) noexcept { short_name = v; } public: - AdapterInfo(const int dev_id_, const EUI48 & address_, + AdapterInfo(const uint16_t dev_id_, const EUI48 & address_, const uint8_t version_, const uint16_t manufacturer_, const AdapterSetting supported_setting_, const AdapterSetting current_setting_, const uint32_t dev_class_, const std::string & name_, const std::string & short_name_) noexcept : dev_id(dev_id_), address(address_), version(version_), - manufacturer(manufacturer_), supported_setting(supported_setting_), + manufacturer(manufacturer_), + supported_setting(supported_setting_), current_setting(current_setting_), dev_class(dev_class_), name(name_), short_name(short_name_) { } + AdapterInfo(const AdapterInfo &o) noexcept + : dev_id(o.dev_id), address(o.address), version(o.version), + manufacturer(o.manufacturer), + supported_setting(o.supported_setting), + current_setting(o.current_setting.load()), dev_class(o.dev_class), + name(o.name), short_name(o.short_name) + { } + AdapterInfo& operator=(const AdapterInfo &o) { + if( this != &o ) { + if( dev_id != o.dev_id || address != o.address ) { + throw jau::IllegalArgumentException("Can't assign different device id's or address "+o.toString()+" -> "+toString(), E_FILE_LINE); + } + supported_setting = o.supported_setting; + current_setting = o.current_setting.load(); + dev_class = o.dev_class; + name = o.name; + short_name = o.short_name; + } + return *this; + } + AdapterInfo(AdapterInfo&& o) noexcept + : dev_id(std::move(o.dev_id)), address(std::move(o.address)), version(std::move(o.version)), + manufacturer(std::move(o.manufacturer)), + supported_setting(std::move(o.supported_setting)), + current_setting(o.current_setting.load()), dev_class(std::move(o.dev_class)), + name(std::move(o.name)), short_name(std::move(o.short_name)) + { } + AdapterInfo& operator=(AdapterInfo &&o) noexcept = delete; + + constexpr const AdapterSetting& get_supportedSetting() const noexcept { return supported_setting; } + bool isSettingMaskSupported(const AdapterSetting setting) const noexcept { return setting == ( setting & supported_setting ); } diff --git a/api/direct_bt/DirectBT.hpp b/api/direct_bt/DirectBT.hpp index df470676..3c6f2367 100644 --- a/api/direct_bt/DirectBT.hpp +++ b/api/direct_bt/DirectBT.hpp @@ -34,15 +34,18 @@ #include <string> #include <memory> #include <cstdint> -#include <vector> #include <mutex> #include <atomic> +#include <jau/darray.hpp> + #include "DBTTypes.hpp" #include "DBTDevice.hpp" #include "DBTAdapter.hpp" +#include "DBTManager.hpp" + #endif /* DIRECTBT_HPP_ */ diff --git a/api/direct_bt/MgmtTypes.hpp b/api/direct_bt/MgmtTypes.hpp index d304ad4c..f8d96dd1 100644 --- a/api/direct_bt/MgmtTypes.hpp +++ b/api/direct_bt/MgmtTypes.hpp @@ -2228,7 +2228,7 @@ namespace direct_bt { std::string getName() const noexcept { return pdu.get_string_nc(getDataOffset()+20); } std::string getShortName() const noexcept { return pdu.get_string_nc(getDataOffset()+20+MgmtConstU16::MGMT_MAX_NAME_LENGTH); } - std::shared_ptr<AdapterInfo> toAdapterInfo() const noexcept; + std::unique_ptr<AdapterInfo> toAdapterInfo() const noexcept; }; |