[bluetooth_proxy] Finish the connection scan before reserving a slot (#18239)

This commit is contained in:
J. Nick Koston
2026-08-10 12:56:16 -05:00
committed by GitHub
parent ad733272e5
commit 8f1e439792
@@ -198,6 +198,10 @@ void BluetoothProxy::reset_connection_slot_(BluetoothConnection *connection, con
} }
BluetoothConnection *BluetoothProxy::get_connection_(uint64_t address, bool reserve) { BluetoothConnection *BluetoothProxy::get_connection_(uint64_t address, bool reserve) {
// Finish the scan before reserving: a free slot earlier in the array must
// not win over a later slot that already holds the address, or one device
// ends up on two slots with a second connection attempt racing the first.
BluetoothConnection *free_slot = nullptr;
for (uint8_t i = 0; i < this->connection_count_; i++) { for (uint8_t i = 0; i < this->connection_count_; i++) {
auto *connection = this->connections_[i]; auto *connection = this->connections_[i];
uint64_t conn_addr = connection->get_address(); uint64_t conn_addr = connection->get_address();
@@ -205,18 +209,19 @@ BluetoothConnection *BluetoothProxy::get_connection_(uint64_t address, bool rese
if (conn_addr == address) if (conn_addr == address)
return connection; return connection;
if (reserve && conn_addr == 0) { if (free_slot == nullptr && conn_addr == 0)
connection->send_service_ = INIT_SENDING_SERVICES; free_slot = connection;
connection->set_address(address); }
if (!reserve || free_slot == nullptr)
return nullptr;
free_slot->send_service_ = INIT_SENDING_SERVICES;
free_slot->set_address(address);
// All connections must start at INIT // All connections must start at INIT
// We only set the state if we allocate the connection // We only set the state if we allocate the connection
// to avoid a race where multiple connection attempts // to avoid a race where multiple connection attempts
// are made. // are made.
connection->set_state(ClientState::INIT); free_slot->set_state(ClientState::INIT);
return connection; return free_slot;
}
}
return nullptr;
} }
void BluetoothProxy::bluetooth_device_request(const api::BluetoothDeviceRequest &msg) { void BluetoothProxy::bluetooth_device_request(const api::BluetoothDeviceRequest &msg) {