Loading system/stack/acl/btm_acl.cc +29 −0 Original line number Diff line number Diff line Loading @@ -2708,8 +2708,37 @@ void acl_disconnect_from_handle(uint16_t handle, tHCI_STATUS reason, acl_disconnect_after_role_switch(handle, reason, comment); } // BLUETOOTH CORE SPECIFICATION Version 5.4 | Vol 4, Part E // 7.1.6 Disconnect command // Only a subset of reasons are valid and will be accepted // by the controller bool is_disconnect_reason_valid(const tHCI_REASON& reason) { switch (reason) { case HCI_ERR_AUTH_FAILURE: case HCI_ERR_PEER_USER: case HCI_ERR_REMOTE_LOW_RESOURCE: case HCI_ERR_REMOTE_POWER_OFF: case HCI_ERR_UNSUPPORTED_REM_FEATURE: case HCI_ERR_PAIRING_WITH_UNIT_KEY_NOT_SUPPORTED: case HCI_ERR_UNACCEPT_CONN_INTERVAL: return true; default: break; } return false; } void acl_disconnect_after_role_switch(uint16_t conn_handle, tHCI_STATUS reason, std::string comment) { if (!is_disconnect_reason_valid(reason)) { LOG_WARN( "Controller will not accept invalid reason parameter:%s" " instead sending:%s", hci_error_code_text(reason).c_str(), hci_error_code_text(HCI_ERR_PEER_USER).c_str()); reason = HCI_ERR_PEER_USER; } tACL_CONN* p_acl = internal_.acl_get_connection_from_handle(conn_handle); if (p_acl == nullptr) { LOG_ERROR("Sending disconnect for unknown acl:%hu PLEASE FIX", conn_handle); Loading system/stack/test/btm/stack_btm_test.cc +20 −0 Original line number Diff line number Diff line Loading @@ -493,3 +493,23 @@ TEST_F(StackBtmWithInitFreeTest, wipe_secrets_and_remove) { wipe_secrets_and_remove(device_record); } bool is_disconnect_reason_valid(const tHCI_REASON& reason); TEST_F(StackBtmWithInitFreeTest, is_disconnect_reason_valid) { std::set<tHCI_REASON> valid_reason_set{ HCI_ERR_AUTH_FAILURE, HCI_ERR_PEER_USER, HCI_ERR_REMOTE_LOW_RESOURCE, HCI_ERR_REMOTE_POWER_OFF, HCI_ERR_UNSUPPORTED_REM_FEATURE, HCI_ERR_PAIRING_WITH_UNIT_KEY_NOT_SUPPORTED, HCI_ERR_UNACCEPT_CONN_INTERVAL, }; for (unsigned u = 0; u < 256; u++) { const tHCI_REASON reason = static_cast<tHCI_REASON>(u); if (valid_reason_set.count(reason)) ASSERT_TRUE(is_disconnect_reason_valid(reason)); else ASSERT_FALSE(is_disconnect_reason_valid(reason)); } } Loading
system/stack/acl/btm_acl.cc +29 −0 Original line number Diff line number Diff line Loading @@ -2708,8 +2708,37 @@ void acl_disconnect_from_handle(uint16_t handle, tHCI_STATUS reason, acl_disconnect_after_role_switch(handle, reason, comment); } // BLUETOOTH CORE SPECIFICATION Version 5.4 | Vol 4, Part E // 7.1.6 Disconnect command // Only a subset of reasons are valid and will be accepted // by the controller bool is_disconnect_reason_valid(const tHCI_REASON& reason) { switch (reason) { case HCI_ERR_AUTH_FAILURE: case HCI_ERR_PEER_USER: case HCI_ERR_REMOTE_LOW_RESOURCE: case HCI_ERR_REMOTE_POWER_OFF: case HCI_ERR_UNSUPPORTED_REM_FEATURE: case HCI_ERR_PAIRING_WITH_UNIT_KEY_NOT_SUPPORTED: case HCI_ERR_UNACCEPT_CONN_INTERVAL: return true; default: break; } return false; } void acl_disconnect_after_role_switch(uint16_t conn_handle, tHCI_STATUS reason, std::string comment) { if (!is_disconnect_reason_valid(reason)) { LOG_WARN( "Controller will not accept invalid reason parameter:%s" " instead sending:%s", hci_error_code_text(reason).c_str(), hci_error_code_text(HCI_ERR_PEER_USER).c_str()); reason = HCI_ERR_PEER_USER; } tACL_CONN* p_acl = internal_.acl_get_connection_from_handle(conn_handle); if (p_acl == nullptr) { LOG_ERROR("Sending disconnect for unknown acl:%hu PLEASE FIX", conn_handle); Loading
system/stack/test/btm/stack_btm_test.cc +20 −0 Original line number Diff line number Diff line Loading @@ -493,3 +493,23 @@ TEST_F(StackBtmWithInitFreeTest, wipe_secrets_and_remove) { wipe_secrets_and_remove(device_record); } bool is_disconnect_reason_valid(const tHCI_REASON& reason); TEST_F(StackBtmWithInitFreeTest, is_disconnect_reason_valid) { std::set<tHCI_REASON> valid_reason_set{ HCI_ERR_AUTH_FAILURE, HCI_ERR_PEER_USER, HCI_ERR_REMOTE_LOW_RESOURCE, HCI_ERR_REMOTE_POWER_OFF, HCI_ERR_UNSUPPORTED_REM_FEATURE, HCI_ERR_PAIRING_WITH_UNIT_KEY_NOT_SUPPORTED, HCI_ERR_UNACCEPT_CONN_INTERVAL, }; for (unsigned u = 0; u < 256; u++) { const tHCI_REASON reason = static_cast<tHCI_REASON>(u); if (valid_reason_set.count(reason)) ASSERT_TRUE(is_disconnect_reason_valid(reason)); else ASSERT_FALSE(is_disconnect_reason_valid(reason)); } }