1pub mod discovery;
6pub mod eeprom;
7pub mod flash;
8pub mod params;
9pub mod pixel;
10pub mod upgrade;
11
12pub use discovery::*;
13pub use flash::*;
14pub use pixel::*;
15
16pub const CARD_MAC: [u8; 6] = [0x11, 0x22, 0x33, 0x44, 0x55, 0x66];
17pub const SENDER_MAC: [u8; 6] = [0x22, 0x22, 0x33, 0x44, 0x55, 0x66];
18
19pub const BROADCAST: u16 = 0xffff;
22
23pub const HEADER_LEN: usize = 14;
25
26pub(crate) fn write_header(f: &mut [u8], ethertype: [u8; 2]) {
27 f[..6].copy_from_slice(&CARD_MAC);
28 f[6..12].copy_from_slice(&SENDER_MAC);
29 f[12..14].copy_from_slice(ðertype);
30}
31
32#[must_use]
34pub fn frame_with(ethertype: [u8; 2], payload_len: usize, fill: impl FnOnce(&mut [u8])) -> Vec<u8> {
35 let mut f = vec![0u8; HEADER_LEN + payload_len];
36 write_header(&mut f, ethertype);
37 fill(&mut f[HEADER_LEN..]);
38 f
39}
40
41#[must_use]
42pub fn frame(ethertype: [u8; 2], payload: &[u8]) -> Vec<u8> {
43 frame_with(ethertype, payload.len(), |p| p.copy_from_slice(payload))
44}
45
46pub(crate) fn indexed(p: &mut [u8], rcv_index: u16, opcode: u8) {
49 p[1..3].copy_from_slice(&rcv_index.to_be_bytes());
50 p[3] = opcode;
51}
52
53pub(crate) fn command(rcv_index: u16, opcode: u8, flags: &[u8]) -> Vec<u8> {
55 frame_with([0x06, 0x00], 126, |p| {
56 indexed(p, rcv_index, opcode);
57 p[8..8 + flags.len()].copy_from_slice(flags);
58 })
59}
60
61pub trait Protocol {
68 fn discover(&self) -> Vec<u8>;
70 fn discovery_reply(&self, frame: &[u8]) -> Option<DiscoveryInfo>;
72 fn row(&self, buf: &mut Vec<u8>, row: u16, x: u16, rgb: &[[u8; 3]], order: ColorOrder);
74 fn latch(&self, brightness: u8) -> Vec<u8>;
76 fn brightness(&self, brightness: u8) -> Vec<u8>;
78 fn flash_read(&self, index: u16, page: u16) -> Vec<u8>;
80 fn flash_reply<'a>(&self, frame: &'a [u8]) -> Option<&'a [u8]>;
82 fn flash_write(&self, map: &FlashMap, index: u16, block: u8, page: u8, data: &[u8]) -> Result<Vec<u8>, WriteError>;
87 fn eeprom_write(&self, addr: u16, data: &[u8]) -> Vec<u8>;
89}
90
91#[derive(Debug, Clone, Copy, Default)]
94pub struct Colorlight;
95
96impl Protocol for Colorlight {
97 fn discover(&self) -> Vec<u8> {
98 discovery()
99 }
100
101 fn discovery_reply(&self, frame: &[u8]) -> Option<DiscoveryInfo> {
102 parse_discovery_response(frame)
103 }
104
105 fn row(&self, buf: &mut Vec<u8>, row: u16, x: u16, rgb: &[[u8; 3]], order: ColorOrder) {
106 pixel_row_into(buf, row, x, rgb, order);
107 }
108
109 fn latch(&self, brightness: u8) -> Vec<u8> {
110 sync(brightness).to_vec()
111 }
112
113 fn brightness(&self, brightness: u8) -> Vec<u8> {
114 pixel::brightness(brightness).to_vec()
115 }
116
117 fn flash_read(&self, index: u16, page: u16) -> Vec<u8> {
118 read_flash(index, page)
119 }
120
121 fn flash_reply<'a>(&self, frame: &'a [u8]) -> Option<&'a [u8]> {
122 flash_reply_data(frame)
123 }
124
125 fn flash_write(&self, map: &FlashMap, index: u16, block: u8, page: u8, data: &[u8]) -> Result<Vec<u8>, WriteError> {
126 map.write_page(index, block, page, data)
127 }
128
129 fn eeprom_write(&self, addr: u16, data: &[u8]) -> Vec<u8> {
130 eeprom::write(addr, data)
131 }
132}
133
134#[cfg(test)]
135mod protocol_tests {
136 use super::*;
137
138 #[test]
139 fn the_trait_builds_the_same_frames_as_the_functions() {
140 let p = Colorlight;
141 assert_eq!(p.discover(), discovery());
142 assert_eq!(p.latch(40), sync(40).to_vec());
143 assert_eq!(p.brightness(40), pixel::brightness(40).to_vec());
144 assert_eq!(p.flash_read(0, FLASH_PAGE_BASIC_PARAM), read_flash(0, FLASH_PAGE_BASIC_PARAM));
145 assert_eq!(p.eeprom_write(0x02, &[0; 42]), eeprom::write(0x02, &[0; 42]));
146 let page = [0u8; FLASH_PAGE_BYTES];
147 assert_eq!(p.flash_write(&E120, 0, PARAM_BLOCK, 0x80, &page), E120.write_page(0, PARAM_BLOCK, 0x80, &page));
148 assert_eq!(p.flash_write(&E120, 0, 0x00, 0, &page), Err(WriteError::ForbiddenBlock(0)));
149 let mut a = Vec::new();
150 p.row(&mut a, 3, 0, &[[1, 2, 3]; 4], ColorOrder::Bgr);
151 assert_eq!(a, pixel_row(3, 0, &[[1, 2, 3]; 4], ColorOrder::Bgr));
152 assert!(p.discovery_reply(&[0; 20]).is_none());
153 assert!(p.flash_reply(&[0; 20]).is_none());
154 }
155}