From e4c3505aaf7e0a126a13b3be3ae33fd76522027e Mon Sep 17 00:00:00 2001 From: Ondrej Babec Date: Sun, 20 Feb 2022 13:25:44 +0100 Subject: [PATCH] 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;