mirror of
https://github.com/esphome/esphome.git
synced 2026-08-22 22:26:21 +00:00
[bluetooth_proxy] Finish the connection scan before reserving a slot (#18239)
This commit is contained in:
@@ -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) {
|
||||||
|
|||||||
Reference in New Issue
Block a user