rust_mqtt/packet/v5/mqtt_packet.rs
1/*
2 * MIT License
3 *
4 * Copyright (c) [2022] [Ondrej Babec <ond.babec@gmail.com>]
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in all
14 * copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 * SOFTWARE.
23 */
24
25use heapless::Vec;
26
27use crate::packet::v5::packet_type::PacketType;
28use crate::utils::buffer_reader::BuffReader;
29use crate::utils::types::BufferError;
30
31use super::property::Property;
32
33/// This trait provide interface for mapping MQTTv5 packets to human readable structures
34/// which can be later modified and used for communication purposes.
35pub trait Packet<'a> {
36 fn new() -> Self;
37 /// Method encode provide way how to transfer Packet struct into Byte array (buffer)
38 fn encode(&mut self, buffer: &mut [u8], buff_len: usize) -> Result<usize, BufferError>;
39 /// Decode method is opposite of encode - decoding Byte array and mapping it into corresponding Packet struct
40 fn decode(&mut self, buff_reader: &mut BuffReader<'a>) -> Result<(), BufferError>;
41
42 /// Setter method for packet properties len - not all Packet types support this
43 fn set_property_len(&mut self, value: u32);
44 /// Setter method for packet properties len - not all Packet types support this
45 fn get_property_len(&mut self) -> u32;
46 /// Method enables pushing new property into packet properties
47 fn push_to_properties(&mut self, property: Property<'a>);
48 /// Returns if property is allowed for packet
49 fn property_allowed(&mut self, property: &Property<'a>) -> bool;
50 /// Method enables adding properties from client config - each packet decides if property can be used with that or not
51 fn add_properties<const MAX_PROPERTIES: usize>(
52 &mut self,
53 properties: &Vec<Property<'a>, MAX_PROPERTIES>,
54 ) -> u32 {
55 let mut res: u32 = 0;
56 for prop in properties.iter() {
57 if self.property_allowed(prop) {
58 self.push_to_properties((*prop).clone());
59 res = res + prop.encoded_len() as u32 + 1;
60 }
61 }
62 res
63 }
64
65 /// Setter for packet fixed header
66 fn set_fixed_header(&mut self, header: u8);
67 /// Setter for remaining len
68 fn set_remaining_len(&mut self, remaining_len: u32);
69
70 /// Method is decoding Byte array pointing to properties into heapless Vec
71 /// in packet. If decoding goes wrong method is returning Error
72 fn decode_properties(&mut self, buff_reader: &mut BuffReader<'a>) -> Result<(), BufferError> {
73 self.set_property_len(buff_reader.read_variable_byte_int()?);
74 let mut x: u32 = 0;
75 let mut prop: Property;
76 if self.get_property_len() != 0 {
77 loop {
78 prop = Property::decode(buff_reader)?;
79 //debug!("Parsed property {:?}", prop);
80 x = x + prop.encoded_len() as u32 + 1;
81 self.push_to_properties(prop);
82
83 if x == self.get_property_len() {
84 break;
85 }
86 }
87 }
88 Ok(())
89 }
90
91 /// Method is decoding packet header into fixed header part and remaining length
92 fn decode_fixed_header(
93 &mut self,
94 buff_reader: &mut BuffReader,
95 ) -> Result<PacketType, BufferError> {
96 let first_byte: u8 = buff_reader.read_u8()?;
97 trace!("First byte of accepted packet: {:02X}", first_byte);
98 self.set_fixed_header(first_byte);
99 self.set_remaining_len(buff_reader.read_variable_byte_int()?);
100 Ok(PacketType::from(first_byte))
101 }
102}