seeed_lora_e5_at_commands/lora/
mod.rs

1pub mod commands;
2pub mod responses;
3pub mod types;
4pub mod urc;
5
6#[cfg(feature = "async")]
7pub mod asynch {
8    use crate::client::asynch::{JoinStatus, SeeedLoraE5Client};
9    use crate::lora::types::LoraJoinMode;
10    use crate::lora::{
11        commands,
12        types::{LoraClass, LoraJoiningStatus, LoraRegion},
13    };
14    use crate::urc::{
15        MessageStats, ReceivedMessage, LAST_LORA_MESSAGE_RECEIVED, LORA_JOIN_STATUS,
16        LORA_MESSAGE_RECEIVED_COUNT, LORA_MESSAGE_RECEIVED_STATS,
17    };
18    use atat::asynch::AtatClient;
19    use atat::Error;
20    use core::str::FromStr;
21    use embedded_io_async::Write;
22    use heapless::{String, Vec};
23    use serde_at::HexStr;
24
25    static mut CONFIRMED_SENDING: Option<bool> = Some(false);
26
27    impl<'a, W: Write, const INGRESS_BUF_SIZE: usize> SeeedLoraE5Client<'a, W, INGRESS_BUF_SIZE> {
28        pub async fn join_mode(&mut self) -> Result<LoraJoinMode, Error> {
29            let command = commands::ModeGet {};
30            let response = self.client.send(&command).await?;
31            Ok(LoraJoinMode::from(response))
32        }
33
34        pub async fn join_mode_set(&mut self, mode: LoraJoinMode) -> Result<LoraJoinMode, Error> {
35            let command = match mode {
36                LoraJoinMode::Otaa => commands::ModeSet::otaa(),
37                LoraJoinMode::Abp => commands::ModeSet::abp(),
38                LoraJoinMode::Test => commands::ModeSet::test(),
39                _ => return Err(Error::Error),
40            };
41            let response = self.client.send(&command).await?;
42            Ok(response.mode())
43        }
44
45        pub async fn dev_eui(&mut self) -> Result<u64, Error> {
46            let command = commands::DevEuiGet {};
47            let response = self.client.send(&command).await?;
48            Ok(response.dev_eui.val)
49        }
50
51        pub async fn dev_eui_set(&mut self, dev_eui: u64) -> Result<u64, Error> {
52            let command = commands::DevEuiSet::dev_eui(dev_eui);
53            let response = self.client.send(&command).await?;
54            Ok(response.dev_eui.val)
55        }
56
57        pub async fn app_eui(&mut self) -> Result<u64, Error> {
58            let command = commands::AppEuiGet {};
59            let response = self.client.send(&command).await?;
60            Ok(response.app_eui.val)
61        }
62
63        pub async fn app_eui_set(&mut self, app_eui: u64) -> Result<u64, Error> {
64            let command = commands::AppEuiSet::app_eui(app_eui);
65            let response = self.client.send(&command).await?;
66            Ok(response.app_eui.val)
67        }
68
69        pub async fn app_key_set(&mut self, app_key: u128) -> Result<(), Error> {
70            let command = commands::AppKeySet::app_key(app_key);
71            self.client.send(&command).await?;
72            Ok(())
73        }
74
75        pub async fn lora_region(&mut self) -> Result<LoraRegion, Error> {
76            let command = commands::LoraDrGet {};
77            let response = self.client.send(&command).await?;
78            let s = response.rate.as_str();
79            let s: String<24> = String::from_str(s).map_err(|_| Error::Parse)?;
80            Ok(s.into())
81        }
82
83        pub async fn lora_region_set(&mut self, region: LoraRegion) -> Result<LoraRegion, Error> {
84            let command = commands::DataRateSchemeSet::region(region);
85            let response = self.client.send(&command).await?;
86            let s = response.rate.as_str();
87            let s: String<24> = String::from_str(s).map_err(|_| Error::Parse)?;
88            Ok(s.into())
89        }
90
91        pub async fn lora_class(&mut self) -> Result<LoraClass, Error> {
92            let command = commands::LoraClassGet {};
93            let response = self.client.send(&command).await?;
94            Ok(response.class.into())
95        }
96
97        pub async fn lora_class_set(&mut self, class: LoraClass) -> Result<LoraClass, Error> {
98            let command = commands::LoraClassSet::class(class);
99            let response = self.client.send(&command).await?;
100            Ok(response.class.into())
101        }
102
103        pub async fn lora_join_otaa(&mut self) -> Result<LoraJoiningStatus, Error> {
104            self.join_status.join_status = JoinStatus::Joining;
105            LORA_JOIN_STATUS.signal(JoinStatus::Joining);
106            let command = commands::LoraJoinOtaa {};
107            let response = self
108                .client
109                .send(&command)
110                .await
111                .map_err(|e| {
112                    LORA_JOIN_STATUS.signal(JoinStatus::NotJoined);
113                    self.join_status.join_status = JoinStatus::NotJoined;
114                    e
115                })?
116                .response;
117            Ok(response.into())
118        }
119
120        pub async fn lora_join_status(&mut self) -> Result<JoinStatus, Error> {
121            Ok(LORA_JOIN_STATUS
122                .try_signaled_value()
123                .unwrap_or(JoinStatus::NotJoined))
124        }
125
126        pub async fn lora_join_otaa_and_wait_for_result(&mut self) -> Result<JoinStatus, Error> {
127            self.lora_join_otaa().await?;
128            loop {
129                let status = LORA_JOIN_STATUS.wait().await;
130                if matches!(
131                    status,
132                    JoinStatus::Success | JoinStatus::Failure | JoinStatus::NotJoined
133                ) {
134                    return Ok(status);
135                }
136            }
137        }
138
139        pub async fn auto_join_set(
140            &mut self,
141            is_on: bool,
142            interval: u32,
143        ) -> Result<String<26>, Error> {
144            let response = if is_on {
145                let command = commands::LoraAutoJoinOtaaMode0 { interval };
146                self.client.send(&command).await?
147            } else {
148                let command = commands::LoraAutoJoinOtaaDisable {};
149                self.client.send(&command).await?
150            };
151            Ok(response.response)
152        }
153
154        pub async fn max_tx_len(&mut self) -> Result<u8, Error> {
155            let command = commands::LoraMaxTxLengthGet::default();
156            let response = self.client.send(&command).await?;
157            Ok(response.max)
158        }
159
160        pub async fn confirm_send(&mut self) -> Result<bool, Error> {
161            let confirmed_sending = unsafe { CONFIRMED_SENDING.unwrap() };
162            Ok(confirmed_sending)
163        }
164
165        pub async fn confirm_send_set(&mut self, is_on: bool) -> Result<bool, Error> {
166            unsafe {
167                CONFIRMED_SENDING = Some(is_on);
168            }
169            Ok(is_on)
170        }
171
172        pub async fn send(
173            &mut self,
174            retransmission_times: u8,
175            port: u8,
176            data: &[u8],
177        ) -> Result<(), Error> {
178            let mut val = [0u8; 242];
179            for (place, array) in val.iter_mut().zip(data.iter()) {
180                *place = *array;
181            }
182
183            let message = HexStr {
184                val,
185                add_0x_with_encoding: false,
186                hex_in_caps: false,
187                delimiter_after_nibble_count: 0,
188                delimiter: ' ',
189                skip_last_0_values: true,
190            };
191            let port_set = commands::LoraPortSet { port };
192            let _response = self.client.send(&port_set).await?;
193            match self.confirm_send().await? {
194                true => {
195                    let retry = commands::RetrySet {
196                        retry: retransmission_times,
197                    };
198                    let _response = self.client.send(&retry).await?;
199                    let command = commands::MessageHexConfirmed { message };
200                    let _response = self.client.send(&command).await?;
201                    Ok(())
202                }
203                false => {
204                    let repeat = commands::RepeatSet {
205                        repeat: retransmission_times,
206                    };
207                    let _response = self.client.send(&repeat).await?;
208                    let command = commands::MessageHexConfirmed { message };
209                    let _response = self.client.send(&command).await?;
210                    Ok(())
211                }
212            }
213        }
214
215        pub async fn receive(&mut self) -> Result<(ReceivedMessage, MessageStats), Error> {
216            let value = LAST_LORA_MESSAGE_RECEIVED.wait().await;
217            LAST_LORA_MESSAGE_RECEIVED.reset();
218            let stats = LORA_MESSAGE_RECEIVED_STATS.wait().await;
219            LORA_MESSAGE_RECEIVED_STATS.reset();
220            Ok((value, stats))
221        }
222
223        pub async fn adr_set(&mut self, on: bool) -> Result<bool, Error> {
224            let command = if on {
225                commands::LoraAdrSet::on()
226            } else {
227                commands::LoraAdrSet::off()
228            };
229            let response = self.client.send(&command).await?;
230            Ok(response.is_on())
231        }
232
233        pub async fn dr_set(&mut self, data_rate: u8) -> Result<u8, Error> {
234            let command = commands::LoraDrSet::new(data_rate);
235            let _response = self.client.send(&command).await?;
236            Ok(data_rate)
237        }
238
239        pub async fn uplink_frame_count(&mut self) -> Result<u32, Error> {
240            let command = commands::LoraUplinkDownlinkCounterGet {};
241            let response = self.client.send(&command).await?;
242            Ok(response.uplink())
243        }
244
245        pub async fn downlink_frame_count(&mut self) -> Result<u32, Error> {
246            let command = commands::LoraUplinkDownlinkCounterGet {};
247            let response = self.client.send(&command).await?;
248            Ok(response.downlink())
249        }
250
251        pub async fn downlink_message_count(&self) -> Result<u32, Error> {
252            Ok(LORA_MESSAGE_RECEIVED_COUNT
253                .try_signaled_value()
254                .unwrap_or_default())
255        }
256
257        pub async fn tx_power_force_set(&mut self, db_m: u8) -> Result<u8, Error> {
258            let command = commands::TxPowerForceSet::new(db_m);
259            let response = self.client.send(&command).await?;
260            Ok(response.db_m)
261        }
262
263        pub async fn tx_power_table(&mut self) -> Result<Vec<u8, 12>, Error> {
264            let command = commands::TxPowerTableGet::default();
265            let response = self.client.send(&command).await?;
266            response.db_m_list()
267        }
268    }
269}