1use crate::{
2 firmware_functions,
3 ring_fs::{RingFs, RingFsReader, RingFsWriter},
4 mapper,
5};
6use rpk_common::usb_vendor_message::{
7 CLOSE_SAVE_CONFIG, OPEN_SAVE_CONFIG, RESET_KEYBOARD, RESET_TO_USB_BOOT,
8};
9
10enum ReceiveState {
11 Idle,
12 ConfigData,
13}
14
15pub struct ConfigInterface<'f, 'c> {
16 fs: &'f dyn RingFs<'f>,
17 mapper_ctl: &'c mapper::ControlSignal,
18 fw: Option<RingFsWriter<'f>>,
19 rcv_state: ReceiveState,
20}
21
22impl<'f, 'c> ConfigInterface<'f, 'c> {
23 pub fn new(fs: &'f dyn RingFs<'f>, mapper_ctl: &'c mapper::ControlSignal) -> Self {
24 Self {
25 fs,
26 mapper_ctl,
27 fw: None,
28 rcv_state: ReceiveState::Idle,
29 }
30 }
31
32 pub async fn receive(&mut self, data: &[u8]) {
33 match self.rcv_state {
34 ReceiveState::Idle => match *data.first().unwrap_or(&0) {
35 OPEN_SAVE_CONFIG if data.len() == 1 => {
36 self.rcv_state = ReceiveState::ConfigData;
37 }
38 RESET_KEYBOARD if data.len() == 1 => {
39 firmware_functions::reset();
40 }
41 RESET_TO_USB_BOOT if data.len() == 1 => {
42 firmware_functions::reset_to_usb_boot();
43 }
44 n => {
45 crate::error!("Unexpected msg [{}; {}]", n, data.len())
46 }
47 },
48 ReceiveState::ConfigData => match *data.first().unwrap_or(&0) {
49 _ if data.len() == 64 => {
50 self.file_write(data);
51 }
52 OPEN_SAVE_CONFIG if data.len() == 1 => {
53 self.rcv_state = ReceiveState::ConfigData;
54 }
55 CLOSE_SAVE_CONFIG => {
56 let data = data.split_at(1).1;
57 self.file_write(data);
58 if let Some(fw) = self.fw.take() {
59 self.mapper_ctl.load_layout(fw.location());
60 }
61 self.rcv_state = ReceiveState::Idle;
62 }
63 n => {
64 crate::error!("Unexpected msg [{}; {}]", n, data.len());
65 self.rcv_state = ReceiveState::Idle;
66 }
67 },
68 }
69 }
70
71 fn file_write(&mut self, data: &[u8]) {
72 if self.fw.is_none() {
73 match self.fs.create_file() {
74 Ok(fw) => self.fw = Some(fw),
75 Err(_) => {
76 crate::info!("can't create file");
77 return;
78 }
79 }
80 }
81 if let Some(ref mut fw) = &mut self.fw {
82 if let Err(err) = fw.write(data) {
83 crate::info!("write failed {:?}", err);
84 }
85 }
86 }
87}
88
89pub struct ConfigFileIter<'f>(RingFsReader<'f>);
90
91impl Iterator for ConfigFileIter<'_> {
92 type Item = u16;
93
94 fn next(&mut self) -> Option<Self::Item> {
95 let mut bytes = [0; 2];
96 match self.0.read(&mut bytes) {
97 Ok(2) => Some(u16::from_le_bytes(bytes)),
98 _ => None,
99 }
100 }
101}
102
103impl<'f> ConfigFileIter<'f> {
104 pub fn new(reader: RingFsReader<'f>) -> Self {
105 Self(reader)
106 }
107}
108
109#[cfg(test)]
110#[path = "config_test.rs"]
111mod test;