Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions rmk-types/src/protocol/rynk/payload/system.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ pub struct ProtocolVersion {

impl ProtocolVersion {
/// Current protocol version for this firmware release.
/// Now the protocol is still being developed, so the version is v0.1
pub const CURRENT: Self = Self { major: 0, minor: 1 };
/// Now the protocol is still being developed, so the version is v0.2
pub const CURRENT: Self = Self { major: 0, minor: 2 };
}

/// Device capabilities discovered during the connection handshake.
Expand Down Expand Up @@ -151,8 +151,8 @@ pub enum StorageResetMode {
#[cfg_attr(feature = "wasm", derive(tsify::Tsify))]
#[cfg_attr(feature = "wasm", tsify(into_wasm_abi, from_wasm_abi))]
pub struct BehaviorConfig {
pub combo_timeout_ms: u16,
pub oneshot_timeout_ms: u16,
pub combo_timeout_ms: u32,
pub oneshot_timeout_ms: u32,
pub tap_interval_ms: u16,
pub tap_capslock_interval_ms: u16,
}
Expand Down Expand Up @@ -283,8 +283,8 @@ mod tests {
#[test]
fn round_trip_behavior_config() {
round_trip(&BehaviorConfig {
combo_timeout_ms: 50,
oneshot_timeout_ms: 500,
combo_timeout_ms: 120_000,
oneshot_timeout_ms: 300_000,
tap_interval_ms: 200,
tap_capslock_interval_ms: 20,
});
Expand Down
6 changes: 3 additions & 3 deletions rmk-types/src/protocol/rynk/snapshots/wire_frames.snap
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
BootloaderJump reply Ok(()) 04 00 01 01 00 00
BootloaderJump request () 04 00 01 00 00
ConnectionChange topic ConnectionStatus{Configured,{1,Adv},Ble} 03 80 00 04 00 02 01 00 01
GetBehaviorConfig reply Ok(BehaviorConfig{50,500,200,20}) 01 06 01 07 00 00 32 f4 03 c8 01 14
GetBehaviorConfig reply Ok(BehaviorConfig{120000,300000,200,20}) 01 06 01 0a 00 00 c0 a9 07 e0 a7 12 c8 01 14
GetBehaviorConfig request () 01 06 01 00 00
GetCapabilities reply Ok(DeviceCapabilities{1..16}) 02 00 01 16 00 00 01 02 03 04 05 06 07 08 09 0a 01 00 01 0b 00 0c 0d 0e 0f 10 01
GetCapabilities request () 02 00 01 00 00
Expand Down Expand Up @@ -44,7 +44,7 @@ GetMorse reply Ok(Morse{TAP->Key(A)}) 01 04 01
GetMorse request 0 01 04 01 01 00 00
GetSleepState reply Ok(true) 06 08 01 02 00 00 01
GetSleepState request () 06 08 01 00 00
GetVersion reply Ok(CURRENT) 01 00 01 03 00 00 00 01
GetVersion reply Ok(CURRENT) 01 00 01 03 00 00 00 02
GetVersion request () 01 00 01 00 00
GetWpm reply Ok(42) 05 08 01 02 00 00 2a
GetWpm request () 05 08 01 00 00
Expand All @@ -55,7 +55,7 @@ Lock request () 08 00 01
Reboot reply Ok(()) 03 00 01 01 00 00
Reboot request () 03 00 01 00 00
SetBehaviorConfig reply Ok(()) 02 06 01 01 00 00
SetBehaviorConfig request BehaviorConfig{50,500,200,20} 02 06 01 06 00 32 f4 03 c8 01 14
SetBehaviorConfig request BehaviorConfig{120000,300000,200,20} 02 06 01 09 00 c0 a9 07 e0 a7 12 c8 01 14
SetCombo reply Ok(()) 02 03 01 01 00 00
SetCombo request SetComboRequest{3,combo} 02 03 01 0a 00 03 01 02 01 00 04 05 01 01 02
SetDefaultLayer reply Ok(()) 04 01 01 01 00 00
Expand Down
4 changes: 2 additions & 2 deletions rmk-types/src/protocol/rynk/snapshots/wire_values.snap
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ Action::TriggerMacro(7) 0c 07
Action::User(9) 13 09
BatteryStatus::Available{Discharging,85} 01 01 01 55
BatteryStatus::Unavailable 00
BehaviorConfig{50,500,200,20} 32 f4 03 c8 01 14
BehaviorConfig{120000,300000,200,20} c0 a9 07 e0 a7 12 c8 01 14
BleState::Advertising 00
BleState::Connected 01
BleState::Inactive 02
Expand Down Expand Up @@ -64,7 +64,7 @@ ModifierCombination(LCtrl|RGui) 81
MorseProfile(Normal,200,150) c8 81 b0 89 0c
Morse{TAP->Key(A)} 00 01 02 01 00 04
MouseButtons(B1|B8) 81
ProtocolVersion::CURRENT 00 01
ProtocolVersion::CURRENT 00 02
ProtocolVersion{1,0} 01 00
Result<(),RynkError>::Err(StorageFault) 01 02
Result<(),RynkError>::Ok 00
Expand Down
10 changes: 5 additions & 5 deletions rmk-types/src/protocol/rynk/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -252,8 +252,8 @@ fn exemplars() -> Exemplars {
serial_number: heapless::String::try_from("rynk:0001").unwrap(),
};
let behavior = BehaviorConfig {
combo_timeout_ms: 50,
oneshot_timeout_ms: 500,
combo_timeout_ms: 120_000,
oneshot_timeout_ms: 300_000,
tap_interval_ms: 200,
tap_capslock_interval_ms: 20,
};
Expand Down Expand Up @@ -459,7 +459,7 @@ fn wire_values_locked() {
("MatrixState{[0x05,0x00,0x20]}", encode(&ex.matrix)),
("DeviceCapabilities{1..16}", encode(&ex.capabilities)),
("DeviceInfo{1.2.3,4,5,RMK,..}", encode(&ex.device_info)),
("BehaviorConfig{50,500,200,20}", encode(&ex.behavior)),
("BehaviorConfig{120000,300000,200,20}", encode(&ex.behavior)),
("ConnectionStatus{Configured,{1,Adv},Ble}", encode(&ex.connection)),
("ProtocolVersion{1,0}", encode(&ProtocolVersion { major: 1, minor: 0 })),
("ProtocolVersion::CURRENT", encode(&ProtocolVersion::CURRENT)),
Expand Down Expand Up @@ -831,15 +831,15 @@ fn wire_frames_locked() {
encode_frame(Cmd::GetBehaviorConfig, SEQ, &())
),
(
"GetBehaviorConfig reply Ok(BehaviorConfig{50,500,200,20})",
"GetBehaviorConfig reply Ok(BehaviorConfig{120000,300000,200,20})",
encode_frame(
Cmd::GetBehaviorConfig,
SEQ,
&Ok::<BehaviorConfig, RynkError>(ex.behavior)
),
),
(
"SetBehaviorConfig request BehaviorConfig{50,500,200,20}",
"SetBehaviorConfig request BehaviorConfig{120000,300000,200,20}",
encode_frame(Cmd::SetBehaviorConfig, SEQ, &ex.behavior)
),
(
Expand Down
4 changes: 2 additions & 2 deletions rmk/src/host/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -241,13 +241,13 @@ impl<'a> KeyboardContext<'a> {
self.keymap.morse_prior_idle_time()
}

pub async fn set_combo_timeout(&self, ms: u16) {
pub async fn set_combo_timeout(&self, ms: u32) {
self.keymap.set_combo_timeout(Duration::from_millis(ms as u64));
#[cfg(feature = "storage")]
FLASH_CHANNEL.send(FlashOperationMessage::ComboTimeout(ms)).await;
}

pub async fn set_one_shot_timeout(&self, ms: u16) {
pub async fn set_one_shot_timeout(&self, ms: u32) {
self.keymap.set_one_shot_timeout(Duration::from_millis(ms as u64));
#[cfg(feature = "storage")]
FLASH_CHANNEL.send(FlashOperationMessage::OneShotTimeout(ms)).await;
Expand Down
4 changes: 2 additions & 2 deletions rmk/src/host/rynk/handlers/behavior.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ use super::Handle;
impl Handle<GetBehaviorConfig> for RynkService<'_> {
async fn handle(&self, _: ()) -> Result<BehaviorConfig, RynkError> {
Ok(BehaviorConfig {
combo_timeout_ms: self.ctx.combo_timeout().as_millis() as u16,
oneshot_timeout_ms: self.ctx.one_shot_timeout().as_millis() as u16,
combo_timeout_ms: u32::try_from(self.ctx.combo_timeout().as_millis()).unwrap_or(u32::MAX),
oneshot_timeout_ms: u32::try_from(self.ctx.one_shot_timeout().as_millis()).unwrap_or(u32::MAX),
tap_interval_ms: self.ctx.tap_interval(),
tap_capslock_interval_ms: self.ctx.tap_capslock_interval(),
})
Expand Down
8 changes: 4 additions & 4 deletions rmk/src/host/via/vial.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,15 +117,15 @@ pub(crate) async fn process_vial<'a>(
match value.into() {
SettingKey::None => report.input_data[0] = 0xFF,
SettingKey::ComboTimeout => {
let combo_timeout = ctx.combo_timeout().as_millis() as u16;
let combo_timeout = u16::try_from(ctx.combo_timeout().as_millis()).unwrap_or(u16::MAX);
LittleEndian::write_u16(&mut report.input_data[1..3], combo_timeout);
}
SettingKey::MorseTimeout => {
let tapping_term = ctx.morse_default_profile().hold_timeout_ms().unwrap_or(250);
LittleEndian::write_u16(&mut report.input_data[1..3], tapping_term);
}
SettingKey::OneShotTimeout => {
let one_shot_timeout = ctx.one_shot_timeout().as_millis() as u16;
let one_shot_timeout = u16::try_from(ctx.one_shot_timeout().as_millis()).unwrap_or(u16::MAX);
LittleEndian::write_u16(&mut report.input_data[1..3], one_shot_timeout);
}
SettingKey::TapInterval => {
Expand Down Expand Up @@ -174,7 +174,7 @@ pub(crate) async fn process_vial<'a>(
SettingKey::None => (),
SettingKey::ComboTimeout => {
let combo_timeout = u16::from_le_bytes([report.output_data[4], report.output_data[5]]);
ctx.set_combo_timeout(combo_timeout).await;
ctx.set_combo_timeout(combo_timeout.into()).await;
}
SettingKey::MorseTimeout => {
let timeout_time = u16::from_le_bytes([report.output_data[4], report.output_data[5]]);
Expand All @@ -183,7 +183,7 @@ pub(crate) async fn process_vial<'a>(
}
SettingKey::OneShotTimeout => {
let timeout_time = u16::from_le_bytes([report.output_data[4], report.output_data[5]]);
ctx.set_one_shot_timeout(timeout_time).await;
ctx.set_one_shot_timeout(timeout_time.into()).await;
}
SettingKey::TapInterval => {
let tap_interval = u16::from_le_bytes([report.output_data[4], report.output_data[5]]);
Expand Down
53 changes: 47 additions & 6 deletions rmk/src/storage/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -140,9 +140,9 @@ pub(crate) enum FlashOperationMessage {
// Current saved connection type
ConnectionType(ConnectionType),
// Timeout time for combos
ComboTimeout(u16),
ComboTimeout(u32),
// Timeout time for one-shot keys
OneShotTimeout(u16),
OneShotTimeout(u32),
// Interval for tap actions
TapInterval(u16),
// Interval for tapping capslock
Expand Down Expand Up @@ -305,9 +305,9 @@ pub(crate) struct BehaviorConfig {
pub(crate) morse_default_profile: MorseProfile,

// Timeout time for combos
pub(crate) combo_timeout: u16,
pub(crate) combo_timeout: u32,
// Timeout time for one-shot keys
pub(crate) one_shot_timeout: u16,
pub(crate) one_shot_timeout: u32,
// Interval for tap actions
pub(crate) tap_interval: u16,
// Interval for tapping capslock.
Expand All @@ -333,8 +333,8 @@ impl From<&config::BehaviorConfig> for StorageData {
Self::BehaviorConfig(BehaviorConfig {
prior_idle_time: behavior.morse.prior_idle_time.as_millis() as u16,
morse_default_profile: behavior.morse.default_profile,
combo_timeout: behavior.combo.timeout.as_millis() as u16,
one_shot_timeout: behavior.one_shot.timeout.as_millis() as u16,
combo_timeout: u32::try_from(behavior.combo.timeout.as_millis()).unwrap_or(u32::MAX),
one_shot_timeout: u32::try_from(behavior.one_shot.timeout.as_millis()).unwrap_or(u32::MAX),
tap_interval: behavior.tap.tap_interval,
tap_capslock_interval: behavior.tap.tap_capslock_interval,
})
Expand Down Expand Up @@ -1007,6 +1007,47 @@ mod tests {
}
}

#[test]
fn behavior_storage_preserves_long_timeouts() {
let mut behavior = RuntimeBehaviorConfig::default();
behavior.combo.timeout = Duration::from_secs(120);
behavior.one_shot.timeout = Duration::from_secs(300);

let StorageData::BehaviorConfig(stored) = StorageData::from(&behavior) else {
panic!("expected behavior storage data");
};
assert_eq!(stored.combo_timeout, 120_000);
assert_eq!(stored.one_shot_timeout, 300_000);
}

#[test]
fn behavior_storage_reads_legacy_u16_timeouts() {
#[derive(serde::Serialize)]
struct LegacyBehaviorConfig {
prior_idle_time: u16,
morse_default_profile: MorseProfile,
combo_timeout: u16,
one_shot_timeout: u16,
tap_interval: u16,
tap_capslock_interval: u16,
}

let legacy = LegacyBehaviorConfig {
prior_idle_time: 100,
morse_default_profile: MorseProfile::default(),
combo_timeout: 50,
one_shot_timeout: 500,
tap_interval: 200,
tap_capslock_interval: 20,
};
let mut buffer = [0u8; 64];
let encoded = postcard::to_slice(&legacy, &mut buffer).unwrap();
let decoded: BehaviorConfig = postcard::from_bytes(encoded).unwrap();

assert_eq!(decoded.combo_timeout, 50);
assert_eq!(decoded.one_shot_timeout, 500);
}

#[test]
fn build_hash_mismatch_reinitializes_storage() {
block_on(async {
Expand Down
4 changes: 2 additions & 2 deletions rmk/tests/rynk_loopback.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1030,8 +1030,8 @@ fn get_set_behavior_config_round_trip() {
// Non-default values make a dropped Set observable.
link_session(&service, async |client| {
let cfg = WireBehaviorConfig {
combo_timeout_ms: 123,
oneshot_timeout_ms: 456,
combo_timeout_ms: 120_000,
oneshot_timeout_ms: 300_000,
tap_interval_ms: 78,
tap_capslock_interval_ms: 90,
};
Expand Down
2 changes: 1 addition & 1 deletion rynk/rynk-wasm/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,7 @@ <h1>Rynk web demo</h1>
// Keep the loader keyed by protocol major even while there is one wasm artifact.
async function loadCore(major) {
switch (major) {
case 0: // protocol v0.x (ProtocolVersion::CURRENT = {0, 1})
case 0: // protocol v0.x (ProtocolVersion::CURRENT = {0, 2})
case 1:
return await import("./pkg/rynk_wasm.js");
default:
Expand Down