application: Set up a Logger instance.
[gps-watch.git] / src / common / shell.rs
index 09c79079d62178444b6d1f0dd82553dd4b616a92..bb59b62e322f62edd5e81685d9cf4664361f3837 100644 (file)
@@ -22,6 +22,9 @@
  */
 
 use buffer::Buffer;
+use logger::Logger;
+use yencode::Yencode;
+use systick;
 
 pub struct Shell<'a> {
     tx_buf: &'a mut Buffer,
@@ -88,6 +91,23 @@ fn read_char() -> Option<u8> {
     }
 }
 
+fn read_char_delay_ms(limit_ms: u32) -> Option<u8> {
+    let mut total_delay_ms = 0u32;
+
+    while total_delay_ms < limit_ms {
+        if let Some(c) = read_char() {
+            return Some(c);
+        }
+
+        let ms = 50;
+
+        systick::delay_ms(ms);
+        total_delay_ms += ms;
+    }
+
+    None
+}
+
 impl<'a> Shell<'a> {
     pub fn new(tx_buf: &mut Buffer) -> Shell {
         Shell {
@@ -97,7 +117,7 @@ impl<'a> Shell<'a> {
         }
     }
 
-    pub fn update(&mut self) {
+    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() {
@@ -112,7 +132,7 @@ impl<'a> Shell<'a> {
                     self.command_buffer[command_length] = b'\0';
 
                     if command_length != 0 {
-                        self.dispatch(command_length);
+                        self.dispatch(command_length, logger);
                     }
                 } else {
                     self.command_buffer[self.command_offset] = b'\0';
@@ -126,7 +146,7 @@ impl<'a> Shell<'a> {
         }
     }
 
-    fn dispatch(&mut self, command_length: usize) {
+    fn dispatch(&mut self, command_length: usize, logger: &mut Logger) {
         let command : [u8; 32] = self.command_buffer;
 
         let mut args_iter = ArgumentIter {
@@ -139,11 +159,16 @@ impl<'a> Shell<'a> {
                 let usage = b"\
 Supported commands:
     help           Show this help message.
+    clear_storage  Fully erase the flash's contents.
+    dump_storage   Dump the flash's contents.
 ";
 
                 self.tx_buf.write(usage);
             },
 
+            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: ");
                 self.tx_buf.write(other);
@@ -154,4 +179,44 @@ Supported commands:
             }
         }
     }
+
+    fn run_clear_storage(&self, logger: &mut Logger) {
+        logger.storage.clear();
+    }
+
+    fn run_dump_storage(&mut self, logger: &mut Logger) {
+        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 mut yenc = Yencode::new(&mut self.tx_buf);
+
+            yenc.start(b"gps-watch-storage.bin");
+
+            const CHUNK_SIZE: usize = 1024;
+            let num_chunks = logger.storage.size() / CHUNK_SIZE;
+
+            for i in 0..num_chunks {
+                let mut buf = [0u8; CHUNK_SIZE];
+
+                logger.storage.read(i * CHUNK_SIZE, &mut buf);
+
+                yenc.data(&buf);
+            }
+
+            yenc.finish();
+
+            true
+        });
+
+        if !have_receiver {
+            self.tx_buf.write(b"no signal from receiver\n");
+        }
+
+        self.tx_buf.flush();
+    }
 }