Merge branch 'master' into feature/protocol-neutral-state
This commit is contained in:
commit
df515934ab
4 changed files with 44 additions and 16 deletions
|
|
@ -92,6 +92,7 @@ enum class ConnectionStatus {
|
|||
enum class ConnectionPolicyState {
|
||||
Uninitialized,
|
||||
Open,
|
||||
Passive,
|
||||
Paused,
|
||||
FailedClosed,
|
||||
};
|
||||
|
|
@ -631,26 +632,40 @@ void process_clear_pairings(uint32_t now_ms) {
|
|||
|
||||
void apply_connection_policy() {
|
||||
const bool free_slot = has_free_slot();
|
||||
if ((!free_slot &&
|
||||
g_connection_policy_state == ConnectionPolicyState::Paused) ||
|
||||
(free_slot &&
|
||||
g_connection_policy_state == ConnectionPolicyState::Open)) {
|
||||
const bool active_controller = has_active_controller();
|
||||
const bool pairing_open =
|
||||
pairing_window_active_at(btstack_run_loop_get_time_ms());
|
||||
const bool active_scan =
|
||||
free_slot && (!active_controller || pairing_open);
|
||||
const ConnectionPolicyState desired_state =
|
||||
!free_slot
|
||||
? ConnectionPolicyState::Paused
|
||||
: (active_scan ? ConnectionPolicyState::Open
|
||||
: ConnectionPolicyState::Passive);
|
||||
if (g_connection_policy_state == desired_state) {
|
||||
return;
|
||||
}
|
||||
|
||||
uni_bt_allow_incoming_connections(false);
|
||||
// Classic inquiry and BLE scanning consume radio time and measurably delay
|
||||
// active controller HID traffic. Stop them before every policy transition.
|
||||
uni_bt_stop_scanning_unsafe();
|
||||
|
||||
if (!free_slot) {
|
||||
uni_bt_allow_incoming_connections(false);
|
||||
g_connection_policy_state = ConnectionPolicyState::Paused;
|
||||
return;
|
||||
}
|
||||
|
||||
// Bluepad32's normal scan/autoconnect path handles both remembered
|
||||
// controllers powering on and controllers in explicit pairing mode.
|
||||
// Passive mode still accepts controller-initiated reconnects without
|
||||
// running inquiry. Active discovery is reserved for zero-controller idle
|
||||
// state and the explicit BOOTSEL pairing window.
|
||||
uni_bt_allow_incoming_connections(true);
|
||||
uni_bt_start_scanning_and_autoconnect_unsafe();
|
||||
g_connection_policy_state = ConnectionPolicyState::Open;
|
||||
if (active_scan) {
|
||||
uni_bt_start_scanning_and_autoconnect_unsafe();
|
||||
g_connection_policy_state = ConnectionPolicyState::Open;
|
||||
} else {
|
||||
g_connection_policy_state = ConnectionPolicyState::Passive;
|
||||
}
|
||||
}
|
||||
|
||||
void update_status_led() {
|
||||
|
|
@ -683,7 +698,9 @@ void process_rumble_timer(btstack_timer_source_t* timer) {
|
|||
const uint32_t now_ms = btstack_run_loop_get_time_ms();
|
||||
process_clear_pairings(now_ms);
|
||||
process_pairing_snapshot_request();
|
||||
update_pairing_window(now_ms);
|
||||
if (update_pairing_window(now_ms)) {
|
||||
apply_connection_policy();
|
||||
}
|
||||
|
||||
for (uint8_t slot_index = 0; slot_index < kSlotCount; ++slot_index) {
|
||||
RumbleEnvelope envelope{};
|
||||
|
|
@ -791,7 +808,8 @@ void platform_on_device_connected(uni_hid_device_t* device) {
|
|||
if (device == nullptr) {
|
||||
return;
|
||||
}
|
||||
if (g_connection_policy_state != ConnectionPolicyState::Open) {
|
||||
if (g_connection_policy_state != ConnectionPolicyState::Open &&
|
||||
g_connection_policy_state != ConnectionPolicyState::Passive) {
|
||||
uni_hid_device_disconnect(device);
|
||||
return;
|
||||
}
|
||||
|
|
@ -843,9 +861,9 @@ void platform_on_device_disconnected(uni_hid_device_t* device) {
|
|||
critical_section_exit(&g_state_lock);
|
||||
|
||||
if (disconnected_tracked_device) {
|
||||
// A controller can disconnect while the policy is already Open.
|
||||
// Restart both scans so host-initiated reconnect controllers such as
|
||||
// 8BitDo Ultimate become reachable without rebooting the Pico.
|
||||
// Re-evaluate from scratch: resume discovery only after the final
|
||||
// active controller disconnects; otherwise keep passive incoming
|
||||
// reconnect support without inquiry-induced latency.
|
||||
g_connection_policy_state = ConnectionPolicyState::Uninitialized;
|
||||
recompute_connection_status();
|
||||
}
|
||||
|
|
|
|||
Binary file not shown.
Binary file not shown.
|
|
@ -808,13 +808,23 @@ void test_pairing_window_policy() {
|
|||
g_connection_policy_state == ConnectionPolicyState::Paused,
|
||||
"Classic and BLE pairing authentication must close at the deadline");
|
||||
platform_on_device_disconnected(&devices[3]);
|
||||
require(g_connection_policy_state == ConnectionPolicyState::Passive &&
|
||||
!classic_scanning_enabled && !scanning_enabled &&
|
||||
incoming_connections,
|
||||
"a freed slot with active controllers must remain passive");
|
||||
require(platform_on_device_discovered(address, "controller", 0, 0) ==
|
||||
UNI_ERROR_IGNORE_DEVICE,
|
||||
"passive policy must reject inquiry discoveries");
|
||||
|
||||
bluepad32_input_backend_open_pairing_window();
|
||||
process_rumble_timer(&g_rumble_timer);
|
||||
require(g_connection_policy_state == ConnectionPolicyState::Open &&
|
||||
classic_scanning_enabled && scanning_enabled &&
|
||||
incoming_connections,
|
||||
"a freed slot must resume autoconnect after pairing indication expires");
|
||||
"explicit BOOTSEL window must resume active discovery");
|
||||
require(platform_on_device_discovered(address, "controller", 0, 0) ==
|
||||
UNI_ERROR_SUCCESS,
|
||||
"resumed autoconnect must accept a discovered controller");
|
||||
"pairing window discovery must accept a controller");
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue