diff options
author | Sven Gothel <[email protected]> | 2020-12-14 03:11:00 +0100 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2020-12-14 03:11:00 +0100 |
commit | d7f17e9cbd1211d5470e8f42aa35d58a7760f771 (patch) | |
tree | 5943b90f7d3137b6e2a724b4c2fccacbc0056dd5 /api | |
parent | d22915932120e4486ad09691ae5fb6c635b8c925 (diff) |
smart_ptr-3: Handle HCIEvent + SMPPDUMsg instances via std::unique_ptr instead of shared_ptr; Callbacks use 'const <T> &' now.
smart_ptr change series, commit #2
This series started with commit cafd8d1f3689135eae36854a9cca4def690045fd,
see for details.
Refined MgmtMsg clone template and added same to HCIPacket and SMPPDUMsg.
Notable: To have this clone template to work, the default copy-constructor
should not be deleted. Hence removing the const qualifier from timestamp
and manual default/deleted directives.
+++
At this point, all high frequent objects (ATT, HCI w/ SMP, Mgmt events)
use std::unique_ptr and therefor reduce a certain overhead.
Further, this constraint also removes a potential 'build in' leaks,
in case a callback method keeps the shared_ptr instance.
Now, callbacks only received the const reference and if so desired,
need to create a copy themselves.
Diffstat (limited to 'api')
-rw-r--r-- | api/direct_bt/DBTAdapter.hpp | 18 | ||||
-rw-r--r-- | api/direct_bt/DBTDevice.hpp | 2 | ||||
-rw-r--r-- | api/direct_bt/HCIHandler.hpp | 23 | ||||
-rw-r--r-- | api/direct_bt/HCITypes.hpp | 31 | ||||
-rw-r--r-- | api/direct_bt/MgmtTypes.hpp | 9 | ||||
-rw-r--r-- | api/direct_bt/SMPHandler.hpp | 6 | ||||
-rw-r--r-- | api/direct_bt/SMPTypes.hpp | 35 |
7 files changed, 69 insertions, 55 deletions
diff --git a/api/direct_bt/DBTAdapter.hpp b/api/direct_bt/DBTAdapter.hpp index c9cd3c8d..32d381e4 100644 --- a/api/direct_bt/DBTAdapter.hpp +++ b/api/direct_bt/DBTAdapter.hpp @@ -252,8 +252,8 @@ namespace direct_bt { uint16_t latency, uint16_t supervision_timeout); friend HCIStatusCode DBTDevice::connectBREDR(const uint16_t pkt_type, const uint16_t clock_offset, const uint8_t role_switch); friend void DBTDevice::processL2CAPSetup(std::shared_ptr<DBTDevice> sthis); - friend void DBTDevice::hciSMPMsgCallback(std::shared_ptr<DBTDevice> sthis, std::shared_ptr<const SMPPDUMsg> msg, const HCIACLData::l2cap_frame& source) noexcept; friend bool DBTDevice::updatePairingState(std::shared_ptr<DBTDevice> sthis, const MgmtEvent& evt, const HCIStatusCode evtStatus, SMPPairingState claimed_state) noexcept; + friend void DBTDevice::hciSMPMsgCallback(std::shared_ptr<DBTDevice> sthis, const SMPPDUMsg& msg, const HCIACLData::l2cap_frame& source) noexcept; friend void DBTDevice::processDeviceReady(std::shared_ptr<DBTDevice> sthis, const uint64_t timestamp); friend std::vector<std::shared_ptr<GATTService>> DBTDevice::getGATTServices() noexcept; @@ -284,13 +284,13 @@ namespace direct_bt { bool mgmtEvPairDeviceCompleteMgmt(const MgmtEvent& e) noexcept; bool mgmtEvNewLongTermKeyMgmt(const MgmtEvent& e) noexcept; - bool mgmtEvDeviceDiscoveringHCI(std::shared_ptr<MgmtEvent> e) noexcept; - bool mgmtEvDeviceConnectedHCI(std::shared_ptr<MgmtEvent> e) noexcept; - bool mgmtEvConnectFailedHCI(std::shared_ptr<MgmtEvent> e) noexcept; - bool mgmtEvHCIEncryptionChangedHCI(std::shared_ptr<MgmtEvent> e) noexcept; - bool mgmtEvHCIEncryptionKeyRefreshCompleteHCI(std::shared_ptr<MgmtEvent> e) noexcept; - bool mgmtEvHCILERemoteUserFeaturesHCI(std::shared_ptr<MgmtEvent> e) noexcept; - bool mgmtEvDeviceDisconnectedHCI(std::shared_ptr<MgmtEvent> e) noexcept; + bool mgmtEvDeviceDiscoveringHCI(const MgmtEvent& e) noexcept; + bool mgmtEvDeviceConnectedHCI(const MgmtEvent& e) noexcept; + bool mgmtEvConnectFailedHCI(const MgmtEvent& e) noexcept; + bool mgmtEvHCIEncryptionChangedHCI(const MgmtEvent& e) noexcept; + bool mgmtEvHCIEncryptionKeyRefreshCompleteHCI(const MgmtEvent& e) noexcept; + bool mgmtEvHCILERemoteUserFeaturesHCI(const MgmtEvent& e) noexcept; + bool mgmtEvDeviceDisconnectedHCI(const MgmtEvent& e) noexcept; bool mgmtEvDeviceDiscoveringAny(const MgmtEvent& e, const bool hciSourced) noexcept; @@ -302,7 +302,7 @@ namespace direct_bt { bool mgmtEvDeviceUnpairedMgmt(const MgmtEvent& e) noexcept; bool hciSMPMsgCallback(const BDAddressAndType & addressAndType, - std::shared_ptr<const SMPPDUMsg> msg, const HCIACLData::l2cap_frame& source) noexcept; + const SMPPDUMsg& msg, const HCIACLData::l2cap_frame& source) noexcept; void sendDevicePairingState(std::shared_ptr<DBTDevice> device, const SMPPairingState state, const PairingMode mode, uint64_t timestamp) noexcept; void sendDeviceReady(std::shared_ptr<DBTDevice> device, uint64_t timestamp) noexcept; diff --git a/api/direct_bt/DBTDevice.hpp b/api/direct_bt/DBTDevice.hpp index b338e811..f40411c7 100644 --- a/api/direct_bt/DBTDevice.hpp +++ b/api/direct_bt/DBTDevice.hpp @@ -169,7 +169,7 @@ namespace direct_bt { * Will be initiated by processL2CAPSetup()'s security_level setup after connectLE(..), i.e. notifyConnected() and notifyLEFeatures(). * </p> */ - void hciSMPMsgCallback(std::shared_ptr<DBTDevice> sthis, std::shared_ptr<const SMPPDUMsg> msg, const HCIACLData::l2cap_frame& source) noexcept; + void hciSMPMsgCallback(std::shared_ptr<DBTDevice> sthis, const SMPPDUMsg& msg, const HCIACLData::l2cap_frame& source) noexcept; /** * Setup GATT via connectGATT() off-thread. diff --git a/api/direct_bt/HCIHandler.hpp b/api/direct_bt/HCIHandler.hpp index e07b6350..a33840bd 100644 --- a/api/direct_bt/HCIHandler.hpp +++ b/api/direct_bt/HCIHandler.hpp @@ -148,7 +148,7 @@ namespace direct_bt { }; typedef jau::FunctionDef<bool, const BDAddressAndType& /* addressAndType */, - std::shared_ptr<const SMPPDUMsg>, const HCIACLData::l2cap_frame& /* source */> HCISMPMsgCallback; + const SMPPDUMsg&, const HCIACLData::l2cap_frame& /* source */> HCISMPMsgCallback; typedef jau::cow_vector<HCISMPMsgCallback> HCISMPMsgCallbackList; /** @@ -236,7 +236,7 @@ namespace direct_bt { constexpr static void filter_all_opcbit(uint64_t &mask) noexcept { mask=0xffffffffffffffffUL; } inline static void filter_set_opcbit(HCIOpcodeBit opcbit, uint64_t &mask) noexcept { jau::set_bit_uint64(number(opcbit), mask); } - jau::ringbuffer<std::shared_ptr<HCIEvent>, nullptr, jau::nsize_t> hciEventRing; + jau::ringbuffer<std::unique_ptr<HCIEvent>, nullptr, jau::nsize_t> hciEventRing; jau::sc_atomic_bool hciReaderShallStop; std::mutex mtx_hciReaderLifecycle; @@ -307,28 +307,29 @@ namespace direct_bt { HCISMPMsgCallbackList hciSMPMsgCallbackList; - std::shared_ptr<MgmtEvent> translate(std::shared_ptr<HCIEvent> ev) noexcept; + std::unique_ptr<MgmtEvent> translate(HCIEvent& ev) noexcept; + std::unique_ptr<const SMPPDUMsg> getSMPPDUMsg(const HCIACLData::l2cap_frame & l2cap, const uint8_t * l2cap_data) const noexcept; void hciReaderThreadImpl() noexcept; bool sendCommand(HCICommand &req) noexcept; - std::shared_ptr<HCIEvent> getNextReply(HCICommand &req, int32_t & retryCount, const int32_t replyTimeoutMS) noexcept; - std::shared_ptr<HCIEvent> getNextCmdCompleteReply(HCICommand &req, HCICommandCompleteEvent **res) noexcept; + std::unique_ptr<HCIEvent> getNextReply(HCICommand &req, int32_t & retryCount, const int32_t replyTimeoutMS) noexcept; + std::unique_ptr<HCIEvent> getNextCmdCompleteReply(HCICommand &req, HCICommandCompleteEvent **res) noexcept; - std::shared_ptr<HCIEvent> processCommandStatus(HCICommand &req, HCIStatusCode *status) noexcept; + std::unique_ptr<HCIEvent> processCommandStatus(HCICommand &req, HCIStatusCode *status) noexcept; template<typename hci_cmd_event_struct> - std::shared_ptr<HCIEvent> processCommandComplete(HCICommand &req, + std::unique_ptr<HCIEvent> processCommandComplete(HCICommand &req, const hci_cmd_event_struct **res, HCIStatusCode *status) noexcept; template<typename hci_cmd_event_struct> - std::shared_ptr<HCIEvent> receiveCommandComplete(HCICommand &req, + std::unique_ptr<HCIEvent> receiveCommandComplete(HCICommand &req, const hci_cmd_event_struct **res, HCIStatusCode *status) noexcept; template<typename hci_cmd_event_struct> - const hci_cmd_event_struct* getReplyStruct(std::shared_ptr<HCIEvent> event, HCIEventType evc, HCIStatusCode *status) noexcept; + const hci_cmd_event_struct* getReplyStruct(HCIEvent& event, HCIEventType evc, HCIStatusCode *status) noexcept; template<typename hci_cmd_event_struct> - const hci_cmd_event_struct* getMetaReplyStruct(std::shared_ptr<HCIEvent> event, HCIMetaEventType mec, HCIStatusCode *status) noexcept; + const hci_cmd_event_struct* getMetaReplyStruct(HCIEvent& event, HCIMetaEventType mec, HCIStatusCode *status) noexcept; public: HCIHandler(const uint16_t dev_id, const BTMode btMode=BTMode::NONE) noexcept; @@ -563,7 +564,7 @@ namespace direct_bt { void clearAllCallbacks() noexcept; /** Manually send a MgmtEvent to all of its listeners. */ - void sendMgmtEvent(std::shared_ptr<MgmtEvent> event) noexcept; + void sendMgmtEvent(const MgmtEvent& event) noexcept; /** * FIXME / TODO: Privacy Mode / Pairing / Bonding diff --git a/api/direct_bt/HCITypes.hpp b/api/direct_bt/HCITypes.hpp index 0f7070dd..813b2fa0 100644 --- a/api/direct_bt/HCITypes.hpp +++ b/api/direct_bt/HCITypes.hpp @@ -492,6 +492,15 @@ namespace direct_bt { virtual ~HCIPacket() noexcept {} + /** + * Clone template for convenience, based on derived class's copy-constructor. + * @tparam T The derived definite class type, deducible by source argument + * @param source the source to be copied + * @return a new instance. + */ + template<class T> + static T* clone(const T& source) noexcept { return new T(source); } + inline jau::nsize_t getTotalSize() const noexcept { return pdu.getSize(); } /** Return the underlying octets read only */ @@ -609,6 +618,8 @@ namespace direct_bt { hcistruct * getWStruct() noexcept { return (hcistruct *)( pdu.get_wptr_nc( number(HCIConstSizeT::COMMAND_HDR_SIZE) ) ); } }; + class HCIHandler; // fwd + /** * BT Core Spec v5.2: Vol 4, Part E HCI: 5.4.2 HCI ACL Data packets * <p> @@ -661,22 +672,13 @@ namespace direct_bt { const uint16_t cid; const uint16_t psm; const uint16_t len; - const uint8_t * data; bool isSMP() const noexcept { return L2CAP_CID_SMP == cid || L2CAP_CID_SMP_BREDR == cid; } - std::shared_ptr<const SMPPDUMsg> getSMPPDUMsg() const noexcept { - if( 0 < len && isSMP() ) { - return SMPPDUMsg::getSpecialized(data, len); - } - return nullptr; - } - std::string toString() const noexcept { return "l2cap[handle "+jau::uint16HexString(handle)+", flags[pb "+getPBFlagString(pb_flag)+", bc "+jau::uint8HexString(bc_flag)+ "], cid "+jau::uint8HexString(cid)+ - ", psm "+jau::uint8HexString(psm)+", len "+std::to_string(len)+ - ", data "+ jau::bytesHexString(data, 0, len, true /* lsbFirst */, true /* leading0X */) +"]"; + ", psm "+jau::uint8HexString(psm)+", len "+std::to_string(len)+ "]"; } }; @@ -686,7 +688,7 @@ namespace direct_bt { * Returned memory reference is managed by caller (delete etc) * </p> */ - static std::shared_ptr<HCIACLData> getSpecialized(const uint8_t * buffer, jau::nsize_t const buffer_size) noexcept; + static std::unique_ptr<HCIACLData> getSpecialized(const uint8_t * buffer, jau::nsize_t const buffer_size) noexcept; /** * Returns the handle. @@ -715,10 +717,11 @@ namespace direct_bt { jau::nsize_t getParamSize() const noexcept { return pdu.get_uint16_nc(3); } const uint8_t* getParam() const noexcept { return pdu.get_ptr_nc(number(HCIConstSizeT::ACL_HDR_SIZE)); } - l2cap_frame getL2CAPFrame() const noexcept; + l2cap_frame getL2CAPFrame(const uint8_t* & l2cap_data) const noexcept; std::string toString() const noexcept { - return "ACLData[size "+std::to_string(getParamSize())+", data "+getL2CAPFrame().toString()+", tsz "+std::to_string(getTotalSize())+"]"; + const uint8_t* l2cap_data; + return "ACLData[size "+std::to_string(getParamSize())+", data "+getL2CAPFrame(l2cap_data).toString()+", tsz "+std::to_string(getTotalSize())+"]"; } }; @@ -773,7 +776,7 @@ namespace direct_bt { * Returned memory reference is managed by caller (delete etc) * </p> */ - static std::shared_ptr<HCIEvent> getSpecialized(const uint8_t * buffer, jau::nsize_t const buffer_size) noexcept; + static std::unique_ptr<HCIEvent> getSpecialized(const uint8_t * buffer, jau::nsize_t const buffer_size) noexcept; /** Persistent memory, w/ ownership ..*/ HCIEvent(const uint8_t* buffer, const jau::nsize_t buffer_len, const jau::nsize_t exp_param_size) diff --git a/api/direct_bt/MgmtTypes.hpp b/api/direct_bt/MgmtTypes.hpp index ab0c83b0..027a3dbd 100644 --- a/api/direct_bt/MgmtTypes.hpp +++ b/api/direct_bt/MgmtTypes.hpp @@ -336,21 +336,22 @@ namespace direct_bt { virtual ~MgmtMsg() {} /** - * User utility clone template for convenience, based on derived class's copy-constructor.<br> + * Clone template for convenience, based on derived class's copy-constructor.<br> * MgmtEvent callback example: * <pre> * bool mgmtEvDeviceUnpairedMgmt(const MgmtEvent& e) noexcept { * const MgmtEvtDeviceUnpaired &event = *static_cast<const MgmtEvtDeviceUnpaired *>(&e); - * MgmtMsg * b2 = MgmtMsg::clone(event); + * MgmtMsg * b1 = MgmtMsg::clone(event); + * MgmtEvtDeviceUnpaired * b2 = MgmtMsg::clone(event); * .. do something .. * } * </pre> - * @tparam T The derived definite class type, deduced by source + * @tparam T The derived definite class type, deducible by source argument * @param source the source to be copied * @return a new instance. */ template<class T> - static MgmtMsg* clone(const T& source) noexcept { return new T(source); } + static T* clone(const T& source) noexcept { return new T(source); } uint64_t getTimestamp() const noexcept { return ts_creation; } diff --git a/api/direct_bt/SMPHandler.hpp b/api/direct_bt/SMPHandler.hpp index c1f62865..15485c36 100644 --- a/api/direct_bt/SMPHandler.hpp +++ b/api/direct_bt/SMPHandler.hpp @@ -130,7 +130,7 @@ namespace direct_bt { }; - typedef jau::FunctionDef<bool, std::shared_ptr<const SMPPDUMsg>> SMPSecurityReqCallback; + typedef jau::FunctionDef<bool, const SMPPDUMsg&> SMPSecurityReqCallback; typedef jau::cow_vector<SMPSecurityReqCallback> SMPSecurityReqCallbackList; /** @@ -178,7 +178,7 @@ namespace direct_bt { jau::sc_atomic_bool is_connected; // reflects state jau::relaxed_atomic_bool has_ioerror; // reflects state - jau::ringbuffer<std::shared_ptr<const SMPPDUMsg>, nullptr, jau::nsize_t> smpPDURing; + jau::ringbuffer<std::unique_ptr<const SMPPDUMsg>, nullptr, jau::nsize_t> smpPDURing; jau::sc_atomic_bool l2capReaderShallStop; std::mutex mtx_l2capReaderLifecycle; @@ -195,7 +195,7 @@ namespace direct_bt { void l2capReaderThreadImpl(); void send(const SMPPDUMsg & msg); - std::shared_ptr<const SMPPDUMsg> sendWithReply(const SMPPDUMsg & msg, const int timeout); + std::unique_ptr<const SMPPDUMsg> sendWithReply(const SMPPDUMsg & msg, const int timeout); void clearAllCallbacks() noexcept; diff --git a/api/direct_bt/SMPTypes.hpp b/api/direct_bt/SMPTypes.hpp index 2b30ffc4..3da5fc74 100644 --- a/api/direct_bt/SMPTypes.hpp +++ b/api/direct_bt/SMPTypes.hpp @@ -624,6 +624,8 @@ namespace direct_bt { static std::string getOpcodeString(const Opcode opc) noexcept; protected: + friend class SMPHandler; + void checkOpcode(const Opcode expected) const { const Opcode has = getOpcode(); @@ -651,20 +653,20 @@ namespace direct_bt { +jau::bytesHexString(pdu.get_ptr(), getDataOffset(), getDataSize(), true /* lsbFirst */, true /* leading0X */); } - public: /** actual received PDU */ POctets pdu; /** creation timestamp in milliseconds */ - const uint64_t ts_creation; + uint64_t ts_creation; + public: /** * Return a newly created specialized instance pointer to base class. * <p> * Returned memory reference is managed by caller (delete etc) * </p> */ - static std::shared_ptr<const SMPPDUMsg> getSpecialized(const uint8_t * buffer, jau::nsize_t const buffer_size) noexcept; + static std::unique_ptr<const SMPPDUMsg> getSpecialized(const uint8_t * buffer, jau::nsize_t const buffer_size) noexcept; /** Persistent memory, w/ ownership ..*/ SMPPDUMsg(const uint8_t* source, const jau::nsize_t size) @@ -681,13 +683,25 @@ namespace direct_bt { pdu.check_range(0, getDataOffset()+getDataSize()); } - SMPPDUMsg(const SMPPDUMsg &o) noexcept = default; - SMPPDUMsg(SMPPDUMsg &&o) noexcept = default; - SMPPDUMsg& operator=(const SMPPDUMsg &o) noexcept = delete; // const ts_creation - SMPPDUMsg& operator=(SMPPDUMsg &&o) noexcept = delete; // const ts_creation - virtual ~SMPPDUMsg() noexcept {} + /** + * Clone template for convenience, based on derived class's copy-constructor. + * <pre> + * const SMPPDUMsg & smpPDU; + * const SMPSignInfoMsg * signInfo = static_cast<const SMPSignInfoMsg *>(&smpPDU); + * SMPPDUMsg* b1 = SMPPDUMsg::clone(*signInfo); + * SMPSignInfoMsg* b2 = SMPPDUMsg::clone(*signInfo); + * </pre> + * @tparam T The derived definite class type, deducible by source argument + * @param source the source to be copied + * @return a new instance. + */ + template<class T> + static T* clone(const T& source) noexcept { return new T(source); } + + uint64_t getTimestamp() const noexcept { return ts_creation; } + /** SMP Command Codes Vol 3, Part H (SM): 3.3 */ inline Opcode getOpcode() const noexcept { return static_cast<Opcode>(pdu.get_uint8_nc(0)); @@ -757,11 +771,6 @@ namespace direct_bt { SMPEncKeyByteStream(const Opcode opc, const jau::nsize_t size) : SMPPDUMsg(opc, size) { } - SMPEncKeyByteStream(const SMPEncKeyByteStream &o) noexcept = default; - SMPEncKeyByteStream(SMPEncKeyByteStream &&o) noexcept = default; - SMPEncKeyByteStream& operator=(const SMPEncKeyByteStream &o) noexcept = delete; // const ts_creation - SMPEncKeyByteStream& operator=(SMPEncKeyByteStream &&o) noexcept = delete; // const ts_creation - virtual ~SMPEncKeyByteStream() noexcept {} }; |