2017-08-07 23:57:29 +08:00
|
|
|
use eeprom;
|
|
|
|
use crc32;
|
2018-01-26 21:03:04 +08:00
|
|
|
use smoltcp::wire::{IpCidr, IpAddress};
|
2017-08-07 23:57:29 +08:00
|
|
|
|
|
|
|
const MAGIC: u8 = 0x54;
|
|
|
|
|
|
|
|
struct EepromReader {
|
|
|
|
buffer: [u8; eeprom::BLOCK_LEN]
|
|
|
|
}
|
|
|
|
|
|
|
|
impl EepromReader {
|
|
|
|
fn new() -> EepromReader {
|
|
|
|
EepromReader {
|
|
|
|
buffer: [0; eeprom::BLOCK_LEN]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn read_payload_block<'a>(&'a mut self, block: u16) -> bool {
|
|
|
|
eeprom::read_block(&mut self.buffer, block);
|
|
|
|
|
|
|
|
if self.buffer[0] != MAGIC {
|
|
|
|
return false;
|
|
|
|
}
|
2017-08-08 10:48:59 +08:00
|
|
|
let len = self.buffer.len();
|
|
|
|
let cksum = self.buffer[len-4] as u32 | (self.buffer[len-3] as u32) << 8 |
|
|
|
|
(self.buffer[len-2] as u32) << 16 | (self.buffer[len-1] as u32) << 24;
|
|
|
|
if crc32::checksum_ieee(&self.buffer[0..len-4]) != cksum {
|
2017-08-07 23:57:29 +08:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
true
|
|
|
|
}
|
2018-01-26 21:03:04 +08:00
|
|
|
|
2017-08-07 23:57:29 +08:00
|
|
|
fn read_payload<'a>(&'a mut self) -> Result<&'a [u8], ()> {
|
|
|
|
let mut ok = self.read_payload_block(0);
|
|
|
|
if !ok {
|
|
|
|
ok = self.read_payload_block(1);
|
|
|
|
}
|
|
|
|
if ok {
|
|
|
|
Ok(&self.buffer[1..self.buffer.len()-4])
|
|
|
|
} else {
|
|
|
|
Err(())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn write_eeprom_payload(payload: &[u8]) {
|
|
|
|
let mut buffer: [u8; eeprom::BLOCK_LEN] = [0; eeprom::BLOCK_LEN];
|
|
|
|
buffer[0] = MAGIC;
|
|
|
|
buffer[1..payload.len()+1].copy_from_slice(payload);
|
|
|
|
let len = buffer.len();
|
|
|
|
let cksum = crc32::checksum_ieee(&buffer[0..len-4]);
|
|
|
|
buffer[len-4] = cksum as u8;
|
|
|
|
buffer[len-3] = (cksum >> 8) as u8;
|
|
|
|
buffer[len-2] = (cksum >> 16) as u8;
|
|
|
|
buffer[len-1] = (cksum >> 24) as u8;
|
|
|
|
eeprom::write_block(&buffer, 0);
|
|
|
|
eeprom::write_block(&buffer, 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
pub struct Config {
|
2018-01-26 21:03:04 +08:00
|
|
|
pub ip: IpCidr,
|
2017-08-07 23:57:29 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
impl Config {
|
|
|
|
pub fn new() -> Config {
|
|
|
|
Config {
|
2018-01-26 21:03:04 +08:00
|
|
|
ip: IpCidr::new(IpAddress::v4(192, 168, 69, 1), 24)
|
2017-08-07 23:57:29 +08:00
|
|
|
}
|
|
|
|
}
|
2018-01-26 21:03:04 +08:00
|
|
|
|
2017-08-07 23:57:29 +08:00
|
|
|
pub fn load(&mut self) {
|
|
|
|
let mut reader = EepromReader::new();
|
|
|
|
let payload = reader.read_payload();
|
|
|
|
if payload.is_ok() {
|
|
|
|
let payload = payload.unwrap();
|
2018-01-26 21:03:04 +08:00
|
|
|
self.ip = IpCidr::new(
|
|
|
|
IpAddress::v4(payload[0], payload[1], payload[2], payload[3]),
|
|
|
|
payload[4])
|
2017-08-07 23:57:29 +08:00
|
|
|
}
|
|
|
|
}
|
2018-01-26 21:03:04 +08:00
|
|
|
|
2017-08-07 23:57:29 +08:00
|
|
|
pub fn save(&self) {
|
2018-01-26 21:03:04 +08:00
|
|
|
match self.ip {
|
|
|
|
IpCidr::Ipv4(ipv4) => {
|
|
|
|
let mut payload: [u8; 5] = [0; 5];
|
|
|
|
payload[0..4].copy_from_slice(&ipv4.address().0);
|
|
|
|
payload[4] = ipv4.prefix_len();
|
|
|
|
write_eeprom_payload(&payload);
|
|
|
|
}
|
2017-08-07 23:57:29 +08:00
|
|
|
_ => panic!("unsupported network address")
|
|
|
|
};
|
|
|
|
}
|
|
|
|
}
|