aws_iot_device_sdk_rust/
settings.rs

1use crate::error;
2use rumqttc::{self, LastWill, MqttOptions, TlsConfiguration, Transport};
3use std::time::Duration;
4
5const DEFAULT_PORT: u16 = 8883;
6
7#[derive(Clone, Debug)]
8pub struct MQTTMaxPacketSize {
9    incoming_max_packet_size: usize,
10    outgoing_max_packet_size: usize,
11}
12
13impl MQTTMaxPacketSize {
14    pub fn new(incoming_max_packet_size: usize, outgoing_max_packet_size: usize) -> Self {
15        MQTTMaxPacketSize {
16            incoming_max_packet_size,
17            outgoing_max_packet_size,
18        }
19    }
20}
21
22#[derive(Clone, Default)]
23pub struct MQTTOptionsOverrides {
24    pub port: Option<u16>,
25    pub clean_session: Option<bool>,
26    pub keep_alive: Option<Duration>,
27    pub max_packet_size: Option<MQTTMaxPacketSize>,
28    pub request_channel_capacity: Option<usize>,
29    pub pending_throttle: Option<Duration>,
30    pub inflight: Option<u16>,
31    pub last_will: Option<LastWill>,
32    pub conn_timeout: Option<u64>,
33    pub transport: Option<Transport>,
34}
35
36pub struct AWSIoTSettings {
37    client_id: String,
38    ca_path: String,
39    client_cert_path: String,
40    client_key_path: String,
41    aws_iot_endpoint: String,
42    pub(crate) mqtt_options_overrides: Option<MQTTOptionsOverrides>,
43}
44
45impl AWSIoTSettings {
46    pub fn new(
47        client_id: String,
48        ca_path: String,
49        client_cert_path: String,
50        client_key_path: String,
51        aws_iot_endpoint: String,
52        mqtt_options_overrides: Option<MQTTOptionsOverrides>,
53    ) -> AWSIoTSettings {
54        AWSIoTSettings {
55            client_id,
56            ca_path,
57            client_cert_path,
58            client_key_path,
59            aws_iot_endpoint,
60            mqtt_options_overrides,
61        }
62    }
63}
64
65fn set_overrides(settings: AWSIoTSettings) -> MqttOptions {
66    let port = settings
67        .mqtt_options_overrides
68        .as_ref()
69        .map_or(DEFAULT_PORT, |overrides| {
70            overrides.port.unwrap_or(DEFAULT_PORT)
71        });
72    let mut mqtt_options = MqttOptions::new(settings.client_id, settings.aws_iot_endpoint, port);
73    mqtt_options.set_keep_alive(Duration::from_secs(10));
74    if let Some(overrides) = settings.mqtt_options_overrides {
75        if let Some(clean_session) = overrides.clean_session {
76            mqtt_options.set_clean_session(clean_session);
77        }
78        if let Some(transport) = overrides.transport {
79            mqtt_options.set_transport(transport);
80        }
81        if let Some(keep_alive) = overrides.keep_alive {
82            mqtt_options.set_keep_alive(keep_alive);
83        }
84        if let Some(packet_size) = overrides.max_packet_size {
85            mqtt_options.set_max_packet_size(
86                packet_size.incoming_max_packet_size,
87                packet_size.outgoing_max_packet_size,
88            );
89        }
90        if let Some(request_channel_capacity) = overrides.request_channel_capacity {
91            mqtt_options.set_request_channel_capacity(request_channel_capacity);
92        }
93        if let Some(pending_throttle) = overrides.pending_throttle {
94            mqtt_options.set_pending_throttle(pending_throttle);
95        }
96        if let Some(inflight) = overrides.inflight {
97            mqtt_options.set_inflight(inflight);
98        }
99        if let Some(clean_session) = overrides.clean_session {
100            mqtt_options.set_clean_session(clean_session);
101        }
102        if let Some(last_will) = overrides.last_will {
103            mqtt_options.set_last_will(last_will);
104        }
105    }
106
107    mqtt_options
108}
109
110#[cfg(feature = "async")]
111pub(crate) async fn get_mqtt_options_async(
112    settings: AWSIoTSettings,
113) -> Result<MqttOptions, error::AWSIoTError> {
114    use tokio::fs::read;
115
116    let transport_overrided = settings
117        .mqtt_options_overrides
118        .as_ref()
119        .is_some_and(|over| over.transport.is_some());
120
121    let transport = (!transport_overrided).then_some({
122        let ca = read(&settings.ca_path).await?;
123        let client_cert = read(&settings.client_cert_path).await?;
124        let client_key = read(&settings.client_key_path).await?;
125
126        Transport::Tls(TlsConfiguration::Simple {
127            ca,
128            alpn: None,
129            client_auth: Some((client_cert, client_key)),
130        })
131    });
132
133    let mut mqtt_options = set_overrides(settings);
134    if let Some(transport) = transport {
135        mqtt_options.set_transport(transport);
136    }
137
138    Ok(mqtt_options)
139}
140
141#[cfg(feature = "sync")]
142pub(crate) fn get_mqtt_options(
143    settings: AWSIoTSettings,
144) -> Result<MqttOptions, error::AWSIoTError> {
145    use std::fs::read;
146
147    let transport_overrided = settings
148        .mqtt_options_overrides
149        .as_ref()
150        .is_some_and(|over| over.transport.is_some());
151
152    let transport = (!transport_overrided).then_some({
153        let ca = read(&settings.ca_path)?;
154        let client_cert = read(&settings.client_cert_path)?;
155        let client_key = read(&settings.client_key_path)?;
156
157        Transport::Tls(TlsConfiguration::Simple {
158            ca,
159            alpn: None,
160            client_auth: Some((client_cert, client_key)),
161        })
162    });
163
164    let mut mqtt_options = set_overrides(settings);
165    if let Some(transport) = transport {
166        mqtt_options.set_transport(transport);
167    }
168
169    Ok(mqtt_options)
170}