diff options
Diffstat (limited to 'src/direct_bt')
-rw-r--r-- | src/direct_bt/BTTypes.cpp | 11 | ||||
-rw-r--r-- | src/direct_bt/DBTDevice.cpp | 44 | ||||
-rw-r--r-- | src/direct_bt/L2CAPComm.cpp | 12 | ||||
-rw-r--r-- | src/direct_bt/SMPHandler.cpp | 2 |
4 files changed, 48 insertions, 21 deletions
diff --git a/src/direct_bt/BTTypes.cpp b/src/direct_bt/BTTypes.cpp index 886bf37e..79a52591 100644 --- a/src/direct_bt/BTTypes.cpp +++ b/src/direct_bt/BTTypes.cpp @@ -218,6 +218,17 @@ BTMode direct_bt::getBTMode(const std::string & value) noexcept { return BTMode::NONE; } +std::string direct_bt::getBTSecurityLevelString(const BTSecurityLevel v) noexcept { + switch(v) { + case BTSecurityLevel::UNSET: return "UNSET"; + case BTSecurityLevel::NONE: return "NONE"; + case BTSecurityLevel::ENC_ONLY: return "ENC_ONLY"; + case BTSecurityLevel::ENC_AUTH: return "ENC_AUTH"; + case BTSecurityLevel::ENC_AUTH_FIPS: return "ENC_AUTH_FIPS"; + } + return "Unknown BTSecurityLevel"; +} + std::string direct_bt::getPairingModeString(const PairingMode v) noexcept { switch(v) { case PairingMode::NONE: return "NONE"; diff --git a/src/direct_bt/DBTDevice.cpp b/src/direct_bt/DBTDevice.cpp index 7dd6d999..f68512ca 100644 --- a/src/direct_bt/DBTDevice.cpp +++ b/src/direct_bt/DBTDevice.cpp @@ -414,13 +414,18 @@ void DBTDevice::processL2CAPSetup(std::shared_ptr<DBTDevice> sthis) { DBG_PRINT("DBTDevice::processL2CAPSetup: %s", toString().c_str()); if( isLEAddressType() && !l2cap_att.isOpen() ) { const bool responderLikesEncryption = pairing_data.res_requested_sec || isLEFeaturesBitSet(le_features, LEFeatures::LE_Encryption); - uint8_t sec_level; - if( responderLikesEncryption && adapter.hasSecureConnections() ) { - sec_level = BT_SECURITY_FIPS; // 4 - } else if( responderLikesEncryption ) { - sec_level = BT_SECURITY_HIGH; // 3 + const BTSecurityLevel sec_level_user = pairing_data.sec_level_user; + BTSecurityLevel sec_level = pairing_data.sec_level; + if( BTSecurityLevel::UNSET != sec_level_user ) { + sec_level = sec_level_user; } else { - sec_level = 0; + if( responderLikesEncryption && adapter.hasSecureConnections() ) { + sec_level = BTSecurityLevel::ENC_AUTH_FIPS; + } else if( responderLikesEncryption ) { + sec_level = BTSecurityLevel::ENC_AUTH; + } else { + sec_level = BTSecurityLevel::NONE; + } } const bool l2cap_open = l2cap_att.open(*this); const bool l2cap_sec = l2cap_open && l2cap_att.setBTSecurityLevel(sec_level); // initiates hciSMPMsgCallback() if sec_level > BT_SECURITY_LOW @@ -429,13 +434,16 @@ void DBTDevice::processL2CAPSetup(std::shared_ptr<DBTDevice> sthis) { #else const bool smp_sec = false; #endif - DBG_PRINT("DBTDevice::processL2CAPSetup: sec_level %u, connect[SMP %d, l2cap[open %d, sec %d]], %s", - sec_level, smp_sec, l2cap_open, l2cap_sec, toString().c_str()); + DBG_PRINT("DBTDevice::processL2CAPSetup: sec_level %s, connect[smp %d, l2cap[open %d, sec %d]], %s", + getBTSecurityLevelString(sec_level).c_str(), smp_sec, l2cap_open, l2cap_sec, toString().c_str()); if( !l2cap_open ) { disconnect(HCIStatusCode::INTERNAL_FAILURE); } else if( !l2cap_sec && !smp_sec ) { // No security and hence no SMP dialogue, i.e. hciSMPMsgCallback(): + pairing_data.sec_level = BTSecurityLevel::NONE; processDeviceReady(sthis, jau::getCurrentMilliseconds()); + } else { + pairing_data.sec_level = sec_level; } } } @@ -496,11 +504,18 @@ void DBTDevice::hciSMPMsgCallback(std::shared_ptr<DBTDevice> sthis, std::shared_ pairing_data.res_requested_sec = false; // After a failed encryption/authentication, we try without security! - bool res_l2cap_close = l2cap_att.close(); - bool res_l2cap_open = l2cap_att.open(*this); - DBG_PRINT("DBTDevice:hci:SMP: l2cap ATT reopen: close %d, open %d", res_l2cap_close, res_l2cap_open); + BTSecurityLevel sec_level = pairing_data.sec_level; + if( BTSecurityLevel::NONE < sec_level ) { + sec_level = BTSecurityLevel::NONE; + pairing_data.sec_level = sec_level; + } + const bool l2cap_close = l2cap_att.close(); + const bool l2cap_open = l2cap_att.open(*this); + is_device_ready = l2cap_open; + + DBG_PRINT("DBTDevice:hci:SMP: l2cap ATT reopen: ready %d, sec_level %s, l2cap[close %d, open %d], %s", + is_device_ready, getBTSecurityLevelString(sec_level).c_str(), l2cap_close, l2cap_open, toString().c_str()); - is_device_ready = res_l2cap_open; } break; case SMPPDUMsg::Opcode::SECURITY_REQUEST: @@ -653,6 +668,7 @@ HCIStatusCode DBTDevice::setPairingNumericComparison(const bool positive) noexce void DBTDevice::clearSMPStates() noexcept { const std::lock_guard<std::mutex> lock(mtx_pairing); // RAII-style acquire and relinquish via destructor + pairing_data.sec_level = BTSecurityLevel::UNSET; pairing_data.mode = PairingMode::NONE; pairing_data.state = SMPPairingState::NONE; pairing_data.res_requested_sec = false; @@ -684,7 +700,7 @@ void DBTDevice::disconnectSMP(int caller) noexcept { #endif } -bool DBTDevice::connectSMP(std::shared_ptr<DBTDevice> sthis, const uint8_t sec_level) noexcept { +bool DBTDevice::connectSMP(std::shared_ptr<DBTDevice> sthis, const BTSecurityLevel sec_level) noexcept { #if SMP_SUPPORTED_BY_OS if( !isConnected || !allowDisconnect) { ERR_PRINT("DBTDevice::connectSMP(%u): Device not connected: %s", sec_level, toString().c_str()); @@ -696,7 +712,7 @@ bool DBTDevice::connectSMP(std::shared_ptr<DBTDevice> sthis, const uint8_t sec_l return false; } - if( BT_SECURITY_LOW >= sec_level ) { + if( BTSecurityLevel::NONE >= sec_level ) { return false; } diff --git a/src/direct_bt/L2CAPComm.cpp b/src/direct_bt/L2CAPComm.cpp index 1a5f9d14..3eeae8a6 100644 --- a/src/direct_bt/L2CAPComm.cpp +++ b/src/direct_bt/L2CAPComm.cpp @@ -238,7 +238,7 @@ bool L2CAPComm::close() noexcept { return true; } -bool L2CAPComm::setBTSecurityLevel(const uint8_t sec_level) { +bool L2CAPComm::setBTSecurityLevel(const BTSecurityLevel sec_level) { if( !is_open ) { DBG_PRINT("L2CAPComm::setBTSecurityLevel: Not connected: %s, dd %d, %s, psm %u, cid %u", getStateString().c_str(), socket_descriptor.load(), deviceString.c_str(), psm, cid); @@ -246,22 +246,22 @@ bool L2CAPComm::setBTSecurityLevel(const uint8_t sec_level) { } const std::lock_guard<std::recursive_mutex> lock(mtx_write); // RAII-style acquire and relinquish via destructor - if( BT_SECURITY_LOW < sec_level ) { + if( BTSecurityLevel::NONE < sec_level ) { #if USE_LINUX_BT_SECURITY struct bt_security bt_sec; int result; bzero(&bt_sec, sizeof(bt_sec)); - bt_sec.level = sec_level; + bt_sec.level = direct_bt::number(sec_level); result = setsockopt(socket_descriptor, SOL_BLUETOOTH, BT_SECURITY, &bt_sec, sizeof(bt_sec)); if ( 0 == result ) { - DBG_PRINT("L2CAPComm::setBTSecurityLevel: sec_level %u, success", sec_level); + DBG_PRINT("L2CAPComm::setBTSecurityLevel: sec_level %s, success", getBTSecurityLevelString(sec_level).c_str()); return true; } else { - ERR_PRINT("L2CAPComm::setBTSecurityLevel: sec_level %u, failed", sec_level); + ERR_PRINT("L2CAPComm::setBTSecurityLevel: sec_level %s, failed", getBTSecurityLevelString(sec_level).c_str()); } #else - DBG_PRINT("L2CAPComm::setBTSecurityLevel: sec_level %u, not implemented", sec_level); + DBG_PRINT("L2CAPComm::setBTSecurityLevel: sec_level %s, not implemented", getBTSecurityLevelString(sec_level).c_str()); #endif } return false; diff --git a/src/direct_bt/SMPHandler.cpp b/src/direct_bt/SMPHandler.cpp index 3255aaf8..352f53b0 100644 --- a/src/direct_bt/SMPHandler.cpp +++ b/src/direct_bt/SMPHandler.cpp @@ -200,7 +200,7 @@ SMPHandler::~SMPHandler() noexcept { clearAllCallbacks(); } -bool SMPHandler::establishSecurity(const uint8_t sec_level) { +bool SMPHandler::establishSecurity(const BTSecurityLevel sec_level) { // FIXME: Start negotiating security! // FIXME: Return true only if security has been established (encryption and optionally authentication) (void)sec_level; |