rust_mqtt/client/
client_config.rs

1/*
2 * MIT License
3 *
4 * Copyright (c) [2022] [Ondrej Babec <ond.babec@gmail.com>]
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in all
14 * copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 * SOFTWARE.
23 */
24
25use heapless::Vec;
26use rand_core::RngCore;
27
28use crate::packet::v5::property::Property;
29use crate::packet::v5::publish_packet::QualityOfService;
30use crate::utils::types::{BinaryData, EncodedString};
31
32#[derive(Clone, PartialEq)]
33pub enum MqttVersion {
34    MQTTv3,
35    MQTTv5,
36}
37/// Client config is main configuration for the `MQTTClient` structure.
38/// All of the properties are optional if they are not set they are not gonna
39/// be used. Configuration contains also MQTTv5 properties. Generic constant
40/// `MAX_PROPERTIES` sets the length for the properties Vec. User can insert
41/// all the properties and client will automatically use variables that are
42/// usable for the specific packet types. `mqtt_version` sets the version
43/// of the MQTT protocol that is gonna be used. Config also expects the rng
44/// implementation. This implementation is used for generating packet identifiers.
45/// There is counting rng implementation in the `utils` module that can be used.
46/// Examples of the configurations can be found in the integration tests.
47#[derive(Clone)]
48pub struct ClientConfig<'a, const MAX_PROPERTIES: usize, T: RngCore> {
49    pub max_subscribe_qos: QualityOfService,
50    pub keep_alive: u16,
51    pub username_flag: bool,
52    pub username: EncodedString<'a>,
53    pub password_flag: bool,
54    pub password: BinaryData<'a>,
55    pub properties: Vec<Property<'a>, MAX_PROPERTIES>,
56    pub max_packet_size: u32,
57    pub mqtt_version: MqttVersion,
58    pub rng: T,
59    pub will_flag: bool,
60    pub will_topic: EncodedString<'a>,
61    pub will_payload: BinaryData<'a>,
62    pub will_retain: bool,
63    pub client_id: EncodedString<'a>,
64}
65
66impl<'a, const MAX_PROPERTIES: usize, T: RngCore> ClientConfig<'a, MAX_PROPERTIES, T> {
67    pub fn new(version: MqttVersion, rng: T) -> Self {
68        Self {
69            max_subscribe_qos: QualityOfService::QoS0,
70            keep_alive: 60,
71            username_flag: false,
72            username: EncodedString::new(),
73            password_flag: false,
74            password: BinaryData::new(),
75            properties: Vec::<Property<'a>, MAX_PROPERTIES>::new(),
76            max_packet_size: 265_000,
77            mqtt_version: version,
78            rng,
79            will_flag: false,
80            will_topic: EncodedString::new(),
81            will_payload: BinaryData::new(),
82            will_retain: false,
83            client_id: EncodedString::new(),
84        }
85    }
86
87    pub fn add_max_subscribe_qos(&mut self, qos: QualityOfService) {
88        self.max_subscribe_qos = qos;
89    }
90
91    pub fn add_will(&mut self, topic: &'a str, payload: &'a [u8], retain: bool) {
92        let mut topic_s = EncodedString::new();
93        topic_s.string = topic;
94        topic_s.len = topic.len() as u16;
95
96        let mut payload_d = BinaryData::new();
97        payload_d.bin = payload;
98        payload_d.len = payload.len() as u16;
99
100        self.will_flag = true;
101        self.will_retain = retain;
102        self.will_topic = topic_s;
103        self.will_payload = payload_d;
104    }
105
106    /// Method adds the username array and also sets the username flag so client
107    /// will use it for the authentication
108    pub fn add_username(&mut self, username: &'a str) {
109        let mut username_s: EncodedString = EncodedString::new();
110        username_s.string = username;
111        username_s.len = username.len() as u16;
112        self.username_flag = true;
113        self.username = username_s;
114    }
115    /// Method adds the password array and also sets the password flag so client
116    /// will use it for the authentication
117    pub fn add_password(&mut self, password: &'a str) {
118        let mut password_s: BinaryData = BinaryData::new();
119        password_s.bin = password.as_bytes();
120        password_s.len = password_s.bin.len() as u16;
121        self.password = password_s;
122        self.password_flag = true;
123    }
124
125    /// Method adds the property to the properties Vec if there is still space. Otherwise do nothing.
126    pub fn add_property(&mut self, prop: Property<'a>) {
127        if self.properties.len() < MAX_PROPERTIES {
128            self.properties.push(prop);
129        }
130    }
131
132    /// Method encode the `max_packet_size` attribute as property to the properties Vec.
133    pub fn add_max_packet_size_as_prop(&mut self) -> u32 {
134        if self.properties.len() < MAX_PROPERTIES {
135            let prop = Property::MaximumPacketSize(self.max_packet_size);
136            self.properties.push(prop);
137            return 5;
138        }
139        0
140    }
141
142    pub fn add_client_id(&mut self, client_id: &'a str) {
143        let mut client_id_s = EncodedString::new();
144        client_id_s.string = client_id;
145        client_id_s.len = client_id.len() as u16;
146
147        self.client_id = client_id_s
148    }
149}