1use crate::{
3 errors::LllvError,
4 version::{CAP_MAGIC, CAP_VER, HEADER_LEN},
5};
6
7#[derive(Copy, Clone, Debug, PartialEq, Eq)]
8pub struct CapsuleHeader {
9 pub magic: u16, pub ver: u8, pub flags: u8, pub ts_ms: u64, pub cid: [u8; 32], pub dim: u16, pub len: u32, pub sig: [u8; 64], }
18
19bitflags::bitflags! {
20 #[derive(Default, Copy, Clone)]
21 pub struct CapsuleFlags: u8 {
22 const NONE = 0b0000_0000;
23 const ENCRYPTED = 0b0000_0001; const RECEIPTREQ = 0b0000_0010; }
26}
27
28impl CapsuleHeader {
29 #[must_use]
30 pub const fn empty(dim: u16, flags: CapsuleFlags, cid: [u8; 32], len: u32, ts_ms: u64) -> Self {
31 Self {
32 magic: CAP_MAGIC,
33 ver: CAP_VER,
34 flags: flags.bits(),
35 ts_ms,
36 cid,
37 dim,
38 len,
39 sig: [0u8; 64],
40 }
41 }
42
43 #[must_use]
44 pub fn to_bytes_wo_sig(&self) -> [u8; HEADER_LEN - 64] {
45 let mut out = [0u8; HEADER_LEN - 64];
46 let mut i = 0usize;
47 out[i..=i + 1].copy_from_slice(&self.magic.to_le_bytes());
48 i += 2;
49 out[i..=i].copy_from_slice(&[self.ver]);
50 i += 1;
51 out[i..=i].copy_from_slice(&[self.flags]);
52 i += 1;
53 out[i..=i + 7].copy_from_slice(&self.ts_ms.to_le_bytes());
54 i += 8;
55 out[i..=i + 31].copy_from_slice(&self.cid);
56 i += 32;
57 out[i..=i + 1].copy_from_slice(&self.dim.to_le_bytes());
58 i += 2;
59 out[i..=i + 3].copy_from_slice(&self.len.to_le_bytes());
60 i += 4;
61 debug_assert_eq!(i, HEADER_LEN - 64);
62 out
63 }
64
65 #[must_use]
66 pub fn to_bytes(&self) -> [u8; HEADER_LEN] {
67 let mut out = [0u8; HEADER_LEN];
68 let (head, tail) = out.split_at_mut(HEADER_LEN - 64);
69 head.copy_from_slice(&self.to_bytes_wo_sig());
70 tail.copy_from_slice(&self.sig);
71 out
72 }
73
74 pub fn from_bytes(raw: &[u8]) -> Result<Self, LllvError> {
81 if raw.len() < HEADER_LEN {
82 return Err(LllvError::InvalidHeaderLen);
83 }
84 let mut i = 0usize;
85 let magic = u16::from_le_bytes(
86 raw[i..i + 2]
87 .try_into()
88 .map_err(|_| LllvError::InvalidHeaderLen)?,
89 );
90 i += 2;
91 let ver = raw[i];
92 i += 1;
93 let flags = raw[i];
94 i += 1;
95 let ts_ms = u64::from_le_bytes(
96 raw[i..i + 8]
97 .try_into()
98 .map_err(|_| LllvError::InvalidHeaderLen)?,
99 );
100 i += 8;
101 let mut cid = [0u8; 32];
102 cid.copy_from_slice(&raw[i..i + 32]);
103 i += 32;
104 let dim = u16::from_le_bytes(
105 raw[i..i + 2]
106 .try_into()
107 .map_err(|_| LllvError::InvalidHeaderLen)?,
108 );
109 i += 2;
110 let len = u32::from_le_bytes(
111 raw[i..i + 4]
112 .try_into()
113 .map_err(|_| LllvError::InvalidHeaderLen)?,
114 );
115 i += 4;
116 let mut sig = [0u8; 64];
117 sig.copy_from_slice(&raw[i..i + 64]);
118
119 if magic != CAP_MAGIC {
120 return Err(LllvError::InvalidMagic);
121 }
122 if ver != CAP_VER {
123 return Err(LllvError::InvalidVersion);
124 }
125
126 Ok(Self {
127 magic,
128 ver,
129 flags,
130 ts_ms,
131 cid,
132 dim,
133 len,
134 sig,
135 })
136 }
137}