seeed_lora_e5_at_commands/lora/
mod.rs1pub 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}