forked from M-Labs/ionpak-thermostat
add session
This commit is contained in:
parent
7f95f01711
commit
0dcd35c9f2
|
@ -137,6 +137,7 @@ dependencies = [
|
||||||
"crc 1.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"crc 1.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"embedded-hal 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"embedded-hal 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libm 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libm 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"logos 0.9.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"nb 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"nb 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"smoltcp 0.4.0 (git+https://github.com/m-labs/smoltcp?rev=cd893e6)",
|
"smoltcp 0.4.0 (git+https://github.com/m-labs/smoltcp?rev=cd893e6)",
|
||||||
"tm4c129x 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"tm4c129x 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@ -157,6 +158,26 @@ name = "libm"
|
||||||
version = "0.1.4"
|
version = "0.1.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "logos"
|
||||||
|
version = "0.9.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"logos-derive 0.9.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "logos-derive"
|
||||||
|
version = "0.9.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"regex-syntax 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"utf8-ranges 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "managed"
|
name = "managed"
|
||||||
version = "0.5.1"
|
version = "0.5.1"
|
||||||
|
@ -209,6 +230,11 @@ name = "rand_core"
|
||||||
version = "0.4.2"
|
version = "0.4.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "regex-syntax"
|
||||||
|
version = "0.6.12"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustc_version"
|
name = "rustc_version"
|
||||||
version = "0.2.3"
|
version = "0.2.3"
|
||||||
|
@ -285,6 +311,11 @@ name = "unicode-xid"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "utf8-ranges"
|
||||||
|
version = "1.0.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "vcell"
|
name = "vcell"
|
||||||
version = "0.1.2"
|
version = "0.1.2"
|
||||||
|
@ -342,6 +373,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
"checksum generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c68f0274ae0e023facc3c97b2e00f076be70e254bc851d972503b328db79b2ec"
|
"checksum generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c68f0274ae0e023facc3c97b2e00f076be70e254bc851d972503b328db79b2ec"
|
||||||
"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
|
"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
|
||||||
"checksum libm 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "7fc7aa29613bd6a620df431842069224d8bc9011086b1db4c0e0cd47fa03ec9a"
|
"checksum libm 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "7fc7aa29613bd6a620df431842069224d8bc9011086b1db4c0e0cd47fa03ec9a"
|
||||||
|
"checksum logos 0.9.7 (registry+https://github.com/rust-lang/crates.io-index)" = "f494e22d293fa05db60b3fd95fb30e9409feb5672b56ce6f250f99d9fbae6b93"
|
||||||
|
"checksum logos-derive 0.9.7 (registry+https://github.com/rust-lang/crates.io-index)" = "13ff1b1068db09ee21d12baf55eccc0900a781a735273e0a606f6f4fbb32a322"
|
||||||
"checksum managed 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "43e2737ecabe4ae36a68061398bf27d2bfd0763f4c3c837a398478459494c4b7"
|
"checksum managed 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "43e2737ecabe4ae36a68061398bf27d2bfd0763f4c3c837a398478459494c4b7"
|
||||||
"checksum nb 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b1411551beb3c11dedfb0a90a0fa256b47d28b9ec2cdff34c25a2fa59e45dbdc"
|
"checksum nb 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b1411551beb3c11dedfb0a90a0fa256b47d28b9ec2cdff34c25a2fa59e45dbdc"
|
||||||
"checksum proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)" = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759"
|
"checksum proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)" = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759"
|
||||||
|
@ -350,6 +383,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
"checksum rand 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c618c47cd3ebd209790115ab837de41425723956ad3ce2e6a7f09890947cacb9"
|
"checksum rand 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c618c47cd3ebd209790115ab837de41425723956ad3ce2e6a7f09890947cacb9"
|
||||||
"checksum rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b"
|
"checksum rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b"
|
||||||
"checksum rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc"
|
"checksum rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc"
|
||||||
|
"checksum regex-syntax 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)" = "11a7e20d1cce64ef2fed88b66d347f88bd9babb82845b2b858f3edbf59a4f716"
|
||||||
"checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
|
"checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
|
||||||
"checksum same-file 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d931a44fdaa43b8637009e7632a02adc4f2b2e0733c08caa4cf00e8da4a117a7"
|
"checksum same-file 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d931a44fdaa43b8637009e7632a02adc4f2b2e0733c08caa4cf00e8da4a117a7"
|
||||||
"checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
|
"checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
|
||||||
|
@ -360,6 +394,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
"checksum tm4c129x 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7d430ed4ed06dd9fff3d4517a37343e1b53789218f2f608bf1e0432f67abf624"
|
"checksum tm4c129x 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7d430ed4ed06dd9fff3d4517a37343e1b53789218f2f608bf1e0432f67abf624"
|
||||||
"checksum typenum 1.11.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6d2783fe2d6b8c1101136184eb41be8b1ad379e4657050b8aaff0c79ee7575f9"
|
"checksum typenum 1.11.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6d2783fe2d6b8c1101136184eb41be8b1ad379e4657050b8aaff0c79ee7575f9"
|
||||||
"checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc"
|
"checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc"
|
||||||
|
"checksum utf8-ranges 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b4ae116fef2b7fea257ed6440d3cfcff7f190865f170cdad00bb6465bf18ecba"
|
||||||
"checksum vcell 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "876e32dcadfe563a4289e994f7cb391197f362b6315dc45e8ba4aa6f564a4b3c"
|
"checksum vcell 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "876e32dcadfe563a4289e994f7cb391197f362b6315dc45e8ba4aa6f564a4b3c"
|
||||||
"checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
|
"checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
|
||||||
"checksum volatile-register 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0d67cb4616d99b940db1d6bd28844ff97108b498a6ca850e5b6191a532063286"
|
"checksum volatile-register 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0d67cb4616d99b940db1d6bd28844ff97108b498a6ca850e5b6191a532063286"
|
||||||
|
|
|
@ -19,6 +19,7 @@ cortex-m-semihosting = "0.3"
|
||||||
byteorder = { version = "1.3", default-features = false }
|
byteorder = { version = "1.3", default-features = false }
|
||||||
bit_field = "0.10"
|
bit_field = "0.10"
|
||||||
bare-metal = "0.2"
|
bare-metal = "0.2"
|
||||||
|
logos = { version = "~0.9", default-features = false, features = ["export_derive"] }
|
||||||
|
|
||||||
[dependencies.smoltcp]
|
[dependencies.smoltcp]
|
||||||
git = "https://github.com/m-labs/smoltcp"
|
git = "https://github.com/m-labs/smoltcp"
|
||||||
|
|
|
@ -0,0 +1,85 @@
|
||||||
|
use logos::{Logos, Lexer};
|
||||||
|
use super::session::ReportMode;
|
||||||
|
|
||||||
|
#[derive(Logos, Debug, PartialEq)]
|
||||||
|
enum Token {
|
||||||
|
#[end]
|
||||||
|
End,
|
||||||
|
#[error]
|
||||||
|
Error,
|
||||||
|
|
||||||
|
#[token = "Quit"]
|
||||||
|
Quit,
|
||||||
|
#[token = "show"]
|
||||||
|
Show,
|
||||||
|
#[token = "channel"]
|
||||||
|
Channel,
|
||||||
|
#[token = "report"]
|
||||||
|
Report,
|
||||||
|
#[token = "mode"]
|
||||||
|
Mode,
|
||||||
|
#[token = "off"]
|
||||||
|
Off,
|
||||||
|
#[token = "once"]
|
||||||
|
Once,
|
||||||
|
#[token = "continuous"]
|
||||||
|
Continuous,
|
||||||
|
|
||||||
|
#[regex = "[0-9]+"]
|
||||||
|
Number,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum Error {
|
||||||
|
Parser,
|
||||||
|
UnexpectedEnd,
|
||||||
|
UnexpectedToken(Token),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum CommandShow {
|
||||||
|
ReportMode,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum Command {
|
||||||
|
Quit,
|
||||||
|
Show(CommandShow),
|
||||||
|
Report(ReportMode),
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
impl Command {
|
||||||
|
pub fn parse(input: &str) -> Result<Self, Error> {
|
||||||
|
let mut lexer = Token::lexer(input);
|
||||||
|
|
||||||
|
macro_rules! choice {
|
||||||
|
[$($token: tt => $block: stmt,)*] => {
|
||||||
|
match lexer.token {
|
||||||
|
$(
|
||||||
|
Token::$token => {
|
||||||
|
lexer.advance();
|
||||||
|
$block
|
||||||
|
}
|
||||||
|
)*
|
||||||
|
Token::End => Err(Error::UnexpectedEnd),
|
||||||
|
_ => Err(Error::UnexpectedToken(lexer.token))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
choice![
|
||||||
|
Quit => Ok(Command::Quit),
|
||||||
|
Report => choice![
|
||||||
|
Mode => choice![
|
||||||
|
End => Ok(Command::Show(CommandShow::ReportMode)),
|
||||||
|
Off => Ok(Command::Report(ReportMode::Off)),
|
||||||
|
Once => Ok(Command::Report(ReportMode::Once)),
|
||||||
|
Continuous => Ok(Command::Report(ReportMode::Continuous)),
|
||||||
|
],
|
||||||
|
End => Ok(Command::Report(ReportMode::Once)),
|
||||||
|
],
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
|
@ -34,6 +34,10 @@ pub fn panic_fmt(info: &core::panic::PanicInfo) -> ! {
|
||||||
mod board;
|
mod board;
|
||||||
use self::board::{gpio::Gpio, systick::get_time};
|
use self::board::{gpio::Gpio, systick::get_time};
|
||||||
mod ethmac;
|
mod ethmac;
|
||||||
|
mod command_parser;
|
||||||
|
use command_parser::{Command, CommandShow};
|
||||||
|
mod session;
|
||||||
|
use self::session::{Session, SessionOutput};
|
||||||
mod ad7172;
|
mod ad7172;
|
||||||
|
|
||||||
pub struct UART0;
|
pub struct UART0;
|
||||||
|
@ -129,6 +133,7 @@ fn main() -> ! {
|
||||||
writeln!(stdout, "Corrupt ADC id: {:04X}", id).unwrap(),
|
writeln!(stdout, "Corrupt ADC id: {:04X}", id).unwrap(),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut hardware_addr = EthernetAddress(board::get_mac_address());
|
let mut hardware_addr = EthernetAddress(board::get_mac_address());
|
||||||
if hardware_addr.is_multicast() {
|
if hardware_addr.is_multicast() {
|
||||||
println!("programmed MAC address is invalid, using default");
|
println!("programmed MAC address is invalid, using default");
|
||||||
|
@ -166,21 +171,20 @@ fn main() -> ! {
|
||||||
create_socket!(sockets, tcp_rx_storage5, tcp_tx_storage5, tcp_handle5);
|
create_socket!(sockets, tcp_rx_storage5, tcp_tx_storage5, tcp_handle5);
|
||||||
create_socket!(sockets, tcp_rx_storage6, tcp_tx_storage6, tcp_handle6);
|
create_socket!(sockets, tcp_rx_storage6, tcp_tx_storage6, tcp_handle6);
|
||||||
create_socket!(sockets, tcp_rx_storage7, tcp_tx_storage7, tcp_handle7);
|
create_socket!(sockets, tcp_rx_storage7, tcp_tx_storage7, tcp_handle7);
|
||||||
let handles = [
|
let mut sessions_handles = [
|
||||||
tcp_handle0,
|
(Session::new(), tcp_handle0),
|
||||||
tcp_handle1,
|
(Session::new(), tcp_handle1),
|
||||||
tcp_handle2,
|
(Session::new(), tcp_handle2),
|
||||||
tcp_handle3,
|
(Session::new(), tcp_handle3),
|
||||||
tcp_handle4,
|
(Session::new(), tcp_handle4),
|
||||||
tcp_handle5,
|
(Session::new(), tcp_handle5),
|
||||||
tcp_handle6,
|
(Session::new(), tcp_handle6),
|
||||||
tcp_handle7,
|
(Session::new(), tcp_handle7),
|
||||||
];
|
];
|
||||||
|
|
||||||
let mut read_times = [0, 0];
|
let mut read_times = [0, 0];
|
||||||
let mut data = None;
|
let mut data = None;
|
||||||
// if a socket has sent the latest data
|
// if a socket has sent the latest data
|
||||||
let mut socket_pending = [false; 8];
|
|
||||||
loop {
|
loop {
|
||||||
let _ = adc.data_ready()
|
let _ = adc.data_ready()
|
||||||
.and_then(|channel|
|
.and_then(|channel|
|
||||||
|
@ -190,8 +194,8 @@ fn main() -> ! {
|
||||||
read_times[0] = read_times[1];
|
read_times[0] = read_times[1];
|
||||||
read_times[1] = now;
|
read_times[1] = now;
|
||||||
data = Some((now, Ok((channel, new_data))));
|
data = Some((now, Ok((channel, new_data))));
|
||||||
for p in socket_pending.iter_mut() {
|
for (session, _) in sessions_handles.iter_mut() {
|
||||||
*p = true;
|
session.set_report_pending();
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
).unwrap_or(Ok(()))
|
).unwrap_or(Ok(()))
|
||||||
|
@ -199,17 +203,43 @@ fn main() -> ! {
|
||||||
.map_err(|e| {
|
.map_err(|e| {
|
||||||
let now = get_time();
|
let now = get_time();
|
||||||
data = Some((now, Err(e)));
|
data = Some((now, Err(e)));
|
||||||
for p in socket_pending.iter_mut() {
|
for (session, _) in sessions_handles.iter_mut() {
|
||||||
*p = true;
|
session.set_report_pending();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
for (&tcp_handle, pending) in handles.iter().zip(socket_pending.iter_mut()) {
|
for (session, tcp_handle) in sessions_handles.iter_mut() {
|
||||||
let socket = &mut *sockets.get::<TcpSocket>(tcp_handle);
|
let socket = &mut *sockets.get::<TcpSocket>(*tcp_handle);
|
||||||
if !socket.is_open() {
|
if !socket.is_open() {
|
||||||
|
if session.is_dirty() {
|
||||||
|
// Reset a previously uses session/socket
|
||||||
|
*session = Session::new();
|
||||||
|
}
|
||||||
socket.listen(23).unwrap()
|
socket.listen(23).unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
if socket.may_send() && *pending {
|
if socket.may_recv() && socket.may_send() {
|
||||||
|
let command = socket.recv(|buf| session.feed(buf));
|
||||||
|
|
||||||
|
match command {
|
||||||
|
Ok(SessionOutput::Nothing) => {}
|
||||||
|
Ok(SessionOutput::Command(Command::Quit)) =>
|
||||||
|
socket.close(),
|
||||||
|
Ok(SessionOutput::Command(Command::Report(mode))) => {
|
||||||
|
let _ = writeln!(socket, "Report mode: {:?}", mode);
|
||||||
|
}
|
||||||
|
Ok(SessionOutput::Command(Command::Show(CommandShow::ReportMode))) => {
|
||||||
|
let _ = writeln!(socket, "Report mode: {:?}", session.report_mode());
|
||||||
|
}
|
||||||
|
Ok(SessionOutput::Command(command)) => {
|
||||||
|
let _ = writeln!(socket, "Not implemented: {:?}", command);
|
||||||
|
}
|
||||||
|
Ok(SessionOutput::Error(e)) => {
|
||||||
|
let _ = writeln!(socket, "Command error: {:?}", e);
|
||||||
|
}
|
||||||
|
Err(_) => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if socket.may_send() && session.is_report_pending() {
|
||||||
match &data {
|
match &data {
|
||||||
Some((time, Ok((channel, input)))) => {
|
Some((time, Ok((channel, input)))) => {
|
||||||
let interval = read_times[1] - read_times[0];
|
let interval = read_times[1] - read_times[0];
|
||||||
|
@ -223,7 +253,7 @@ fn main() -> ! {
|
||||||
}
|
}
|
||||||
None => {}
|
None => {}
|
||||||
}
|
}
|
||||||
*pending = false;
|
session.mark_report_sent();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
match iface.poll(&mut sockets, Instant::from_millis((get_time() / 1000) as i64)) {
|
match iface.poll(&mut sockets, Instant::from_millis((get_time() / 1000) as i64)) {
|
||||||
|
|
|
@ -0,0 +1,124 @@
|
||||||
|
use super::command_parser::{Command, Error as ParserError};
|
||||||
|
|
||||||
|
|
||||||
|
const MAX_LINE_LEN: usize = 64;
|
||||||
|
|
||||||
|
struct LineReader {
|
||||||
|
buf: [u8; MAX_LINE_LEN],
|
||||||
|
pos: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl LineReader {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
LineReader {
|
||||||
|
buf: [0; MAX_LINE_LEN],
|
||||||
|
pos: 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn feed(&mut self, c: u8) -> Option<&str> {
|
||||||
|
if (c == 13 || c == 10) {
|
||||||
|
// Enter
|
||||||
|
if self.pos > 0 {
|
||||||
|
let len = self.pos;
|
||||||
|
self.pos = 0;
|
||||||
|
core::str::from_utf8(&self.buf[..len]).ok()
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
} else if self.pos < self.buf.len() {
|
||||||
|
// Add input
|
||||||
|
self.buf[self.pos] = c;
|
||||||
|
self.pos += 1;
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
// Buffer is full, ignore
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy)]
|
||||||
|
pub enum ReportMode {
|
||||||
|
Off,
|
||||||
|
Once,
|
||||||
|
Continuous,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub enum SessionOutput {
|
||||||
|
Nothing,
|
||||||
|
Command(Command),
|
||||||
|
Error(ParserError),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Result<Command, ParserError>> for SessionOutput {
|
||||||
|
fn from(input: Result<Command, ParserError>) -> Self {
|
||||||
|
input.map(SessionOutput::Command)
|
||||||
|
.unwrap_or_else(SessionOutput::Error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Session {
|
||||||
|
reader: LineReader,
|
||||||
|
report_mode: ReportMode,
|
||||||
|
report_pending: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Session {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Session {
|
||||||
|
reader: LineReader::new(),
|
||||||
|
report_mode: ReportMode::Off,
|
||||||
|
report_pending: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn is_dirty(&self) -> bool {
|
||||||
|
self.reader.pos > 0
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn report_mode(&self) -> ReportMode {
|
||||||
|
self.report_mode
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_report_pending(&mut self) {
|
||||||
|
self.report_pending = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn is_report_pending(&self) -> bool {
|
||||||
|
match self.report_mode {
|
||||||
|
ReportMode::Off => false,
|
||||||
|
_ => self.report_pending,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn mark_report_sent(&mut self) {
|
||||||
|
self.report_pending = false;
|
||||||
|
match self.report_mode {
|
||||||
|
ReportMode::Once =>
|
||||||
|
self.report_mode = ReportMode::Off,
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn feed(&mut self, buf: &[u8]) -> (usize, SessionOutput) {
|
||||||
|
let mut buf_bytes = 0;
|
||||||
|
for (i, b) in buf.iter().enumerate() {
|
||||||
|
buf_bytes = i + 1;
|
||||||
|
match self.reader.feed(*b) {
|
||||||
|
Some(line) => {
|
||||||
|
let command = Command::parse(line);
|
||||||
|
match command {
|
||||||
|
Ok(Command::Report(mode)) => {
|
||||||
|
self.report_mode = mode;
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
return (buf_bytes, command.into());
|
||||||
|
}
|
||||||
|
None => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
(buf_bytes, SessionOutput::Nothing)
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue