X-Git-Url: http://git.code-monkey.de/?a=blobdiff_plain;f=src%2Fcommon%2Fshell.rs;h=59472f6c9eb029d5e4aa6c70649586fa2a7f379c;hb=ad586de91fbe9648414f4fbaab0b3b0b85d67cb3;hp=730a0a89fd78a85131fe221d943d5f5425ef0426;hpb=b0d277d6cb2a60e8dd3ec94b6c1dae569f8070bf;p=gps-watch.git diff --git a/src/common/shell.rs b/src/common/shell.rs index 730a0a8..59472f6 100644 --- a/src/common/shell.rs +++ b/src/common/shell.rs @@ -22,7 +22,7 @@ */ use buffer::Buffer; -use storage::Storage; +use logger::Logger; use yencode::Yencode; use systick; @@ -79,6 +79,44 @@ impl<'a> Iterator for ArgumentIter<'a> { } } +fn atoi32(s: &[u8]) -> Option { + let mut u = 0u32; + + for o in 0..s.len() { + let c = s[o]; + let zero = b'0' as u8; + let nine = b'9' as u8; + + if c < zero || c > nine { + return None; + } + + let d = (c - zero) as u32; + + if let Some(u2) = u.checked_mul(10) { + if let Some(u3) = u2.checked_add(d) { + u = u3; + } else { + return None; + } + } else { + return None; + } + } + + Some(u) +} + +fn atoi16(s: &[u8]) -> Option { + atoi32(s).and_then(|u| { + if u <= u16::max_value() as u32 { + Some(u as u16) + } else { + None + } + }) +} + fn read_char() -> Option { unsafe { let mut c = b'\0'; @@ -108,10 +146,6 @@ fn read_char_delay_ms(limit_ms: u32) -> Option { None } -struct Context<'a> { - storage: &'a mut dyn Storage, -} - impl<'a> Shell<'a> { pub fn new(tx_buf: &mut Buffer) -> Shell { Shell { @@ -121,11 +155,7 @@ impl<'a> Shell<'a> { } } - pub fn update(&mut self, storage: &mut dyn Storage) { - let mut context = Context { - storage: storage, - }; - + pub fn update(&mut self, logger: &mut Logger) { while let Some(c) = read_char() { if c != b'\n' { if self.command_offset != self.command_buffer.len() { @@ -140,7 +170,7 @@ impl<'a> Shell<'a> { self.command_buffer[command_length] = b'\0'; if command_length != 0 { - self.dispatch(command_length, &mut context); + self.dispatch(command_length, logger); } } else { self.command_buffer[self.command_offset] = b'\0'; @@ -154,7 +184,7 @@ impl<'a> Shell<'a> { } } - fn dispatch(&mut self, command_length: usize, mut context: &mut Context) { + fn dispatch(&mut self, command_length: usize, logger: &mut Logger) { let command : [u8; 32] = self.command_buffer; let mut args_iter = ArgumentIter { @@ -167,6 +197,7 @@ impl<'a> Shell<'a> { let usage = b"\ Supported commands: help Show this help message. + get REC_ID Retrieve recording. clear_storage Fully erase the flash's contents. dump_storage Dump the flash's contents. "; @@ -174,8 +205,9 @@ Supported commands: self.tx_buf.write(usage); }, - Some(b"clear_storage") => self.run_clear_storage(&mut context), - Some(b"dump_storage") => self.run_dump_storage(&mut context), + Some(b"get") => self.run_get(logger, &mut args_iter), + Some(b"clear_storage") => self.run_clear_storage(logger), + Some(b"dump_storage") => self.run_dump_storage(logger), Some(ref other) => { self.tx_buf.write(b"unknown_command: "); @@ -188,11 +220,49 @@ Supported commands: } } - fn run_clear_storage(&self, context: &mut Context) { - context.storage.clear(); + fn run_get(&mut self, logger: &mut Logger, args_iter: &mut ArgumentIter) { + if let Some(recording_id_s) = args_iter.next() { + if let Some(recording_id) = atoi16(recording_id_s) { + if logger.has_recording(recording_id) { + self.tx_buf.write(b"waiting for receiver to start...\n"); + self.tx_buf.flush(); + + let have_receiver = read_char_delay_ms(5000).map(|c| { + c == b'R' + }).map_or_else(|| { + false + }, |_| { + let result = logger.get_recording(recording_id, + self.tx_buf); + + if result.is_err() { + self.tx_buf.write(b"get: failed to retrieve recording\n"); + } + + true + }); + + if !have_receiver { + self.tx_buf.write(b"no signal from receiver\n"); + } + } else { + self.tx_buf.write(b"get: no such recording\n"); + } + } else { + self.tx_buf.write(b"get: invalid argument\n"); + } + } else { + self.tx_buf.write(b"get: missing argument\n"); + } + + self.tx_buf.flush(); + } + + fn run_clear_storage(&self, logger: &mut Logger) { + logger.storage.clear(); } - fn run_dump_storage(&mut self, context: &mut Context) { + fn run_dump_storage(&mut self, logger: &mut Logger) { self.tx_buf.write(b"waiting for receiver to start...\n"); self.tx_buf.flush(); @@ -206,12 +276,12 @@ Supported commands: yenc.start(b"gps-watch-storage.bin"); const CHUNK_SIZE: usize = 1024; - let num_chunks = context.storage.size() / CHUNK_SIZE; + let num_chunks = logger.storage.size() / CHUNK_SIZE; for i in 0..num_chunks { let mut buf = [0u8; CHUNK_SIZE]; - context.storage.read(i * CHUNK_SIZE, &mut buf); + logger.storage.read(i * CHUNK_SIZE, &mut buf); yenc.data(&buf); }