From 5c814d75019310e13df9e311c948e58899c3b271 Mon Sep 17 00:00:00 2001 From: Ondrej Babec Date: Fri, 18 Feb 2022 15:27:18 +0100 Subject: [PATCH 1/7] Create all packets --- src/main.rs | 10 +- src/packet/auth_packet.rs | 38 ++++++ src/packet/connack_packet.rs | 76 ++++++++++++ src/packet/control_packet.rs | 175 ++++++++++++++++++++++++++++ src/packet/disconnect_packet.rs | 74 ++++++++++++ src/packet/mod.rs | 17 ++- src/packet/mqtt_packet.rs | 57 +-------- src/packet/packet_builder.rs | 107 ----------------- src/packet/pingreq_packet.rs | 33 ++++++ src/packet/pingresp_packet.rs | 43 +++++++ src/packet/puback_packet.rs | 79 +++++++++++++ src/packet/pubcomp_packet.rs | 79 +++++++++++++ src/packet/publish_packet.rs | 82 +++++++++++++ src/packet/pubrec_packet.rs | 79 +++++++++++++ src/packet/pubrel_packet.rs | 79 +++++++++++++ src/packet/suback_packet.rs | 91 +++++++++++++++ src/packet/subscription_packet.rs | 50 ++++++++ src/packet/unsuback_packet.rs | 91 +++++++++++++++ src/packet/unsubscription_packet.rs | 49 ++++++++ src/utils/buffer_reader.rs | 31 ++++- 20 files changed, 1171 insertions(+), 169 deletions(-) create mode 100644 src/packet/auth_packet.rs create mode 100644 src/packet/connack_packet.rs create mode 100644 src/packet/control_packet.rs create mode 100644 src/packet/disconnect_packet.rs delete mode 100644 src/packet/packet_builder.rs create mode 100644 src/packet/pingreq_packet.rs create mode 100644 src/packet/pingresp_packet.rs create mode 100644 src/packet/puback_packet.rs create mode 100644 src/packet/pubcomp_packet.rs create mode 100644 src/packet/publish_packet.rs create mode 100644 src/packet/pubrec_packet.rs create mode 100644 src/packet/pubrel_packet.rs create mode 100644 src/packet/suback_packet.rs create mode 100644 src/packet/subscription_packet.rs create mode 100644 src/packet/unsuback_packet.rs create mode 100644 src/packet/unsubscription_packet.rs diff --git a/src/main.rs b/src/main.rs index 535d88f..fb12cfc 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,6 +1,5 @@ use rust_mqtt::packet::mqtt_packet::*; use rust_mqtt::packet::packet_type::PacketType; -use rust_mqtt::packet::packet_builder::PacketBuilder; use rust_mqtt::encoding::variable_byte_integer::VariableByteIntegerEncoder; use rust_mqtt::encoding::variable_byte_integer::VariableByteIntegerDecoder; use rust_mqtt::packet::property::*; @@ -22,18 +21,17 @@ fn main() { f.read(&mut buffer).expect("buffer overflow"); - let mut txt = Vec::new(); + //let mut txt = Vec::new(); let mut payld = *b"xxxxx"; - let packet = Packet::clean(txt, &mut payld); - let mut packet_builder = PacketBuilder::new(packet); - let mut buffer_reader = BuffReader::new(&buffer); + //let packet = Packet::clean(txt, &mut payld); + /*let mut buffer_reader = BuffReader::new(&buffer); packet_builder.decode_packet(& mut buffer_reader); let bytes: [u8; 4] = packet_builder.currentPacket.protocol_name.to_be_bytes(); let prot = std::str::from_utf8(&bytes).unwrap(); - log::info!("Protocol name: {}", prot) + log::info!("Protocol name: {}", prot)*/ } /*fn test(tst: &str) { diff --git a/src/packet/auth_packet.rs b/src/packet/auth_packet.rs new file mode 100644 index 0000000..a81a9f1 --- /dev/null +++ b/src/packet/auth_packet.rs @@ -0,0 +1,38 @@ +use super::property::Property; +use super::packet_type::PacketType; +use crate::utils::buffer_reader::BuffReader; +use crate::utils::buffer_reader::EncodedString; +use crate::utils::buffer_reader::BinaryData; +use crate::utils::buffer_reader::ParseError; +use crate::packet::mqtt_packet::Packet; +use heapless::Vec; + + + +pub struct AuthPacket<'a, const MAX_PROPERTIES: usize> { + // 7 - 4 mqtt control packet type, 3-0 flagy + pub fixed_header: u8, + // 1 - 4 B lenght of variable header + len of payload + pub remain_len: u32, + + pub auth_reason: u8, + + pub property_len: u32, + + pub properties: Vec, MAX_PROPERTIES>, +} + + +impl<'a, const MAX_PROPERTIES: usize> AuthPacket<'a, MAX_PROPERTIES> { + +} + +impl<'a, const MAX_PROPERTIES: usize> Packet<'a> for AuthPacket<'a, MAX_PROPERTIES> { + fn decode(& mut self, buff_reader: & mut BuffReader<'a>) { + log::error!("PingreqPacket packet does not support decode funtion on client!"); + } + + fn encode(& mut self, buffer: & mut [u8]) { + + } +} \ No newline at end of file diff --git a/src/packet/connack_packet.rs b/src/packet/connack_packet.rs new file mode 100644 index 0000000..a0720a0 --- /dev/null +++ b/src/packet/connack_packet.rs @@ -0,0 +1,76 @@ +use super::property::Property; +use super::packet_type::PacketType; +use crate::utils::buffer_reader::BuffReader; +use crate::utils::buffer_reader::EncodedString; +use crate::utils::buffer_reader::BinaryData; +use crate::utils::buffer_reader::ParseError; +use crate::packet::mqtt_packet::Packet; +use heapless::Vec; + + +pub const MAX_PROPERTIES: usize = 18; + +pub struct ConnackPacket<'a> { + + // 7 - 4 mqtt control packet type, 3-0 flagy + pub fixed_header: u8, + // 1 - 4 B lenght of variable header + len of payload + pub remain_len: u32, + pub ack_flags: u8, + pub connect_reason_code: u8, + pub property_len: u32, + pub properties: Vec, MAX_PROPERTIES>, + +} + +impl<'a> ConnackPacket<'a> { + + pub fn decode_fixed_header(& mut self, buff_reader: & mut BuffReader) -> PacketType { + let first_byte: u8 = buff_reader.readU8().unwrap(); + self.fixed_header = first_byte; + self.remain_len = buff_reader.readVariableByteInt().unwrap(); + return PacketType::from(self.fixed_header); + } + + pub fn decode_properties(& mut self, buff_reader: & mut BuffReader<'a>) { + self.property_len = buff_reader.readVariableByteInt().unwrap(); + let mut x: u32 = 0; + let mut prop: Result; + loop { + let mut res: Property; + prop = Property::decode(buff_reader); + if let Ok(res) = prop { + log::info!("Parsed property {:?}", res); + x = x + res.len() as u32 + 1; + self.properties.push(res); + } else { + // error handlo + log::error!("Problem during property decoding"); + } + + if x == self.property_len { + break; + } + } + } + + pub fn decode_connack_packet(& mut self, buff_reader: & mut BuffReader<'a>) { + + if self.decode_fixed_header(buff_reader) != (PacketType::Connack).into() { + log::error!("Packet you are trying to decode is not CONNACK packet!"); + return; + } + self.ack_flags = buff_reader.readU8().unwrap(); + self.connect_reason_code = buff_reader.readU8().unwrap(); + self.decode_properties(buff_reader); + } +} + +impl<'a> Packet<'a> for ConnackPacket<'a> { + fn decode(& mut self, buff_reader: & mut BuffReader<'a>) { + self.decode_connack_packet(buff_reader); + } + fn encode(& mut self, buffer: & mut [u8]) { + + } +} \ No newline at end of file diff --git a/src/packet/control_packet.rs b/src/packet/control_packet.rs new file mode 100644 index 0000000..8d1d996 --- /dev/null +++ b/src/packet/control_packet.rs @@ -0,0 +1,175 @@ +use super::property::Property; +use super::packet_type::PacketType; +use crate::utils::buffer_reader::BuffReader; +use crate::utils::buffer_reader::EncodedString; +use crate::utils::buffer_reader::BinaryData; +use crate::utils::buffer_reader::ParseError; +use crate::packet::mqtt_packet::Packet; +use heapless::Vec; + +pub const MAX_PROPERTIES: usize = 18; +pub const MAX_WILL_PROPERTIES: usize = 7; + +pub struct ControlPacket<'a> { + // 7 - 4 mqtt control packet type, 3-0 flagy + pub fixed_header: u8, + // 1 - 4 B lenght of variable header + len of payload + pub remain_len: u32, + + // variable header + //optional prida se pouze u packetu ve kterych ma co delat + pub packet_identifier: u16, + pub protocol_name_len: u16, + pub protocol_name: u32, + pub protocol_version: u8, + pub connect_flags: u8, + pub keep_alive: u16, + // property len + pub property_len: u32, + + // properties + pub properties: Vec, MAX_PROPERTIES>, + + //payload + pub client_id: EncodedString<'a>, + // property len + pub will_property_len: u32, + pub will_properties: Vec, MAX_WILL_PROPERTIES>, + pub will_topic: EncodedString<'a>, + pub will_payload: BinaryData<'a>, + pub username: EncodedString<'a>, + pub password: BinaryData<'a> +} + +impl<'a> ControlPacket<'a> { + pub fn clean(properties: Vec, MAX_PROPERTIES>, will_properties: Vec, MAX_WILL_PROPERTIES> ) -> Self { + Self{ fixed_header: 0x00, remain_len: 0, packet_identifier: 0, protocol_name_len: 0, protocol_name: 0, protocol_version: 5, connect_flags: 0, + keep_alive: 0, property_len: 0, properties, client_id: EncodedString::new(), will_property_len: 0, will_properties, will_topic: EncodedString::new(), + will_payload: BinaryData::new(), username: EncodedString::new(), password: BinaryData::new() } + } + + pub fn get_reason_code(&self) { + log::info!("Getting reason code!"); + } + + pub fn addPacketType(& mut self, new_packet_type: PacketType) { + self.fixed_header = self.fixed_header & 0x0F; + self.fixed_header = self.fixed_header | >::into(new_packet_type); + } + + pub fn addFlags(& mut self, dup: bool, qos: u8, retain: bool) { + let cur_type: u8 = self.fixed_header & 0xF0; + if cur_type != 0x30 { + log::error!("Cannot add flags into packet with other than PUBLISH type"); + return; + } + let mut flags: u8 = 0x00; + if dup { + flags = flags | 0x08; + } + if qos == 1 { + flags = flags | 0x02; + } + if qos == 2 { + flags = flags | 0x04; + } + if retain { + flags = flags | 0x01; + } + self.fixed_header = cur_type | flags; + } + + pub fn decode_fixed_header(& mut self, buff_reader: & mut BuffReader) -> PacketType { + let first_byte: u8 = buff_reader.readU8().unwrap(); + self.fixed_header = first_byte; + self.remain_len = buff_reader.readVariableByteInt().unwrap(); + return PacketType::from(self.fixed_header); + } + + pub fn decode_properties(& mut self, buff_reader: & mut BuffReader<'a>) { + + self.property_len = buff_reader.readVariableByteInt().unwrap(); + let mut x: u32 = 0; + let mut prop: Result; + loop { + let mut res: Property; + prop = Property::decode(buff_reader); + if let Ok(res) = prop { + log::info!("Parsed property {:?}", res); + x = x + res.len() as u32 + 1; + self.properties.push(res); + } else { + // error handlo + log::error!("Problem during property decoding"); + } + + if x == self.property_len { + break; + } + } + } + + pub fn decode_will_properties(& mut self, buff_reader: & mut BuffReader<'a>) { + //todo: need to check if we are parsing only will properties + let will_property_len = buff_reader.readVariableByteInt().unwrap(); + let mut x: u32 = 0; + let mut prop: Result; + loop { + let mut res: Property; + prop = Property::decode(buff_reader); + if let Ok(res) = prop { + log::info!("Will property parsed: {:?}", res); + x = x + res.len() as u32 + 1; + self.will_properties.push(res); + } else { + // error handlo + log::error!("Problem during property decoding"); + } + + if x == will_property_len { + break; + } + } + } + + pub fn decode_payload(& mut self, buff_reader: & mut BuffReader<'a>) { + self.client_id = buff_reader.readString().unwrap(); + if self.connect_flags & (1 << 2) == 1 { + self.decode_will_properties(buff_reader); + self.will_topic = buff_reader.readString().unwrap(); + self.will_payload = buff_reader.readBinary().unwrap(); + } + + if self.connect_flags & (1 << 7) == 1 { + self.username = buff_reader.readString().unwrap(); + } + if self.connect_flags & (1 << 6) == 1 { + self.password = buff_reader.readBinary().unwrap(); + } + } + + pub fn decode_control_packet(& mut self, buff_reader: & mut BuffReader<'a>) { + if self.decode_fixed_header(buff_reader) != (PacketType::Connect).into() { + log::error!("Packet you are trying to decode is not CONNECT packet!"); + } + self.packet_identifier = 0; + self.protocol_name_len = buff_reader.readU16().unwrap(); + self.protocol_name = buff_reader.readU32().unwrap(); + self.protocol_version = buff_reader.readU8().unwrap(); + self.connect_flags = buff_reader.readU8().unwrap(); + self.keep_alive = buff_reader.readU16().unwrap(); + self.decode_properties(buff_reader); + self.decode_payload(buff_reader); + } +} + +impl<'a> Packet<'a> for ControlPacket<'a> { + fn decode(& mut self, buff_reader: & mut BuffReader<'a>) { + log::error!("Decode function is not available for control packet!") + //self.decode_control_packet(buff_reader); + } + + fn encode(& mut self, buffer: & mut [u8]) { + + } +} \ No newline at end of file diff --git a/src/packet/disconnect_packet.rs b/src/packet/disconnect_packet.rs new file mode 100644 index 0000000..a539c7c --- /dev/null +++ b/src/packet/disconnect_packet.rs @@ -0,0 +1,74 @@ +use super::property::Property; +use super::packet_type::PacketType; +use crate::utils::buffer_reader::BuffReader; +use crate::utils::buffer_reader::EncodedString; +use crate::utils::buffer_reader::BinaryData; +use crate::utils::buffer_reader::ParseError; +use crate::packet::mqtt_packet::Packet; +use heapless::Vec; + + + +pub struct DisconnectPacket<'a, const MAX_PROPERTIES: usize> { + // 7 - 4 mqtt control packet type, 3-0 flagy + pub fixed_header: u8, + // 1 - 4 B lenght of variable header + len of payload + pub remain_len: u32, + + pub disconnect_reason: u8, + + pub property_len: u32, + + pub properties: Vec, MAX_PROPERTIES>, +} + + +impl<'a, const MAX_PROPERTIES: usize> DisconnectPacket<'a, MAX_PROPERTIES> { + pub fn decode_properties(& mut self, buff_reader: & mut BuffReader<'a>) { + self.property_len = buff_reader.readVariableByteInt().unwrap(); + let mut x: u32 = 0; + let mut prop: Result; + loop { + let mut res: Property; + prop = Property::decode(buff_reader); + if let Ok(res) = prop { + log::info!("Parsed property {:?}", res); + x = x + res.len() as u32 + 1; + self.properties.push(res); + } else { + // error handlo + log::error!("Problem during property decoding"); + } + + if x == self.property_len { + break; + } + } + } + + pub fn decode_fixed_header(& mut self, buff_reader: & mut BuffReader<'a>) -> PacketType { + let first_byte: u8 = buff_reader.readU8().unwrap(); + self.fixed_header = first_byte; + self.remain_len = buff_reader.readVariableByteInt().unwrap(); + return PacketType::from(self.fixed_header); + } + + pub fn decode_auth_packet(& mut self, buff_reader: & mut BuffReader<'a>) { + if self.decode_fixed_header(buff_reader) != (PacketType::Pingresp).into() { + log::error!("Packet you are trying to decode is not PUBACK packet!"); + return; + } + self.disconnect_reason = buff_reader.readU8().unwrap(); + self.decode_properties(buff_reader); + } +} + +impl<'a, const MAX_PROPERTIES: usize> Packet<'a> for DisconnectPacket<'a, MAX_PROPERTIES> { + fn decode(& mut self, buff_reader: & mut BuffReader<'a>) { + self.decode_auth_packet(buff_reader); + } + + fn encode(& mut self, buffer: & mut [u8]) { + + } +} \ No newline at end of file diff --git a/src/packet/mod.rs b/src/packet/mod.rs index 1ede481..ec726f9 100644 --- a/src/packet/mod.rs +++ b/src/packet/mod.rs @@ -1,4 +1,17 @@ +pub mod control_packet; pub mod mqtt_packet; pub mod packet_type; -pub mod packet_builder; -pub mod property; \ No newline at end of file +pub mod property; +pub mod puback_packet; +pub mod publish_packet; +pub mod pubrec_packet; +pub mod connack_packet; +pub mod pubrel_packet; +pub mod pubcomp_packet; +pub mod subscription_packet; +pub mod unsubscription_packet; +pub mod suback_packet; +pub mod unsuback_packet; +pub mod pingreq_packet; +pub mod pingresp_packet; +pub mod disconnect_packet; \ No newline at end of file diff --git a/src/packet/mqtt_packet.rs b/src/packet/mqtt_packet.rs index 4b5ca0d..66b2a69 100644 --- a/src/packet/mqtt_packet.rs +++ b/src/packet/mqtt_packet.rs @@ -1,55 +1,6 @@ -use super::property::Property; -use super::packet_type::PacketType; -use heapless::Vec; +use crate::utils::buffer_reader::BuffReader; -pub const MAX_PROPERTIES: usize = 18; - -pub struct Packet<'a> { - // 7 - 4 mqtt control packet type, 3-0 flagy - pub fixed_header: u8, - // 1 - 4 B lenght of variable header + len of payload - pub remain_len: u32, - - // variable header - //optional prida se pouze u packetu ve kterych ma co delat - pub packet_identifier: u16, - - pub protocol_name_len: u16, - - pub protocol_name: u32, - - pub protocol_version: u8, - - pub connect_flags: u8, - - pub keep_alive: u16, - // property len - pub property_len: u32, - - // properties - pub properties: Vec, MAX_PROPERTIES>, - - // Payload of message - pub payload: &'a mut [u8] -} - -impl<'a> Packet<'a> { - pub fn new(fixed_header: u8, remain_len: u32, packet_identifier: u16, protocol_name_len: u16, - protocol_name: u32, protocol_version: u8, - connect_flags: u8, keep_alive: u16, property_len: u32, - properties: Vec, MAX_PROPERTIES>, payload: &'a mut [u8]) -> Self { - Self { fixed_header, remain_len, packet_identifier, property_len, properties, payload, connect_flags, keep_alive, protocol_name_len, protocol_name, protocol_version } - } - - pub fn clean(properties: Vec, MAX_PROPERTIES>, payload: &'a mut [u8]) -> Self { - Self{ fixed_header: 0x00, remain_len: 0, packet_identifier: 0, property_len: 0, properties, payload, connect_flags: 0, keep_alive: 0, protocol_name_len: 0, protocol_name: 0, protocol_version: 5} - } - - pub fn encode(&self) { - log::info!("Encoding!"); - } - - pub fn get_reason_code(&self) { - log::info!("Getting reason code!"); - } +pub trait Packet<'a> { + fn encode(& mut self, buffer: & mut [u8]); + fn decode(& mut self, buff_reader: & mut BuffReader<'a>); } \ No newline at end of file diff --git a/src/packet/packet_builder.rs b/src/packet/packet_builder.rs deleted file mode 100644 index 66d568e..0000000 --- a/src/packet/packet_builder.rs +++ /dev/null @@ -1,107 +0,0 @@ -use super::mqtt_packet::Packet; -use super::packet_type::PacketType; -use super::property::Property; -use crate::utils::buffer_reader::*; - -// Je potreba vytvori - -// metody packet buildery budou prijimat jako parametr buff reader, z ktereho bude postupne parsovat - -pub struct PacketBuilder<'a> { - pub currentPacket: Packet<'a>, -} - -impl<'a> PacketBuilder<'a> { - - pub fn new(packet: Packet<'a>) -> Self { - Self{ currentPacket: packet } - } - - pub fn build(&self) -> &Packet<'a> { - return &self.currentPacket; - } - - pub fn decode(&self, buffer: &'a mut [u8]) -> &Packet<'a> { - return &self.currentPacket; - } - - pub fn addPacketType(& mut self, new_packet_type: PacketType) { - self.currentPacket.fixed_header = self.currentPacket.fixed_header & 0x0F; - self.currentPacket.fixed_header = self.currentPacket.fixed_header | >::into(new_packet_type); - } - - pub fn addFlags(& mut self, dup: bool, qos: u8, retain: bool) { - let cur_type: u8 = self.currentPacket.fixed_header & 0xF0; - if cur_type != 0x30 { - log::error!("Cannot add flags into packet with other than PUBLISH type"); - return; - } - let mut flags: u8 = 0x00; - if dup { - flags = flags | 0x08; - } - if qos == 1 { - flags = flags | 0x02; - } - if qos == 2 { - flags = flags | 0x04; - } - if retain { - flags = flags | 0x01; - } - self.currentPacket.fixed_header = cur_type | flags; - } - - pub fn completePacket(& mut self) { - // Tutaj se cely packet dokonci - spocita se remaining len co chybi v hlavicce atd... - } - - pub fn decode_packet(& mut self, buff_reader: & mut BuffReader<'a>) { - self.decodeFixedHeader(buff_reader); - let y: u8 = self.currentPacket.fixed_header & 0xF0; - let z: u8 = (PacketType::Connect).into(); - if self.currentPacket.fixed_header & 0xF0 == (PacketType::Connect).into() { - self.decodeControllPacket(buff_reader); - } - } - - pub fn decodeFixedHeader(& mut self, buff_reader: & mut BuffReader) -> PacketType { - let first_byte: u8 = buff_reader.readU8().unwrap(); - self.currentPacket.fixed_header = first_byte; - self.currentPacket.remain_len = buff_reader.readVariableByteInt().unwrap(); - return PacketType::from(self.currentPacket.fixed_header); - } - - pub fn decode_properties(& mut self, buff_reader: & mut BuffReader<'a>) { - self.currentPacket.property_len = buff_reader.readVariableByteInt().unwrap(); - let mut x: u32 = 0; - let mut prop: Result; - loop { - let mut res: Property; - prop = Property::decode(buff_reader); - if let Ok(res) = prop { - log::info!("Parsed property {:?}", res); - x = x + res.len() as u32 + 1; - self.currentPacket.properties.push(res); - } else { - // error handlo - log::error!("Problem during property decoding"); - } - - - if x == self.currentPacket.property_len { - break; - } - } - } - - pub fn decodeControllPacket(& mut self, buff_reader: & mut BuffReader<'a>) { - self.currentPacket.packet_identifier = 0; - self.currentPacket.protocol_name_len = buff_reader.readU16().unwrap(); - self.currentPacket.protocol_name = buff_reader.readU32().unwrap(); - self.currentPacket.protocol_version = buff_reader.readU8().unwrap(); - self.currentPacket.connect_flags = buff_reader.readU8().unwrap(); - self.currentPacket.keep_alive = buff_reader.readU16().unwrap(); - self.decode_properties(buff_reader); - } -} \ No newline at end of file diff --git a/src/packet/pingreq_packet.rs b/src/packet/pingreq_packet.rs new file mode 100644 index 0000000..a5f8356 --- /dev/null +++ b/src/packet/pingreq_packet.rs @@ -0,0 +1,33 @@ +use super::property::Property; +use super::packet_type::PacketType; +use crate::utils::buffer_reader::BuffReader; +use crate::utils::buffer_reader::EncodedString; +use crate::utils::buffer_reader::BinaryData; +use crate::utils::buffer_reader::ParseError; +use crate::packet::mqtt_packet::Packet; +use heapless::Vec; + + +pub const MAX_PROPERTIES: usize = 2; + +pub struct PingreqPacket{ + // 7 - 4 mqtt control packet type, 3-0 flagy + pub fixed_header: u8, + // 1 - 4 B lenght of variable header + len of payload + pub remain_len: u32, +} + + +impl PingreqPacket { + +} + +impl<'a> Packet<'a> for PingreqPacket { + fn decode(& mut self, buff_reader: & mut BuffReader<'a>) { + log::error!("PingreqPacket packet does not support decode funtion on client!"); + } + + fn encode(& mut self, buffer: & mut [u8]) { + + } +} \ No newline at end of file diff --git a/src/packet/pingresp_packet.rs b/src/packet/pingresp_packet.rs new file mode 100644 index 0000000..4349cb6 --- /dev/null +++ b/src/packet/pingresp_packet.rs @@ -0,0 +1,43 @@ +use super::property::Property; +use super::packet_type::PacketType; +use crate::utils::buffer_reader::BuffReader; +use crate::utils::buffer_reader::EncodedString; +use crate::utils::buffer_reader::BinaryData; +use crate::utils::buffer_reader::ParseError; +use crate::packet::mqtt_packet::Packet; +use heapless::Vec; + + +pub struct PingrespPacket { + // 7 - 4 mqtt control packet type, 3-0 flagy + pub fixed_header: u8, + // 1 - 4 B lenght of variable header + len of payload + pub remain_len: u32, +} + + +impl<'a> PingrespPacket { + pub fn decode_fixed_header(& mut self, buff_reader: & mut BuffReader<'a>) -> PacketType { + let first_byte: u8 = buff_reader.readU8().unwrap(); + self.fixed_header = first_byte; + self.remain_len = buff_reader.readVariableByteInt().unwrap(); + return PacketType::from(self.fixed_header); + } + + pub fn decode_pingresp_packet(& mut self, buff_reader: & mut BuffReader<'a>) { + if self.decode_fixed_header(buff_reader) != (PacketType::Pingresp).into() { + log::error!("Packet you are trying to decode is not PUBACK packet!"); + return; + } + } +} + +impl<'a> Packet<'a> for PingrespPacket { + fn decode(& mut self, buff_reader: & mut BuffReader<'a>) { + self.decode_pingresp_packet(buff_reader); + } + + fn encode(& mut self, buffer: & mut [u8]) { + + } +} \ No newline at end of file diff --git a/src/packet/puback_packet.rs b/src/packet/puback_packet.rs new file mode 100644 index 0000000..f364ae6 --- /dev/null +++ b/src/packet/puback_packet.rs @@ -0,0 +1,79 @@ +use super::property::Property; +use super::packet_type::PacketType; +use crate::utils::buffer_reader::BuffReader; +use crate::utils::buffer_reader::EncodedString; +use crate::utils::buffer_reader::BinaryData; +use crate::utils::buffer_reader::ParseError; +use crate::packet::mqtt_packet::Packet; +use heapless::Vec; + + +pub const MAX_PROPERTIES: usize = 2; + +pub struct PubackPacket<'a> { + // 7 - 4 mqtt control packet type, 3-0 flagy + pub fixed_header: u8, + // 1 - 4 B lenght of variable header + len of payload + pub remain_len: u32, + + pub packet_identifier: u16, + pub reason_code: u8, + + pub property_len: u32, + + // properties + pub properties: Vec, MAX_PROPERTIES>, +} + + +impl<'a> PubackPacket<'a> { + + pub fn decode_properties(& mut self, buff_reader: & mut BuffReader<'a>) { + self.property_len = buff_reader.readVariableByteInt().unwrap(); + let mut x: u32 = 0; + let mut prop: Result; + loop { + let mut res: Property; + prop = Property::decode(buff_reader); + if let Ok(res) = prop { + log::info!("Parsed property {:?}", res); + x = x + res.len() as u32 + 1; + self.properties.push(res); + } else { + // error handlo + log::error!("Problem during property decoding"); + } + + if x == self.property_len { + break; + } + } + } + + pub fn decode_fixed_header(& mut self, buff_reader: & mut BuffReader) -> PacketType { + let first_byte: u8 = buff_reader.readU8().unwrap(); + self.fixed_header = first_byte; + self.remain_len = buff_reader.readVariableByteInt().unwrap(); + return PacketType::from(self.fixed_header); + } + + pub fn decode_puback_packet(& mut self, buff_reader: & mut BuffReader<'a>) { + if self.decode_fixed_header(buff_reader) != (PacketType::Puback).into() { + log::error!("Packet you are trying to decode is not PUBACK packet!"); + return; + } + self.packet_identifier = buff_reader.readU16().unwrap(); + self.reason_code = buff_reader.readU8().unwrap(); + self.decode_properties(buff_reader); + } +} + +impl<'a> Packet<'a> for PubackPacket<'a> { + fn decode(& mut self, buff_reader: & mut BuffReader<'a>) { + self.decode_puback_packet(buff_reader); + } + + fn encode(& mut self, buffer: & mut [u8]) { + + } +} \ No newline at end of file diff --git a/src/packet/pubcomp_packet.rs b/src/packet/pubcomp_packet.rs new file mode 100644 index 0000000..e70c0a3 --- /dev/null +++ b/src/packet/pubcomp_packet.rs @@ -0,0 +1,79 @@ +use super::property::Property; +use super::packet_type::PacketType; +use crate::utils::buffer_reader::BuffReader; +use crate::utils::buffer_reader::EncodedString; +use crate::utils::buffer_reader::BinaryData; +use crate::utils::buffer_reader::ParseError; +use crate::packet::mqtt_packet::Packet; +use heapless::Vec; + + +pub const MAX_PROPERTIES: usize = 2; + +pub struct PubcompPacket<'a> { + // 7 - 4 mqtt control packet type, 3-0 flagy + pub fixed_header: u8, + // 1 - 4 B lenght of variable header + len of payload + pub remain_len: u32, + + pub packet_identifier: u16, + pub reason_code: u8, + + pub property_len: u32, + + // properties + pub properties: Vec, MAX_PROPERTIES>, +} + + +impl<'a> PubcompPacket<'a> { + + pub fn decode_properties(& mut self, buff_reader: & mut BuffReader<'a>) { + self.property_len = buff_reader.readVariableByteInt().unwrap(); + let mut x: u32 = 0; + let mut prop: Result; + loop { + let mut res: Property; + prop = Property::decode(buff_reader); + if let Ok(res) = prop { + log::info!("Parsed property {:?}", res); + x = x + res.len() as u32 + 1; + self.properties.push(res); + } else { + // error handlo + log::error!("Problem during property decoding"); + } + + if x == self.property_len { + break; + } + } + } + + pub fn decode_fixed_header(& mut self, buff_reader: & mut BuffReader) -> PacketType { + let first_byte: u8 = buff_reader.readU8().unwrap(); + self.fixed_header = first_byte; + self.remain_len = buff_reader.readVariableByteInt().unwrap(); + return PacketType::from(self.fixed_header); + } + + pub fn decode_puback_packet(& mut self, buff_reader: & mut BuffReader<'a>) { + if self.decode_fixed_header(buff_reader) != (PacketType::Pubcomp).into() { + log::error!("Packet you are trying to decode is not PUBCOMP packet!"); + return; + } + self.packet_identifier = buff_reader.readU16().unwrap(); + self.reason_code = buff_reader.readU8().unwrap(); + self.decode_properties(buff_reader); + } +} + +impl<'a> Packet<'a> for PubcompPacket<'a> { + fn decode(& mut self, buff_reader: & mut BuffReader<'a>) { + self.decode_puback_packet(buff_reader); + } + + fn encode(& mut self, buffer: & mut [u8]) { + + } +} \ No newline at end of file diff --git a/src/packet/publish_packet.rs b/src/packet/publish_packet.rs new file mode 100644 index 0000000..8c74d5e --- /dev/null +++ b/src/packet/publish_packet.rs @@ -0,0 +1,82 @@ +use super::property::Property; +use super::packet_type::PacketType; +use crate::utils::buffer_reader::BuffReader; +use crate::utils::buffer_reader::EncodedString; +use crate::utils::buffer_reader::BinaryData; +use crate::utils::buffer_reader::ParseError; +use crate::packet::mqtt_packet::Packet; +use heapless::Vec; + + +pub const MAX_PROPERTIES: usize = 9; + +pub struct PublishPacket<'a> { + // 7 - 4 mqtt control packet type, 3-0 flagy + pub fixed_header: u8, + // 1 - 4 B lenght of variable header + len of payload + pub remain_len: u32, + + pub topic_name: EncodedString<'a>, + pub packet_identifier: u16, + + pub property_len: u32, + + // properties + pub properties: Vec, MAX_PROPERTIES>, + + pub message: &'a [u8], +} + + +impl<'a> PublishPacket<'a> { + + pub fn decode_properties(& mut self, buff_reader: & mut BuffReader<'a>) { + self.property_len = buff_reader.readVariableByteInt().unwrap(); + let mut x: u32 = 0; + let mut prop: Result; + loop { + let mut res: Property; + prop = Property::decode(buff_reader); + if let Ok(res) = prop { + log::info!("Parsed property {:?}", res); + x = x + res.len() as u32 + 1; + self.properties.push(res); + } else { + // error handlo + log::error!("Problem during property decoding"); + } + + if x == self.property_len { + break; + } + } + } + + pub fn decode_fixed_header(& mut self, buff_reader: & mut BuffReader) -> PacketType { + let first_byte: u8 = buff_reader.readU8().unwrap(); + self.fixed_header = first_byte; + self.remain_len = buff_reader.readVariableByteInt().unwrap(); + return PacketType::from(self.fixed_header); + } + + pub fn decode_publish_packet(& mut self, buff_reader: & mut BuffReader<'a>) { + if self.decode_fixed_header(buff_reader) != (PacketType::Publish).into() { + log::error!("Packet you are trying to decode is not PUBLISH packet!"); + return; + } + self.topic_name = buff_reader.readString().unwrap(); + self.packet_identifier = buff_reader.readU16().unwrap(); + self.decode_properties(buff_reader); + self.message = buff_reader.readMessage(); + } +} + +impl<'a> Packet<'a> for PublishPacket<'a> { + fn decode(& mut self, buff_reader: & mut BuffReader<'a>) { + self.decode_publish_packet(buff_reader); + } + + fn encode(& mut self, buffer: & mut [u8]) { + + } +} \ No newline at end of file diff --git a/src/packet/pubrec_packet.rs b/src/packet/pubrec_packet.rs new file mode 100644 index 0000000..4d40601 --- /dev/null +++ b/src/packet/pubrec_packet.rs @@ -0,0 +1,79 @@ +use super::property::Property; +use super::packet_type::PacketType; +use crate::utils::buffer_reader::BuffReader; +use crate::utils::buffer_reader::EncodedString; +use crate::utils::buffer_reader::BinaryData; +use crate::utils::buffer_reader::ParseError; +use crate::packet::mqtt_packet::Packet; +use heapless::Vec; + + +pub const MAX_PROPERTIES: usize = 2; + +pub struct PubrecPacket<'a> { + // 7 - 4 mqtt control packet type, 3-0 flagy + pub fixed_header: u8, + // 1 - 4 B lenght of variable header + len of payload + pub remain_len: u32, + + pub packet_identifier: u16, + pub reason_code: u8, + + pub property_len: u32, + + // properties + pub properties: Vec, MAX_PROPERTIES>, +} + + +impl<'a> PubrecPacket<'a> { + + pub fn decode_properties(& mut self, buff_reader: & mut BuffReader<'a>) { + self.property_len = buff_reader.readVariableByteInt().unwrap(); + let mut x: u32 = 0; + let mut prop: Result; + loop { + let mut res: Property; + prop = Property::decode(buff_reader); + if let Ok(res) = prop { + log::info!("Parsed property {:?}", res); + x = x + res.len() as u32 + 1; + self.properties.push(res); + } else { + // error handlo + log::error!("Problem during property decoding"); + } + + if x == self.property_len { + break; + } + } + } + + pub fn decode_fixed_header(& mut self, buff_reader: & mut BuffReader) -> PacketType { + let first_byte: u8 = buff_reader.readU8().unwrap(); + self.fixed_header = first_byte; + self.remain_len = buff_reader.readVariableByteInt().unwrap(); + return PacketType::from(self.fixed_header); + } + + pub fn decode_pubrec_packet(& mut self, buff_reader: & mut BuffReader<'a>) { + if self.decode_fixed_header(buff_reader) != (PacketType::Pubrec).into() { + log::error!("Packet you are trying to decode is not PUBREC packet!"); + return; + } + self.packet_identifier = buff_reader.readU16().unwrap(); + self.reason_code = buff_reader.readU8().unwrap(); + self.decode_properties(buff_reader); + } +} + +impl<'a> Packet<'a> for PubrecPacket<'a> { + fn decode(& mut self, buff_reader: & mut BuffReader<'a>) { + self.decode_pubrec_packet(buff_reader); + } + + fn encode(& mut self, buffer: & mut [u8]) { + + } +} \ No newline at end of file diff --git a/src/packet/pubrel_packet.rs b/src/packet/pubrel_packet.rs new file mode 100644 index 0000000..91f042f --- /dev/null +++ b/src/packet/pubrel_packet.rs @@ -0,0 +1,79 @@ +use super::property::Property; +use super::packet_type::PacketType; +use crate::utils::buffer_reader::BuffReader; +use crate::utils::buffer_reader::EncodedString; +use crate::utils::buffer_reader::BinaryData; +use crate::utils::buffer_reader::ParseError; +use crate::packet::mqtt_packet::Packet; +use heapless::Vec; + + +pub const MAX_PROPERTIES: usize = 2; + +pub struct PubrelPacket<'a> { + // 7 - 4 mqtt control packet type, 3-0 flagy + pub fixed_header: u8, + // 1 - 4 B lenght of variable header + len of payload + pub remain_len: u32, + + pub packet_identifier: u16, + pub reason_code: u8, + + pub property_len: u32, + + // properties + pub properties: Vec, MAX_PROPERTIES>, +} + + +impl<'a> PubrelPacket<'a> { + + pub fn decode_properties(& mut self, buff_reader: & mut BuffReader<'a>) { + self.property_len = buff_reader.readVariableByteInt().unwrap(); + let mut x: u32 = 0; + let mut prop: Result; + loop { + let mut res: Property; + prop = Property::decode(buff_reader); + if let Ok(res) = prop { + log::info!("Parsed property {:?}", res); + x = x + res.len() as u32 + 1; + self.properties.push(res); + } else { + // error handlo + log::error!("Problem during property decoding"); + } + + if x == self.property_len { + break; + } + } + } + + pub fn decode_fixed_header(& mut self, buff_reader: & mut BuffReader) -> PacketType { + let first_byte: u8 = buff_reader.readU8().unwrap(); + self.fixed_header = first_byte; + self.remain_len = buff_reader.readVariableByteInt().unwrap(); + return PacketType::from(self.fixed_header); + } + + pub fn decode_puback_packet(& mut self, buff_reader: & mut BuffReader<'a>) { + if self.decode_fixed_header(buff_reader) != (PacketType::Pubrel).into() { + log::error!("Packet you are trying to decode is not PUBREL packet!"); + return; + } + self.packet_identifier = buff_reader.readU16().unwrap(); + self.reason_code = buff_reader.readU8().unwrap(); + self.decode_properties(buff_reader); + } +} + +impl<'a> Packet<'a> for PubrelPacket<'a> { + fn decode(& mut self, buff_reader: & mut BuffReader<'a>) { + self.decode_puback_packet(buff_reader); + } + + fn encode(& mut self, buffer: & mut [u8]) { + + } +} \ No newline at end of file diff --git a/src/packet/suback_packet.rs b/src/packet/suback_packet.rs new file mode 100644 index 0000000..81ab6a0 --- /dev/null +++ b/src/packet/suback_packet.rs @@ -0,0 +1,91 @@ +use super::property::Property; +use super::packet_type::PacketType; +use crate::utils::buffer_reader::BuffReader; +use crate::utils::buffer_reader::EncodedString; +use crate::utils::buffer_reader::BinaryData; +use crate::utils::buffer_reader::ParseError; +use crate::packet::mqtt_packet::Packet; +use heapless::Vec; + + +pub const MAX_PROPERTIES: usize = 2; + +pub struct SubackPacket<'a, const MAX_REASONS: usize> { + // 7 - 4 mqtt control packet type, 3-0 flagy + pub fixed_header: u8, + // 1 - 4 B lenght of variable header + len of payload + pub remain_len: u32, + + pub packet_identifier: u16, + + pub property_len: u32, + + // properties + pub properties: Vec, MAX_PROPERTIES>, + + pub reason_codes: Vec, +} + + +impl<'a, const MAX_REASONS: usize> SubackPacket<'a, MAX_REASONS> { + + pub fn decode_properties(& mut self, buff_reader: & mut BuffReader<'a>) { + self.property_len = buff_reader.readVariableByteInt().unwrap(); + let mut x: u32 = 0; + let mut prop: Result; + loop { + let mut res: Property; + prop = Property::decode(buff_reader); + if let Ok(res) = prop { + log::info!("Parsed property {:?}", res); + x = x + res.len() as u32 + 1; + self.properties.push(res); + } else { + // error handlo + log::error!("Problem during property decoding"); + } + + if x == self.property_len { + break; + } + } + } + + pub fn decode_fixed_header(& mut self, buff_reader: & mut BuffReader) -> PacketType { + let first_byte: u8 = buff_reader.readU8().unwrap(); + self.fixed_header = first_byte; + self.remain_len = buff_reader.readVariableByteInt().unwrap(); + return PacketType::from(self.fixed_header); + } + + pub fn read_reason_codes(& mut self, buff_reader: & mut BuffReader<'a>) { + let mut i = 0; + loop { + self.reason_codes.push(buff_reader.readU8().unwrap()); + i = i + 1; + if i == MAX_REASONS { + break; + } + } + } + + pub fn decode_suback_packet(& mut self, buff_reader: & mut BuffReader<'a>) { + if self.decode_fixed_header(buff_reader) != (PacketType::Suback).into() { + log::error!("Packet you are trying to decode is not SUBACK packet!"); + return; + } + self.packet_identifier = buff_reader.readU16().unwrap(); + self.decode_properties(buff_reader); + self.read_reason_codes(buff_reader); + } +} + +impl<'a, const MAX_REASONS: usize> Packet<'a> for SubackPacket<'a, MAX_REASONS>{ + fn decode(& mut self, buff_reader: & mut BuffReader<'a>) { + self.decode_suback_packet(buff_reader); + } + + fn encode(& mut self, buffer: & mut [u8]) { + + } +} \ No newline at end of file diff --git a/src/packet/subscription_packet.rs b/src/packet/subscription_packet.rs new file mode 100644 index 0000000..3d8cad9 --- /dev/null +++ b/src/packet/subscription_packet.rs @@ -0,0 +1,50 @@ +use super::property::Property; +use super::packet_type::PacketType; +use crate::utils::buffer_reader::BuffReader; +use crate::utils::buffer_reader::EncodedString; +use crate::utils::buffer_reader::BinaryData; +use crate::utils::buffer_reader::ParseError; +use crate::packet::mqtt_packet::Packet; +use crate::utils::buffer_reader::TopicFilter; +use heapless::Vec; + + +pub const MAX_PROPERTIES: usize = 2; + +pub struct SubscriptionPacket<'a, const MAX_FILTERS: usize> { + pub maximal_filters: u8, + // 7 - 4 mqtt control packet type, 3-0 flagy + pub fixed_header: u8, + // 1 - 4 B lenght of variable header + len of payload + pub remain_len: u32, + + pub packet_identifier: u16, + + pub property_len: u32, + + // properties + pub properties: Vec, MAX_PROPERTIES>, + + // topic filter len + pub topic_filter_let: u16, + + // payload + pub topic_filters: Vec, MAX_FILTERS>, +} + + +impl<'a, const MAX_FILTERS: usize> SubscriptionPacket<'a, MAX_FILTERS> { + /*pub fn new() -> Self { + + }*/ +} + +impl<'a, const MAX_FILTERS: usize> Packet<'a> for SubscriptionPacket<'a, MAX_FILTERS> { + fn decode(& mut self, buff_reader: & mut BuffReader<'a>) { + log::error!("Subscribe packet does not support decode funtion on client!"); + } + + fn encode(& mut self, buffer: & mut [u8]) { + + } +} \ No newline at end of file diff --git a/src/packet/unsuback_packet.rs b/src/packet/unsuback_packet.rs new file mode 100644 index 0000000..b8fadaf --- /dev/null +++ b/src/packet/unsuback_packet.rs @@ -0,0 +1,91 @@ +use super::property::Property; +use super::packet_type::PacketType; +use crate::utils::buffer_reader::BuffReader; +use crate::utils::buffer_reader::EncodedString; +use crate::utils::buffer_reader::BinaryData; +use crate::utils::buffer_reader::ParseError; +use crate::packet::mqtt_packet::Packet; +use heapless::Vec; + + +pub const MAX_PROPERTIES: usize = 20; + +pub struct UnsubackPacket<'a, const MAX_REASONS: usize> { + // 7 - 4 mqtt control packet type, 3-0 flagy + pub fixed_header: u8, + // 1 - 4 B lenght of variable header + len of payload + pub remain_len: u32, + + pub packet_identifier: u16, + + pub property_len: u32, + + // properties + pub properties: Vec, MAX_PROPERTIES>, + + pub reason_codes: Vec, +} + + +impl<'a, const MAX_REASONS: usize> UnsubackPacket<'a, MAX_REASONS> { + + pub fn decode_properties(& mut self, buff_reader: & mut BuffReader<'a>) { + self.property_len = buff_reader.readVariableByteInt().unwrap(); + let mut x: u32 = 0; + let mut prop: Result; + loop { + let mut res: Property; + prop = Property::decode(buff_reader); + if let Ok(res) = prop { + log::info!("Parsed property {:?}", res); + x = x + res.len() as u32 + 1; + self.properties.push(res); + } else { + // error handlo + log::error!("Problem during property decoding"); + } + + if x == self.property_len { + break; + } + } + } + + pub fn decode_fixed_header(& mut self, buff_reader: & mut BuffReader) -> PacketType { + let first_byte: u8 = buff_reader.readU8().unwrap(); + self.fixed_header = first_byte; + self.remain_len = buff_reader.readVariableByteInt().unwrap(); + return PacketType::from(self.fixed_header); + } + + pub fn read_reason_codes(& mut self, buff_reader: & mut BuffReader<'a>) { + let mut i = 0; + loop { + self.reason_codes.push(buff_reader.readU8().unwrap()); + i = i + 1; + if i == MAX_REASONS { + break; + } + } + } + + pub fn decode_suback_packet(& mut self, buff_reader: & mut BuffReader<'a>) { + if self.decode_fixed_header(buff_reader) != (PacketType::Suback).into() { + log::error!("Packet you are trying to decode is not SUBACK packet!"); + return; + } + self.packet_identifier = buff_reader.readU16().unwrap(); + self.decode_properties(buff_reader); + self.read_reason_codes(buff_reader); + } +} + +impl<'a, const MAX_REASONS: usize> Packet<'a> for UnsubackPacket<'a, MAX_REASONS>{ + fn decode(& mut self, buff_reader: & mut BuffReader<'a>) { + self.decode_suback_packet(buff_reader); + } + + fn encode(& mut self, buffer: & mut [u8]) { + + } +} \ No newline at end of file diff --git a/src/packet/unsubscription_packet.rs b/src/packet/unsubscription_packet.rs new file mode 100644 index 0000000..e9736f6 --- /dev/null +++ b/src/packet/unsubscription_packet.rs @@ -0,0 +1,49 @@ +use super::property::Property; +use super::packet_type::PacketType; +use crate::utils::buffer_reader::BuffReader; +use crate::utils::buffer_reader::EncodedString; +use crate::utils::buffer_reader::BinaryData; +use crate::utils::buffer_reader::ParseError; +use crate::packet::mqtt_packet::Packet; +use crate::utils::buffer_reader::TopicFilter; +use heapless::Vec; + + +pub const MAX_PROPERTIES: usize = 20; + +pub struct UnsubscriptionPacket<'a, const MAX_FILTERS: usize> { + // 7 - 4 mqtt control packet type, 3-0 flagy + pub fixed_header: u8, + // 1 - 4 B lenght of variable header + len of payload + pub remain_len: u32, + + pub packet_identifier: u16, + + pub property_len: u32, + + // properties + pub properties: Vec, MAX_PROPERTIES>, + + // topic filter len + pub topic_filter_let: u16, + + // payload + pub topic_filters: Vec, MAX_FILTERS>, +} + + +impl<'a, const MAX_FILTERS: usize> UnsubscriptionPacket<'a, MAX_FILTERS> { + /*pub fn new() -> Self { + + }*/ +} + +impl<'a, const MAX_FILTERS: usize> Packet<'a> for UnsubscriptionPacket<'a, MAX_FILTERS> { + fn decode(& mut self, buff_reader: & mut BuffReader<'a>) { + log::error!("Unsubscribe packet does not support decode funtion on client!"); + } + + fn encode(& mut self, buffer: & mut [u8]) { + + } +} \ No newline at end of file diff --git a/src/utils/buffer_reader.rs b/src/utils/buffer_reader.rs index 92e33ac..f707d93 100644 --- a/src/utils/buffer_reader.rs +++ b/src/utils/buffer_reader.rs @@ -5,10 +5,14 @@ use core::mem; #[derive(Debug)] pub struct EncodedString<'a> { pub string: &'a str, - pub len: u16 + pub len: u16, } impl EncodedString<'_> { + pub fn new() -> Self { + Self { string: "", len: 0 } + } + pub fn len(&self) -> u16 { return self.len + 2; } @@ -21,6 +25,10 @@ pub struct BinaryData<'a> { } impl BinaryData<'_> { + pub fn new() -> Self { + Self { bin: &[0], len: 0 } + } + pub fn len(&self) -> u16 { return self.len + 2; } @@ -39,6 +47,23 @@ impl StringPair<'_> { } } +#[derive(Debug)] +pub struct TopicFilter<'a> { + pub len: u16, + pub filter: EncodedString<'a>, + pub sub_options: u8, +} + +impl TopicFilter<'_> { + pub fn new() -> Self { + Self { len: 0, filter: EncodedString::new(), sub_options: 0 } + } + + pub fn len(&self) -> u16 { + return self.len + 2; + } +} + #[derive(core::fmt::Debug)] #[derive(Clone)] pub enum ParseError { @@ -142,4 +167,8 @@ impl<'a> BuffReader<'a> { } return Ok(StringPair { name: name.unwrap(), value: value.unwrap() }); } + + pub fn readMessage(& mut self) -> &'a [u8] { + return &self.buffer[self.position..]; + } } \ No newline at end of file From e4c3505aaf7e0a126a13b3be3ae33fd76522027e Mon Sep 17 00:00:00 2001 From: Ondrej Babec Date: Sun, 20 Feb 2022 13:25:44 +0100 Subject: [PATCH 2/7] Start encoding and refactor --- src/encoding/mod.rs | 2 +- src/encoding/variable_byte_integer.rs | 25 ++- src/lib.rs | 6 +- src/main.rs | 26 ++- src/packet/auth_packet.rs | 84 +++++++-- src/packet/connack_packet.rs | 75 ++++---- src/packet/control_packet.rs | 157 ++++++++++------- src/packet/disconnect_packet.rs | 73 ++++---- src/packet/mod.rs | 17 +- src/packet/mqtt_packet.rs | 50 +++++- src/packet/packet_type.rs | 73 ++++---- src/packet/pingreq_packet.rs | 44 +++-- src/packet/pingresp_packet.rs | 49 +++--- src/packet/property.rs | 235 +++++++++++++++++++------- src/packet/puback_packet.rs | 77 ++++----- src/packet/pubcomp_packet.rs | 76 ++++----- src/packet/publish_packet.rs | 80 ++++----- src/packet/pubrec_packet.rs | 75 ++++---- src/packet/pubrel_packet.rs | 76 ++++----- src/packet/suback_packet.rs | 80 ++++----- src/packet/subscription_packet.rs | 47 ++++-- src/packet/unsuback_packet.rs | 82 ++++----- src/packet/unsubscription_packet.rs | 45 +++-- src/utils/buffer_reader.rs | 134 +++++++++------ src/utils/buffer_writer.rs | 119 +++++++++++++ src/utils/mod.rs | 3 +- 26 files changed, 1061 insertions(+), 749 deletions(-) create mode 100644 src/utils/buffer_writer.rs diff --git a/src/encoding/mod.rs b/src/encoding/mod.rs index 9ba016a..563194c 100644 --- a/src/encoding/mod.rs +++ b/src/encoding/mod.rs @@ -1 +1 @@ -pub mod variable_byte_integer; \ No newline at end of file +pub mod variable_byte_integer; diff --git a/src/encoding/variable_byte_integer.rs b/src/encoding/variable_byte_integer.rs index 6ed1b35..2964375 100644 --- a/src/encoding/variable_byte_integer.rs +++ b/src/encoding/variable_byte_integer.rs @@ -1,7 +1,8 @@ #![crate_name = "doc"] use crate::utils::buffer_reader::ParseError; -/// VariableByteIntegerEncoder and VariableByteIntegerDecoder are implemented based on + +/// VariableByteIntegerEncoder and VariableByteIntegerDecoder are implemented based on /// pseudo code which is introduced in MQTT version 5.0 OASIS standard accesible from /// https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901107 @@ -9,6 +10,7 @@ use crate::utils::buffer_reader::ParseError; /// encode integer into MQTT variable byte integer format. This format is mainly used to encode /// lenghts stored in a packet. pub struct VariableByteIntegerEncoder; + /// Variable byte integers error enumeration is used by both encoder and decoder for /// error notification. @@ -44,7 +46,21 @@ impl VariableByteIntegerEncoder { break; } } - return Ok(res); + return Ok(res); + } + + pub fn len(var_int: VariableByteInteger) -> usize { + let mut i: usize = 0; + loop { + let mut encoded_byte: u8; + encoded_byte = var_int[i]; + + if (encoded_byte & 128) == 0 { + break; + } + i = i + 1; + } + return i; } } @@ -52,7 +68,6 @@ impl VariableByteIntegerEncoder { /// decode message lenghts in MQTT packet and other parts encoded into variable byte integer. pub struct VariableByteIntegerDecoder; - impl VariableByteIntegerDecoder { /// Decode function takes as paramater encoded integer represented /// as array of 4 unsigned numbers of exactly 1 Byte each -> 4 Bytes maximal @@ -63,7 +78,7 @@ impl VariableByteIntegerDecoder { let mut encoded_byte: u8; let mut i: usize = 0; - + loop { encoded_byte = encoded[i]; i = i + 1; @@ -79,4 +94,4 @@ impl VariableByteIntegerDecoder { return Ok(ret); } -} \ No newline at end of file +} diff --git a/src/lib.rs b/src/lib.rs index 7673fbc..9ce0124 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,10 +1,10 @@ - +#![feature(in_band_lifetimes)] #![macro_use] #![cfg_attr(not(feature = "std"), no_std)] #![allow(dead_code)] -pub mod packet; pub mod encoding; +pub mod packet; pub mod utils; #[allow(unused_variables)] @@ -33,4 +33,4 @@ pub fn print_value_size(name: &'static str, val: &T) { name, core::mem::size_of_val::(val) );*/ -} \ No newline at end of file +} diff --git a/src/main.rs b/src/main.rs index fb12cfc..dd0bc92 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,20 +1,16 @@ -use rust_mqtt::packet::mqtt_packet::*; -use rust_mqtt::packet::packet_type::PacketType; -use rust_mqtt::encoding::variable_byte_integer::VariableByteIntegerEncoder; -use rust_mqtt::encoding::variable_byte_integer::VariableByteIntegerDecoder; -use rust_mqtt::packet::property::*; -use rust_mqtt::utils::buffer_reader::BuffReader; -use heapless::Vec; +/*use rust_mqtt::packet::mqtt_packet::*; +use rust_mqtt::packet::property::*;*/ +/*use heapless::Vec; use std::fs::File; -use std::io::Read; +use std::io::Read;*/ fn main() { env_logger::builder() - .filter_level(log::LevelFilter::Info) - .format_timestamp_nanos() - .init(); + .filter_level(log::LevelFilter::Info) + .format_timestamp_nanos() + .init(); - let fl = File::open("/Users/obabec/development/school/rust-mqtt/mqtt_control_example.bin"); + /*let fl = File::open("/Users/obabec/development/school/rust-mqtt/mqtt_control_example.bin"); let mut f = File::open("/Users/obabec/development/school/rust-mqtt/mqtt_control_example.bin").expect("no file found"); let mut buffer: [u8; 500] = [0; 500]; @@ -22,12 +18,12 @@ fn main() { //let mut txt = Vec::new(); - let mut payld = *b"xxxxx"; + let mut payld = *b"xxxxx";*/ //let packet = Packet::clean(txt, &mut payld); /*let mut buffer_reader = BuffReader::new(&buffer); packet_builder.decode_packet(& mut buffer_reader); - + let bytes: [u8; 4] = packet_builder.currentPacket.protocol_name.to_be_bytes(); let prot = std::str::from_utf8(&bytes).unwrap(); @@ -37,4 +33,4 @@ fn main() { /*fn test(tst: &str) { log::info!("xx"); log::info!("Prvni: {}", ) -}*/ \ No newline at end of file +}*/ diff --git a/src/packet/auth_packet.rs b/src/packet/auth_packet.rs index a81a9f1..b3d417f 100644 --- a/src/packet/auth_packet.rs +++ b/src/packet/auth_packet.rs @@ -1,13 +1,12 @@ -use super::property::Property; -use super::packet_type::PacketType; -use crate::utils::buffer_reader::BuffReader; -use crate::utils::buffer_reader::EncodedString; -use crate::utils::buffer_reader::BinaryData; -use crate::utils::buffer_reader::ParseError; -use crate::packet::mqtt_packet::Packet; use heapless::Vec; +use crate::encoding::variable_byte_integer::VariableByteIntegerEncoder; +use crate::packet::mqtt_packet::Packet; +use crate::utils::buffer_reader::BuffReader; +use crate::utils::buffer_writer::{BuffWriter}; +use super::packet_type::PacketType; +use super::property::Property; pub struct AuthPacket<'a, const MAX_PROPERTIES: usize> { // 7 - 4 mqtt control packet type, 3-0 flagy @@ -22,17 +21,74 @@ pub struct AuthPacket<'a, const MAX_PROPERTIES: usize> { pub properties: Vec, MAX_PROPERTIES>, } - impl<'a, const MAX_PROPERTIES: usize> AuthPacket<'a, MAX_PROPERTIES> { + pub fn decode_auth_packet(& mut self, buff_reader: & mut BuffReader<'a>) { + self.decode_fixed_header(buff_reader); + self.auth_reason = buff_reader.read_u8().unwrap(); + self.decode_properties(buff_reader); + } -} + pub fn add_reason_code(& mut self, code: u8) { + if code != 0 && code != 24 && code != 25 { + log::error!("Provided reason code is not supported!"); + return; + } + self.auth_reason = code; + } + + pub fn add_property(& mut self, p: Property<'a>) { + if p.auth_property() { + self.push_to_properties(p); + } else { + log::error!("Provided property is not correct AUTH packet property!"); + } + } +} impl<'a, const MAX_PROPERTIES: usize> Packet<'a> for AuthPacket<'a, MAX_PROPERTIES> { - fn decode(& mut self, buff_reader: & mut BuffReader<'a>) { - log::error!("PingreqPacket packet does not support decode funtion on client!"); + /*fn new() -> Packet<'a, MAX_PROPERTIES> { + return AuthPacket { fixed_header: PacketType::Auth.into(), remain_len: 0, auth_reason: 0, property_len: 0, properties: Vec::, MAX_PROPERTIES>::new() } + }*/ + + fn encode(&mut self, buffer: & mut [u8]) { + let mut buff_writer = BuffWriter::new(buffer); + + let mut rm_ln = self.property_len; + let property_len_enc: [u8; 4] = VariableByteIntegerEncoder::encode(self.property_len).unwrap(); + let property_len_len = VariableByteIntegerEncoder::len(property_len_enc); + rm_ln = rm_ln + property_len_len as u32; + rm_ln = rm_ln + 1; + let rm_len_enc: [u8; 4] = VariableByteIntegerEncoder::encode(rm_ln).unwrap(); + let rm_len_len = VariableByteIntegerEncoder::len(rm_len_enc); + + buff_writer.write_u8(self.fixed_header); + buff_writer.insert_ref(rm_len_len, &rm_len_enc); + buff_writer.write_u8(self.auth_reason); + buff_writer.insert_ref(property_len_len, &property_len_enc); + buff_writer.encode_properties::(&self.properties); } - fn encode(& mut self, buffer: & mut [u8]) { - + fn decode(&mut self, buff_reader: &mut BuffReader<'a>) { + self.decode_auth_packet(buff_reader); } -} \ No newline at end of file + + fn set_property_len(&mut self, value: u32) { + self.property_len = value; + } + + fn get_property_len(&mut self) -> u32 { + return self.property_len; + } + + fn push_to_properties(&mut self, property: Property<'a>) { + self.properties.push(property); + } + + fn set_fixed_header(& mut self, header: u8) { + self.fixed_header = header; + } + + fn set_remaining_len(& mut self, remaining_len: u32) { + self.remain_len = remaining_len; + } +} diff --git a/src/packet/connack_packet.rs b/src/packet/connack_packet.rs index a0720a0..f82ddbf 100644 --- a/src/packet/connack_packet.rs +++ b/src/packet/connack_packet.rs @@ -1,17 +1,14 @@ -use super::property::Property; -use super::packet_type::PacketType; -use crate::utils::buffer_reader::BuffReader; -use crate::utils::buffer_reader::EncodedString; -use crate::utils::buffer_reader::BinaryData; -use crate::utils::buffer_reader::ParseError; -use crate::packet::mqtt_packet::Packet; use heapless::Vec; +use crate::packet::mqtt_packet::Packet; +use crate::utils::buffer_reader::BuffReader; + +use super::packet_type::PacketType; +use super::property::Property; pub const MAX_PROPERTIES: usize = 18; pub struct ConnackPacket<'a> { - // 7 - 4 mqtt control packet type, 3-0 flagy pub fixed_header: u8, // 1 - 4 B lenght of variable header + len of payload @@ -20,57 +17,43 @@ pub struct ConnackPacket<'a> { pub connect_reason_code: u8, pub property_len: u32, pub properties: Vec, MAX_PROPERTIES>, - } impl<'a> ConnackPacket<'a> { - - pub fn decode_fixed_header(& mut self, buff_reader: & mut BuffReader) -> PacketType { - let first_byte: u8 = buff_reader.readU8().unwrap(); - self.fixed_header = first_byte; - self.remain_len = buff_reader.readVariableByteInt().unwrap(); - return PacketType::from(self.fixed_header); - } - - pub fn decode_properties(& mut self, buff_reader: & mut BuffReader<'a>) { - self.property_len = buff_reader.readVariableByteInt().unwrap(); - let mut x: u32 = 0; - let mut prop: Result; - loop { - let mut res: Property; - prop = Property::decode(buff_reader); - if let Ok(res) = prop { - log::info!("Parsed property {:?}", res); - x = x + res.len() as u32 + 1; - self.properties.push(res); - } else { - // error handlo - log::error!("Problem during property decoding"); - } - - if x == self.property_len { - break; - } - } - } - - pub fn decode_connack_packet(& mut self, buff_reader: & mut BuffReader<'a>) { - + pub fn decode_connack_packet(&mut self, buff_reader: &mut BuffReader<'a>) { if self.decode_fixed_header(buff_reader) != (PacketType::Connack).into() { log::error!("Packet you are trying to decode is not CONNACK packet!"); return; } - self.ack_flags = buff_reader.readU8().unwrap(); - self.connect_reason_code = buff_reader.readU8().unwrap(); + self.ack_flags = buff_reader.read_u8().unwrap(); + self.connect_reason_code = buff_reader.read_u8().unwrap(); self.decode_properties(buff_reader); } } impl<'a> Packet<'a> for ConnackPacket<'a> { - fn decode(& mut self, buff_reader: & mut BuffReader<'a>) { + fn encode(&mut self, buffer: &mut [u8]) {} + fn decode(&mut self, buff_reader: &mut BuffReader<'a>) { self.decode_connack_packet(buff_reader); } - fn encode(& mut self, buffer: & mut [u8]) { + fn set_property_len(&mut self, value: u32) { + self.property_len = value; } -} \ No newline at end of file + + fn get_property_len(&mut self) -> u32 { + return self.property_len; + } + + fn push_to_properties(&mut self, property: Property<'a>) { + self.properties.push(property); + } + + fn set_fixed_header(& mut self, header: u8) { + self.fixed_header = header; + } + + fn set_remaining_len(& mut self, remaining_len: u32) { + self.remain_len = remaining_len; + } +} diff --git a/src/packet/control_packet.rs b/src/packet/control_packet.rs index 8d1d996..783e121 100644 --- a/src/packet/control_packet.rs +++ b/src/packet/control_packet.rs @@ -1,11 +1,13 @@ -use super::property::Property; -use super::packet_type::PacketType; +use heapless::Vec; + +use crate::packet::mqtt_packet::Packet; +use crate::utils::buffer_reader::BinaryData; use crate::utils::buffer_reader::BuffReader; use crate::utils::buffer_reader::EncodedString; -use crate::utils::buffer_reader::BinaryData; use crate::utils::buffer_reader::ParseError; -use crate::packet::mqtt_packet::Packet; -use heapless::Vec; + +use super::packet_type::PacketType; +use super::property::Property; pub const MAX_PROPERTIES: usize = 18; pub const MAX_WILL_PROPERTIES: usize = 7; @@ -17,7 +19,7 @@ pub struct ControlPacket<'a> { pub remain_len: u32, // variable header - //optional prida se pouze u packetu ve kterych ma co delat + //optional prida se pouze u packetu ve kterych ma co delat pub packet_identifier: u16, pub protocol_name_len: u16, pub protocol_name: u32, @@ -38,26 +40,45 @@ pub struct ControlPacket<'a> { pub will_topic: EncodedString<'a>, pub will_payload: BinaryData<'a>, pub username: EncodedString<'a>, - pub password: BinaryData<'a> + pub password: BinaryData<'a>, } impl<'a> ControlPacket<'a> { - pub fn clean(properties: Vec, MAX_PROPERTIES>, will_properties: Vec, MAX_WILL_PROPERTIES> ) -> Self { - Self{ fixed_header: 0x00, remain_len: 0, packet_identifier: 0, protocol_name_len: 0, protocol_name: 0, protocol_version: 5, connect_flags: 0, - keep_alive: 0, property_len: 0, properties, client_id: EncodedString::new(), will_property_len: 0, will_properties, will_topic: EncodedString::new(), - will_payload: BinaryData::new(), username: EncodedString::new(), password: BinaryData::new() } + pub fn clean( + properties: Vec, MAX_PROPERTIES>, + will_properties: Vec, MAX_WILL_PROPERTIES>, + ) -> Self { + Self { + fixed_header: 0x00, + remain_len: 0, + packet_identifier: 0, + protocol_name_len: 0, + protocol_name: 0, + protocol_version: 5, + connect_flags: 0, + keep_alive: 0, + property_len: 0, + properties, + client_id: EncodedString::new(), + will_property_len: 0, + will_properties, + will_topic: EncodedString::new(), + will_payload: BinaryData::new(), + username: EncodedString::new(), + password: BinaryData::new(), + } } pub fn get_reason_code(&self) { log::info!("Getting reason code!"); } - pub fn addPacketType(& mut self, new_packet_type: PacketType) { + pub fn add_packet_type(&mut self, new_packet_type: PacketType) { self.fixed_header = self.fixed_header & 0x0F; self.fixed_header = self.fixed_header | >::into(new_packet_type); } - pub fn addFlags(& mut self, dup: bool, qos: u8, retain: bool) { + pub fn add_flags(&mut self, dup: bool, qos: u8, retain: bool) { let cur_type: u8 = self.fixed_header & 0xF0; if cur_type != 0x30 { log::error!("Cannot add flags into packet with other than PUBLISH type"); @@ -79,39 +100,9 @@ impl<'a> ControlPacket<'a> { self.fixed_header = cur_type | flags; } - pub fn decode_fixed_header(& mut self, buff_reader: & mut BuffReader) -> PacketType { - let first_byte: u8 = buff_reader.readU8().unwrap(); - self.fixed_header = first_byte; - self.remain_len = buff_reader.readVariableByteInt().unwrap(); - return PacketType::from(self.fixed_header); - } - - pub fn decode_properties(& mut self, buff_reader: & mut BuffReader<'a>) { - - self.property_len = buff_reader.readVariableByteInt().unwrap(); - let mut x: u32 = 0; - let mut prop: Result; - loop { - let mut res: Property; - prop = Property::decode(buff_reader); - if let Ok(res) = prop { - log::info!("Parsed property {:?}", res); - x = x + res.len() as u32 + 1; - self.properties.push(res); - } else { - // error handlo - log::error!("Problem during property decoding"); - } - - if x == self.property_len { - break; - } - } - } - - pub fn decode_will_properties(& mut self, buff_reader: & mut BuffReader<'a>) { + pub fn decode_will_properties(&mut self, buff_reader: &mut BuffReader<'a>) { //todo: need to check if we are parsing only will properties - let will_property_len = buff_reader.readVariableByteInt().unwrap(); + let will_property_len = buff_reader.read_variable_byte_int().unwrap(); let mut x: u32 = 0; let mut prop: Result; loop { @@ -125,51 +116,91 @@ impl<'a> ControlPacket<'a> { // error handlo log::error!("Problem during property decoding"); } - + if x == will_property_len { break; } } } - pub fn decode_payload(& mut self, buff_reader: & mut BuffReader<'a>) { - self.client_id = buff_reader.readString().unwrap(); + pub fn decode_payload(&mut self, buff_reader: &mut BuffReader<'a>) { + self.client_id = buff_reader.read_string().unwrap(); if self.connect_flags & (1 << 2) == 1 { self.decode_will_properties(buff_reader); - self.will_topic = buff_reader.readString().unwrap(); - self.will_payload = buff_reader.readBinary().unwrap(); + self.will_topic = buff_reader.read_string().unwrap(); + self.will_payload = buff_reader.read_binary().unwrap(); } - + if self.connect_flags & (1 << 7) == 1 { - self.username = buff_reader.readString().unwrap(); + self.username = buff_reader.read_string().unwrap(); } if self.connect_flags & (1 << 6) == 1 { - self.password = buff_reader.readBinary().unwrap(); + self.password = buff_reader.read_binary().unwrap(); } } - pub fn decode_control_packet(& mut self, buff_reader: & mut BuffReader<'a>) { + pub fn decode_control_packet(&mut self, buff_reader: &mut BuffReader<'a>) { if self.decode_fixed_header(buff_reader) != (PacketType::Connect).into() { log::error!("Packet you are trying to decode is not CONNECT packet!"); } self.packet_identifier = 0; - self.protocol_name_len = buff_reader.readU16().unwrap(); - self.protocol_name = buff_reader.readU32().unwrap(); - self.protocol_version = buff_reader.readU8().unwrap(); - self.connect_flags = buff_reader.readU8().unwrap(); - self.keep_alive = buff_reader.readU16().unwrap(); + self.protocol_name_len = buff_reader.read_u16().unwrap(); + self.protocol_name = buff_reader.read_u32().unwrap(); + self.protocol_version = buff_reader.read_u8().unwrap(); + self.connect_flags = buff_reader.read_u8().unwrap(); + self.keep_alive = buff_reader.read_u16().unwrap(); self.decode_properties(buff_reader); self.decode_payload(buff_reader); } } impl<'a> Packet<'a> for ControlPacket<'a> { - fn decode(& mut self, buff_reader: & mut BuffReader<'a>) { + fn encode(&mut self, buffer: &mut [u8]) {} + + fn decode(&mut self, buff_reader: &mut BuffReader<'a>) { log::error!("Decode function is not available for control packet!") //self.decode_control_packet(buff_reader); } - fn encode(& mut self, buffer: & mut [u8]) { - + fn set_property_len(&mut self, value: u32) { + self.property_len = value; } -} \ No newline at end of file + + fn get_property_len(&mut self) -> u32 { + return self.property_len; + } + + fn push_to_properties(&mut self, property: Property<'a>) { + self.properties.push(property); + } + + fn set_fixed_header(& mut self, header: u8) { + self.fixed_header = header; + } + + fn set_remaining_len(& mut self, remaining_len: u32) { + self.remain_len = remaining_len; + } + + fn decode_properties(&mut self, buff_reader: &mut BuffReader<'a>) { + self.property_len = buff_reader.read_variable_byte_int().unwrap(); + let mut x: u32 = 0; + let mut prop: Result; + loop { + let mut res: Property; + prop = Property::decode(buff_reader); + if let Ok(res) = prop { + log::info!("Parsed property {:?}", res); + x = x + res.len() as u32 + 1; + self.properties.push(res); + } else { + // error handlo + log::error!("Problem during property decoding"); + } + + if x == self.property_len { + break; + } + } + } +} diff --git a/src/packet/disconnect_packet.rs b/src/packet/disconnect_packet.rs index a539c7c..df07b52 100644 --- a/src/packet/disconnect_packet.rs +++ b/src/packet/disconnect_packet.rs @@ -1,13 +1,10 @@ -use super::property::Property; -use super::packet_type::PacketType; -use crate::utils::buffer_reader::BuffReader; -use crate::utils::buffer_reader::EncodedString; -use crate::utils::buffer_reader::BinaryData; -use crate::utils::buffer_reader::ParseError; -use crate::packet::mqtt_packet::Packet; use heapless::Vec; +use crate::packet::mqtt_packet::Packet; +use crate::utils::buffer_reader::BuffReader; +use super::packet_type::PacketType; +use super::property::Property; pub struct DisconnectPacket<'a, const MAX_PROPERTIES: usize> { // 7 - 4 mqtt control packet type, 3-0 flagy @@ -22,53 +19,41 @@ pub struct DisconnectPacket<'a, const MAX_PROPERTIES: usize> { pub properties: Vec, MAX_PROPERTIES>, } - impl<'a, const MAX_PROPERTIES: usize> DisconnectPacket<'a, MAX_PROPERTIES> { - pub fn decode_properties(& mut self, buff_reader: & mut BuffReader<'a>) { - self.property_len = buff_reader.readVariableByteInt().unwrap(); - let mut x: u32 = 0; - let mut prop: Result; - loop { - let mut res: Property; - prop = Property::decode(buff_reader); - if let Ok(res) = prop { - log::info!("Parsed property {:?}", res); - x = x + res.len() as u32 + 1; - self.properties.push(res); - } else { - // error handlo - log::error!("Problem during property decoding"); - } - - if x == self.property_len { - break; - } - } - } - - pub fn decode_fixed_header(& mut self, buff_reader: & mut BuffReader<'a>) -> PacketType { - let first_byte: u8 = buff_reader.readU8().unwrap(); - self.fixed_header = first_byte; - self.remain_len = buff_reader.readVariableByteInt().unwrap(); - return PacketType::from(self.fixed_header); - } - - pub fn decode_auth_packet(& mut self, buff_reader: & mut BuffReader<'a>) { + pub fn decode_auth_packet(&mut self, buff_reader: &mut BuffReader<'a>) { if self.decode_fixed_header(buff_reader) != (PacketType::Pingresp).into() { log::error!("Packet you are trying to decode is not PUBACK packet!"); return; } - self.disconnect_reason = buff_reader.readU8().unwrap(); + self.disconnect_reason = buff_reader.read_u8().unwrap(); self.decode_properties(buff_reader); } -} +} impl<'a, const MAX_PROPERTIES: usize> Packet<'a> for DisconnectPacket<'a, MAX_PROPERTIES> { - fn decode(& mut self, buff_reader: & mut BuffReader<'a>) { + fn encode(&mut self, buffer: &mut [u8]) {} + + fn decode(&mut self, buff_reader: &mut BuffReader<'a>) { self.decode_auth_packet(buff_reader); } - fn encode(& mut self, buffer: & mut [u8]) { - + fn set_property_len(&mut self, value: u32) { + self.property_len = value; } -} \ No newline at end of file + + fn get_property_len(&mut self) -> u32 { + return self.property_len; + } + + fn push_to_properties(&mut self, property: Property<'a>) { + self.properties.push(property); + } + + fn set_fixed_header(& mut self, header: u8) { + self.fixed_header = header; + } + + fn set_remaining_len(& mut self, remaining_len: u32) { + self.remain_len = remaining_len; + } +} diff --git a/src/packet/mod.rs b/src/packet/mod.rs index ec726f9..7208f60 100644 --- a/src/packet/mod.rs +++ b/src/packet/mod.rs @@ -1,17 +1,20 @@ -pub mod control_packet; +/*pub mod connack_packet; +pub mod control_packet;*/ pub mod mqtt_packet; pub mod packet_type; pub mod property; -pub mod puback_packet; +pub mod auth_packet; +/*pub mod puback_packet; +pub mod pubcomp_packet; pub mod publish_packet; pub mod pubrec_packet; -pub mod connack_packet; pub mod pubrel_packet; -pub mod pubcomp_packet; pub mod subscription_packet; pub mod unsubscription_packet; -pub mod suback_packet; -pub mod unsuback_packet; + + +pub mod disconnect_packet; pub mod pingreq_packet; pub mod pingresp_packet; -pub mod disconnect_packet; \ No newline at end of file +pub mod suback_packet; +pub mod unsuback_packet;*/ diff --git a/src/packet/mqtt_packet.rs b/src/packet/mqtt_packet.rs index 66b2a69..ca4a837 100644 --- a/src/packet/mqtt_packet.rs +++ b/src/packet/mqtt_packet.rs @@ -1,6 +1,50 @@ +use crate::packet::packet_type::PacketType; use crate::utils::buffer_reader::BuffReader; +use crate::utils::buffer_reader::ParseError; + +use super::property::Property; pub trait Packet<'a> { - fn encode(& mut self, buffer: & mut [u8]); - fn decode(& mut self, buff_reader: & mut BuffReader<'a>); -} \ No newline at end of file + //fn new() -> dyn Packet<'a> where Self: Sized; + + fn encode(&mut self, buffer: &mut [u8]); + fn decode(&mut self, buff_reader: &mut BuffReader<'a>); + + // properties + fn set_property_len(&mut self, value: u32); + fn get_property_len(&mut self) -> u32; + fn push_to_properties(&mut self, property: Property<'a>); + + // header + fn set_fixed_header(& mut self, header: u8); + fn set_remaining_len(& mut self, remaining_len: u32); + + fn decode_properties(&mut self, buff_reader: & mut BuffReader<'a>) { + self.set_property_len(buff_reader.read_variable_byte_int().unwrap()); + let mut x: u32 = 0; + let mut prop: Result; + loop { + let mut res: Property; + prop = Property::decode(buff_reader); + if let Ok(res) = prop { + log::info!("Parsed property {:?}", res); + x = x + res.len() as u32 + 1; + self.push_to_properties(res); + } else { + // error handler + log::error!("Problem during property decoding"); + } + + if x == self.get_property_len() { + break; + } + } + } + + fn decode_fixed_header(&mut self, buff_reader: &mut BuffReader) -> PacketType { + let first_byte: u8 = buff_reader.read_u8().unwrap(); + self.set_fixed_header(first_byte); + self.set_remaining_len(buff_reader.read_variable_byte_int().unwrap()); + return PacketType::from(first_byte); + } +} diff --git a/src/packet/packet_type.rs b/src/packet/packet_type.rs index 3598209..7502580 100644 --- a/src/packet/packet_type.rs +++ b/src/packet/packet_type.rs @@ -17,54 +17,53 @@ pub enum PacketType { Pingreq, Pingresp, Disconnect, - Auth + Auth, } impl From for PacketType { fn from(orig: u8) -> Self { let packet_type: u8 = orig & 0xF0; - match packet_type { - 0x10 => return PacketType::Connect, - 0x20 => return PacketType::Connack, - 0x00 => return PacketType::Reserved, - 0x30 => return PacketType::Publish, - 0x40 => return PacketType::Puback, - 0x50 => return PacketType::Pubrec, - 0x60 => return PacketType::Pubrel, - 0x70 => return PacketType::Pubcomp, - 0x80 => return PacketType::Subscribe, - 0x90 => return PacketType::Suback, - 0xA0 => return PacketType::Unsubscribe, - 0xB0 => return PacketType::Unsuback, - 0xC0 => return PacketType::Pingreq, - 0xD0 => return PacketType::Pingresp, - 0xE0 => return PacketType::Disconnect, - 0xF0 => return PacketType::Auth, - _ => return PacketType::Reserved + return match packet_type { + 0x10 => PacketType::Connect, + 0x20 => PacketType::Connack, + 0x00 => PacketType::Reserved, + 0x30 => PacketType::Publish, + 0x40 => PacketType::Puback, + 0x50 => PacketType::Pubrec, + 0x60 => PacketType::Pubrel, + 0x70 => PacketType::Pubcomp, + 0x80 => PacketType::Subscribe, + 0x90 => PacketType::Suback, + 0xA0 => PacketType::Unsubscribe, + 0xB0 => PacketType::Unsuback, + 0xC0 => PacketType::Pingreq, + 0xD0 => PacketType::Pingresp, + 0xE0 => PacketType::Disconnect, + 0xF0 => PacketType::Auth, + _ => PacketType::Reserved, }; } } impl Into for PacketType { fn into(self) -> u8 { - match self { - PacketType::Connect => return 0x10, - PacketType::Connack => return 0x20, - PacketType::Publish => return 0x30, - PacketType::Puback => return 0x40, - PacketType::Pubrec => return 0x50, - PacketType::Pubrel => return 0x60, - PacketType::Pubcomp => return 0x70, - PacketType::Subscribe => return 0x80, - PacketType::Suback => return 0x90, - PacketType::Unsubscribe => return 0xA0, - PacketType::Unsuback => return 0xB0, - PacketType::Pingreq => return 0xC0, - PacketType::Pingresp => return 0xD0, - PacketType::Disconnect => return 0xE0, - PacketType::Auth => return 0xF0, - PacketType::Reserved => return 0x00 + return match self { + PacketType::Connect => 0x10, + PacketType::Connack => 0x20, + PacketType::Publish => 0x30, + PacketType::Puback => 0x40, + PacketType::Pubrec => 0x50, + PacketType::Pubrel => 0x60, + PacketType::Pubcomp => 0x70, + PacketType::Subscribe => 0x80, + PacketType::Suback => 0x90, + PacketType::Unsubscribe => 0xA0, + PacketType::Unsuback => 0xB0, + PacketType::Pingreq => 0xC0, + PacketType::Pingresp => 0xD0, + PacketType::Disconnect => 0xE0, + PacketType::Auth => 0xF0, + PacketType::Reserved => 0x00, } } } - diff --git a/src/packet/pingreq_packet.rs b/src/packet/pingreq_packet.rs index a5f8356..b2f81dc 100644 --- a/src/packet/pingreq_packet.rs +++ b/src/packet/pingreq_packet.rs @@ -1,33 +1,45 @@ -use super::property::Property; -use super::packet_type::PacketType; -use crate::utils::buffer_reader::BuffReader; -use crate::utils::buffer_reader::EncodedString; -use crate::utils::buffer_reader::BinaryData; -use crate::utils::buffer_reader::ParseError; use crate::packet::mqtt_packet::Packet; -use heapless::Vec; +use crate::utils::buffer_reader::BuffReader; +use super::packet_type::PacketType; +use super::property::Property; pub const MAX_PROPERTIES: usize = 2; -pub struct PingreqPacket{ +pub struct PingreqPacket { // 7 - 4 mqtt control packet type, 3-0 flagy pub fixed_header: u8, // 1 - 4 B lenght of variable header + len of payload pub remain_len: u32, } - -impl PingreqPacket { - -} +impl PingreqPacket {} impl<'a> Packet<'a> for PingreqPacket { - fn decode(& mut self, buff_reader: & mut BuffReader<'a>) { + fn encode(&mut self, buffer: &mut [u8]) {} + + fn decode(&mut self, buff_reader: &mut BuffReader<'a>) { log::error!("PingreqPacket packet does not support decode funtion on client!"); } - fn encode(& mut self, buffer: & mut [u8]) { - + fn set_property_len(&mut self, value: u32) { + log::error!("PINGREQ packet does not contain any properties!"); } -} \ No newline at end of file + + fn get_property_len(&mut self) -> u32 { + log::error!("PINGREQ packet does not contain any properties!"); + return 0; + } + + fn push_to_properties(&mut self, property: Property<'a>) { + log::error!("PINGREQ packet does not contain any properties!"); + } + + fn set_fixed_header(& mut self, header: u8) { + self.fixed_header = header; + } + + fn set_remaining_len(& mut self, remaining_len: u32) { + self.remain_len = remaining_len; + } +} diff --git a/src/packet/pingresp_packet.rs b/src/packet/pingresp_packet.rs index 4349cb6..ec64e37 100644 --- a/src/packet/pingresp_packet.rs +++ b/src/packet/pingresp_packet.rs @@ -1,12 +1,8 @@ -use super::property::Property; -use super::packet_type::PacketType; -use crate::utils::buffer_reader::BuffReader; -use crate::utils::buffer_reader::EncodedString; -use crate::utils::buffer_reader::BinaryData; -use crate::utils::buffer_reader::ParseError; use crate::packet::mqtt_packet::Packet; -use heapless::Vec; +use crate::utils::buffer_reader::BuffReader; +use super::packet_type::PacketType; +use super::property::Property; pub struct PingrespPacket { // 7 - 4 mqtt control packet type, 3-0 flagy @@ -15,29 +11,40 @@ pub struct PingrespPacket { pub remain_len: u32, } - impl<'a> PingrespPacket { - pub fn decode_fixed_header(& mut self, buff_reader: & mut BuffReader<'a>) -> PacketType { - let first_byte: u8 = buff_reader.readU8().unwrap(); - self.fixed_header = first_byte; - self.remain_len = buff_reader.readVariableByteInt().unwrap(); - return PacketType::from(self.fixed_header); - } - - pub fn decode_pingresp_packet(& mut self, buff_reader: & mut BuffReader<'a>) { + pub fn decode_pingresp_packet(&mut self, buff_reader: &mut BuffReader<'a>) { if self.decode_fixed_header(buff_reader) != (PacketType::Pingresp).into() { log::error!("Packet you are trying to decode is not PUBACK packet!"); return; } } -} +} impl<'a> Packet<'a> for PingrespPacket { - fn decode(& mut self, buff_reader: & mut BuffReader<'a>) { + fn encode(&mut self, buffer: &mut [u8]) {} + + fn decode(&mut self, buff_reader: &mut BuffReader<'a>) { self.decode_pingresp_packet(buff_reader); } - fn encode(& mut self, buffer: & mut [u8]) { - + fn set_property_len(&mut self, value: u32) { + log::error!("PINGRESP packet does not contain any properties!"); } -} \ No newline at end of file + + fn get_property_len(&mut self) -> u32 { + log::error!("PINGRESP packet does not contain any properties!"); + return 0; + } + + fn push_to_properties(&mut self, property: Property<'a>) { + log::error!("PINGRESP packet does not contain any properties!"); + } + + fn set_fixed_header(& mut self, header: u8) { + self.fixed_header = header; + } + + fn set_remaining_len(& mut self, remaining_len: u32) { + self.remain_len = remaining_len; + } +} diff --git a/src/packet/property.rs b/src/packet/property.rs index 059315d..a977e35 100644 --- a/src/packet/property.rs +++ b/src/packet/property.rs @@ -1,8 +1,10 @@ -use crate::utils::buffer_reader::ParseError; -use crate::utils::buffer_reader::StringPair; -use crate::utils::buffer_reader::EncodedString; +use crate::encoding::variable_byte_integer::{VariableByteInteger, VariableByteIntegerEncoder}; use crate::utils::buffer_reader::BinaryData; use crate::utils::buffer_reader::BuffReader; +use crate::utils::buffer_reader::EncodedString; +use crate::utils::buffer_reader::ParseError; +use crate::utils::buffer_reader::StringPair; +use crate::utils::buffer_writer::BuffWriter; #[derive(Debug)] pub enum Property<'a> { @@ -32,73 +34,182 @@ pub enum Property<'a> { MaximumPacketSize(u32), WildcardSubscriptionAvailable(u8), SubscriptionIdentifierAvailable(u8), - SharedSubscriptionAvailable(u8) + SharedSubscriptionAvailable(u8), + Reserved(), } impl<'a> Property<'a> { + + pub fn auth_property(& self) -> bool { + return match self { + Property::AuthenticationMethod(_u) => true, + Property::AuthenticationData(_u) => true, + Property::ReasonString(_u) => true, + Property::UserProperty(_u) => true, + _ => false + } + } + pub fn len(&self) -> u16 { - match self { - Property::PayloadFormat(u) => return 1, - Property::MessageExpiryInterval(u) => return 4, - Property::ContentType(u) => return u.len(), - Property::ResponseTopic(u) => return u.len(), - Property::CorrelationData(u) => return u.len(), - Property::SubscriptionIdentifier(u) => return 4, - Property::AssignedClientIdentifier(u) => return u.len(), - Property::ServerKeepAlive(u) => return 2, - Property::AuthenticationMethod(u) => return u.len(), - Property::AuthenticationData(u) => return u.len(), - Property::RequestProblemInformation(u) => return 1, - Property::WillDelayInterval(u) => return 4, - Property::RequestResponseInformation(u) => return 1, - Property::ResponseInformation(u) => return u.len(), - Property::ServerReference(u) => return u.len(), - Property::ReasonString(u) => return u.len(), - Property::ReceiveMaximum(u) => return 2, - Property::TopicAliasMaximum(u) => return 2, - Property::TopicAlias(u) => return 2, - Property::MaximumQoS(u) => return 1, - Property::RetainAvailable(u) => return 1, - Property::UserProperty(u) => return u.len(), - Property::MaximumPacketSize(u) => return 4, - Property::WildcardSubscriptionAvailable(u) => return 1, - Property::SubscriptionIdentifierAvailable(u) => return 1, - Property::SharedSubscriptionAvailable(u) => return 1, - _ => return 0 + return match self { + Property::PayloadFormat(_u) => 1, + Property::MessageExpiryInterval(_u) => 4, + Property::ContentType(u) => u.len(), + Property::ResponseTopic(u) => u.len(), + Property::CorrelationData(u) => u.len(), + Property::SubscriptionIdentifier(_u) => 4, + Property::SessionExpiryInterval(_u) => 4, + Property::AssignedClientIdentifier(u) => u.len(), + Property::ServerKeepAlive(_u) => 2, + Property::AuthenticationMethod(u) => u.len(), + Property::AuthenticationData(u) => u.len(), + Property::RequestProblemInformation(_u) => 1, + Property::WillDelayInterval(_u) => 4, + Property::RequestResponseInformation(_u) => 1, + Property::ResponseInformation(u) => u.len(), + Property::ServerReference(u) => u.len(), + Property::ReasonString(u) => u.len(), + Property::ReceiveMaximum(_u) => 2, + Property::TopicAliasMaximum(_u) => 2, + Property::TopicAlias(_u) => 2, + Property::MaximumQoS(_u) => 1, + Property::RetainAvailable(_u) => 1, + Property::UserProperty(u) => u.len(), + Property::MaximumPacketSize(_u) => 4, + Property::WildcardSubscriptionAvailable(_u) => 1, + Property::SubscriptionIdentifierAvailable(_u) => 1, + Property::SharedSubscriptionAvailable(_u) => 1, + _ => 0, + } + } + + pub fn encode(&self, buff_writer: & mut BuffWriter<'a>) { + return match self { + Property::PayloadFormat(u) => buff_writer.write_u8(*u), + Property::MessageExpiryInterval(u) => buff_writer.write_u32(*u), + Property::ContentType(u) => buff_writer.write_string_ref(u), + Property::ResponseTopic(u) => buff_writer.write_string_ref(u), + Property::CorrelationData(u) => buff_writer.write_binary_ref(u), + Property::SubscriptionIdentifier(u) => buff_writer.write_variable_byte_int(*u), + Property::SessionExpiryInterval(u) => buff_writer.write_u32(*u), + Property::AssignedClientIdentifier(u) => buff_writer.write_string_ref(u), + Property::ServerKeepAlive(u) => buff_writer.write_u16(*u), + Property::AuthenticationMethod(u) => buff_writer.write_string_ref(u), + Property::AuthenticationData(u) => buff_writer.write_binary_ref(u), + Property::RequestProblemInformation(u) => buff_writer.write_u8(*u), + Property::WillDelayInterval(u) => buff_writer.write_u32(*u), + Property::RequestResponseInformation(u) => buff_writer.write_u8(*u), + Property::ResponseInformation(u) => buff_writer.write_string_ref(u), + Property::ServerReference(u) => buff_writer.write_string_ref(u), + Property::ReasonString(u) => buff_writer.write_string_ref(u), + Property::ReceiveMaximum(u) => buff_writer.write_u16(*u), + Property::TopicAliasMaximum(u) => buff_writer.write_u16(*u), + Property::TopicAlias(u) => buff_writer.write_u16(*u), + Property::MaximumQoS(u) => buff_writer.write_u8(*u), + Property::RetainAvailable(u) => buff_writer.write_u8(*u), + Property::UserProperty(u) => buff_writer.write_string_pair_ref(u), + Property::MaximumPacketSize(u) => buff_writer.write_u32(*u), + Property::WildcardSubscriptionAvailable(u) => buff_writer.write_u8(*u), + Property::SubscriptionIdentifierAvailable(u) => buff_writer.write_u8(*u), + Property::SharedSubscriptionAvailable(u) => buff_writer.write_u8(*u), + _ => (), } } pub fn decode(buff_reader: & mut BuffReader<'a>) -> Result, ParseError> { - let propertyIdentifier = buff_reader.readU8(); - match propertyIdentifier { - Ok(0x01) => return Ok(Property::PayloadFormat(buff_reader.readU8()?)), - Ok(0x02) => return Ok(Property::MessageExpiryInterval(buff_reader.readU32()?)), - Ok(0x03) => return Ok(Property::ContentType(buff_reader.readString()?)), - Ok(0x08) => return Ok(Property::ResponseTopic(buff_reader.readString()?)), - Ok(0x09) => return Ok(Property::CorrelationData(buff_reader.readBinary()?)), - Ok(0x0B) => return Ok(Property::SubscriptionIdentifier(buff_reader.readVariableByteInt()?)), - Ok(0x11) => return Ok(Property::SessionExpiryInterval(buff_reader.readU32()?)), - Ok(0x12) => return Ok(Property::AssignedClientIdentifier(buff_reader.readString()?)), - Ok(0x13) => return Ok(Property::ServerKeepAlive(buff_reader.readU16()?)), - Ok(0x15) => return Ok(Property::AuthenticationMethod(buff_reader.readString()?)), - Ok(0x16) => return Ok(Property::AuthenticationData(buff_reader.readBinary()?)), - Ok(0x17) => return Ok(Property::RequestProblemInformation(buff_reader.readU8()?)), - Ok(0x18) => return Ok(Property::WillDelayInterval(buff_reader.readU32()?)), - Ok(0x19) => return Ok(Property::RequestResponseInformation(buff_reader.readU8()?)), - Ok(0x1A) => return Ok(Property::ResponseInformation(buff_reader.readString()?)), - Ok(0x1C) => return Ok(Property::ServerReference(buff_reader.readString()?)), - Ok(0x1F) => return Ok(Property::ReasonString(buff_reader.readString()?)), - Ok(0x21) => return Ok(Property::ReceiveMaximum(buff_reader.readU16()?)), - Ok(0x22) => return Ok(Property::TopicAliasMaximum(buff_reader.readU16()?)), - Ok(0x23) => return Ok(Property::TopicAlias(buff_reader.readU16()?)), - Ok(0x24) => return Ok(Property::MaximumQoS(buff_reader.readU8()?)), - Ok(0x25) => return Ok(Property::RetainAvailable(buff_reader.readU8()?)), - Ok(0x26) => return Ok(Property::UserProperty(buff_reader.readStringPair()?)), - Ok(0x28) => return Ok(Property::WildcardSubscriptionAvailable(buff_reader.readU8()?)), - Ok(0x29) => return Ok(Property::SubscriptionIdentifierAvailable(buff_reader.readU8()?)), - Ok(0x2A) => return Ok(Property::SharedSubscriptionAvailable(buff_reader.readU8()?)), - Err(err) => return Err(err), - _ => return Err(ParseError::IdNotFound) + let property_identifier = buff_reader.read_u8(); + return match property_identifier { + Ok(0x01) => Ok(Property::PayloadFormat(buff_reader.read_u8()?)), + Ok(0x02) => Ok(Property::MessageExpiryInterval(buff_reader.read_u32()?)), + Ok(0x03) => Ok(Property::ContentType(buff_reader.read_string()?)), + Ok(0x08) => Ok(Property::ResponseTopic(buff_reader.read_string()?)), + Ok(0x09) => Ok(Property::CorrelationData(buff_reader.read_binary()?)), + Ok(0x0B) => { + Ok(Property::SubscriptionIdentifier( + buff_reader.read_variable_byte_int()?, + )) + } + Ok(0x11) => Ok(Property::SessionExpiryInterval(buff_reader.read_u32()?)), + Ok(0x12) => { + Ok(Property::AssignedClientIdentifier( + buff_reader.read_string()?, + )) + } + Ok(0x13) => Ok(Property::ServerKeepAlive(buff_reader.read_u16()?)), + Ok(0x15) => Ok(Property::AuthenticationMethod(buff_reader.read_string()?)), + Ok(0x16) => Ok(Property::AuthenticationData(buff_reader.read_binary()?)), + Ok(0x17) => Ok(Property::RequestProblemInformation(buff_reader.read_u8()?)), + Ok(0x18) => Ok(Property::WillDelayInterval(buff_reader.read_u32()?)), + Ok(0x19) => Ok(Property::RequestResponseInformation(buff_reader.read_u8()?)), + Ok(0x1A) => Ok(Property::ResponseInformation(buff_reader.read_string()?)), + Ok(0x1C) => Ok(Property::ServerReference(buff_reader.read_string()?)), + Ok(0x1F) => Ok(Property::ReasonString(buff_reader.read_string()?)), + Ok(0x21) => Ok(Property::ReceiveMaximum(buff_reader.read_u16()?)), + Ok(0x22) => Ok(Property::TopicAliasMaximum(buff_reader.read_u16()?)), + Ok(0x23) => Ok(Property::TopicAlias(buff_reader.read_u16()?)), + Ok(0x24) => Ok(Property::MaximumQoS(buff_reader.read_u8()?)), + Ok(0x25) => Ok(Property::RetainAvailable(buff_reader.read_u8()?)), + Ok(0x26) => Ok(Property::UserProperty(buff_reader.read_string_pair()?)), + Ok(0x28) => { + Ok(Property::WildcardSubscriptionAvailable( + buff_reader.read_u8()?, + )) + } + Ok(0x29) => { + Ok(Property::SubscriptionIdentifierAvailable( + buff_reader.read_u8()?, + )) + } + Ok(0x2A) => { + Ok(Property::SharedSubscriptionAvailable( + buff_reader.read_u8()?, + )) + } + Err(err) => Err(err), + _ => Err(ParseError::IdNotFound), } } +} + +impl Into for & Property<'a> { + fn into(self) -> u8 { + return match &*self { + Property::PayloadFormat(_u) => 0x01, + Property::MessageExpiryInterval(_u) => 0x02, + Property::ContentType(_u) => 0x03, + Property::ResponseTopic(_u) => 0x08, + Property::CorrelationData(_u) => 0x09, + Property::SubscriptionIdentifier(_u) => 0x0B, + Property::SessionExpiryInterval(_u) => 0x11, + Property::AssignedClientIdentifier(_u) => 0x12, + Property::ServerKeepAlive(_u) => 0x13, + Property::AuthenticationMethod(_u) => 0x15, + Property::AuthenticationData(_u) => 0x16, + Property::RequestProblemInformation(_u) => 0x17, + Property::WillDelayInterval(_u) => 0x18, + Property::RequestResponseInformation(_u) => 0x19, + Property::ResponseInformation(_u) => 0x1A, + Property::ServerReference(_u) => 0x1C, + Property::ReasonString(_u) => 0x1F, + Property::ReceiveMaximum(_u) => 0x21, + Property::TopicAliasMaximum(_u) => 0x22, + Property::TopicAlias(_u) => 0x23, + Property::MaximumQoS(_u) => 0x24, + Property::RetainAvailable(_u) => 0x25, + Property::UserProperty(_u) => 0x26, + Property::MaximumPacketSize(_u) => 0x27, + Property::WildcardSubscriptionAvailable(_u) => 0x28, + Property::SubscriptionIdentifierAvailable(_u) => 0x29, + Property::SharedSubscriptionAvailable(_u) => 0x2A, + _ => 0x00 + } + } +} + +impl From for Property<'a> { + fn from(_orig: u8) -> Self { + return match _orig { + _ => Property::Reserved(), + }; + } } \ No newline at end of file diff --git a/src/packet/puback_packet.rs b/src/packet/puback_packet.rs index f364ae6..c9ab5ae 100644 --- a/src/packet/puback_packet.rs +++ b/src/packet/puback_packet.rs @@ -1,12 +1,10 @@ -use super::property::Property; -use super::packet_type::PacketType; -use crate::utils::buffer_reader::BuffReader; -use crate::utils::buffer_reader::EncodedString; -use crate::utils::buffer_reader::BinaryData; -use crate::utils::buffer_reader::ParseError; -use crate::packet::mqtt_packet::Packet; use heapless::Vec; +use crate::packet::mqtt_packet::Packet; +use crate::utils::buffer_reader::BuffReader; + +use super::packet_type::PacketType; +use super::property::Property; pub const MAX_PROPERTIES: usize = 2; @@ -25,55 +23,42 @@ pub struct PubackPacket<'a> { pub properties: Vec, MAX_PROPERTIES>, } - impl<'a> PubackPacket<'a> { - - pub fn decode_properties(& mut self, buff_reader: & mut BuffReader<'a>) { - self.property_len = buff_reader.readVariableByteInt().unwrap(); - let mut x: u32 = 0; - let mut prop: Result; - loop { - let mut res: Property; - prop = Property::decode(buff_reader); - if let Ok(res) = prop { - log::info!("Parsed property {:?}", res); - x = x + res.len() as u32 + 1; - self.properties.push(res); - } else { - // error handlo - log::error!("Problem during property decoding"); - } - - if x == self.property_len { - break; - } - } - } - - pub fn decode_fixed_header(& mut self, buff_reader: & mut BuffReader) -> PacketType { - let first_byte: u8 = buff_reader.readU8().unwrap(); - self.fixed_header = first_byte; - self.remain_len = buff_reader.readVariableByteInt().unwrap(); - return PacketType::from(self.fixed_header); - } - - pub fn decode_puback_packet(& mut self, buff_reader: & mut BuffReader<'a>) { + pub fn decode_puback_packet(&mut self, buff_reader: &mut BuffReader<'a>) { if self.decode_fixed_header(buff_reader) != (PacketType::Puback).into() { log::error!("Packet you are trying to decode is not PUBACK packet!"); return; } - self.packet_identifier = buff_reader.readU16().unwrap(); - self.reason_code = buff_reader.readU8().unwrap(); + self.packet_identifier = buff_reader.read_u16().unwrap(); + self.reason_code = buff_reader.read_u8().unwrap(); self.decode_properties(buff_reader); } -} +} impl<'a> Packet<'a> for PubackPacket<'a> { - fn decode(& mut self, buff_reader: & mut BuffReader<'a>) { + fn encode(&mut self, buffer: &mut [u8]) {} + + fn decode(&mut self, buff_reader: &mut BuffReader<'a>) { self.decode_puback_packet(buff_reader); } - fn encode(& mut self, buffer: & mut [u8]) { - + fn set_property_len(&mut self, value: u32) { + self.property_len = value; } -} \ No newline at end of file + + fn get_property_len(&mut self) -> u32 { + return self.property_len; + } + + fn push_to_properties(&mut self, property: Property<'a>) { + self.properties.push(property); + } + + fn set_fixed_header(& mut self, header: u8) { + self.fixed_header = header; + } + + fn set_remaining_len(& mut self, remaining_len: u32) { + self.remain_len = remaining_len; + } +} diff --git a/src/packet/pubcomp_packet.rs b/src/packet/pubcomp_packet.rs index e70c0a3..c908770 100644 --- a/src/packet/pubcomp_packet.rs +++ b/src/packet/pubcomp_packet.rs @@ -1,12 +1,10 @@ -use super::property::Property; -use super::packet_type::PacketType; -use crate::utils::buffer_reader::BuffReader; -use crate::utils::buffer_reader::EncodedString; -use crate::utils::buffer_reader::BinaryData; -use crate::utils::buffer_reader::ParseError; -use crate::packet::mqtt_packet::Packet; use heapless::Vec; +use crate::packet::mqtt_packet::Packet; +use crate::utils::buffer_reader::BuffReader; + +use super::packet_type::PacketType; +use super::property::Property; pub const MAX_PROPERTIES: usize = 2; @@ -25,55 +23,43 @@ pub struct PubcompPacket<'a> { pub properties: Vec, MAX_PROPERTIES>, } - impl<'a> PubcompPacket<'a> { - pub fn decode_properties(& mut self, buff_reader: & mut BuffReader<'a>) { - self.property_len = buff_reader.readVariableByteInt().unwrap(); - let mut x: u32 = 0; - let mut prop: Result; - loop { - let mut res: Property; - prop = Property::decode(buff_reader); - if let Ok(res) = prop { - log::info!("Parsed property {:?}", res); - x = x + res.len() as u32 + 1; - self.properties.push(res); - } else { - // error handlo - log::error!("Problem during property decoding"); - } - - if x == self.property_len { - break; - } - } - } - - pub fn decode_fixed_header(& mut self, buff_reader: & mut BuffReader) -> PacketType { - let first_byte: u8 = buff_reader.readU8().unwrap(); - self.fixed_header = first_byte; - self.remain_len = buff_reader.readVariableByteInt().unwrap(); - return PacketType::from(self.fixed_header); - } - - pub fn decode_puback_packet(& mut self, buff_reader: & mut BuffReader<'a>) { + pub fn decode_puback_packet(&mut self, buff_reader: &mut BuffReader<'a>) { if self.decode_fixed_header(buff_reader) != (PacketType::Pubcomp).into() { log::error!("Packet you are trying to decode is not PUBCOMP packet!"); return; } - self.packet_identifier = buff_reader.readU16().unwrap(); - self.reason_code = buff_reader.readU8().unwrap(); + self.packet_identifier = buff_reader.read_u16().unwrap(); + self.reason_code = buff_reader.read_u8().unwrap(); self.decode_properties(buff_reader); } -} +} impl<'a> Packet<'a> for PubcompPacket<'a> { - fn decode(& mut self, buff_reader: & mut BuffReader<'a>) { + fn encode(&mut self, buffer: &mut [u8]) {} + + fn decode(&mut self, buff_reader: &mut BuffReader<'a>) { self.decode_puback_packet(buff_reader); } - fn encode(& mut self, buffer: & mut [u8]) { - + fn set_property_len(&mut self, value: u32) { + self.property_len = value; } -} \ No newline at end of file + + fn get_property_len(&mut self) -> u32 { + return self.property_len; + } + + fn push_to_properties(&mut self, property: Property<'a>) { + self.properties.push(property); + } + + fn set_fixed_header(& mut self, header: u8) { + self.fixed_header = header; + } + + fn set_remaining_len(& mut self, remaining_len: u32) { + self.remain_len = remaining_len; + } +} diff --git a/src/packet/publish_packet.rs b/src/packet/publish_packet.rs index 8c74d5e..c7ea25a 100644 --- a/src/packet/publish_packet.rs +++ b/src/packet/publish_packet.rs @@ -1,12 +1,11 @@ -use super::property::Property; -use super::packet_type::PacketType; -use crate::utils::buffer_reader::BuffReader; -use crate::utils::buffer_reader::EncodedString; -use crate::utils::buffer_reader::BinaryData; -use crate::utils::buffer_reader::ParseError; -use crate::packet::mqtt_packet::Packet; use heapless::Vec; +use crate::packet::mqtt_packet::Packet; +use crate::utils::buffer_reader::BuffReader; +use crate::utils::buffer_reader::EncodedString; + +use super::packet_type::PacketType; +use super::property::Property; pub const MAX_PROPERTIES: usize = 9; @@ -27,56 +26,43 @@ pub struct PublishPacket<'a> { pub message: &'a [u8], } - impl<'a> PublishPacket<'a> { - - pub fn decode_properties(& mut self, buff_reader: & mut BuffReader<'a>) { - self.property_len = buff_reader.readVariableByteInt().unwrap(); - let mut x: u32 = 0; - let mut prop: Result; - loop { - let mut res: Property; - prop = Property::decode(buff_reader); - if let Ok(res) = prop { - log::info!("Parsed property {:?}", res); - x = x + res.len() as u32 + 1; - self.properties.push(res); - } else { - // error handlo - log::error!("Problem during property decoding"); - } - - if x == self.property_len { - break; - } - } - } - - pub fn decode_fixed_header(& mut self, buff_reader: & mut BuffReader) -> PacketType { - let first_byte: u8 = buff_reader.readU8().unwrap(); - self.fixed_header = first_byte; - self.remain_len = buff_reader.readVariableByteInt().unwrap(); - return PacketType::from(self.fixed_header); - } - - pub fn decode_publish_packet(& mut self, buff_reader: & mut BuffReader<'a>) { + pub fn decode_publish_packet(&mut self, buff_reader: &mut BuffReader<'a>) { if self.decode_fixed_header(buff_reader) != (PacketType::Publish).into() { log::error!("Packet you are trying to decode is not PUBLISH packet!"); return; } - self.topic_name = buff_reader.readString().unwrap(); - self.packet_identifier = buff_reader.readU16().unwrap(); + self.topic_name = buff_reader.read_string().unwrap(); + self.packet_identifier = buff_reader.read_u16().unwrap(); self.decode_properties(buff_reader); - self.message = buff_reader.readMessage(); + self.message = buff_reader.read_message(); } -} +} impl<'a> Packet<'a> for PublishPacket<'a> { - fn decode(& mut self, buff_reader: & mut BuffReader<'a>) { + fn encode(&mut self, buffer: &mut [u8]) {} + + fn decode(&mut self, buff_reader: &mut BuffReader<'a>) { self.decode_publish_packet(buff_reader); } - fn encode(& mut self, buffer: & mut [u8]) { - + fn set_property_len(&mut self, value: u32) { + self.property_len = value; } -} \ No newline at end of file + + fn get_property_len(&mut self) -> u32 { + return self.property_len; + } + + fn push_to_properties(&mut self, property: Property<'a>) { + self.properties.push(property); + } + + fn set_fixed_header(& mut self, header: u8) { + self.fixed_header = header; + } + + fn set_remaining_len(& mut self, remaining_len: u32) { + self.remain_len = remaining_len; + } +} diff --git a/src/packet/pubrec_packet.rs b/src/packet/pubrec_packet.rs index 4d40601..bfa7885 100644 --- a/src/packet/pubrec_packet.rs +++ b/src/packet/pubrec_packet.rs @@ -1,12 +1,10 @@ -use super::property::Property; -use super::packet_type::PacketType; -use crate::utils::buffer_reader::BuffReader; -use crate::utils::buffer_reader::EncodedString; -use crate::utils::buffer_reader::BinaryData; -use crate::utils::buffer_reader::ParseError; -use crate::packet::mqtt_packet::Packet; use heapless::Vec; +use crate::packet::mqtt_packet::Packet; +use crate::utils::buffer_reader::BuffReader; + +use super::packet_type::PacketType; +use super::property::Property; pub const MAX_PROPERTIES: usize = 2; @@ -25,55 +23,42 @@ pub struct PubrecPacket<'a> { pub properties: Vec, MAX_PROPERTIES>, } - impl<'a> PubrecPacket<'a> { - pub fn decode_properties(& mut self, buff_reader: & mut BuffReader<'a>) { - self.property_len = buff_reader.readVariableByteInt().unwrap(); - let mut x: u32 = 0; - let mut prop: Result; - loop { - let mut res: Property; - prop = Property::decode(buff_reader); - if let Ok(res) = prop { - log::info!("Parsed property {:?}", res); - x = x + res.len() as u32 + 1; - self.properties.push(res); - } else { - // error handlo - log::error!("Problem during property decoding"); - } - - if x == self.property_len { - break; - } - } - } - - pub fn decode_fixed_header(& mut self, buff_reader: & mut BuffReader) -> PacketType { - let first_byte: u8 = buff_reader.readU8().unwrap(); - self.fixed_header = first_byte; - self.remain_len = buff_reader.readVariableByteInt().unwrap(); - return PacketType::from(self.fixed_header); - } - - pub fn decode_pubrec_packet(& mut self, buff_reader: & mut BuffReader<'a>) { + pub fn decode_pubrec_packet(&mut self, buff_reader: &mut BuffReader<'a>) { if self.decode_fixed_header(buff_reader) != (PacketType::Pubrec).into() { log::error!("Packet you are trying to decode is not PUBREC packet!"); return; } - self.packet_identifier = buff_reader.readU16().unwrap(); - self.reason_code = buff_reader.readU8().unwrap(); + self.packet_identifier = buff_reader.read_u16().unwrap(); + self.reason_code = buff_reader.read_u8().unwrap(); self.decode_properties(buff_reader); } -} +} impl<'a> Packet<'a> for PubrecPacket<'a> { - fn decode(& mut self, buff_reader: & mut BuffReader<'a>) { + fn encode(&mut self, buffer: &mut [u8]) {} + + fn decode(&mut self, buff_reader: &mut BuffReader<'a>) { self.decode_pubrec_packet(buff_reader); } - fn encode(& mut self, buffer: & mut [u8]) { - + fn set_property_len(&mut self, value: u32) { + self.property_len = value; } -} \ No newline at end of file + + fn get_property_len(&mut self) -> u32 { + return self.property_len; + } + + fn push_to_properties(&mut self, property: Property<'a>) { + self.properties.push(property); + } + fn set_fixed_header(& mut self, header: u8) { + self.fixed_header = header; + } + + fn set_remaining_len(& mut self, remaining_len: u32) { + self.remain_len = remaining_len; + } +} diff --git a/src/packet/pubrel_packet.rs b/src/packet/pubrel_packet.rs index 91f042f..a79c0b0 100644 --- a/src/packet/pubrel_packet.rs +++ b/src/packet/pubrel_packet.rs @@ -1,12 +1,10 @@ -use super::property::Property; -use super::packet_type::PacketType; -use crate::utils::buffer_reader::BuffReader; -use crate::utils::buffer_reader::EncodedString; -use crate::utils::buffer_reader::BinaryData; -use crate::utils::buffer_reader::ParseError; -use crate::packet::mqtt_packet::Packet; use heapless::Vec; +use crate::packet::mqtt_packet::Packet; +use crate::utils::buffer_reader::BuffReader; + +use super::packet_type::PacketType; +use super::property::Property; pub const MAX_PROPERTIES: usize = 2; @@ -25,55 +23,43 @@ pub struct PubrelPacket<'a> { pub properties: Vec, MAX_PROPERTIES>, } - impl<'a> PubrelPacket<'a> { - pub fn decode_properties(& mut self, buff_reader: & mut BuffReader<'a>) { - self.property_len = buff_reader.readVariableByteInt().unwrap(); - let mut x: u32 = 0; - let mut prop: Result; - loop { - let mut res: Property; - prop = Property::decode(buff_reader); - if let Ok(res) = prop { - log::info!("Parsed property {:?}", res); - x = x + res.len() as u32 + 1; - self.properties.push(res); - } else { - // error handlo - log::error!("Problem during property decoding"); - } - - if x == self.property_len { - break; - } - } - } - - pub fn decode_fixed_header(& mut self, buff_reader: & mut BuffReader) -> PacketType { - let first_byte: u8 = buff_reader.readU8().unwrap(); - self.fixed_header = first_byte; - self.remain_len = buff_reader.readVariableByteInt().unwrap(); - return PacketType::from(self.fixed_header); - } - - pub fn decode_puback_packet(& mut self, buff_reader: & mut BuffReader<'a>) { + pub fn decode_puback_packet(&mut self, buff_reader: &mut BuffReader<'a>) { if self.decode_fixed_header(buff_reader) != (PacketType::Pubrel).into() { log::error!("Packet you are trying to decode is not PUBREL packet!"); return; } - self.packet_identifier = buff_reader.readU16().unwrap(); - self.reason_code = buff_reader.readU8().unwrap(); + self.packet_identifier = buff_reader.read_u16().unwrap(); + self.reason_code = buff_reader.read_u8().unwrap(); self.decode_properties(buff_reader); } -} +} impl<'a> Packet<'a> for PubrelPacket<'a> { - fn decode(& mut self, buff_reader: & mut BuffReader<'a>) { + fn encode(&mut self, buffer: &mut [u8]) {} + + fn decode(&mut self, buff_reader: &mut BuffReader<'a>) { self.decode_puback_packet(buff_reader); } - fn encode(& mut self, buffer: & mut [u8]) { - + fn set_property_len(&mut self, value: u32) { + self.property_len = value; } -} \ No newline at end of file + + fn get_property_len(&mut self) -> u32 { + return self.property_len; + } + + fn push_to_properties(&mut self, property: Property<'a>) { + self.properties.push(property); + } + + fn set_fixed_header(& mut self, header: u8) { + self.fixed_header = header; + } + + fn set_remaining_len(& mut self, remaining_len: u32) { + self.remain_len = remaining_len; + } +} diff --git a/src/packet/suback_packet.rs b/src/packet/suback_packet.rs index 81ab6a0..c6a9a43 100644 --- a/src/packet/suback_packet.rs +++ b/src/packet/suback_packet.rs @@ -1,12 +1,10 @@ -use super::property::Property; -use super::packet_type::PacketType; -use crate::utils::buffer_reader::BuffReader; -use crate::utils::buffer_reader::EncodedString; -use crate::utils::buffer_reader::BinaryData; -use crate::utils::buffer_reader::ParseError; -use crate::packet::mqtt_packet::Packet; use heapless::Vec; +use crate::packet::mqtt_packet::Packet; +use crate::utils::buffer_reader::BuffReader; + +use super::packet_type::PacketType; +use super::property::Property; pub const MAX_PROPERTIES: usize = 2; @@ -26,42 +24,12 @@ pub struct SubackPacket<'a, const MAX_REASONS: usize> { pub reason_codes: Vec, } - impl<'a, const MAX_REASONS: usize> SubackPacket<'a, MAX_REASONS> { - pub fn decode_properties(& mut self, buff_reader: & mut BuffReader<'a>) { - self.property_len = buff_reader.readVariableByteInt().unwrap(); - let mut x: u32 = 0; - let mut prop: Result; - loop { - let mut res: Property; - prop = Property::decode(buff_reader); - if let Ok(res) = prop { - log::info!("Parsed property {:?}", res); - x = x + res.len() as u32 + 1; - self.properties.push(res); - } else { - // error handlo - log::error!("Problem during property decoding"); - } - - if x == self.property_len { - break; - } - } - } - - pub fn decode_fixed_header(& mut self, buff_reader: & mut BuffReader) -> PacketType { - let first_byte: u8 = buff_reader.readU8().unwrap(); - self.fixed_header = first_byte; - self.remain_len = buff_reader.readVariableByteInt().unwrap(); - return PacketType::from(self.fixed_header); - } - - pub fn read_reason_codes(& mut self, buff_reader: & mut BuffReader<'a>) { + pub fn read_reason_codes(&mut self, buff_reader: &mut BuffReader<'a>) { let mut i = 0; loop { - self.reason_codes.push(buff_reader.readU8().unwrap()); + self.reason_codes.push(buff_reader.read_u8().unwrap()); i = i + 1; if i == MAX_REASONS { break; @@ -69,23 +37,41 @@ impl<'a, const MAX_REASONS: usize> SubackPacket<'a, MAX_REASONS> { } } - pub fn decode_suback_packet(& mut self, buff_reader: & mut BuffReader<'a>) { + pub fn decode_suback_packet(&mut self, buff_reader: &mut BuffReader<'a>) { if self.decode_fixed_header(buff_reader) != (PacketType::Suback).into() { log::error!("Packet you are trying to decode is not SUBACK packet!"); return; } - self.packet_identifier = buff_reader.readU16().unwrap(); + self.packet_identifier = buff_reader.read_u16().unwrap(); self.decode_properties(buff_reader); self.read_reason_codes(buff_reader); } -} +} -impl<'a, const MAX_REASONS: usize> Packet<'a> for SubackPacket<'a, MAX_REASONS>{ - fn decode(& mut self, buff_reader: & mut BuffReader<'a>) { +impl<'a, const MAX_REASONS: usize> Packet<'a> for SubackPacket<'a, MAX_REASONS> { + fn encode(&mut self, buffer: &mut [u8]) {} + + fn decode(&mut self, buff_reader: &mut BuffReader<'a>) { self.decode_suback_packet(buff_reader); } - fn encode(& mut self, buffer: & mut [u8]) { - + fn set_property_len(&mut self, value: u32) { + self.property_len = value; } -} \ No newline at end of file + + fn get_property_len(&mut self) -> u32 { + return self.property_len; + } + + fn push_to_properties(&mut self, property: Property<'a>) { + self.properties.push(property); + } + + fn set_fixed_header(& mut self, header: u8) { + self.fixed_header = header; + } + + fn set_remaining_len(& mut self, remaining_len: u32) { + self.remain_len = remaining_len; + } +} diff --git a/src/packet/subscription_packet.rs b/src/packet/subscription_packet.rs index 3d8cad9..44855bf 100644 --- a/src/packet/subscription_packet.rs +++ b/src/packet/subscription_packet.rs @@ -1,18 +1,15 @@ -use super::property::Property; -use super::packet_type::PacketType; -use crate::utils::buffer_reader::BuffReader; -use crate::utils::buffer_reader::EncodedString; -use crate::utils::buffer_reader::BinaryData; -use crate::utils::buffer_reader::ParseError; -use crate::packet::mqtt_packet::Packet; -use crate::utils::buffer_reader::TopicFilter; use heapless::Vec; +use crate::packet::mqtt_packet::Packet; +use crate::utils::buffer_reader::BuffReader; +use crate::utils::buffer_reader::TopicFilter; + +use super::packet_type::PacketType; +use super::property::Property; pub const MAX_PROPERTIES: usize = 2; pub struct SubscriptionPacket<'a, const MAX_FILTERS: usize> { - pub maximal_filters: u8, // 7 - 4 mqtt control packet type, 3-0 flagy pub fixed_header: u8, // 1 - 4 B lenght of variable header + len of payload @@ -32,19 +29,35 @@ pub struct SubscriptionPacket<'a, const MAX_FILTERS: usize> { pub topic_filters: Vec, MAX_FILTERS>, } - impl<'a, const MAX_FILTERS: usize> SubscriptionPacket<'a, MAX_FILTERS> { /*pub fn new() -> Self { - + }*/ -} +} impl<'a, const MAX_FILTERS: usize> Packet<'a> for SubscriptionPacket<'a, MAX_FILTERS> { - fn decode(& mut self, buff_reader: & mut BuffReader<'a>) { + fn encode(&mut self, buffer: &mut [u8]) {} + + fn decode(&mut self, buff_reader: &mut BuffReader<'a>) { log::error!("Subscribe packet does not support decode funtion on client!"); } - - fn encode(& mut self, buffer: & mut [u8]) { - + fn set_property_len(&mut self, value: u32) { + self.property_len = value; } -} \ No newline at end of file + + fn get_property_len(&mut self) -> u32 { + return self.property_len; + } + + fn push_to_properties(&mut self, property: Property<'a>) { + self.properties.push(property); + } + + fn set_fixed_header(& mut self, header: u8) { + self.fixed_header = header; + } + + fn set_remaining_len(& mut self, remaining_len: u32) { + self.remain_len = remaining_len; + } +} diff --git a/src/packet/unsuback_packet.rs b/src/packet/unsuback_packet.rs index b8fadaf..3719b11 100644 --- a/src/packet/unsuback_packet.rs +++ b/src/packet/unsuback_packet.rs @@ -1,12 +1,10 @@ -use super::property::Property; -use super::packet_type::PacketType; -use crate::utils::buffer_reader::BuffReader; -use crate::utils::buffer_reader::EncodedString; -use crate::utils::buffer_reader::BinaryData; -use crate::utils::buffer_reader::ParseError; -use crate::packet::mqtt_packet::Packet; use heapless::Vec; +use crate::packet::mqtt_packet::Packet; +use crate::utils::buffer_reader::BuffReader; + +use super::packet_type::PacketType; +use super::property::Property; pub const MAX_PROPERTIES: usize = 20; @@ -26,42 +24,12 @@ pub struct UnsubackPacket<'a, const MAX_REASONS: usize> { pub reason_codes: Vec, } - impl<'a, const MAX_REASONS: usize> UnsubackPacket<'a, MAX_REASONS> { - pub fn decode_properties(& mut self, buff_reader: & mut BuffReader<'a>) { - self.property_len = buff_reader.readVariableByteInt().unwrap(); - let mut x: u32 = 0; - let mut prop: Result; - loop { - let mut res: Property; - prop = Property::decode(buff_reader); - if let Ok(res) = prop { - log::info!("Parsed property {:?}", res); - x = x + res.len() as u32 + 1; - self.properties.push(res); - } else { - // error handlo - log::error!("Problem during property decoding"); - } - - if x == self.property_len { - break; - } - } - } - - pub fn decode_fixed_header(& mut self, buff_reader: & mut BuffReader) -> PacketType { - let first_byte: u8 = buff_reader.readU8().unwrap(); - self.fixed_header = first_byte; - self.remain_len = buff_reader.readVariableByteInt().unwrap(); - return PacketType::from(self.fixed_header); - } - - pub fn read_reason_codes(& mut self, buff_reader: & mut BuffReader<'a>) { + pub fn read_reason_codes(&mut self, buff_reader: &mut BuffReader<'a>) { let mut i = 0; loop { - self.reason_codes.push(buff_reader.readU8().unwrap()); + self.reason_codes.push(buff_reader.read_u8().unwrap()); i = i + 1; if i == MAX_REASONS { break; @@ -69,23 +37,41 @@ impl<'a, const MAX_REASONS: usize> UnsubackPacket<'a, MAX_REASONS> { } } - pub fn decode_suback_packet(& mut self, buff_reader: & mut BuffReader<'a>) { + pub fn decode_suback_packet(&mut self, buff_reader: &mut BuffReader<'a>) { if self.decode_fixed_header(buff_reader) != (PacketType::Suback).into() { - log::error!("Packet you are trying to decode is not SUBACK packet!"); + log::error!("Packet you are trying to decode is not UNSUBACK packet!"); return; } - self.packet_identifier = buff_reader.readU16().unwrap(); + self.packet_identifier = buff_reader.read_u16().unwrap(); self.decode_properties(buff_reader); self.read_reason_codes(buff_reader); } -} +} -impl<'a, const MAX_REASONS: usize> Packet<'a> for UnsubackPacket<'a, MAX_REASONS>{ - fn decode(& mut self, buff_reader: & mut BuffReader<'a>) { +impl<'a, const MAX_REASONS: usize> Packet<'a> for UnsubackPacket<'a, MAX_REASONS> { + fn encode(&mut self, buffer: &mut [u8]) {} + + fn decode(&mut self, buff_reader: &mut BuffReader<'a>) { self.decode_suback_packet(buff_reader); } - fn encode(& mut self, buffer: & mut [u8]) { - + fn set_property_len(&mut self, value: u32) { + self.property_len = value; } -} \ No newline at end of file + + fn get_property_len(&mut self) -> u32 { + return self.property_len; + } + + fn push_to_properties(&mut self, property: Property<'a>) { + self.properties.push(property); + } + + fn set_fixed_header(& mut self, header: u8) { + self.fixed_header = header; + } + + fn set_remaining_len(& mut self, remaining_len: u32) { + self.remain_len = remaining_len; + } +} diff --git a/src/packet/unsubscription_packet.rs b/src/packet/unsubscription_packet.rs index e9736f6..92b6962 100644 --- a/src/packet/unsubscription_packet.rs +++ b/src/packet/unsubscription_packet.rs @@ -1,13 +1,11 @@ -use super::property::Property; -use super::packet_type::PacketType; -use crate::utils::buffer_reader::BuffReader; -use crate::utils::buffer_reader::EncodedString; -use crate::utils::buffer_reader::BinaryData; -use crate::utils::buffer_reader::ParseError; -use crate::packet::mqtt_packet::Packet; -use crate::utils::buffer_reader::TopicFilter; use heapless::Vec; +use crate::packet::mqtt_packet::Packet; +use crate::utils::buffer_reader::BuffReader; +use crate::utils::buffer_reader::TopicFilter; + +use super::packet_type::PacketType; +use super::property::Property; pub const MAX_PROPERTIES: usize = 20; @@ -31,19 +29,36 @@ pub struct UnsubscriptionPacket<'a, const MAX_FILTERS: usize> { pub topic_filters: Vec, MAX_FILTERS>, } - impl<'a, const MAX_FILTERS: usize> UnsubscriptionPacket<'a, MAX_FILTERS> { /*pub fn new() -> Self { - + }*/ -} +} impl<'a, const MAX_FILTERS: usize> Packet<'a> for UnsubscriptionPacket<'a, MAX_FILTERS> { - fn decode(& mut self, buff_reader: & mut BuffReader<'a>) { + fn encode(&mut self, buffer: &mut [u8]) {} + + fn decode(&mut self, buff_reader: &mut BuffReader<'a>) { log::error!("Unsubscribe packet does not support decode funtion on client!"); } - fn encode(& mut self, buffer: & mut [u8]) { - + fn set_property_len(&mut self, value: u32) { + self.property_len = value; } -} \ No newline at end of file + + fn get_property_len(&mut self) -> u32 { + return self.property_len; + } + + fn push_to_properties(&mut self, property: Property<'a>) { + self.properties.push(property); + } + + fn set_fixed_header(& mut self, header: u8) { + self.fixed_header = header; + } + + fn set_remaining_len(& mut self, remaining_len: u32) { + self.remain_len = remaining_len; + } +} diff --git a/src/utils/buffer_reader.rs b/src/utils/buffer_reader.rs index f707d93..19d49f0 100644 --- a/src/utils/buffer_reader.rs +++ b/src/utils/buffer_reader.rs @@ -1,6 +1,7 @@ -use crate::encoding::variable_byte_integer::VariableByteIntegerDecoder; -use core::str; use core::mem; +use core::str; + +use crate::encoding::variable_byte_integer::VariableByteIntegerDecoder; #[derive(Debug)] pub struct EncodedString<'a> { @@ -21,7 +22,7 @@ impl EncodedString<'_> { #[derive(Debug)] pub struct BinaryData<'a> { pub bin: &'a [u8], - pub len: u16 + pub len: u16, } impl BinaryData<'_> { @@ -37,7 +38,7 @@ impl BinaryData<'_> { #[derive(Debug)] pub struct StringPair<'a> { pub name: EncodedString<'a>, - pub value: EncodedString<'a> + pub value: EncodedString<'a>, } impl StringPair<'_> { @@ -56,7 +57,11 @@ pub struct TopicFilter<'a> { impl TopicFilter<'_> { pub fn new() -> Self { - Self { len: 0, filter: EncodedString::new(), sub_options: 0 } + Self { + len: 0, + filter: EncodedString::new(), + sub_options: 0, + } } pub fn len(&self) -> u16 { @@ -64,15 +69,14 @@ impl TopicFilter<'_> { } } -#[derive(core::fmt::Debug)] -#[derive(Clone)] +#[derive(core::fmt::Debug, Clone)] pub enum ParseError { Utf8Error, IndexOutOfBounce, VariableByteIntegerError, IdNotFound, EncodingError, - DecodingError + DecodingError, } pub struct BuffReader<'a> { @@ -81,94 +85,112 @@ pub struct BuffReader<'a> { } impl<'a> BuffReader<'a> { - pub fn incrementPosition(& mut self, increment: usize) { + pub fn increment_position(&mut self, increment: usize) { self.position = self.position + increment; } pub fn new(buffer: &'a [u8]) -> Self { - return BuffReader { buffer: buffer, position: 0 }; + return BuffReader { + buffer: buffer, + position: 0, + }; } - pub fn readVariableByteInt(& mut self) -> Result { - let variable_byte_integer: [u8; 4] = [self.buffer[self.position], self.buffer[self.position + 1], self.buffer[self.position + 2], self.buffer[self.position + 3]]; + pub fn read_variable_byte_int(&mut self) -> Result { + let variable_byte_integer: [u8; 4] = [ + self.buffer[self.position], + self.buffer[self.position + 1], + self.buffer[self.position + 2], + self.buffer[self.position + 3], + ]; let mut len: usize = 1; - if variable_byte_integer[0] & 0x80 == 1 { - len = len + 1; - if variable_byte_integer[1] & 0x80 == 1 { - len = len + 1; - if variable_byte_integer[2] & 0x80 == 1 { - len = len + 1; + if variable_byte_integer[0] & 0x80 == 1 { + len = len + 1; + if variable_byte_integer[1] & 0x80 == 1 { + len = len + 1; + if variable_byte_integer[2] & 0x80 == 1 { + len = len + 1; } } } - self.incrementPosition(len); + self.increment_position(len); return VariableByteIntegerDecoder::decode(variable_byte_integer); } - - pub fn readU32(& mut self) -> Result { + + pub fn read_u32(&mut self) -> Result { let (int_bytes, rest) = self.buffer[self.position..].split_at(mem::size_of::()); let ret: u32 = u32::from_be_bytes(int_bytes.try_into().unwrap()); //let ret: u32 = (((self.buffer[self.position] as u32) << 24) | ((self.buffer[self.position + 1] as u32) << 16) | ((self.buffer[self.position + 2] as u32) << 8) | (self.buffer[self.position + 3] as u32)) as u32; - self.incrementPosition(4); + self.increment_position(4); return Ok(ret); } - - pub fn readU16(& mut self) -> Result { + + pub fn read_u16(&mut self) -> Result { let (int_bytes, rest) = self.buffer[self.position..].split_at(mem::size_of::()); - let ret: u16 = u16::from_be_bytes(int_bytes.try_into().unwrap()); + let ret: u16 = u16::from_be_bytes(int_bytes.try_into().unwrap()); //(((self.buffer[self.position] as u16) << 8) | (self.buffer[self.position + 1] as u16)) as u16; - self.incrementPosition(2); + self.increment_position(2); return Ok(ret); } - - pub fn readU8(& mut self) -> Result { + + pub fn read_u8(&mut self) -> Result { let ret: u8 = self.buffer[self.position]; - self.incrementPosition(1); + self.increment_position(1); return Ok(ret); } - - pub fn readString(& mut self) -> Result, ParseError> { - let len = self.readU16(); + + pub fn read_string(&mut self) -> Result, ParseError> { + let len = self.read_u16(); match len { Err(err) => return Err(err), - _ => log::debug!("[parseString] let not parsed") + _ => log::debug!("[parseString] let not parsed"), } let len_res = len.unwrap(); - let res_str = str::from_utf8(&(self.buffer[self.position..(self.position + len_res as usize)])); + let res_str = + str::from_utf8(&(self.buffer[self.position..(self.position + len_res as usize)])); if res_str.is_err() { log::error!("Could not parse utf-8 string"); return Err(ParseError::Utf8Error); } - return Ok(EncodedString { string: res_str.unwrap(), len: len_res }); + return Ok(EncodedString { + string: res_str.unwrap(), + len: len_res, + }); } - + //TODO: Index out of bounce err !!!!! - pub fn readBinary(& mut self) -> Result, ParseError> { - let len = self.readU16(); + pub fn read_binary(&mut self) -> Result, ParseError> { + let len = self.read_u16(); match len { Err(err) => return Err(err), - _ => log::debug!("[parseBinary] let not parsed") + _ => log::debug!("[parseBinary] let not parsed"), } let len_res = len.unwrap(); let res_bin = &(self.buffer[self.position..(self.position + len_res as usize)]); - return Ok(BinaryData { bin: res_bin, len: len_res }); - } - - pub fn readStringPair(& mut self) -> Result, ParseError> { - let name = self.readString(); - match name { - Err(err) => return Err(err), - _ => log::debug!("[String pair] name not parsed") - } - let value = self.readString(); - match value { - Err(err) => return Err(err), - _ => log::debug!("[String pair] value not parsed") - } - return Ok(StringPair { name: name.unwrap(), value: value.unwrap() }); + return Ok(BinaryData { + bin: res_bin, + len: len_res, + }); } - pub fn readMessage(& mut self) -> &'a [u8] { + pub fn read_string_pair(&mut self) -> Result, ParseError> { + let name = self.read_string(); + match name { + Err(err) => return Err(err), + _ => log::debug!("[String pair] name not parsed"), + } + let value = self.read_string(); + match value { + Err(err) => return Err(err), + _ => log::debug!("[String pair] value not parsed"), + } + return Ok(StringPair { + name: name.unwrap(), + value: value.unwrap(), + }); + } + + pub fn read_message(&mut self) -> &'a [u8] { return &self.buffer[self.position..]; } -} \ No newline at end of file +} diff --git a/src/utils/buffer_writer.rs b/src/utils/buffer_writer.rs new file mode 100644 index 0000000..c68bcac --- /dev/null +++ b/src/utils/buffer_writer.rs @@ -0,0 +1,119 @@ +use crate::utils::buffer_reader::{BinaryData, EncodedString, StringPair}; +use core::str; +use heapless::Vec; +use crate::encoding::variable_byte_integer::{VariableByteInteger, VariableByteIntegerEncoder}; +use crate::packet::property::Property; + +pub struct BuffWriter<'a> { + buffer: &'a mut [u8], + pub position: usize, +} + +impl<'a> BuffWriter<'a> { + + pub fn insert(& mut self, array: [u8; LEN]) { + let mut x: usize = 0; + loop { + self.buffer[self.position] = array[x]; + self.increment_position(1); + x = x + 1; + if x == LEN { + break; + } + } + } + + pub fn insert_ref(& mut self, len: usize, array: &[u8]) { + let mut x: usize = 0; + loop { + self.buffer[self.position] = array[x]; + self.increment_position(1); + x = x + 1; + if x == len { + break; + } + } + } + + pub fn new(buffer: &'a mut [u8]) -> Self { + return BuffWriter { + buffer, + position: 0, + }; + } + + fn increment_position(& mut self, increment: usize) { + self.position = self.position + increment; + } + + pub fn write_u8(& mut self, byte: u8) { + self.buffer[self.position] = byte; + self.increment_position(1); + } + + pub fn write_u16(& mut self, two_bytes: u16) { + let bytes: [u8; 2] = two_bytes.to_be_bytes(); + self.insert::<2>(bytes); + } + + pub fn write_u32(& mut self, four_bytes: u32) { + let bytes: [u8; 4] = four_bytes.to_be_bytes(); + self.insert::<4>(bytes); + } + + pub fn write_string_ref(& mut self, str: & EncodedString<'a>) { + self.write_u16(str.len); + let bytes = str.string.as_bytes(); + self.insert_ref(str.len as usize, bytes); + } + + pub fn write_string(& mut self, str: EncodedString<'a>) { + self.write_u16(str.len); + let bytes = str.string.as_bytes(); + self.insert_ref(str.len as usize, bytes); + } + + pub fn write_binary_ref(& mut self, bin: & BinaryData<'a>) { + self.write_u16(bin.len); + self.insert_ref(bin.len as usize, bin.bin); + } + + pub fn write_binary(& mut self, bin: BinaryData<'a>) { + self.write_u16(bin.len); + self.insert_ref(bin.len as usize, bin.bin); + } + + pub fn write_string_pair_ref(& mut self, str_pair: & StringPair<'a>) { + self.write_string_ref(&str_pair.name); + self.write_string_ref(&str_pair.value); + } + + pub fn write_string_pair(& mut self, str_pair: StringPair<'a>) { + self.write_string(str_pair.name); + self.write_string(str_pair.value); + } + + pub fn write_variable_byte_int(& mut self, int: u32) { + let x: VariableByteInteger = VariableByteIntegerEncoder::encode(int).unwrap(); + let len = VariableByteIntegerEncoder::len(x); + self.insert_ref(len, &x); + } + + pub fn encode_property(& mut self, property: & Property<'a>) { + let x: u8 = property.into(); + self.write_u8(x); + property.encode(self); + } + + pub fn encode_properties(& mut self, properties: & Vec, LEN>) { + let mut i = 0; + loop { + let prop: &Property = properties.get(i).unwrap(); + self.encode_property(prop); + i = i + 1; + if i == LEN { + break; + } + } + } +} \ No newline at end of file diff --git a/src/utils/mod.rs b/src/utils/mod.rs index fbf6310..7f6b1dc 100644 --- a/src/utils/mod.rs +++ b/src/utils/mod.rs @@ -1 +1,2 @@ -pub mod buffer_reader; \ No newline at end of file +pub mod buffer_reader; +pub mod buffer_writer; From 7218cb2a06913454bb22ec43d0589e10ae17a0c3 Mon Sep 17 00:00:00 2001 From: Ondrej Babec Date: Sun, 20 Feb 2022 14:18:31 +0100 Subject: [PATCH 3/7] Encoding --- src/packet/auth_packet.rs | 6 ++---- src/packet/connack_packet.rs | 16 +++++++++++++++- src/packet/disconnect_packet.rs | 15 ++++++++++++++- src/packet/mod.rs | 9 +++++---- src/packet/pingreq_packet.rs | 7 ++++++- src/packet/pingresp_packet.rs | 7 ++++++- src/packet/puback_packet.rs | 18 +++++++++++++++++- src/packet/pubcomp_packet.rs | 18 +++++++++++++++++- src/packet/publish_packet.rs | 20 +++++++++++++++++++- src/packet/pubrec_packet.rs | 18 +++++++++++++++++- src/packet/pubrel_packet.rs | 18 +++++++++++++++++- src/packet/suback_packet.rs | 6 +++++- src/packet/subscription_packet.rs | 21 +++++++++++++++++++-- src/packet/unsuback_packet.rs | 4 +++- src/packet/unsubscription_packet.rs | 21 +++++++++++++++++++-- src/utils/buffer_reader.rs | 4 +--- src/utils/buffer_writer.rs | 20 +++++++++++++++++++- 17 files changed, 201 insertions(+), 27 deletions(-) diff --git a/src/packet/auth_packet.rs b/src/packet/auth_packet.rs index b3d417f..3176b31 100644 --- a/src/packet/auth_packet.rs +++ b/src/packet/auth_packet.rs @@ -58,13 +58,11 @@ impl<'a, const MAX_PROPERTIES: usize> Packet<'a> for AuthPacket<'a, MAX_PROPERTI let property_len_len = VariableByteIntegerEncoder::len(property_len_enc); rm_ln = rm_ln + property_len_len as u32; rm_ln = rm_ln + 1; - let rm_len_enc: [u8; 4] = VariableByteIntegerEncoder::encode(rm_ln).unwrap(); - let rm_len_len = VariableByteIntegerEncoder::len(rm_len_enc); buff_writer.write_u8(self.fixed_header); - buff_writer.insert_ref(rm_len_len, &rm_len_enc); + buff_writer.write_variable_byte_int(rm_ln); buff_writer.write_u8(self.auth_reason); - buff_writer.insert_ref(property_len_len, &property_len_enc); + buff_writer.write_variable_byte_int(self.property_len); buff_writer.encode_properties::(&self.properties); } diff --git a/src/packet/connack_packet.rs b/src/packet/connack_packet.rs index f82ddbf..8ab6191 100644 --- a/src/packet/connack_packet.rs +++ b/src/packet/connack_packet.rs @@ -1,7 +1,9 @@ use heapless::Vec; +use crate::encoding::variable_byte_integer::VariableByteIntegerEncoder; use crate::packet::mqtt_packet::Packet; use crate::utils::buffer_reader::BuffReader; +use crate::utils::buffer_writer::BuffWriter; use super::packet_type::PacketType; use super::property::Property; @@ -32,7 +34,19 @@ impl<'a> ConnackPacket<'a> { } impl<'a> Packet<'a> for ConnackPacket<'a> { - fn encode(&mut self, buffer: &mut [u8]) {} + fn encode(&mut self, buffer: &mut [u8]) { + let mut buff_writer = BuffWriter::new(buffer); + buff_writer.write_u8(self.fixed_header); + let mut property_len_enc = VariableByteIntegerEncoder::encode(self.property_len).unwrap(); + let property_len_len = VariableByteIntegerEncoder::len(property_len_enc); + + let rm_len: u32 = 2 + self.property_len + property_len_len as u32; + buff_writer.write_variable_byte_int(rm_len); + buff_writer.write_u8(self.ack_flags); + buff_writer.write_u8(self.connect_reason_code); + buff_writer.write_variable_byte_int(self.property_len); + buff_writer.encode_properties(&self.properties); + } fn decode(&mut self, buff_reader: &mut BuffReader<'a>) { self.decode_connack_packet(buff_reader); } diff --git a/src/packet/disconnect_packet.rs b/src/packet/disconnect_packet.rs index df07b52..f6a4f5b 100644 --- a/src/packet/disconnect_packet.rs +++ b/src/packet/disconnect_packet.rs @@ -1,7 +1,9 @@ use heapless::Vec; +use crate::encoding::variable_byte_integer::VariableByteIntegerEncoder; use crate::packet::mqtt_packet::Packet; use crate::utils::buffer_reader::BuffReader; +use crate::utils::buffer_writer::BuffWriter; use super::packet_type::PacketType; use super::property::Property; @@ -31,7 +33,18 @@ impl<'a, const MAX_PROPERTIES: usize> DisconnectPacket<'a, MAX_PROPERTIES> { } impl<'a, const MAX_PROPERTIES: usize> Packet<'a> for DisconnectPacket<'a, MAX_PROPERTIES> { - fn encode(&mut self, buffer: &mut [u8]) {} + fn encode(&mut self, buffer: &mut [u8]) { + let mut buff_writer = BuffWriter::new(buffer); + buff_writer.write_u8(self.fixed_header); + let mut property_len_enc = VariableByteIntegerEncoder::encode(self.property_len).unwrap(); + let property_len_len = VariableByteIntegerEncoder::len(property_len_enc); + + let rm_len: u32 = 1 + self.property_len + property_len_len as u32; + buff_writer.write_variable_byte_int(rm_len); + buff_writer.write_u8(self.disconnect_reason); + buff_writer.write_variable_byte_int(self.property_len); + buff_writer.encode_properties(&self.properties); + } fn decode(&mut self, buff_reader: &mut BuffReader<'a>) { self.decode_auth_packet(buff_reader); diff --git a/src/packet/mod.rs b/src/packet/mod.rs index 7208f60..0a7ede3 100644 --- a/src/packet/mod.rs +++ b/src/packet/mod.rs @@ -1,10 +1,11 @@ -/*pub mod connack_packet; -pub mod control_packet;*/ + +//pub mod control_packet; pub mod mqtt_packet; pub mod packet_type; pub mod property; pub mod auth_packet; -/*pub mod puback_packet; +pub mod connack_packet; +pub mod puback_packet; pub mod pubcomp_packet; pub mod publish_packet; pub mod pubrec_packet; @@ -17,4 +18,4 @@ pub mod disconnect_packet; pub mod pingreq_packet; pub mod pingresp_packet; pub mod suback_packet; -pub mod unsuback_packet;*/ +pub mod unsuback_packet; diff --git a/src/packet/pingreq_packet.rs b/src/packet/pingreq_packet.rs index b2f81dc..78a34ee 100644 --- a/src/packet/pingreq_packet.rs +++ b/src/packet/pingreq_packet.rs @@ -1,5 +1,6 @@ use crate::packet::mqtt_packet::Packet; use crate::utils::buffer_reader::BuffReader; +use crate::utils::buffer_writer::BuffWriter; use super::packet_type::PacketType; use super::property::Property; @@ -16,7 +17,11 @@ pub struct PingreqPacket { impl PingreqPacket {} impl<'a> Packet<'a> for PingreqPacket { - fn encode(&mut self, buffer: &mut [u8]) {} + fn encode(&mut self, buffer: &mut [u8]) { + let mut buff_writer = BuffWriter::new(buffer); + buff_writer.write_u8(self.fixed_header); + buff_writer.write_variable_byte_int(0 as u32); + } fn decode(&mut self, buff_reader: &mut BuffReader<'a>) { log::error!("PingreqPacket packet does not support decode funtion on client!"); diff --git a/src/packet/pingresp_packet.rs b/src/packet/pingresp_packet.rs index ec64e37..1f57323 100644 --- a/src/packet/pingresp_packet.rs +++ b/src/packet/pingresp_packet.rs @@ -1,5 +1,6 @@ use crate::packet::mqtt_packet::Packet; use crate::utils::buffer_reader::BuffReader; +use crate::utils::buffer_writer::BuffWriter; use super::packet_type::PacketType; use super::property::Property; @@ -21,7 +22,11 @@ impl<'a> PingrespPacket { } impl<'a> Packet<'a> for PingrespPacket { - fn encode(&mut self, buffer: &mut [u8]) {} + fn encode(&mut self, buffer: &mut [u8]) { + let mut buff_writer = BuffWriter::new(buffer); + buff_writer.write_u8(self.fixed_header); + buff_writer.write_variable_byte_int(0 as u32); + } fn decode(&mut self, buff_reader: &mut BuffReader<'a>) { self.decode_pingresp_packet(buff_reader); diff --git a/src/packet/puback_packet.rs b/src/packet/puback_packet.rs index c9ab5ae..9683b8a 100644 --- a/src/packet/puback_packet.rs +++ b/src/packet/puback_packet.rs @@ -1,7 +1,9 @@ use heapless::Vec; +use crate::encoding::variable_byte_integer::VariableByteIntegerEncoder; use crate::packet::mqtt_packet::Packet; use crate::utils::buffer_reader::BuffReader; +use crate::utils::buffer_writer::BuffWriter; use super::packet_type::PacketType; use super::property::Property; @@ -36,7 +38,21 @@ impl<'a> PubackPacket<'a> { } impl<'a> Packet<'a> for PubackPacket<'a> { - fn encode(&mut self, buffer: &mut [u8]) {} + fn encode(&mut self, buffer: &mut [u8]) { + let mut buff_writer = BuffWriter::new(buffer); + + let mut rm_ln = self.property_len; + let property_len_enc: [u8; 4] = VariableByteIntegerEncoder::encode(self.property_len).unwrap(); + let property_len_len = VariableByteIntegerEncoder::len(property_len_enc); + rm_ln = rm_ln + property_len_len as u32 + 3; + + buff_writer.write_u8(self.fixed_header); + buff_writer.write_variable_byte_int(rm_ln); + buff_writer.write_u16(self.packet_identifier); + buff_writer.write_u8(self.reason_code); + buff_writer.write_variable_byte_int(self.property_len); + buff_writer.encode_properties::(&self.properties); + } fn decode(&mut self, buff_reader: &mut BuffReader<'a>) { self.decode_puback_packet(buff_reader); diff --git a/src/packet/pubcomp_packet.rs b/src/packet/pubcomp_packet.rs index c908770..864befe 100644 --- a/src/packet/pubcomp_packet.rs +++ b/src/packet/pubcomp_packet.rs @@ -1,7 +1,9 @@ use heapless::Vec; +use crate::encoding::variable_byte_integer::VariableByteIntegerEncoder; use crate::packet::mqtt_packet::Packet; use crate::utils::buffer_reader::BuffReader; +use crate::utils::buffer_writer::BuffWriter; use super::packet_type::PacketType; use super::property::Property; @@ -37,7 +39,21 @@ impl<'a> PubcompPacket<'a> { } impl<'a> Packet<'a> for PubcompPacket<'a> { - fn encode(&mut self, buffer: &mut [u8]) {} + fn encode(&mut self, buffer: &mut [u8]) { + let mut buff_writer = BuffWriter::new(buffer); + + let mut rm_ln = self.property_len; + let property_len_enc: [u8; 4] = VariableByteIntegerEncoder::encode(self.property_len).unwrap(); + let property_len_len = VariableByteIntegerEncoder::len(property_len_enc); + rm_ln = rm_ln + property_len_len as u32 + 3; + + buff_writer.write_u8(self.fixed_header); + buff_writer.write_variable_byte_int(rm_ln); + buff_writer.write_u16(self.packet_identifier); + buff_writer.write_u8(self.reason_code); + buff_writer.write_variable_byte_int(self.property_len); + buff_writer.encode_properties::(&self.properties); + } fn decode(&mut self, buff_reader: &mut BuffReader<'a>) { self.decode_puback_packet(buff_reader); diff --git a/src/packet/publish_packet.rs b/src/packet/publish_packet.rs index c7ea25a..b71ed03 100644 --- a/src/packet/publish_packet.rs +++ b/src/packet/publish_packet.rs @@ -1,8 +1,10 @@ use heapless::Vec; +use crate::encoding::variable_byte_integer::VariableByteIntegerEncoder; use crate::packet::mqtt_packet::Packet; use crate::utils::buffer_reader::BuffReader; use crate::utils::buffer_reader::EncodedString; +use crate::utils::buffer_writer::BuffWriter; use super::packet_type::PacketType; use super::property::Property; @@ -40,7 +42,23 @@ impl<'a> PublishPacket<'a> { } impl<'a> Packet<'a> for PublishPacket<'a> { - fn encode(&mut self, buffer: &mut [u8]) {} + fn encode(&mut self, buffer: &mut [u8]) { + let mut buff_writer = BuffWriter::new(buffer); + + let mut rm_ln = self.property_len; + let property_len_enc: [u8; 4] = VariableByteIntegerEncoder::encode(self.property_len).unwrap(); + let property_len_len = VariableByteIntegerEncoder::len(property_len_enc); + let mut msg_len = self.message.len() as u32; + rm_ln = rm_ln + property_len_len as u32 + 2 + msg_len + self.topic_name.len as u32 + 2; + + buff_writer.write_u8(self.fixed_header); + buff_writer.write_variable_byte_int(rm_ln); + buff_writer.write_string_ref(& self.topic_name); + buff_writer.write_u16(self.packet_identifier); + buff_writer.write_variable_byte_int(self.property_len); + buff_writer.encode_properties::(&self.properties); + buff_writer.insert_ref(msg_len as usize, self.message) + } fn decode(&mut self, buff_reader: &mut BuffReader<'a>) { self.decode_publish_packet(buff_reader); diff --git a/src/packet/pubrec_packet.rs b/src/packet/pubrec_packet.rs index bfa7885..43cb52c 100644 --- a/src/packet/pubrec_packet.rs +++ b/src/packet/pubrec_packet.rs @@ -1,7 +1,9 @@ use heapless::Vec; +use crate::encoding::variable_byte_integer::VariableByteIntegerEncoder; use crate::packet::mqtt_packet::Packet; use crate::utils::buffer_reader::BuffReader; +use crate::utils::buffer_writer::BuffWriter; use super::packet_type::PacketType; use super::property::Property; @@ -37,7 +39,21 @@ impl<'a> PubrecPacket<'a> { } impl<'a> Packet<'a> for PubrecPacket<'a> { - fn encode(&mut self, buffer: &mut [u8]) {} + fn encode(&mut self, buffer: &mut [u8]) { + let mut buff_writer = BuffWriter::new(buffer); + + let mut rm_ln = self.property_len; + let property_len_enc: [u8; 4] = VariableByteIntegerEncoder::encode(self.property_len).unwrap(); + let property_len_len = VariableByteIntegerEncoder::len(property_len_enc); + rm_ln = rm_ln + property_len_len as u32 + 3; + + buff_writer.write_u8(self.fixed_header); + buff_writer.write_variable_byte_int(rm_ln); + buff_writer.write_u16(self.packet_identifier); + buff_writer.write_u8(self.reason_code); + buff_writer.write_variable_byte_int(self.property_len); + buff_writer.encode_properties::(&self.properties); + } fn decode(&mut self, buff_reader: &mut BuffReader<'a>) { self.decode_pubrec_packet(buff_reader); diff --git a/src/packet/pubrel_packet.rs b/src/packet/pubrel_packet.rs index a79c0b0..10569c4 100644 --- a/src/packet/pubrel_packet.rs +++ b/src/packet/pubrel_packet.rs @@ -1,7 +1,9 @@ use heapless::Vec; +use crate::encoding::variable_byte_integer::VariableByteIntegerEncoder; use crate::packet::mqtt_packet::Packet; use crate::utils::buffer_reader::BuffReader; +use crate::utils::buffer_writer::BuffWriter; use super::packet_type::PacketType; use super::property::Property; @@ -37,7 +39,21 @@ impl<'a> PubrelPacket<'a> { } impl<'a> Packet<'a> for PubrelPacket<'a> { - fn encode(&mut self, buffer: &mut [u8]) {} + fn encode(&mut self, buffer: &mut [u8]) { + let mut buff_writer = BuffWriter::new(buffer); + + let mut rm_ln = self.property_len; + let property_len_enc: [u8; 4] = VariableByteIntegerEncoder::encode(self.property_len).unwrap(); + let property_len_len = VariableByteIntegerEncoder::len(property_len_enc); + rm_ln = rm_ln + property_len_len as u32 + 3; + + buff_writer.write_u8(self.fixed_header); + buff_writer.write_variable_byte_int(rm_ln); + buff_writer.write_u16(self.packet_identifier); + buff_writer.write_u8(self.reason_code); + buff_writer.write_variable_byte_int(self.property_len); + buff_writer.encode_properties::(&self.properties); + } fn decode(&mut self, buff_reader: &mut BuffReader<'a>) { self.decode_puback_packet(buff_reader); diff --git a/src/packet/suback_packet.rs b/src/packet/suback_packet.rs index c6a9a43..6b12aa4 100644 --- a/src/packet/suback_packet.rs +++ b/src/packet/suback_packet.rs @@ -1,7 +1,9 @@ use heapless::Vec; +use crate::encoding::variable_byte_integer::VariableByteIntegerEncoder; use crate::packet::mqtt_packet::Packet; use crate::utils::buffer_reader::BuffReader; +use crate::utils::buffer_writer::BuffWriter; use super::packet_type::PacketType; use super::property::Property; @@ -49,7 +51,9 @@ impl<'a, const MAX_REASONS: usize> SubackPacket<'a, MAX_REASONS> { } impl<'a, const MAX_REASONS: usize> Packet<'a> for SubackPacket<'a, MAX_REASONS> { - fn encode(&mut self, buffer: &mut [u8]) {} + fn encode(&mut self, buffer: &mut [u8]) { + log::error!("SUBACK packet does not support encoding!"); + } fn decode(&mut self, buff_reader: &mut BuffReader<'a>) { self.decode_suback_packet(buff_reader); diff --git a/src/packet/subscription_packet.rs b/src/packet/subscription_packet.rs index 44855bf..eb15677 100644 --- a/src/packet/subscription_packet.rs +++ b/src/packet/subscription_packet.rs @@ -1,8 +1,10 @@ use heapless::Vec; +use crate::encoding::variable_byte_integer::VariableByteIntegerEncoder; use crate::packet::mqtt_packet::Packet; use crate::utils::buffer_reader::BuffReader; use crate::utils::buffer_reader::TopicFilter; +use crate::utils::buffer_writer::BuffWriter; use super::packet_type::PacketType; use super::property::Property; @@ -23,7 +25,7 @@ pub struct SubscriptionPacket<'a, const MAX_FILTERS: usize> { pub properties: Vec, MAX_PROPERTIES>, // topic filter len - pub topic_filter_let: u16, + pub topic_filter_len: u16, // payload pub topic_filters: Vec, MAX_FILTERS>, @@ -36,7 +38,22 @@ impl<'a, const MAX_FILTERS: usize> SubscriptionPacket<'a, MAX_FILTERS> { } impl<'a, const MAX_FILTERS: usize> Packet<'a> for SubscriptionPacket<'a, MAX_FILTERS> { - fn encode(&mut self, buffer: &mut [u8]) {} + fn encode(&mut self, buffer: &mut [u8]) { + let mut buff_writer = BuffWriter::new(buffer); + + let mut rm_ln = self.property_len; + let property_len_enc: [u8; 4] = VariableByteIntegerEncoder::encode(self.property_len).unwrap(); + let property_len_len = VariableByteIntegerEncoder::len(property_len_enc); + rm_ln = rm_ln + property_len_len as u32 + 4 + self.topic_filter_len as u32; + + buff_writer.write_u8(self.fixed_header); + buff_writer.write_variable_byte_int(rm_ln); + buff_writer.write_u16(self.packet_identifier); + buff_writer.write_variable_byte_int(self.property_len); + buff_writer.encode_properties::(&self.properties); + buff_writer.write_u16(self.topic_filter_len); + buff_writer.encode_topic_filters_ref(false, self.topic_filter_len as usize, & self.topic_filters); + } fn decode(&mut self, buff_reader: &mut BuffReader<'a>) { log::error!("Subscribe packet does not support decode funtion on client!"); diff --git a/src/packet/unsuback_packet.rs b/src/packet/unsuback_packet.rs index 3719b11..291d808 100644 --- a/src/packet/unsuback_packet.rs +++ b/src/packet/unsuback_packet.rs @@ -49,7 +49,9 @@ impl<'a, const MAX_REASONS: usize> UnsubackPacket<'a, MAX_REASONS> { } impl<'a, const MAX_REASONS: usize> Packet<'a> for UnsubackPacket<'a, MAX_REASONS> { - fn encode(&mut self, buffer: &mut [u8]) {} + fn encode(&mut self, buffer: &mut [u8]) { + log::error!("UNSUBACK packet does not support encoding!"); + } fn decode(&mut self, buff_reader: &mut BuffReader<'a>) { self.decode_suback_packet(buff_reader); diff --git a/src/packet/unsubscription_packet.rs b/src/packet/unsubscription_packet.rs index 92b6962..9fbd81f 100644 --- a/src/packet/unsubscription_packet.rs +++ b/src/packet/unsubscription_packet.rs @@ -1,8 +1,10 @@ use heapless::Vec; +use crate::encoding::variable_byte_integer::VariableByteIntegerEncoder; use crate::packet::mqtt_packet::Packet; use crate::utils::buffer_reader::BuffReader; use crate::utils::buffer_reader::TopicFilter; +use crate::utils::buffer_writer::BuffWriter; use super::packet_type::PacketType; use super::property::Property; @@ -23,7 +25,7 @@ pub struct UnsubscriptionPacket<'a, const MAX_FILTERS: usize> { pub properties: Vec, MAX_PROPERTIES>, // topic filter len - pub topic_filter_let: u16, + pub topic_filter_len: u16, // payload pub topic_filters: Vec, MAX_FILTERS>, @@ -36,7 +38,22 @@ impl<'a, const MAX_FILTERS: usize> UnsubscriptionPacket<'a, MAX_FILTERS> { } impl<'a, const MAX_FILTERS: usize> Packet<'a> for UnsubscriptionPacket<'a, MAX_FILTERS> { - fn encode(&mut self, buffer: &mut [u8]) {} + fn encode(&mut self, buffer: &mut [u8]) { + let mut buff_writer = BuffWriter::new(buffer); + + let mut rm_ln = self.property_len; + let property_len_enc: [u8; 4] = VariableByteIntegerEncoder::encode(self.property_len).unwrap(); + let property_len_len = VariableByteIntegerEncoder::len(property_len_enc); + rm_ln = rm_ln + property_len_len as u32 + 4 + self.topic_filter_len as u32; + + buff_writer.write_u8(self.fixed_header); + buff_writer.write_variable_byte_int(rm_ln); + buff_writer.write_u16(self.packet_identifier); + buff_writer.write_variable_byte_int(self.property_len); + buff_writer.encode_properties::(&self.properties); + buff_writer.write_u16(self.topic_filter_len); + buff_writer.encode_topic_filters_ref(false, self.topic_filter_len as usize, & self.topic_filters); + } fn decode(&mut self, buff_reader: &mut BuffReader<'a>) { log::error!("Unsubscribe packet does not support decode funtion on client!"); diff --git a/src/utils/buffer_reader.rs b/src/utils/buffer_reader.rs index 19d49f0..0b8c272 100644 --- a/src/utils/buffer_reader.rs +++ b/src/utils/buffer_reader.rs @@ -50,7 +50,6 @@ impl StringPair<'_> { #[derive(Debug)] pub struct TopicFilter<'a> { - pub len: u16, pub filter: EncodedString<'a>, pub sub_options: u8, } @@ -58,14 +57,13 @@ pub struct TopicFilter<'a> { impl TopicFilter<'_> { pub fn new() -> Self { Self { - len: 0, filter: EncodedString::new(), sub_options: 0, } } pub fn len(&self) -> u16 { - return self.len + 2; + return self.filter.len + 3; } } diff --git a/src/utils/buffer_writer.rs b/src/utils/buffer_writer.rs index c68bcac..ed6abb1 100644 --- a/src/utils/buffer_writer.rs +++ b/src/utils/buffer_writer.rs @@ -1,4 +1,4 @@ -use crate::utils::buffer_reader::{BinaryData, EncodedString, StringPair}; +use crate::utils::buffer_reader::{BinaryData, EncodedString, StringPair, TopicFilter}; use core::str; use heapless::Vec; use crate::encoding::variable_byte_integer::{VariableByteInteger, VariableByteIntegerEncoder}; @@ -116,4 +116,22 @@ impl<'a> BuffWriter<'a> { } } } + + fn encode_topic_filter_ref(& mut self, sub: bool, topic_filter: & TopicFilter<'a>) { + self.write_string_ref(&topic_filter.filter); + if sub { + self.write_u8(topic_filter.sub_options) + } + } + + pub fn encode_topic_filters_ref(& mut self, sub: bool, len: usize, filters: & Vec, MAX>) { + let mut i = 0; + loop { + let topic_filter: & TopicFilter<'a> = filters.get(i).unwrap(); + self.encode_topic_filter_ref(sub, topic_filter); + if i == len { + break; + } + } + } } \ No newline at end of file From 6f0d2d5de449ce235d094b0da84368952c05f75c Mon Sep 17 00:00:00 2001 From: Ondrej Babec Date: Sun, 20 Feb 2022 15:49:34 +0100 Subject: [PATCH 4/7] Fixed failures --- src/encoding/variable_byte_integer.rs | 4 ++-- src/main.rs | 13 +++++++++++-- src/packet/packet_type.rs | 2 +- src/packet/subscription_packet.rs | 25 ++++++++++++++++++++----- src/utils/buffer_writer.rs | 15 +++++++++------ 5 files changed, 43 insertions(+), 16 deletions(-) diff --git a/src/encoding/variable_byte_integer.rs b/src/encoding/variable_byte_integer.rs index 2964375..c0904fb 100644 --- a/src/encoding/variable_byte_integer.rs +++ b/src/encoding/variable_byte_integer.rs @@ -54,11 +54,11 @@ impl VariableByteIntegerEncoder { loop { let mut encoded_byte: u8; encoded_byte = var_int[i]; - + i = i + 1; if (encoded_byte & 128) == 0 { break; } - i = i + 1; + } return i; } diff --git a/src/main.rs b/src/main.rs index dd0bc92..c332a7f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,12 +4,21 @@ use rust_mqtt::packet::property::*;*/ use std::fs::File; use std::io::Read;*/ +use rust_mqtt::packet::mqtt_packet::Packet; +use rust_mqtt::packet::subscription_packet::SubscriptionPacket; + fn main() { env_logger::builder() .filter_level(log::LevelFilter::Info) .format_timestamp_nanos() .init(); - + + let mut pckt: SubscriptionPacket<1> = SubscriptionPacket::new(); + let mut res = vec![0; 14]; + pckt.encode(&mut res); + println!("{:02X?}", res); + log::info!("xxx"); + /*let fl = File::open("/Users/obabec/development/school/rust-mqtt/mqtt_control_example.bin"); let mut f = File::open("/Users/obabec/development/school/rust-mqtt/mqtt_control_example.bin").expect("no file found"); @@ -17,7 +26,7 @@ fn main() { f.read(&mut buffer).expect("buffer overflow"); - //let mut txt = Vec::new(); + // let mut payld = *b"xxxxx";*/ //let packet = Packet::clean(txt, &mut payld); /*let mut buffer_reader = BuffReader::new(&buffer); diff --git a/src/packet/packet_type.rs b/src/packet/packet_type.rs index 7502580..679a4a3 100644 --- a/src/packet/packet_type.rs +++ b/src/packet/packet_type.rs @@ -55,7 +55,7 @@ impl Into for PacketType { PacketType::Pubrec => 0x50, PacketType::Pubrel => 0x60, PacketType::Pubcomp => 0x70, - PacketType::Subscribe => 0x80, + PacketType::Subscribe => 0x82, PacketType::Suback => 0x90, PacketType::Unsubscribe => 0xA0, PacketType::Unsuback => 0xB0, diff --git a/src/packet/subscription_packet.rs b/src/packet/subscription_packet.rs index eb15677..af3c610 100644 --- a/src/packet/subscription_packet.rs +++ b/src/packet/subscription_packet.rs @@ -32,9 +32,15 @@ pub struct SubscriptionPacket<'a, const MAX_FILTERS: usize> { } impl<'a, const MAX_FILTERS: usize> SubscriptionPacket<'a, MAX_FILTERS> { - /*pub fn new() -> Self { - - }*/ + pub fn new() -> Self { + let mut x = Self { fixed_header: PacketType::Subscribe.into(), remain_len: 0, packet_identifier: 1, + property_len: 0, properties: Vec::, MAX_PROPERTIES>::new(), topic_filter_len: 1, topic_filters: Vec::, MAX_FILTERS>::new() }; + let mut p = TopicFilter::new(); + p.filter.len = 6; + p.filter.string = "test/#"; + x.topic_filters.push(p); + return x; + } } impl<'a, const MAX_FILTERS: usize> Packet<'a> for SubscriptionPacket<'a, MAX_FILTERS> { @@ -44,14 +50,23 @@ impl<'a, const MAX_FILTERS: usize> Packet<'a> for SubscriptionPacket<'a, MAX_FIL let mut rm_ln = self.property_len; let property_len_enc: [u8; 4] = VariableByteIntegerEncoder::encode(self.property_len).unwrap(); let property_len_len = VariableByteIntegerEncoder::len(property_len_enc); - rm_ln = rm_ln + property_len_len as u32 + 4 + self.topic_filter_len as u32; + + let mut lt = 0; + let mut filters_len = 0; + loop { + filters_len = filters_len + self.topic_filters.get(lt).unwrap().filter.len + 3; + lt = lt + 1; + if lt == self.topic_filter_len as usize { + break; + } + } + rm_ln = rm_ln + property_len_len as u32 + 2 + filters_len as u32; buff_writer.write_u8(self.fixed_header); buff_writer.write_variable_byte_int(rm_ln); buff_writer.write_u16(self.packet_identifier); buff_writer.write_variable_byte_int(self.property_len); buff_writer.encode_properties::(&self.properties); - buff_writer.write_u16(self.topic_filter_len); buff_writer.encode_topic_filters_ref(false, self.topic_filter_len as usize, & self.topic_filters); } diff --git a/src/utils/buffer_writer.rs b/src/utils/buffer_writer.rs index ed6abb1..f148044 100644 --- a/src/utils/buffer_writer.rs +++ b/src/utils/buffer_writer.rs @@ -107,12 +107,14 @@ impl<'a> BuffWriter<'a> { pub fn encode_properties(& mut self, properties: & Vec, LEN>) { let mut i = 0; - loop { - let prop: &Property = properties.get(i).unwrap(); - self.encode_property(prop); - i = i + 1; - if i == LEN { - break; + if properties.len() != 0 { + loop { + let prop: &Property = properties.get(i).unwrap(); + self.encode_property(prop); + i = i + 1; + if i == LEN { + break; + } } } } @@ -129,6 +131,7 @@ impl<'a> BuffWriter<'a> { loop { let topic_filter: & TopicFilter<'a> = filters.get(i).unwrap(); self.encode_topic_filter_ref(sub, topic_filter); + i = i + 1; if i == len { break; } From 963040026a00afb3302eb28563361e90bea86039 Mon Sep 17 00:00:00 2001 From: Ondrej Babec Date: Mon, 21 Feb 2022 15:08:56 +0100 Subject: [PATCH 5/7] Complete encode --- src/main.rs | 19 ++- src/packet/auth_packet.rs | 3 +- src/packet/connack_packet.rs | 3 +- .../{control_packet.rs => connect_packet.rs} | 152 +++++++++--------- src/packet/disconnect_packet.rs | 3 +- src/packet/mod.rs | 1 + src/packet/mqtt_packet.rs | 2 +- src/packet/pingreq_packet.rs | 3 +- src/packet/pingresp_packet.rs | 3 +- src/packet/puback_packet.rs | 3 +- src/packet/pubcomp_packet.rs | 3 +- src/packet/publish_packet.rs | 32 +++- src/packet/pubrec_packet.rs | 3 +- src/packet/pubrel_packet.rs | 3 +- src/packet/suback_packet.rs | 3 +- src/packet/subscription_packet.rs | 3 +- src/packet/unsuback_packet.rs | 3 +- src/packet/unsubscription_packet.rs | 3 +- src/utils/buffer_writer.rs | 33 ++-- 19 files changed, 162 insertions(+), 116 deletions(-) rename src/packet/{control_packet.rs => connect_packet.rs} (53%) diff --git a/src/main.rs b/src/main.rs index c332a7f..553faef 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,7 +4,9 @@ use rust_mqtt::packet::property::*;*/ use std::fs::File; use std::io::Read;*/ +use rust_mqtt::packet::connect_packet::ConnectPacket; use rust_mqtt::packet::mqtt_packet::Packet; +use rust_mqtt::packet::publish_packet::PublishPacket; use rust_mqtt::packet::subscription_packet::SubscriptionPacket; fn main() { @@ -14,9 +16,20 @@ fn main() { .init(); let mut pckt: SubscriptionPacket<1> = SubscriptionPacket::new(); - let mut res = vec![0; 14]; - pckt.encode(&mut res); - println!("{:02X?}", res); + let mut res = vec![0; 140]; + let lnsub = pckt.encode(&mut res); + println!("{:02X?}", &res[0..lnsub]); + let mut res2 = vec![0; 260]; + let mut x = b"hello world"; + let mut pblsh: PublishPacket = PublishPacket::new(x); + let lnpblsh = pblsh.encode(&mut res2); + println!("{:02X?}", &res2[0..lnpblsh]); + log::info!("xxx"); + + let mut res3 = vec![0; 260]; + let mut cntrl = ConnectPacket::<3, 0>::clean(); + let lncntrl = cntrl.encode(&mut res3); + println!("{:02X?}", &res3[0..lncntrl]); log::info!("xxx"); /*let fl = File::open("/Users/obabec/development/school/rust-mqtt/mqtt_control_example.bin"); diff --git a/src/packet/auth_packet.rs b/src/packet/auth_packet.rs index 3176b31..78b1742 100644 --- a/src/packet/auth_packet.rs +++ b/src/packet/auth_packet.rs @@ -50,7 +50,7 @@ impl<'a, const MAX_PROPERTIES: usize> Packet<'a> for AuthPacket<'a, MAX_PROPERTI return AuthPacket { fixed_header: PacketType::Auth.into(), remain_len: 0, auth_reason: 0, property_len: 0, properties: Vec::, MAX_PROPERTIES>::new() } }*/ - fn encode(&mut self, buffer: & mut [u8]) { + fn encode(&mut self, buffer: & mut [u8]) -> usize { let mut buff_writer = BuffWriter::new(buffer); let mut rm_ln = self.property_len; @@ -64,6 +64,7 @@ impl<'a, const MAX_PROPERTIES: usize> Packet<'a> for AuthPacket<'a, MAX_PROPERTI buff_writer.write_u8(self.auth_reason); buff_writer.write_variable_byte_int(self.property_len); buff_writer.encode_properties::(&self.properties); + return buff_writer.position; } fn decode(&mut self, buff_reader: &mut BuffReader<'a>) { diff --git a/src/packet/connack_packet.rs b/src/packet/connack_packet.rs index 8ab6191..9ddfabd 100644 --- a/src/packet/connack_packet.rs +++ b/src/packet/connack_packet.rs @@ -34,7 +34,7 @@ impl<'a> ConnackPacket<'a> { } impl<'a> Packet<'a> for ConnackPacket<'a> { - fn encode(&mut self, buffer: &mut [u8]) { + fn encode(&mut self, buffer: &mut [u8]) -> usize { let mut buff_writer = BuffWriter::new(buffer); buff_writer.write_u8(self.fixed_header); let mut property_len_enc = VariableByteIntegerEncoder::encode(self.property_len).unwrap(); @@ -46,6 +46,7 @@ impl<'a> Packet<'a> for ConnackPacket<'a> { buff_writer.write_u8(self.connect_reason_code); buff_writer.write_variable_byte_int(self.property_len); buff_writer.encode_properties(&self.properties); + return buff_writer.position; } fn decode(&mut self, buff_reader: &mut BuffReader<'a>) { self.decode_connack_packet(buff_reader); diff --git a/src/packet/control_packet.rs b/src/packet/connect_packet.rs similarity index 53% rename from src/packet/control_packet.rs rename to src/packet/connect_packet.rs index 783e121..336e1e3 100644 --- a/src/packet/control_packet.rs +++ b/src/packet/connect_packet.rs @@ -1,26 +1,21 @@ use heapless::Vec; +use crate::encoding::variable_byte_integer::VariableByteIntegerEncoder; use crate::packet::mqtt_packet::Packet; use crate::utils::buffer_reader::BinaryData; use crate::utils::buffer_reader::BuffReader; use crate::utils::buffer_reader::EncodedString; use crate::utils::buffer_reader::ParseError; +use crate::utils::buffer_writer::BuffWriter; use super::packet_type::PacketType; use super::property::Property; -pub const MAX_PROPERTIES: usize = 18; -pub const MAX_WILL_PROPERTIES: usize = 7; - -pub struct ControlPacket<'a> { +pub struct ConnectPacket<'a, const MAX_PROPERTIES: usize, const MAX_WILL_PROPERTIES: usize> { // 7 - 4 mqtt control packet type, 3-0 flagy pub fixed_header: u8, // 1 - 4 B lenght of variable header + len of payload pub remain_len: u32, - - // variable header - //optional prida se pouze u packetu ve kterych ma co delat - pub packet_identifier: u16, pub protocol_name_len: u16, pub protocol_name: u32, pub protocol_version: u8, @@ -43,30 +38,31 @@ pub struct ControlPacket<'a> { pub password: BinaryData<'a>, } -impl<'a> ControlPacket<'a> { - pub fn clean( - properties: Vec, MAX_PROPERTIES>, - will_properties: Vec, MAX_WILL_PROPERTIES>, - ) -> Self { - Self { - fixed_header: 0x00, +impl<'a, const MAX_PROPERTIES: usize, const MAX_WILL_PROPERTIES: usize> ConnectPacket<'a, MAX_PROPERTIES, MAX_WILL_PROPERTIES> { + pub fn clean() -> Self { + let mut x = Self { + fixed_header: PacketType::Connect.into(), remain_len: 0, - packet_identifier: 0, - protocol_name_len: 0, - protocol_name: 0, + protocol_name_len: 4, + protocol_name: 0x4d515454, protocol_version: 5, - connect_flags: 0, - keep_alive: 0, - property_len: 0, - properties, + connect_flags: 0x02, + keep_alive: 60, + property_len: 3, + properties: Vec::, MAX_PROPERTIES>::new(), client_id: EncodedString::new(), will_property_len: 0, - will_properties, + will_properties: Vec::, MAX_WILL_PROPERTIES>::new(), will_topic: EncodedString::new(), will_payload: BinaryData::new(), username: EncodedString::new(), password: BinaryData::new(), - } + }; + + let y = Property::ReceiveMaximum(20); + x.properties.push(y); + x.client_id.len = 0; + return x; } pub fn get_reason_code(&self) { @@ -99,67 +95,63 @@ impl<'a> ControlPacket<'a> { } self.fixed_header = cur_type | flags; } - - pub fn decode_will_properties(&mut self, buff_reader: &mut BuffReader<'a>) { - //todo: need to check if we are parsing only will properties - let will_property_len = buff_reader.read_variable_byte_int().unwrap(); - let mut x: u32 = 0; - let mut prop: Result; - loop { - let mut res: Property; - prop = Property::decode(buff_reader); - if let Ok(res) = prop { - log::info!("Will property parsed: {:?}", res); - x = x + res.len() as u32 + 1; - self.will_properties.push(res); - } else { - // error handlo - log::error!("Problem during property decoding"); - } - - if x == will_property_len { - break; - } - } - } - - pub fn decode_payload(&mut self, buff_reader: &mut BuffReader<'a>) { - self.client_id = buff_reader.read_string().unwrap(); - if self.connect_flags & (1 << 2) == 1 { - self.decode_will_properties(buff_reader); - self.will_topic = buff_reader.read_string().unwrap(); - self.will_payload = buff_reader.read_binary().unwrap(); - } - - if self.connect_flags & (1 << 7) == 1 { - self.username = buff_reader.read_string().unwrap(); - } - if self.connect_flags & (1 << 6) == 1 { - self.password = buff_reader.read_binary().unwrap(); - } - } - - pub fn decode_control_packet(&mut self, buff_reader: &mut BuffReader<'a>) { - if self.decode_fixed_header(buff_reader) != (PacketType::Connect).into() { - log::error!("Packet you are trying to decode is not CONNECT packet!"); - } - self.packet_identifier = 0; - self.protocol_name_len = buff_reader.read_u16().unwrap(); - self.protocol_name = buff_reader.read_u32().unwrap(); - self.protocol_version = buff_reader.read_u8().unwrap(); - self.connect_flags = buff_reader.read_u8().unwrap(); - self.keep_alive = buff_reader.read_u16().unwrap(); - self.decode_properties(buff_reader); - self.decode_payload(buff_reader); - } } +impl<'a, const MAX_PROPERTIES: usize, const MAX_WILL_PROPERTIES: usize> Packet<'a> for ConnectPacket<'a, MAX_PROPERTIES, MAX_WILL_PROPERTIES> { + fn encode(&mut self, buffer: &mut [u8]) -> usize { + let mut buff_writer = BuffWriter::new(buffer); -impl<'a> Packet<'a> for ControlPacket<'a> { - fn encode(&mut self, buffer: &mut [u8]) {} + let mut rm_ln = self.property_len; + let property_len_enc: [u8; 4] = VariableByteIntegerEncoder::encode(self.property_len).unwrap(); + let property_len_len = VariableByteIntegerEncoder::len(property_len_enc); + // 12 = protocol_name_len + protocol_name + protocol_version + connect_flags + keep_alive + client_id_len + rm_ln = rm_ln + property_len_len as u32 + 12; + + if self.connect_flags & 0x04 == 1 { + let wil_prop_len_enc = VariableByteIntegerEncoder::encode(self.will_property_len).unwrap(); + let wil_prop_len_len = VariableByteIntegerEncoder::len(wil_prop_len_enc); + rm_ln = rm_ln + wil_prop_len_len as u32 + self.will_property_len as u32 + self.will_topic.len as u32 + self.will_payload.len as u32; + } + + if self.connect_flags & 0x80 == 1 { + rm_ln = rm_ln + self.username.len as u32; + } + + if self.connect_flags & 0x40 == 1 { + rm_ln = rm_ln + self.password.len as u32; + } + + buff_writer.write_u8(self.fixed_header); + buff_writer.write_variable_byte_int(rm_ln); + + buff_writer.write_u16(self.protocol_name_len); + buff_writer.write_u32(self.protocol_name); + buff_writer.write_u8(self.protocol_version); + buff_writer.write_u8(self.connect_flags); + buff_writer.write_u16(self.keep_alive); + buff_writer.write_variable_byte_int(self.property_len); + buff_writer.encode_properties::(&self.properties); + buff_writer.write_string_ref(&self.client_id); + + if self.connect_flags & 0x04 == 1 { + buff_writer.write_variable_byte_int(self.will_property_len); + buff_writer.encode_properties(& self.will_properties); + buff_writer.write_string_ref(& self.will_topic); + buff_writer.write_binary_ref(& self.will_payload); + } + + if self.connect_flags & 0x80 == 1 { + buff_writer.write_string_ref(& self.username); + } + + if self.connect_flags & 0x40 == 1 { + buff_writer.write_binary_ref(& self.password); + } + + return buff_writer.position; + } fn decode(&mut self, buff_reader: &mut BuffReader<'a>) { log::error!("Decode function is not available for control packet!") - //self.decode_control_packet(buff_reader); } fn set_property_len(&mut self, value: u32) { diff --git a/src/packet/disconnect_packet.rs b/src/packet/disconnect_packet.rs index f6a4f5b..52fc2b3 100644 --- a/src/packet/disconnect_packet.rs +++ b/src/packet/disconnect_packet.rs @@ -33,7 +33,7 @@ impl<'a, const MAX_PROPERTIES: usize> DisconnectPacket<'a, MAX_PROPERTIES> { } impl<'a, const MAX_PROPERTIES: usize> Packet<'a> for DisconnectPacket<'a, MAX_PROPERTIES> { - fn encode(&mut self, buffer: &mut [u8]) { + fn encode(&mut self, buffer: &mut [u8]) -> usize { let mut buff_writer = BuffWriter::new(buffer); buff_writer.write_u8(self.fixed_header); let mut property_len_enc = VariableByteIntegerEncoder::encode(self.property_len).unwrap(); @@ -44,6 +44,7 @@ impl<'a, const MAX_PROPERTIES: usize> Packet<'a> for DisconnectPacket<'a, MAX_PR buff_writer.write_u8(self.disconnect_reason); buff_writer.write_variable_byte_int(self.property_len); buff_writer.encode_properties(&self.properties); + return buff_writer.position; } fn decode(&mut self, buff_reader: &mut BuffReader<'a>) { diff --git a/src/packet/mod.rs b/src/packet/mod.rs index 0a7ede3..3d0f275 100644 --- a/src/packet/mod.rs +++ b/src/packet/mod.rs @@ -19,3 +19,4 @@ pub mod pingreq_packet; pub mod pingresp_packet; pub mod suback_packet; pub mod unsuback_packet; +pub mod connect_packet; diff --git a/src/packet/mqtt_packet.rs b/src/packet/mqtt_packet.rs index ca4a837..ad5e6c0 100644 --- a/src/packet/mqtt_packet.rs +++ b/src/packet/mqtt_packet.rs @@ -7,7 +7,7 @@ use super::property::Property; pub trait Packet<'a> { //fn new() -> dyn Packet<'a> where Self: Sized; - fn encode(&mut self, buffer: &mut [u8]); + fn encode(&mut self, buffer: &mut [u8]) -> usize; fn decode(&mut self, buff_reader: &mut BuffReader<'a>); // properties diff --git a/src/packet/pingreq_packet.rs b/src/packet/pingreq_packet.rs index 78a34ee..b13de06 100644 --- a/src/packet/pingreq_packet.rs +++ b/src/packet/pingreq_packet.rs @@ -17,10 +17,11 @@ pub struct PingreqPacket { impl PingreqPacket {} impl<'a> Packet<'a> for PingreqPacket { - fn encode(&mut self, buffer: &mut [u8]) { + fn encode(&mut self, buffer: &mut [u8]) -> usize { let mut buff_writer = BuffWriter::new(buffer); buff_writer.write_u8(self.fixed_header); buff_writer.write_variable_byte_int(0 as u32); + return buff_writer.position; } fn decode(&mut self, buff_reader: &mut BuffReader<'a>) { diff --git a/src/packet/pingresp_packet.rs b/src/packet/pingresp_packet.rs index 1f57323..58de28d 100644 --- a/src/packet/pingresp_packet.rs +++ b/src/packet/pingresp_packet.rs @@ -22,10 +22,11 @@ impl<'a> PingrespPacket { } impl<'a> Packet<'a> for PingrespPacket { - fn encode(&mut self, buffer: &mut [u8]) { + fn encode(&mut self, buffer: &mut [u8]) -> usize { let mut buff_writer = BuffWriter::new(buffer); buff_writer.write_u8(self.fixed_header); buff_writer.write_variable_byte_int(0 as u32); + return buff_writer.position; } fn decode(&mut self, buff_reader: &mut BuffReader<'a>) { diff --git a/src/packet/puback_packet.rs b/src/packet/puback_packet.rs index 9683b8a..bf85c41 100644 --- a/src/packet/puback_packet.rs +++ b/src/packet/puback_packet.rs @@ -38,7 +38,7 @@ impl<'a> PubackPacket<'a> { } impl<'a> Packet<'a> for PubackPacket<'a> { - fn encode(&mut self, buffer: &mut [u8]) { + fn encode(&mut self, buffer: &mut [u8]) -> usize { let mut buff_writer = BuffWriter::new(buffer); let mut rm_ln = self.property_len; @@ -52,6 +52,7 @@ impl<'a> Packet<'a> for PubackPacket<'a> { buff_writer.write_u8(self.reason_code); buff_writer.write_variable_byte_int(self.property_len); buff_writer.encode_properties::(&self.properties); + return buff_writer.position; } fn decode(&mut self, buff_reader: &mut BuffReader<'a>) { diff --git a/src/packet/pubcomp_packet.rs b/src/packet/pubcomp_packet.rs index 864befe..3b9a528 100644 --- a/src/packet/pubcomp_packet.rs +++ b/src/packet/pubcomp_packet.rs @@ -39,7 +39,7 @@ impl<'a> PubcompPacket<'a> { } impl<'a> Packet<'a> for PubcompPacket<'a> { - fn encode(&mut self, buffer: &mut [u8]) { + fn encode(&mut self, buffer: &mut [u8]) -> usize { let mut buff_writer = BuffWriter::new(buffer); let mut rm_ln = self.property_len; @@ -53,6 +53,7 @@ impl<'a> Packet<'a> for PubcompPacket<'a> { buff_writer.write_u8(self.reason_code); buff_writer.write_variable_byte_int(self.property_len); buff_writer.encode_properties::(&self.properties); + return buff_writer.position; } fn decode(&mut self, buff_reader: &mut BuffReader<'a>) { diff --git a/src/packet/publish_packet.rs b/src/packet/publish_packet.rs index b71ed03..322d2fd 100644 --- a/src/packet/publish_packet.rs +++ b/src/packet/publish_packet.rs @@ -29,35 +29,57 @@ pub struct PublishPacket<'a> { } impl<'a> PublishPacket<'a> { + pub fn new(message: &'a [u8]) -> Self { + let mut x = Self { fixed_header: PacketType::Publish.into(), remain_len: 0, topic_name: EncodedString::new(), packet_identifier: 0, + property_len: 0, properties: Vec::, MAX_PROPERTIES>::new(), message }; + x.topic_name.string = "test/topic"; + x.topic_name.len = 10; + return x; + } + pub fn decode_publish_packet(&mut self, buff_reader: &mut BuffReader<'a>) { if self.decode_fixed_header(buff_reader) != (PacketType::Publish).into() { log::error!("Packet you are trying to decode is not PUBLISH packet!"); return; } self.topic_name = buff_reader.read_string().unwrap(); - self.packet_identifier = buff_reader.read_u16().unwrap(); + let qos = self.fixed_header & 0x03; + if qos != 0 { + // je potreba dekodovat jenom pro QoS 1 / 2 + self.packet_identifier = buff_reader.read_u16().unwrap(); + } self.decode_properties(buff_reader); self.message = buff_reader.read_message(); } } impl<'a> Packet<'a> for PublishPacket<'a> { - fn encode(&mut self, buffer: &mut [u8]) { + fn encode(&mut self, buffer: &mut [u8]) -> usize { let mut buff_writer = BuffWriter::new(buffer); let mut rm_ln = self.property_len; let property_len_enc: [u8; 4] = VariableByteIntegerEncoder::encode(self.property_len).unwrap(); let property_len_len = VariableByteIntegerEncoder::len(property_len_enc); let mut msg_len = self.message.len() as u32; - rm_ln = rm_ln + property_len_len as u32 + 2 + msg_len + self.topic_name.len as u32 + 2; + rm_ln = rm_ln + property_len_len as u32 + msg_len + self.topic_name.len as u32 + 2; buff_writer.write_u8(self.fixed_header); + let qos = self.fixed_header & 0x03; + if qos != 0 { + rm_ln + 2; + } + buff_writer.write_variable_byte_int(rm_ln); buff_writer.write_string_ref(& self.topic_name); - buff_writer.write_u16(self.packet_identifier); + + if qos != 0 { + buff_writer.write_u16(self.packet_identifier); + } + buff_writer.write_variable_byte_int(self.property_len); buff_writer.encode_properties::(&self.properties); - buff_writer.insert_ref(msg_len as usize, self.message) + buff_writer.insert_ref(msg_len as usize, self.message); + return buff_writer.position; } fn decode(&mut self, buff_reader: &mut BuffReader<'a>) { diff --git a/src/packet/pubrec_packet.rs b/src/packet/pubrec_packet.rs index 43cb52c..07f5c7e 100644 --- a/src/packet/pubrec_packet.rs +++ b/src/packet/pubrec_packet.rs @@ -39,7 +39,7 @@ impl<'a> PubrecPacket<'a> { } impl<'a> Packet<'a> for PubrecPacket<'a> { - fn encode(&mut self, buffer: &mut [u8]) { + fn encode(&mut self, buffer: &mut [u8]) -> usize { let mut buff_writer = BuffWriter::new(buffer); let mut rm_ln = self.property_len; @@ -53,6 +53,7 @@ impl<'a> Packet<'a> for PubrecPacket<'a> { buff_writer.write_u8(self.reason_code); buff_writer.write_variable_byte_int(self.property_len); buff_writer.encode_properties::(&self.properties); + return buff_writer.position; } fn decode(&mut self, buff_reader: &mut BuffReader<'a>) { diff --git a/src/packet/pubrel_packet.rs b/src/packet/pubrel_packet.rs index 10569c4..31a1133 100644 --- a/src/packet/pubrel_packet.rs +++ b/src/packet/pubrel_packet.rs @@ -39,7 +39,7 @@ impl<'a> PubrelPacket<'a> { } impl<'a> Packet<'a> for PubrelPacket<'a> { - fn encode(&mut self, buffer: &mut [u8]) { + fn encode(&mut self, buffer: &mut [u8]) -> usize { let mut buff_writer = BuffWriter::new(buffer); let mut rm_ln = self.property_len; @@ -53,6 +53,7 @@ impl<'a> Packet<'a> for PubrelPacket<'a> { buff_writer.write_u8(self.reason_code); buff_writer.write_variable_byte_int(self.property_len); buff_writer.encode_properties::(&self.properties); + return buff_writer.position; } fn decode(&mut self, buff_reader: &mut BuffReader<'a>) { diff --git a/src/packet/suback_packet.rs b/src/packet/suback_packet.rs index 6b12aa4..6a68ea6 100644 --- a/src/packet/suback_packet.rs +++ b/src/packet/suback_packet.rs @@ -51,8 +51,9 @@ impl<'a, const MAX_REASONS: usize> SubackPacket<'a, MAX_REASONS> { } impl<'a, const MAX_REASONS: usize> Packet<'a> for SubackPacket<'a, MAX_REASONS> { - fn encode(&mut self, buffer: &mut [u8]) { + fn encode(&mut self, buffer: &mut [u8]) -> usize { log::error!("SUBACK packet does not support encoding!"); + return 0; } fn decode(&mut self, buff_reader: &mut BuffReader<'a>) { diff --git a/src/packet/subscription_packet.rs b/src/packet/subscription_packet.rs index af3c610..3ac0d5f 100644 --- a/src/packet/subscription_packet.rs +++ b/src/packet/subscription_packet.rs @@ -44,7 +44,7 @@ impl<'a, const MAX_FILTERS: usize> SubscriptionPacket<'a, MAX_FILTERS> { } impl<'a, const MAX_FILTERS: usize> Packet<'a> for SubscriptionPacket<'a, MAX_FILTERS> { - fn encode(&mut self, buffer: &mut [u8]) { + fn encode(&mut self, buffer: &mut [u8]) -> usize { let mut buff_writer = BuffWriter::new(buffer); let mut rm_ln = self.property_len; @@ -68,6 +68,7 @@ impl<'a, const MAX_FILTERS: usize> Packet<'a> for SubscriptionPacket<'a, MAX_FIL buff_writer.write_variable_byte_int(self.property_len); buff_writer.encode_properties::(&self.properties); buff_writer.encode_topic_filters_ref(false, self.topic_filter_len as usize, & self.topic_filters); + return buff_writer.position; } fn decode(&mut self, buff_reader: &mut BuffReader<'a>) { diff --git a/src/packet/unsuback_packet.rs b/src/packet/unsuback_packet.rs index 291d808..91262f5 100644 --- a/src/packet/unsuback_packet.rs +++ b/src/packet/unsuback_packet.rs @@ -49,8 +49,9 @@ impl<'a, const MAX_REASONS: usize> UnsubackPacket<'a, MAX_REASONS> { } impl<'a, const MAX_REASONS: usize> Packet<'a> for UnsubackPacket<'a, MAX_REASONS> { - fn encode(&mut self, buffer: &mut [u8]) { + fn encode(&mut self, buffer: &mut [u8]) -> usize { log::error!("UNSUBACK packet does not support encoding!"); + return 0; } fn decode(&mut self, buff_reader: &mut BuffReader<'a>) { diff --git a/src/packet/unsubscription_packet.rs b/src/packet/unsubscription_packet.rs index 9fbd81f..6300bda 100644 --- a/src/packet/unsubscription_packet.rs +++ b/src/packet/unsubscription_packet.rs @@ -38,7 +38,7 @@ impl<'a, const MAX_FILTERS: usize> UnsubscriptionPacket<'a, MAX_FILTERS> { } impl<'a, const MAX_FILTERS: usize> Packet<'a> for UnsubscriptionPacket<'a, MAX_FILTERS> { - fn encode(&mut self, buffer: &mut [u8]) { + fn encode(&mut self, buffer: &mut [u8]) -> usize { let mut buff_writer = BuffWriter::new(buffer); let mut rm_ln = self.property_len; @@ -53,6 +53,7 @@ impl<'a, const MAX_FILTERS: usize> Packet<'a> for UnsubscriptionPacket<'a, MAX_F buff_writer.encode_properties::(&self.properties); buff_writer.write_u16(self.topic_filter_len); buff_writer.encode_topic_filters_ref(false, self.topic_filter_len as usize, & self.topic_filters); + return buff_writer.position; } fn decode(&mut self, buff_reader: &mut BuffReader<'a>) { diff --git a/src/utils/buffer_writer.rs b/src/utils/buffer_writer.rs index f148044..5939bf8 100644 --- a/src/utils/buffer_writer.rs +++ b/src/utils/buffer_writer.rs @@ -13,24 +13,28 @@ impl<'a> BuffWriter<'a> { pub fn insert(& mut self, array: [u8; LEN]) { let mut x: usize = 0; - loop { - self.buffer[self.position] = array[x]; - self.increment_position(1); - x = x + 1; - if x == LEN { - break; + if LEN != 0 { + loop { + self.buffer[self.position] = array[x]; + self.increment_position(1); + x = x + 1; + if x == LEN { + break; + } } } } pub fn insert_ref(& mut self, len: usize, array: &[u8]) { let mut x: usize = 0; - loop { - self.buffer[self.position] = array[x]; - self.increment_position(1); - x = x + 1; - if x == len { - break; + if len != 0 { + loop { + self.buffer[self.position] = array[x]; + self.increment_position(1); + x = x + 1; + if x == len { + break; + } } } } @@ -107,12 +111,13 @@ impl<'a> BuffWriter<'a> { pub fn encode_properties(& mut self, properties: & Vec, LEN>) { let mut i = 0; - if properties.len() != 0 { + let len = properties.len(); + if len != 0 { loop { let prop: &Property = properties.get(i).unwrap(); self.encode_property(prop); i = i + 1; - if i == LEN { + if i == len { break; } } From 4ed1c7bd2b9a6157219b957a1b26e2b2f866b285 Mon Sep 17 00:00:00 2001 From: Ondrej Babec Date: Mon, 21 Feb 2022 15:30:57 +0100 Subject: [PATCH 6/7] Get rid of constants --- src/encoding/variable_byte_integer.rs | 1 - src/main.rs | 4 +- src/packet/auth_packet.rs | 21 ++++----- src/packet/connack_packet.rs | 14 +++--- src/packet/connect_packet.rs | 36 +++++++++------ src/packet/disconnect_packet.rs | 6 +-- src/packet/mod.rs | 8 ++-- src/packet/mqtt_packet.rs | 6 +-- src/packet/packet_type.rs | 2 +- src/packet/pingreq_packet.rs | 6 +-- src/packet/pingresp_packet.rs | 4 +- src/packet/property.rs | 65 +++++++++++---------------- src/packet/puback_packet.rs | 17 ++++--- src/packet/pubcomp_packet.rs | 18 ++++---- src/packet/publish_packet.rs | 30 ++++++++----- src/packet/pubrec_packet.rs | 18 ++++---- src/packet/pubrel_packet.rs | 18 ++++---- src/packet/suback_packet.rs | 19 ++++---- src/packet/subscription_packet.rs | 38 +++++++++++----- src/packet/unsuback_packet.rs | 17 +++---- src/packet/unsubscription_packet.rs | 27 ++++++----- src/utils/buffer_writer.rs | 48 +++++++++++--------- 22 files changed, 221 insertions(+), 202 deletions(-) diff --git a/src/encoding/variable_byte_integer.rs b/src/encoding/variable_byte_integer.rs index c0904fb..a338f90 100644 --- a/src/encoding/variable_byte_integer.rs +++ b/src/encoding/variable_byte_integer.rs @@ -58,7 +58,6 @@ impl VariableByteIntegerEncoder { if (encoded_byte & 128) == 0 { break; } - } return i; } diff --git a/src/main.rs b/src/main.rs index 553faef..36a99eb 100644 --- a/src/main.rs +++ b/src/main.rs @@ -14,7 +14,7 @@ fn main() { .filter_level(log::LevelFilter::Info) .format_timestamp_nanos() .init(); - + let mut pckt: SubscriptionPacket<1> = SubscriptionPacket::new(); let mut res = vec![0; 140]; let lnsub = pckt.encode(&mut res); @@ -31,7 +31,7 @@ fn main() { let lncntrl = cntrl.encode(&mut res3); println!("{:02X?}", &res3[0..lncntrl]); log::info!("xxx"); - + /*let fl = File::open("/Users/obabec/development/school/rust-mqtt/mqtt_control_example.bin"); let mut f = File::open("/Users/obabec/development/school/rust-mqtt/mqtt_control_example.bin").expect("no file found"); diff --git a/src/packet/auth_packet.rs b/src/packet/auth_packet.rs index 78b1742..4e62253 100644 --- a/src/packet/auth_packet.rs +++ b/src/packet/auth_packet.rs @@ -1,9 +1,9 @@ -use heapless::Vec; use crate::encoding::variable_byte_integer::VariableByteIntegerEncoder; +use heapless::Vec; use crate::packet::mqtt_packet::Packet; use crate::utils::buffer_reader::BuffReader; -use crate::utils::buffer_writer::{BuffWriter}; +use crate::utils::buffer_writer::BuffWriter; use super::packet_type::PacketType; use super::property::Property; @@ -22,13 +22,13 @@ pub struct AuthPacket<'a, const MAX_PROPERTIES: usize> { } impl<'a, const MAX_PROPERTIES: usize> AuthPacket<'a, MAX_PROPERTIES> { - pub fn decode_auth_packet(& mut self, buff_reader: & mut BuffReader<'a>) { + pub fn decode_auth_packet(&mut self, buff_reader: &mut BuffReader<'a>) { self.decode_fixed_header(buff_reader); self.auth_reason = buff_reader.read_u8().unwrap(); self.decode_properties(buff_reader); } - pub fn add_reason_code(& mut self, code: u8) { + pub fn add_reason_code(&mut self, code: u8) { if code != 0 && code != 24 && code != 25 { log::error!("Provided reason code is not supported!"); return; @@ -36,7 +36,7 @@ impl<'a, const MAX_PROPERTIES: usize> AuthPacket<'a, MAX_PROPERTIES> { self.auth_reason = code; } - pub fn add_property(& mut self, p: Property<'a>) { + pub fn add_property(&mut self, p: Property<'a>) { if p.auth_property() { self.push_to_properties(p); } else { @@ -49,12 +49,13 @@ impl<'a, const MAX_PROPERTIES: usize> Packet<'a> for AuthPacket<'a, MAX_PROPERTI /*fn new() -> Packet<'a, MAX_PROPERTIES> { return AuthPacket { fixed_header: PacketType::Auth.into(), remain_len: 0, auth_reason: 0, property_len: 0, properties: Vec::, MAX_PROPERTIES>::new() } }*/ - - fn encode(&mut self, buffer: & mut [u8]) -> usize { + + fn encode(&mut self, buffer: &mut [u8]) -> usize { let mut buff_writer = BuffWriter::new(buffer); let mut rm_ln = self.property_len; - let property_len_enc: [u8; 4] = VariableByteIntegerEncoder::encode(self.property_len).unwrap(); + let property_len_enc: [u8; 4] = + VariableByteIntegerEncoder::encode(self.property_len).unwrap(); let property_len_len = VariableByteIntegerEncoder::len(property_len_enc); rm_ln = rm_ln + property_len_len as u32; rm_ln = rm_ln + 1; @@ -83,11 +84,11 @@ impl<'a, const MAX_PROPERTIES: usize> Packet<'a> for AuthPacket<'a, MAX_PROPERTI self.properties.push(property); } - fn set_fixed_header(& mut self, header: u8) { + fn set_fixed_header(&mut self, header: u8) { self.fixed_header = header; } - fn set_remaining_len(& mut self, remaining_len: u32) { + fn set_remaining_len(&mut self, remaining_len: u32) { self.remain_len = remaining_len; } } diff --git a/src/packet/connack_packet.rs b/src/packet/connack_packet.rs index 9ddfabd..83cd1cb 100644 --- a/src/packet/connack_packet.rs +++ b/src/packet/connack_packet.rs @@ -1,5 +1,5 @@ -use heapless::Vec; use crate::encoding::variable_byte_integer::VariableByteIntegerEncoder; +use heapless::Vec; use crate::packet::mqtt_packet::Packet; use crate::utils::buffer_reader::BuffReader; @@ -8,9 +8,7 @@ use crate::utils::buffer_writer::BuffWriter; use super::packet_type::PacketType; use super::property::Property; -pub const MAX_PROPERTIES: usize = 18; - -pub struct ConnackPacket<'a> { +pub struct ConnackPacket<'a, const MAX_PROPERTIES: usize> { // 7 - 4 mqtt control packet type, 3-0 flagy pub fixed_header: u8, // 1 - 4 B lenght of variable header + len of payload @@ -21,7 +19,7 @@ pub struct ConnackPacket<'a> { pub properties: Vec, MAX_PROPERTIES>, } -impl<'a> ConnackPacket<'a> { +impl<'a, const MAX_PROPERTIES: usize> ConnackPacket<'a, MAX_PROPERTIES> { pub fn decode_connack_packet(&mut self, buff_reader: &mut BuffReader<'a>) { if self.decode_fixed_header(buff_reader) != (PacketType::Connack).into() { log::error!("Packet you are trying to decode is not CONNACK packet!"); @@ -33,7 +31,7 @@ impl<'a> ConnackPacket<'a> { } } -impl<'a> Packet<'a> for ConnackPacket<'a> { +impl<'a, const MAX_PROPERTIES: usize> Packet<'a> for ConnackPacket<'a, MAX_PROPERTIES> { fn encode(&mut self, buffer: &mut [u8]) -> usize { let mut buff_writer = BuffWriter::new(buffer); buff_writer.write_u8(self.fixed_header); @@ -64,11 +62,11 @@ impl<'a> Packet<'a> for ConnackPacket<'a> { self.properties.push(property); } - fn set_fixed_header(& mut self, header: u8) { + fn set_fixed_header(&mut self, header: u8) { self.fixed_header = header; } - fn set_remaining_len(& mut self, remaining_len: u32) { + fn set_remaining_len(&mut self, remaining_len: u32) { self.remain_len = remaining_len; } } diff --git a/src/packet/connect_packet.rs b/src/packet/connect_packet.rs index 336e1e3..9e55674 100644 --- a/src/packet/connect_packet.rs +++ b/src/packet/connect_packet.rs @@ -1,5 +1,5 @@ -use heapless::Vec; use crate::encoding::variable_byte_integer::VariableByteIntegerEncoder; +use heapless::Vec; use crate::packet::mqtt_packet::Packet; use crate::utils::buffer_reader::BinaryData; @@ -38,7 +38,9 @@ pub struct ConnectPacket<'a, const MAX_PROPERTIES: usize, const MAX_WILL_PROPERT pub password: BinaryData<'a>, } -impl<'a, const MAX_PROPERTIES: usize, const MAX_WILL_PROPERTIES: usize> ConnectPacket<'a, MAX_PROPERTIES, MAX_WILL_PROPERTIES> { +impl<'a, const MAX_PROPERTIES: usize, const MAX_WILL_PROPERTIES: usize> + ConnectPacket<'a, MAX_PROPERTIES, MAX_WILL_PROPERTIES> +{ pub fn clean() -> Self { let mut x = Self { fixed_header: PacketType::Connect.into(), @@ -96,20 +98,28 @@ impl<'a, const MAX_PROPERTIES: usize, const MAX_WILL_PROPERTIES: usize> ConnectP self.fixed_header = cur_type | flags; } } -impl<'a, const MAX_PROPERTIES: usize, const MAX_WILL_PROPERTIES: usize> Packet<'a> for ConnectPacket<'a, MAX_PROPERTIES, MAX_WILL_PROPERTIES> { +impl<'a, const MAX_PROPERTIES: usize, const MAX_WILL_PROPERTIES: usize> Packet<'a> + for ConnectPacket<'a, MAX_PROPERTIES, MAX_WILL_PROPERTIES> +{ fn encode(&mut self, buffer: &mut [u8]) -> usize { let mut buff_writer = BuffWriter::new(buffer); let mut rm_ln = self.property_len; - let property_len_enc: [u8; 4] = VariableByteIntegerEncoder::encode(self.property_len).unwrap(); + let property_len_enc: [u8; 4] = + VariableByteIntegerEncoder::encode(self.property_len).unwrap(); let property_len_len = VariableByteIntegerEncoder::len(property_len_enc); // 12 = protocol_name_len + protocol_name + protocol_version + connect_flags + keep_alive + client_id_len rm_ln = rm_ln + property_len_len as u32 + 12; if self.connect_flags & 0x04 == 1 { - let wil_prop_len_enc = VariableByteIntegerEncoder::encode(self.will_property_len).unwrap(); + let wil_prop_len_enc = + VariableByteIntegerEncoder::encode(self.will_property_len).unwrap(); let wil_prop_len_len = VariableByteIntegerEncoder::len(wil_prop_len_enc); - rm_ln = rm_ln + wil_prop_len_len as u32 + self.will_property_len as u32 + self.will_topic.len as u32 + self.will_payload.len as u32; + rm_ln = rm_ln + + wil_prop_len_len as u32 + + self.will_property_len as u32 + + self.will_topic.len as u32 + + self.will_payload.len as u32; } if self.connect_flags & 0x80 == 1 { @@ -134,17 +144,17 @@ impl<'a, const MAX_PROPERTIES: usize, const MAX_WILL_PROPERTIES: usize> Packet<' if self.connect_flags & 0x04 == 1 { buff_writer.write_variable_byte_int(self.will_property_len); - buff_writer.encode_properties(& self.will_properties); - buff_writer.write_string_ref(& self.will_topic); - buff_writer.write_binary_ref(& self.will_payload); + buff_writer.encode_properties(&self.will_properties); + buff_writer.write_string_ref(&self.will_topic); + buff_writer.write_binary_ref(&self.will_payload); } if self.connect_flags & 0x80 == 1 { - buff_writer.write_string_ref(& self.username); + buff_writer.write_string_ref(&self.username); } if self.connect_flags & 0x40 == 1 { - buff_writer.write_binary_ref(& self.password); + buff_writer.write_binary_ref(&self.password); } return buff_writer.position; @@ -166,11 +176,11 @@ impl<'a, const MAX_PROPERTIES: usize, const MAX_WILL_PROPERTIES: usize> Packet<' self.properties.push(property); } - fn set_fixed_header(& mut self, header: u8) { + fn set_fixed_header(&mut self, header: u8) { self.fixed_header = header; } - fn set_remaining_len(& mut self, remaining_len: u32) { + fn set_remaining_len(&mut self, remaining_len: u32) { self.remain_len = remaining_len; } diff --git a/src/packet/disconnect_packet.rs b/src/packet/disconnect_packet.rs index 52fc2b3..f182e50 100644 --- a/src/packet/disconnect_packet.rs +++ b/src/packet/disconnect_packet.rs @@ -1,5 +1,5 @@ -use heapless::Vec; use crate::encoding::variable_byte_integer::VariableByteIntegerEncoder; +use heapless::Vec; use crate::packet::mqtt_packet::Packet; use crate::utils::buffer_reader::BuffReader; @@ -63,11 +63,11 @@ impl<'a, const MAX_PROPERTIES: usize> Packet<'a> for DisconnectPacket<'a, MAX_PR self.properties.push(property); } - fn set_fixed_header(& mut self, header: u8) { + fn set_fixed_header(&mut self, header: u8) { self.fixed_header = header; } - fn set_remaining_len(& mut self, remaining_len: u32) { + fn set_remaining_len(&mut self, remaining_len: u32) { self.remain_len = remaining_len; } } diff --git a/src/packet/mod.rs b/src/packet/mod.rs index 3d0f275..f76a034 100644 --- a/src/packet/mod.rs +++ b/src/packet/mod.rs @@ -1,10 +1,9 @@ - //pub mod control_packet; +pub mod auth_packet; +pub mod connack_packet; pub mod mqtt_packet; pub mod packet_type; pub mod property; -pub mod auth_packet; -pub mod connack_packet; pub mod puback_packet; pub mod pubcomp_packet; pub mod publish_packet; @@ -13,10 +12,9 @@ pub mod pubrel_packet; pub mod subscription_packet; pub mod unsubscription_packet; - +pub mod connect_packet; pub mod disconnect_packet; pub mod pingreq_packet; pub mod pingresp_packet; pub mod suback_packet; pub mod unsuback_packet; -pub mod connect_packet; diff --git a/src/packet/mqtt_packet.rs b/src/packet/mqtt_packet.rs index ad5e6c0..b090d63 100644 --- a/src/packet/mqtt_packet.rs +++ b/src/packet/mqtt_packet.rs @@ -16,10 +16,10 @@ pub trait Packet<'a> { fn push_to_properties(&mut self, property: Property<'a>); // header - fn set_fixed_header(& mut self, header: u8); - fn set_remaining_len(& mut self, remaining_len: u32); + fn set_fixed_header(&mut self, header: u8); + fn set_remaining_len(&mut self, remaining_len: u32); - fn decode_properties(&mut self, buff_reader: & mut BuffReader<'a>) { + fn decode_properties(&mut self, buff_reader: &mut BuffReader<'a>) { self.set_property_len(buff_reader.read_variable_byte_int().unwrap()); let mut x: u32 = 0; let mut prop: Result; diff --git a/src/packet/packet_type.rs b/src/packet/packet_type.rs index 679a4a3..82fc069 100644 --- a/src/packet/packet_type.rs +++ b/src/packet/packet_type.rs @@ -64,6 +64,6 @@ impl Into for PacketType { PacketType::Disconnect => 0xE0, PacketType::Auth => 0xF0, PacketType::Reserved => 0x00, - } + }; } } diff --git a/src/packet/pingreq_packet.rs b/src/packet/pingreq_packet.rs index b13de06..40234f2 100644 --- a/src/packet/pingreq_packet.rs +++ b/src/packet/pingreq_packet.rs @@ -5,8 +5,6 @@ use crate::utils::buffer_writer::BuffWriter; use super::packet_type::PacketType; use super::property::Property; -pub const MAX_PROPERTIES: usize = 2; - pub struct PingreqPacket { // 7 - 4 mqtt control packet type, 3-0 flagy pub fixed_header: u8, @@ -41,11 +39,11 @@ impl<'a> Packet<'a> for PingreqPacket { log::error!("PINGREQ packet does not contain any properties!"); } - fn set_fixed_header(& mut self, header: u8) { + fn set_fixed_header(&mut self, header: u8) { self.fixed_header = header; } - fn set_remaining_len(& mut self, remaining_len: u32) { + fn set_remaining_len(&mut self, remaining_len: u32) { self.remain_len = remaining_len; } } diff --git a/src/packet/pingresp_packet.rs b/src/packet/pingresp_packet.rs index 58de28d..b6c32ae 100644 --- a/src/packet/pingresp_packet.rs +++ b/src/packet/pingresp_packet.rs @@ -46,11 +46,11 @@ impl<'a> Packet<'a> for PingrespPacket { log::error!("PINGRESP packet does not contain any properties!"); } - fn set_fixed_header(& mut self, header: u8) { + fn set_fixed_header(&mut self, header: u8) { self.fixed_header = header; } - fn set_remaining_len(& mut self, remaining_len: u32) { + fn set_remaining_len(&mut self, remaining_len: u32) { self.remain_len = remaining_len; } } diff --git a/src/packet/property.rs b/src/packet/property.rs index a977e35..fe16104 100644 --- a/src/packet/property.rs +++ b/src/packet/property.rs @@ -39,15 +39,14 @@ pub enum Property<'a> { } impl<'a> Property<'a> { - - pub fn auth_property(& self) -> bool { + pub fn auth_property(&self) -> bool { return match self { Property::AuthenticationMethod(_u) => true, Property::AuthenticationData(_u) => true, Property::ReasonString(_u) => true, Property::UserProperty(_u) => true, - _ => false - } + _ => false, + }; } pub fn len(&self) -> u16 { @@ -80,10 +79,10 @@ impl<'a> Property<'a> { Property::SubscriptionIdentifierAvailable(_u) => 1, Property::SharedSubscriptionAvailable(_u) => 1, _ => 0, - } + }; } - pub fn encode(&self, buff_writer: & mut BuffWriter<'a>) { + pub fn encode(&self, buff_writer: &mut BuffWriter<'a>) { return match self { Property::PayloadFormat(u) => buff_writer.write_u8(*u), Property::MessageExpiryInterval(u) => buff_writer.write_u32(*u), @@ -113,10 +112,10 @@ impl<'a> Property<'a> { Property::SubscriptionIdentifierAvailable(u) => buff_writer.write_u8(*u), Property::SharedSubscriptionAvailable(u) => buff_writer.write_u8(*u), _ => (), - } + }; } - pub fn decode(buff_reader: & mut BuffReader<'a>) -> Result, ParseError> { + pub fn decode(buff_reader: &mut BuffReader<'a>) -> Result, ParseError> { let property_identifier = buff_reader.read_u8(); return match property_identifier { Ok(0x01) => Ok(Property::PayloadFormat(buff_reader.read_u8()?)), @@ -124,17 +123,13 @@ impl<'a> Property<'a> { Ok(0x03) => Ok(Property::ContentType(buff_reader.read_string()?)), Ok(0x08) => Ok(Property::ResponseTopic(buff_reader.read_string()?)), Ok(0x09) => Ok(Property::CorrelationData(buff_reader.read_binary()?)), - Ok(0x0B) => { - Ok(Property::SubscriptionIdentifier( - buff_reader.read_variable_byte_int()?, - )) - } + Ok(0x0B) => Ok(Property::SubscriptionIdentifier( + buff_reader.read_variable_byte_int()?, + )), Ok(0x11) => Ok(Property::SessionExpiryInterval(buff_reader.read_u32()?)), - Ok(0x12) => { - Ok(Property::AssignedClientIdentifier( - buff_reader.read_string()?, - )) - } + Ok(0x12) => Ok(Property::AssignedClientIdentifier( + buff_reader.read_string()?, + )), Ok(0x13) => Ok(Property::ServerKeepAlive(buff_reader.read_u16()?)), Ok(0x15) => Ok(Property::AuthenticationMethod(buff_reader.read_string()?)), Ok(0x16) => Ok(Property::AuthenticationData(buff_reader.read_binary()?)), @@ -150,28 +145,22 @@ impl<'a> Property<'a> { Ok(0x24) => Ok(Property::MaximumQoS(buff_reader.read_u8()?)), Ok(0x25) => Ok(Property::RetainAvailable(buff_reader.read_u8()?)), Ok(0x26) => Ok(Property::UserProperty(buff_reader.read_string_pair()?)), - Ok(0x28) => { - Ok(Property::WildcardSubscriptionAvailable( - buff_reader.read_u8()?, - )) - } - Ok(0x29) => { - Ok(Property::SubscriptionIdentifierAvailable( - buff_reader.read_u8()?, - )) - } - Ok(0x2A) => { - Ok(Property::SharedSubscriptionAvailable( - buff_reader.read_u8()?, - )) - } + Ok(0x28) => Ok(Property::WildcardSubscriptionAvailable( + buff_reader.read_u8()?, + )), + Ok(0x29) => Ok(Property::SubscriptionIdentifierAvailable( + buff_reader.read_u8()?, + )), + Ok(0x2A) => Ok(Property::SharedSubscriptionAvailable( + buff_reader.read_u8()?, + )), Err(err) => Err(err), _ => Err(ParseError::IdNotFound), - } + }; } } -impl Into for & Property<'a> { +impl Into for &Property<'a> { fn into(self) -> u8 { return match &*self { Property::PayloadFormat(_u) => 0x01, @@ -201,8 +190,8 @@ impl Into for & Property<'a> { Property::WildcardSubscriptionAvailable(_u) => 0x28, Property::SubscriptionIdentifierAvailable(_u) => 0x29, Property::SharedSubscriptionAvailable(_u) => 0x2A, - _ => 0x00 - } + _ => 0x00, + }; } } @@ -212,4 +201,4 @@ impl From for Property<'a> { _ => Property::Reserved(), }; } -} \ No newline at end of file +} diff --git a/src/packet/puback_packet.rs b/src/packet/puback_packet.rs index bf85c41..42e8278 100644 --- a/src/packet/puback_packet.rs +++ b/src/packet/puback_packet.rs @@ -1,5 +1,5 @@ -use heapless::Vec; use crate::encoding::variable_byte_integer::VariableByteIntegerEncoder; +use heapless::Vec; use crate::packet::mqtt_packet::Packet; use crate::utils::buffer_reader::BuffReader; @@ -8,9 +8,7 @@ use crate::utils::buffer_writer::BuffWriter; use super::packet_type::PacketType; use super::property::Property; -pub const MAX_PROPERTIES: usize = 2; - -pub struct PubackPacket<'a> { +pub struct PubackPacket<'a, const MAX_PROPERTIES: usize> { // 7 - 4 mqtt control packet type, 3-0 flagy pub fixed_header: u8, // 1 - 4 B lenght of variable header + len of payload @@ -25,7 +23,7 @@ pub struct PubackPacket<'a> { pub properties: Vec, MAX_PROPERTIES>, } -impl<'a> PubackPacket<'a> { +impl<'a, const MAX_PROPERTIES: usize> PubackPacket<'a, MAX_PROPERTIES> { pub fn decode_puback_packet(&mut self, buff_reader: &mut BuffReader<'a>) { if self.decode_fixed_header(buff_reader) != (PacketType::Puback).into() { log::error!("Packet you are trying to decode is not PUBACK packet!"); @@ -37,12 +35,13 @@ impl<'a> PubackPacket<'a> { } } -impl<'a> Packet<'a> for PubackPacket<'a> { +impl<'a, const MAX_PROPERTIES: usize> Packet<'a> for PubackPacket<'a, MAX_PROPERTIES> { fn encode(&mut self, buffer: &mut [u8]) -> usize { let mut buff_writer = BuffWriter::new(buffer); let mut rm_ln = self.property_len; - let property_len_enc: [u8; 4] = VariableByteIntegerEncoder::encode(self.property_len).unwrap(); + let property_len_enc: [u8; 4] = + VariableByteIntegerEncoder::encode(self.property_len).unwrap(); let property_len_len = VariableByteIntegerEncoder::len(property_len_enc); rm_ln = rm_ln + property_len_len as u32 + 3; @@ -71,11 +70,11 @@ impl<'a> Packet<'a> for PubackPacket<'a> { self.properties.push(property); } - fn set_fixed_header(& mut self, header: u8) { + fn set_fixed_header(&mut self, header: u8) { self.fixed_header = header; } - fn set_remaining_len(& mut self, remaining_len: u32) { + fn set_remaining_len(&mut self, remaining_len: u32) { self.remain_len = remaining_len; } } diff --git a/src/packet/pubcomp_packet.rs b/src/packet/pubcomp_packet.rs index 3b9a528..58811a9 100644 --- a/src/packet/pubcomp_packet.rs +++ b/src/packet/pubcomp_packet.rs @@ -1,5 +1,5 @@ -use heapless::Vec; use crate::encoding::variable_byte_integer::VariableByteIntegerEncoder; +use heapless::Vec; use crate::packet::mqtt_packet::Packet; use crate::utils::buffer_reader::BuffReader; @@ -8,9 +8,7 @@ use crate::utils::buffer_writer::BuffWriter; use super::packet_type::PacketType; use super::property::Property; -pub const MAX_PROPERTIES: usize = 2; - -pub struct PubcompPacket<'a> { +pub struct PubcompPacket<'a, const MAX_PROPERTIES: usize> { // 7 - 4 mqtt control packet type, 3-0 flagy pub fixed_header: u8, // 1 - 4 B lenght of variable header + len of payload @@ -25,8 +23,7 @@ pub struct PubcompPacket<'a> { pub properties: Vec, MAX_PROPERTIES>, } -impl<'a> PubcompPacket<'a> { - +impl<'a, const MAX_PROPERTIES: usize> PubcompPacket<'a, MAX_PROPERTIES> { pub fn decode_puback_packet(&mut self, buff_reader: &mut BuffReader<'a>) { if self.decode_fixed_header(buff_reader) != (PacketType::Pubcomp).into() { log::error!("Packet you are trying to decode is not PUBCOMP packet!"); @@ -38,12 +35,13 @@ impl<'a> PubcompPacket<'a> { } } -impl<'a> Packet<'a> for PubcompPacket<'a> { +impl<'a, const MAX_PROPERTIES: usize> Packet<'a> for PubcompPacket<'a, MAX_PROPERTIES> { fn encode(&mut self, buffer: &mut [u8]) -> usize { let mut buff_writer = BuffWriter::new(buffer); let mut rm_ln = self.property_len; - let property_len_enc: [u8; 4] = VariableByteIntegerEncoder::encode(self.property_len).unwrap(); + let property_len_enc: [u8; 4] = + VariableByteIntegerEncoder::encode(self.property_len).unwrap(); let property_len_len = VariableByteIntegerEncoder::len(property_len_enc); rm_ln = rm_ln + property_len_len as u32 + 3; @@ -72,11 +70,11 @@ impl<'a> Packet<'a> for PubcompPacket<'a> { self.properties.push(property); } - fn set_fixed_header(& mut self, header: u8) { + fn set_fixed_header(&mut self, header: u8) { self.fixed_header = header; } - fn set_remaining_len(& mut self, remaining_len: u32) { + fn set_remaining_len(&mut self, remaining_len: u32) { self.remain_len = remaining_len; } } diff --git a/src/packet/publish_packet.rs b/src/packet/publish_packet.rs index 322d2fd..cb7d05e 100644 --- a/src/packet/publish_packet.rs +++ b/src/packet/publish_packet.rs @@ -1,5 +1,5 @@ -use heapless::Vec; use crate::encoding::variable_byte_integer::VariableByteIntegerEncoder; +use heapless::Vec; use crate::packet::mqtt_packet::Packet; use crate::utils::buffer_reader::BuffReader; @@ -9,9 +9,7 @@ use crate::utils::buffer_writer::BuffWriter; use super::packet_type::PacketType; use super::property::Property; -pub const MAX_PROPERTIES: usize = 9; - -pub struct PublishPacket<'a> { +pub struct PublishPacket<'a, const MAX_PROPERTIES: usize> { // 7 - 4 mqtt control packet type, 3-0 flagy pub fixed_header: u8, // 1 - 4 B lenght of variable header + len of payload @@ -28,10 +26,17 @@ pub struct PublishPacket<'a> { pub message: &'a [u8], } -impl<'a> PublishPacket<'a> { +impl<'a, const MAX_PROPERTIES: usize> PublishPacket<'a, MAX_PROPERTIES> { pub fn new(message: &'a [u8]) -> Self { - let mut x = Self { fixed_header: PacketType::Publish.into(), remain_len: 0, topic_name: EncodedString::new(), packet_identifier: 0, - property_len: 0, properties: Vec::, MAX_PROPERTIES>::new(), message }; + let mut x = Self { + fixed_header: PacketType::Publish.into(), + remain_len: 0, + topic_name: EncodedString::new(), + packet_identifier: 0, + property_len: 0, + properties: Vec::, MAX_PROPERTIES>::new(), + message, + }; x.topic_name.string = "test/topic"; x.topic_name.len = 10; return x; @@ -53,12 +58,13 @@ impl<'a> PublishPacket<'a> { } } -impl<'a> Packet<'a> for PublishPacket<'a> { +impl<'a, const MAX_PROPERTIES: usize> Packet<'a> for PublishPacket<'a, MAX_PROPERTIES> { fn encode(&mut self, buffer: &mut [u8]) -> usize { let mut buff_writer = BuffWriter::new(buffer); let mut rm_ln = self.property_len; - let property_len_enc: [u8; 4] = VariableByteIntegerEncoder::encode(self.property_len).unwrap(); + let property_len_enc: [u8; 4] = + VariableByteIntegerEncoder::encode(self.property_len).unwrap(); let property_len_len = VariableByteIntegerEncoder::len(property_len_enc); let mut msg_len = self.message.len() as u32; rm_ln = rm_ln + property_len_len as u32 + msg_len + self.topic_name.len as u32 + 2; @@ -70,7 +76,7 @@ impl<'a> Packet<'a> for PublishPacket<'a> { } buff_writer.write_variable_byte_int(rm_ln); - buff_writer.write_string_ref(& self.topic_name); + buff_writer.write_string_ref(&self.topic_name); if qos != 0 { buff_writer.write_u16(self.packet_identifier); @@ -98,11 +104,11 @@ impl<'a> Packet<'a> for PublishPacket<'a> { self.properties.push(property); } - fn set_fixed_header(& mut self, header: u8) { + fn set_fixed_header(&mut self, header: u8) { self.fixed_header = header; } - fn set_remaining_len(& mut self, remaining_len: u32) { + fn set_remaining_len(&mut self, remaining_len: u32) { self.remain_len = remaining_len; } } diff --git a/src/packet/pubrec_packet.rs b/src/packet/pubrec_packet.rs index 07f5c7e..996016e 100644 --- a/src/packet/pubrec_packet.rs +++ b/src/packet/pubrec_packet.rs @@ -1,5 +1,5 @@ -use heapless::Vec; use crate::encoding::variable_byte_integer::VariableByteIntegerEncoder; +use heapless::Vec; use crate::packet::mqtt_packet::Packet; use crate::utils::buffer_reader::BuffReader; @@ -8,9 +8,7 @@ use crate::utils::buffer_writer::BuffWriter; use super::packet_type::PacketType; use super::property::Property; -pub const MAX_PROPERTIES: usize = 2; - -pub struct PubrecPacket<'a> { +pub struct PubrecPacket<'a, const MAX_PROPERTIES: usize> { // 7 - 4 mqtt control packet type, 3-0 flagy pub fixed_header: u8, // 1 - 4 B lenght of variable header + len of payload @@ -25,8 +23,7 @@ pub struct PubrecPacket<'a> { pub properties: Vec, MAX_PROPERTIES>, } -impl<'a> PubrecPacket<'a> { - +impl<'a, const MAX_PROPERTIES: usize> PubrecPacket<'a, MAX_PROPERTIES> { pub fn decode_pubrec_packet(&mut self, buff_reader: &mut BuffReader<'a>) { if self.decode_fixed_header(buff_reader) != (PacketType::Pubrec).into() { log::error!("Packet you are trying to decode is not PUBREC packet!"); @@ -38,12 +35,13 @@ impl<'a> PubrecPacket<'a> { } } -impl<'a> Packet<'a> for PubrecPacket<'a> { +impl<'a, const MAX_PROPERTIES: usize> Packet<'a> for PubrecPacket<'a, MAX_PROPERTIES> { fn encode(&mut self, buffer: &mut [u8]) -> usize { let mut buff_writer = BuffWriter::new(buffer); let mut rm_ln = self.property_len; - let property_len_enc: [u8; 4] = VariableByteIntegerEncoder::encode(self.property_len).unwrap(); + let property_len_enc: [u8; 4] = + VariableByteIntegerEncoder::encode(self.property_len).unwrap(); let property_len_len = VariableByteIntegerEncoder::len(property_len_enc); rm_ln = rm_ln + property_len_len as u32 + 3; @@ -71,11 +69,11 @@ impl<'a> Packet<'a> for PubrecPacket<'a> { fn push_to_properties(&mut self, property: Property<'a>) { self.properties.push(property); } - fn set_fixed_header(& mut self, header: u8) { + fn set_fixed_header(&mut self, header: u8) { self.fixed_header = header; } - fn set_remaining_len(& mut self, remaining_len: u32) { + fn set_remaining_len(&mut self, remaining_len: u32) { self.remain_len = remaining_len; } } diff --git a/src/packet/pubrel_packet.rs b/src/packet/pubrel_packet.rs index 31a1133..3ac8da3 100644 --- a/src/packet/pubrel_packet.rs +++ b/src/packet/pubrel_packet.rs @@ -1,5 +1,5 @@ -use heapless::Vec; use crate::encoding::variable_byte_integer::VariableByteIntegerEncoder; +use heapless::Vec; use crate::packet::mqtt_packet::Packet; use crate::utils::buffer_reader::BuffReader; @@ -8,9 +8,7 @@ use crate::utils::buffer_writer::BuffWriter; use super::packet_type::PacketType; use super::property::Property; -pub const MAX_PROPERTIES: usize = 2; - -pub struct PubrelPacket<'a> { +pub struct PubrelPacket<'a, const MAX_PROPERTIES: usize> { // 7 - 4 mqtt control packet type, 3-0 flagy pub fixed_header: u8, // 1 - 4 B lenght of variable header + len of payload @@ -25,8 +23,7 @@ pub struct PubrelPacket<'a> { pub properties: Vec, MAX_PROPERTIES>, } -impl<'a> PubrelPacket<'a> { - +impl<'a, const MAX_PROPERTIES: usize> PubrelPacket<'a, MAX_PROPERTIES> { pub fn decode_puback_packet(&mut self, buff_reader: &mut BuffReader<'a>) { if self.decode_fixed_header(buff_reader) != (PacketType::Pubrel).into() { log::error!("Packet you are trying to decode is not PUBREL packet!"); @@ -38,12 +35,13 @@ impl<'a> PubrelPacket<'a> { } } -impl<'a> Packet<'a> for PubrelPacket<'a> { +impl<'a, const MAX_PROPERTIES: usize> Packet<'a> for PubrelPacket<'a, MAX_PROPERTIES> { fn encode(&mut self, buffer: &mut [u8]) -> usize { let mut buff_writer = BuffWriter::new(buffer); let mut rm_ln = self.property_len; - let property_len_enc: [u8; 4] = VariableByteIntegerEncoder::encode(self.property_len).unwrap(); + let property_len_enc: [u8; 4] = + VariableByteIntegerEncoder::encode(self.property_len).unwrap(); let property_len_len = VariableByteIntegerEncoder::len(property_len_enc); rm_ln = rm_ln + property_len_len as u32 + 3; @@ -72,11 +70,11 @@ impl<'a> Packet<'a> for PubrelPacket<'a> { self.properties.push(property); } - fn set_fixed_header(& mut self, header: u8) { + fn set_fixed_header(&mut self, header: u8) { self.fixed_header = header; } - fn set_remaining_len(& mut self, remaining_len: u32) { + fn set_remaining_len(&mut self, remaining_len: u32) { self.remain_len = remaining_len; } } diff --git a/src/packet/suback_packet.rs b/src/packet/suback_packet.rs index 6a68ea6..c90bc28 100644 --- a/src/packet/suback_packet.rs +++ b/src/packet/suback_packet.rs @@ -1,5 +1,5 @@ -use heapless::Vec; use crate::encoding::variable_byte_integer::VariableByteIntegerEncoder; +use heapless::Vec; use crate::packet::mqtt_packet::Packet; use crate::utils::buffer_reader::BuffReader; @@ -8,9 +8,7 @@ use crate::utils::buffer_writer::BuffWriter; use super::packet_type::PacketType; use super::property::Property; -pub const MAX_PROPERTIES: usize = 2; - -pub struct SubackPacket<'a, const MAX_REASONS: usize> { +pub struct SubackPacket<'a, const MAX_REASONS: usize, const MAX_PROPERTIES: usize> { // 7 - 4 mqtt control packet type, 3-0 flagy pub fixed_header: u8, // 1 - 4 B lenght of variable header + len of payload @@ -26,8 +24,9 @@ pub struct SubackPacket<'a, const MAX_REASONS: usize> { pub reason_codes: Vec, } -impl<'a, const MAX_REASONS: usize> SubackPacket<'a, MAX_REASONS> { - +impl<'a, const MAX_REASONS: usize, const MAX_PROPERTIES: usize> + SubackPacket<'a, MAX_REASONS, MAX_PROPERTIES> +{ pub fn read_reason_codes(&mut self, buff_reader: &mut BuffReader<'a>) { let mut i = 0; loop { @@ -50,7 +49,9 @@ impl<'a, const MAX_REASONS: usize> SubackPacket<'a, MAX_REASONS> { } } -impl<'a, const MAX_REASONS: usize> Packet<'a> for SubackPacket<'a, MAX_REASONS> { +impl<'a, const MAX_REASONS: usize, const MAX_PROPERTIES: usize> Packet<'a> + for SubackPacket<'a, MAX_REASONS, MAX_PROPERTIES> +{ fn encode(&mut self, buffer: &mut [u8]) -> usize { log::error!("SUBACK packet does not support encoding!"); return 0; @@ -72,11 +73,11 @@ impl<'a, const MAX_REASONS: usize> Packet<'a> for SubackPacket<'a, MAX_REASONS> self.properties.push(property); } - fn set_fixed_header(& mut self, header: u8) { + fn set_fixed_header(&mut self, header: u8) { self.fixed_header = header; } - fn set_remaining_len(& mut self, remaining_len: u32) { + fn set_remaining_len(&mut self, remaining_len: u32) { self.remain_len = remaining_len; } } diff --git a/src/packet/subscription_packet.rs b/src/packet/subscription_packet.rs index 3ac0d5f..096f8ac 100644 --- a/src/packet/subscription_packet.rs +++ b/src/packet/subscription_packet.rs @@ -1,5 +1,5 @@ -use heapless::Vec; use crate::encoding::variable_byte_integer::VariableByteIntegerEncoder; +use heapless::Vec; use crate::packet::mqtt_packet::Packet; use crate::utils::buffer_reader::BuffReader; @@ -9,9 +9,7 @@ use crate::utils::buffer_writer::BuffWriter; use super::packet_type::PacketType; use super::property::Property; -pub const MAX_PROPERTIES: usize = 2; - -pub struct SubscriptionPacket<'a, const MAX_FILTERS: usize> { +pub struct SubscriptionPacket<'a, const MAX_FILTERS: usize, const MAX_PROPERTIES: usize> { // 7 - 4 mqtt control packet type, 3-0 flagy pub fixed_header: u8, // 1 - 4 B lenght of variable header + len of payload @@ -31,10 +29,19 @@ pub struct SubscriptionPacket<'a, const MAX_FILTERS: usize> { pub topic_filters: Vec, MAX_FILTERS>, } -impl<'a, const MAX_FILTERS: usize> SubscriptionPacket<'a, MAX_FILTERS> { +impl<'a, const MAX_FILTERS: usize, const MAX_PROPERTIES: usize> + SubscriptionPacket<'a, MAX_FILTERS, MAX_PROPERTIES> +{ pub fn new() -> Self { - let mut x = Self { fixed_header: PacketType::Subscribe.into(), remain_len: 0, packet_identifier: 1, - property_len: 0, properties: Vec::, MAX_PROPERTIES>::new(), topic_filter_len: 1, topic_filters: Vec::, MAX_FILTERS>::new() }; + let mut x = Self { + fixed_header: PacketType::Subscribe.into(), + remain_len: 0, + packet_identifier: 1, + property_len: 0, + properties: Vec::, MAX_PROPERTIES>::new(), + topic_filter_len: 1, + topic_filters: Vec::, MAX_FILTERS>::new(), + }; let mut p = TopicFilter::new(); p.filter.len = 6; p.filter.string = "test/#"; @@ -43,12 +50,15 @@ impl<'a, const MAX_FILTERS: usize> SubscriptionPacket<'a, MAX_FILTERS> { } } -impl<'a, const MAX_FILTERS: usize> Packet<'a> for SubscriptionPacket<'a, MAX_FILTERS> { +impl<'a, const MAX_FILTERS: usize, const MAX_PROPERTIES: usize> Packet<'a> + for SubscriptionPacket<'a, MAX_FILTERS, MAX_PROPERTIES> +{ fn encode(&mut self, buffer: &mut [u8]) -> usize { let mut buff_writer = BuffWriter::new(buffer); let mut rm_ln = self.property_len; - let property_len_enc: [u8; 4] = VariableByteIntegerEncoder::encode(self.property_len).unwrap(); + let property_len_enc: [u8; 4] = + VariableByteIntegerEncoder::encode(self.property_len).unwrap(); let property_len_len = VariableByteIntegerEncoder::len(property_len_enc); let mut lt = 0; @@ -67,7 +77,11 @@ impl<'a, const MAX_FILTERS: usize> Packet<'a> for SubscriptionPacket<'a, MAX_FIL buff_writer.write_u16(self.packet_identifier); buff_writer.write_variable_byte_int(self.property_len); buff_writer.encode_properties::(&self.properties); - buff_writer.encode_topic_filters_ref(false, self.topic_filter_len as usize, & self.topic_filters); + buff_writer.encode_topic_filters_ref( + false, + self.topic_filter_len as usize, + &self.topic_filters, + ); return buff_writer.position; } @@ -86,11 +100,11 @@ impl<'a, const MAX_FILTERS: usize> Packet<'a> for SubscriptionPacket<'a, MAX_FIL self.properties.push(property); } - fn set_fixed_header(& mut self, header: u8) { + fn set_fixed_header(&mut self, header: u8) { self.fixed_header = header; } - fn set_remaining_len(& mut self, remaining_len: u32) { + fn set_remaining_len(&mut self, remaining_len: u32) { self.remain_len = remaining_len; } } diff --git a/src/packet/unsuback_packet.rs b/src/packet/unsuback_packet.rs index 91262f5..b1c857a 100644 --- a/src/packet/unsuback_packet.rs +++ b/src/packet/unsuback_packet.rs @@ -6,9 +6,7 @@ use crate::utils::buffer_reader::BuffReader; use super::packet_type::PacketType; use super::property::Property; -pub const MAX_PROPERTIES: usize = 20; - -pub struct UnsubackPacket<'a, const MAX_REASONS: usize> { +pub struct UnsubackPacket<'a, const MAX_REASONS: usize, const MAX_PROPERTIES: usize> { // 7 - 4 mqtt control packet type, 3-0 flagy pub fixed_header: u8, // 1 - 4 B lenght of variable header + len of payload @@ -24,8 +22,9 @@ pub struct UnsubackPacket<'a, const MAX_REASONS: usize> { pub reason_codes: Vec, } -impl<'a, const MAX_REASONS: usize> UnsubackPacket<'a, MAX_REASONS> { - +impl<'a, const MAX_REASONS: usize, const MAX_PROPERTIES: usize> + UnsubackPacket<'a, MAX_REASONS, MAX_PROPERTIES> +{ pub fn read_reason_codes(&mut self, buff_reader: &mut BuffReader<'a>) { let mut i = 0; loop { @@ -48,7 +47,9 @@ impl<'a, const MAX_REASONS: usize> UnsubackPacket<'a, MAX_REASONS> { } } -impl<'a, const MAX_REASONS: usize> Packet<'a> for UnsubackPacket<'a, MAX_REASONS> { +impl<'a, const MAX_REASONS: usize, const MAX_PROPERTIES: usize> Packet<'a> + for UnsubackPacket<'a, MAX_REASONS, MAX_PROPERTIES> +{ fn encode(&mut self, buffer: &mut [u8]) -> usize { log::error!("UNSUBACK packet does not support encoding!"); return 0; @@ -70,11 +71,11 @@ impl<'a, const MAX_REASONS: usize> Packet<'a> for UnsubackPacket<'a, MAX_REASONS self.properties.push(property); } - fn set_fixed_header(& mut self, header: u8) { + fn set_fixed_header(&mut self, header: u8) { self.fixed_header = header; } - fn set_remaining_len(& mut self, remaining_len: u32) { + fn set_remaining_len(&mut self, remaining_len: u32) { self.remain_len = remaining_len; } } diff --git a/src/packet/unsubscription_packet.rs b/src/packet/unsubscription_packet.rs index 6300bda..1464eec 100644 --- a/src/packet/unsubscription_packet.rs +++ b/src/packet/unsubscription_packet.rs @@ -1,5 +1,5 @@ -use heapless::Vec; use crate::encoding::variable_byte_integer::VariableByteIntegerEncoder; +use heapless::Vec; use crate::packet::mqtt_packet::Packet; use crate::utils::buffer_reader::BuffReader; @@ -9,9 +9,7 @@ use crate::utils::buffer_writer::BuffWriter; use super::packet_type::PacketType; use super::property::Property; -pub const MAX_PROPERTIES: usize = 20; - -pub struct UnsubscriptionPacket<'a, const MAX_FILTERS: usize> { +pub struct UnsubscriptionPacket<'a, const MAX_FILTERS: usize, const MAX_PROPERTIES: usize> { // 7 - 4 mqtt control packet type, 3-0 flagy pub fixed_header: u8, // 1 - 4 B lenght of variable header + len of payload @@ -31,18 +29,23 @@ pub struct UnsubscriptionPacket<'a, const MAX_FILTERS: usize> { pub topic_filters: Vec, MAX_FILTERS>, } -impl<'a, const MAX_FILTERS: usize> UnsubscriptionPacket<'a, MAX_FILTERS> { +impl<'a, const MAX_FILTERS: usize, const MAX_PROPERTIES: usize> + UnsubscriptionPacket<'a, MAX_FILTERS, MAX_PROPERTIES> +{ /*pub fn new() -> Self { }*/ } -impl<'a, const MAX_FILTERS: usize> Packet<'a> for UnsubscriptionPacket<'a, MAX_FILTERS> { +impl<'a, const MAX_FILTERS: usize, const MAX_PROPERTIES: usize> Packet<'a> + for UnsubscriptionPacket<'a, MAX_FILTERS, MAX_PROPERTIES> +{ fn encode(&mut self, buffer: &mut [u8]) -> usize { let mut buff_writer = BuffWriter::new(buffer); let mut rm_ln = self.property_len; - let property_len_enc: [u8; 4] = VariableByteIntegerEncoder::encode(self.property_len).unwrap(); + let property_len_enc: [u8; 4] = + VariableByteIntegerEncoder::encode(self.property_len).unwrap(); let property_len_len = VariableByteIntegerEncoder::len(property_len_enc); rm_ln = rm_ln + property_len_len as u32 + 4 + self.topic_filter_len as u32; @@ -52,7 +55,11 @@ impl<'a, const MAX_FILTERS: usize> Packet<'a> for UnsubscriptionPacket<'a, MAX_F buff_writer.write_variable_byte_int(self.property_len); buff_writer.encode_properties::(&self.properties); buff_writer.write_u16(self.topic_filter_len); - buff_writer.encode_topic_filters_ref(false, self.topic_filter_len as usize, & self.topic_filters); + buff_writer.encode_topic_filters_ref( + false, + self.topic_filter_len as usize, + &self.topic_filters, + ); return buff_writer.position; } @@ -72,11 +79,11 @@ impl<'a, const MAX_FILTERS: usize> Packet<'a> for UnsubscriptionPacket<'a, MAX_F self.properties.push(property); } - fn set_fixed_header(& mut self, header: u8) { + fn set_fixed_header(&mut self, header: u8) { self.fixed_header = header; } - fn set_remaining_len(& mut self, remaining_len: u32) { + fn set_remaining_len(&mut self, remaining_len: u32) { self.remain_len = remaining_len; } } diff --git a/src/utils/buffer_writer.rs b/src/utils/buffer_writer.rs index 5939bf8..23a6d8f 100644 --- a/src/utils/buffer_writer.rs +++ b/src/utils/buffer_writer.rs @@ -1,8 +1,8 @@ +use crate::encoding::variable_byte_integer::{VariableByteInteger, VariableByteIntegerEncoder}; +use crate::packet::property::Property; use crate::utils::buffer_reader::{BinaryData, EncodedString, StringPair, TopicFilter}; use core::str; use heapless::Vec; -use crate::encoding::variable_byte_integer::{VariableByteInteger, VariableByteIntegerEncoder}; -use crate::packet::property::Property; pub struct BuffWriter<'a> { buffer: &'a mut [u8], @@ -10,8 +10,7 @@ pub struct BuffWriter<'a> { } impl<'a> BuffWriter<'a> { - - pub fn insert(& mut self, array: [u8; LEN]) { + pub fn insert(&mut self, array: [u8; LEN]) { let mut x: usize = 0; if LEN != 0 { loop { @@ -25,7 +24,7 @@ impl<'a> BuffWriter<'a> { } } - pub fn insert_ref(& mut self, len: usize, array: &[u8]) { + pub fn insert_ref(&mut self, len: usize, array: &[u8]) { let mut x: usize = 0; if len != 0 { loop { @@ -46,70 +45,70 @@ impl<'a> BuffWriter<'a> { }; } - fn increment_position(& mut self, increment: usize) { + fn increment_position(&mut self, increment: usize) { self.position = self.position + increment; } - pub fn write_u8(& mut self, byte: u8) { + pub fn write_u8(&mut self, byte: u8) { self.buffer[self.position] = byte; self.increment_position(1); } - pub fn write_u16(& mut self, two_bytes: u16) { + pub fn write_u16(&mut self, two_bytes: u16) { let bytes: [u8; 2] = two_bytes.to_be_bytes(); self.insert::<2>(bytes); } - pub fn write_u32(& mut self, four_bytes: u32) { + pub fn write_u32(&mut self, four_bytes: u32) { let bytes: [u8; 4] = four_bytes.to_be_bytes(); self.insert::<4>(bytes); } - pub fn write_string_ref(& mut self, str: & EncodedString<'a>) { + pub fn write_string_ref(&mut self, str: &EncodedString<'a>) { self.write_u16(str.len); let bytes = str.string.as_bytes(); self.insert_ref(str.len as usize, bytes); } - pub fn write_string(& mut self, str: EncodedString<'a>) { + pub fn write_string(&mut self, str: EncodedString<'a>) { self.write_u16(str.len); let bytes = str.string.as_bytes(); self.insert_ref(str.len as usize, bytes); } - pub fn write_binary_ref(& mut self, bin: & BinaryData<'a>) { + pub fn write_binary_ref(&mut self, bin: &BinaryData<'a>) { self.write_u16(bin.len); self.insert_ref(bin.len as usize, bin.bin); } - pub fn write_binary(& mut self, bin: BinaryData<'a>) { + pub fn write_binary(&mut self, bin: BinaryData<'a>) { self.write_u16(bin.len); self.insert_ref(bin.len as usize, bin.bin); } - pub fn write_string_pair_ref(& mut self, str_pair: & StringPair<'a>) { + pub fn write_string_pair_ref(&mut self, str_pair: &StringPair<'a>) { self.write_string_ref(&str_pair.name); self.write_string_ref(&str_pair.value); } - pub fn write_string_pair(& mut self, str_pair: StringPair<'a>) { + pub fn write_string_pair(&mut self, str_pair: StringPair<'a>) { self.write_string(str_pair.name); self.write_string(str_pair.value); } - pub fn write_variable_byte_int(& mut self, int: u32) { + pub fn write_variable_byte_int(&mut self, int: u32) { let x: VariableByteInteger = VariableByteIntegerEncoder::encode(int).unwrap(); let len = VariableByteIntegerEncoder::len(x); self.insert_ref(len, &x); } - pub fn encode_property(& mut self, property: & Property<'a>) { + pub fn encode_property(&mut self, property: &Property<'a>) { let x: u8 = property.into(); self.write_u8(x); property.encode(self); } - pub fn encode_properties(& mut self, properties: & Vec, LEN>) { + pub fn encode_properties(&mut self, properties: &Vec, LEN>) { let mut i = 0; let len = properties.len(); if len != 0 { @@ -124,17 +123,22 @@ impl<'a> BuffWriter<'a> { } } - fn encode_topic_filter_ref(& mut self, sub: bool, topic_filter: & TopicFilter<'a>) { + fn encode_topic_filter_ref(&mut self, sub: bool, topic_filter: &TopicFilter<'a>) { self.write_string_ref(&topic_filter.filter); if sub { self.write_u8(topic_filter.sub_options) } } - pub fn encode_topic_filters_ref(& mut self, sub: bool, len: usize, filters: & Vec, MAX>) { + pub fn encode_topic_filters_ref( + &mut self, + sub: bool, + len: usize, + filters: &Vec, MAX>, + ) { let mut i = 0; loop { - let topic_filter: & TopicFilter<'a> = filters.get(i).unwrap(); + let topic_filter: &TopicFilter<'a> = filters.get(i).unwrap(); self.encode_topic_filter_ref(sub, topic_filter); i = i + 1; if i == len { @@ -142,4 +146,4 @@ impl<'a> BuffWriter<'a> { } } } -} \ No newline at end of file +} From 5fda98525cb50c8c3e2c19861aae621d466f29ce Mon Sep 17 00:00:00 2001 From: Ondrej Babec Date: Mon, 21 Feb 2022 16:23:36 +0100 Subject: [PATCH 7/7] Clean up --- src/main.rs | 9 ++------- src/utils/buffer_writer.rs | 18 ++---------------- 2 files changed, 4 insertions(+), 23 deletions(-) diff --git a/src/main.rs b/src/main.rs index 36a99eb..d8ac3a5 100644 --- a/src/main.rs +++ b/src/main.rs @@ -15,13 +15,13 @@ fn main() { .format_timestamp_nanos() .init(); - let mut pckt: SubscriptionPacket<1> = SubscriptionPacket::new(); + let mut pckt: SubscriptionPacket<1, 0> = SubscriptionPacket::new(); let mut res = vec![0; 140]; let lnsub = pckt.encode(&mut res); println!("{:02X?}", &res[0..lnsub]); let mut res2 = vec![0; 260]; let mut x = b"hello world"; - let mut pblsh: PublishPacket = PublishPacket::new(x); + let mut pblsh = PublishPacket::<0>::new(x); let lnpblsh = pblsh.encode(&mut res2); println!("{:02X?}", &res2[0..lnpblsh]); log::info!("xxx"); @@ -51,8 +51,3 @@ fn main() { let prot = std::str::from_utf8(&bytes).unwrap(); log::info!("Protocol name: {}", prot)*/ } - -/*fn test(tst: &str) { - log::info!("xx"); - log::info!("Prvni: {}", ) -}*/ diff --git a/src/utils/buffer_writer.rs b/src/utils/buffer_writer.rs index 23a6d8f..bb6f974 100644 --- a/src/utils/buffer_writer.rs +++ b/src/utils/buffer_writer.rs @@ -10,20 +10,6 @@ pub struct BuffWriter<'a> { } impl<'a> BuffWriter<'a> { - pub fn insert(&mut self, array: [u8; LEN]) { - let mut x: usize = 0; - if LEN != 0 { - loop { - self.buffer[self.position] = array[x]; - self.increment_position(1); - x = x + 1; - if x == LEN { - break; - } - } - } - } - pub fn insert_ref(&mut self, len: usize, array: &[u8]) { let mut x: usize = 0; if len != 0 { @@ -56,12 +42,12 @@ impl<'a> BuffWriter<'a> { pub fn write_u16(&mut self, two_bytes: u16) { let bytes: [u8; 2] = two_bytes.to_be_bytes(); - self.insert::<2>(bytes); + self.insert_ref(2, &bytes); } pub fn write_u32(&mut self, four_bytes: u32) { let bytes: [u8; 4] = four_bytes.to_be_bytes(); - self.insert::<4>(bytes); + self.insert_ref(4,&bytes); } pub fn write_string_ref(&mut self, str: &EncodedString<'a>) {