Skip to main content

rs_matter/transport/
packet.rs

1/*
2 *
3 *    Copyright (c) 2022-2026 Project CHIP Authors
4 *
5 *    Licensed under the Apache License, Version 2.0 (the "License");
6 *    you may not use this file except in compliance with the License.
7 *    You may obtain a copy of the License at
8 *
9 *        http://www.apache.org/licenses/LICENSE-2.0
10 *
11 *    Unless required by applicable law or agreed to in writing, software
12 *    distributed under the License is distributed on an "AS IS" BASIS,
13 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 *    See the License for the specific language governing permissions and
15 *    limitations under the License.
16 */
17
18use core::fmt;
19
20use crate::crypto::{self, Crypto};
21use crate::error::Error;
22use crate::fmt::Bytes;
23use crate::utils::storage::{ParseBuf, WriteBuf};
24
25use super::plain_hdr::PlainHdr;
26use super::proto_hdr::{self, ProtoHdr};
27
28#[derive(Debug, Default, Clone)]
29pub struct PacketHdr {
30    pub plain: PlainHdr,
31    pub proto: ProtoHdr,
32}
33
34impl PacketHdr {
35    pub const HDR_RESERVE: usize = PlainHdr::MAX_LEN + ProtoHdr::MAX_LEN;
36    pub const TAIL_RESERVE: usize = crypto::AEAD_TAG_LEN;
37
38    #[inline(always)]
39    pub const fn new() -> Self {
40        Self {
41            plain: PlainHdr::new(),
42            proto: ProtoHdr::new(),
43        }
44    }
45
46    pub fn reset(&mut self) {
47        self.plain = Default::default();
48        self.proto = Default::default();
49        self.proto.set_reliable();
50    }
51
52    pub fn load(&mut self, packet: &PacketHdr) {
53        self.plain = packet.plain.clone();
54        self.proto = packet.proto.clone();
55    }
56
57    pub fn decode_plain_hdr(&mut self, pb: &mut ParseBuf) -> Result<(), Error> {
58        self.plain.decode(pb)
59    }
60
61    pub fn decode_remaining<C: Crypto>(
62        &mut self,
63        crypto: C,
64        dec_key: Option<crypto::CanonAeadKeyRef<'_>>,
65        peer_nodeid: u64,
66        pb: &mut ParseBuf,
67    ) -> Result<(), Error> {
68        self.proto
69            .decrypt_and_decode(crypto, dec_key, peer_nodeid, &self.plain, pb)
70    }
71
72    pub fn encode<C: Crypto>(
73        &self,
74        crypto: C,
75        enc_key: Option<crypto::CanonAeadKeyRef<'_>>,
76        local_nodeid: u64,
77        wb: &mut WriteBuf,
78    ) -> Result<(), Error> {
79        // TODO: Get rid of the temporary buffers
80
81        let mut tmp_buf = [0_u8; ProtoHdr::MAX_LEN];
82        let mut write_buf = WriteBuf::new(&mut tmp_buf);
83        self.proto.encode(&mut write_buf)?;
84        wb.prepend(write_buf.as_slice())?;
85
86        let mut tmp_buf = [0_u8; PlainHdr::MAX_LEN];
87        let mut write_buf = WriteBuf::new(&mut tmp_buf);
88        self.plain.encode(&mut write_buf)?;
89        let plain_hdr_bytes = write_buf.as_slice();
90
91        trace!("Unencrypted packet: {}", Bytes(wb.as_slice()));
92        let ctr = self.plain.ctr;
93        if let Some(enc_key) = enc_key {
94            proto_hdr::encrypt_in_place(
95                crypto,
96                enc_key,
97                self.plain.sec_flags.bits(),
98                ctr,
99                local_nodeid,
100                plain_hdr_bytes,
101                wb,
102            )?;
103        }
104
105        wb.prepend(plain_hdr_bytes)?;
106        trace!("Full encrypted packet: {}", Bytes(wb.as_slice()));
107
108        Ok(())
109    }
110}
111
112impl fmt::Display for PacketHdr {
113    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
114        write!(f, "[{}][{}]", self.plain, self.proto)
115    }
116}
117
118#[cfg(feature = "defmt")]
119impl defmt::Format for PacketHdr {
120    fn format(&self, f: defmt::Formatter<'_>) {
121        defmt::write!(f, "[{}][{}]", self.plain, self.proto)
122    }
123}