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