#![cfg_attr(not(feature = "std"), no_std)]
mod checksum;
mod decoder;
mod encode;
mod framehandler;
pub use encode::ChunkedEncoder;
pub use encode::encode;
#[cfg(feature = "std")]
pub use encode::encode_buffered;
pub use encode::encode_configuration;
pub use encode::encode_diagnostic;
pub use encode::encode_packet;
pub use decoder::DecodeStatus;
pub use decoder::Decoder;
pub use decoder::FrameHandler;
#[cfg(feature = "std")]
pub use framehandler::BufferedFrameHandler;
#[cfg(feature = "std")]
pub use framehandler::OwnedLatestFrame;
pub use framehandler::ReferencedLatestFrame;
#[non_exhaustive]
pub struct Constants;
impl Constants {
pub const END: u8 = 0xC0;
pub const ESC: u8 = 0xDB;
pub const ESC_END: u8 = 0xDC;
pub const ESC_ESC: u8 = 0xDD;
pub const DIAGNOSTIC: u8 = 0x0A;
pub const CONFIGURATION: u8 = 0xA9;
pub const IP4_FROM: u8 = 0x45;
pub const IP4_TO: u8 = 0x4F;
pub const IP6_FROM: u8 = 0x60;
pub const IP6_TO: u8 = 0x6F;
}
#[derive(Debug, Copy, Clone)]
pub enum FrameType {
Diagnostic,
Configuration,
Ip,
}
#[derive(Debug)]
#[cfg(feature = "std")]
pub enum Slipmux {
Diagnostic(String),
Configuration(Vec<u8>),
Packet(Vec<u8>),
}
#[derive(Debug)]
pub enum Error {
NotEnoughSpace,
BadFraming,
BadFrameType(u8),
BadFCS,
Abort,
}
#[cfg(test)]
#[cfg(feature = "std")]
mod tests {
use super::*;
use crate::encode::encode_buffered;
use coap_lite::Packet;
#[test]
fn encode_decode_all_frametypes() {
let input_diagnostic = Slipmux::Diagnostic("Hello World!".to_owned());
let mut buffer = encode_buffered(input_diagnostic);
let input_configuration = Slipmux::Configuration(Packet::new().to_bytes().unwrap());
buffer.append(&mut encode_buffered(input_configuration));
let input_packet = Slipmux::Packet(vec![0x60, 0x0d, 0xda, 0x01, 0xfe, 0x80]);
buffer.append(&mut encode_buffered(input_packet));
let mut slipmux = Decoder::new();
let mut handler = BufferedFrameHandler::new();
for byte in &buffer {
let _: Result<DecodeStatus, Error> = slipmux.decode(*byte, &mut handler);
}
let frames = handler.results;
assert_eq!(3, frames.len());
for slipframe in frames {
match slipframe {
Ok(Slipmux::Diagnostic(s)) => {
assert_eq!(s, "Hello World!");
}
Ok(Slipmux::Configuration(conf)) => {
assert_eq!(conf, Packet::new().to_bytes().unwrap());
}
Ok(Slipmux::Packet(packet)) => {
assert_eq!(packet, vec![0x60, 0x0d, 0xda, 0x01, 0xfe, 0x80]);
}
Err(_) => unreachable!(),
}
}
}
#[test]
fn encode_decode_ip() {
const IP4_FOO: [u8; 124] = [
0x45, 0x00, 0x00, 0x7c, 0x44, 0xcd, 0x40, 0x00, 0x40, 0x06, 0x96, 0x57, 0x8d, 0x16,
0x1c, 0x31, 0x68, 0x14, 0x4d, 0xfc, 0xa6, 0x1c, 0x01, 0xbb, 0xb2, 0xb2, 0xfc, 0xee,
0x81, 0xf0, 0x38, 0xfd, 0x80, 0x18, 0x26, 0x70, 0x5f, 0xc6, 0x00, 0x00, 0x01, 0x01,
0x08, 0x0a, 0xb0, 0x74, 0xff, 0x78, 0x39, 0x26, 0x09, 0xb2, 0x17, 0x03, 0x03, 0x00,
0x43, 0x81, 0x0d, 0xf1, 0x55, 0xb4, 0x9b, 0xcc, 0xb6, 0xd3, 0xcc, 0x91, 0x02, 0x27,
0x33, 0xef, 0x55, 0x88, 0x75, 0x7f, 0x18, 0x07, 0x01, 0xba, 0x6f, 0x89, 0xd8, 0x30,
0xfc, 0x3a, 0x9f, 0xc8, 0x66, 0xa4, 0xf4, 0x77, 0x71, 0x2c, 0xac, 0xc2, 0xbc, 0x06,
0x45, 0x00, 0x20, 0x48, 0xbe, 0xda, 0x93, 0x23, 0xf3, 0xf5, 0x23, 0xfb, 0x4c, 0x26,
0x13, 0xcf, 0x97, 0xdf, 0x09, 0x1e, 0x01, 0x7c, 0x98, 0xc1, 0xf2, 0xea,
];
const IP4_BAR: [u8; 90] = [
0x45, 0x00, 0x00, 0x5a, 0x3f, 0x6a, 0x40, 0x00, 0x40, 0x06, 0x4f, 0x4e, 0x8d, 0x16,
0x1c, 0x31, 0x41, 0x6c, 0xc1, 0x32, 0xde, 0x8c, 0x01, 0xbb, 0xd8, 0x6c, 0xbb, 0x32,
0x1a, 0x93, 0x1f, 0x83, 0x80, 0x18, 0x30, 0xf3, 0xac, 0x32, 0x00, 0x00, 0x01, 0x01,
0x08, 0x0a, 0x46, 0x9d, 0x99, 0x43, 0x16, 0x9f, 0x1e, 0xf2, 0x17, 0x03, 0x03, 0x00,
0x21, 0xa2, 0x2b, 0xbf, 0x36, 0xaa, 0x63, 0x47, 0x6d, 0xcf, 0xe6, 0x30, 0x6e, 0xb7,
0x79, 0x28, 0x49, 0x42, 0x3e, 0x7f, 0xc1, 0xb4, 0x80, 0x09, 0x5a, 0xd2, 0x63, 0x16,
0x35, 0x4a, 0xe5, 0x98, 0xf8, 0x70,
];
const IP6_FOO: [u8; 147] = [
0x60, 0x00, 0x00, 0x00, 0x00, 0x6b, 0x11, 0x01, 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x02, 0x1a, 0xe8, 0xff, 0xfe, 0x96, 0xa1, 0xd7, 0xff, 0x02, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x02, 0x22,
0x02, 0x23, 0x00, 0x6b, 0xc0, 0x0a, 0x01, 0xb0, 0x49, 0x0e, 0x00, 0x01, 0x00, 0x0a,
0x00, 0x03, 0x00, 0x01, 0x00, 0x1a, 0xe8, 0x96, 0xa1, 0xd7, 0x00, 0x06, 0x00, 0x0e,
0x00, 0x17, 0x00, 0x18, 0x00, 0x1f, 0x00, 0x11, 0x00, 0x15, 0x00, 0x16, 0x00, 0x27,
0x00, 0x08, 0x00, 0x02, 0xff, 0xff, 0x00, 0x10, 0x00, 0x11, 0x00, 0x00, 0x80, 0x24,
0x00, 0x0b, 0x4f, 0x70, 0x74, 0x69, 0x49, 0x70, 0x50, 0x68, 0x6f, 0x6e, 0x65, 0x00,
0x27, 0x00, 0x10, 0x01, 0x0d, 0x34, 0x39, 0x34, 0x30, 0x34, 0x32, 0x38, 0x37, 0x35,
0x38, 0x35, 0x34, 0x35, 0x00, 0x00, 0x03, 0x00, 0x0c, 0xe8, 0x96, 0xa1, 0xd7, 0x00,
0x00, 0x0e, 0x10, 0x00, 0x00, 0x15, 0x18,
];
const IP6_BAR: [u8; 105] = [
0x60, 0x0d, 0xda, 0x0e, 0x00, 0x41, 0x11, 0x01, 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x45, 0x45, 0xbc, 0x0d, 0x6f, 0x88, 0x2f, 0x17, 0xff, 0x02, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x02, 0x22,
0x02, 0x23, 0x00, 0x41, 0x84, 0xbe, 0x0b, 0xe1, 0x3f, 0x99, 0x00, 0x01, 0x00, 0x0e,
0x00, 0x01, 0x00, 0x01, 0x23, 0xfd, 0xc5, 0x32, 0x50, 0x9a, 0x4c, 0xb3, 0x04, 0xfe,
0x00, 0x06, 0x00, 0x0a, 0x00, 0x11, 0x00, 0x20, 0x00, 0x17, 0x00, 0x18, 0x00, 0x27,
0x00, 0x08, 0x00, 0x02, 0xff, 0xff, 0x00, 0x10, 0x00, 0x0b, 0x00, 0x00, 0x02, 0xa2,
0x00, 0x05, 0x69, 0x44, 0x52, 0x41, 0x43,
];
let mut buffer: [u8; 2048] = [0; 2048];
let length = encode_packet(&IP4_FOO, &mut buffer);
assert_eq!(length, 126);
let mut slipmux = Decoder::new();
let mut handler = BufferedFrameHandler::new();
for byte in &buffer[..length] {
let _: Result<DecodeStatus, Error> = slipmux.decode(*byte, &mut handler);
}
let mut frames = handler.results;
let decoded = frames.pop().unwrap();
match decoded.unwrap() {
Slipmux::Packet(decoded_ip4_foo) => assert_eq!(decoded_ip4_foo, IP4_FOO),
_ => unreachable!(),
}
let length = encode_packet(&IP4_BAR, &mut buffer);
assert_eq!(length, 92);
let mut slipmux = Decoder::new();
let mut handler = BufferedFrameHandler::new();
for byte in &buffer[..length] {
let _: Result<DecodeStatus, Error> = slipmux.decode(*byte, &mut handler);
}
let mut frames = handler.results;
let decoded = frames.pop().unwrap();
match decoded.unwrap() {
Slipmux::Packet(decoded_ip4_bar) => assert_eq!(decoded_ip4_bar, IP4_BAR),
_ => unreachable!(),
}
let length = encode_packet(&IP6_FOO, &mut buffer);
assert_eq!(length, 150);
let mut slipmux = Decoder::new();
let mut handler = BufferedFrameHandler::new();
for byte in &buffer[..length] {
let _: Result<DecodeStatus, Error> = slipmux.decode(*byte, &mut handler);
}
let mut frames = handler.results;
let decoded = frames.pop().unwrap();
match decoded.unwrap() {
Slipmux::Packet(decoded_ip6_foo) => assert_eq!(decoded_ip6_foo, IP6_FOO),
_ => unreachable!(),
}
let length = encode_packet(&IP6_BAR, &mut buffer);
assert_eq!(length, 107);
let mut slipmux = Decoder::new();
let mut handler = BufferedFrameHandler::new();
for byte in &buffer[..length] {
let _: Result<DecodeStatus, Error> = slipmux.decode(*byte, &mut handler);
}
let mut frames = handler.results;
let decoded = frames.pop().unwrap();
match decoded.unwrap() {
Slipmux::Packet(decoded_ip6_bar) => assert_eq!(decoded_ip6_bar, IP6_BAR),
_ => unreachable!(),
}
}
}