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;
/// Variable byte integers error enumeration is used by both encoder and decoder for
/// error notification.
#[derive(core::fmt::Debug)]
#[derive(Clone)]
pub enum VariableByteIntegerError {
EncodingError,
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_builder::PacketBuilder;
use rust_mqtt::encoding::variable_byte_integer::VariableByteIntegerEncoder;
use rust_mqtt::encoding::variable_byte_integer::VariableByteIntegerDecoder;
use rust_mqtt::packet::property::*;
use heapless::Vec;
fn main() {
env_logger::builder()
@ -15,9 +17,9 @@ fn main() {
let z: u16 = 3;
let p: u32 = 4;
let mut txt = *b"abcde";
let mut txt = Vec::new();
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);
packet_builder.addPacketType(PacketType::Publish);
@ -34,11 +36,8 @@ fn main() {
log::info!("{:02X?}", r);
let d = VariableByteIntegerDecoder::decode(r);
log::info!("Enum val: {}", o);
let x = Packet::new( l, 0, z, 0, &mut txt, &mut payld );
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> {
// 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
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: &'a mut [u8],
pub properties: Vec<Property<'a>, MAX_PROPERTIES>,
// Payload of message
pub payload: &'a mut [u8]
}
impl<'a> Packet<'a> {
pub fn new(header_control: u8, remain_len: u32, packet_identifier: u16, property_len: u32,
properties: &'a mut [u8], payload: &'a mut [u8]) -> Self {
Self { header_control, remain_len, packet_identifier, property_len, properties, payload }
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<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 {
Self{ header_control: 0, remain_len: 0, packet_identifier: 0, property_len: 0, properties, payload }
pub fn clean(properties: Vec<Property<'a>, 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) {

View File

@ -1,13 +1,18 @@
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> {
currentPacket: Packet<'a>,
}
impl<'a> PacketBuilder<'a> {
pub fn new(packet: Packet<'a>) -> Self {
Self{ currentPacket: packet }
}
@ -20,13 +25,13 @@ impl<'a> PacketBuilder<'a> {
return &self.currentPacket;
}
pub fn addPacketType(& mut self, packet_type: PacketType) {
self.currentPacket.header_control = self.currentPacket.header_control & 0x0F;
self.currentPacket.header_control = self.currentPacket.header_control | <PacketType as Into<u8>>::into(packet_type);
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 | <PacketType as Into<u8>>::into(new_packet_type);
}
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 {
log::error!("Cannot add flags into packet with other than PUBLISH type");
return;
@ -44,10 +49,51 @@ impl<'a> PacketBuilder<'a> {
if retain {
flags = flags | 0x01;
}
self.currentPacket.header_control = cur_type | flags;
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: &'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 - - - -
#[derive(PartialEq)]
pub enum PacketType {
Reserved,
Connect,
@ -22,7 +22,8 @@ pub enum PacketType {
impl From<u8> for PacketType {
fn from(orig: u8) -> Self {
match orig {
let packet_type: u8 = orig & 0xF0;
match packet_type {
0x10 => return PacketType::Connect,
0x20 => return PacketType::Connack,
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::BinaryData;
use crate::encoding::variable_byte_integer::VariableByteIntegerError;
/*use crate::encoding::variable_byte_integer::VariableByteIntegerDecoder;
use crate::encoding::variable_byte_integer::VariableByteIntegerError;
use core::str;
use crate::utils::buffer_reader::BuffReader;
pub trait Decode<'a> {
fn decode(input: &'a [u8], offset: &'a mut usize) -> Result<Self, ProperyParseError> where Self: Sized;
}
*/
#[derive(Clone)]
pub enum Property<'a> {
PayloadFormat(Result<u8, ProperyParseError>),
MessageExpiryInterval(Result<u32, ProperyParseError>),
@ -42,40 +36,70 @@ pub enum Property<'a> {
SharedSubscriptionAvailable(Result<u8, ProperyParseError>)
}
/*
impl<'a> Decode<'a> for Property<'a> {
fn decode(input: &'a [u8], offset: &'a mut usize) -> Result<Self, ProperyParseError> {
let propertyIdentifier = parseU8(input, offset);
impl<'a> Property<'a> {
pub fn len(mut self) -> u16 {
match self {
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 {
Ok(0x01) => return Ok(Property::PayloadFormat(parseU8(input, offset))),
Ok(0x02) => return Ok(Property::MessageExpiryInterval(parseU32(input, offset))),
Ok(0x03) => return Ok(Property::ContentType(parseString(input, offset))),
Ok(0x08) => return Ok(Property::ResponseTopic(parseString(input, offset))),
Ok(0x09) => return Ok(Property::CorrelationData(parseBinary(input, offset))),
Ok(0x0B) => return Ok(Property::SubscriptionIdentifier(parseVariableByteInt(input, offset))),
Ok(0x11) => return Ok(Property::SessionExpiryInterval(parseU32(input, offset))),
Ok(0x12) => return Ok(Property::AssignedClientIdentifier(parseString(input, offset))),
Ok(0x13) => return Ok(Property::ServerKeepAlive(parseU16(input, offset))),
Ok(0x15) => return Ok(Property::AuthenticationMethod(parseString(input, offset))),
Ok(0x16) => return Ok(Property::AuthenticationData(parseBinary(input, offset))),
Ok(0x17) => return Ok(Property::RequestProblemInformation(parseU8(input, offset))),
Ok(0x18) => return Ok(Property::WillDelayInterval(parseU32(input, offset))),
Ok(0x19) => return Ok(Property::RequestResponseInformation(parseU8(input, offset))),
Ok(0x1A) => return Ok(Property::ResponseInformation(parseString(input, offset))),
Ok(0x1C) => return Ok(Property::ServerReference(parseString(input, offset))),
Ok(0x1F) => return Ok(Property::ReasonString(parseString(input, offset))),
Ok(0x21) => return Ok(Property::ReceiveMaximum(parseU16(input, offset))),
Ok(0x22) => return Ok(Property::TopicAliasMaximum(parseU16(input, offset))),
Ok(0x23) => return Ok(Property::TopicAlias(parseU16(input, offset))),
Ok(0x24) => return Ok(Property::MaximumQoS(parseU8(input, offset))),
Ok(0x25) => return Ok(Property::RetainAvailable(parseU8(input, offset))),
Ok(0x26) => return Ok(Property::UserProperty(parseStringPair(input, offset))),
Ok(0x28) => return Ok(Property::WildcardSubscriptionAvailable(parseU8(input, offset))),
Ok(0x29) => return Ok(Property::SubscriptionIdentifierAvailable(parseU8(input, offset))),
Ok(0x2A) => return Ok(Property::SharedSubscriptionAvailable(parseU8(input, offset))),
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(ProperyParseError::IdNotFound)
}
}
}*/
}

View File

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