rpk_firmware/
config.rs

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;