use heapless::Vec;
use crate::encoding::variable_byte_integer::VariableByteIntegerEncoder;
use crate::packet::v5::mqtt_packet::Packet;
use crate::packet::v5::publish_packet::QualityOfService;
use crate::utils::buffer_reader::BuffReader;
use crate::utils::buffer_writer::BuffWriter;
use crate::utils::types::{BufferError, TopicFilter};
use super::packet_type::PacketType;
use super::property::Property;
pub struct SubscriptionPacket<'a, const MAX_FILTERS: usize, const MAX_PROPERTIES: usize> {
pub fixed_header: u8,
pub remain_len: u32,
pub packet_identifier: u16,
pub property_len: u32,
pub properties: Vec<Property<'a>, MAX_PROPERTIES>,
pub topic_filter_len: u16,
pub topic_filters: Vec<TopicFilter<'a>, MAX_FILTERS>,
}
impl<'a, const MAX_FILTERS: usize, const MAX_PROPERTIES: usize>
SubscriptionPacket<'a, MAX_FILTERS, MAX_PROPERTIES>
{
pub fn add_new_filter(&mut self, topic_name: &'a str, qos: QualityOfService) {
let len = topic_name.len();
let mut new_filter = TopicFilter::new();
new_filter.filter.string = topic_name;
new_filter.filter.len = len as u16;
new_filter.sub_options |= <QualityOfService as Into<u8>>::into(qos) >> 1;
self.topic_filters.push(new_filter);
self.topic_filter_len += 1;
}
}
impl<'a, const MAX_FILTERS: usize, const MAX_PROPERTIES: usize> Packet<'a>
for SubscriptionPacket<'a, MAX_FILTERS, MAX_PROPERTIES>
{
fn new() -> Self {
Self {
fixed_header: PacketType::Subscribe.into(),
remain_len: 0,
packet_identifier: 1,
property_len: 0,
properties: Vec::<Property<'a>, MAX_PROPERTIES>::new(),
topic_filter_len: 0,
topic_filters: Vec::<TopicFilter<'a>, MAX_FILTERS>::new(),
}
}
fn encode(&mut self, buffer: &mut [u8], buffer_len: usize) -> Result<usize, BufferError> {
let mut buff_writer = BuffWriter::new(buffer, buffer_len);
let mut rm_ln = self.property_len;
let property_len_enc: [u8; 4] = VariableByteIntegerEncoder::encode(self.property_len)?;
let property_len_len = VariableByteIntegerEncoder::len(property_len_enc);
let mut lt = 0;
let mut filters_len = 0;
loop {
filters_len = filters_len + self.topic_filters.get(lt).unwrap().filter.len + 3;
lt += 1;
if lt == self.topic_filter_len as usize {
break;
}
}
rm_ln = rm_ln + property_len_len as u32 + 2 + filters_len as u32;
buff_writer.write_u8(self.fixed_header)?;
buff_writer.write_variable_byte_int(rm_ln)?;
buff_writer.write_u16(self.packet_identifier)?;
buff_writer.write_variable_byte_int(self.property_len)?;
buff_writer.write_properties::<MAX_PROPERTIES>(&self.properties)?;
buff_writer.write_topic_filters_ref(
true,
self.topic_filter_len as usize,
&self.topic_filters,
)?;
Ok(buff_writer.position)
}
fn decode(&mut self, _buff_reader: &mut BuffReader<'a>) -> Result<(), BufferError> {
error!("Subscribe packet does not support decode funtion on client!");
Err(BufferError::WrongPacketToDecode)
}
fn set_property_len(&mut self, value: u32) {
self.property_len = value;
}
fn get_property_len(&mut self) -> u32 {
self.property_len
}
fn push_to_properties(&mut self, property: Property<'a>) {
self.properties.push(property);
}
fn property_allowed(&mut self, property: &Property<'a>) -> bool {
property.subscribe_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;
}
}