tockloader_proto/
lib.rs

1//! Implements the Tockloader protocol.
2//!
3//! TockOS applications are loaded with `tockloader`.
4//! This speaks to the TockOS bootloader using a specific
5//! protocol. This crate implements that protocol so
6//! that you can write future tockloader compatible bootloaders
7//! in Rust!
8
9#![no_std]
10
11// ****************************************************************************
12//
13// Imports
14//
15// ****************************************************************************
16
17extern crate byteorder;
18
19use byteorder::{LittleEndian, ByteOrder};
20
21pub mod prelude {
22    pub use super::Encoder;
23}
24
25// ****************************************************************************
26//
27// Public Types
28//
29// ****************************************************************************
30
31/// Commands supported by the protocol. A bootloader will decode these and a
32/// flash tool will encode them.
33#[derive(Debug, PartialEq)]
34pub enum Command<'a> {
35    /// Send a PING to the bootloader. It will drop its hp buffer and send
36    /// back a PONG.
37    Ping,
38    /// Get info about the bootloader. The result is one byte of length, plus
39    /// length bytes of string, followed by 192-length zeroes.
40    Info,
41    /// Get the Unique ID. Result is 8 bytes of unique ID (but I'm not sure
42    /// what the result code should be).
43    Id,
44    /// Reset all TX and RX buffers.
45    Reset,
46    /// Erase a page. The RX buffer should contain the address of the start of
47    /// the 512 byte page. Any non-page-aligned addresses will result in
48    /// RES_BADADDR. This command is not required before writing a page, it is
49    /// just an optimisation. It is particularly quick for already empty pages.
50    ErasePage { address: u32 },
51    /// Write a page in internal flash. The RX buffer should contain the 4
52    /// byte address of the start of the page, followed by 512 bytes of page.
53    WritePage { address: u32, data: &'a [u8] },
54    /// Erase a block of pages in ex flash. The RX buffer should contain the
55    /// address of the start of the block. Each block is 8 pages, so 2048
56    /// bytes.
57    EraseExBlock { address: u32 },
58    /// Write a page to ex flash. The RX buffer should contain the address of
59    /// the start of the 256 byte page, followed by 256 bytes of page.
60    WriteExPage { address: u32, data: &'a [u8] },
61    /// Get the length and CRC of the RX buffer. The response is two bytes of
62    /// little endian length, followed by 4 bytes of crc32.
63    CrcRxBuffer,
64    /// Read a range from internal flash. The RX buffer should contain a 4
65    /// byte address followed by 2 bytes of length. The response will be
66    /// length bytes long.
67    ReadRange { address: u32, length: u16 },
68    /// Read a range from external flash. The RX buffer should contain a 4
69    /// byte address followed by 2 bytes of length. The response will be
70    /// length bytes long.
71    ExReadRange { address: u32, length: u16 },
72    /// Write a payload attribute. The RX buffer should contain a one byte
73    /// index, 8 bytes of key (null padded), one byte of value length, and
74    /// valuelength value bytes. valuelength must be less than or equal to 55.
75    /// The value may contain nulls.
76    ///
77    /// The attribute index must be less than 16.
78    SetAttr {
79        index: u8,
80        key: &'a [u8],
81        value: &'a [u8],
82    },
83    /// Get a payload attribute. The RX buffer should contain a 1 byte index.
84    /// The result is 8 bytes of key, 1 byte of value length, and 55 bytes of
85    /// potential value. You must discard 55-valuelength bytes from the end
86    /// yourself.
87    GetAttr { index: u8 },
88    /// Get the CRC of a range of internal flash. The RX buffer should contain
89    /// a four byte address and a four byte range. The result will be a four
90    /// byte crc32.
91    CrcIntFlash { address: u32, length: u32 },
92    /// Get the CRC of a range of external flash. The RX buffer should contain
93    /// a four byte address and a four byte range. The result will be a four
94    /// byte crc32.
95    CrcExtFlash { address: u32, length: u32 },
96    /// Erase a page in external flash. The RX buffer should contain a 4 byte
97    /// address pointing to the start of the 256 byte page.
98    EraseExPage { address: u32 },
99    /// Initialise the external flash chip. This sets the page size to 256b.
100    ExtFlashInit,
101    /// Go into an infinite loop with the 32khz clock present on pin PA19
102    /// (GP6) this is used for clock calibration.
103    ClockOut,
104    /// Write the flash user pages (first 4 bytes is first page, second 4
105    /// bytes is second page, little endian).
106    WriteFlashUserPages { page1: u32, page2: u32 },
107    /// Change the baud rate of the bootloader. The first byte is 0x01 to set
108    /// a new baud rate. The next 4 bytes are the new baud rate. To allow the
109    /// bootloader to verify that the new baud rate works, the host must call
110    /// this command again with the first byte of 0x02 and the next 4 bytes of
111    /// the new baud rate. If the next command does not match this, the
112    /// bootloader will revert to the old baud rate.
113    ChangeBaud { mode: BaudMode, baud: u32 },
114}
115
116/// Reponses supported by the protocol. A bootloader will encode these
117/// and a flash tool will decode them.
118#[derive(Debug, PartialEq)]
119pub enum Response<'a> {
120    Overflow, // RES_OVERFLOW
121    Pong, // RES_PONG
122    BadAddress, // RES_BADADDR
123    InternalError, // RES_INTERROR
124    BadArguments, // RES_BADARGS
125    Ok, // RES_OK
126    Unknown, // RES_UNKNOWN
127    ExtFlashTimeout, // RES_XFTIMEOUT
128    ExtFlashPageError, // RES_XFEPE ??
129    CrcRxBuffer { length: u16, crc: u32 }, // RES_CRCRX
130    ReadRange { data: &'a [u8] }, // RES_RRANGE
131    ExReadRange { data: &'a [u8] }, // RES_XRRANGE
132    GetAttr { key: &'a [u8], value: &'a [u8] }, // RES_GATTR
133    CrcIntFlash { crc: u32 }, // RES_CRCIF
134    CrcExtFlash { crc: u32 }, // RES_CRCXF
135    Info { info: &'a [u8] }, // RES_INFO
136    ChangeBaudFail, // RES_CHANGE_BAUD_FAIL
137}
138
139#[derive(Debug, PartialEq)]
140pub enum Error {
141    /// We got a command we didn't understand.
142    UnknownCommand,
143    /// We didn't like the arguments given with a command.
144    BadArguments,
145    /// The user didn't call `set_payload_len` yet we
146    /// got a response of unbounded length.
147    UnsetLength,
148    /// The user called `set_payload_len` yet we
149    /// got a response of bounded length.
150    SetLength,
151    /// The buffer passed by the user wasn't large enough for the packet.
152    BufferTooSmall,
153}
154
155/// The `ComandDecoder` takes bytes and gives you `Command`s.
156pub struct CommandDecoder {
157    state: DecoderState,
158    buffer: [u8; 520],
159    count: usize,
160}
161
162/// The `ResponseDecoder` takes bytes and gives you `Responses`s.
163pub struct ResponseDecoder {
164    state: DecoderState,
165    buffer: [u8; 520],
166    count: usize,
167    needed: Option<usize>,
168}
169
170/// The `CommandEncoder` takes a `Command` and gives you bytes.
171pub struct CommandEncoder<'a> {
172    command: &'a Command<'a>,
173    count: usize,
174    sent_escape: bool,
175}
176
177/// The `ResponseEncoder` takes a `Response` and gives you bytes.
178pub struct ResponseEncoder<'a> {
179    response: &'a Response<'a>,
180    count: usize,
181    sent_escape: bool,
182}
183
184#[derive(Debug, PartialEq, Clone, Copy)]
185pub enum BaudMode {
186    Set, // 0x01
187    Verify, // 0x02
188}
189
190// ****************************************************************************
191//
192// Public Data
193//
194// ****************************************************************************
195
196// None
197
198// ****************************************************************************
199//
200// Private Types
201//
202// ****************************************************************************
203
204enum DecoderState {
205    Loading,
206    Escape,
207}
208
209// ****************************************************************************
210//
211// Private Data
212//
213// ****************************************************************************
214
215const ESCAPE_CHAR: u8 = 0xFC;
216
217const CMD_PING: u8 = 0x01;
218const CMD_INFO: u8 = 0x03;
219const CMD_ID: u8 = 0x04;
220const CMD_RESET: u8 = 0x05;
221const CMD_EPAGE: u8 = 0x06;
222const CMD_WPAGE: u8 = 0x07;
223const CMD_XEBLOCK: u8 = 0x08;
224const CMD_XWPAGE: u8 = 0x09;
225const CMD_CRCRX: u8 = 0x10;
226const CMD_RRANGE: u8 = 0x11;
227const CMD_XRRANGE: u8 = 0x12;
228const CMD_SATTR: u8 = 0x13;
229const CMD_GATTR: u8 = 0x14;
230const CMD_CRCIF: u8 = 0x15;
231const CMD_CRCEF: u8 = 0x16;
232const CMD_XEPAGE: u8 = 0x17;
233const CMD_XFINIT: u8 = 0x18;
234const CMD_CLKOUT: u8 = 0x19;
235const CMD_WUSER: u8 = 0x20;
236const CMD_CHANGE_BAUD: u8 = 0x21;
237
238const RES_OVERFLOW: u8 = 0x10;
239const RES_PONG: u8 = 0x11;
240const RES_BADADDR: u8 = 0x12;
241const RES_INTERROR: u8 = 0x13;
242const RES_BADARGS: u8 = 0x14;
243const RES_OK: u8 = 0x15;
244const RES_UNKNOWN: u8 = 0x16;
245const RES_XFTIMEOUT: u8 = 0x17;
246const RES_XFEPE: u8 = 0x18;
247const RES_CRCRX: u8 = 0x19;
248const RES_RRANGE: u8 = 0x20;
249const RES_XRRANGE: u8 = 0x21;
250const RES_GATTR: u8 = 0x22;
251const RES_CRCIF: u8 = 0x23;
252const RES_CRCXF: u8 = 0x24;
253const RES_INFO: u8 = 0x25;
254const RES_CHANGE_BAUD_FAIL: u8 = 0x26;
255
256const MAX_INDEX: u8 = 16;
257const KEY_LEN: usize = 8;
258const MAX_ATTR_LEN: usize = 55;
259const INT_PAGE_SIZE: usize = 512;
260const EXT_PAGE_SIZE: usize = 256;
261const MAX_INFO_LEN: usize = 192;
262
263// ****************************************************************************
264//
265// Public Impl/Functions/Modules
266//
267// ****************************************************************************
268
269pub trait Encoder: Iterator<Item = u8> {
270    fn reset(&mut self);
271
272    /// Encode to bytes, storing them in the given buffer.
273    /// Returns the amount of buffer space used.
274    fn write(&mut self, buffer: &mut [u8]) -> usize {
275        for i in 0..buffer.len() {
276            if let Some(ch) = self.next() {
277                // Copy over byte
278                buffer[i] = ch;
279            } else {
280                // We're finished outputting bytes
281                return i;
282            }
283        }
284        // Got to the end - whole buffer used
285        return buffer.len();
286    }
287}
288
289impl CommandDecoder {
290    /// Create a new `CommandDecoder`.
291    ///
292    /// The decoder is fed bytes with the `receive` method.
293    pub fn new() -> CommandDecoder {
294        CommandDecoder {
295            state: DecoderState::Loading,
296            buffer: [0u8; 520],
297            count: 0,
298        }
299    }
300
301    /// Decode a whole buffers worth of bytes.
302    ///
303    /// Due to lifetime problems, the decoded `Command`s are sent via `callback` rather
304    /// than being returned.
305    pub fn read<F>(&mut self, buffer: &[u8], callback: F) -> Result<(), Error>
306    where
307        F: Fn(&Command),
308    {
309        for ch in buffer {
310            match self.receive(*ch) {
311                Err(e) => return Err(e),
312                Ok(None) => {}
313                Ok(Some(ref cmd)) => callback(cmd),
314            }
315        }
316        Ok(())
317    }
318
319    /// Empty the RX buffer.
320    pub fn reset(&mut self) {
321        self.count = 0;
322    }
323
324    /// Process incoming bytes.
325    ///
326    /// The decoder is fed bytes with the `receive` method. If not enough
327    /// bytes have been seen, this function returns `None`. Once enough bytes
328    /// have been seen, it returns `Ok(Some(Command))` containing the decoded
329    /// Command. It returns `Err` if it doesn't like the byte received.
330    pub fn receive(&mut self, ch: u8) -> Result<Option<Command>, Error> {
331        match self.state {
332            DecoderState::Loading => self.handle_loading(ch),
333            DecoderState::Escape => self.handle_escape(ch),
334        }
335    }
336
337    fn load_char(&mut self, ch: u8) {
338        if self.count < self.buffer.len() {
339            self.buffer[self.count] = ch;
340            self.count = self.count + 1;
341        }
342    }
343
344    fn handle_loading(&mut self, ch: u8) -> Result<Option<Command>, Error> {
345        if ch == ESCAPE_CHAR {
346            self.state = DecoderState::Escape;
347        } else {
348            self.load_char(ch);
349        }
350        Ok(None)
351    }
352
353    fn handle_escape(&mut self, ch: u8) -> Result<Option<Command>, Error> {
354        self.state = DecoderState::Loading;
355        let result: Result<Option<Command>, Error> = match ch {
356            ESCAPE_CHAR => {
357                // Double escape means just load an escape
358                self.load_char(ch);
359                Ok(None)
360            }
361            CMD_PING => Ok(Some(Command::Ping)),
362            CMD_INFO => Ok(Some(Command::Info)),
363            CMD_ID => Ok(Some(Command::Id)),
364            CMD_RESET => Ok(Some(Command::Reset)),
365            CMD_EPAGE => {
366                let num_expected_bytes: usize = 4;
367                if self.count == num_expected_bytes {
368                    let address = LittleEndian::read_u32(&self.buffer[0..4]);
369                    Ok(Some(Command::ErasePage { address }))
370                } else {
371                    Err(Error::BadArguments)
372                }
373            }
374            CMD_WPAGE => {
375                let num_expected_bytes: usize = INT_PAGE_SIZE + 4;
376                if self.count == num_expected_bytes {
377                    let payload = &self.buffer[0..num_expected_bytes];
378                    let address = LittleEndian::read_u32(&payload[0..4]);
379                    Ok(Some(Command::WritePage {
380                        address,
381                        data: &payload[4..num_expected_bytes],
382                    }))
383                } else {
384                    Err(Error::BadArguments)
385                }
386            }
387            CMD_XEBLOCK => {
388                let num_expected_bytes: usize = 4;
389                if self.count == num_expected_bytes {
390                    let address = LittleEndian::read_u32(&self.buffer[0..4]);
391                    Ok(Some(Command::EraseExBlock { address }))
392                } else {
393                    Err(Error::BadArguments)
394                }
395            }
396            CMD_XWPAGE => {
397                let num_expected_bytes: usize = EXT_PAGE_SIZE + 4;
398                if self.count == num_expected_bytes {
399                    let payload = &self.buffer[0..num_expected_bytes];
400                    let address = LittleEndian::read_u32(&payload[0..4]);
401                    Ok(Some(Command::WriteExPage {
402                        address,
403                        data: &payload[4..num_expected_bytes],
404                    }))
405                } else {
406                    Err(Error::BadArguments)
407                }
408            }
409            CMD_CRCRX => Ok(Some(Command::CrcRxBuffer)),
410            CMD_RRANGE => {
411                let num_expected_bytes: usize = 6;
412                if self.count == num_expected_bytes {
413                    let address = LittleEndian::read_u32(&self.buffer[0..4]);
414                    let length = LittleEndian::read_u16(&self.buffer[4..6]);
415                    Ok(Some(Command::ReadRange { address, length }))
416                } else {
417                    Err(Error::BadArguments)
418                }
419            }
420            CMD_XRRANGE => {
421                let num_expected_bytes: usize = 6;
422                if self.count == num_expected_bytes {
423                    let address = LittleEndian::read_u32(&self.buffer[0..4]);
424                    let length = LittleEndian::read_u16(&self.buffer[4..6]);
425                    Ok(Some(Command::ExReadRange { address, length }))
426                } else {
427                    Err(Error::BadArguments)
428                }
429            }
430            CMD_SATTR => {
431                let num_expected_bytes: usize = 10;
432                if self.count >= num_expected_bytes {
433                    let index = self.buffer[0];
434                    let key = &self.buffer[1..9];
435                    let length = self.buffer[9] as usize;
436                    if self.count == (num_expected_bytes + length) {
437                        let value = &self.buffer[10..10 + length];
438                        Ok(Some(Command::SetAttr { index, key, value }))
439                    } else {
440                        Err(Error::BadArguments)
441                    }
442                } else {
443                    Err(Error::BadArguments)
444                }
445            }
446            CMD_GATTR => {
447                let num_expected_bytes: usize = 1;
448                if self.count == num_expected_bytes {
449                    let index = self.buffer[0];
450                    Ok(Some(Command::GetAttr { index }))
451                } else {
452                    Err(Error::BadArguments)
453                }
454            }
455            CMD_CRCIF => {
456                let num_expected_bytes: usize = 8;
457                if self.count == num_expected_bytes {
458                    let address = LittleEndian::read_u32(&self.buffer[0..4]);
459                    let length = LittleEndian::read_u32(&self.buffer[4..8]);
460                    Ok(Some(Command::CrcIntFlash { address, length }))
461                } else {
462                    Err(Error::BadArguments)
463                }
464            }
465            CMD_CRCEF => {
466                let num_expected_bytes: usize = 8;
467                if self.count == num_expected_bytes {
468                    let address = LittleEndian::read_u32(&self.buffer[0..4]);
469                    let length = LittleEndian::read_u32(&self.buffer[4..8]);
470                    Ok(Some(Command::CrcExtFlash { address, length }))
471                } else {
472                    Err(Error::BadArguments)
473                }
474            }
475            CMD_XEPAGE => {
476                let num_expected_bytes: usize = 4;
477                if self.count == num_expected_bytes {
478                    let address = LittleEndian::read_u32(&self.buffer[0..4]);
479                    Ok(Some(Command::EraseExPage { address }))
480                } else {
481                    Err(Error::BadArguments)
482                }
483            }
484            CMD_XFINIT => Ok(Some(Command::ExtFlashInit)),
485            CMD_CLKOUT => Ok(Some(Command::ClockOut)),
486            CMD_WUSER => {
487                let num_expected_bytes: usize = 8;
488                if self.count == num_expected_bytes {
489                    let page1 = LittleEndian::read_u32(&self.buffer[0..4]);
490                    let page2 = LittleEndian::read_u32(&self.buffer[4..8]);
491                    Ok(Some(Command::WriteFlashUserPages { page1, page2 }))
492                } else {
493                    Err(Error::BadArguments)
494                }
495            }
496            CMD_CHANGE_BAUD => {
497                let num_expected_bytes: usize = 5;
498                if self.count == num_expected_bytes {
499                    let mode = self.buffer[0];
500                    let baud = LittleEndian::read_u32(&self.buffer[1..5]);
501                    match mode {
502                        0x01 => Ok(Some(Command::ChangeBaud {
503                            mode: BaudMode::Set,
504                            baud,
505                        })),
506                        0x02 => Ok(Some(Command::ChangeBaud {
507                            mode: BaudMode::Verify,
508                            baud,
509                        })),
510                        _ => Err(Error::BadArguments),
511
512                    }
513                } else {
514                    Err(Error::BadArguments)
515                }
516            }
517            _ => Ok(None),
518        };
519        // A command or error signifies the end of the buffer
520        if let Ok(Some(_)) = result {
521            self.count = 0;
522        } else if let Err(_) = result {
523            self.count = 0;
524        }
525        result
526    }
527}
528
529impl ResponseDecoder {
530    /// Create a new `ResponseDecoder`.
531    ///
532    /// The decoder is fed bytes with the `receive` method.
533    pub fn new() -> ResponseDecoder {
534        ResponseDecoder {
535            state: DecoderState::Loading,
536            buffer: [0u8; 520],
537            count: 0,
538            needed: None,
539        }
540    }
541
542    /// Decode a whole buffers worth of bytes.
543    ///
544    /// Due to lifetime problems, the decoded `Response`s are sent via `callback` rather
545    /// than being returned.
546    pub fn read<F>(&mut self, buffer: &[u8], callback: F) -> Result<(), Error>
547    where
548        F: Fn(&Response),
549    {
550        for ch in buffer {
551            match self.receive(*ch) {
552                Err(e) => return Err(e),
553                Ok(None) => {}
554                Ok(Some(ref cmd)) => callback(cmd),
555            }
556        }
557        Ok(())
558    }
559
560    /// Empty the RX buffer.
561    pub fn reset(&mut self) {
562        self.count = 0;
563    }
564
565    /// Process incoming bytes.
566    ///
567    /// The decoder is fed bytes with the `receive` method. If not enough
568    /// bytes have been seen, this function returns `None`. Once enough bytes
569    /// have been seen, it returns `Some(Response)` containing the
570    /// decoded Response.
571    pub fn receive(&mut self, ch: u8) -> Result<Option<Response>, Error> {
572        match self.state {
573            DecoderState::Loading => self.handle_loading(ch),
574            DecoderState::Escape => self.handle_escape(ch),
575        }
576    }
577
578    /// Set the expected length of an unbounded message. This
579    /// depends entirely on the last command you sent.
580    pub fn set_payload_len(&mut self, length: usize) -> Result<(), Error> {
581        match self.needed {
582            Some(_) => Err(Error::SetLength),
583            None => {
584                self.needed = Some(length + 1);
585                Ok(())
586            }
587        }
588    }
589
590    fn load_char(&mut self, ch: u8) -> Result<Option<Response>, Error> {
591        if self.count < self.buffer.len() {
592            self.buffer[self.count] = ch;
593            self.count = self.count + 1;
594        }
595        if self.needed == Some(self.count) {
596            let result = match self.buffer[0] {
597                RES_CRCRX => {
598                    let length = LittleEndian::read_u16(&self.buffer[1..3]);
599                    let crc = LittleEndian::read_u32(&self.buffer[3..7]);
600                    Ok(Some(Response::CrcRxBuffer { length, crc }))
601                }
602                RES_RRANGE => {
603                    let data = &self.buffer[1..self.count];
604                    Ok(Some(Response::ReadRange { data }))
605                }
606                RES_XRRANGE => {
607                    let data = &self.buffer[1..self.count];
608                    Ok(Some(Response::ExReadRange { data }))
609                }
610                RES_GATTR => {
611                    let key = &self.buffer[1..9];
612                    let length = self.buffer[9] as usize;
613                    if (9 + length) <= self.count {
614                        let value = &self.buffer[10..(10 + length)];
615                        Ok(Some(Response::GetAttr { key, value }))
616                    } else {
617                        Err(Error::BadArguments)
618                    }
619                }
620                RES_CRCIF => {
621                    let crc = LittleEndian::read_u32(&self.buffer[1..5]);
622                    Ok(Some(Response::CrcIntFlash { crc }))
623                }
624                RES_CRCXF => {
625                    let crc = LittleEndian::read_u32(&self.buffer[1..5]);
626                    Ok(Some(Response::CrcExtFlash { crc }))
627                }
628                RES_INFO => {
629                    let length: usize = self.buffer[1] as usize;
630                    if length + 1 < self.count {
631                        let info = &self.buffer[2..length + 2];
632                        Ok(Some(Response::Info { info }))
633                    } else {
634                        Err(Error::BadArguments)
635                    }
636                }
637                _ => Err(Error::UnknownCommand),
638            };
639            self.needed = None;
640            self.count = 0;
641            result
642        } else {
643            Ok(None)
644        }
645    }
646
647    fn handle_loading(&mut self, ch: u8) -> Result<Option<Response>, Error> {
648        if ch == ESCAPE_CHAR {
649            self.state = DecoderState::Escape;
650            Ok(None)
651        } else {
652            self.load_char(ch)
653        }
654    }
655
656    fn handle_escape(&mut self, ch: u8) -> Result<Option<Response>, Error> {
657        self.state = DecoderState::Loading;
658        match ch {
659            ESCAPE_CHAR => {
660                // Double escape means just load an escape
661                self.load_char(ch)
662            }
663            RES_PONG => {
664                self.count = 0;
665                self.needed = None;
666                Ok(Some(Response::Pong))
667            }
668            RES_OVERFLOW => {
669                self.count = 0;
670                self.needed = None;
671                Ok(Some(Response::Overflow))
672            }
673            RES_BADADDR => {
674                self.count = 0;
675                self.needed = None;
676                Ok(Some(Response::BadAddress))
677            }
678            RES_INTERROR => {
679                self.count = 0;
680                self.needed = None;
681                Ok(Some(Response::InternalError))
682            }
683            RES_BADARGS => {
684                self.count = 0;
685                self.needed = None;
686                Ok(Some(Response::BadArguments))
687            }
688            RES_OK => {
689                self.count = 0;
690                self.needed = None;
691                Ok(Some(Response::Ok))
692            }
693            RES_UNKNOWN => {
694                self.count = 0;
695                self.needed = None;
696                Ok(Some(Response::Unknown))
697            }
698            RES_XFTIMEOUT => {
699                self.count = 0;
700                self.needed = None;
701                Ok(Some(Response::ExtFlashTimeout))
702            }
703            RES_XFEPE => {
704                self.count = 0;
705                self.needed = None;
706                Ok(Some(Response::ExtFlashPageError))
707            }
708            RES_CHANGE_BAUD_FAIL => {
709                self.count = 0;
710                self.needed = None;
711                Ok(Some(Response::ChangeBaudFail))
712            }
713            RES_CRCRX => {
714                self.set_payload_len(6)?;
715                self.load_char(ch)?;
716                Ok(None)
717            }
718            RES_RRANGE => {
719                if self.needed.is_none() {
720                    Err(Error::UnsetLength)
721                } else {
722                    self.load_char(ch)?;
723                    Ok(None)
724                }
725            }
726            RES_XRRANGE => {
727                if self.needed.is_none() {
728                    Err(Error::UnsetLength)
729                } else {
730                    self.load_char(ch)?;
731                    Ok(None)
732                }
733            }
734            RES_GATTR => {
735                self.set_payload_len(1 + KEY_LEN + MAX_ATTR_LEN)?;
736                self.load_char(ch)?;
737                Ok(None)
738            }
739            RES_CRCIF => {
740                self.set_payload_len(4)?;
741                self.load_char(ch)?;
742                Ok(None)
743            }
744            RES_CRCXF => {
745                self.set_payload_len(4)?;
746                self.load_char(ch)?;
747                Ok(None)
748            }
749            RES_INFO => {
750                // length + data
751                self.set_payload_len(1 + MAX_INFO_LEN)?;
752                self.load_char(ch)?;
753                Ok(None)
754            }
755            _ => Ok(None),
756        }
757    }
758}
759
760impl<'a> CommandEncoder<'a> {
761    /// Create a new `CommandEncoder`.
762    ///
763    /// The encoder takes a reference to a `Command` to encode. The `next` method
764    /// will then supply the encoded bytes one at a time.
765    pub fn new(command: &'a Command) -> Result<CommandEncoder<'a>, Error> {
766        // We have to accept slices rather than arrays, so bounds check them
767        // all now to save surprises later.
768        match command {
769            &Command::WritePage { address: _, data } => {
770                if data.len() != INT_PAGE_SIZE {
771                    return Err(Error::BadArguments);
772                }
773            }
774            &Command::WriteExPage { address: _, data } => {
775                if data.len() != EXT_PAGE_SIZE {
776                    return Err(Error::BadArguments);
777                }
778            }
779            &Command::SetAttr { index, key, value } => {
780                if index > MAX_INDEX {
781                    return Err(Error::BadArguments);
782                }
783                if key.len() != KEY_LEN {
784                    return Err(Error::BadArguments);
785                }
786                if value.len() > MAX_ATTR_LEN {
787                    return Err(Error::BadArguments);
788                }
789            }
790            _ => {}
791        };
792        Ok(CommandEncoder {
793            command: command,
794            count: 0,
795            sent_escape: false,
796        })
797    }
798
799    /// Reset the `CommandEncoder`, so that next time you call `self.next()`
800    /// you get the first byte again.
801    pub fn reset(&mut self) {
802        self.count = 0;
803        self.sent_escape = false;
804    }
805
806    fn render_byte(&mut self, byte: u8) -> (usize, Option<u8>) {
807        if byte == ESCAPE_CHAR {
808            if self.sent_escape {
809                self.sent_escape = false;
810                (1, Some(ESCAPE_CHAR))
811            } else {
812                self.sent_escape = true;
813                (0, Some(ESCAPE_CHAR))
814            }
815        } else {
816            self.sent_escape = false;
817            (1, Some(byte))
818        }
819    }
820
821    fn render_u16(&mut self, idx: usize, value: u16) -> (usize, Option<u8>) {
822        match idx {
823            0 => self.render_byte(value as u8),
824            1 => self.render_byte((value >> 8) as u8),
825            _ => (0, None),
826        }
827    }
828
829    fn render_u32(&mut self, idx: usize, value: u32) -> (usize, Option<u8>) {
830        match idx {
831            0 => self.render_byte(value as u8),
832            1 => self.render_byte((value >> 8) as u8),
833            2 => self.render_byte((value >> 16) as u8),
834            3 => self.render_byte((value >> 24) as u8),
835            _ => (0, None),
836        }
837    }
838
839    fn render_buffer(&mut self, idx: usize, page_size: usize, data: &[u8]) -> (usize, Option<u8>) {
840        if (idx < data.len()) && (idx < page_size) {
841            self.render_byte(data[idx])
842        } else if idx < page_size {
843            self.render_byte(0x00) // pad short data with nulls
844        } else {
845            (0, None)
846        }
847    }
848
849    fn render_basic_cmd(&mut self, count: usize, cmd: u8) -> (usize, Option<u8>) {
850        match count {
851            0 => (1, Some(ESCAPE_CHAR)), // Escape
852            1 => (1, Some(cmd)), // Command
853            _ => (0, None),
854        }
855    }
856
857    fn render_erasepage_cmd(&mut self, address: u32) -> (usize, Option<u8>) {
858        let count = self.count;
859        match count {
860            0...3 => self.render_u32(count, address),
861            _ => self.render_basic_cmd(count - 4, CMD_EPAGE),
862        }
863    }
864
865    fn render_writepage_cmd(&mut self, address: u32, data: &[u8]) -> (usize, Option<u8>) {
866        let count = self.count;
867        match count {
868            0...3 => self.render_u32(count, address),
869            4...515 => self.render_buffer(count - 4, INT_PAGE_SIZE, data),
870            _ => self.render_basic_cmd(count - 516, CMD_WPAGE),
871        }
872    }
873
874    fn render_eraseexblock(&mut self, address: u32) -> (usize, Option<u8>) {
875        let count = self.count;
876        match count {
877            0...3 => self.render_u32(count, address),
878            _ => self.render_basic_cmd(count - 4, CMD_XEBLOCK),
879        }
880    }
881
882    fn render_writeexpage(&mut self, address: u32, data: &[u8]) -> (usize, Option<u8>) {
883        let count = self.count;
884        match count {
885            0...3 => self.render_u32(count, address),
886            4...259 => self.render_buffer(count - 4, EXT_PAGE_SIZE, data),
887            _ => self.render_basic_cmd(count - (EXT_PAGE_SIZE + 4), CMD_XWPAGE),
888        }
889    }
890
891    fn render_readrange(&mut self, address: u32, length: u16) -> (usize, Option<u8>) {
892        let count = self.count;
893        match count {
894            0...3 => self.render_u32(count, address),
895            4...5 => self.render_u16(count - 4, length),
896            _ => self.render_basic_cmd(count - 6, CMD_RRANGE),
897        }
898    }
899
900    fn render_exreadrange(&mut self, address: u32, length: u16) -> (usize, Option<u8>) {
901        let count = self.count;
902        match count {
903            0...3 => self.render_u32(count, address),
904            4...5 => self.render_u16(count - 4, length),
905            _ => self.render_basic_cmd(count - 6, CMD_XRRANGE),
906        }
907    }
908
909    fn render_setattr(&mut self, index: u8, key: &[u8], value: &[u8]) -> (usize, Option<u8>) {
910        let count = self.count;
911        let max_len = if value.len() > MAX_ATTR_LEN {
912            MAX_ATTR_LEN
913        } else {
914            value.len()
915        };
916        match count {
917            0 => self.render_byte(index),
918            1...8 => self.render_buffer(count - 1, KEY_LEN, key),
919            9 => self.render_byte(max_len as u8),
920            x if (max_len > 0) && (x < (max_len + 10)) => {
921                self.render_buffer(x - 10, max_len, value)
922            }
923            _ => self.render_basic_cmd(count - (10 + max_len), CMD_SATTR),
924        }
925    }
926
927    fn render_getattr(&mut self, index: u8) -> (usize, Option<u8>) {
928        let count = self.count;
929        match count {
930            0 => self.render_byte(index),
931            _ => self.render_basic_cmd(count - 1, CMD_GATTR),
932        }
933    }
934
935    fn render_crcintflash(&mut self, address: u32, length: u32) -> (usize, Option<u8>) {
936        let count = self.count;
937        match count {
938            0...3 => self.render_u32(count, address),
939            4...7 => self.render_u32(count - 4, length),
940            _ => self.render_basic_cmd(count - 8, CMD_CRCIF),
941        }
942    }
943
944    fn render_crcextflash(&mut self, address: u32, length: u32) -> (usize, Option<u8>) {
945        let count = self.count;
946        match count {
947            0...3 => self.render_u32(count, address),
948            4...7 => self.render_u32(count - 4, length),
949            _ => self.render_basic_cmd(count - 8, CMD_CRCEF),
950        }
951    }
952
953    fn render_eraseexpage(&mut self, address: u32) -> (usize, Option<u8>) {
954        let count = self.count;
955        match count {
956            0...3 => self.render_u32(count, address),
957            _ => self.render_basic_cmd(count - 4, CMD_XEPAGE),
958        }
959    }
960
961    fn render_writeflashuserpages(&mut self, page1: u32, page2: u32) -> (usize, Option<u8>) {
962        let count = self.count;
963        match count {
964            0...3 => self.render_u32(count, page1),
965            4...7 => self.render_u32(count - 4, page2),
966            _ => self.render_basic_cmd(count - 8, CMD_WUSER),
967        }
968    }
969
970    fn render_changebaud(&mut self, mode: BaudMode, baud: u32) -> (usize, Option<u8>) {
971        let count = self.count;
972        match count {
973            0 => {
974                self.render_byte(match mode {
975                    BaudMode::Set => 0x01,
976                    BaudMode::Verify => 0x02,
977                })
978            }
979            1...4 => self.render_u32(count - 1, baud),
980            _ => self.render_basic_cmd(count - 5, CMD_CHANGE_BAUD),
981        }
982    }
983}
984
985impl<'a> Iterator for CommandEncoder<'a> {
986    type Item = u8;
987
988    /// Supply the next encoded byte. Once all the bytes have been emitted, it
989    /// returns `None` forevermore.
990    fn next(&mut self) -> Option<u8> {
991        let count = self.count;
992        let (inc, result) = match self.command {
993            &Command::Ping => self.render_basic_cmd(count, CMD_PING),
994            &Command::Info => self.render_basic_cmd(count, CMD_INFO),
995            &Command::Id => self.render_basic_cmd(count, CMD_ID),
996            &Command::Reset => self.render_basic_cmd(count, CMD_RESET),
997            &Command::ErasePage { address } => self.render_erasepage_cmd(address),
998            &Command::WritePage { address, data } => self.render_writepage_cmd(address, data),
999            &Command::EraseExBlock { address } => self.render_eraseexblock(address),
1000            &Command::WriteExPage { address, data } => self.render_writeexpage(address, data),
1001            &Command::CrcRxBuffer => self.render_basic_cmd(count, CMD_CRCRX),
1002            &Command::ReadRange { address, length } => self.render_readrange(address, length),
1003            &Command::ExReadRange { address, length } => self.render_exreadrange(address, length),
1004            &Command::SetAttr { index, key, value } => self.render_setattr(index, key, value),
1005            &Command::GetAttr { index } => self.render_getattr(index),
1006            &Command::CrcIntFlash { address, length } => self.render_crcintflash(address, length),
1007            &Command::CrcExtFlash { address, length } => self.render_crcextflash(address, length),
1008            &Command::EraseExPage { address } => self.render_eraseexpage(address),
1009            &Command::ExtFlashInit => self.render_basic_cmd(count, CMD_XFINIT),
1010            &Command::ClockOut => self.render_basic_cmd(count, CMD_CLKOUT),
1011            &Command::WriteFlashUserPages { page1, page2 } => {
1012                self.render_writeflashuserpages(page1, page2)
1013            }
1014            &Command::ChangeBaud { mode, baud } => self.render_changebaud(mode, baud),
1015        };
1016        self.count = self.count + inc;
1017        result
1018    }
1019}
1020
1021impl<'a> Encoder for CommandEncoder<'a> {
1022    /// Reset the `Encoder`, so that next time you call `self.next()`
1023    /// you get the first byte again.
1024    fn reset(&mut self) {
1025        self.count = 0;
1026        self.sent_escape = false;
1027    }
1028}
1029
1030impl<'a> ResponseEncoder<'a> {
1031    /// Create a new `ResponseEncoder`.
1032    ///
1033    /// The encoder takes a reference to a `Command` to encode. The `next` method
1034    /// will then supply the encoded bytes one at a time.
1035    pub fn new(response: &'a Response) -> Result<ResponseEncoder<'a>, Error> {
1036        match response {
1037            &Response::GetAttr { key, value } => {
1038                if key.len() != KEY_LEN {
1039                    return Err(Error::BadArguments);
1040                }
1041                if value.len() > MAX_ATTR_LEN {
1042                    return Err(Error::BadArguments);
1043                }
1044            }
1045            &Response::Info { info } => {
1046                if info.len() > MAX_INFO_LEN {
1047                    return Err(Error::BadArguments);
1048                }
1049            }
1050            _ => {}
1051        }
1052        Ok(ResponseEncoder {
1053            response: response,
1054            count: 0,
1055            sent_escape: false,
1056        })
1057    }
1058
1059    fn render_byte(&mut self, byte: u8) -> (usize, Option<u8>) {
1060        if byte == ESCAPE_CHAR {
1061            if self.sent_escape {
1062                self.sent_escape = false;
1063                (1, Some(ESCAPE_CHAR))
1064            } else {
1065                self.sent_escape = true;
1066                (0, Some(ESCAPE_CHAR))
1067            }
1068        } else {
1069            (1, Some(byte))
1070        }
1071    }
1072
1073    fn render_crc_rx_buffer(&mut self, length: u16, crc: u32) -> (usize, Option<u8>) {
1074        let count = self.count;
1075        match count {
1076            0...1 => self.render_header(count, RES_CRCRX),
1077            2...3 => self.render_u16(count - 2, length),
1078            4...7 => self.render_u32(count - 4, crc),
1079            _ => (0, None),
1080        }
1081    }
1082
1083    fn render_read_range(&mut self, data: &[u8]) -> (usize, Option<u8>) {
1084        let count = self.count;
1085        match count {
1086            0...1 => self.render_header(count, RES_RRANGE),
1087            x if x < data.len() + 2 => self.render_byte(data[x - 2]),
1088            _ => (0, None),
1089        }
1090    }
1091
1092    fn render_ex_read_range(&mut self, data: &[u8]) -> (usize, Option<u8>) {
1093        let count = self.count;
1094        match count {
1095            0...1 => self.render_header(count, RES_XRRANGE),
1096            x if x - 2 < data.len() => self.render_byte(data[x - 2]),
1097            _ => (0, None),
1098        }
1099    }
1100
1101    fn render_get_attr(&mut self, key: &[u8], value: &[u8]) -> (usize, Option<u8>) {
1102        let count = self.count;
1103        match count {
1104            0...1 => self.render_header(count, RES_GATTR),
1105            2...9 => self.render_buffer(count - 2, 8, key),
1106            10 => self.render_byte(value.len() as u8),
1107            _ => self.render_buffer(count - 11, MAX_ATTR_LEN, value),
1108        }
1109    }
1110
1111    fn render_crc_int_flash(&mut self, crc: u32) -> (usize, Option<u8>) {
1112        let count = self.count;
1113        match count {
1114            0...1 => self.render_header(count, RES_CRCIF),
1115            _ => self.render_u32(count - 2, crc),
1116        }
1117    }
1118
1119    fn render_crc_ex_flash(&mut self, crc: u32) -> (usize, Option<u8>) {
1120        let count = self.count;
1121        match count {
1122            0...1 => self.render_header(count, RES_CRCXF),
1123            _ => self.render_u32(count - 2, crc),
1124        }
1125    }
1126
1127    fn render_info(&mut self, info: &[u8]) -> (usize, Option<u8>) {
1128        let count = self.count;
1129        match count {
1130            0...1 => self.render_header(count, RES_INFO),
1131            2 => self.render_byte(info.len() as u8),
1132            _ => self.render_buffer(count - 3, MAX_INFO_LEN, info),
1133        }
1134    }
1135
1136    fn render_u16(&mut self, idx: usize, value: u16) -> (usize, Option<u8>) {
1137        match idx {
1138            0 => self.render_byte(value as u8),
1139            1 => self.render_byte((value >> 8) as u8),
1140            _ => (0, None),
1141        }
1142    }
1143
1144    fn render_u32(&mut self, idx: usize, value: u32) -> (usize, Option<u8>) {
1145        match idx {
1146            0 => self.render_byte(value as u8),
1147            1 => self.render_byte((value >> 8) as u8),
1148            2 => self.render_byte((value >> 16) as u8),
1149            3 => self.render_byte((value >> 24) as u8),
1150            _ => (0, None),
1151        }
1152    }
1153
1154    fn render_buffer(&mut self, idx: usize, page_size: usize, data: &[u8]) -> (usize, Option<u8>) {
1155        if (idx < data.len()) && (idx < page_size) {
1156            self.render_byte(data[idx])
1157        } else if idx < page_size {
1158            self.render_byte(0x00) // pad short data with nulls
1159        } else {
1160            (0, None)
1161        }
1162    }
1163
1164    fn render_header(&mut self, count: usize, cmd: u8) -> (usize, Option<u8>) {
1165        match count {
1166            0 => (1, Some(ESCAPE_CHAR)), // Escape
1167            1 => (1, Some(cmd)), // Command
1168            _ => (0, None),
1169        }
1170    }
1171}
1172
1173impl<'a> Encoder for ResponseEncoder<'a> {
1174    fn reset(&mut self) {
1175        self.count = 0;
1176        self.sent_escape = false;
1177    }
1178}
1179
1180impl<'a> Iterator for ResponseEncoder<'a> {
1181    type Item = u8;
1182
1183    /// Supply the next encoded byte. Once all the bytes have been emitted, it
1184    /// returns `None` forevermore.
1185    fn next(&mut self) -> Option<u8> {
1186        let count = self.count;
1187        let (inc, result) = match self.response {
1188            &Response::Overflow => self.render_header(count, RES_OVERFLOW),
1189            &Response::Pong => self.render_header(count, RES_PONG),
1190            &Response::BadAddress => self.render_header(count, RES_BADADDR),
1191            &Response::InternalError => self.render_header(count, RES_INTERROR),
1192            &Response::BadArguments => self.render_header(count, RES_BADARGS),
1193            &Response::Ok => self.render_header(count, RES_OK),
1194            &Response::Unknown => self.render_header(count, RES_UNKNOWN),
1195            &Response::ExtFlashTimeout => self.render_header(count, RES_XFTIMEOUT),
1196            &Response::ExtFlashPageError => self.render_header(count, RES_XFEPE),
1197            &Response::CrcRxBuffer { length, crc } => self.render_crc_rx_buffer(length, crc),
1198            &Response::ReadRange { data } => self.render_read_range(data),
1199            &Response::ExReadRange { data } => self.render_ex_read_range(data),
1200            &Response::GetAttr { key, value } => self.render_get_attr(key, value),
1201            &Response::CrcIntFlash { crc } => self.render_crc_int_flash(crc),
1202            &Response::CrcExtFlash { crc } => self.render_crc_ex_flash(crc),
1203            &Response::Info { info } => self.render_info(info),
1204            &Response::ChangeBaudFail => self.render_header(count, RES_CHANGE_BAUD_FAIL),
1205        };
1206        self.count = self.count + inc;
1207        result
1208    }
1209}
1210
1211// ****************************************************************************
1212//
1213// Private Impl/Functions/Modules
1214//
1215// ****************************************************************************
1216
1217#[cfg(test)]
1218mod tests {
1219    use super::*;
1220
1221    #[test]
1222    fn decode_cmd_ping() {
1223        let mut p = CommandDecoder::new();
1224        assert_eq!(p.receive(ESCAPE_CHAR), Ok(None));
1225        match p.receive(CMD_PING) {
1226            Ok(Some(Command::Ping)) => {}
1227            e => panic!("Did not expect: {:?}", e),
1228        }
1229    }
1230
1231    #[test]
1232    fn encode_cmd_ping() {
1233        let cmd = Command::Ping;
1234        let mut e = CommandEncoder::new(&cmd).unwrap();
1235        assert_eq!(e.next(), Some(ESCAPE_CHAR));
1236        assert_eq!(e.next(), Some(CMD_PING));
1237        assert_eq!(e.next(), None);
1238        assert_eq!(e.next(), None);
1239    }
1240
1241    #[test]
1242    fn decode_cmd_info() {
1243        let mut p = CommandDecoder::new();
1244        assert_eq!(p.receive(ESCAPE_CHAR), Ok(None));
1245        match p.receive(CMD_INFO) {
1246            Ok(Some(Command::Info)) => {}
1247            e => panic!("Did not expect: {:?}", e),
1248        }
1249    }
1250
1251    #[test]
1252    fn encode_cmd_info() {
1253        let cmd = Command::Info;
1254        let mut e = CommandEncoder::new(&cmd).unwrap();
1255        assert_eq!(e.next(), Some(ESCAPE_CHAR));
1256        assert_eq!(e.next(), Some(CMD_INFO));
1257        assert_eq!(e.next(), None);
1258        assert_eq!(e.next(), None);
1259    }
1260
1261    #[test]
1262    fn decode_cmd_id() {
1263        let mut p = CommandDecoder::new();
1264        assert_eq!(p.receive(ESCAPE_CHAR), Ok(None));
1265        match p.receive(CMD_ID) {
1266            Ok(Some(Command::Id)) => {}
1267            e => panic!("Did not expect: {:?}", e),
1268        }
1269    }
1270
1271    #[test]
1272    fn encode_cmd_id() {
1273        let cmd = Command::Id;
1274        let mut e = CommandEncoder::new(&cmd).unwrap();
1275        assert_eq!(e.next(), Some(ESCAPE_CHAR));
1276        assert_eq!(e.next(), Some(CMD_ID));
1277        assert_eq!(e.next(), None);
1278        assert_eq!(e.next(), None);
1279    }
1280
1281    #[test]
1282    fn decode_cmd_reset() {
1283        let mut p = CommandDecoder::new();
1284        assert_eq!(p.receive(ESCAPE_CHAR), Ok(None));
1285        match p.receive(CMD_RESET) {
1286            Ok(Some(Command::Reset)) => {}
1287            e => panic!("Did not expect: {:?}", e),
1288        }
1289    }
1290
1291    #[test]
1292    fn encode_cmd_reset() {
1293        let cmd = Command::Reset;
1294        let mut e = CommandEncoder::new(&cmd).unwrap();
1295        assert_eq!(e.next(), Some(ESCAPE_CHAR));
1296        assert_eq!(e.next(), Some(CMD_RESET));
1297        assert_eq!(e.next(), None);
1298        assert_eq!(e.next(), None);
1299    }
1300
1301    #[test]
1302    fn decode_cmd_erase_page() {
1303        let mut p = CommandDecoder::new();
1304        assert_eq!(p.receive(0xEF), Ok(None));
1305        assert_eq!(p.receive(0xBE), Ok(None));
1306        assert_eq!(p.receive(0xAD), Ok(None));
1307        assert_eq!(p.receive(0xDE), Ok(None));
1308        assert_eq!(p.receive(ESCAPE_CHAR), Ok(None)); // Escape
1309        match p.receive(CMD_EPAGE) {
1310            Ok(Some(Command::ErasePage { address })) => {
1311                assert_eq!(address, 0xDEADBEEF);
1312            }
1313            e => panic!("Did not expect: {:?}", e),
1314        }
1315    }
1316
1317    #[test]
1318    fn encode_cmd_erase_page() {
1319        let cmd = Command::ErasePage { address: 0xDEADBEEF };
1320        let mut e = CommandEncoder::new(&cmd).unwrap();
1321        // 4 byte address, little-endian
1322        assert_eq!(e.next(), Some(0xEF));
1323        assert_eq!(e.next(), Some(0xBE));
1324        assert_eq!(e.next(), Some(0xAD));
1325        assert_eq!(e.next(), Some(0xDE));
1326        assert_eq!(e.next(), Some(ESCAPE_CHAR));
1327        assert_eq!(e.next(), Some(CMD_EPAGE));
1328        assert_eq!(e.next(), None);
1329        assert_eq!(e.next(), None);
1330    }
1331
1332    #[test]
1333    fn decode_cmd_write_page() {
1334        let mut p = CommandDecoder::new();
1335        assert_eq!(p.receive(0xEF), Ok(None));
1336        assert_eq!(p.receive(0xBE), Ok(None));
1337        assert_eq!(p.receive(0xAD), Ok(None));
1338        assert_eq!(p.receive(0xDE), Ok(None));
1339        for i in 0..INT_PAGE_SIZE {
1340            let datum = i as u8;
1341            assert_eq!(p.receive(datum), Ok(None));
1342            if datum == ESCAPE_CHAR {
1343                assert_eq!(p.receive(datum), Ok(None));
1344            }
1345        }
1346        assert_eq!(p.receive(ESCAPE_CHAR), Ok(None)); // Escape
1347        match p.receive(CMD_WPAGE) {
1348            Ok(Some(Command::WritePage {
1349                        address,
1350                        data: ref page,
1351                    })) => {
1352                assert_eq!(address, 0xDEADBEEF);
1353                assert_eq!(page.len(), INT_PAGE_SIZE);
1354                for i in 0..INT_PAGE_SIZE {
1355                    let datum = i as u8;
1356                    assert_eq!(datum, page[i as usize]);
1357                }
1358            }
1359            e => panic!("Did not expect: {:?}", e),
1360        }
1361    }
1362
1363    #[test]
1364    fn encode_cmd_write_page() {
1365        let mut buffer = [0xBBu8; INT_PAGE_SIZE];
1366        buffer[0] = 0xAA;
1367        buffer[INT_PAGE_SIZE - 1] = 0xCC;
1368        let cmd = Command::WritePage {
1369            address: 0xDEADBEEF,
1370            data: &buffer,
1371        };
1372        let mut e = CommandEncoder::new(&cmd).unwrap();
1373        // 4 byte address, little-endian
1374        assert_eq!(e.next(), Some(0xEF));
1375        assert_eq!(e.next(), Some(0xBE));
1376        assert_eq!(e.next(), Some(0xAD));
1377        assert_eq!(e.next(), Some(0xDE));
1378        // first byte of data
1379        assert_eq!(e.next(), Some(0xAA));
1380        for _ in 1..(INT_PAGE_SIZE - 1) {
1381            assert_eq!(e.next(), Some(0xBB));
1382        }
1383        // last byte of data
1384        assert_eq!(e.next(), Some(0xCC));
1385        assert_eq!(e.next(), Some(ESCAPE_CHAR));
1386        assert_eq!(e.next(), Some(CMD_WPAGE));
1387        assert_eq!(e.next(), None);
1388        assert_eq!(e.next(), None);
1389    }
1390
1391    #[test]
1392    fn decode_cmd_erase_block() {
1393        let mut p = CommandDecoder::new();
1394        assert_eq!(p.receive(0xEF), Ok(None));
1395        assert_eq!(p.receive(0xBE), Ok(None));
1396        assert_eq!(p.receive(0xAD), Ok(None));
1397        assert_eq!(p.receive(0xDE), Ok(None));
1398        assert_eq!(p.receive(ESCAPE_CHAR), Ok(None)); // Escape
1399        match p.receive(CMD_XEBLOCK) {
1400            Ok(Some(Command::EraseExBlock { address })) => {
1401                assert_eq!(address, 0xDEADBEEF);
1402            }
1403            e => panic!("Did not expect: {:?}", e),
1404        }
1405    }
1406
1407    #[test]
1408    fn encode_cmd_erase_block() {
1409        let cmd = Command::EraseExBlock { address: 0xDEADBEEF };
1410        let mut e = CommandEncoder::new(&cmd).unwrap();
1411        // 4 byte address, little-endian
1412        assert_eq!(e.next(), Some(0xEF));
1413        assert_eq!(e.next(), Some(0xBE));
1414        assert_eq!(e.next(), Some(0xAD));
1415        assert_eq!(e.next(), Some(0xDE));
1416        assert_eq!(e.next(), Some(ESCAPE_CHAR));
1417        assert_eq!(e.next(), Some(CMD_XEBLOCK));
1418        assert_eq!(e.next(), None);
1419        assert_eq!(e.next(), None);
1420    }
1421
1422    #[test]
1423    fn decode_cmd_write_ex_page() {
1424        let mut p = CommandDecoder::new();
1425        assert_eq!(p.receive(0xEF), Ok(None));
1426        assert_eq!(p.receive(0xBE), Ok(None));
1427        assert_eq!(p.receive(0xAD), Ok(None));
1428        assert_eq!(p.receive(0xDE), Ok(None));
1429        for i in 0..EXT_PAGE_SIZE {
1430            let datum = i as u8;
1431            assert_eq!(p.receive(datum), Ok(None));
1432            if datum == ESCAPE_CHAR {
1433                assert_eq!(p.receive(datum), Ok(None));
1434            }
1435        }
1436        assert_eq!(p.receive(ESCAPE_CHAR), Ok(None)); // Escape
1437        match p.receive(CMD_XWPAGE) {
1438            Ok(Some(Command::WriteExPage {
1439                        address,
1440                        data: ref page,
1441                    })) => {
1442                assert_eq!(address, 0xDEADBEEF);
1443                assert_eq!(page.len(), EXT_PAGE_SIZE);
1444                for i in 0..EXT_PAGE_SIZE {
1445                    let datum = i as u8;
1446                    assert_eq!(datum, page[i as usize]);
1447                }
1448            }
1449            e => panic!("Did not expect: {:?}", e),
1450        }
1451    }
1452
1453    #[test]
1454    fn encode_cmd_write_ex_page() {
1455        let mut buffer = [0xBBu8; EXT_PAGE_SIZE];
1456        buffer[0] = 0xAA;
1457        buffer[EXT_PAGE_SIZE - 1] = 0xCC;
1458        let cmd = Command::WriteExPage {
1459            address: 0xDEADBEEF,
1460            data: &buffer,
1461        };
1462        let mut e = CommandEncoder::new(&cmd).unwrap();
1463        // 4 byte address, little-endian
1464        assert_eq!(e.next(), Some(0xEF));
1465        assert_eq!(e.next(), Some(0xBE));
1466        assert_eq!(e.next(), Some(0xAD));
1467        assert_eq!(e.next(), Some(0xDE));
1468        // first byte of data
1469        assert_eq!(e.next(), Some(0xAA));
1470        for _ in 1..(EXT_PAGE_SIZE - 1) {
1471            assert_eq!(e.next(), Some(0xBB));
1472        }
1473        // last byte of data
1474        assert_eq!(e.next(), Some(0xCC));
1475        assert_eq!(e.next(), Some(ESCAPE_CHAR));
1476        assert_eq!(e.next(), Some(CMD_XWPAGE));
1477        assert_eq!(e.next(), None);
1478        assert_eq!(e.next(), None);
1479    }
1480
1481    #[test]
1482    fn encode_cmd_crcrx() {
1483        let cmd = Command::CrcRxBuffer;
1484        let mut e = CommandEncoder::new(&cmd).unwrap();
1485        assert_eq!(e.next(), Some(ESCAPE_CHAR));
1486        assert_eq!(e.next(), Some(CMD_CRCRX));
1487        assert_eq!(e.next(), None);
1488        assert_eq!(e.next(), None);
1489    }
1490
1491    #[test]
1492    fn decode_cmd_crcrx() {
1493        let mut p = CommandDecoder::new();
1494        assert_eq!(p.receive(ESCAPE_CHAR), Ok(None)); // Escape
1495        match p.receive(CMD_CRCRX) {
1496            Ok(Some(Command::CrcRxBuffer)) => {}
1497            e => panic!("Did not expect: {:?}", e),
1498        }
1499    }
1500
1501    #[test]
1502    fn encode_cmd_rrange() {
1503        let cmd = Command::ReadRange {
1504            address: 0xDEADBEEF,
1505            length: 0x1234,
1506        };
1507        let mut e = CommandEncoder::new(&cmd).unwrap();
1508        // 4 byte address, little-endian
1509        assert_eq!(e.next(), Some(0xEF));
1510        assert_eq!(e.next(), Some(0xBE));
1511        assert_eq!(e.next(), Some(0xAD));
1512        assert_eq!(e.next(), Some(0xDE));
1513        // 2 byte length
1514        assert_eq!(e.next(), Some(0x34));
1515        assert_eq!(e.next(), Some(0x12));
1516        assert_eq!(e.next(), Some(ESCAPE_CHAR));
1517        assert_eq!(e.next(), Some(CMD_RRANGE));
1518        assert_eq!(e.next(), None);
1519        assert_eq!(e.next(), None);
1520    }
1521
1522    #[test]
1523    fn decode_cmd_rrange() {
1524        let mut p = CommandDecoder::new();
1525        assert_eq!(p.receive(0xEF), Ok(None));
1526        assert_eq!(p.receive(0xBE), Ok(None));
1527        assert_eq!(p.receive(0xAD), Ok(None));
1528        assert_eq!(p.receive(0xDE), Ok(None));
1529        assert_eq!(p.receive(0x34), Ok(None));
1530        assert_eq!(p.receive(0x12), Ok(None));
1531        assert_eq!(p.receive(ESCAPE_CHAR), Ok(None)); // Escape
1532        match p.receive(CMD_RRANGE) {
1533            Ok(Some(Command::ReadRange { address, length })) => {
1534                assert_eq!(address, 0xDEADBEEF);
1535                assert_eq!(length, 0x1234);
1536            }
1537            e => panic!("Did not expect: {:?}", e),
1538        }
1539    }
1540
1541    #[test]
1542    fn encode_cmd_xrrange() {
1543        let cmd = Command::ExReadRange {
1544            address: 0xDEADBEEF,
1545            length: 0x1234,
1546        };
1547        let mut e = CommandEncoder::new(&cmd).unwrap();
1548        // 4 byte address, little-endian
1549        assert_eq!(e.next(), Some(0xEF));
1550        assert_eq!(e.next(), Some(0xBE));
1551        assert_eq!(e.next(), Some(0xAD));
1552        assert_eq!(e.next(), Some(0xDE));
1553        // 2 byte length
1554        assert_eq!(e.next(), Some(0x34));
1555        assert_eq!(e.next(), Some(0x12));
1556        assert_eq!(e.next(), Some(ESCAPE_CHAR));
1557        assert_eq!(e.next(), Some(CMD_XRRANGE));
1558        assert_eq!(e.next(), None);
1559        assert_eq!(e.next(), None);
1560    }
1561
1562    #[test]
1563    fn decode_cmd_xrrange() {
1564        let mut p = CommandDecoder::new();
1565        assert_eq!(p.receive(0xEF), Ok(None));
1566        assert_eq!(p.receive(0xBE), Ok(None));
1567        assert_eq!(p.receive(0xAD), Ok(None));
1568        assert_eq!(p.receive(0xDE), Ok(None));
1569        assert_eq!(p.receive(0x34), Ok(None));
1570        assert_eq!(p.receive(0x12), Ok(None));
1571        assert_eq!(p.receive(ESCAPE_CHAR), Ok(None)); // Escape
1572        match p.receive(CMD_XRRANGE) {
1573            Ok(Some(Command::ExReadRange { address, length })) => {
1574                assert_eq!(address, 0xDEADBEEF);
1575                assert_eq!(length, 0x1234);
1576            }
1577            e => panic!("Did not expect: {:?}", e),
1578        }
1579    }
1580
1581    #[test]
1582    fn encode_cmd_sattr() {
1583        let r = Command::SetAttr {
1584            index: MAX_INDEX,
1585            key: &[0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77],
1586            value: &[0xAA, 0xBB, 0xCC, 0xDD],
1587        };
1588        let mut e = CommandEncoder::new(&r).unwrap();
1589        assert_eq!(e.next(), Some(MAX_INDEX));
1590        assert_eq!(e.next(), Some(0x00));
1591        assert_eq!(e.next(), Some(0x11));
1592        assert_eq!(e.next(), Some(0x22));
1593        assert_eq!(e.next(), Some(0x33));
1594        assert_eq!(e.next(), Some(0x44));
1595        assert_eq!(e.next(), Some(0x55));
1596        assert_eq!(e.next(), Some(0x66));
1597        assert_eq!(e.next(), Some(0x77));
1598        assert_eq!(e.next(), Some(0x04));
1599        assert_eq!(e.next(), Some(0xAA));
1600        assert_eq!(e.next(), Some(0xBB));
1601        assert_eq!(e.next(), Some(0xCC));
1602        assert_eq!(e.next(), Some(0xDD));
1603        // Commands don't seem to need padding
1604        assert_eq!(e.next(), Some(ESCAPE_CHAR));
1605        assert_eq!(e.next(), Some(CMD_SATTR));
1606        assert_eq!(e.next(), None);
1607        assert_eq!(e.next(), None);
1608    }
1609
1610    #[test]
1611    fn decode_cmd_sattr() {
1612        let mut p = CommandDecoder::new();
1613        assert_eq!(p.receive(MAX_INDEX), Ok(None));
1614        assert_eq!(p.receive(0x00), Ok(None));
1615        assert_eq!(p.receive(0x11), Ok(None));
1616        assert_eq!(p.receive(0x22), Ok(None));
1617        assert_eq!(p.receive(0x33), Ok(None));
1618        assert_eq!(p.receive(0x44), Ok(None));
1619        assert_eq!(p.receive(0x55), Ok(None));
1620        assert_eq!(p.receive(0x66), Ok(None));
1621        assert_eq!(p.receive(0x77), Ok(None));
1622        assert_eq!(p.receive(0x04), Ok(None));
1623        assert_eq!(p.receive(0xAA), Ok(None));
1624        assert_eq!(p.receive(0xBB), Ok(None));
1625        assert_eq!(p.receive(0xCC), Ok(None));
1626        assert_eq!(p.receive(0xDD), Ok(None));
1627        assert_eq!(p.receive(ESCAPE_CHAR), Ok(None)); // Escape
1628        match p.receive(CMD_SATTR) {
1629            Ok(Some(Command::SetAttr { index, key, value })) => {
1630                assert_eq!(index, MAX_INDEX);
1631                assert_eq!(key, [0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77]);
1632                assert_eq!(value, [0xAA, 0xBB, 0xCC, 0xDD]);
1633            }
1634            e => panic!("Did not expect: {:?}", e),
1635        }
1636    }
1637
1638    #[test]
1639    fn encode_cmd_gattr() {
1640        let r = Command::GetAttr { index: MAX_INDEX };
1641        let mut e = CommandEncoder::new(&r).unwrap();
1642        assert_eq!(e.next(), Some(MAX_INDEX));
1643        assert_eq!(e.next(), Some(ESCAPE_CHAR));
1644        assert_eq!(e.next(), Some(CMD_GATTR));
1645        assert_eq!(e.next(), None);
1646        assert_eq!(e.next(), None);
1647    }
1648
1649    #[test]
1650    fn decode_cmd_gattr() {
1651        let mut p = CommandDecoder::new();
1652        assert_eq!(p.receive(MAX_INDEX), Ok(None));
1653        assert_eq!(p.receive(ESCAPE_CHAR), Ok(None)); // Escape
1654        match p.receive(CMD_GATTR) {
1655            Ok(Some(Command::GetAttr { index })) => {
1656                assert_eq!(index, MAX_INDEX);
1657            }
1658            e => panic!("Did not expect: {:?}", e),
1659        }
1660    }
1661
1662    #[test]
1663    fn encode_cmd_crcif() {
1664        let cmd = Command::CrcIntFlash {
1665            address: 0xDEADBEEF,
1666            length: 0x12345678,
1667        };
1668        let mut e = CommandEncoder::new(&cmd).unwrap();
1669        // 4 byte address, little-endian
1670        assert_eq!(e.next(), Some(0xEF));
1671        assert_eq!(e.next(), Some(0xBE));
1672        assert_eq!(e.next(), Some(0xAD));
1673        assert_eq!(e.next(), Some(0xDE));
1674        // 4 byte length
1675        assert_eq!(e.next(), Some(0x78));
1676        assert_eq!(e.next(), Some(0x56));
1677        assert_eq!(e.next(), Some(0x34));
1678        assert_eq!(e.next(), Some(0x12));
1679        assert_eq!(e.next(), Some(ESCAPE_CHAR));
1680        assert_eq!(e.next(), Some(CMD_CRCIF));
1681        assert_eq!(e.next(), None);
1682        assert_eq!(e.next(), None);
1683    }
1684
1685    #[test]
1686    fn decode_cmd_crcif() {
1687        let mut p = CommandDecoder::new();
1688        assert_eq!(p.receive(0xEF), Ok(None));
1689        assert_eq!(p.receive(0xBE), Ok(None));
1690        assert_eq!(p.receive(0xAD), Ok(None));
1691        assert_eq!(p.receive(0xDE), Ok(None));
1692        assert_eq!(p.receive(0x78), Ok(None));
1693        assert_eq!(p.receive(0x56), Ok(None));
1694        assert_eq!(p.receive(0x34), Ok(None));
1695        assert_eq!(p.receive(0x12), Ok(None));
1696        assert_eq!(p.receive(ESCAPE_CHAR), Ok(None)); // Escape
1697        match p.receive(CMD_CRCIF) {
1698            Ok(Some(Command::CrcIntFlash { address, length })) => {
1699                assert_eq!(address, 0xDEADBEEF);
1700                assert_eq!(length, 0x12345678);
1701            }
1702            e => panic!("Did not expect: {:?}", e),
1703        }
1704    }
1705
1706    #[test]
1707    fn encode_cmd_crcef() {
1708        let cmd = Command::CrcExtFlash {
1709            address: 0xDEADBEEF,
1710            length: 0x12345678,
1711        };
1712        let mut e = CommandEncoder::new(&cmd).unwrap();
1713        // 4 byte address, little-endian
1714        assert_eq!(e.next(), Some(0xEF));
1715        assert_eq!(e.next(), Some(0xBE));
1716        assert_eq!(e.next(), Some(0xAD));
1717        assert_eq!(e.next(), Some(0xDE));
1718        // 4 byte length
1719        assert_eq!(e.next(), Some(0x78));
1720        assert_eq!(e.next(), Some(0x56));
1721        assert_eq!(e.next(), Some(0x34));
1722        assert_eq!(e.next(), Some(0x12));
1723        assert_eq!(e.next(), Some(ESCAPE_CHAR));
1724        assert_eq!(e.next(), Some(CMD_CRCEF));
1725        assert_eq!(e.next(), None);
1726        assert_eq!(e.next(), None);
1727    }
1728
1729    #[test]
1730    fn decode_cmd_crcef() {
1731        let mut p = CommandDecoder::new();
1732        assert_eq!(p.receive(0xEF), Ok(None));
1733        assert_eq!(p.receive(0xBE), Ok(None));
1734        assert_eq!(p.receive(0xAD), Ok(None));
1735        assert_eq!(p.receive(0xDE), Ok(None));
1736        assert_eq!(p.receive(0x78), Ok(None));
1737        assert_eq!(p.receive(0x56), Ok(None));
1738        assert_eq!(p.receive(0x34), Ok(None));
1739        assert_eq!(p.receive(0x12), Ok(None));
1740        assert_eq!(p.receive(ESCAPE_CHAR), Ok(None)); // Escape
1741        match p.receive(CMD_CRCEF) {
1742            Ok(Some(Command::CrcExtFlash { address, length })) => {
1743                assert_eq!(address, 0xDEADBEEF);
1744                assert_eq!(length, 0x12345678);
1745            }
1746            e => panic!("Did not expect: {:?}", e),
1747        }
1748    }
1749
1750    #[test]
1751    fn encode_cmd_xepage() {
1752        let cmd = Command::EraseExPage { address: 0xDEADBEEF };
1753        let mut e = CommandEncoder::new(&cmd).unwrap();
1754        // 4 byte address, little-endian
1755        assert_eq!(e.next(), Some(0xEF));
1756        assert_eq!(e.next(), Some(0xBE));
1757        assert_eq!(e.next(), Some(0xAD));
1758        assert_eq!(e.next(), Some(0xDE));
1759        assert_eq!(e.next(), Some(ESCAPE_CHAR));
1760        assert_eq!(e.next(), Some(CMD_XEPAGE));
1761        assert_eq!(e.next(), None);
1762        assert_eq!(e.next(), None);
1763    }
1764
1765    #[test]
1766    fn decode_cmd_xepage() {
1767        let mut p = CommandDecoder::new();
1768        assert_eq!(p.receive(0xEF), Ok(None));
1769        assert_eq!(p.receive(0xBE), Ok(None));
1770        assert_eq!(p.receive(0xAD), Ok(None));
1771        assert_eq!(p.receive(0xDE), Ok(None));
1772        assert_eq!(p.receive(ESCAPE_CHAR), Ok(None)); // Escape
1773        match p.receive(CMD_XEPAGE) {
1774            Ok(Some(Command::EraseExPage { address })) => {
1775                assert_eq!(address, 0xDEADBEEF);
1776            }
1777            e => panic!("Did not expect: {:?}", e),
1778        }
1779    }
1780
1781    #[test]
1782    fn encode_cmd_xfinit() {
1783        let cmd = Command::ExtFlashInit {};
1784        let mut e = CommandEncoder::new(&cmd).unwrap();
1785        assert_eq!(e.next(), Some(ESCAPE_CHAR));
1786        assert_eq!(e.next(), Some(CMD_XFINIT));
1787        assert_eq!(e.next(), None);
1788        assert_eq!(e.next(), None);
1789    }
1790
1791    #[test]
1792    fn decode_cmd_xfinit() {
1793        let mut p = CommandDecoder::new();
1794        assert_eq!(p.receive(ESCAPE_CHAR), Ok(None)); // Escape
1795        match p.receive(CMD_XFINIT) {
1796            Ok(Some(Command::ExtFlashInit)) => {}
1797            e => panic!("Did not expect: {:?}", e),
1798        }
1799    }
1800
1801    #[test]
1802    fn encode_cmd_clkout() {
1803        let cmd = Command::ClockOut {};
1804        let mut e = CommandEncoder::new(&cmd).unwrap();
1805        assert_eq!(e.next(), Some(ESCAPE_CHAR));
1806        assert_eq!(e.next(), Some(CMD_CLKOUT));
1807        assert_eq!(e.next(), None);
1808        assert_eq!(e.next(), None);
1809    }
1810
1811    #[test]
1812    fn decode_cmd_clkout() {
1813        let mut p = CommandDecoder::new();
1814        assert_eq!(p.receive(ESCAPE_CHAR), Ok(None)); // Escape
1815        match p.receive(CMD_CLKOUT) {
1816            Ok(Some(Command::ClockOut)) => {}
1817            e => panic!("Did not expect: {:?}", e),
1818        }
1819    }
1820
1821    #[test]
1822    fn encode_cmd_wuser() {
1823        let cmd = Command::WriteFlashUserPages {
1824            page1: 0xDEADBEEF,
1825            page2: 0x12345678,
1826        };
1827        let mut e = CommandEncoder::new(&cmd).unwrap();
1828        // 4 byte address, little-endian
1829        assert_eq!(e.next(), Some(0xEF));
1830        assert_eq!(e.next(), Some(0xBE));
1831        assert_eq!(e.next(), Some(0xAD));
1832        assert_eq!(e.next(), Some(0xDE));
1833        // 4 byte length
1834        assert_eq!(e.next(), Some(0x78));
1835        assert_eq!(e.next(), Some(0x56));
1836        assert_eq!(e.next(), Some(0x34));
1837        assert_eq!(e.next(), Some(0x12));
1838        assert_eq!(e.next(), Some(ESCAPE_CHAR));
1839        assert_eq!(e.next(), Some(CMD_WUSER));
1840        assert_eq!(e.next(), None);
1841        assert_eq!(e.next(), None);
1842    }
1843
1844    #[test]
1845    fn decode_cmd_wuser() {
1846        let mut p = CommandDecoder::new();
1847        assert_eq!(p.receive(0xEF), Ok(None));
1848        assert_eq!(p.receive(0xBE), Ok(None));
1849        assert_eq!(p.receive(0xAD), Ok(None));
1850        assert_eq!(p.receive(0xDE), Ok(None));
1851        assert_eq!(p.receive(0x78), Ok(None));
1852        assert_eq!(p.receive(0x56), Ok(None));
1853        assert_eq!(p.receive(0x34), Ok(None));
1854        assert_eq!(p.receive(0x12), Ok(None));
1855        assert_eq!(p.receive(ESCAPE_CHAR), Ok(None)); // Escape
1856        match p.receive(CMD_WUSER) {
1857            Ok(Some(Command::WriteFlashUserPages { page1, page2 })) => {
1858                assert_eq!(page1, 0xDEADBEEF);
1859                assert_eq!(page2, 0x12345678);
1860            }
1861            e => panic!("Did not expect: {:?}", e),
1862        }
1863    }
1864
1865    #[test]
1866    fn encode_cmd_change_baud() {
1867        let cmd = Command::ChangeBaud {
1868            mode: BaudMode::Set,
1869            baud: 0xDEADBEEF,
1870        };
1871        let mut e = CommandEncoder::new(&cmd).unwrap();
1872        // Mode
1873        assert_eq!(e.next(), Some(0x01));
1874        // 4 byte baud (0x0001 C200)
1875        assert_eq!(e.next(), Some(0xEF));
1876        assert_eq!(e.next(), Some(0xBE));
1877        assert_eq!(e.next(), Some(0xAD));
1878        assert_eq!(e.next(), Some(0xDE));
1879        assert_eq!(e.next(), Some(ESCAPE_CHAR));
1880        assert_eq!(e.next(), Some(CMD_CHANGE_BAUD));
1881        assert_eq!(e.next(), None);
1882        assert_eq!(e.next(), None);
1883    }
1884
1885    #[test]
1886    fn decode_cmd_change_baud() {
1887        let mut p = CommandDecoder::new();
1888        assert_eq!(p.receive(0x01), Ok(None));
1889        assert_eq!(p.receive(0xEF), Ok(None));
1890        assert_eq!(p.receive(0xBE), Ok(None));
1891        assert_eq!(p.receive(0xAD), Ok(None));
1892        assert_eq!(p.receive(0xDE), Ok(None));
1893        assert_eq!(p.receive(ESCAPE_CHAR), Ok(None)); // Escape
1894        match p.receive(CMD_CHANGE_BAUD) {
1895            Ok(Some(Command::ChangeBaud { mode, baud })) => {
1896                assert_eq!(mode, BaudMode::Set);
1897                assert_eq!(baud, 0xDEADBEEF);
1898            }
1899            e => panic!("Did not expect: {:?}", e),
1900        }
1901        assert_eq!(p.receive(0x02), Ok(None));
1902        assert_eq!(p.receive(0xEF), Ok(None));
1903        assert_eq!(p.receive(0xBE), Ok(None));
1904        assert_eq!(p.receive(0xAD), Ok(None));
1905        assert_eq!(p.receive(0xDE), Ok(None));
1906        assert_eq!(p.receive(ESCAPE_CHAR), Ok(None)); // Escape
1907        match p.receive(CMD_CHANGE_BAUD) {
1908            Ok(Some(Command::ChangeBaud { mode, baud })) => {
1909                assert_eq!(mode, BaudMode::Verify);
1910                assert_eq!(baud, 0xDEADBEEF);
1911            }
1912            e => panic!("Did not expect: {:?}", e),
1913        }
1914    }
1915
1916    // Responses
1917
1918    fn check_rsp_generic(response: Response, cmd: u8) {
1919        let mut p = ResponseDecoder::new();
1920        assert_eq!(p.receive(ESCAPE_CHAR), Ok(None));
1921        match p.receive(cmd) {
1922            Ok(Some(ref x)) if x == &response => {}
1923            e => panic!("Did not expect: {:?}", e),
1924        }
1925
1926        let mut e = ResponseEncoder::new(&response).unwrap();
1927        assert_eq!(e.next(), Some(ESCAPE_CHAR));
1928        assert_eq!(e.next(), Some(cmd));
1929        assert_eq!(e.next(), None);
1930        assert_eq!(e.next(), None);
1931    }
1932
1933    #[test]
1934    fn check_rsp_overflow() {
1935        check_rsp_generic(Response::Overflow, RES_OVERFLOW);
1936    }
1937
1938    #[test]
1939    fn check_rsp_pong() {
1940        check_rsp_generic(Response::Pong, RES_PONG);
1941    }
1942
1943    #[test]
1944    fn check_rsp_badaddress() {
1945        check_rsp_generic(Response::BadAddress, RES_BADADDR);
1946    }
1947
1948    #[test]
1949    fn check_rsp_internalerror() {
1950        check_rsp_generic(Response::InternalError, RES_INTERROR);
1951    }
1952
1953    #[test]
1954    fn check_rsp_badarguments() {
1955        check_rsp_generic(Response::BadArguments, RES_BADARGS);
1956    }
1957
1958    #[test]
1959    fn check_rsp_ok() {
1960        check_rsp_generic(Response::Ok, RES_OK);
1961    }
1962
1963    #[test]
1964    fn check_rsp_unknown() {
1965        check_rsp_generic(Response::Unknown, RES_UNKNOWN);
1966    }
1967
1968    #[test]
1969    fn check_rsp_exflashtimeout() {
1970        check_rsp_generic(Response::ExtFlashTimeout, RES_XFTIMEOUT);
1971    }
1972
1973    #[test]
1974    fn check_rsp_exflashpageerror() {
1975        check_rsp_generic(Response::ExtFlashPageError, RES_XFEPE);
1976    }
1977
1978    #[test]
1979    fn check_rsp_changebaudfail() {
1980        check_rsp_generic(Response::ChangeBaudFail, RES_CHANGE_BAUD_FAIL);
1981    }
1982
1983    #[test]
1984    fn check_rsp_crc_rx() {
1985        let mut p = ResponseDecoder::new();
1986        assert_eq!(p.receive(ESCAPE_CHAR), Ok(None));
1987        assert_eq!(p.receive(RES_CRCRX), Ok(None));
1988        // Length
1989        assert_eq!(p.receive(0x34), Ok(None));
1990        assert_eq!(p.receive(0x12), Ok(None));
1991        // CRC
1992        assert_eq!(p.receive(0xEF), Ok(None));
1993        assert_eq!(p.receive(0xBE), Ok(None));
1994        assert_eq!(p.receive(0xAD), Ok(None));
1995        assert_eq!(
1996            p.receive(0xDE),
1997            Ok(Some(Response::CrcRxBuffer {
1998                length: 0x1234,
1999                crc: 0xDEADBEEF,
2000            }))
2001        );
2002
2003        let r = Response::CrcRxBuffer {
2004            length: 0x1234,
2005            crc: 0xDEADBEEF,
2006        };
2007        let mut e = ResponseEncoder::new(&r).unwrap();
2008        assert_eq!(e.next(), Some(ESCAPE_CHAR));
2009        assert_eq!(e.next(), Some(RES_CRCRX));
2010        assert_eq!(e.next(), Some(0x34));
2011        assert_eq!(e.next(), Some(0x12));
2012        assert_eq!(e.next(), Some(0xEF));
2013        assert_eq!(e.next(), Some(0xBE));
2014        assert_eq!(e.next(), Some(0xAD));
2015        assert_eq!(e.next(), Some(0xDE));
2016        assert_eq!(e.next(), None);
2017        assert_eq!(e.next(), None);
2018    }
2019
2020    #[test]
2021    fn check_rsp_rrange() {
2022        let mut p = ResponseDecoder::new();
2023        p.set_payload_len(4).unwrap();
2024        assert_eq!(p.receive(ESCAPE_CHAR), Ok(None));
2025        assert_eq!(p.receive(RES_RRANGE), Ok(None));
2026        // four bytes of data
2027        assert_eq!(p.receive(0x00), Ok(None));
2028        assert_eq!(p.receive(0x11), Ok(None));
2029        assert_eq!(p.receive(0x22), Ok(None));
2030        assert_eq!(
2031            p.receive(0x33),
2032            Ok(Some(
2033                Response::ReadRange { data: &[0x00, 0x11, 0x22, 0x33] },
2034            ))
2035        );
2036
2037        let r = Response::ReadRange { data: &[0x00, 0x11, 0x22, 0x33] };
2038        let mut e = ResponseEncoder::new(&r).unwrap();
2039        assert_eq!(e.next(), Some(ESCAPE_CHAR));
2040        assert_eq!(e.next(), Some(RES_RRANGE));
2041        assert_eq!(e.next(), Some(0x00));
2042        assert_eq!(e.next(), Some(0x11));
2043        assert_eq!(e.next(), Some(0x22));
2044        assert_eq!(e.next(), Some(0x33));
2045        assert_eq!(e.next(), None);
2046        assert_eq!(e.next(), None);
2047    }
2048
2049    #[test]
2050    fn check_rsp_xrrange() {
2051        let mut p = ResponseDecoder::new();
2052        p.set_payload_len(4).unwrap();
2053        assert_eq!(p.receive(ESCAPE_CHAR), Ok(None));
2054        assert_eq!(p.receive(RES_XRRANGE), Ok(None));
2055        // four bytes of data
2056        assert_eq!(p.receive(0x00), Ok(None));
2057        assert_eq!(p.receive(0x11), Ok(None));
2058        assert_eq!(p.receive(0x22), Ok(None));
2059        assert_eq!(
2060            p.receive(0x33),
2061            Ok(Some(
2062                Response::ExReadRange { data: &[0x00, 0x11, 0x22, 0x33] },
2063            ))
2064        );
2065
2066        let r = Response::ExReadRange { data: &[0x00, 0x11, 0x22, 0x33] };
2067        let mut e = ResponseEncoder::new(&r).unwrap();
2068        assert_eq!(e.next(), Some(ESCAPE_CHAR));
2069        assert_eq!(e.next(), Some(RES_XRRANGE));
2070        assert_eq!(e.next(), Some(0x00));
2071        assert_eq!(e.next(), Some(0x11));
2072        assert_eq!(e.next(), Some(0x22));
2073        assert_eq!(e.next(), Some(0x33));
2074        assert_eq!(e.next(), None);
2075        assert_eq!(e.next(), None);
2076    }
2077
2078    #[test]
2079    fn check_rsp_get_attr() {
2080        let mut p = ResponseDecoder::new();
2081        assert_eq!(p.receive(ESCAPE_CHAR), Ok(None));
2082        assert_eq!(p.receive(RES_GATTR), Ok(None));
2083        // eight bytes of key
2084        assert_eq!(p.receive(0x00), Ok(None));
2085        assert_eq!(p.receive(0x11), Ok(None));
2086        assert_eq!(p.receive(0x22), Ok(None));
2087        assert_eq!(p.receive(0x33), Ok(None));
2088        assert_eq!(p.receive(0x44), Ok(None));
2089        assert_eq!(p.receive(0x55), Ok(None));
2090        assert_eq!(p.receive(0x66), Ok(None));
2091        assert_eq!(p.receive(0x77), Ok(None));
2092        // Length byte
2093        assert_eq!(p.receive(0x04), Ok(None));
2094        // length bytes of data
2095        assert_eq!(p.receive(0xAA), Ok(None));
2096        assert_eq!(p.receive(0xBB), Ok(None));
2097        assert_eq!(p.receive(0xCC), Ok(None));
2098        assert_eq!(p.receive(0xDD), Ok(None));
2099        // 55 - length bytes of padding
2100        for _ in 4..MAX_ATTR_LEN - 1 {
2101            assert_eq!(p.receive(0xFF), Ok(None));
2102        }
2103        assert_eq!(
2104            p.receive(0xFF),
2105            Ok(Some(Response::GetAttr {
2106                key: &[0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77],
2107                value: &[0xAA, 0xBB, 0xCC, 0xDD],
2108            }))
2109        );
2110
2111        let r = Response::GetAttr {
2112            key: &[0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77],
2113            value: &[0xAA, 0xBB, 0xCC, 0xDD],
2114        };
2115        let mut e = ResponseEncoder::new(&r).unwrap();
2116        assert_eq!(e.next(), Some(ESCAPE_CHAR));
2117        assert_eq!(e.next(), Some(RES_GATTR));
2118        assert_eq!(e.next(), Some(0x00));
2119        assert_eq!(e.next(), Some(0x11));
2120        assert_eq!(e.next(), Some(0x22));
2121        assert_eq!(e.next(), Some(0x33));
2122        assert_eq!(e.next(), Some(0x44));
2123        assert_eq!(e.next(), Some(0x55));
2124        assert_eq!(e.next(), Some(0x66));
2125        assert_eq!(e.next(), Some(0x77));
2126        assert_eq!(e.next(), Some(0x04));
2127        assert_eq!(e.next(), Some(0xAA));
2128        assert_eq!(e.next(), Some(0xBB));
2129        assert_eq!(e.next(), Some(0xCC));
2130        assert_eq!(e.next(), Some(0xDD));
2131        for _ in 4..MAX_ATTR_LEN {
2132            assert!(e.next().is_some());
2133        }
2134        assert_eq!(e.next(), None);
2135        assert_eq!(e.next(), None);
2136    }
2137
2138    #[test]
2139    fn check_rsp_crc_int_flash() {
2140        let mut p = ResponseDecoder::new();
2141        assert_eq!(p.receive(ESCAPE_CHAR), Ok(None));
2142        assert_eq!(p.receive(RES_CRCIF), Ok(None));
2143        // CRC
2144        assert_eq!(p.receive(0xEF), Ok(None));
2145        assert_eq!(p.receive(0xBE), Ok(None));
2146        assert_eq!(p.receive(0xAD), Ok(None));
2147        assert_eq!(
2148            p.receive(0xDE),
2149            Ok(Some(Response::CrcIntFlash { crc: 0xDEADBEEF }))
2150        );
2151
2152        let r = Response::CrcIntFlash { crc: 0xDEADBEEF };
2153        let mut e = ResponseEncoder::new(&r).unwrap();
2154        assert_eq!(e.next(), Some(ESCAPE_CHAR));
2155        assert_eq!(e.next(), Some(RES_CRCIF));
2156        assert_eq!(e.next(), Some(0xEF));
2157        assert_eq!(e.next(), Some(0xBE));
2158        assert_eq!(e.next(), Some(0xAD));
2159        assert_eq!(e.next(), Some(0xDE));
2160        assert_eq!(e.next(), None);
2161        assert_eq!(e.next(), None);
2162    }
2163
2164    #[test]
2165    fn check_rsp_crc_ext_flash() {
2166        let mut p = ResponseDecoder::new();
2167        assert_eq!(p.receive(ESCAPE_CHAR), Ok(None));
2168        assert_eq!(p.receive(RES_CRCXF), Ok(None));
2169        // CRC
2170        assert_eq!(p.receive(0xEF), Ok(None));
2171        assert_eq!(p.receive(0xBE), Ok(None));
2172        assert_eq!(p.receive(0xAD), Ok(None));
2173        assert_eq!(
2174            p.receive(0xDE),
2175            Ok(Some(Response::CrcExtFlash { crc: 0xDEADBEEF }))
2176        );
2177
2178        let r = Response::CrcExtFlash { crc: 0xDEADBEEF };
2179        let mut e = ResponseEncoder::new(&r).unwrap();
2180        assert_eq!(e.next(), Some(ESCAPE_CHAR));
2181        assert_eq!(e.next(), Some(RES_CRCXF));
2182        assert_eq!(e.next(), Some(0xEF));
2183        assert_eq!(e.next(), Some(0xBE));
2184        assert_eq!(e.next(), Some(0xAD));
2185        assert_eq!(e.next(), Some(0xDE));
2186        assert_eq!(e.next(), None);
2187        assert_eq!(e.next(), None);
2188    }
2189
2190    #[test]
2191    fn check_rsp_info() {
2192        let mut p = ResponseDecoder::new();
2193        assert_eq!(p.receive(ESCAPE_CHAR), Ok(None));
2194        assert_eq!(p.receive(RES_INFO), Ok(None));
2195        // length
2196        assert_eq!(p.receive(0x08), Ok(None));
2197        // eight bytes of data
2198        assert_eq!(p.receive(0x00), Ok(None));
2199        assert_eq!(p.receive(0x11), Ok(None));
2200        assert_eq!(p.receive(0x22), Ok(None));
2201        assert_eq!(p.receive(0x33), Ok(None));
2202        assert_eq!(p.receive(0x44), Ok(None));
2203        assert_eq!(p.receive(0x55), Ok(None));
2204        assert_eq!(p.receive(0x66), Ok(None));
2205        assert_eq!(p.receive(0x77), Ok(None));
2206        // pad up to 191 bytes
2207        for _ in 8..MAX_INFO_LEN - 1 {
2208            assert_eq!(p.receive(0x00), Ok(None));
2209        }
2210        // final padding byte
2211        assert_eq!(
2212            p.receive(0x00),
2213            Ok(Some(Response::Info {
2214                info: &[0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77],
2215            }))
2216        );
2217
2218        // Check follow-on command
2219        assert_eq!(p.receive(ESCAPE_CHAR), Ok(None));
2220        assert_eq!(p.receive(RES_PONG), Ok(Some(Response::Pong)));
2221
2222        let r = Response::Info { info: &[0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77] };
2223        let mut e = ResponseEncoder::new(&r).unwrap();
2224        assert_eq!(e.next(), Some(ESCAPE_CHAR));
2225        assert_eq!(e.next(), Some(RES_INFO));
2226        // length
2227        assert_eq!(e.next(), Some(0x08));
2228        // data
2229        assert_eq!(e.next(), Some(0x00));
2230        assert_eq!(e.next(), Some(0x11));
2231        assert_eq!(e.next(), Some(0x22));
2232        assert_eq!(e.next(), Some(0x33));
2233        assert_eq!(e.next(), Some(0x44));
2234        assert_eq!(e.next(), Some(0x55));
2235        assert_eq!(e.next(), Some(0x66));
2236        assert_eq!(e.next(), Some(0x77));
2237        // padding
2238        for _ in 8..MAX_INFO_LEN {
2239            assert_eq!(e.next(), Some(0x00));
2240        }
2241        assert_eq!(e.next(), None);
2242        assert_eq!(e.next(), None);
2243    }
2244
2245    #[test]
2246    fn check_response_write() {
2247        let r = Response::Pong;
2248        // More than large enough
2249        let mut e = ResponseEncoder::new(&r).unwrap();
2250        let mut buffer = [0xFFu8; 4];
2251        assert_eq!(e.write(&mut buffer), 2);
2252        assert_eq!(&buffer[0..4], &[ESCAPE_CHAR, RES_PONG, 0xFF, 0xFF]);
2253
2254        // Too small - do it in pieces
2255        e.reset();
2256        buffer[0] = 0xFF;
2257        assert_eq!(e.write(&mut buffer[0..1]), 1);
2258        assert_eq!(buffer[0], ESCAPE_CHAR);
2259        buffer[0] = 0xFF;
2260        assert_eq!(e.write(&mut buffer[0..1]), 1);
2261        assert_eq!(buffer[0], RES_PONG);
2262        assert_eq!(e.write(&mut buffer[0..1]), 0);
2263
2264        // perfectly sized
2265        e.reset();
2266        for b in buffer.iter_mut() {
2267            *b = 0xFF
2268        }
2269        assert_eq!(e.write(&mut buffer[0..2]), 2);
2270        assert_eq!(&buffer[0..2], &[ESCAPE_CHAR, RES_PONG]);
2271    }
2272
2273    #[test]
2274    fn check_command_write() {
2275        let r = Command::Ping;
2276        let mut e = CommandEncoder::new(&r).unwrap();
2277        let mut buffer = [0xFFu8; 4];
2278        // More than large enough
2279        assert_eq!(e.write(&mut buffer), 2);
2280        assert_eq!(&buffer[0..4], &[ESCAPE_CHAR, CMD_PING, 0xFF, 0xFF]);
2281
2282        // Too small - do it in pieces
2283        e.reset();
2284        buffer[0] = 0xFF;
2285        assert_eq!(e.write(&mut buffer[0..1]), 1);
2286        assert_eq!(buffer[0], ESCAPE_CHAR);
2287        buffer[0] = 0xFF;
2288        assert_eq!(e.write(&mut buffer[0..1]), 1);
2289        assert_eq!(buffer[0], CMD_PING);
2290        assert_eq!(e.write(&mut buffer[0..1]), 0);
2291
2292        // perfectly sized
2293        e.reset();
2294        for b in buffer.iter_mut() {
2295            *b = 0xFF
2296        }
2297        assert_eq!(e.write(&mut buffer[0..2]), 2);
2298        assert_eq!(&buffer[0..2], &[ESCAPE_CHAR, CMD_PING]);
2299    }
2300
2301    #[test]
2302    fn check_command_decode_buffer() {
2303        let mut p = CommandDecoder::new();
2304        let buffer = [
2305            0xEFu8,
2306            0xBE,
2307            0xAD,
2308            0xDE,
2309            0x78,
2310            0x56,
2311            0x34,
2312            0x12,
2313            ESCAPE_CHAR,
2314            CMD_CRCIF,
2315        ];
2316        let callback = |x: &Command| match x {
2317            &Command::CrcIntFlash { address, length } => {
2318                assert_eq!(address, 0xDEADBEEF);
2319                assert_eq!(length, 0x12345678);
2320            }
2321            _ => panic!("Bad command {:?}", x),
2322        };
2323        match p.read(&buffer, callback) {
2324            Ok(_) => {}
2325            Err(e) => panic!("Did not expect: {:?}", e),
2326        }
2327    }
2328
2329    #[test]
2330    fn check_response_decode_buffer() {
2331        let mut p = ResponseDecoder::new();
2332        let buffer = [ESCAPE_CHAR, RES_CRCXF, 0xEF, 0xBE, 0xAD, 0xDE];
2333        let callback = |x: &Response| match x {
2334            &Response::CrcExtFlash { crc } => {
2335                assert_eq!(crc, 0xDEADBEEF);
2336            }
2337            _ => panic!("Bad command {:?}", x),
2338        };
2339        match p.read(&buffer, callback) {
2340            Ok(_) => {}
2341            Err(e) => panic!("Did not expect: {:?}", e),
2342        }
2343    }
2344
2345}
2346
2347// ****************************************************************************
2348//
2349// End Of File
2350//
2351// ****************************************************************************