Ownership problem

This commit is contained in:
Ondrej Babec 2022-02-10 13:32:52 +01:00
parent 8a638bba29
commit bdd5720c28
No known key found for this signature in database
GPG Key ID: 13E577E3769B2079
7 changed files with 175 additions and 60 deletions

View File

@ -9,6 +9,8 @@
pub struct VariableByteIntegerEncoder; pub struct VariableByteIntegerEncoder;
/// Variable byte integers error enumeration is used by both encoder and decoder for /// Variable byte integers error enumeration is used by both encoder and decoder for
/// error notification. /// error notification.
#[derive(core::fmt::Debug)]
#[derive(Clone)]
pub enum VariableByteIntegerError { pub enum VariableByteIntegerError {
EncodingError, EncodingError,
DecodingError DecodingError

View File

@ -1,8 +1,10 @@
use rust_mqtt::packet::mqtt_packet::Packet; use rust_mqtt::packet::mqtt_packet::*;
use rust_mqtt::packet::packet_type::PacketType; use rust_mqtt::packet::packet_type::PacketType;
use rust_mqtt::packet::packet_builder::PacketBuilder; use rust_mqtt::packet::packet_builder::PacketBuilder;
use rust_mqtt::encoding::variable_byte_integer::VariableByteIntegerEncoder; use rust_mqtt::encoding::variable_byte_integer::VariableByteIntegerEncoder;
use rust_mqtt::encoding::variable_byte_integer::VariableByteIntegerDecoder; use rust_mqtt::encoding::variable_byte_integer::VariableByteIntegerDecoder;
use rust_mqtt::packet::property::*;
use heapless::Vec;
fn main() { fn main() {
env_logger::builder() env_logger::builder()
@ -15,9 +17,9 @@ fn main() {
let z: u16 = 3; let z: u16 = 3;
let p: u32 = 4; let p: u32 = 4;
let mut txt = *b"abcde"; let mut txt = Vec::new();
let mut payld = *b"xxxxx"; let mut payld = *b"xxxxx";
let packet = Packet::clean(&mut txt, &mut payld); let packet = Packet::clean(txt, &mut payld);
let mut packet_builder = PacketBuilder::new(packet); let mut packet_builder = PacketBuilder::new(packet);
packet_builder.addPacketType(PacketType::Publish); packet_builder.addPacketType(PacketType::Publish);
@ -34,11 +36,8 @@ fn main() {
log::info!("{:02X?}", r); log::info!("{:02X?}", r);
let d = VariableByteIntegerDecoder::decode(r); let d = VariableByteIntegerDecoder::decode(r);
log::info!("Enum val: {}", o); log::info!("Enum val: {}", o);
let x = Packet::new( l, 0, z, 0, &mut txt, &mut payld );
log::info!("Hello world"); log::info!("Hello world");
x.encode();
x.get_reason_code();
} }

View File

@ -1,28 +1,48 @@
use super::property::Property;
use super::packet_type::PacketType;
use heapless::Vec;
pub const MAX_PROPERTIES: usize = 18;
pub struct Packet<'a> { pub struct Packet<'a> {
// 7 - 4 mqtt control packet type, 3-0 flagy // 7 - 4 mqtt control packet type, 3-0 flagy
pub header_control: u8, pub fixed_header: u8,
// 1 - 4 B lenght of variable header + len of payload // 1 - 4 B lenght of variable header + len of payload
pub remain_len: u32, pub remain_len: u32,
// variable header // 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 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 // property len
pub property_len: u32, pub property_len: u32,
// properties // properties
pub properties: &'a mut [u8], pub properties: Vec<Property<'a>, MAX_PROPERTIES>,
// Payload of message // Payload of message
pub payload: &'a mut [u8] pub payload: &'a mut [u8]
} }
impl<'a> Packet<'a> { impl<'a> Packet<'a> {
pub fn new(header_control: u8, remain_len: u32, packet_identifier: u16, property_len: u32, pub fn new(fixed_header: u8, remain_len: u32, packet_identifier: u16, protocol_name_len: u16,
properties: &'a mut [u8], payload: &'a mut [u8]) -> Self { protocol_name: u32, protocol_version: u8,
Self { header_control, remain_len, packet_identifier, property_len, properties, payload } connect_flags: u8, keep_alive: u16, property_len: u32,
properties: Vec<Property<'a>, 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: &'a mut [u8], payload: &'a mut [u8]) -> Self { pub fn clean(properties: Vec<Property<'a>, MAX_PROPERTIES>, payload: &'a mut [u8]) -> Self {
Self{ header_control: 0, remain_len: 0, packet_identifier: 0, property_len: 0, properties, payload } 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) { pub fn encode(&self) {

View File

@ -1,13 +1,18 @@
use super::mqtt_packet::Packet; use super::mqtt_packet::Packet;
use super::packet_type::PacketType; use super::packet_type::PacketType;
use super::property::Property;
use crate::utils::buffer_reader::*;
// Je potreba vytvori // Je potreba vytvori
// metody packet buildery budou prijimat jako parametr buff reader, z ktereho bude postupne parsovat
pub struct PacketBuilder<'a> { pub struct PacketBuilder<'a> {
currentPacket: Packet<'a>, currentPacket: Packet<'a>,
} }
impl<'a> PacketBuilder<'a> { impl<'a> PacketBuilder<'a> {
pub fn new(packet: Packet<'a>) -> Self { pub fn new(packet: Packet<'a>) -> Self {
Self{ currentPacket: packet } Self{ currentPacket: packet }
} }
@ -20,13 +25,13 @@ impl<'a> PacketBuilder<'a> {
return &self.currentPacket; return &self.currentPacket;
} }
pub fn addPacketType(& mut self, packet_type: PacketType) { pub fn addPacketType(& mut self, new_packet_type: PacketType) {
self.currentPacket.header_control = self.currentPacket.header_control & 0x0F; self.currentPacket.fixed_header = self.currentPacket.fixed_header & 0x0F;
self.currentPacket.header_control = self.currentPacket.header_control | <PacketType as Into<u8>>::into(packet_type); self.currentPacket.fixed_header = self.currentPacket.fixed_header | <PacketType as Into<u8>>::into(new_packet_type);
} }
pub fn addFlags(& mut self, dup: bool, qos: u8, retain: bool) { pub fn addFlags(& mut self, dup: bool, qos: u8, retain: bool) {
let cur_type: u8 = self.currentPacket.header_control & 0xF0; let cur_type: u8 = self.currentPacket.fixed_header & 0xF0;
if cur_type != 0x30 { if cur_type != 0x30 {
log::error!("Cannot add flags into packet with other than PUBLISH type"); log::error!("Cannot add flags into packet with other than PUBLISH type");
return; return;
@ -44,10 +49,51 @@ impl<'a> PacketBuilder<'a> {
if retain { if retain {
flags = flags | 0x01; flags = flags | 0x01;
} }
self.currentPacket.header_control = cur_type | flags; self.currentPacket.fixed_header = cur_type | flags;
} }
pub fn completePacket(& mut self) { pub fn completePacket(& mut self) {
// Tutaj se cely packet dokonci - spocita se remaining len co chybi v hlavicce atd... // Tutaj se cely packet dokonci - spocita se remaining len co chybi v hlavicce atd...
} }
pub fn decode_packet(& mut self, buff_reader: &'a mut BuffReader) {
self.decodeFixedHeader(buff_reader);
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 decodeControllPacket(& mut self, buff_reader: &'a mut BuffReader) {
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.currentPacket.property_len = buff_reader.readVariableByteInt().unwrap();
let mut x: u32 = 0;
let mut prop: Result<Property, ProperyParseError>;
let mut res;
loop {
prop = Property::decode(buff_reader);
if prop.is_ok() {
res = prop.unwrap();
self.currentPacket.properties.push(res);
} else {
log::error!("Decoding property did not went well!");
}
x = x + res.len() as u32 + 1;
if x == self.currentPacket.property_len {
break;
}
}
}
} }

View File

@ -1,6 +1,6 @@
// x x x x - - - - // x x x x - - - -
#[derive(PartialEq)]
pub enum PacketType { pub enum PacketType {
Reserved, Reserved,
Connect, Connect,
@ -22,7 +22,8 @@ pub enum PacketType {
impl From<u8> for PacketType { impl From<u8> for PacketType {
fn from(orig: u8) -> Self { fn from(orig: u8) -> Self {
match orig { let packet_type: u8 = orig & 0xF0;
match packet_type {
0x10 => return PacketType::Connect, 0x10 => return PacketType::Connect,
0x20 => return PacketType::Connack, 0x20 => return PacketType::Connack,
0x00 => return PacketType::Reserved, 0x00 => return PacketType::Reserved,

View File

@ -3,15 +3,9 @@ use crate::utils::buffer_reader::StringPair;
use crate::utils::buffer_reader::EncodedString; use crate::utils::buffer_reader::EncodedString;
use crate::utils::buffer_reader::BinaryData; use crate::utils::buffer_reader::BinaryData;
use crate::encoding::variable_byte_integer::VariableByteIntegerError; use crate::encoding::variable_byte_integer::VariableByteIntegerError;
/*use crate::encoding::variable_byte_integer::VariableByteIntegerDecoder; use crate::utils::buffer_reader::BuffReader;
use crate::encoding::variable_byte_integer::VariableByteIntegerError;
use core::str;
#[derive(Clone)]
pub trait Decode<'a> {
fn decode(input: &'a [u8], offset: &'a mut usize) -> Result<Self, ProperyParseError> where Self: Sized;
}
*/
pub enum Property<'a> { pub enum Property<'a> {
PayloadFormat(Result<u8, ProperyParseError>), PayloadFormat(Result<u8, ProperyParseError>),
MessageExpiryInterval(Result<u32, ProperyParseError>), MessageExpiryInterval(Result<u32, ProperyParseError>),
@ -42,40 +36,70 @@ pub enum Property<'a> {
SharedSubscriptionAvailable(Result<u8, ProperyParseError>) SharedSubscriptionAvailable(Result<u8, ProperyParseError>)
} }
/* impl<'a> Property<'a> {
impl<'a> Decode<'a> for Property<'a> { pub fn len(mut self) -> u16 {
fn decode(input: &'a [u8], offset: &'a mut usize) -> Result<Self, ProperyParseError> { match self {
let propertyIdentifier = parseU8(input, offset); Property::PayloadFormat(u) => return 1,
Property::MessageExpiryInterval(u) => return 4,
Property::ContentType(u) => return u.unwrap().len(),
Property::ResponseTopic(u) => return u.unwrap().len(),
Property::CorrelationData(u) => return u.unwrap().len(),
Property::SubscriptionIdentifier(u) => return 4,
Property::AssignedClientIdentifier(u) => return u.unwrap().len(),
Property::ServerKeepAlive(u) => return 2,
Property::AuthenticationMethod(u) => return u.unwrap().len(),
Property::AuthenticationData(u) => return u.unwrap().len(),
Property::RequestProblemInformation(u) => return 1,
Property::WillDelayInterval(u) => return 4,
Property::RequestResponseInformation(u) => return 1,
Property::ResponseInformation(u) => return u.unwrap().len(),
Property::ServerReference(u) => return u.unwrap().len(),
Property::ReasonString(u) => return u.unwrap().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.unwrap().len(),
Property::MaximumPacketSize(u) => return 4,
Property::WildcardSubscriptionAvailable(u) => return 1,
Property::SubscriptionIdentifierAvailable(u) => return 1,
Property::SharedSubscriptionAvailable(u) => return 1,
_ => return 0
}
}
pub fn decode(buff_reader: &'a mut BuffReader) -> Result<Property<'a>, ProperyParseError> {
let propertyIdentifier = buff_reader.readU8();
match propertyIdentifier { match propertyIdentifier {
Ok(0x01) => return Ok(Property::PayloadFormat(parseU8(input, offset))), Ok(0x01) => return Ok(Property::PayloadFormat(buff_reader.readU8())),
Ok(0x02) => return Ok(Property::MessageExpiryInterval(parseU32(input, offset))), Ok(0x02) => return Ok(Property::MessageExpiryInterval(buff_reader.readU32())),
Ok(0x03) => return Ok(Property::ContentType(parseString(input, offset))), Ok(0x03) => return Ok(Property::ContentType(buff_reader.readString())),
Ok(0x08) => return Ok(Property::ResponseTopic(parseString(input, offset))), Ok(0x08) => return Ok(Property::ResponseTopic(buff_reader.readString())),
Ok(0x09) => return Ok(Property::CorrelationData(parseBinary(input, offset))), Ok(0x09) => return Ok(Property::CorrelationData(buff_reader.readBinary())),
Ok(0x0B) => return Ok(Property::SubscriptionIdentifier(parseVariableByteInt(input, offset))), Ok(0x0B) => return Ok(Property::SubscriptionIdentifier(buff_reader.readVariableByteInt())),
Ok(0x11) => return Ok(Property::SessionExpiryInterval(parseU32(input, offset))), Ok(0x11) => return Ok(Property::SessionExpiryInterval(buff_reader.readU32())),
Ok(0x12) => return Ok(Property::AssignedClientIdentifier(parseString(input, offset))), Ok(0x12) => return Ok(Property::AssignedClientIdentifier(buff_reader.readString())),
Ok(0x13) => return Ok(Property::ServerKeepAlive(parseU16(input, offset))), Ok(0x13) => return Ok(Property::ServerKeepAlive(buff_reader.readU16())),
Ok(0x15) => return Ok(Property::AuthenticationMethod(parseString(input, offset))), Ok(0x15) => return Ok(Property::AuthenticationMethod(buff_reader.readString())),
Ok(0x16) => return Ok(Property::AuthenticationData(parseBinary(input, offset))), Ok(0x16) => return Ok(Property::AuthenticationData(buff_reader.readBinary())),
Ok(0x17) => return Ok(Property::RequestProblemInformation(parseU8(input, offset))), Ok(0x17) => return Ok(Property::RequestProblemInformation(buff_reader.readU8())),
Ok(0x18) => return Ok(Property::WillDelayInterval(parseU32(input, offset))), Ok(0x18) => return Ok(Property::WillDelayInterval(buff_reader.readU32())),
Ok(0x19) => return Ok(Property::RequestResponseInformation(parseU8(input, offset))), Ok(0x19) => return Ok(Property::RequestResponseInformation(buff_reader.readU8())),
Ok(0x1A) => return Ok(Property::ResponseInformation(parseString(input, offset))), Ok(0x1A) => return Ok(Property::ResponseInformation(buff_reader.readString())),
Ok(0x1C) => return Ok(Property::ServerReference(parseString(input, offset))), Ok(0x1C) => return Ok(Property::ServerReference(buff_reader.readString())),
Ok(0x1F) => return Ok(Property::ReasonString(parseString(input, offset))), Ok(0x1F) => return Ok(Property::ReasonString(buff_reader.readString())),
Ok(0x21) => return Ok(Property::ReceiveMaximum(parseU16(input, offset))), Ok(0x21) => return Ok(Property::ReceiveMaximum(buff_reader.readU16())),
Ok(0x22) => return Ok(Property::TopicAliasMaximum(parseU16(input, offset))), Ok(0x22) => return Ok(Property::TopicAliasMaximum(buff_reader.readU16())),
Ok(0x23) => return Ok(Property::TopicAlias(parseU16(input, offset))), Ok(0x23) => return Ok(Property::TopicAlias(buff_reader.readU16())),
Ok(0x24) => return Ok(Property::MaximumQoS(parseU8(input, offset))), Ok(0x24) => return Ok(Property::MaximumQoS(buff_reader.readU8())),
Ok(0x25) => return Ok(Property::RetainAvailable(parseU8(input, offset))), Ok(0x25) => return Ok(Property::RetainAvailable(buff_reader.readU8())),
Ok(0x26) => return Ok(Property::UserProperty(parseStringPair(input, offset))), Ok(0x26) => return Ok(Property::UserProperty(buff_reader.readStringPair())),
Ok(0x28) => return Ok(Property::WildcardSubscriptionAvailable(parseU8(input, offset))), Ok(0x28) => return Ok(Property::WildcardSubscriptionAvailable(buff_reader.readU8())),
Ok(0x29) => return Ok(Property::SubscriptionIdentifierAvailable(parseU8(input, offset))), Ok(0x29) => return Ok(Property::SubscriptionIdentifierAvailable(buff_reader.readU8())),
Ok(0x2A) => return Ok(Property::SharedSubscriptionAvailable(parseU8(input, offset))), Ok(0x2A) => return Ok(Property::SharedSubscriptionAvailable(buff_reader.readU8())),
Err(err) => return Err(err), Err(err) => return Err(err),
_ => return Err(ProperyParseError::IdNotFound) _ => return Err(ProperyParseError::IdNotFound)
} }
} }
}*/ }

View File

@ -3,22 +3,45 @@ use crate::encoding::variable_byte_integer::VariableByteIntegerError;
use core::str; use core::str;
use core::mem; use core::mem;
#[derive(Clone)]
pub struct EncodedString<'a> { pub struct EncodedString<'a> {
pub string: &'a str, pub string: &'a str,
pub len: u16 pub len: u16
} }
impl EncodedString<'_> {
pub fn len(&self) -> u16 {
return self.len + 2;
}
}
#[derive(Clone)]
pub struct BinaryData<'a> { pub struct BinaryData<'a> {
pub bin: &'a [u8], pub bin: &'a [u8],
pub len: u16 pub len: u16
} }
impl BinaryData<'_> {
pub fn len(&self) -> u16 {
return self.len + 2;
}
}
#[derive(Clone)]
pub struct StringPair<'a> { pub struct StringPair<'a> {
pub name: EncodedString<'a>, pub name: EncodedString<'a>,
pub value: EncodedString<'a> pub value: EncodedString<'a>
} }
impl StringPair<'_> {
pub fn len(&self) -> u16 {
let ln = self.name.len() + self.value.len();
return ln;
}
}
#[derive(core::fmt::Debug)] #[derive(core::fmt::Debug)]
#[derive(Clone)]
pub enum ProperyParseError { pub enum ProperyParseError {
Utf8Error, Utf8Error,
IndexOutOfBounce, IndexOutOfBounce,