1use crate::ValidStr;
10use packet::{
11 BufferView, BufferViewMut, FragmentedBytesMut, InnerPacketBuilder, PacketBuilder,
12 PacketConstraints, ParsablePacket, ParseMetadata, SerializeTarget,
13};
14use std::num::NonZeroU16;
15use zerocopy::byteorder::little_endian::U32;
16use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout, Ref, SplitByteSlice, Unaligned};
17
18pub const MULTICAST_PORT: NonZeroU16 = NonZeroU16::new(33337).unwrap();
19pub const ACK_PORT: NonZeroU16 = NonZeroU16::new(33338).unwrap();
20
21const MAGIC: u32 = 0xAEAE1123;
22const MAX_LOG_DATA: usize = 1216;
23const MAX_NODENAME_LENGTH: usize = 64;
24
25pub const ACK_SIZE: usize = std::mem::size_of::<PacketHead>();
26
27#[repr(C)]
28#[derive(KnownLayout, FromBytes, IntoBytes, Immutable, Unaligned)]
29pub struct PacketHead {
30 magic: U32,
31 seqno: U32,
32}
33
34pub struct DebugLogPacket<B> {
35 head: Ref<B, PacketHead>,
36 nodename: ValidStr<B>,
37 data: ValidStr<B>,
38}
39
40impl<B: SplitByteSlice> DebugLogPacket<B> {
41 pub fn seqno(&self) -> u32 {
42 self.head.seqno.get()
43 }
44
45 pub fn nodename(&self) -> &str {
46 self.nodename.as_str()
47 }
48
49 pub fn data(&self) -> &str {
50 self.data.as_str()
51 }
52}
53
54#[derive(Debug)]
55pub enum ParseError {
56 BadMagic,
57 Malformed,
58 Encoding(std::str::Utf8Error),
59}
60
61impl<B> ParsablePacket<B, ()> for DebugLogPacket<B>
62where
63 B: SplitByteSlice,
64{
65 type Error = ParseError;
66
67 fn parse<BV: BufferView<B>>(mut buffer: BV, _args: ()) -> Result<Self, Self::Error> {
68 let head = buffer.take_obj_front::<PacketHead>().ok_or(ParseError::Malformed)?;
69 if head.magic.get() != MAGIC {
70 return Err(ParseError::BadMagic);
71 }
72 let nodename = buffer.take_front(MAX_NODENAME_LENGTH).ok_or(ParseError::Malformed)?;
73 let nodename = ValidStr::new(nodename).map_err(ParseError::Encoding)?;
74 let (nodename, _rest) = nodename.truncate_null();
75 let data = ValidStr::new(buffer.into_rest()).map_err(ParseError::Encoding)?;
76
77 Ok(Self { head, nodename, data })
78 }
79
80 fn parse_metadata(&self) -> ParseMetadata {
81 unimplemented!()
83 }
84}
85
86#[derive(Debug)]
87pub struct AckPacketBuilder {
88 seqno: u32,
89}
90
91impl AckPacketBuilder {
92 pub fn new(seqno: u32) -> Self {
93 Self { seqno }
94 }
95}
96
97impl InnerPacketBuilder for AckPacketBuilder {
98 fn bytes_len(&self) -> usize {
99 std::mem::size_of::<PacketHead>()
100 }
101
102 fn serialize(&self, mut buffer: &mut [u8]) {
103 let mut bv = crate::as_buffer_view_mut(&mut buffer);
104 let mut head = bv.take_obj_front::<PacketHead>().unwrap();
105 head.magic.set(MAGIC);
106 head.seqno.set(self.seqno);
107 }
108}
109
110#[derive(Debug)]
111pub struct LogPacketBuilder<'a> {
112 seqno: u32,
113 nodename: &'a str,
114}
115
116impl<'a> LogPacketBuilder<'a> {
117 pub fn new(seqno: u32, nodename: &'a str) -> Option<Self> {
118 if nodename.len() <= MAX_NODENAME_LENGTH { Some(Self { seqno, nodename }) } else { None }
119 }
120}
121
122impl<'a> PacketBuilder for LogPacketBuilder<'a> {
123 fn constraints(&self) -> PacketConstraints {
124 PacketConstraints::new(
125 std::mem::size_of::<PacketHead>() + MAX_NODENAME_LENGTH,
126 0,
127 0,
128 MAX_LOG_DATA,
129 )
130 }
131
132 fn serialize(&self, target: &mut SerializeTarget<'_>, _body: FragmentedBytesMut<'_, '_>) {
133 let mut bv = crate::as_buffer_view_mut(&mut target.header);
134 let mut head = bv.take_obj_front::<PacketHead>().unwrap();
135 head.magic.set(MAGIC);
136 head.seqno.set(self.seqno);
137 let nodename_bytes = self.nodename.as_bytes();
138 let nodename = bv.take_front_zero(MAX_NODENAME_LENGTH).unwrap();
139 let (nodename, _rest) = nodename.split_at_mut(nodename_bytes.len());
140 nodename.copy_from_slice(nodename_bytes);
141 }
142}
143
144#[cfg(test)]
145mod tests {
146 use super::*;
147 use packet::{ParseBuffer as _, Serializer as _};
148
149 fn as_buffer_view<'a, B: packet::BufferView<&'a [u8]>>(
151 v: B,
152 ) -> impl packet::BufferView<&'a [u8]> {
153 v
154 }
155
156 #[test]
157 fn test_log_packet() {
158 const LOG_DATA: &'static str = "some log data";
159 const NODENAME: &'static str = "my node";
160 let mut log = LogPacketBuilder::new(3, NODENAME)
161 .unwrap()
162 .wrap_body(LOG_DATA.as_bytes().into_serializer())
163 .serialize_vec_outer()
164 .unwrap_or_else(|_| panic!("Failed to serialize"));
165 let packet = log.parse::<DebugLogPacket<_>>().expect("Failed to parse");
166 assert_eq!(packet.seqno(), 3);
167 assert_eq!(packet.nodename(), NODENAME);
168 assert_eq!(packet.data(), LOG_DATA);
169 }
170
171 #[test]
172 fn test_ack_packet() {
173 const SEQNO: u32 = 4;
174 let ack = AckPacketBuilder::new(SEQNO)
175 .into_serializer()
176 .serialize_vec_outer()
177 .unwrap_or_else(|_| panic!("Failed to serialize"));
178 let mut bv = ack.as_ref();
179 let head = as_buffer_view(&mut bv)
180 .take_obj_front::<PacketHead>()
181 .expect("failed to get serialized head");
182 assert_eq!(head.magic.get(), MAGIC);
183 assert_eq!(head.seqno.get(), SEQNO);
184 }
185}