Update documentation
This commit is contained in:
parent
63314fc867
commit
e47667156d
|
@ -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> {
|
pub async fn connect_to_broker<'b>(&'b mut self) -> Result<(), ReasonCode> {
|
||||||
match self.config.mqtt_version {
|
match self.config.mqtt_version {
|
||||||
MqttVersion::MQTTv3 => Err(ReasonCode::UnsupportedProtocolVersion),
|
MqttVersion::MQTTv3 => Err(ReasonCode::UnsupportedProtocolVersion),
|
||||||
|
@ -175,6 +179,10 @@ where
|
||||||
Ok(())
|
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> {
|
pub async fn disconnect<'b>(&'b mut self) -> Result<(), ReasonCode> {
|
||||||
match self.config.mqtt_version {
|
match self.config.mqtt_version {
|
||||||
MqttVersion::MQTTv3 => Err(ReasonCode::UnsupportedProtocolVersion),
|
MqttVersion::MQTTv3 => Err(ReasonCode::UnsupportedProtocolVersion),
|
||||||
|
@ -242,7 +250,10 @@ where
|
||||||
}
|
}
|
||||||
Ok(())
|
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>(
|
pub async fn send_message<'b>(
|
||||||
&'b mut self,
|
&'b mut self,
|
||||||
topic_name: &'b str,
|
topic_name: &'b str,
|
||||||
|
@ -314,6 +325,10 @@ where
|
||||||
Ok(())
|
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>(
|
pub async fn subscribe_to_topics<'b, const TOPICS: usize>(
|
||||||
&'b mut self,
|
&'b mut self,
|
||||||
topic_names: &'b Vec<&'b str, TOPICS>,
|
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>(
|
pub async fn unsubscribe_from_topic<'b>(
|
||||||
&'b mut self,
|
&'b mut self,
|
||||||
topic_name: &'b str,
|
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,
|
&'b mut self,
|
||||||
topic_name: &'b str,
|
topic_name: &'b str,
|
||||||
) -> Result<(), ReasonCode> {
|
) -> 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>(
|
pub async fn subscribe_to_topic<'b>(
|
||||||
&'b mut self,
|
&'b mut self,
|
||||||
topic_name: &'b str,
|
topic_name: &'b str,
|
||||||
|
@ -471,6 +492,9 @@ where
|
||||||
return Ok(packet.message.unwrap());
|
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> {
|
pub async fn receive_message<'b>(&'b mut self) -> Result<&'b [u8], ReasonCode> {
|
||||||
match self.config.mqtt_version {
|
match self.config.mqtt_version {
|
||||||
MqttVersion::MQTTv3 => Err(ReasonCode::UnsupportedProtocolVersion),
|
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> {
|
pub async fn send_ping<'b>(&'b mut self) -> Result<(), ReasonCode> {
|
||||||
match self.config.mqtt_version {
|
match self.config.mqtt_version {
|
||||||
MqttVersion::MQTTv3 => Err(ReasonCode::UnsupportedProtocolVersion),
|
MqttVersion::MQTTv3 => Err(ReasonCode::UnsupportedProtocolVersion),
|
||||||
|
|
|
@ -34,7 +34,16 @@ pub enum MqttVersion {
|
||||||
MQTTv3,
|
MQTTv3,
|
||||||
MQTTv5,
|
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)]
|
#[derive(Clone)]
|
||||||
pub struct ClientConfig<'a, const MAX_PROPERTIES: usize, T: RngCore> {
|
pub struct ClientConfig<'a, const MAX_PROPERTIES: usize, T: RngCore> {
|
||||||
pub qos: QualityOfService,
|
pub qos: QualityOfService,
|
||||||
|
@ -69,6 +78,8 @@ impl<'a, const MAX_PROPERTIES: usize, T: RngCore> ClientConfig<'a, MAX_PROPERTIE
|
||||||
self.qos = qos;
|
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) {
|
pub fn add_username(&mut self, username: &'a str) {
|
||||||
let mut username_s: EncodedString = EncodedString::new();
|
let mut username_s: EncodedString = EncodedString::new();
|
||||||
username_s.string = username;
|
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_flag = true;
|
||||||
self.username = username_s;
|
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) {
|
pub fn add_password(&mut self, password: &'a str) {
|
||||||
let mut password_s: BinaryData = BinaryData::new();
|
let mut password_s: BinaryData = BinaryData::new();
|
||||||
password_s.bin = password.as_bytes();
|
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;
|
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>) {
|
pub fn add_property(&mut self, prop: Property<'a>) {
|
||||||
if self.properties.len() < MAX_PROPERTIES {
|
if self.properties.len() < MAX_PROPERTIES {
|
||||||
self.properties.push(prop);
|
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 {
|
pub fn add_max_packet_size_as_prop(&mut self) -> u32 {
|
||||||
if self.properties.len() < MAX_PROPERTIES {
|
if self.properties.len() < MAX_PROPERTIES {
|
||||||
let prop = Property::MaximumPacketSize(self.max_packet_size);
|
let prop = Property::MaximumPacketSize(self.max_packet_size);
|
||||||
|
|
|
@ -34,7 +34,8 @@ pub enum NetworkError {
|
||||||
IDNotMatchedOnAck,
|
IDNotMatchedOnAck,
|
||||||
NoMatchingSubs,
|
NoMatchingSubs,
|
||||||
}
|
}
|
||||||
|
/// NetworkConnectionFactory implementation should create a TCP connection and return
|
||||||
|
/// the `Connection` trait implementation. Otherwise return `ReasonCode`.
|
||||||
pub trait NetworkConnectionFactory: Sized {
|
pub trait NetworkConnectionFactory: Sized {
|
||||||
type Connection: NetworkConnection;
|
type Connection: NetworkConnection;
|
||||||
|
|
||||||
|
@ -42,9 +43,11 @@ pub trait NetworkConnectionFactory: Sized {
|
||||||
where
|
where
|
||||||
Self: 'm;
|
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>;
|
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 {
|
pub trait NetworkConnection {
|
||||||
type SendFuture<'m>: Future<Output = Result<(), ReasonCode>>
|
type SendFuture<'m>: Future<Output = Result<(), ReasonCode>>
|
||||||
where
|
where
|
||||||
|
@ -56,9 +59,12 @@ pub trait NetworkConnection {
|
||||||
|
|
||||||
type CloseFuture<'m>: Future<Output = Result<(), ReasonCode>>;
|
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>;
|
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>;
|
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>;
|
fn close<'m>(self) -> Self::CloseFuture<'m>;
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,6 +34,8 @@ use tokio::net::TcpStream;
|
||||||
use crate::network::{NetworkConnection, NetworkConnectionFactory};
|
use crate::network::{NetworkConnection, NetworkConnectionFactory};
|
||||||
use crate::packet::v5::reason_codes::ReasonCode;
|
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 {
|
pub struct TokioNetwork {
|
||||||
stream: TcpStream,
|
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 {}
|
pub struct TokioNetworkFactory {}
|
||||||
|
|
||||||
impl TokioNetworkFactory {
|
impl TokioNetworkFactory {
|
||||||
|
|
|
@ -28,6 +28,8 @@ use crate::encoding::variable_byte_integer::{VariableByteInteger, VariableByteIn
|
||||||
use crate::packet::v5::property::Property;
|
use crate::packet::v5::property::Property;
|
||||||
use crate::utils::types::{BinaryData, BufferError, EncodedString, StringPair, TopicFilter};
|
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> {
|
pub struct BuffWriter<'a> {
|
||||||
buffer: &'a mut [u8],
|
buffer: &'a mut [u8],
|
||||||
pub position: usize,
|
pub position: usize,
|
||||||
|
@ -47,6 +49,7 @@ impl<'a> BuffWriter<'a> {
|
||||||
self.position = self.position + increment;
|
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 {
|
pub fn get_n_byte(&mut self, n: usize) -> u8 {
|
||||||
if self.position >= n {
|
if self.position >= n {
|
||||||
return self.buffer[n];
|
return self.buffer[n];
|
||||||
|
@ -54,6 +57,7 @@ impl<'a> BuffWriter<'a> {
|
||||||
return 0;
|
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, ()> {
|
pub fn get_rem_len(&mut self) -> Result<VariableByteInteger, ()> {
|
||||||
let max = if self.position >= 5 {
|
let max = if self.position >= 5 {
|
||||||
4
|
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> {
|
pub fn insert_ref(&mut self, len: usize, array: &[u8]) -> Result<(), BufferError> {
|
||||||
let mut x: usize = 0;
|
let mut x: usize = 0;
|
||||||
if self.position + len > self.len {
|
if self.position + len > self.len {
|
||||||
|
@ -95,6 +100,7 @@ impl<'a> BuffWriter<'a> {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Writes a single Byte to the buffer.
|
||||||
pub fn write_u8(&mut self, byte: u8) -> Result<(), BufferError> {
|
pub fn write_u8(&mut self, byte: u8) -> Result<(), BufferError> {
|
||||||
return if self.position >= self.len {
|
return if self.position >= self.len {
|
||||||
Err(BufferError::InsufficientBufferSize)
|
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> {
|
pub fn write_u16(&mut self, two_bytes: u16) -> Result<(), BufferError> {
|
||||||
let bytes: [u8; 2] = two_bytes.to_be_bytes();
|
let bytes: [u8; 2] = two_bytes.to_be_bytes();
|
||||||
return self.insert_ref(2, &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> {
|
pub fn write_u32(&mut self, four_bytes: u32) -> Result<(), BufferError> {
|
||||||
let bytes: [u8; 4] = four_bytes.to_be_bytes();
|
let bytes: [u8; 4] = four_bytes.to_be_bytes();
|
||||||
return self.insert_ref(4, &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> {
|
pub fn write_string_ref(&mut self, str: &EncodedString<'a>) -> Result<(), BufferError> {
|
||||||
self.write_u16(str.len)?;
|
self.write_u16(str.len)?;
|
||||||
if str.len != 0 {
|
if str.len != 0 {
|
||||||
|
@ -124,16 +133,19 @@ impl<'a> BuffWriter<'a> {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Writes BinaryData to the buffer.
|
||||||
pub fn write_binary_ref(&mut self, bin: &BinaryData<'a>) -> Result<(), BufferError> {
|
pub fn write_binary_ref(&mut self, bin: &BinaryData<'a>) -> Result<(), BufferError> {
|
||||||
self.write_u16(bin.len)?;
|
self.write_u16(bin.len)?;
|
||||||
return self.insert_ref(bin.len as usize, bin.bin);
|
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> {
|
pub fn write_string_pair_ref(&mut self, str_pair: &StringPair<'a>) -> Result<(), BufferError> {
|
||||||
self.write_string_ref(&str_pair.name)?;
|
self.write_string_ref(&str_pair.name)?;
|
||||||
return self.write_string_ref(&str_pair.value);
|
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> {
|
pub fn write_variable_byte_int(&mut self, int: u32) -> Result<(), BufferError> {
|
||||||
let x: VariableByteInteger = VariableByteIntegerEncoder::encode(int)?;
|
let x: VariableByteInteger = VariableByteIntegerEncoder::encode(int)?;
|
||||||
let len = VariableByteIntegerEncoder::len(x);
|
let len = VariableByteIntegerEncoder::len(x);
|
||||||
|
@ -146,6 +158,7 @@ impl<'a> BuffWriter<'a> {
|
||||||
return property.encode(self);
|
return property.encode(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Writes all properties from the `properties` Vec into the buffer.
|
||||||
pub fn write_properties<const LEN: usize>(
|
pub fn write_properties<const LEN: usize>(
|
||||||
&mut self,
|
&mut self,
|
||||||
properties: &Vec<Property<'a>, LEN>,
|
properties: &Vec<Property<'a>, LEN>,
|
||||||
|
@ -165,6 +178,8 @@ impl<'a> BuffWriter<'a> {
|
||||||
Ok(())
|
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(
|
fn write_topic_filter_ref(
|
||||||
&mut self,
|
&mut self,
|
||||||
sub: bool,
|
sub: bool,
|
||||||
|
@ -177,6 +192,8 @@ impl<'a> BuffWriter<'a> {
|
||||||
return Ok(());
|
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>(
|
pub fn write_topic_filters_ref<const MAX: usize>(
|
||||||
&mut self,
|
&mut self,
|
||||||
sub: bool,
|
sub: bool,
|
||||||
|
|
Loading…
Reference in New Issue
Block a user