summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2021-07-27 14:01:02 +0200
committerSven Gothel <[email protected]>2021-07-27 14:01:02 +0200
commit927678e3b739cc2b6efdc1ea43513333838df2ae (patch)
tree01df9a4e400b9a8880e793c6d2def0606ec7eea0
parent6fe79f792dcfe31227c40de3cc0cd63ecfe2a92b (diff)
Clarify EInfoReport ownership between MgmtEvtDeviceFound, HCIHandler and BTAdapter; Add AD_EIR debug flag
MgmtEvtDeviceFound changes: Stringent ownership - field eireport type `std::shared_ptr<EInfoReport>` -> `std::unique_ptr<EInfoReport>` - getEIR() returns immutable EInfoReport pointer BTAdapter::mgmtEvDeviceFoundHCI(): Cleanup confusion - Expect coming from HCIHandler (we only listen to it), ABORT otherwise - Cleanup confusion of ownership etc Debug: - HCIHandler env.DEBUG_SCAN_AD_EIR `direct_bt.debug.hci.scan_ad_eir`
-rw-r--r--api/direct_bt/BTTypes0.hpp2
-rw-r--r--api/direct_bt/HCIHandler.hpp8
-rw-r--r--api/direct_bt/MgmtTypes.hpp22
-rw-r--r--examples/direct_bt_scanner10/dbt_scanner10.cpp2
-rwxr-xr-xscripts/run-dbt_scanner10.sh23
-rw-r--r--src/direct_bt/BTAdapter.cpp13
-rw-r--r--src/direct_bt/BTTypes0.cpp6
-rw-r--r--src/direct_bt/HCIHandler.cpp11
8 files changed, 50 insertions, 37 deletions
diff --git a/api/direct_bt/BTTypes0.hpp b/api/direct_bt/BTTypes0.hpp
index a9b5c3f5..fe56c986 100644
--- a/api/direct_bt/BTTypes0.hpp
+++ b/api/direct_bt/BTTypes0.hpp
@@ -699,7 +699,7 @@ namespace direct_bt {
* https://www.bluetooth.com/specifications/archived-specifications/
* </p>
*/
- static jau::darray<std::shared_ptr<EInfoReport>> read_ad_reports(uint8_t const * data, jau::nsize_t const data_length) noexcept;
+ static jau::darray<std::unique_ptr<EInfoReport>> read_ad_reports(uint8_t const * data, jau::nsize_t const data_length) noexcept;
/**
* Reads the Extended Inquiry Response (EIR) or Advertising Data (AD) segments
diff --git a/api/direct_bt/HCIHandler.hpp b/api/direct_bt/HCIHandler.hpp
index a4dcd8dc..b1467c82 100644
--- a/api/direct_bt/HCIHandler.hpp
+++ b/api/direct_bt/HCIHandler.hpp
@@ -126,6 +126,14 @@ namespace direct_bt {
*/
const bool DEBUG_EVENT;
+ /**
+ * Debug all scanned HCI 'Advertising Data' (AD) 'Extended Inquiry Response' (EIR) packages.
+ * <p>
+ * Environment variable is 'direct_bt.debug.hci.scan_ad_eir'.
+ * </p>
+ */
+ const bool DEBUG_SCAN_AD_EIR;
+
private:
/** Maximum number of packets to wait for until matching a sequential command. Won't block as timeout will limit. */
const int32_t HCI_READ_PACKET_MAX_RETRY;
diff --git a/api/direct_bt/MgmtTypes.hpp b/api/direct_bt/MgmtTypes.hpp
index c1d53c95..90382539 100644
--- a/api/direct_bt/MgmtTypes.hpp
+++ b/api/direct_bt/MgmtTypes.hpp
@@ -1769,7 +1769,7 @@ namespace direct_bt {
class MgmtEvtDeviceFound : public MgmtEvent
{
private:
- std::shared_ptr<EInfoReport> eireport;
+ std::unique_ptr<EInfoReport> eireport;
protected:
std::string baseString() const noexcept override {
@@ -1785,24 +1785,22 @@ namespace direct_bt {
public:
MgmtEvtDeviceFound(const uint8_t* buffer, const jau::nsize_t buffer_len)
- : MgmtEvent(buffer, buffer_len, 14)
+ : MgmtEvent(buffer, buffer_len, 14), eireport(nullptr)
{
checkOpcode(getOpcode(), Opcode::DEVICE_FOUND);
- eireport = nullptr;
}
- MgmtEvtDeviceFound(const uint16_t dev_id, std::shared_ptr<EInfoReport> eir)
- : MgmtEvent(Opcode::DEVICE_FOUND, dev_id, 6+1+1+4+2+0)
+ MgmtEvtDeviceFound(const uint16_t dev_id, std::unique_ptr<EInfoReport> && eir)
+ : MgmtEvent(Opcode::DEVICE_FOUND, dev_id, 6+1+1+4+2+0), eireport(std::move(eir))
{
- pdu.put_eui48_nc(MGMT_HEADER_SIZE, eir->getAddress());
- pdu.put_uint8_nc(MGMT_HEADER_SIZE+6, direct_bt::number(eir->getAddressType()));
- pdu.put_int8_nc(MGMT_HEADER_SIZE+6+1, eir->getRSSI());
- pdu.put_uint32_nc(MGMT_HEADER_SIZE+6+1+1, eir->getFlags()); // EIR flags only 8bit, Mgmt uses 32bit?
+ pdu.put_eui48_nc(MGMT_HEADER_SIZE, eireport->getAddress());
+ pdu.put_uint8_nc(MGMT_HEADER_SIZE+6, direct_bt::number(eireport->getAddressType()));
+ pdu.put_int8_nc(MGMT_HEADER_SIZE+6+1, eireport->getRSSI());
+ pdu.put_uint32_nc(MGMT_HEADER_SIZE+6+1+1, eireport->getFlags()); // EIR flags only 8bit, Mgmt uses 32bit?
pdu.put_uint16_nc(MGMT_HEADER_SIZE+6+1+1+4, 0); // eir_len
- eireport = eir;
}
- /** Returns the EInfoReport, assuming creation occurred via HCIHandler. Otherwise nullptr. */
- std::shared_ptr<EInfoReport> getEIR() const noexcept { return eireport; }
+ /** Returns reference to the immutable EInfoReport, assuming creation occurred via HCIHandler. Otherwise nullptr. */
+ const EInfoReport* getEIR() const noexcept { return eireport.get(); }
const EUI48& getAddress() const noexcept { return *reinterpret_cast<const EUI48 *>( pdu.get_ptr_nc(MGMT_HEADER_SIZE + 0) ); } // mgmt_addr_info
BDAddressType getAddressType() const noexcept { return static_cast<BDAddressType>(pdu.get_uint8_nc(MGMT_HEADER_SIZE+6)); } // mgmt_addr_info
diff --git a/examples/direct_bt_scanner10/dbt_scanner10.cpp b/examples/direct_bt_scanner10/dbt_scanner10.cpp
index a7b6e6bc..bef05fae 100644
--- a/examples/direct_bt_scanner10/dbt_scanner10.cpp
+++ b/examples/direct_bt_scanner10/dbt_scanner10.cpp
@@ -914,7 +914,7 @@ int main(int argc, char *argv[])
"[-unpairPre] [-unpairPost] "
"[-charid <uuid>] [-charval <byte-val>] "
"[-dbt_verbose true|false] "
- "[-dbt_debug true|false|adapter.event,gatt.data,hci.event,mgmt.event] "
+ "[-dbt_debug true|false|adapter.event,gatt.data,hci.event,hci.scan_ad_eir,mgmt.event] "
"[-dbt_mgmt cmd.timeout=3000,ringsize=64,...] "
"[-dbt_hci cmd.complete.timeout=10000,cmd.status.timeout=3000,ringsize=64,...] "
"[-dbt_gatt cmd.read.timeout=500,cmd.write.timeout=500,cmd.init.timeout=2500,ringsize=128,...] "
diff --git a/scripts/run-dbt_scanner10.sh b/scripts/run-dbt_scanner10.sh
index 5da9d76b..e88e46f1 100755
--- a/scripts/run-dbt_scanner10.sh
+++ b/scripts/run-dbt_scanner10.sh
@@ -1,15 +1,28 @@
#!/bin/sh
# export direct_bt_debug=true
-# export direct_bt_debug=adapter.event=false,gatt.data=false,hci.event=true,mgmt.event=false
-# export direct_bt_debug=adapter.event,gatt.data,hci.event,mgmt.event
+# export direct_bt_debug=adapter.event=false,gatt.data=false,hci.event=true,hci.scan_ad_eir=true,mgmt.event=false
+# export direct_bt_debug=adapter.event,gatt.data,hci.event,hci.scan_ad_eir,mgmt.event
# export direct_bt_debug=adapter.event,gatt.data
# export direct_bt_debug=adapter.event,hci.event
# export direct_bt_debug=adapter.event
#
-# ../scripts/run-dbt_scanner10.sh -wait -mac C0:26:DA:01:DA:B1 2>&1 | tee ~/scanner-h01-dbt10.log
-# ../scripts/run-dbt_scanner10.sh -wait -wl C0:26:DA:01:DA:B1 2>&1 | tee ~/scanner-h01-dbt10.log
-# ../scripts/run-dbt_scanner10.sh -wait 2>&1 | tee ~/scanner-h01-dbt10.log
+# Default logfile in ~/run-dbt_scanner10.log
+#
+# Scan and read all devices (using default auto-sec w/ keyboard iocap)
+# ../scripts/run-dbt_scanner10.sh
+#
+# Read device C0:26:DA:01:DA:B1 (using default auto-sec w/ keyboard iocap)
+# ../scripts/run-dbt_scanner10.sh -mac C0:26:DA:01:DA:B1
+#
+# Read device C0:26:DA:01:DA:B1 (enforcing no security)
+# ../scripts/run-dbt_scanner10.sh -mac C0:26:DA:01:DA:B1 -seclevel C0:26:DA:01:DA:B1 1 1
+#
+# Read device C0:26:DA:01:DA:B1, basic debug flags enabled (using default auto-sec w/ keyboard iocap)
+# ../scripts/run-dbt_scanner10.sh -mac C0:26:DA:01:DA:B1 -dbt_debug true
+#
+# Read device C0:26:DA:01:DA:B1, all debug flags enabled (using default auto-sec w/ keyboard iocap)
+# ../scripts/run-dbt_scanner10.sh -mac C0:26:DA:01:DA:B1 -dbt_debug adapter.event,gatt.data,hci.event,hci.scan_ad_eir,mgmt.event
#
# To do a BT adapter removal/add via software, assuming the device is '1-4' (Bus 1.Port 4):
# echo '1-4' > /sys/bus/usb/drivers/usb/unbind
diff --git a/src/direct_bt/BTAdapter.cpp b/src/direct_bt/BTAdapter.cpp
index 82c6c7c1..0c5475d0 100644
--- a/src/direct_bt/BTAdapter.cpp
+++ b/src/direct_bt/BTAdapter.cpp
@@ -1391,17 +1391,10 @@ bool BTAdapter::mgmtEvDeviceFoundHCI(const MgmtEvent& e) noexcept {
COND_PRINT(debug_event, "BTAdapter:hci:DeviceFound(dev_id %d): %s", dev_id, e.toString().c_str());
const MgmtEvtDeviceFound &deviceFoundEvent = *static_cast<const MgmtEvtDeviceFound *>(&e);
- std::shared_ptr<EInfoReport> eir = deviceFoundEvent.getEIR();
+ const EInfoReport* eir = deviceFoundEvent.getEIR();
if( nullptr == eir ) {
- // Sourced from Linux Mgmt or otherwise ...
- eir = std::make_shared<EInfoReport>();
- eir->setSource(EInfoReport::Source::EIR_MGMT);
- eir->setTimestamp(deviceFoundEvent.getTimestamp());
- eir->setEvtType(AD_PDU_Type::ADV_IND);
- eir->setAddressType(deviceFoundEvent.getAddressType());
- eir->setAddress( deviceFoundEvent.getAddress() );
- eir->setRSSI( deviceFoundEvent.getRSSI() );
- eir->read_data(deviceFoundEvent.getData(), deviceFoundEvent.getDataSize());
+ // Sourced from Linux Mgmt, which we don't support
+ ABORT("BTAdapter:hci:DeviceFound: Not sourced from LE_ADVERTISING_REPORT: %s", deviceFoundEvent.toString().c_str());
} // else: Sourced from HCIHandler via LE_ADVERTISING_REPORT (default!)
std::shared_ptr<BTDevice> dev = findDiscoveredDevice(eir->getAddress(), eir->getAddressType());
diff --git a/src/direct_bt/BTTypes0.cpp b/src/direct_bt/BTTypes0.cpp
index 424e880e..1e7a2400 100644
--- a/src/direct_bt/BTTypes0.cpp
+++ b/src/direct_bt/BTTypes0.cpp
@@ -848,9 +848,9 @@ int EInfoReport::read_data(uint8_t const * data, uint8_t const data_length) noex
return count;
}
-jau::darray<std::shared_ptr<EInfoReport>> EInfoReport::read_ad_reports(uint8_t const * data, jau::nsize_t const data_length) noexcept {
+jau::darray<std::unique_ptr<EInfoReport>> EInfoReport::read_ad_reports(uint8_t const * data, jau::nsize_t const data_length) noexcept {
jau::nsize_t const num_reports = (jau::nsize_t) data[0];
- jau::darray<std::shared_ptr<EInfoReport>> ad_reports;
+ jau::darray<std::unique_ptr<EInfoReport>> ad_reports;
if( 0 == num_reports || num_reports > 0x19 ) {
DBG_PRINT("AD-Reports: Invalid reports count: %d", num_reports);
@@ -865,7 +865,7 @@ jau::darray<std::shared_ptr<EInfoReport>> EInfoReport::read_ad_reports(uint8_t c
const uint64_t timestamp = jau::getCurrentMilliseconds();
for(i = 0; i < num_reports && i_octets < limes; i++) {
- ad_reports.push_back( std::make_shared<EInfoReport>() );
+ ad_reports.push_back( std::make_unique<EInfoReport>() );
ad_reports[i]->setSource(Source::AD);
ad_reports[i]->setTimestamp(timestamp);
ad_reports[i]->setEvtType(static_cast<AD_PDU_Type>(*i_octets++));
diff --git a/src/direct_bt/HCIHandler.cpp b/src/direct_bt/HCIHandler.cpp
index 2ac5ae9e..64e06c94 100644
--- a/src/direct_bt/HCIHandler.cpp
+++ b/src/direct_bt/HCIHandler.cpp
@@ -65,6 +65,7 @@ HCIEnv::HCIEnv() noexcept
HCI_COMMAND_POLL_PERIOD( jau::environment::getInt32Property("direct_bt.hci.cmd.poll.period", 125, 50 /* min */, INT32_MAX /* max */) ),
HCI_EVT_RING_CAPACITY( jau::environment::getInt32Property("direct_bt.hci.ringsize", 64, 64 /* min */, 1024 /* max */) ),
DEBUG_EVENT( jau::environment::getBooleanProperty("direct_bt.debug.hci.event", false) ),
+ DEBUG_SCAN_AD_EIR( jau::environment::getBooleanProperty("direct_bt.debug.hci.scan_ad_eir", false) ),
HCI_READ_PACKET_MAX_RETRY( HCI_EVT_RING_CAPACITY )
{
}
@@ -423,12 +424,12 @@ void HCIHandler::hciReaderThreadImpl() noexcept {
hciEventRing.putBlocking( std::move( event ) );
} else if( event->isMetaEvent(HCIMetaEventType::LE_ADVERTISING_REPORT) ) {
// issue callbacks for the translated AD events
- jau::darray<std::shared_ptr<EInfoReport>> eirlist = EInfoReport::read_ad_reports(event->getParam(), event->getParamSize());
- jau::for_each_idx(eirlist, [&](std::shared_ptr<EInfoReport> & eir) {
- // COND_PRINT(env.DEBUG_EVENT, "HCIHandler-IO RECV (AD EIR) %s", eir->toString().c_str());
- const MgmtEvtDeviceFound e(dev_id, eir);
+ jau::darray<std::unique_ptr<EInfoReport>> eirlist = EInfoReport::read_ad_reports(event->getParam(), event->getParamSize());
+ for(jau::nsize_t eircount = eirlist.size(); eircount>0; --eircount) {
+ const MgmtEvtDeviceFound e(dev_id, std::move( eirlist[0] ) );
+ COND_PRINT(env.DEBUG_SCAN_AD_EIR, "HCIHandler-IO RECV (AD EIR) %s", e.getEIR()->toString().c_str());
sendMgmtEvent( e );
- });
+ }
} else {
// issue a callback for the translated event
std::unique_ptr<MgmtEvent> mevent = translate(*event);