diff options
author | Sven Gothel <[email protected]> | 2020-08-23 09:47:10 +0200 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2020-08-23 09:47:10 +0200 |
commit | e7164946014ab8d5c5587fe8f69e6262aed64bc5 (patch) | |
tree | da93772834744aef34414fed872936b066b2332f /src | |
parent | 5cb8c348f36359ea8e81fc6789337a582bbd516b (diff) |
DBTAdapter: Use HCIHandler discovery/scan start and stop
TODO: For now we send the DISCOVERY events ourselves as the le_enable_scan command
is a CMD_COMPLETE type procedure, i.e. has no lagging result and finishes its operation.
Need to validate why Linux Mgmt uses a lagging event notification in the first place,
however the current code should be compliant w/ HCI spec.
See commit 5cb8c348f36359ea8e81fc6789337a582bbd516b,
which adds le_enable_scan(..) to HCIHandler
Diffstat (limited to 'src')
-rw-r--r-- | src/direct_bt/DBTAdapter.cpp | 76 |
1 files changed, 72 insertions, 4 deletions
diff --git a/src/direct_bt/DBTAdapter.cpp b/src/direct_bt/DBTAdapter.cpp index 09969ccd..a6624f4c 100644 --- a/src/direct_bt/DBTAdapter.cpp +++ b/src/direct_bt/DBTAdapter.cpp @@ -364,6 +364,8 @@ void DBTAdapter::checkDiscoveryState() { } } +#define USE_HCI_DISCOVERY 1 + bool DBTAdapter::startDiscovery(const bool keepAlive, const HCILEOwnAddressType own_mac_type, const uint16_t le_scan_interval, const uint16_t le_scan_window) { @@ -390,19 +392,65 @@ bool DBTAdapter::startDiscovery(const bool keepAlive, const HCILEOwnAddressType removeDiscoveredDevices(); keepDiscoveringAlive = keepAlive; + +#ifdef USE_HCI_DISCOVERY + std::shared_ptr<HCIHandler> hci = getHCI(); + if( nullptr == hci ) { + ERR_PRINT("DBTAdapter::startDiscovery: HCI not available: %s", toString().c_str()); + return false; + } + HCIStatusCode status = hci->le_set_scan_param(); + if( HCIStatusCode::SUCCESS != status ) { + currentNativeScanType = ScanType::NONE; + ERR_PRINT("DBTAdapter::startDiscovery: le_set_scan_param failed: %s", getHCIStatusCodeString(status).c_str()); + } else { + status = hci->le_enable_scan(true /* enable */, true /* filter_dup */); + if( HCIStatusCode::SUCCESS != status ) { + currentNativeScanType = ScanType::NONE; + ERR_PRINT("DBTAdapter::startDiscovery: le_enable_scan failed: %s", getHCIStatusCodeString(status).c_str()); + } else { + currentNativeScanType = ScanType::LE; + } + } +#else currentNativeScanType = mgmt.startDiscovery(dev_id); +#endif + currentMetaScanType = currentNativeScanType.load(); DBG_PRINT("DBTAdapter::startDiscovery: Initiated discovery, keepAlive %d -> %d, currentScanType[native %s, meta %s] ...", keepDiscoveringAlive.load(), keepAlive, getScanTypeString(currentNativeScanType).c_str(), getScanTypeString(currentMetaScanType).c_str()); checkDiscoveryState(); + +#ifdef USE_HCI_DISCOVERY + if( ScanType::NONE != currentMetaScanType ) { + // will call mgmtEvDeviceDiscoveringMgmt and hence AdapterStatusListener.discoveryChanged(..) + MgmtEvtDiscovering *e = new MgmtEvtDiscovering(dev_id, ScanType::LE, true); + mgmt.sendMgmtEvent(std::shared_ptr<MgmtEvent>(e)); + } +#endif return ScanType::NONE != currentMetaScanType; } void DBTAdapter::startDiscoveryBackground() { const std::lock_guard<std::recursive_mutex> lock(mtx_discovery); // RAII-style acquire and relinquish via destructor if( ScanType::NONE == currentNativeScanType && keepDiscoveringAlive ) { // still? +#ifdef USE_HCI_DISCOVERY + std::shared_ptr<HCIHandler> hci = getHCI(); + if( nullptr == hci ) { + ERR_PRINT("DBTAdapter::startDiscoveryBackground: HCI not available: %s", toString().c_str()); + return; + } + HCIStatusCode status = hci->le_enable_scan(true /* enable */, true /* filter_dup */); + if( HCIStatusCode::SUCCESS != status ) { + currentNativeScanType = ScanType::NONE; + ERR_PRINT("DBTAdapter::startDiscoveryBackground: le_enable_scan failed: %s", getHCIStatusCodeString(status).c_str()); + } else { + currentNativeScanType = ScanType::LE; + } +#else currentNativeScanType = mgmt.startDiscovery(dev_id); +#endif checkDiscoveryState(); } } @@ -437,19 +485,39 @@ void DBTAdapter::stopDiscovery() { return; } - bool r; - if( ( r = mgmt.stopDiscovery(dev_id, currentMetaScanType) ) == true ) { + bool res; +#ifdef USE_HCI_DISCOVERY + std::shared_ptr<HCIHandler> hci = getHCI(); + if( nullptr == hci ) { + ERR_PRINT("DBTAdapter::stopDiscovery: HCI not available: %s", toString().c_str()); + return false; + } + HCIStatusCode status = hci->le_enable_scan(false /* enable */, false /* filter_dup */); + if( HCIStatusCode::SUCCESS != status ) { + res = false; + ERR_PRINT("DBTAdapter::stopDiscovery: le_enable_scan failed: %s", getHCIStatusCodeString(status).c_str()); + } else { + currentNativeScanType = ScanType::NONE; + res = true; + } +#else + if( ( res = mgmt.stopDiscovery(dev_id, currentMetaScanType) ) == true ) { currentNativeScanType = ScanType::NONE; } +#endif currentMetaScanType = currentNativeScanType.load(); // always to have valid DiscoveryState triple DBG_PRINT("DBTAdapter::stopDiscovery: Stopped (res %d), keepAlive %d, currentScanType[native %s, meta %s], sendEvent %d ...", - r, keepDiscoveringAlive.load(), + res, keepDiscoveringAlive.load(), getScanTypeString(currentNativeScanType).c_str(), getScanTypeString(currentMetaScanType).c_str(), sendEvent); checkDiscoveryState(); - if( sendEvent ) { +#ifdef USE_HCI_DISCOVERY + { +#else + if( sendEvent ) { ; +#endif // will call mgmtEvDeviceDiscoveringMgmt and hence AdapterStatusListener.discoveryChanged(..) MgmtEvtDiscovering *e = new MgmtEvtDiscovering(dev_id, ScanType::NONE, false); mgmt.sendMgmtEvent(std::shared_ptr<MgmtEvent>(e)); |