[−][src]Crate anpp
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.
Examples
Each 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 Decoder
.
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");
Feature Flags
The std
feature flag enables several nice-to-have features, including:
- Implementations of
std::error::Error
for all error types - The
Decoder
will use a dynamically sized buffer which can resize when it is full instead of throwing an error - You can use the
std::io::Write
trait to write data into theDecoder
andPacket
- A
write_to()
method is added toPacket
, allowing you to write thePacket
directly to anything that implementsstd::io::Write
An example of using std::io::Write
with a Packet
:
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)?;
Likewise, 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);
Modules
errors | All error types used in this crate. |
Structs
Decoder | Decoder for the Advanced Navigation Packet Protocol. |
Packet | An arbitrary chunk of bytes with a user-defined ID. |