ergot_base/
lib.rs

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