aboutsummaryrefslogtreecommitdiffstats
path: root/src/direct_bt/BTAdapter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/direct_bt/BTAdapter.cpp')
-rw-r--r--src/direct_bt/BTAdapter.cpp107
1 files changed, 82 insertions, 25 deletions
diff --git a/src/direct_bt/BTAdapter.cpp b/src/direct_bt/BTAdapter.cpp
index f22b3ff0..61302e79 100644
--- a/src/direct_bt/BTAdapter.cpp
+++ b/src/direct_bt/BTAdapter.cpp
@@ -66,17 +66,39 @@ std::string direct_bt::to_string(const DiscoveryPolicy v) noexcept {
return "Unknown DiscoveryPolicy "+jau::to_hexstring(number(v));
}
-BTDeviceRef BTAdapter::findDevice(device_list_t & devices, const EUI48 & address, const BDAddressType addressType) noexcept {
+BTDeviceRef BTAdapter::findDevice(HCIHandler& hci, device_list_t & devices, const EUI48 & address, const BDAddressType addressType) noexcept {
+ BDAddressAndType rpa(address, addressType);
const jau::nsize_t size = devices.size();
for (jau::nsize_t i = 0; i < size; ++i) {
BTDeviceRef & e = devices[i];
- if ( nullptr != e && address == e->getAddressAndType().address &&
- ( addressType == e->getAddressAndType().type || addressType == BDAddressType::BDADDR_UNDEFINED )
+ if ( nullptr != e &&
+ (
+ ( address == e->getAddressAndType().address &&
+ ( addressType == e->getAddressAndType().type || addressType == BDAddressType::BDADDR_UNDEFINED )
+ ) ||
+ ( address == e->getVisibleAddressAndType().address &&
+ ( addressType == e->getVisibleAddressAndType().type || addressType == BDAddressType::BDADDR_UNDEFINED )
+ )
+ )
)
{
+ if( !rpa.isIdentityAddress() ) {
+ e->updateVisibleAddress(rpa);
+ hci.setResolvHCIConnectionAddr(rpa, e->getAddressAndType());
+ }
return e;
}
}
+ if( !rpa.isIdentityAddress() ) {
+ for (jau::nsize_t i = 0; i < size; ++i) {
+ BTDeviceRef & e = devices[i];
+ if ( nullptr != e && e->matches_irk(rpa) ) {
+ e->updateVisibleAddress(rpa);
+ hci.setResolvHCIConnectionAddr(rpa, e->getAddressAndType());
+ return e;
+ }
+ }
+ }
return nullptr;
}
@@ -98,8 +120,12 @@ BTDeviceRef BTAdapter::findWeakDevice(weak_device_list_t & devices, const EUI48
BTDeviceRef e = w.lock();
if( nullptr == e ) {
devices.erase(it); // erase and move it to next element
- } else if ( address == e->getAddressAndType().address &&
- ( addressType == e->getAddressAndType().type || addressType == BDAddressType::BDADDR_UNDEFINED )
+ } else if ( ( address == e->getAddressAndType().address &&
+ ( addressType == e->getAddressAndType().type || addressType == BDAddressType::BDADDR_UNDEFINED )
+ ) ||
+ ( address == e->getVisibleAddressAndType().address &&
+ ( addressType == e->getVisibleAddressAndType().type || addressType == BDAddressType::BDADDR_UNDEFINED )
+ )
)
{
return e;
@@ -230,7 +256,7 @@ BTAdapter::size_type BTAdapter::disconnectAllDevices(const HCIStatusCode reason)
BTDeviceRef BTAdapter::findConnectedDevice (const EUI48 & address, const BDAddressType & addressType) noexcept {
const std::lock_guard<std::mutex> lock(mtx_connectedDevices); // RAII-style acquire and relinquish via destructor
- return findDevice(connectedDevices, address, addressType);
+ return findDevice(hci, connectedDevices, address, addressType);
}
jau::nsize_t BTAdapter::getConnectedDeviceCount() const noexcept {
@@ -255,9 +281,13 @@ bool BTAdapter::updateDataFromHCI() noexcept {
hci_uses_ext_conn = hci.use_ext_conn();
hci_uses_ext_adv = hci.use_ext_adv();
+ status = hci.le_set_addr_resolv_enable(true);
+ if( HCIStatusCode::SUCCESS != status ) {
+ jau::INFO_PRINT("Adapter[%d]: ENABLE RESOLV LIST: %s", dev_id, to_string(status).c_str());
+ }
status = hci.le_clear_resolv_list();
if( HCIStatusCode::SUCCESS != status ) {
- jau::INFO_PRINT("Adapter[%d]: CLEAR RESOLV LIST failed %s", dev_id, to_string(status).c_str());
+ jau::INFO_PRINT("Adapter[%d]: CLEAR RESOLV LIST: %s", dev_id, to_string(status).c_str());
}
WORDY_PRINT("BTAdapter::updateDataFromHCI: Adapter[%d]: POWERED, %s - %s, hci_ext[scan %d, conn %d], features: %s",
@@ -340,6 +370,11 @@ bool BTAdapter::enableListening(const bool enable) noexcept {
ok = mgmt->addMgmtEventCallback(dev_id, MgmtEvent::Opcode::NEW_LINK_KEY, jau::bind_member(this, &BTAdapter::mgmtEvNewLinkKeyMgmt)) && ok;
ok = mgmt->addMgmtEventCallback(dev_id, MgmtEvent::Opcode::NEW_IRK, jau::bind_member(this, &BTAdapter::mgmtEvNewIdentityResolvingKeyMgmt)) && ok;
+ if( debug_event || jau::environment::get().debug ) {
+ ok = mgmt->addMgmtEventCallback(dev_id, MgmtEvent::Opcode::DEVICE_CONNECTED, jau::bind_member(this, &BTAdapter::mgmtEvDeviceConnectedMgmt)) && ok;
+ ok = mgmt->addMgmtEventCallback(dev_id, MgmtEvent::Opcode::DEVICE_DISCONNECTED, jau::bind_member(this, &BTAdapter::mgmtEvMgmtAnyMgmt)) && ok;
+ }
+
if( !ok ) {
ERR_PRINT("Could not add all required MgmtEventCallbacks to DBTManager: %s", toString().c_str());
return false;
@@ -509,8 +544,8 @@ void BTAdapter::poweredOff(bool active, const std::string& msg) noexcept {
stopDiscoveryImpl(true /* forceDiscoveringEvent */, false /* temporary */);
}
- // Removes all device references from the lists: connectedDevices, discoveredDevices, sharedDevices
- disconnectAllDevices();
+ // Removes all device references from the lists: connectedDevices, discoveredDevices
+ disconnectAllDevices(HCIStatusCode::NOT_POWERED);
removeDiscoveredDevices();
// ensure all hci states are reset.
@@ -551,9 +586,10 @@ void BTAdapter::printDeviceList(const std::string& prefix, const BTAdapter::devi
} else if( (*it)->isValidInstance() /** TODO: See above */ ) {
jau::PLAIN_PRINT(true, " - %d / %zu: invalid", (idx+1), sz);
} else {
- jau::PLAIN_PRINT(true, " - %d / %zu: %s, name '%s'", (idx+1), sz,
+ jau::PLAIN_PRINT(true, " - %d / %zu: %s, name '%s', visible %s", (idx+1), sz,
(*it)->getAddressAndType().toString().c_str(),
- (*it)->getName().c_str() );
+ (*it)->getName().c_str(),
+ (*it)->getVisibleAddressAndType().toString().c_str());
}
PRAGMA_DISABLE_WARNING_POP
}
@@ -570,9 +606,10 @@ void BTAdapter::printWeakDeviceList(const std::string& prefix, BTAdapter::weak_d
} else if( !e->isValidInstance() ) {
jau::PLAIN_PRINT(true, " - %d / %zu: invalid", (idx+1), sz);
} else {
- jau::PLAIN_PRINT(true, " - %d / %zu: %s, name '%s'", (idx+1), sz,
+ jau::PLAIN_PRINT(true, " - %d / %zu: %s, name '%s', visible %s", (idx+1), sz,
e->getAddressAndType().toString().c_str(),
- e->getName().c_str() );
+ e->getName().c_str(),
+ e->getVisibleAddressAndType().toString().c_str());
}
}
}
@@ -1327,7 +1364,7 @@ exit:
BTDeviceRef BTAdapter::findDiscoveredDevice (const EUI48 & address, const BDAddressType addressType) noexcept {
const std::lock_guard<std::mutex> lock(mtx_discoveredDevices); // RAII-style acquire and relinquish via destructor
- return findDevice(discoveredDevices, address, addressType);
+ return findDevice(hci, discoveredDevices, address, addressType);
}
bool BTAdapter::addDiscoveredDevice(BTDeviceRef const &device) noexcept {
@@ -1417,7 +1454,7 @@ void BTAdapter::removeSharedDevice(const BTDevice & device) noexcept {
BTDeviceRef BTAdapter::findSharedDevice (const EUI48 & address, const BDAddressType addressType) noexcept {
const std::lock_guard<std::mutex> lock(mtx_sharedDevices); // RAII-style acquire and relinquish via destructor
- return findDevice(sharedDevices, address, addressType);
+ return findDevice(hci, sharedDevices, address, addressType);
}
// *************************************************
@@ -1691,6 +1728,10 @@ void BTAdapter::mgmtEvHCIAnyHCI(const MgmtEvent& e) noexcept {
DBG_PRINT("BTAdapter:hci::Any: %s", e.toString().c_str());
(void)e;
}
+void BTAdapter::mgmtEvMgmtAnyMgmt(const MgmtEvent& e) noexcept {
+ DBG_PRINT("BTAdapter:mgmt:Any: %s", e.toString().c_str());
+ (void)e;
+}
void BTAdapter::mgmtEvDeviceDiscoveringHCI(const MgmtEvent& e) noexcept {
const MgmtEvtDiscovering &event = *static_cast<const MgmtEvtDiscovering *>(&e);
@@ -1813,7 +1854,7 @@ void BTAdapter::updateAdapterSettings(const bool off_thread, const AdapterSettin
if( justPoweredOff ) {
// Adapter has been powered off, close connections and cleanup off-thread.
if( off_thread ) {
- std::thread bg(&BTAdapter::poweredOff, this, false, "powered_off.0"); // @suppress("Invalid arguments")
+ std::thread bg(&BTAdapter::poweredOff, this, false, "adapter_settings.0"); // @suppress("Invalid arguments")
bg.detach();
} else {
poweredOff(false, "powered_off.1");
@@ -1861,8 +1902,8 @@ void BTAdapter::l2capServerEnd(jau::service_runner& sr) noexcept {
void BTAdapter::l2capServerWork(jau::service_runner& sr) noexcept {
(void)sr;
std::unique_ptr<L2CAPClient> l2cap_att_ = l2cap_att_srv.accept();
- if( BTRole::Slave == getRole() && nullptr != l2cap_att_ ) {
- DBG_PRINT("L2CAP-ACCEPT: BTAdapter::l2capServer connected.1: %s", l2cap_att_->toString().c_str());
+ if( BTRole::Slave == getRole() && nullptr != l2cap_att_ && l2cap_att_->getRemoteAddressAndType().isIdentityLEAddress() ) {
+ DBG_PRINT("L2CAP-ACCEPT: BTAdapter::l2capServer connected.1: (public) %s", l2cap_att_->toString().c_str());
std::unique_lock<std::mutex> lock(mtx_l2cap_att); // RAII-style acquire and relinquish via destructor
l2cap_att = std::move( l2cap_att_ );
@@ -1870,7 +1911,7 @@ void BTAdapter::l2capServerWork(jau::service_runner& sr) noexcept {
cv_l2cap_att.notify_all(); // notify waiting getter
} else if( nullptr != l2cap_att_ ) {
- DBG_PRINT("L2CAP-ACCEPT: BTAdapter::l2capServer connected.2: %s", l2cap_att_->toString().c_str());
+ DBG_PRINT("L2CAP-ACCEPT: BTAdapter::l2capServer connected.2: (ignored) %s", l2cap_att_->toString().c_str());
} else {
DBG_PRINT("L2CAP-ACCEPT: BTAdapter::l2capServer connected.0: nullptr");
}
@@ -1960,6 +2001,8 @@ void BTAdapter::mgmtEvDeviceConnectedHCI(const MgmtEvent& e) noexcept {
ad_report.setAddress( event.getAddress() );
ad_report.read_data(event.getData(), event.getDataSize());
}
+ DBG_PRINT("BTAdapter::mgmtEvDeviceConnectedHCI(dev_id %d): Event %s, AD EIR %s",
+ dev_id, e.toString().c_str(), ad_report.toString(true).c_str());
int new_connect = 0;
bool device_discovered = true;
@@ -2080,6 +2123,19 @@ void BTAdapter::mgmtEvDeviceConnectedHCI(const MgmtEvent& e) noexcept {
device->notifyLEFeatures(device, LE_Features::LE_Encryption);
}
}
+void BTAdapter::mgmtEvDeviceConnectedMgmt(const MgmtEvent& e) noexcept {
+ const MgmtEvtDeviceConnected &event = *static_cast<const MgmtEvtDeviceConnected *>(&e);
+ EInfoReport ad_report;
+ {
+ ad_report.setSource(EInfoReport::Source::EIR, false);
+ ad_report.setTimestamp(event.getTimestamp());
+ ad_report.setAddressType(event.getAddressType());
+ ad_report.setAddress( event.getAddress() );
+ ad_report.read_data(event.getData(), event.getDataSize());
+ }
+ DBG_PRINT("BTAdapter::mgmtEvDeviceConnectedMgmt(dev_id %d): Event %s, AD EIR %s",
+ dev_id, e.toString().c_str(), ad_report.toString(true).c_str());
+}
void BTAdapter::mgmtEvConnectFailedHCI(const MgmtEvent& e) noexcept {
const MgmtEvtDeviceConnectFailed &event = *static_cast<const MgmtEvtDeviceConnectFailed *>(&e);
@@ -2347,7 +2403,7 @@ void BTAdapter::mgmtEvPairDeviceCompleteMgmt(const MgmtEvent& e) noexcept {
void BTAdapter::mgmtEvNewLongTermKeyMgmt(const MgmtEvent& e) noexcept {
const MgmtEvtNewLongTermKey& event = *static_cast<const MgmtEvtNewLongTermKey *>(&e);
- const MgmtLongTermKeyInfo& ltk_info = event.getLongTermKey();
+ const MgmtLongTermKey& ltk_info = event.getLongTermKey();
BTDeviceRef device = findConnectedDevice(ltk_info.address, ltk_info.address_type);
if( nullptr != device ) {
const bool ok = ltk_info.enc_size > 0 && ltk_info.key_type != MgmtLTKType::NONE;
@@ -2385,7 +2441,7 @@ void BTAdapter::mgmtEvNewLinkKeyMgmt(const MgmtEvent& e) noexcept {
void BTAdapter::mgmtEvNewIdentityResolvingKeyMgmt(const MgmtEvent& e) noexcept {
const MgmtEvtNewIdentityResolvingKey& event = *static_cast<const MgmtEvtNewIdentityResolvingKey *>(&e);
const EUI48& randomAddress = event.getRandomAddress();
- const MgmtIdentityResolvingKeyInfo& irk = event.getIdentityResolvingKey();
+ const MgmtIdentityResolvingKey& irk = event.getIdentityResolvingKey();
if( adapterInfo.addressAndType.address == irk.address && adapterInfo.addressAndType.type == irk.address_type ) {
// setPrivacy ...
visibleAddressAndType.address = randomAddress;
@@ -2397,9 +2453,8 @@ void BTAdapter::mgmtEvNewIdentityResolvingKeyMgmt(const MgmtEvent& e) noexcept {
} else {
BTDeviceRef device = findConnectedDevice(randomAddress, BDAddressType::BDADDR_UNDEFINED);
if( nullptr != device ) {
- // TODO: Notify our remove BDDevice instance about the resolved address!
- // TODO: Support Random Address resolution!
- WORDY_PRINT("BTAdapter::mgmt:NewIdentityResolvingKey(dev_id %d): Device found (Resolvable not yet supported): %s, %s",
+ // Handled via SMP
+ WORDY_PRINT("BTAdapter::mgmt:NewIdentityResolvingKey(dev_id %d): Device found (Resolvable): %s, %s",
dev_id, event.toString().c_str(), device->toString().c_str());
} else {
WORDY_PRINT("BTAdapter::mgmt:NewIdentityResolvingKey(dev_id %d): Device not tracked: %s",
@@ -2682,6 +2737,8 @@ void BTAdapter::sendDevicePairingState(const BTDeviceRef& device, const SMPPairi
SMPKeyBin key = SMPKeyBin::create(*device);
if( key.isValid() ) {
addSMPKeyBin( std::make_shared<SMPKeyBin>(key), true /* write_file */ );
+ } else {
+ WARN_PRINT("(dev_id %d): created SMPKeyBin invalid: %s", dev_id, key.toString().c_str());
}
} else {
// pre-paired, refresh PairingData of BTDevice (perhaps a new instance)
@@ -2689,7 +2746,7 @@ void BTAdapter::sendDevicePairingState(const BTDeviceRef& device, const SMPPairi
if( nullptr != key ) {
bool res = device->setSMPKeyBin(*key);
if( !res ) {
- WARN_PRINT("(dev_id %d): device::setSMPKeyBin() failed %d, %s", res, key->toString().c_str());
+ WARN_PRINT("(dev_id %d): device::setSMPKeyBin() failed %d, %s", dev_id, res, key->toString().c_str());
}
}
}