[][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 the Decoder and Packet
  • A write_to() method is added to Packet, allowing you to write the Packet directly to anything that implements std::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.