diff options
author | Sven Gothel <[email protected]> | 2022-04-10 01:53:53 +0200 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2022-04-10 01:53:53 +0200 |
commit | 35ecc48639ae1dd20a3d7e4428559cc199e0ca28 (patch) | |
tree | ea0a9d36b30683ab05c0ab3d5483b066ee46a8dd | |
parent | 03d93b36f91f03e6ad6f4250a4967119a17b92e8 (diff) |
SMPHandler.hpp: #define -> 'inline constexpr' to allow proper compile time analysis; Also 'static constexpr const -> inline constexpr const' for global constants
-rw-r--r-- | api/direct_bt/BTAdapter.hpp | 2 | ||||
-rw-r--r-- | api/direct_bt/BTDevice.hpp | 2 | ||||
-rw-r--r-- | api/direct_bt/BTManager.hpp | 7 | ||||
-rw-r--r-- | api/direct_bt/DBTConst.hpp | 2 | ||||
-rw-r--r-- | api/direct_bt/SMPHandler.hpp | 16 | ||||
-rw-r--r-- | src/direct_bt/BTAdapter.cpp | 103 | ||||
-rw-r--r-- | src/direct_bt/BTDevice.cpp | 455 | ||||
-rw-r--r-- | src/direct_bt/BTManager.cpp | 329 | ||||
-rw-r--r-- | src/direct_bt/HCIHandler.cpp | 8 | ||||
-rw-r--r-- | src/direct_bt/SMPHandler.cpp | 6 |
10 files changed, 456 insertions, 474 deletions
diff --git a/api/direct_bt/BTAdapter.hpp b/api/direct_bt/BTAdapter.hpp index 3e6ad065..0b94b399 100644 --- a/api/direct_bt/BTAdapter.hpp +++ b/api/direct_bt/BTAdapter.hpp @@ -1046,7 +1046,7 @@ namespace direct_bt { const bool filter_dup=true) noexcept; private: - HCIStatusCode stopDiscovery(const bool forceDiscoveringEvent, const bool temporary) noexcept; + HCIStatusCode stopDiscoveryImpl(const bool forceDiscoveringEvent, const bool temporary) noexcept; public: /** diff --git a/api/direct_bt/BTDevice.hpp b/api/direct_bt/BTDevice.hpp index 537645b2..3b90e1c3 100644 --- a/api/direct_bt/BTDevice.hpp +++ b/api/direct_bt/BTDevice.hpp @@ -89,10 +89,8 @@ namespace direct_bt { jau::ordered_atomic<LE_Features, std::memory_order_relaxed> le_features; jau::ordered_atomic<LE_PHYs, std::memory_order_relaxed> le_phy_tx; jau::ordered_atomic<LE_PHYs, std::memory_order_relaxed> le_phy_rx; -#if SMP_SUPPORTED_BY_OS std::shared_ptr<SMPHandler> smpHandler = nullptr; std::recursive_mutex mtx_smpHandler; -#endif std::shared_ptr<BTGattHandler> gattHandler = nullptr; mutable std::recursive_mutex mtx_gattHandler; mutable std::recursive_mutex mtx_connect; diff --git a/api/direct_bt/BTManager.hpp b/api/direct_bt/BTManager.hpp index cf973dec..dd99585b 100644 --- a/api/direct_bt/BTManager.hpp +++ b/api/direct_bt/BTManager.hpp @@ -205,13 +205,8 @@ namespace direct_bt { private: friend BTAdapter; -#if USE_LINUX_BT_SECURITY /** Default initialization with ::SMPIOCapability::NO_INPUT_NO_OUTPUT for PairingMode::JUST_WORKS. */ - constexpr static const SMPIOCapability defaultIOCapability = SMPIOCapability::NO_INPUT_NO_OUTPUT; -#else - /** Default initialization with ::SMPIOCapability::NO_INPUT_NO_OUTPUT for PairingMode::JUST_WORKS. */ - constexpr static const SMPIOCapability defaultIOCapability = SMPIOCapability::UNSET; -#endif + constexpr static const SMPIOCapability defaultIOCapability = USE_LINUX_BT_SECURITY ? SMPIOCapability::NO_INPUT_NO_OUTPUT : SMPIOCapability::UNSET; struct WhitelistElem { uint16_t dev_id; diff --git a/api/direct_bt/DBTConst.hpp b/api/direct_bt/DBTConst.hpp index 646cc8b5..336714e4 100644 --- a/api/direct_bt/DBTConst.hpp +++ b/api/direct_bt/DBTConst.hpp @@ -37,7 +37,7 @@ namespace direct_bt { * * Usually used for socket reader threads, like used within HCIHandler. */ - static constexpr const jau::nsize_t THREAD_SHUTDOWN_TIMEOUT_MS = 8000; + inline constexpr const jau::nsize_t THREAD_SHUTDOWN_TIMEOUT_MS = 8000; } // namespace direct_bt diff --git a/api/direct_bt/SMPHandler.hpp b/api/direct_bt/SMPHandler.hpp index 05650a8f..39d911e3 100644 --- a/api/direct_bt/SMPHandler.hpp +++ b/api/direct_bt/SMPHandler.hpp @@ -49,15 +49,15 @@ * Linux/BlueZ prohibits access to the existing SMP implementation via L2CAP (socket). */ #ifdef __linux__ - #define SMP_SUPPORTED_BY_OS 0 - #define USE_LINUX_BT_SECURITY 1 - #define CONSIDER_HCI_CMD_FOR_SMP_STATE 0 - #define SCAN_DISABLED_POST_CONNECT 1 + inline constexpr const bool SMP_SUPPORTED_BY_OS = false; + inline constexpr const bool USE_LINUX_BT_SECURITY = true; + inline constexpr const bool CONSIDER_HCI_CMD_FOR_SMP_STATE = false; + inline constexpr const bool SCAN_DISABLED_POST_CONNECT = true; #else - #define SMP_SUPPORTED_BY_OS 1 - #define USE_LINUX_BT_SECURITY 0 - #define CONSIDER_HCI_CMD_FOR_SMP_STATE 1 - #define SCAN_DISABLED_POST_CONNECT 0 + inline constexpr const bool SMP_SUPPORTED_BY_OS = true; + inline constexpr const bool USE_LINUX_BT_SECURITY = false; + inline constexpr const bool CONSIDER_HCI_CMD_FOR_SMP_STATE = true; + inline constexpr const bool SCAN_DISABLED_POST_CONNECT = false; #endif /** diff --git a/src/direct_bt/BTAdapter.cpp b/src/direct_bt/BTAdapter.cpp index 9a9d0dee..582ca57a 100644 --- a/src/direct_bt/BTAdapter.cpp +++ b/src/direct_bt/BTAdapter.cpp @@ -140,12 +140,12 @@ bool BTAdapter::addDevicePausingDiscovery(const BTDeviceRef & device) noexcept { pausing_discovery_devices.push_back(device); } if( added_first ) { -#if SCAN_DISABLED_POST_CONNECT - updateDeviceDiscoveringState(ScanType::LE, false /* eventEnabled */, true /* off_thread */); -#else - std::thread bg(&BTAdapter::stopDiscovery, this, false /* forceDiscoveringEvent */, true /* temporary */); // @suppress("Invalid arguments") - bg.detach(); -#endif + if constexpr ( SCAN_DISABLED_POST_CONNECT ) { + updateDeviceDiscoveringState(ScanType::LE, false /* eventEnabled */, true /* off_thread */); + } else { + std::thread bg(&BTAdapter::stopDiscoveryImpl, this, false /* forceDiscoveringEvent */, true /* temporary */); // @suppress("Invalid arguments") + bg.detach(); + } return true; } else { return false; @@ -354,13 +354,12 @@ bool BTAdapter::enableListening(const bool enable) noexcept { ok = hci.addMgmtEventCallback(MgmtEvent::Opcode::HCI_ENC_CHANGED, jau::bindMemberFunc(this, &BTAdapter::mgmtEvHCIEncryptionChangedHCI)) && ok; ok = hci.addMgmtEventCallback(MgmtEvent::Opcode::HCI_ENC_KEY_REFRESH_COMPLETE, jau::bindMemberFunc(this, &BTAdapter::mgmtEvHCIEncryptionKeyRefreshCompleteHCI)) && ok; -#if CONSIDER_HCI_CMD_FOR_SMP_STATE - ok = hci.addMgmtEventCallback(MgmtEvent::Opcode::HCI_LE_LTK_REQUEST, jau::bindMemberFunc(this, &BTAdapter::mgmtEvLELTKReqEventHCI)) && ok; - ok = hci.addMgmtEventCallback(MgmtEvent::Opcode::HCI_LE_LTK_REPLY_ACK, jau::bindMemberFunc(this, &BTAdapter::mgmtEvLELTKReplyAckCmdHCI)) && ok; - ok = hci.addMgmtEventCallback(MgmtEvent::Opcode::HCI_LE_LTK_REPLY_REJ, jau::bindMemberFunc(this, &BTAdapter::mgmtEvLELTKReplyRejCmdHCI)) && ok; - ok = hci.addMgmtEventCallback(MgmtEvent::Opcode::HCI_LE_ENABLE_ENC, jau::bindMemberFunc(this, &BTAdapter::mgmtEvLEEnableEncryptionCmdHCI)) && ok; -#endif - + if constexpr ( CONSIDER_HCI_CMD_FOR_SMP_STATE ) { + ok = hci.addMgmtEventCallback(MgmtEvent::Opcode::HCI_LE_LTK_REQUEST, jau::bindMemberFunc(this, &BTAdapter::mgmtEvLELTKReqEventHCI)) && ok; + ok = hci.addMgmtEventCallback(MgmtEvent::Opcode::HCI_LE_LTK_REPLY_ACK, jau::bindMemberFunc(this, &BTAdapter::mgmtEvLELTKReplyAckCmdHCI)) && ok; + ok = hci.addMgmtEventCallback(MgmtEvent::Opcode::HCI_LE_LTK_REPLY_REJ, jau::bindMemberFunc(this, &BTAdapter::mgmtEvLELTKReplyRejCmdHCI)) && ok; + ok = hci.addMgmtEventCallback(MgmtEvent::Opcode::HCI_LE_ENABLE_ENC, jau::bindMemberFunc(this, &BTAdapter::mgmtEvLEEnableEncryptionCmdHCI)) && ok; + } if( !ok ) { ERR_PRINT("Could not add all required MgmtEventCallbacks to HCIHandler: %s of %s", hci.toString().c_str(), toString().c_str()); return false; // dtor local HCIHandler w/ closing @@ -488,7 +487,7 @@ void BTAdapter::poweredOff(bool active) noexcept { discovery_policy = DiscoveryPolicy::PAUSE_CONNECTED_UNTIL_READY; if( active ) { - stopDiscovery(true /* forceDiscoveringEvent */, false /* temporary */); + stopDiscoveryImpl(true /* forceDiscoveringEvent */, false /* temporary */); } // Removes all device references from the lists: connectedDevices, discoveredDevices, sharedDevices @@ -735,30 +734,29 @@ bool BTAdapter::lockConnect(const BTDevice & device, const bool wait, const SMPI single_conn_device_ptr = &device; if( SMPIOCapability::UNSET != io_cap ) { -#if USE_LINUX_BT_SECURITY - SMPIOCapability pre_io_cap { SMPIOCapability::UNSET }; - const bool res_iocap = mgmt.setIOCapability(dev_id, io_cap, pre_io_cap); - if( res_iocap ) { - iocap_defaultval = pre_io_cap; - COND_PRINT(debug_lock, "BTAdapter::lockConnect: Success: New lock, setIOCapability[%s -> %s], %s", - to_string(pre_io_cap).c_str(), to_string(io_cap).c_str(), - device.toString().c_str()); - return true; + if constexpr ( USE_LINUX_BT_SECURITY ) { + SMPIOCapability pre_io_cap { SMPIOCapability::UNSET }; + const bool res_iocap = mgmt.setIOCapability(dev_id, io_cap, pre_io_cap); + if( res_iocap ) { + iocap_defaultval = pre_io_cap; + COND_PRINT(debug_lock, "BTAdapter::lockConnect: Success: New lock, setIOCapability[%s -> %s], %s", + to_string(pre_io_cap).c_str(), to_string(io_cap).c_str(), + device.toString().c_str()); + return true; + } else { + // failed, unlock and exit + COND_PRINT(debug_lock, "BTAdapter::lockConnect: Failed: setIOCapability[%s], %s", + to_string(io_cap).c_str(), device.toString().c_str()); + single_conn_device_ptr = nullptr; + lock.unlock(); // unlock mutex before notify_all to avoid pessimistic re-block of notified wait() thread. + cv_single_conn_device.notify_all(); // notify waiting getter + return false; + } } else { - // failed, unlock and exit - COND_PRINT(debug_lock, "BTAdapter::lockConnect: Failed: setIOCapability[%s], %s", - to_string(io_cap).c_str(), device.toString().c_str()); - single_conn_device_ptr = nullptr; - lock.unlock(); // unlock mutex before notify_all to avoid pessimistic re-block of notified wait() thread. - cv_single_conn_device.notify_all(); // notify waiting getter - return false; + COND_PRINT(debug_lock, "BTAdapter::lockConnect: Success: New lock, ignored io-cap: %s, %s", + to_string(io_cap).c_str(), device.toString().c_str()); + return true; } -#else - COND_PRINT(debug_lock, "BTAdapter::lockConnect: Success: New lock, ignored io-cap: %s, %s", - to_string(io_cap).c_str() - device.toString().c_str()); - return true; -#endif } else { COND_PRINT(debug_lock, "BTAdapter::lockConnect: Success: New lock, no io-cap: %s", device.toString().c_str()); return true; @@ -771,7 +769,7 @@ bool BTAdapter::unlockConnect(const BTDevice & device) noexcept { if( nullptr != single_conn_device_ptr && device == *single_conn_device_ptr ) { const SMPIOCapability v = iocap_defaultval; iocap_defaultval = SMPIOCapability::UNSET; - if( SMPIOCapability::UNSET != v ) { + if( USE_LINUX_BT_SECURITY && SMPIOCapability::UNSET != v ) { // Unreachable: !USE_LINUX_BT_SECURITY SMPIOCapability o; const bool res = mgmt.setIOCapability(dev_id, v, o); @@ -803,7 +801,7 @@ bool BTAdapter::unlockConnectAny() noexcept { if( nullptr != single_conn_device_ptr ) { const SMPIOCapability v = iocap_defaultval; iocap_defaultval = SMPIOCapability::UNSET; - if( SMPIOCapability::UNSET != v ) { + if( USE_LINUX_BT_SECURITY && SMPIOCapability::UNSET != v ) { // Unreachable: !USE_LINUX_BT_SECURITY SMPIOCapability o; const bool res = mgmt.setIOCapability(dev_id, v, o); @@ -1119,10 +1117,10 @@ void BTAdapter::startDiscoveryBackground() noexcept { HCIStatusCode BTAdapter::stopDiscovery() noexcept { clearDevicesPausingDiscovery(); - return stopDiscovery(false /* forceDiscoveringEvent */, false /* temporary */); + return stopDiscoveryImpl(false /* forceDiscoveringEvent */, false /* temporary */); } -HCIStatusCode BTAdapter::stopDiscovery(const bool forceDiscoveringEvent, const bool temporary) noexcept { +HCIStatusCode BTAdapter::stopDiscoveryImpl(const bool forceDiscoveringEvent, const bool temporary) noexcept { // We allow !isEnabled, to utilize method for adjusting discovery state and notifying listeners // FIXME: Respect BTAdapter::btMode, i.e. BTMode::BREDR, BTMode::LE or BTMode::DUAL to stop BREDR, LE or DUAL scanning! @@ -1959,20 +1957,19 @@ bool BTAdapter::mgmtEvHCILERemoteUserFeaturesHCI(const MgmtEvent& e) noexcept { if( BTRole::Master == getRole() ) { const DiscoveryPolicy policy = discovery_policy; if( DiscoveryPolicy::AUTO_OFF == policy ) { -#if SCAN_DISABLED_POST_CONNECT - updateDeviceDiscoveringState(ScanType::LE, false /* eventEnabled */, true /* off_thread */); -#else - std::thread bg(&BTAdapter::stopDiscovery, this, false /* forceDiscoveringEvent */, true /* temporary */); // @suppress("Invalid arguments") - bg.detach(); -#endif - + if constexpr ( SCAN_DISABLED_POST_CONNECT ) { + updateDeviceDiscoveringState(ScanType::LE, false /* eventEnabled */, true /* off_thread */); + } else { + std::thread bg(&BTAdapter::stopDiscoveryImpl, this, false /* forceDiscoveringEvent */, true /* temporary */); // @suppress("Invalid arguments") + bg.detach(); + } } else if( DiscoveryPolicy::ALWAYS_ON == policy ) { -#if SCAN_DISABLED_POST_CONNECT - updateDeviceDiscoveringState(ScanType::LE, false /* eventEnabled */, true /* off_thread */); -#else - std::thread bg(&BTAdapter::startDiscoveryBackground, this); // @suppress("Invalid arguments") - bg.detach(); -#endif + if constexpr ( SCAN_DISABLED_POST_CONNECT ) { + updateDeviceDiscoveringState(ScanType::LE, false /* eventEnabled */, true /* off_thread */); + } else { + std::thread bg(&BTAdapter::startDiscoveryBackground, this); // @suppress("Invalid arguments") + bg.detach(); + } } else { addDevicePausingDiscovery(device); } diff --git a/src/direct_bt/BTDevice.cpp b/src/direct_bt/BTDevice.cpp index 59cf4f99..f2269330 100644 --- a/src/direct_bt/BTDevice.cpp +++ b/src/direct_bt/BTDevice.cpp @@ -616,11 +616,9 @@ void BTDevice::processL2CAPSetup(std::shared_ptr<BTDevice> sthis) { l2cap_open = l2cap_att->open(*this, sec_level); // initiates hciSMPMsgCallback() if sec_level > BT_SECURITY_LOW } const bool l2cap_enc = l2cap_open && BTSecurityLevel::NONE < sec_level; -#if SMP_SUPPORTED_BY_OS - const bool smp_enc = connectSMP(sthis, sec_level) && BTSecurityLevel::NONE < sec_level; -#else - const bool smp_enc = false; -#endif + + const bool smp_enc = SMP_SUPPORTED_BY_OS ? connectSMP(sthis, sec_level) && BTSecurityLevel::NONE < sec_level : false; + DBG_PRINT("BTDevice::processL2CAPSetup: lvl %s, connect[smp_enc %d, l2cap[open %d, enc %d]]", to_string(sec_level).c_str(), smp_enc, l2cap_open, l2cap_enc); @@ -830,41 +828,42 @@ bool BTDevice::updatePairingState(std::shared_ptr<BTDevice> sthis, const MgmtEve // // No SMP pairing in process (maybe REQUESTED_BY_RESPONDER at maximum), // -#if CONSIDER_HCI_CMD_FOR_SMP_STATE - if( MgmtEvent::Opcode::HCI_LE_ENABLE_ENC == mgmtEvtOpcode && - HCIStatusCode::SUCCESS == evtStatus ) - { - // 3a - // No SMP pairing in process (maybe REQUESTED_BY_RESPONDER at maximum), - // i.e. prepairing or already paired, reusing keys and usable connection - // - // Local BTRole::Master initiator - // Encryption key is associated with the remote device having role BTRole::Slave (responder). - const MgmtEvtHCILEEnableEncryptionCmd& event = *static_cast<const MgmtEvtHCILEEnableEncryptionCmd *>(&evt); - const bool use_auth = BTSecurityLevel::ENC_AUTH <= pairing_data.sec_level_conn; - const SMPLongTermKey smp_ltk = event.toSMPLongTermKeyInfo(pairing_data.use_sc, use_auth); - if( smp_ltk.isValid() ) { - if( pairing_data.use_sc ) { // in !SC mode, SMP will deliver different keys! - // Secure Connections (SC) use AES sync key for both, initiator and responder. - // true == smp_ltk.isResponder() - if( ( SMPKeyType::ENC_KEY & pairing_data.keys_resp_has ) == SMPKeyType::NONE ) { // no overwrite - pairing_data.ltk_resp = smp_ltk; - pairing_data.keys_resp_has |= SMPKeyType::ENC_KEY; - if( pairing_data.use_sc && - ( SMPKeyType::ENC_KEY & pairing_data.keys_init_has ) == SMPKeyType::NONE ) // no overwrite - { - pairing_data.ltk_init = smp_ltk; - pairing_data.ltk_init.properties &= ~SMPLongTermKey::Property::RESPONDER; // enforce for SC - pairing_data.keys_init_has |= SMPKeyType::ENC_KEY; + if constexpr ( CONSIDER_HCI_CMD_FOR_SMP_STATE ) { + if( MgmtEvent::Opcode::HCI_LE_ENABLE_ENC == mgmtEvtOpcode && + HCIStatusCode::SUCCESS == evtStatus ) + { + // 3a + // No SMP pairing in process (maybe REQUESTED_BY_RESPONDER at maximum), + // i.e. prepairing or already paired, reusing keys and usable connection + // + // Local BTRole::Master initiator + // Encryption key is associated with the remote device having role BTRole::Slave (responder). + const MgmtEvtHCILEEnableEncryptionCmd& event = *static_cast<const MgmtEvtHCILEEnableEncryptionCmd *>(&evt); + const bool use_auth = BTSecurityLevel::ENC_AUTH <= pairing_data.sec_level_conn; + const SMPLongTermKey smp_ltk = event.toSMPLongTermKeyInfo(pairing_data.use_sc, use_auth); + if( smp_ltk.isValid() ) { + if( pairing_data.use_sc ) { // in !SC mode, SMP will deliver different keys! + // Secure Connections (SC) use AES sync key for both, initiator and responder. + // true == smp_ltk.isResponder() + if( ( SMPKeyType::ENC_KEY & pairing_data.keys_resp_has ) == SMPKeyType::NONE ) { // no overwrite + pairing_data.ltk_resp = smp_ltk; + pairing_data.keys_resp_has |= SMPKeyType::ENC_KEY; + if( pairing_data.use_sc && + ( SMPKeyType::ENC_KEY & pairing_data.keys_init_has ) == SMPKeyType::NONE ) // no overwrite + { + pairing_data.ltk_init = smp_ltk; + pairing_data.ltk_init.properties &= ~SMPLongTermKey::Property::RESPONDER; // enforce for SC + pairing_data.keys_init_has |= SMPKeyType::ENC_KEY; + } } } + mode = PairingMode::PRE_PAIRED; + // Waiting for HCI_ENC_CHANGED or HCI_ENC_KEY_REFRESH_COMPLETE } - mode = PairingMode::PRE_PAIRED; - // Waiting for HCI_ENC_CHANGED or HCI_ENC_KEY_REFRESH_COMPLETE + claimed_state = pairing_data.state; // not yet + break; // case SMPPairingState::COMPLETED: } - claimed_state = pairing_data.state; // not yet - } else -#endif /* SMPHandler CONSIDER_HCI_CMD_FOR_SMP_STATE */ + } if( MgmtEvent::Opcode::HCI_ENC_CHANGED == mgmtEvtOpcode && HCIStatusCode::SUCCESS == evtStatus ) { @@ -890,84 +889,88 @@ bool BTDevice::updatePairingState(std::shared_ptr<BTDevice> sthis, const MgmtEve // // SMPPairingState::KEY_DISTRIBUTION // - if( MgmtEvent::Opcode::HCI_ENC_CHANGED == mgmtEvtOpcode || - MgmtEvent::Opcode::HCI_ENC_KEY_REFRESH_COMPLETE == mgmtEvtOpcode ) { - // 4a - pairing_data.encryption_enabled = true; - check_pairing_complete = true; -#if CONSIDER_HCI_CMD_FOR_SMP_STATE - } else if( MgmtEvent::Opcode::HCI_LE_ENABLE_ENC == mgmtEvtOpcode ) { - // 4b - // Local BTRole::Master initiator - // Encryption key is associated with the remote device having role BTRole::Slave (responder). - const MgmtEvtHCILEEnableEncryptionCmd& event = *static_cast<const MgmtEvtHCILEEnableEncryptionCmd *>(&evt); - const bool use_auth = BTSecurityLevel::ENC_AUTH <= pairing_data.sec_level_conn; - const SMPLongTermKey smp_ltk = event.toSMPLongTermKeyInfo(pairing_data.use_sc, use_auth); - if( smp_ltk.isValid() ) { - if( pairing_data.use_sc ) { // in !SC mode, SMP will deliver different keys! - // Secure Connections (SC) use AES sync key for both, initiator and responder. - // true == smp_ltk.isResponder() - if( ( SMPKeyType::ENC_KEY & pairing_data.keys_resp_has ) == SMPKeyType::NONE ) { // no overwrite - pairing_data.ltk_resp = smp_ltk; - pairing_data.keys_resp_has |= SMPKeyType::ENC_KEY; - if( pairing_data.use_sc && - ( SMPKeyType::ENC_KEY & pairing_data.keys_init_has ) == SMPKeyType::NONE ) // no overwrite - { - pairing_data.ltk_init = smp_ltk; - pairing_data.ltk_init.properties &= ~SMPLongTermKey::Property::RESPONDER; // enforce for SC - pairing_data.keys_init_has |= SMPKeyType::ENC_KEY; + if constexpr ( CONSIDER_HCI_CMD_FOR_SMP_STATE ) { + if( MgmtEvent::Opcode::HCI_LE_ENABLE_ENC == mgmtEvtOpcode ) { + // 4b + // Local BTRole::Master initiator + // Encryption key is associated with the remote device having role BTRole::Slave (responder). + const MgmtEvtHCILEEnableEncryptionCmd& event = *static_cast<const MgmtEvtHCILEEnableEncryptionCmd *>(&evt); + const bool use_auth = BTSecurityLevel::ENC_AUTH <= pairing_data.sec_level_conn; + const SMPLongTermKey smp_ltk = event.toSMPLongTermKeyInfo(pairing_data.use_sc, use_auth); + if( smp_ltk.isValid() ) { + if( pairing_data.use_sc ) { // in !SC mode, SMP will deliver different keys! + // Secure Connections (SC) use AES sync key for both, initiator and responder. + // true == smp_ltk.isResponder() + if( ( SMPKeyType::ENC_KEY & pairing_data.keys_resp_has ) == SMPKeyType::NONE ) { // no overwrite + pairing_data.ltk_resp = smp_ltk; + pairing_data.keys_resp_has |= SMPKeyType::ENC_KEY; + if( pairing_data.use_sc && + ( SMPKeyType::ENC_KEY & pairing_data.keys_init_has ) == SMPKeyType::NONE ) // no overwrite + { + pairing_data.ltk_init = smp_ltk; + pairing_data.ltk_init.properties &= ~SMPLongTermKey::Property::RESPONDER; // enforce for SC + pairing_data.keys_init_has |= SMPKeyType::ENC_KEY; + } } } + // Waiting for HCI_ENC_CHANGED or HCI_ENC_KEY_REFRESH_COMPLETE } - // Waiting for HCI_ENC_CHANGED or HCI_ENC_KEY_REFRESH_COMPLETE - } - claimed_state = pairing_data.state; // not yet - } else if( MgmtEvent::Opcode::HCI_LE_LTK_REQUEST == mgmtEvtOpcode ) { - // 4c - // Local BTRole::Slave responder - const MgmtEvtHCILELTKReq& event = *static_cast<const MgmtEvtHCILELTKReq *>(&evt); - const bool use_auth = BTSecurityLevel::ENC_AUTH <= pairing_data.sec_level_conn; - const SMPLongTermKey smp_ltk = event.toSMPLongTermKeyInfo(pairing_data.use_sc, use_auth); - { // if( smp_ltk.isValid() ) // not yet valid - if( pairing_data.use_sc ) { // in !SC mode, SMP will deliver different keys! - // true == smp_ltk.isResponder() - if( ( SMPKeyType::ENC_KEY & pairing_data.keys_init_has ) == SMPKeyType::NONE ) { // no overwrite - pairing_data.ltk_resp = smp_ltk; - // pairing_data.keys_resp_has |= SMPKeyType::ENC_KEY; // not yet -> LE_LTK_REPLY_ACK LTK { LTK } + claimed_state = pairing_data.state; // not yet + break; // case SMPPairingState::COMPLETED: + } else if( MgmtEvent::Opcode::HCI_LE_LTK_REQUEST == mgmtEvtOpcode ) { + // 4c + // Local BTRole::Slave responder + const MgmtEvtHCILELTKReq& event = *static_cast<const MgmtEvtHCILELTKReq *>(&evt); + const bool use_auth = BTSecurityLevel::ENC_AUTH <= pairing_data.sec_level_conn; + const SMPLongTermKey smp_ltk = event.toSMPLongTermKeyInfo(pairing_data.use_sc, use_auth); + { // if( smp_ltk.isValid() ) // not yet valid + if( pairing_data.use_sc ) { // in !SC mode, SMP will deliver different keys! + // true == smp_ltk.isResponder() + if( ( SMPKeyType::ENC_KEY & pairing_data.keys_init_has ) == SMPKeyType::NONE ) { // no overwrite + pairing_data.ltk_resp = smp_ltk; + // pairing_data.keys_resp_has |= SMPKeyType::ENC_KEY; // not yet -> LE_LTK_REPLY_ACK LTK { LTK } + } } + // Waiting for LE_LTK_REPLY_ACK { LTK } } - // Waiting for LE_LTK_REPLY_ACK { LTK } - } - claimed_state = pairing_data.state; // not yet - } else if( MgmtEvent::Opcode::HCI_LE_LTK_REPLY_ACK == mgmtEvtOpcode ) { - // 4d - // Local BTRole::Slave responder - const MgmtEvtHCILELTKReplyAckCmd& event = *static_cast<const MgmtEvtHCILELTKReplyAckCmd *>(&evt); - SMPLongTermKey smp_ltk = pairing_data.ltk_resp; - smp_ltk.enc_size = 16; // valid now; - smp_ltk.ltk = event.getLTK(); - if( smp_ltk.isValid() ) { - if( pairing_data.use_sc ) { // in !SC mode, SMP will deliver different keys! - // Secure Connections (SC) use AES sync key for both, initiator and responder. - // true == smp_ltk.isResponder() - if( ( SMPKeyType::ENC_KEY & pairing_data.keys_resp_has ) == SMPKeyType::NONE ) { // no overwrite - pairing_data.ltk_resp = smp_ltk; - pairing_data.keys_resp_has |= SMPKeyType::ENC_KEY; - if( pairing_data.use_sc && - ( SMPKeyType::ENC_KEY & pairing_data.keys_init_has ) == SMPKeyType::NONE ) // no overwrite - { - pairing_data.ltk_init = smp_ltk; - pairing_data.ltk_init.properties &= ~SMPLongTermKey::Property::RESPONDER; // enforce for SC - pairing_data.keys_init_has |= SMPKeyType::ENC_KEY; + claimed_state = pairing_data.state; // not yet + break; // case SMPPairingState::COMPLETED: + } else if( MgmtEvent::Opcode::HCI_LE_LTK_REPLY_ACK == mgmtEvtOpcode ) { + // 4d + // Local BTRole::Slave responder + const MgmtEvtHCILELTKReplyAckCmd& event = *static_cast<const MgmtEvtHCILELTKReplyAckCmd *>(&evt); + SMPLongTermKey smp_ltk = pairing_data.ltk_resp; + smp_ltk.enc_size = 16; // valid now; + smp_ltk.ltk = event.getLTK(); + if( smp_ltk.isValid() ) { + if( pairing_data.use_sc ) { // in !SC mode, SMP will deliver different keys! + // Secure Connections (SC) use AES sync key for both, initiator and responder. + // true == smp_ltk.isResponder() + if( ( SMPKeyType::ENC_KEY & pairing_data.keys_resp_has ) == SMPKeyType::NONE ) { // no overwrite + pairing_data.ltk_resp = smp_ltk; + pairing_data.keys_resp_has |= SMPKeyType::ENC_KEY; + if( pairing_data.use_sc && + ( SMPKeyType::ENC_KEY & pairing_data.keys_init_has ) == SMPKeyType::NONE ) // no overwrite + { + pairing_data.ltk_init = smp_ltk; + pairing_data.ltk_init.properties &= ~SMPLongTermKey::Property::RESPONDER; // enforce for SC + pairing_data.keys_init_has |= SMPKeyType::ENC_KEY; + } + check_pairing_complete = true; } - check_pairing_complete = true; } } + if( !check_pairing_complete ) { + claimed_state = pairing_data.state; // invalid smp_ltk or no overwrite + } + break; // case SMPPairingState::COMPLETED: } - if( !check_pairing_complete ) { - claimed_state = pairing_data.state; // invalid smp_ltk or no overwrite - } -#endif /* SMPHandler CONSIDER_HCI_CMD_FOR_SMP_STATE */ + } + if( MgmtEvent::Opcode::HCI_ENC_CHANGED == mgmtEvtOpcode || + MgmtEvent::Opcode::HCI_ENC_KEY_REFRESH_COMPLETE == mgmtEvtOpcode ) { + // 4a + pairing_data.encryption_enabled = true; + check_pairing_complete = true; } else if( MgmtEvent::Opcode::NEW_LONG_TERM_KEY == mgmtEvtOpcode ) { /* Legacy: 2; SC: 2 (synthetic by mgmt) */ // 4e // SMP pairing has started, mngr issued new LTK command @@ -1492,71 +1495,71 @@ HCIStatusCode BTDevice::uploadKeys() noexcept { return HCIStatusCode::CONNECTION_ALREADY_EXISTS; } const std::unique_lock<std::recursive_mutex> lock_pairing(mtx_pairing); // RAII-style acquire and relinquish via destructor -#if USE_LINUX_BT_SECURITY - BTManager & mngr = adapter.getManager(); - HCIStatusCode res = HCIStatusCode::SUCCESS; + if constexpr ( USE_LINUX_BT_SECURITY ) { + BTManager & mngr = adapter.getManager(); + HCIStatusCode res = HCIStatusCode::SUCCESS; - if( BTRole::Slave == btRole ) { - // Remote device is slave (peripheral, responder), we are master (initiator) - if( ( SMPKeyType::ENC_KEY & pairing_data.keys_init_has ) != SMPKeyType::NONE ) { - res = mngr.uploadLongTermKey(adapter.dev_id, addressAndType, pairing_data.ltk_init); - DBG_PRINT("BTDevice::uploadKeys.LTK[Remote slave, master/init]: %s", to_string(res).c_str()); - if( HCIStatusCode::SUCCESS != res ) { - return res; + if( BTRole::Slave == btRole ) { + // Remote device is slave (peripheral, responder), we are master (initiator) + if( ( SMPKeyType::ENC_KEY & pairing_data.keys_init_has ) != SMPKeyType::NONE ) { + res = mngr.uploadLongTermKey(adapter.dev_id, addressAndType, pairing_data.ltk_init); + DBG_PRINT("BTDevice::uploadKeys.LTK[Remote slave, master/init]: %s", to_string(res).c_str()); + if( HCIStatusCode::SUCCESS != res ) { + return res; + } } - } - if( ( SMPKeyType::ENC_KEY & pairing_data.keys_resp_has ) != SMPKeyType::NONE ) { - res = mngr.uploadLongTermKey(adapter.dev_id, addressAndType, pairing_data.ltk_resp); - DBG_PRINT("BTDevice::uploadKeys.LTK[Remote slave, peripheral/resp]: %s", to_string(res).c_str()); - if( HCIStatusCode::SUCCESS != res ) { - return res; + if( ( SMPKeyType::ENC_KEY & pairing_data.keys_resp_has ) != SMPKeyType::NONE ) { + res = mngr.uploadLongTermKey(adapter.dev_id, addressAndType, pairing_data.ltk_resp); + DBG_PRINT("BTDevice::uploadKeys.LTK[Remote slave, peripheral/resp]: %s", to_string(res).c_str()); + if( HCIStatusCode::SUCCESS != res ) { + return res; + } } - } - } else { - // Remote device is master (initiator), we are slave (peripheral, responder) - if( ( SMPKeyType::ENC_KEY & pairing_data.keys_resp_has ) != SMPKeyType::NONE ) { - res = mngr.uploadLongTermKey(adapter.dev_id, addressAndType, pairing_data.ltk_resp); - DBG_PRINT("BTDevice::uploadKeys.LTK[Remote master, peripheral/resp]: %s", to_string(res).c_str()); - if( HCIStatusCode::SUCCESS != res ) { - return res; + } else { + // Remote device is master (initiator), we are slave (peripheral, responder) + if( ( SMPKeyType::ENC_KEY & pairing_data.keys_resp_has ) != SMPKeyType::NONE ) { + res = mngr.uploadLongTermKey(adapter.dev_id, addressAndType, pairing_data.ltk_resp); + DBG_PRINT("BTDevice::uploadKeys.LTK[Remote master, peripheral/resp]: %s", to_string(res).c_str()); + if( HCIStatusCode::SUCCESS != res ) { + return res; + } } - } - if( ( SMPKeyType::ENC_KEY & pairing_data.keys_init_has ) != SMPKeyType::NONE ) { - res = mngr.uploadLongTermKey(adapter.dev_id, addressAndType, pairing_data.ltk_init); - DBG_PRINT("BTDevice::uploadKeys.LTK[Remote master, master/init]: %s", to_string(res).c_str()); - if( HCIStatusCode::SUCCESS != res ) { - return res; + if( ( SMPKeyType::ENC_KEY & pairing_data.keys_init_has ) != SMPKeyType::NONE ) { + res = mngr.uploadLongTermKey(adapter.dev_id, addressAndType, pairing_data.ltk_init); + DBG_PRINT("BTDevice::uploadKeys.LTK[Remote master, master/init]: %s", to_string(res).c_str()); + if( HCIStatusCode::SUCCESS != res ) { + return res; + } } } - } - if( BDAddressType::BDADDR_BREDR != addressAndType.type ) { - // Not supported - DBG_PRINT("BTDevice::uploadKeys: Upload LK for LE address not supported -> ignored: %s", toString().c_str()); - return HCIStatusCode::SUCCESS; - } + if( BDAddressType::BDADDR_BREDR != addressAndType.type ) { + // Not supported + DBG_PRINT("BTDevice::uploadKeys: Upload LK for LE address not supported -> ignored: %s", toString().c_str()); + return HCIStatusCode::SUCCESS; + } - if( BTRole::Slave == btRole ) { - // Remote device is slave (peripheral, responder), we are master (initiator) - if( ( SMPKeyType::LINK_KEY & pairing_data.keys_init_has ) != SMPKeyType::NONE ) { - res = mngr.uploadLinkKey(adapter.dev_id, addressAndType, pairing_data.lk_init); - DBG_PRINT("BTDevice::uploadKeys.LK[Remote slave]: %s", to_string(res).c_str()); + if( BTRole::Slave == btRole ) { + // Remote device is slave (peripheral, responder), we are master (initiator) + if( ( SMPKeyType::LINK_KEY & pairing_data.keys_init_has ) != SMPKeyType::NONE ) { + res = mngr.uploadLinkKey(adapter.dev_id, addressAndType, pairing_data.lk_init); + DBG_PRINT("BTDevice::uploadKeys.LK[Remote slave]: %s", to_string(res).c_str()); + } + } else { + // Remote device is master (initiator), we are slave (peripheral, responder) + if( ( SMPKeyType::LINK_KEY & pairing_data.keys_resp_has ) != SMPKeyType::NONE ) { + res = mngr.uploadLinkKey(adapter.dev_id, addressAndType, pairing_data.lk_resp); + DBG_PRINT("BTDevice::uploadKeys.LK[Remote master]: %s", to_string(res).c_str()); + } } + return res; + } else if constexpr ( SMP_SUPPORTED_BY_OS ) { + return HCIStatusCode::NOT_SUPPORTED; } else { - // Remote device is master (initiator), we are slave (peripheral, responder) - if( ( SMPKeyType::LINK_KEY & pairing_data.keys_resp_has ) != SMPKeyType::NONE ) { - res = mngr.uploadLinkKey(adapter.dev_id, addressAndType, pairing_data.lk_resp); - DBG_PRINT("BTDevice::uploadKeys.LK[Remote master]: %s", to_string(res).c_str()); - } + return HCIStatusCode::NOT_SUPPORTED; } - return res; -#elif SMP_SUPPORTED_BY_OS - return HCIStatusCode::NOT_SUPPORTED; -#else - return HCIStatusCode::NOT_SUPPORTED; -#endif } SMPLongTermKey BTDevice::getLongTermKey(const bool responder) const noexcept { @@ -1722,19 +1725,17 @@ HCIStatusCode BTDevice::setPairingPasskey(const uint32_t passkey) noexcept { { WARN_PRINT("BTDevice:mgmt:SMP: PASSKEY '%u', state %s, wrong state", passkey, to_string(pairing_data.state).c_str()); } -#if USE_LINUX_BT_SECURITY - { + if constexpr ( USE_LINUX_BT_SECURITY ) { BTManager& mngr = adapter.getManager(); MgmtStatus res = mngr.userPasskeyReply(adapter.dev_id, addressAndType, passkey); DBG_PRINT("BTDevice:mgmt:SMP: PASSKEY '%d', state %s, result %s", passkey, to_string(pairing_data.state).c_str(), to_string(res).c_str()); return HCIStatusCode::SUCCESS; + } else if constexpr ( SMP_SUPPORTED_BY_OS ) { + return HCIStatusCode::NOT_SUPPORTED; + } else { + return HCIStatusCode::NOT_SUPPORTED; } -#elif SMP_SUPPORTED_BY_OS - return HCIStatusCode::NOT_SUPPORTED; -#else - return HCIStatusCode::NOT_SUPPORTED; -#endif } HCIStatusCode BTDevice::setPairingPasskeyNegative() noexcept { @@ -1745,19 +1746,17 @@ HCIStatusCode BTDevice::setPairingPasskeyNegative() noexcept { { WARN_PRINT("BTDevice:mgmt:SMP: PASSKEY_NEGATIVE, state %s, wrong state", to_string(pairing_data.state).c_str()); } -#if USE_LINUX_BT_SECURITY - { + if constexpr ( USE_LINUX_BT_SECURITY ) { BTManager& mngr = adapter.getManager(); MgmtStatus res = mngr.userPasskeyNegativeReply(adapter.dev_id, addressAndType); DBG_PRINT("BTDevice:mgmt:SMP: PASSKEY NEGATIVE, state %s, result %s", to_string(pairing_data.state).c_str(), to_string(res).c_str()); return HCIStatusCode::SUCCESS; + } else if constexpr ( SMP_SUPPORTED_BY_OS ) { + return HCIStatusCode::NOT_SUPPORTED; + } else { + return HCIStatusCode::NOT_SUPPORTED; } -#elif SMP_SUPPORTED_BY_OS - return HCIStatusCode::NOT_SUPPORTED; -#else - return HCIStatusCode::NOT_SUPPORTED; -#endif } HCIStatusCode BTDevice::setPairingNumericComparison(const bool positive) noexcept { @@ -1768,19 +1767,17 @@ HCIStatusCode BTDevice::setPairingNumericComparison(const bool positive) noexcep { WARN_PRINT("BTDevice:mgmt:SMP: CONFIRM '%d', state %s, wrong state", positive, to_string(pairing_data.state).c_str()); } -#if USE_LINUX_BT_SECURITY - { + if constexpr ( USE_LINUX_BT_SECURITY ) { BTManager& mngr = adapter.getManager(); MgmtStatus res = mngr.userConfirmReply(adapter.dev_id, addressAndType, positive); DBG_PRINT("BTDevice:mgmt:SMP: CONFIRM '%d', state %s, result %s", positive, to_string(pairing_data.state).c_str(), to_string(res).c_str()); return HCIStatusCode::SUCCESS; + } else if constexpr ( SMP_SUPPORTED_BY_OS ) { + return HCIStatusCode::NOT_SUPPORTED; + } else { + return HCIStatusCode::NOT_SUPPORTED; } -#elif SMP_SUPPORTED_BY_OS - return HCIStatusCode::NOT_SUPPORTED; -#else - return HCIStatusCode::NOT_SUPPORTED; -#endif } PairingMode BTDevice::getPairingMode() const noexcept { @@ -1841,58 +1838,58 @@ void BTDevice::clearSMPStates(const bool connected) noexcept { } void BTDevice::disconnectSMP(const int caller) noexcept { - #if SMP_SUPPORTED_BY_OS - const std::lock_guard<std::recursive_mutex> lock_conn(mtx_smpHandler); - if( nullptr != smpHandler ) { - DBG_PRINT("BTDevice::disconnectSMP: start (has smpHandler, caller %d)", caller); - smpHandler->disconnect(false /* disconnectDevice */, false /* ioErrorCause */); + if constexpr ( SMP_SUPPORTED_BY_OS ) { + const std::lock_guard<std::recursive_mutex> lock_conn(mtx_smpHandler); + if( nullptr != smpHandler ) { + DBG_PRINT("BTDevice::disconnectSMP: start (has smpHandler, caller %d)", caller); + smpHandler->disconnect(false /* disconnectDevice */, false /* ioErrorCause */); + } else { + DBG_PRINT("BTDevice::disconnectSMP: start (nil smpHandler, caller %d)", caller); + } + smpHandler = nullptr; + DBG_PRINT("BTDevice::disconnectSMP: end"); } else { - DBG_PRINT("BTDevice::disconnectSMP: start (nil smpHandler, caller %d)", caller); + (void)caller; } - smpHandler = nullptr; - DBG_PRINT("BTDevice::disconnectSMP: end"); - #else - (void)caller; - #endif } bool BTDevice::connectSMP(std::shared_ptr<BTDevice> sthis, const BTSecurityLevel sec_level) noexcept { - #if SMP_SUPPORTED_BY_OS - if( !isConnected || !allowDisconnect) { - ERR_PRINT("connectSMP(%u): Device not connected: %s", sec_level, toString().c_str()); - return false; - } + if constexpr ( SMP_SUPPORTED_BY_OS ) { + if( !isConnected || !allowDisconnect) { + ERR_PRINT("connectSMP(%u): Device not connected: %s", sec_level, toString().c_str()); + return false; + } - if( !SMPHandler::IS_SUPPORTED_BY_OS ) { - DBG_PRINT("BTDevice::connectSMP(%u): SMP Not supported by OS (1): %s", sec_level, toString().c_str()); - return false; - } + if( !SMPHandler::IS_SUPPORTED_BY_OS ) { + DBG_PRINT("BTDevice::connectSMP(%u): SMP Not supported by OS (1): %s", sec_level, toString().c_str()); + return false; + } - if( BTSecurityLevel::NONE >= sec_level ) { - return false; - } + if( BTSecurityLevel::NONE >= sec_level ) { + return false; + } - const std::lock_guard<std::recursive_mutex> lock_conn(mtx_gattHandler); - if( nullptr != smpHandler ) { - if( smpHandler->isConnected() ) { - return smpHandler->establishSecurity(sec_level); + const std::lock_guard<std::recursive_mutex> lock_conn(mtx_gattHandler); + if( nullptr != smpHandler ) { + if( smpHandler->isConnected() ) { + return smpHandler->establishSecurity(sec_level); + } + smpHandler = nullptr; } - smpHandler = nullptr; - } - smpHandler = std::make_shared<SMPHandler>(sthis); - if( !smpHandler->isConnected() ) { - ERR_PRINT("Connection failed"); - smpHandler = nullptr; + smpHandler = std::make_shared<SMPHandler>(sthis); + if( !smpHandler->isConnected() ) { + ERR_PRINT("Connection failed"); + smpHandler = nullptr; + return false; + } + return smpHandler->establishSecurity(sec_level); + } else { + DBG_PRINT("BTDevice::connectSMP: SMP Not supported by OS (0): %s", toString().c_str()); + (void)sthis; + (void)sec_level; return false; } - return smpHandler->establishSecurity(sec_level); - #else - DBG_PRINT("BTDevice::connectSMP: SMP Not supported by OS (0): %s", toString().c_str()); - (void)sthis; - (void)sec_level; - return false; - #endif } void BTDevice::disconnectGATT(const int caller) noexcept { @@ -2255,18 +2252,18 @@ exit: } HCIStatusCode BTDevice::unpair() noexcept { -#if USE_LINUX_BT_SECURITY - const HCIStatusCode res = adapter.getManager().unpairDevice(adapter.dev_id, addressAndType, false /* disconnect */); - if( HCIStatusCode::SUCCESS != res && HCIStatusCode::NOT_PAIRED != res ) { - DBG_PRINT("BTDevice::unpair(): Unpair device failed: %s, %s", to_string(res).c_str(), toString().c_str()); + if constexpr ( USE_LINUX_BT_SECURITY ) { + const HCIStatusCode res = adapter.getManager().unpairDevice(adapter.dev_id, addressAndType, false /* disconnect */); + if( HCIStatusCode::SUCCESS != res && HCIStatusCode::NOT_PAIRED != res ) { + DBG_PRINT("BTDevice::unpair(): Unpair device failed: %s, %s", to_string(res).c_str(), toString().c_str()); + } + clearSMPStates(getConnected() /* connected */); + return res; + } else if constexpr ( SMP_SUPPORTED_BY_OS ) { + return HCIStatusCode::NOT_SUPPORTED; + } else { + return HCIStatusCode::NOT_SUPPORTED; } - clearSMPStates(getConnected() /* connected */); - return res; -#elif SMP_SUPPORTED_BY_OS - return HCIStatusCode::NOT_SUPPORTED; -#else - return HCIStatusCode::NOT_SUPPORTED; -#endif } void BTDevice::remove() noexcept { diff --git a/src/direct_bt/BTManager.cpp b/src/direct_bt/BTManager.cpp index ab91c886..e92b8f38 100644 --- a/src/direct_bt/BTManager.cpp +++ b/src/direct_bt/BTManager.cpp @@ -224,11 +224,9 @@ HCIStatusCode BTManager::initializeAdapter(AdapterInfo& adapterInfo, const uint1 * * See SMPTypes.cpp: getPairingMode(const bool le_sc_pairing, const SMPIOCapability ioCap_init, const SMPIOCapability ioCap_resp) noexcept */ -#if USE_LINUX_BT_SECURITY - const uint8_t debug_keys = 0; - const uint8_t ssp_on_param = 0x01; // SET_SSP 0x00 disabled, 0x01 enable Secure Simple Pairing. SSP only available for BREDR >= 2.1 not single-mode LE. - const uint8_t sc_on_param = 0x01; // SET_SECURE_CONN 0x00 disabled, 0x01 enables SC mixed, 0x02 enables SC only mode -#endif + constexpr const uint8_t debug_keys = 0; + constexpr const uint8_t ssp_on_param = 0x01; // SET_SSP 0x00 disabled, 0x01 enable Secure Simple Pairing. SSP only available for BREDR >= 2.1 not single-mode LE. + constexpr const uint8_t sc_on_param = 0x01; // SET_SECURE_CONN 0x00 disabled, 0x01 enables SC mixed, 0x02 enables SC only mode AdapterSetting current_settings; MgmtCommand req0(MgmtCommand::Opcode::READ_INFO, dev_id); @@ -257,42 +255,42 @@ HCIStatusCode BTManager::initializeAdapter(AdapterInfo& adapterInfo, const uint1 setMode(dev_id, MgmtCommand::Opcode::SET_BREDR, 1, current_settings); setDiscoverable(dev_id, 0, 0, current_settings); setMode(dev_id, MgmtCommand::Opcode::SET_LE, 1, current_settings); -#if USE_LINUX_BT_SECURITY - setMode(dev_id, MgmtCommand::Opcode::SET_SECURE_CONN, sc_on_param, current_settings); - setMode(dev_id, MgmtCommand::Opcode::SET_SSP, ssp_on_param, current_settings); -#endif + if constexpr ( USE_LINUX_BT_SECURITY ) { + setMode(dev_id, MgmtCommand::Opcode::SET_SECURE_CONN, sc_on_param, current_settings); + setMode(dev_id, MgmtCommand::Opcode::SET_SSP, ssp_on_param, current_settings); + } break; case BTMode::BREDR: setMode(dev_id, MgmtCommand::Opcode::SET_BREDR, 1, current_settings); setDiscoverable(dev_id, 0, 0, current_settings); setMode(dev_id, MgmtCommand::Opcode::SET_LE, 0, current_settings); -#if USE_LINUX_BT_SECURITY - setMode(dev_id, MgmtCommand::Opcode::SET_SECURE_CONN, 0, current_settings); - setMode(dev_id, MgmtCommand::Opcode::SET_SSP, ssp_on_param, current_settings); -#endif + if constexpr ( USE_LINUX_BT_SECURITY ) { + setMode(dev_id, MgmtCommand::Opcode::SET_SECURE_CONN, 0, current_settings); + setMode(dev_id, MgmtCommand::Opcode::SET_SSP, ssp_on_param, current_settings); + } break; case BTMode::NONE: [[fallthrough]]; // map NONE -> LE case BTMode::LE: setMode(dev_id, MgmtCommand::Opcode::SET_BREDR, 0, current_settings); setMode(dev_id, MgmtCommand::Opcode::SET_LE, 1, current_settings); -#if USE_LINUX_BT_SECURITY - setMode(dev_id, MgmtCommand::Opcode::SET_SECURE_CONN, sc_on_param, current_settings); - setMode(dev_id, MgmtCommand::Opcode::SET_SSP, 0, current_settings); // SSP not available in LE single mode -#endif + if constexpr ( USE_LINUX_BT_SECURITY ) { + setMode(dev_id, MgmtCommand::Opcode::SET_SECURE_CONN, sc_on_param, current_settings); + setMode(dev_id, MgmtCommand::Opcode::SET_SSP, 0, current_settings); // SSP not available in LE single mode + } break; } -#if USE_LINUX_BT_SECURITY - setMode(dev_id, MgmtCommand::Opcode::SET_DEBUG_KEYS, debug_keys, current_settings); - setMode(dev_id, MgmtCommand::Opcode::SET_IO_CAPABILITY, direct_bt::number(BTManager::defaultIOCapability), current_settings); - setMode(dev_id, MgmtCommand::Opcode::SET_BONDABLE, 1, current_settings); // required for pairing -#else - setMode(dev_id, MgmtCommand::Opcode::SET_SECURE_CONN, 0, current_settings); - setMode(dev_id, MgmtCommand::Opcode::SET_SSP, 0, current_settings); - setMode(dev_id, MgmtCommand::Opcode::SET_DEBUG_KEYS, 0, current_settings); - setMode(dev_id, MgmtCommand::Opcode::SET_BONDABLE, 0, current_settings); -#endif + if constexpr ( USE_LINUX_BT_SECURITY ) { + setMode(dev_id, MgmtCommand::Opcode::SET_DEBUG_KEYS, debug_keys, current_settings); + setMode(dev_id, MgmtCommand::Opcode::SET_IO_CAPABILITY, direct_bt::number(BTManager::defaultIOCapability), current_settings); + setMode(dev_id, MgmtCommand::Opcode::SET_BONDABLE, 1, current_settings); // required for pairing + } else { + setMode(dev_id, MgmtCommand::Opcode::SET_SECURE_CONN, 0, current_settings); + setMode(dev_id, MgmtCommand::Opcode::SET_SSP, 0, current_settings); + setMode(dev_id, MgmtCommand::Opcode::SET_DEBUG_KEYS, 0, current_settings); + setMode(dev_id, MgmtCommand::Opcode::SET_BONDABLE, 0, current_settings); + } #if 0 if( BTRole::Slave == btRole ) { @@ -627,23 +625,23 @@ bool BTManager::removeAdapter(BTAdapter* adapter) noexcept { bool BTManager::setIOCapability(const uint16_t dev_id, const SMPIOCapability io_cap, SMPIOCapability& pre_io_cap) noexcept { if( SMPIOCapability::UNSET != io_cap ) { -#if USE_LINUX_BT_SECURITY - typename adapters_t::const_iterator it = adapters.cbegin(); - for (; !it.is_end(); ++it) { - if( (*it)->dev_id == dev_id ) { - const typename adapters_t::difference_type index = it.dist_begin(); - const SMPIOCapability o = adapterIOCapability.at(index); - AdapterSetting current_settings { AdapterSetting::NONE }; // throw away return value, unchanged on SET_IO_CAPABILITY - if( setMode(dev_id, MgmtCommand::Opcode::SET_IO_CAPABILITY, direct_bt::number(io_cap), current_settings) ) { - adapterIOCapability.at(index) = io_cap; - pre_io_cap = o; - return true; - } else { - return false; + if constexpr ( USE_LINUX_BT_SECURITY ) { + typename adapters_t::const_iterator it = adapters.cbegin(); + for (; !it.is_end(); ++it) { + if( (*it)->dev_id == dev_id ) { + const typename adapters_t::difference_type index = it.dist_begin(); + const SMPIOCapability o = adapterIOCapability.at(index); + AdapterSetting current_settings { AdapterSetting::NONE }; // throw away return value, unchanged on SET_IO_CAPABILITY + if( setMode(dev_id, MgmtCommand::Opcode::SET_IO_CAPABILITY, direct_bt::number(io_cap), current_settings) ) { + adapterIOCapability.at(index) = io_cap; + pre_io_cap = o; + return true; + } else { + return false; + } } } } -#endif } return false; } @@ -754,169 +752,170 @@ bool BTManager::uploadConnParam(const uint16_t dev_id, const BDAddressAndType & } bool BTManager::isValidLongTermKeyAddressAndType(const EUI48 &address, const BDAddressType &address_type) const noexcept { -#if USE_LINUX_BT_SECURITY - // Linux Kernel `load_long_term_keys(..)` (mgmt.c) require either `BDAddressType::BDADDR_LE_PUBLIC` or - // `BDAddressType::BDADDR_LE_RANDOM` and `BLERandomAddressType::STATIC_PUBLIC` - // in ltk_is_valid(..) (mgmt.c). - if( BDAddressType::BDADDR_LE_PUBLIC == address_type ) { - return true; - } else if( BDAddressType::BDADDR_LE_RANDOM == address_type && - BLERandomAddressType::STATIC_PUBLIC == BDAddressAndType::getBLERandomAddressType(address, address_type) ) { - return true; + if constexpr ( USE_LINUX_BT_SECURITY ) { + // Linux Kernel `load_long_term_keys(..)` (mgmt.c) require either `BDAddressType::BDADDR_LE_PUBLIC` or + // `BDAddressType::BDADDR_LE_RANDOM` and `BLERandomAddressType::STATIC_PUBLIC` + // in ltk_is_valid(..) (mgmt.c). + if( BDAddressType::BDADDR_LE_PUBLIC == address_type ) { + return true; + } else if( BDAddressType::BDADDR_LE_RANDOM == address_type && + BLERandomAddressType::STATIC_PUBLIC == BDAddressAndType::getBLERandomAddressType(address, address_type) ) { + return true; + } else { + return false; + } } else { - return false; + return true; } -#else - return true; -#endif } HCIStatusCode BTManager::uploadLongTermKey(const uint16_t dev_id, const MgmtLongTermKeyInfo &key) noexcept { -#if USE_LINUX_BT_SECURITY - const bool is_valid_ltk_addr = isValidLongTermKeyAddressAndType(key.address, key.address_type); - MgmtLoadLongTermKeyCmd req(dev_id, key); - HCIStatusCode res; - std::unique_ptr<MgmtEvent> reply = sendWithReply(req); - if( nullptr != reply ) { - if( reply->getOpcode() == MgmtEvent::Opcode::CMD_COMPLETE ) { - res = to_HCIStatusCode( static_cast<const MgmtEvtCmdComplete *>(reply.get())->getStatus() ); - } else if( reply->getOpcode() == MgmtEvent::Opcode::CMD_STATUS ) { - res = to_HCIStatusCode( static_cast<const MgmtEvtCmdStatus *>(reply.get())->getStatus() ); + if constexpr ( USE_LINUX_BT_SECURITY ) { + const bool is_valid_ltk_addr = isValidLongTermKeyAddressAndType(key.address, key.address_type); + MgmtLoadLongTermKeyCmd req(dev_id, key); + HCIStatusCode res; + std::unique_ptr<MgmtEvent> reply = sendWithReply(req); + if( nullptr != reply ) { + if( reply->getOpcode() == MgmtEvent::Opcode::CMD_COMPLETE ) { + res = to_HCIStatusCode( static_cast<const MgmtEvtCmdComplete *>(reply.get())->getStatus() ); + } else if( reply->getOpcode() == MgmtEvent::Opcode::CMD_STATUS ) { + res = to_HCIStatusCode( static_cast<const MgmtEvtCmdStatus *>(reply.get())->getStatus() ); + } else { + res = HCIStatusCode::UNKNOWN_HCI_COMMAND; + } } else { - res = HCIStatusCode::UNKNOWN_HCI_COMMAND; + res = HCIStatusCode::TIMEOUT; } + if( HCIStatusCode::SUCCESS != res ) { + WARN_PRINT("(dev_id %d): %s (valid_ltk_addr %d), result %s", dev_id, + req.toString().c_str(), is_valid_ltk_addr, to_string(res).c_str()); + } else { + DBG_PRINT("BTManager::uploadLongTermKeyInfo(dev_id %d): %s (valid_ltk_addr %d), result %s", dev_id, + req.toString().c_str(), is_valid_ltk_addr, to_string(res).c_str()); + } + return res; } else { - res = HCIStatusCode::TIMEOUT; - } - if( HCIStatusCode::SUCCESS != res ) { - WARN_PRINT("(dev_id %d): %s (valid_ltk_addr %d), result %s", dev_id, - req.toString().c_str(), is_valid_ltk_addr, to_string(res).c_str()); - } else { - DBG_PRINT("BTManager::uploadLongTermKeyInfo(dev_id %d): %s (valid_ltk_addr %d), result %s", dev_id, - req.toString().c_str(), is_valid_ltk_addr, to_string(res).c_str()); + return HCIStatusCode::NOT_SUPPORTED; } - return res; -#else - return HCIStatusCode::NOT_SUPPORTED; -#endif } HCIStatusCode BTManager::uploadLongTermKey(const uint16_t dev_id, const BDAddressAndType & addressAndType, - const SMPLongTermKey& ltk) noexcept { -#if USE_LINUX_BT_SECURITY - const MgmtLTKType key_type = to_MgmtLTKType(ltk.properties); - const MgmtLongTermKeyInfo mgmt_ltk_info { addressAndType.address, addressAndType.type, key_type, - ltk.isResponder(), ltk.enc_size, ltk.ediv, ltk.rand, ltk.ltk }; - return uploadLongTermKey(dev_id, mgmt_ltk_info); -#else - return HCIStatusCode::NOT_SUPPORTED; -#endif + const SMPLongTermKey& ltk) noexcept +{ + if constexpr ( USE_LINUX_BT_SECURITY ) { + const MgmtLTKType key_type = to_MgmtLTKType(ltk.properties); + const MgmtLongTermKeyInfo mgmt_ltk_info { addressAndType.address, addressAndType.type, key_type, + ltk.isResponder(), ltk.enc_size, ltk.ediv, ltk.rand, ltk.ltk }; + return uploadLongTermKey(dev_id, mgmt_ltk_info); + } else { + return HCIStatusCode::NOT_SUPPORTED; + } } HCIStatusCode BTManager::uploadLinkKey(const uint16_t dev_id, const MgmtLinkKeyInfo &key) noexcept { -#if USE_LINUX_BT_SECURITY - MgmtLoadLinkKeyCmd req(dev_id, false /* debug_keys */, key); - HCIStatusCode res; - std::unique_ptr<MgmtEvent> reply = sendWithReply(req); - if( nullptr != reply ) { - if( reply->getOpcode() == MgmtEvent::Opcode::CMD_COMPLETE ) { - res = to_HCIStatusCode( static_cast<const MgmtEvtCmdComplete *>(reply.get())->getStatus() ); - } else if( reply->getOpcode() == MgmtEvent::Opcode::CMD_STATUS ) { - res = to_HCIStatusCode( static_cast<const MgmtEvtCmdStatus *>(reply.get())->getStatus() ); + if constexpr ( USE_LINUX_BT_SECURITY ) { + MgmtLoadLinkKeyCmd req(dev_id, false /* debug_keys */, key); + HCIStatusCode res; + std::unique_ptr<MgmtEvent> reply = sendWithReply(req); + if( nullptr != reply ) { + if( reply->getOpcode() == MgmtEvent::Opcode::CMD_COMPLETE ) { + res = to_HCIStatusCode( static_cast<const MgmtEvtCmdComplete *>(reply.get())->getStatus() ); + } else if( reply->getOpcode() == MgmtEvent::Opcode::CMD_STATUS ) { + res = to_HCIStatusCode( static_cast<const MgmtEvtCmdStatus *>(reply.get())->getStatus() ); + } else { + res = HCIStatusCode::UNKNOWN_HCI_COMMAND; + } } else { - res = HCIStatusCode::UNKNOWN_HCI_COMMAND; + res = HCIStatusCode::TIMEOUT; } + if( HCIStatusCode::SUCCESS != res ) { + WARN_PRINT("(dev_id %d): %s, result %s", dev_id, + req.toString().c_str(), to_string(res).c_str()); + } else { + DBG_PRINT("BTManager::uploadLinkKeyInfo(dev_id %d): %s, result %s", dev_id, + req.toString().c_str(), to_string(res).c_str()); + } + return res; } else { - res = HCIStatusCode::TIMEOUT; - } - if( HCIStatusCode::SUCCESS != res ) { - WARN_PRINT("(dev_id %d): %s, result %s", dev_id, - req.toString().c_str(), to_string(res).c_str()); - } else { - DBG_PRINT("BTManager::uploadLinkKeyInfo(dev_id %d): %s, result %s", dev_id, - req.toString().c_str(), to_string(res).c_str()); + return HCIStatusCode::NOT_SUPPORTED; } - return res; -#else - return HCIStatusCode::NOT_SUPPORTED; -#endif } HCIStatusCode BTManager::uploadLinkKey(const uint16_t dev_id, const BDAddressAndType & addressAndType, const SMPLinkKey& lk) noexcept { -#if USE_LINUX_BT_SECURITY - const MgmtLinkKeyInfo mgmt_lk_info { addressAndType.address, addressAndType.type, static_cast<MgmtLinkKeyType>(lk.type), - lk.key, lk.pin_length }; - return uploadLinkKey(dev_id, mgmt_lk_info); -#else - return HCIStatusCode::NOT_SUPPORTED; -#endif + if constexpr ( USE_LINUX_BT_SECURITY ) { + const MgmtLinkKeyInfo mgmt_lk_info { addressAndType.address, addressAndType.type, static_cast<MgmtLinkKeyType>(lk.type), + lk.key, lk.pin_length }; + return uploadLinkKey(dev_id, mgmt_lk_info); + } else { + return HCIStatusCode::NOT_SUPPORTED; + } } MgmtStatus BTManager::userPasskeyReply(const uint16_t dev_id, const BDAddressAndType & addressAndType, const uint32_t passkey) noexcept { -#if USE_LINUX_BT_SECURITY - MgmtUserPasskeyReplyCmd cmd(dev_id, addressAndType, passkey); - std::unique_ptr<MgmtEvent> res = sendWithReply(cmd); - if( nullptr != res && res->getOpcode() == MgmtEvent::Opcode::CMD_COMPLETE ) { - const MgmtEvtCmdComplete &res1 = *static_cast<const MgmtEvtCmdComplete *>(res.get()); - // FIXME: Analyze address + addressType result? - return res1.getStatus(); + if constexpr ( USE_LINUX_BT_SECURITY ) { + MgmtUserPasskeyReplyCmd cmd(dev_id, addressAndType, passkey); + std::unique_ptr<MgmtEvent> res = sendWithReply(cmd); + if( nullptr != res && res->getOpcode() == MgmtEvent::Opcode::CMD_COMPLETE ) { + const MgmtEvtCmdComplete &res1 = *static_cast<const MgmtEvtCmdComplete *>(res.get()); + // FIXME: Analyze address + addressType result? + return res1.getStatus(); + } + return MgmtStatus::TIMEOUT; + } else { + return MgmtStatus::NOT_SUPPORTED; } - return MgmtStatus::TIMEOUT; -#else - return MgmtStatus::NOT_SUPPORTED; -#endif } MgmtStatus BTManager::userPasskeyNegativeReply(const uint16_t dev_id, const BDAddressAndType & addressAndType) noexcept { -#if USE_LINUX_BT_SECURITY - MgmtUserPasskeyNegativeReplyCmd cmd(dev_id, addressAndType); - std::unique_ptr<MgmtEvent> res = sendWithReply(cmd); - if( nullptr != res && res->getOpcode() == MgmtEvent::Opcode::CMD_COMPLETE ) { - const MgmtEvtCmdComplete &res1 = *static_cast<const MgmtEvtCmdComplete *>(res.get()); - // FIXME: Analyze address + addressType result? - return res1.getStatus(); + if constexpr ( USE_LINUX_BT_SECURITY ) { + MgmtUserPasskeyNegativeReplyCmd cmd(dev_id, addressAndType); + std::unique_ptr<MgmtEvent> res = sendWithReply(cmd); + if( nullptr != res && res->getOpcode() == MgmtEvent::Opcode::CMD_COMPLETE ) { + const MgmtEvtCmdComplete &res1 = *static_cast<const MgmtEvtCmdComplete *>(res.get()); + // FIXME: Analyze address + addressType result? + return res1.getStatus(); + } + return MgmtStatus::TIMEOUT; + } else { + return MgmtStatus::NOT_SUPPORTED; } - return MgmtStatus::TIMEOUT; -#else - return MgmtStatus::NOT_SUPPORTED; -#endif } MgmtStatus BTManager::userConfirmReply(const uint16_t dev_id, const BDAddressAndType & addressAndType, const bool positive) noexcept { -#if USE_LINUX_BT_SECURITY - std::unique_ptr<MgmtEvent> res; - if( positive ) { - MgmtUserConfirmReplyCmd cmd(dev_id, addressAndType); - res = sendWithReply(cmd); + if constexpr ( USE_LINUX_BT_SECURITY ) { + std::unique_ptr<MgmtEvent> res; + if( positive ) { + MgmtUserConfirmReplyCmd cmd(dev_id, addressAndType); + res = sendWithReply(cmd); + } else { + MgmtUserConfirmNegativeReplyCmd cmd(dev_id, addressAndType); + res = sendWithReply(cmd); + } + if( nullptr != res && res->getOpcode() == MgmtEvent::Opcode::CMD_COMPLETE ) { + const MgmtEvtCmdComplete &res1 = *static_cast<const MgmtEvtCmdComplete *>(res.get()); + // FIXME: Analyze address + addressType result? + return res1.getStatus(); + } + return MgmtStatus::TIMEOUT; } else { - MgmtUserConfirmNegativeReplyCmd cmd(dev_id, addressAndType); - res = sendWithReply(cmd); + return MgmtStatus::NOT_SUPPORTED; } - if( nullptr != res && res->getOpcode() == MgmtEvent::Opcode::CMD_COMPLETE ) { - const MgmtEvtCmdComplete &res1 = *static_cast<const MgmtEvtCmdComplete *>(res.get()); - // FIXME: Analyze address + addressType result? - return res1.getStatus(); - } - return MgmtStatus::TIMEOUT; -#else - return MgmtStatus::NOT_SUPPORTED; -#endif } HCIStatusCode BTManager::unpairDevice(const uint16_t dev_id, const BDAddressAndType & addressAndType, const bool disconnect) noexcept { -#if USE_LINUX_BT_SECURITY - MgmtUnpairDeviceCmd cmd(dev_id, addressAndType, disconnect); - std::unique_ptr<MgmtEvent> res = sendWithReply(cmd); - - if( nullptr != res && res->getOpcode() == MgmtEvent::Opcode::CMD_COMPLETE ) { - const MgmtEvtCmdComplete &res1 = *static_cast<const MgmtEvtCmdComplete *>(res.get()); - // FIXME: Analyze address + addressType result? - return to_HCIStatusCode( res1.getStatus() ); + if constexpr ( USE_LINUX_BT_SECURITY ) { + MgmtUnpairDeviceCmd cmd(dev_id, addressAndType, disconnect); + std::unique_ptr<MgmtEvent> res = sendWithReply(cmd); + + if( nullptr != res && res->getOpcode() == MgmtEvent::Opcode::CMD_COMPLETE ) { + const MgmtEvtCmdComplete &res1 = *static_cast<const MgmtEvtCmdComplete *>(res.get()); + // FIXME: Analyze address + addressType result? + return to_HCIStatusCode( res1.getStatus() ); + } + return HCIStatusCode::TIMEOUT; + } else { + return HCIStatusCode::NOT_SUPPORTED; } - return HCIStatusCode::TIMEOUT; -#else - return HCIStatusCode::NOT_SUPPORTED; -#endif } bool BTManager::isDeviceWhitelisted(const uint16_t dev_id, const BDAddressAndType & addressAndType) noexcept { diff --git a/src/direct_bt/HCIHandler.cpp b/src/direct_bt/HCIHandler.cpp index 84d294ca..ae925aa4 100644 --- a/src/direct_bt/HCIHandler.cpp +++ b/src/direct_bt/HCIHandler.cpp @@ -720,10 +720,10 @@ HCIHandler::HCIHandler(const uint16_t dev_id_, const BTMode btMode_) noexcept } #endif HCIComm::filter_clear(&filter_mask); -#if CONSIDER_HCI_CMD_FOR_SMP_STATE - // Currently only used to determine ENCRYPTION STATE, if at all. - HCIComm::filter_set_ptype(number(HCIPacketType::COMMAND), &filter_mask); // COMMANDs -#endif + if constexpr ( CONSIDER_HCI_CMD_FOR_SMP_STATE ) { + // Currently only used to determine ENCRYPTION STATE, if at all. + HCIComm::filter_set_ptype(number(HCIPacketType::COMMAND), &filter_mask); // COMMANDs + } HCIComm::filter_set_ptype(number(HCIPacketType::EVENT), &filter_mask); // EVENTs HCIComm::filter_set_ptype(number(HCIPacketType::ACLDATA), &filter_mask); // SMP via ACL DATA diff --git a/src/direct_bt/SMPHandler.cpp b/src/direct_bt/SMPHandler.cpp index 50ba1a30..5919cd6e 100644 --- a/src/direct_bt/SMPHandler.cpp +++ b/src/direct_bt/SMPHandler.cpp @@ -67,11 +67,7 @@ SMPEnv::SMPEnv() noexcept { } -#if SMP_SUPPORTED_BY_OS - bool SMPHandler::IS_SUPPORTED_BY_OS = true; -#else - bool SMPHandler::IS_SUPPORTED_BY_OS = false; -#endif +bool SMPHandler::IS_SUPPORTED_BY_OS = SMP_SUPPORTED_BY_OS ? true : false; std::shared_ptr<BTDevice> SMPHandler::getDeviceChecked() const { std::shared_ptr<BTDevice> ref = wbr_device.lock(); |