1#![doc = include_str!("../README.md")]
2#![cfg_attr(not(any(test, feature = "std")), no_std)]
3#![allow(clippy::uninlined_format_args)]
4
5pub mod address;
6pub mod book;
7pub mod interface_manager;
8pub mod logging;
9pub mod nash;
10pub mod net_stack;
11pub mod socket;
12pub mod toolkits;
13pub mod traits;
14pub mod well_known;
15pub mod wire_frames;
16
17#[cfg(any(test, feature = "std"))]
18pub mod conformance;
19
20pub use logging::fmtlog;
22
23use crate::logging::warn;
24pub use address::Address;
25use interface_manager::InterfaceSendError;
26use nash::NameHash;
27pub use net_stack::{NetStack, NetStackSendError};
28use serde::{Deserialize, Serialize};
29
30#[cfg_attr(feature = "defmt-v1", derive(defmt::Format))]
31#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize, Eq)]
32pub struct FrameKind(pub u8);
33
34#[cfg_attr(feature = "defmt-v1", derive(defmt::Format))]
35#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
36pub struct Key(pub [u8; 8]);
37
38#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
39pub struct ProtocolError(pub u16);
40
41#[cfg_attr(feature = "defmt-v1", derive(defmt::Format))]
42#[derive(Debug, Clone, PartialEq)]
43pub struct AnyAllAppendix {
44 pub key: Key,
45 pub nash: Option<NameHash>,
46}
47
48#[cfg_attr(feature = "defmt-v1", derive(defmt::Format))]
49#[derive(Debug, Clone, PartialEq)]
50pub struct Header {
51 pub src: Address,
52 pub dst: Address,
53 pub any_all: Option<AnyAllAppendix>,
54 pub seq_no: Option<u16>,
55 pub kind: FrameKind,
56 pub ttl: u8,
57}
58
59#[cfg_attr(feature = "defmt-v1", derive(defmt::Format))]
60#[derive(Debug, Clone)]
61pub struct HeaderSeq {
62 pub src: Address,
63 pub dst: Address,
64 pub any_all: Option<AnyAllAppendix>,
65 pub seq_no: u16,
66 pub kind: FrameKind,
67 pub ttl: u8,
68}
69
70impl core::fmt::Display for Header {
71 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
72 write!(
73 f,
74 "({} -> {}; FK:{:03}, SQ:",
75 self.src, self.dst, self.kind.0,
76 )?;
77 if let Some(seq) = self.seq_no {
78 write!(f, "{:04X}", seq)?;
79 } else {
80 f.write_str("----")?;
81 }
82 f.write_str(")")?;
83 Ok(())
84 }
85}
86
87impl core::fmt::Display for HeaderSeq {
88 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
89 write!(
90 f,
91 "({} -> {}; FK:{:03}, SQ:{:04X})",
92 self.src, self.dst, self.kind.0, self.seq_no,
93 )?;
94 Ok(())
95 }
96}
97
98impl FrameKind {
99 pub const RESERVED: Self = Self(0);
100 pub const ENDPOINT_REQ: Self = Self(1);
101 pub const ENDPOINT_RESP: Self = Self(2);
102 pub const TOPIC_MSG: Self = Self(3);
103 pub const PROTOCOL_ERROR: Self = Self(u8::MAX);
104}
105
106impl postcard_schema::Schema for FrameKind {
107 const SCHEMA: &'static postcard_schema::schema::NamedType =
108 &postcard_schema::schema::NamedType {
109 name: "FrameKind",
110 ty: u8::SCHEMA.ty,
111 };
112}
113
114impl postcard_schema::Schema for Key {
115 const SCHEMA: &'static postcard_schema::schema::NamedType =
116 &postcard_schema::schema::NamedType {
117 name: "Key",
118 ty: <[u8; 8]>::SCHEMA.ty,
119 };
120}
121
122impl ProtocolError {
123 pub const RESERVED: Self = Self(0);
124 pub const SSE_NO_SPACE: Self = Self(1);
126 pub const SSE_DESER_FAILED: Self = Self(2);
127 pub const SSE_TYPE_MISMATCH: Self = Self(3);
128 pub const SSE_WHAT_THE_HELL: Self = Self(4);
129 pub const ISE_DESTINATION_LOCAL: Self = Self(11);
131 pub const ISE_NO_ROUTE_TO_DEST: Self = Self(12);
132 pub const ISE_INTERFACE_FULL: Self = Self(13);
133 pub const ISE_INTERNAL_ERROR: Self = Self(14);
134 pub const ISE_ANY_PORT_MISSING_KEY: Self = Self(15);
135 pub const ISE_TTL_EXPIRED: Self = Self(16);
136 pub const ISE_ROUTING_LOOP: Self = Self(17);
137 pub const NSSE_NO_ROUTE: Self = Self(21);
139 pub const NSSE_ANY_PORT_MISSING_KEY: Self = Self(22);
140 pub const NSSE_WRONG_PORT_KIND: Self = Self(23);
141 pub const NSSE_ANY_PORT_NOT_UNIQUE: Self = Self(24);
142 pub const NSSE_ALL_PORT_MISSING_KEY: Self = Self(25);
143 pub const NSSE_WOULD_DEADLOCK: Self = Self(26);
144}
145
146impl Header {
147 #[inline]
148 pub fn with_seq(self, seq_no: u16) -> HeaderSeq {
149 let Self {
150 src,
151 dst,
152 any_all,
153 seq_no: _,
154 kind,
155 ttl,
156 } = self;
157 HeaderSeq {
158 src,
159 dst,
160 any_all,
161 seq_no,
162 kind,
163 ttl,
164 }
165 }
166
167 #[inline]
168 pub fn to_headerseq_or_with_seq<F: FnOnce() -> u16>(&self, f: F) -> HeaderSeq {
169 HeaderSeq {
170 src: self.src,
171 dst: self.dst,
172 any_all: self.any_all.clone(),
173 seq_no: self.seq_no.unwrap_or_else(f),
174 kind: self.kind,
175 ttl: self.ttl,
176 }
177 }
178
179 #[inline]
180 pub fn decrement_ttl(&mut self) -> Result<(), InterfaceSendError> {
181 self.ttl = self.ttl.checked_sub(1).ok_or_else(|| {
182 warn!("Header TTL expired: {:?}", self);
183 InterfaceSendError::TtlExpired
184 })?;
185 Ok(())
186 }
187}
188
189impl HeaderSeq {
190 #[inline]
191 pub fn decrement_ttl(&mut self) -> Result<(), InterfaceSendError> {
192 self.ttl = self.ttl.checked_sub(1).ok_or_else(|| {
193 warn!("Header TTL expired: {:?}", self);
194 InterfaceSendError::TtlExpired
195 })?;
196 Ok(())
197 }
198}
199
200impl From<HeaderSeq> for Header {
201 fn from(val: HeaderSeq) -> Self {
202 Self {
203 src: val.src,
204 dst: val.dst,
205 any_all: val.any_all.clone(),
206 seq_no: Some(val.seq_no),
207 kind: val.kind,
208 ttl: val.ttl,
209 }
210 }
211}
212
213pub const DEFAULT_TTL: u8 = 16;
214
215pub mod exports {
217 pub use bbq2;
218 pub use mutex;
219}