Skip to content

Commit d951dca

Browse files
committed
refactor: clean connection status
Signed-off-by: Haobo Gu <haobogu@outlook.com>
1 parent 6c2328b commit d951dca

7 files changed

Lines changed: 52 additions & 47 deletions

File tree

rmk/src/ble/mod.rs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ use crate::ble::profile::{ProfileInfo, ProfileManager, UPDATED_CCCD_TABLE, UPDAT
2323
use crate::channel::{BLE_REPORT_CHANNEL, LED_SIGNAL};
2424
use crate::config::RmkConfig;
2525
use crate::core_traits::Runnable;
26-
use crate::event::{ConnectionChangeEvent, SubscribableEvent, publish_event};
26+
use crate::event::SubscribableEvent;
2727
use crate::hid::{HidWriterTrait, run_led_reader};
2828
#[cfg(feature = "split")]
2929
use crate::split::ble::central::CENTRAL_SLEEP;
@@ -87,7 +87,6 @@ where
8787
pub async fn new(stack: &'a Stack<'a, C, DefaultPacketPool>, rmk_config: RmkConfig<'static>) -> Self {
8888
let preferred = crate::state::load_preferred_connection().await;
8989
crate::state::set_preferred_connection(preferred);
90-
publish_event(ConnectionChangeEvent::new(preferred));
9190

9291
let mut profile_manager = ProfileManager::new(stack);
9392
#[cfg(feature = "storage")]
@@ -741,7 +740,7 @@ mod tests {
741740
use rmk_types::ble::{BleState, BleStatus};
742741

743742
use crate::event::{Axis, AxisEvent, AxisValType, KeyboardEvent, PointingEvent, SubscribableEvent, publish_event};
744-
use crate::state::{connection_status, set_ble_profile, set_ble_state};
743+
use crate::state::{current_ble_status, set_ble_profile, set_ble_state};
745744
use crate::test_support::test_block_on as block_on;
746745

747746
fn ble_status_test_lock() -> &'static Mutex<()> {
@@ -757,7 +756,7 @@ mod tests {
757756
set_ble_state(BleState::Advertising);
758757

759758
assert_eq!(
760-
connection_status().ble,
759+
current_ble_status(),
761760
BleStatus {
762761
profile: 2,
763762
state: BleState::Advertising,
@@ -774,7 +773,7 @@ mod tests {
774773
set_ble_profile(3);
775774

776775
assert_eq!(
777-
connection_status().ble,
776+
current_ble_status(),
778777
BleStatus {
779778
profile: 3,
780779
state: BleState::Inactive,

rmk/src/ble/profile.rs

Lines changed: 1 addition & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,7 @@ use embassy_sync::signal::Signal;
77
use trouble_host::prelude::*;
88
use trouble_host::{BondInformation, LongTermKey};
99
#[cfg(feature = "storage")]
10-
use {
11-
crate::channel::FLASH_CHANNEL,
12-
crate::storage::{FLASH_OPERATION_FINISHED, FlashOperationMessage},
13-
};
10+
use {crate::channel::FLASH_CHANNEL, crate::storage::FLASH_OPERATION_FINISHED};
1411

1512
use super::ble_server::CCCD_TABLE_SIZE;
1613
use crate::NUM_BLE_PROFILE;
@@ -157,7 +154,6 @@ pub(crate) enum BleProfileAction {
157154
PreviousProfile,
158155
NextProfile,
159156
ClearProfile,
160-
ToggleConnection,
161157
}
162158

163159
/// Manage BLE profiles and bonding information
@@ -387,16 +383,6 @@ impl<'a, C: Controller + ControllerCmdAsync<LeSetPhy>, P: PacketPool> ProfileMan
387383
BleProfileAction::ClearProfile => {
388384
self.clear_bond(current_profile()).await;
389385
}
390-
BleProfileAction::ToggleConnection => {
391-
// Flips the persisted transport preference and lets
392-
// the routing cascade recompute `active`.
393-
let updated = crate::state::toggle_preferred();
394-
395-
info!("Switching preferred transport to: {:?}", updated);
396-
397-
#[cfg(feature = "storage")]
398-
FLASH_CHANNEL.send(FlashOperationMessage::ConnectionType(updated)).await;
399-
}
400386
}
401387
#[cfg(feature = "storage")]
402388
FLASH_OPERATION_FINISHED.wait().await;

rmk/src/display/mod.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -417,6 +417,13 @@ where
417417
use crate::event::EventSubscriber;
418418
let mut sub = <Self as Processor>::subscriber();
419419

420+
// Prime from current state after subscribing, so the first render
421+
// reflects state that was set before the processor started.
422+
#[cfg(feature = "_ble")]
423+
{
424+
self.ctx.ble_status = crate::state::current_ble_status();
425+
}
426+
420427
self.pending_render = true;
421428
self.render().await;
422429
let mut ticker = self.render_interval.map(Ticker::every);

rmk/src/keyboard.rs

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1580,7 +1580,7 @@ impl<'a> Keyboard<'a> {
15801580
if event.pressed {
15811581
// Clear Peer is processed when pressed
15821582
if id == NUM_BLE_PROFILE as u8 + 4 {
1583-
#[cfg(all(feature = "split", feature = "_ble"))]
1583+
#[cfg(feature = "split")]
15841584
if event.pressed {
15851585
// Wait for 5s, if the key is still pressed, clear split peer info
15861586
// If there's any other key event received during this period, skip
@@ -1592,7 +1592,7 @@ impl<'a> Keyboard<'a> {
15921592
{
15931593
Either::First(_) => {
15941594
// Timeout reached, send clear peer message
1595-
#[cfg(all(feature = "split", feature = "_ble"))]
1595+
#[cfg(feature = "split")]
15961596
publish_event(ClearPeerEvent);
15971597
info!("Clear peer");
15981598
}
@@ -1606,23 +1606,26 @@ impl<'a> Keyboard<'a> {
16061606
}
16071607
}
16081608
} else {
1609-
// Other user keys are processed when released
1609+
// Other user keys are processed when released.
1610+
// Slots 0..NUM_BLE_PROFILE select a profile directly; the next four are
1611+
// fixed actions stacked on top.
16101612
if id < NUM_BLE_PROFILE as u8 {
16111613
info!("Switch to profile: {}", id);
1612-
// User0~7: Swtich to the specific profile
16131614
BLE_PROFILE_CHANNEL.send(BleProfileAction::SwitchProfile(id)).await;
16141615
} else if id == NUM_BLE_PROFILE as u8 {
1615-
// User8: Next profile
1616+
// Next profile
16161617
BLE_PROFILE_CHANNEL.send(BleProfileAction::NextProfile).await;
16171618
} else if id == NUM_BLE_PROFILE as u8 + 1 {
1618-
// User9: Previous profile
1619+
// Previous profile
16191620
BLE_PROFILE_CHANNEL.send(BleProfileAction::PreviousProfile).await;
16201621
} else if id == NUM_BLE_PROFILE as u8 + 2 {
1621-
// User10: Clear profile
1622+
// Clear profile
16221623
BLE_PROFILE_CHANNEL.send(BleProfileAction::ClearProfile).await;
16231624
} else if id == NUM_BLE_PROFILE as u8 + 3 {
1624-
// User11:
1625-
BLE_PROFILE_CHANNEL.send(BleProfileAction::ToggleConnection).await;
1625+
// Toggle preferred transport (USB <-> BLE);
1626+
// only meaningful when both transports exist in this build.
1627+
#[cfg(not(feature = "_no_usb"))]
1628+
crate::state::toggle_preferred().await;
16261629
}
16271630
}
16281631
}

rmk/src/lib.rs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -193,9 +193,6 @@ pub async fn run_rmk<
193193

194194
#[cfg(all(not(feature = "_ble"), not(feature = "_no_usb")))]
195195
{
196-
crate::event::publish_event(crate::event::ConnectionChangeEvent::new(
197-
rmk_types::connection::ConnectionType::Usb,
198-
));
199196
let mut usb = crate::usb::UsbTransport::new(usb_driver, device_config);
200197
embassy_futures::join::join(usb.run(), wpm.polling_loop()).await;
201198
}

rmk/src/state.rs

Lines changed: 26 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ use core::sync::atomic::{AtomicBool, Ordering};
33

44
use embassy_sync::blocking_mutex::Mutex;
55
use rmk_types::ble::BleState;
6+
#[cfg(feature = "_ble")]
7+
use rmk_types::ble::BleStatus;
68
use rmk_types::connection::{ConnectionStatus, ConnectionType, UsbState};
79

810
use crate::RawMutex;
@@ -17,6 +19,12 @@ use crate::event::{ConnectionChangeEvent, publish_event};
1719
/// is re-established
1820
static MATRIX_SCAN_OVERRIDE: AtomicBool = AtomicBool::new(false);
1921

22+
/// Single source of truth for transport state and routing. All writes go
23+
/// through the mutator helpers below so the active-output cascade runs and
24+
/// change events fire on every transition.
25+
pub(crate) static CONNECTION_STATUS: Mutex<RawMutex, Cell<ConnectionStatus>> =
26+
Mutex::new(Cell::new(ConnectionStatus::new()));
27+
2028
#[cfg(feature = "_ble")]
2129
pub(crate) fn enable_matrix_scan_override() {
2230
MATRIX_SCAN_OVERRIDE.store(true, Ordering::Release);
@@ -32,18 +40,17 @@ pub(crate) fn input_processing_ready() -> bool {
3240
active_transport().is_some() || MATRIX_SCAN_OVERRIDE.load(Ordering::Acquire) || cfg!(not(feature = "_no_usb"))
3341
}
3442

35-
/// Single source of truth for transport state and routing. All writes go
36-
/// through the mutator helpers below so the active-output cascade runs and
37-
/// change events fire on every transition.
38-
pub(crate) static CONNECTION_STATUS: Mutex<RawMutex, Cell<ConnectionStatus>> =
39-
Mutex::new(Cell::new(ConnectionStatus::new()));
40-
4143
pub(crate) fn active_transport() -> Option<ConnectionType> {
42-
connection_status().decide_active()
44+
CONNECTION_STATUS.lock(|c| c.get().decide_active())
4345
}
4446

45-
pub(crate) fn connection_status() -> ConnectionStatus {
46-
CONNECTION_STATUS.lock(|c| c.get())
47+
pub(crate) fn current_usb_state() -> UsbState {
48+
CONNECTION_STATUS.lock(|c| c.get().usb)
49+
}
50+
51+
#[cfg(feature = "_ble")]
52+
pub(crate) fn current_ble_status() -> BleStatus {
53+
CONNECTION_STATUS.lock(|c| c.get().ble)
4754
}
4855

4956
/// Read-modify-write the connection status atomically.
@@ -63,7 +70,7 @@ fn update_status(f: impl FnOnce(&mut ConnectionStatus)) {
6370

6471
let prev_active = prev.decide_active();
6572
let new_active = new.decide_active();
66-
// TODO: Is it really needed?
73+
6774
if prev_active != new_active
6875
&& let Some(prev_active) = prev_active
6976
{
@@ -82,6 +89,7 @@ fn update_status(f: impl FnOnce(&mut ConnectionStatus)) {
8289
}
8390
}
8491

92+
#[cfg(not(feature = "std"))]
8593
pub fn set_usb_state(s: UsbState) {
8694
update_status(|c| c.usb = s);
8795
}
@@ -129,7 +137,8 @@ pub(crate) async fn load_preferred_connection() -> ConnectionType {
129137
}
130138
}
131139

132-
pub(crate) fn toggle_preferred() -> ConnectionType {
140+
#[cfg(all(feature = "_ble", not(feature = "_no_usb")))]
141+
pub(crate) async fn toggle_preferred() {
133142
let mut new = ConnectionType::Usb;
134143
update_status(|c| {
135144
c.preferred = match c.preferred {
@@ -138,12 +147,16 @@ pub(crate) fn toggle_preferred() -> ConnectionType {
138147
};
139148
new = c.preferred;
140149
});
141-
new
150+
info!("Switching preferred transport to: {:?}", new);
151+
#[cfg(feature = "storage")]
152+
crate::channel::FLASH_CHANNEL
153+
.send(crate::storage::FlashOperationMessage::ConnectionType(new))
154+
.await;
142155
}
143156

144157
#[cfg(feature = "_ble")]
145158
pub(crate) fn current_profile() -> u8 {
146-
connection_status().ble.profile
159+
CONNECTION_STATUS.lock(|c| c.get().ble.profile)
147160
}
148161

149162
#[cfg(test)]

rmk/src/usb/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ use crate::hid::{
2323
CompositeReport, CompositeReportType, HidError, HidWriterTrait, KeyboardReport, Report, run_led_reader,
2424
};
2525
use crate::light::UsbLedReader;
26-
use crate::state::{connection_status, set_usb_state};
26+
use crate::state::{current_usb_state, set_usb_state};
2727

2828
pub(crate) static USB_REMOTE_WAKEUP: Signal<RawMutex, ()> = Signal::new();
2929

@@ -60,7 +60,7 @@ impl<'a, 'd, D: Driver<'d>> UsbKeyboardWriter<'a, 'd, D> {
6060
// EndpointError::Disabled never fires on non-OTG STM32/GD32
6161
// peripherals during suspend, so signal wakeup proactively when a
6262
// USB report is pending and the bus is suspended.
63-
if connection_status().usb == UsbState::Suspended {
63+
if current_usb_state() == UsbState::Suspended {
6464
USB_REMOTE_WAKEUP.signal(());
6565
}
6666

0 commit comments

Comments
 (0)