Update documentation

This commit is contained in:
Ondrej Babec 2022-05-05 07:47:07 +02:00
parent 63314fc867
commit e47667156d
No known key found for this signature in database
GPG Key ID: 13E577E3769B2079
5 changed files with 73 additions and 5 deletions

View File

@ -141,6 +141,10 @@ where
}
}
/// Method allows client connect to server. Client is connecting to the specified broker
/// in the `ClientConfig`. Method selects proper implementation of the MQTT version based on the config.
/// If the connection to the broker fails, method returns Err variable that contains
/// Reason codes returned from the broker.
pub async fn connect_to_broker<'b>(&'b mut self) -> Result<(), ReasonCode> {
match self.config.mqtt_version {
MqttVersion::MQTTv3 => Err(ReasonCode::UnsupportedProtocolVersion),
@ -175,6 +179,10 @@ where
Ok(())
}
/// Method allows client disconnect from the server. Client disconnects from the specified broker
/// in the `ClientConfig`. Method selects proper implementation of the MQTT version based on the config.
/// If the disconnect from the broker fails, method returns Err variable that contains
/// Reason codes returned from the broker.
pub async fn disconnect<'b>(&'b mut self) -> Result<(), ReasonCode> {
match self.config.mqtt_version {
MqttVersion::MQTTv3 => Err(ReasonCode::UnsupportedProtocolVersion),
@ -242,7 +250,10 @@ where
}
Ok(())
}
/// Method allows sending message to broker specified from the ClientConfig. Client sends the
/// message from the parameter `message` to the topic `topic_name` on the broker
/// specified in the ClientConfig. If the send fails method returns Err with reason code
/// received by broker.
pub async fn send_message<'b>(
&'b mut self,
topic_name: &'b str,
@ -314,6 +325,10 @@ where
Ok(())
}
/// Method allows client subscribe to multiple topics specified in the parameter
/// `topic_names` on the broker specified in the `ClientConfig`. Generics `TOPICS`
/// sets the value of the `topics_names` vector. MQTT protocol implementation
/// is selected automatically.
pub async fn subscribe_to_topics<'b, const TOPICS: usize>(
&'b mut self,
topic_names: &'b Vec<&'b str, TOPICS>,
@ -324,6 +339,9 @@ where
}
}
/// Method allows client unsubscribe from the topic specified in the parameter
/// `topic_name` on the broker from the `ClientConfig`. MQTT protocol implementation
/// is selected automatically.
pub async fn unsubscribe_from_topic<'b>(
&'b mut self,
topic_name: &'b str,
@ -334,7 +352,7 @@ where
}
}
pub async fn unsubscribe_from_topic_v5<'b>(
async fn unsubscribe_from_topic_v5<'b>(
&'b mut self,
topic_name: &'b str,
) -> Result<(), ReasonCode> {
@ -422,6 +440,9 @@ where
}
}
/// Method allows client subscribe to multiple topics specified in the parameter
/// `topic_name` on the broker specified in the `ClientConfig`. MQTT protocol implementation
/// is selected automatically.
pub async fn subscribe_to_topic<'b>(
&'b mut self,
topic_name: &'b str,
@ -471,6 +492,9 @@ where
return Ok(packet.message.unwrap());
}
/// Method allows client receive a message. The work of this method strictly depends on the
/// network implementation passed in the `ClientConfig`. It expects the PUBLISH packet
/// from the broker.
pub async fn receive_message<'b>(&'b mut self) -> Result<&'b [u8], ReasonCode> {
match self.config.mqtt_version {
MqttVersion::MQTTv3 => Err(ReasonCode::UnsupportedProtocolVersion),
@ -505,6 +529,9 @@ where
}
}
/// Method allows client send PING message to the broker specified in the `ClientConfig`.
/// If there is expectation for long running connection. Method should be executed
/// regularly by the timer that counts down the session expiry interval.
pub async fn send_ping<'b>(&'b mut self) -> Result<(), ReasonCode> {
match self.config.mqtt_version {
MqttVersion::MQTTv3 => Err(ReasonCode::UnsupportedProtocolVersion),

View File

@ -34,7 +34,16 @@ pub enum MqttVersion {
MQTTv3,
MQTTv5,
}
/// Client config is main configuration for the `MQTTClient` structure.
/// All of the properties are optional if they are not set they are not gonna
/// be used. Configuration contains also MQTTv5 properties. Generic constant
/// `MAX_PROPERTIES` sets the length for the properties Vec. User can insert
/// all the properties and client will automatically use variables that are
/// usable for the specific packet types. `mqtt_version` sets the version
/// of the MQTT protocol that is gonna be used. Config also expects the rng
/// implementation. This implementation is used for generating packet identifiers.
/// There is counting rng implementation in the `utils` module that can be used.
/// Examples of the configurations can be found in the integration tests.
#[derive(Clone)]
pub struct ClientConfig<'a, const MAX_PROPERTIES: usize, T: RngCore> {
pub qos: QualityOfService,
@ -69,6 +78,8 @@ impl<'a, const MAX_PROPERTIES: usize, T: RngCore> ClientConfig<'a, MAX_PROPERTIE
self.qos = qos;
}
/// Method adds the username array and also sets the username flag so client
/// will use it for the authentication
pub fn add_username(&mut self, username: &'a str) {
let mut username_s: EncodedString = EncodedString::new();
username_s.string = username;
@ -76,7 +87,8 @@ impl<'a, const MAX_PROPERTIES: usize, T: RngCore> ClientConfig<'a, MAX_PROPERTIE
self.username_flag = true;
self.username = username_s;
}
/// Method adds the password array and also sets the password flag so client
/// will use it for the authentication
pub fn add_password(&mut self, password: &'a str) {
let mut password_s: BinaryData = BinaryData::new();
password_s.bin = password.as_bytes();
@ -85,12 +97,14 @@ impl<'a, const MAX_PROPERTIES: usize, T: RngCore> ClientConfig<'a, MAX_PROPERTIE
self.password_flag = true;
}
/// Method adds the property to the properties Vec if there is still space. Otherwise do nothing.
pub fn add_property(&mut self, prop: Property<'a>) {
if self.properties.len() < MAX_PROPERTIES {
self.properties.push(prop);
}
}
/// Method encode the `max_packet_size` attribute as property to the properties Vec.
pub fn add_max_packet_size_as_prop(&mut self) -> u32 {
if self.properties.len() < MAX_PROPERTIES {
let prop = Property::MaximumPacketSize(self.max_packet_size);

View File

@ -34,7 +34,8 @@ pub enum NetworkError {
IDNotMatchedOnAck,
NoMatchingSubs,
}
/// NetworkConnectionFactory implementation should create a TCP connection and return
/// the `Connection` trait implementation. Otherwise return `ReasonCode`.
pub trait NetworkConnectionFactory: Sized {
type Connection: NetworkConnection;
@ -42,9 +43,11 @@ pub trait NetworkConnectionFactory: Sized {
where
Self: 'm;
/// Connect function estabilish TCP connection and return the `Connection`.
fn connect<'m>(&'m mut self, ip: [u8; 4], port: u16) -> Self::ConnectionFuture<'m>;
}
/// Network connection represents estabilished TCP connection created with `NetworkConnectionFactory`.
pub trait NetworkConnection {
type SendFuture<'m>: Future<Output = Result<(), ReasonCode>>
where
@ -56,9 +59,12 @@ pub trait NetworkConnection {
type CloseFuture<'m>: Future<Output = Result<(), ReasonCode>>;
/// Send function should enable sending the data from `buffer` via TCP connection.
fn send<'m>(&'m mut self, buffer: &'m [u8]) -> Self::SendFuture<'m>;
/// Receive should enable receiving data to the `buffer` from TCP connection.
fn receive<'m>(&'m mut self, buffer: &'m mut [u8]) -> Self::ReceiveFuture<'m>;
/// Close function should close the TCP connection.
fn close<'m>(self) -> Self::CloseFuture<'m>;
}

View File

@ -34,6 +34,8 @@ use tokio::net::TcpStream;
use crate::network::{NetworkConnection, NetworkConnectionFactory};
use crate::packet::v5::reason_codes::ReasonCode;
/// TokioNetwork is an implementation of the `NetworkConnection` trait. This implementation
/// allows communication through the `Tokio` TcpStream.
pub struct TokioNetwork {
stream: TcpStream,
}
@ -86,6 +88,8 @@ impl NetworkConnection for TokioNetwork {
}
}
/// TokioNetworkFactory is an implementation of the `NetworkConnectionFactory` trait. This implementation
/// allows to establish the `Tokio` TcpStream connection.
pub struct TokioNetworkFactory {}
impl TokioNetworkFactory {

View File

@ -28,6 +28,8 @@ use crate::encoding::variable_byte_integer::{VariableByteInteger, VariableByteIn
use crate::packet::v5::property::Property;
use crate::utils::types::{BinaryData, BufferError, EncodedString, StringPair, TopicFilter};
/// Buff writer is writing corresponding types to buffer (Byte array) and stores current position
/// (later as cursor)
pub struct BuffWriter<'a> {
buffer: &'a mut [u8],
pub position: usize,
@ -47,6 +49,7 @@ impl<'a> BuffWriter<'a> {
self.position = self.position + increment;
}
/// Returns n-th Byte from the buffer to which is currently written.
pub fn get_n_byte(&mut self, n: usize) -> u8 {
if self.position >= n {
return self.buffer[n];
@ -54,6 +57,7 @@ impl<'a> BuffWriter<'a> {
return 0;
}
/// Return the remaining lenght of the packet from the buffer to which is packet written.
pub fn get_rem_len(&mut self) -> Result<VariableByteInteger, ()> {
let max = if self.position >= 5 {
4
@ -77,6 +81,7 @@ impl<'a> BuffWriter<'a> {
}
}
/// Writes an array to the buffer.
pub fn insert_ref(&mut self, len: usize, array: &[u8]) -> Result<(), BufferError> {
let mut x: usize = 0;
if self.position + len > self.len {
@ -95,6 +100,7 @@ impl<'a> BuffWriter<'a> {
return Ok(());
}
/// Writes a single Byte to the buffer.
pub fn write_u8(&mut self, byte: u8) -> Result<(), BufferError> {
return if self.position >= self.len {
Err(BufferError::InsufficientBufferSize)
@ -105,16 +111,19 @@ impl<'a> BuffWriter<'a> {
};
}
/// Writes the two Byte value to the buffer.
pub fn write_u16(&mut self, two_bytes: u16) -> Result<(), BufferError> {
let bytes: [u8; 2] = two_bytes.to_be_bytes();
return self.insert_ref(2, &bytes);
}
/// Writes the four Byte value to the buffer.
pub fn write_u32(&mut self, four_bytes: u32) -> Result<(), BufferError> {
let bytes: [u8; 4] = four_bytes.to_be_bytes();
return self.insert_ref(4, &bytes);
}
/// Writes the UTF-8 string type to the buffer.
pub fn write_string_ref(&mut self, str: &EncodedString<'a>) -> Result<(), BufferError> {
self.write_u16(str.len)?;
if str.len != 0 {
@ -124,16 +133,19 @@ impl<'a> BuffWriter<'a> {
return Ok(());
}
/// Writes BinaryData to the buffer.
pub fn write_binary_ref(&mut self, bin: &BinaryData<'a>) -> Result<(), BufferError> {
self.write_u16(bin.len)?;
return self.insert_ref(bin.len as usize, bin.bin);
}
/// Writes the string pair to the buffer.
pub fn write_string_pair_ref(&mut self, str_pair: &StringPair<'a>) -> Result<(), BufferError> {
self.write_string_ref(&str_pair.name)?;
return self.write_string_ref(&str_pair.value);
}
/// Encodes the u32 value into the VariableByteInteger and this value writes to the buffer.
pub fn write_variable_byte_int(&mut self, int: u32) -> Result<(), BufferError> {
let x: VariableByteInteger = VariableByteIntegerEncoder::encode(int)?;
let len = VariableByteIntegerEncoder::len(x);
@ -146,6 +158,7 @@ impl<'a> BuffWriter<'a> {
return property.encode(self);
}
/// Writes all properties from the `properties` Vec into the buffer.
pub fn write_properties<const LEN: usize>(
&mut self,
properties: &Vec<Property<'a>, LEN>,
@ -165,6 +178,8 @@ impl<'a> BuffWriter<'a> {
Ok(())
}
/// Writes the MQTT `TopicFilter` into the buffer. If the `sub` option is set to `false`, it will
/// not write the `sub_options` only topic name.
fn write_topic_filter_ref(
&mut self,
sub: bool,
@ -177,6 +192,8 @@ impl<'a> BuffWriter<'a> {
return Ok(());
}
/// Writes the topic filter Vec to the buffer. If the `sub` option is set to `false`, it will not
/// write the `sub_options` only topic names.
pub fn write_topic_filters_ref<const MAX: usize>(
&mut self,
sub: bool,