summaryrefslogtreecommitdiffstats
path: root/api
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2020-12-14 03:11:00 +0100
committerSven Gothel <[email protected]>2020-12-14 03:11:00 +0100
commitd7f17e9cbd1211d5470e8f42aa35d58a7760f771 (patch)
tree5943b90f7d3137b6e2a724b4c2fccacbc0056dd5 /api
parentd22915932120e4486ad09691ae5fb6c635b8c925 (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.hpp18
-rw-r--r--api/direct_bt/DBTDevice.hpp2
-rw-r--r--api/direct_bt/HCIHandler.hpp23
-rw-r--r--api/direct_bt/HCITypes.hpp31
-rw-r--r--api/direct_bt/MgmtTypes.hpp9
-rw-r--r--api/direct_bt/SMPHandler.hpp6
-rw-r--r--api/direct_bt/SMPTypes.hpp35
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 {}
};