mqtt_packet_3_5/
connack.rs

1use crate::byte_reader::ByteReader;
2use crate::mqtt_writer::MqttWriter;
3use crate::structure::*;
4use std::io;
5
6impl Packet for ConnackPacket {
7    fn encode(&self, protocol_version: u8) -> Res<Vec<u8>> {
8        let rc = if protocol_version == 5 {
9            self.reason_code
10        } else {
11            self.return_code
12        };
13        let mut length = 2; // length of rc and sessionHeader
14                            // Check return code
15        if rc.is_none() {
16            return Err("Invalid return code".to_string());
17        }
18        let rc = rc.unwrap();
19        // mqtt5 properties
20        let (props_len, properties_data) =
21            Properties::encode_option(self.properties.as_ref(), protocol_version)?;
22        length += properties_data.len() + props_len.len();
23        let mut writer = MqttWriter::new(length);
24        writer.write_u8(FixedHeader::for_type(PacketType::Connack).encode());
25        // length
26        writer.write_variable_num(length as u32)?;
27        writer.write_u8(if self.session_present { 0x01 } else { 0x0 });
28        writer.write_u8(rc);
29        writer.write_sized(&properties_data, &props_len)?;
30        // return true
31        Ok(writer.into_vec())
32    }
33
34    fn decode<R: io::Read>(
35        reader: &mut ByteReader<R>,
36        _: FixedHeader,
37        length: u32,
38        protocol_version: u8,
39    ) -> Res<ConnackPacket> {
40        let flags = reader.read_u8()?;
41        if flags > 1 {
42            return Err("Invalid connack flags, bits 7-1 must be set to 0".to_string());
43        }
44        let mut packet = ConnackPacket {
45            // fixed,
46            // length,
47            session_present: flags == 1,
48            ..ConnackPacket::default()
49        };
50
51        if protocol_version == 5 {
52            packet.reason_code = if length >= 2 {
53                Some(reader.read_u8()?)
54            } else {
55                Some(0)
56            };
57        } else {
58            if length < 2 {
59                return Err("Packet too short".to_string());
60            }
61            packet.return_code = Some(reader.read_u8()?);
62        }
63        // mqtt 5 properties
64        if protocol_version == 5 && reader.has_more() {
65            packet.properties = match reader.read_properties()? {
66                None => None,
67                Some(props) => Some(ConnackProperties::from_properties(props)?),
68            };
69        }
70        Ok(packet)
71    }
72}