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 interface_manager;
7pub mod nash;
8pub mod net_stack;
9pub mod socket;
10pub mod wire_frames;
11
12pub use address::Address;
13use interface_manager::InterfaceSendError;
14use log::warn;
15use nash::NameHash;
16pub use net_stack::{NetStack, NetStackSendError};
17use serde::{Deserialize, Serialize};
18
19#[cfg_attr(feature = "defmt-v1", derive(defmt::Format))]
20#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
21pub struct FrameKind(pub u8);
22
23#[cfg_attr(feature = "defmt-v1", derive(defmt::Format))]
24#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
25pub struct Key(pub [u8; 8]);
26
27#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
28pub struct ProtocolError(pub u16);
29
30#[cfg_attr(feature = "defmt-v1", derive(defmt::Format))]
31#[derive(Debug, Clone)]
32pub struct AnyAllAppendix {
33 pub key: Key,
34 pub nash: Option<NameHash>,
35}
36
37#[cfg_attr(feature = "defmt-v1", derive(defmt::Format))]
38#[derive(Debug, Clone)]
39pub struct Header {
40 pub src: Address,
41 pub dst: Address,
42 pub any_all: Option<AnyAllAppendix>,
43 pub seq_no: Option<u16>,
44 pub kind: FrameKind,
45 pub ttl: u8,
46}
47
48#[derive(Debug, Clone)]
49pub struct HeaderSeq {
50 pub src: Address,
51 pub dst: Address,
52 pub any_all: Option<AnyAllAppendix>,
53 pub seq_no: u16,
54 pub kind: FrameKind,
55 pub ttl: u8,
56}
57
58impl FrameKind {
59 pub const RESERVED: Self = Self(0);
60 pub const ENDPOINT_REQ: Self = Self(1);
61 pub const ENDPOINT_RESP: Self = Self(2);
62 pub const TOPIC_MSG: Self = Self(3);
63 pub const PROTOCOL_ERROR: Self = Self(u8::MAX);
64}
65
66#[cfg(feature = "postcard-schema-v0_2")]
67impl postcard_schema::Schema for FrameKind {
68 const SCHEMA: &'static postcard_schema::schema::NamedType =
69 &postcard_schema::schema::NamedType {
70 name: "FrameKind",
71 ty: u8::SCHEMA.ty,
72 };
73}
74
75#[cfg(feature = "postcard-schema-v0_2")]
76impl postcard_schema::Schema for Key {
77 const SCHEMA: &'static postcard_schema::schema::NamedType =
78 &postcard_schema::schema::NamedType {
79 name: "Key",
80 ty: <[u8; 8]>::SCHEMA.ty,
81 };
82}
83
84impl ProtocolError {
85 pub const RESERVED: Self = Self(0);
86 pub const SSE_NO_SPACE: Self = Self(1);
88 pub const SSE_DESER_FAILED: Self = Self(2);
89 pub const SSE_TYPE_MISMATCH: Self = Self(3);
90 pub const SSE_WHAT_THE_HELL: Self = Self(4);
91 pub const ISE_DESTINATION_LOCAL: Self = Self(11);
93 pub const ISE_NO_ROUTE_TO_DEST: Self = Self(12);
94 pub const ISE_INTERFACE_FULL: Self = Self(13);
95 pub const ISE_PLACEHOLDER_OH_NO: Self = Self(14);
96 pub const ISE_ANY_PORT_MISSING_KEY: Self = Self(15);
97 pub const ISE_TTL_EXPIRED: Self = Self(16);
98 pub const NSSE_NO_ROUTE: Self = Self(21);
100 pub const NSSE_ANY_PORT_MISSING_KEY: Self = Self(22);
101 pub const NSSE_WRONG_PORT_KIND: Self = Self(23);
102 pub const NSSE_ANY_PORT_NOT_UNIQUE: Self = Self(24);
103 pub const NSSE_ALL_PORT_MISSING_KEY: Self = Self(25);
104}
105
106impl Header {
107 #[inline]
108 pub fn with_seq(self, seq_no: u16) -> HeaderSeq {
109 let Self {
110 src,
111 dst,
112 any_all,
113 seq_no: _,
114 kind,
115 ttl,
116 } = self;
117 HeaderSeq {
118 src,
119 dst,
120 any_all,
121 seq_no,
122 kind,
123 ttl,
124 }
125 }
126
127 #[inline]
128 pub fn to_headerseq_or_with_seq<F: FnOnce() -> u16>(&self, f: F) -> HeaderSeq {
129 HeaderSeq {
130 src: self.src,
131 dst: self.dst,
132 any_all: self.any_all.clone(),
133 seq_no: self.seq_no.unwrap_or_else(f),
134 kind: self.kind,
135 ttl: self.ttl,
136 }
137 }
138
139 #[inline]
140 pub fn decrement_ttl(&mut self) -> Result<(), InterfaceSendError> {
141 self.ttl = self.ttl.checked_sub(1).ok_or_else(|| {
142 warn!("Header TTL expired: {self:?}");
143 InterfaceSendError::TtlExpired
144 })?;
145 Ok(())
146 }
147}
148
149impl From<HeaderSeq> for Header {
150 fn from(val: HeaderSeq) -> Self {
151 Self {
152 src: val.src,
153 dst: val.dst,
154 any_all: val.any_all.clone(),
155 seq_no: Some(val.seq_no),
156 kind: val.kind,
157 ttl: val.ttl,
158 }
159 }
160}
161
162pub const DEFAULT_TTL: u8 = 16;
163
164pub mod exports {
166 pub use bbq2;
167 pub use mutex;
168}