A Rust implementation of the Advanced Navigation Packet Protocol.
The Advanced Navigation Packet Protocol is a low-overhead communication protocol designed mainly for embedded systems. It provides a mechanism for breaking a stream of data into packets (framing) while ensuring data integrity via CRC-16 checksums.
Packet is essentially a collection of bytes with an associated ID.
The communication protocol is transport-agnostic (it doesn't care if
you're using RS-232, ethernet, smoke signals, etc), you just create a
Packet and write it to a buffer that can be handed off to the
underlying transport mechanism.
// create a packet let pkt = Packet::with_data(42, b"A very important message")?; // then write it to an internal buffer let mut buffer = [0; 512]; let bytes_written = pkt.write_to_buffer(&mut buffer)?; // and finally, you can send the information using your actual transport // mechanism. In this case, RS-232. send_serial_message(&buffer[..bytes_written])?;
In order to read a message on the other side, you'll need a
The idea is you write raw data into the
Decoder and it'll keep returning
DecodeError::RequiresMoreData until it has received a complete packet.
// create the decoder let mut dec = Decoder::new(); // then read some data let data = read_data_from_serial(); // next you need to copy the data into the decoder dec.push_data(&data)?; // Now the decoder has some bytes to work with, we can read back our packet let pkt = dec.decode()?; assert_eq!(pkt.id(), 42); assert_eq!(pkt.contents(), b"A very important message");
std feature flag enables several nice-to-have features, including:
- Implementations of
std::error::Errorfor all error types
Decoderwill use a dynamically sized buffer which can resize when it is full instead of throwing an error
- You can use the
std::io::Writetrait to write data into the
write_to()method is added to
Packet, allowing you to write the
Packetdirectly to anything that implements
An example of using
std::io::Write with a
use std::io::Write; // open our serial port again let mut port = open_serial_port("/dev/TTYUSB1"); // then create a packet let mut pkt = Packet::with_data(42, b"This is a very important message")?; // oops, we forgot to finish the sentence! pkt.write(b".")?; // now encode the packet and write it out over RS-232 pkt.write_to(&mut port)?;
std::io::Write makes it easy to work with a decoder.
use std::io; let mut dec = Decoder::new(); let mut serial = open_serial_port("/dev/TTYUSB0"); // `std::io::copy()` copies all data from a Reader to a Writer let bytes_read = io::copy(&mut serial, &mut dec)?; let pkt = dec.decode()?; assert_eq!(pkt.id(), 42);
All error types used in this crate.
Decoder for the Advanced Navigation Packet Protocol.
An arbitrary chunk of bytes with a user-defined ID.