1#[cfg(feature = "debug")]
2use atat::helpers::LossyStr;
3use atat::{
4 digest::{parser, ParseError},
5 InternalError,
6};
7use atat::{
8 nom,
9 nom::{branch, bytes, combinator, sequence},
10 DigestResult, Digester, Parser,
11};
12
13#[cfg(feature = "debug")]
14use crate::urc::LORA_LATEST_BUF;
15
16use crate::urc::URCMessages;
17#[cfg(feature = "debug")]
18use defmt::{debug, trace};
19
20#[derive(Default)]
21pub struct LoraE5Digester {}
22
23impl LoraE5Digester {
24 pub fn custom_error(buf: &[u8]) -> Result<(&[u8], usize), ParseError> {
25 let (_reminder, (head, data, tail)) = branch::alt((
26 sequence::tuple((
27 combinator::recognize(sequence::tuple((
28 bytes::streaming::take_until(": "),
29 bytes::streaming::tag(b": "),
30 ))),
31 bytes::streaming::tag(b"ERROR(-1)"),
32 bytes::streaming::tag(b"\r\n"),
33 )),
34 sequence::tuple((
35 combinator::recognize(sequence::tuple((
36 bytes::streaming::take_until(": "),
37 bytes::streaming::tag(b": "),
38 ))),
39 bytes::streaming::tag(b"ERROR(-10)"),
40 bytes::streaming::tag(b"\r\n"),
41 )),
42 sequence::tuple((
43 combinator::recognize(sequence::tuple((
44 bytes::streaming::take_until(": "),
45 bytes::streaming::tag(b": "),
46 ))),
47 bytes::streaming::tag(b"ERROR(-11)"),
48 bytes::streaming::tag(b"\r\n"),
49 )),
50 sequence::tuple((
51 combinator::recognize(sequence::tuple((
52 bytes::streaming::take_until(": "),
53 bytes::streaming::tag(b": "),
54 ))),
55 bytes::streaming::tag(b"ERROR(-12)"),
56 bytes::streaming::tag(b"\r\n"),
57 )),
58 sequence::tuple((
59 combinator::recognize(sequence::tuple((
60 bytes::streaming::take_until(": "),
61 bytes::streaming::tag(b": "),
62 ))),
63 bytes::streaming::tag(b"ERROR(-20)"),
64 bytes::streaming::tag(b"\r\n"),
65 )),
66 sequence::tuple((
67 combinator::recognize(sequence::tuple((
68 bytes::streaming::take_until(": "),
69 bytes::streaming::tag(b": "),
70 ))),
71 bytes::streaming::tag(b"ERROR(-21)"),
72 bytes::streaming::tag(b"\r\n"),
73 )),
74 sequence::tuple((
75 combinator::recognize(sequence::tuple((
76 bytes::streaming::take_until(": "),
77 bytes::streaming::tag(b": "),
78 ))),
79 bytes::streaming::tag(b"ERROR(-22)"),
80 bytes::streaming::tag(b"\r\n"),
81 )),
82 sequence::tuple((
83 combinator::recognize(sequence::tuple((
84 bytes::streaming::take_until(": "),
85 bytes::streaming::tag(b": "),
86 ))),
87 bytes::streaming::tag(b"ERROR(-23)"),
88 bytes::streaming::tag(b"\r\n"),
89 )),
90 sequence::tuple((
91 combinator::recognize(sequence::tuple((
92 bytes::streaming::take_until(": "),
93 bytes::streaming::tag(b": "),
94 ))),
95 bytes::streaming::tag(b"ERROR(-24)"),
96 bytes::streaming::tag(b"\r\n"),
97 )),
98 ))(buf)?;
99 #[cfg(feature = "debug")]
100 debug!("Custom error {:?}", LossyStr(data));
101 Ok((data, head.len() + data.len() + tail.len()))
102 }
103
104 pub fn custom_success(buf: &[u8]) -> Result<(&[u8], usize), ParseError> {
105 #[cfg(feature = "debug")]
106 if buf.is_empty() {
107 match LORA_LATEST_BUF.try_write(buf) {
108 Ok(_) => {}
109 Err(_) => {
110 trace!("Failed to write to LORA_LATEST_BUF");
111 }
112 }
113 }
114 #[cfg(feature = "debug")]
115 trace!("Custom success start {:?}", LossyStr(buf));
116 let (_reminder, (head, data, tail)) = branch::alt((
117 sequence::tuple((
119 combinator::success(&b""[..]),
120 combinator::recognize(sequence::tuple((
121 bytes::streaming::tag(b"+AT: "),
122 bytes::streaming::take_until("\r\n"),
123 ))),
124 bytes::streaming::tag("\r\n"),
125 )),
126 sequence::tuple((
128 combinator::success(&b""[..]),
129 combinator::recognize(sequence::tuple((
130 bytes::streaming::tag(b"+ATE: "),
131 bytes::streaming::take_until("\r\n"),
132 ))),
133 branch::alt((
134 bytes::streaming::tag("\r\n"),
135 bytes::streaming::tag("OK\r\n"),
136 )),
137 )),
138 sequence::tuple((
140 bytes::streaming::tag(b"+RESET: "),
141 bytes::streaming::take_until("\r\n\x00"),
142 bytes::streaming::tag("\r\n\x00"),
143 )),
144 sequence::tuple((
146 combinator::recognize(sequence::tuple((
147 bytes::streaming::tag(b"+ID: "),
148 bytes::streaming::take_until(" "),
149 bytes::streaming::tag(b" "),
150 ))),
151 bytes::streaming::take_until("\r\n"),
152 bytes::streaming::tag("\r\n"),
153 )),
154 sequence::tuple((
156 bytes::streaming::tag(b"+MODE: "),
157 bytes::streaming::take_until("\r\n"),
158 bytes::streaming::tag("\r\n"),
159 )),
160 sequence::tuple((
162 bytes::streaming::tag(b"+VER: "),
163 bytes::streaming::take_until("\r\n"),
164 bytes::streaming::tag("\r\n"),
165 )),
166 sequence::tuple((
168 bytes::streaming::tag(b"+DR: "),
169 bytes::streaming::take_until("\r\n"),
170 bytes::streaming::tag("\r\n"),
171 )),
172 sequence::tuple((
174 bytes::streaming::tag(b"+CLASS: "),
175 bytes::streaming::take_until("\r\n"),
176 bytes::streaming::tag("\r\n"),
177 )),
178 sequence::tuple((
180 bytes::streaming::tag(b"+ADR: "),
181 bytes::streaming::take_until("\r\n"),
182 bytes::streaming::tag("\r\n"),
183 )),
184 sequence::tuple((
186 bytes::streaming::tag(b"+LW: "),
187 bytes::streaming::take_until("\r\n"),
188 bytes::streaming::tag("\r\n"),
189 )),
190 sequence::tuple((
192 bytes::streaming::tag(b"+JOIN: "),
193 bytes::streaming::take_until("\r\n"),
194 bytes::streaming::tag("\r\n"),
195 )),
196 sequence::tuple((
198 bytes::streaming::tag(b"+PORT: "),
199 bytes::streaming::take_until("\r\n"),
200 bytes::streaming::tag("\r\n"),
201 )),
202 sequence::tuple((
204 bytes::streaming::tag(b"+RETRY: "),
205 bytes::streaming::take_until("\r\n"),
206 bytes::streaming::tag("\r\n"),
207 )),
208 sequence::tuple((
210 bytes::streaming::tag(b"+REPT: "),
211 bytes::streaming::take_until("\r\n"),
212 bytes::streaming::tag("\r\n"),
213 )),
214 sequence::tuple((
216 combinator::recognize(sequence::tuple((
217 bytes::streaming::tag(b"+KEY: "),
218 bytes::streaming::take_until(" "),
219 bytes::streaming::tag(b" "),
220 ))),
221 bytes::streaming::take_until("\r\n"),
222 bytes::streaming::tag("\r\n"),
223 )),
224 sequence::tuple((
226 bytes::streaming::tag(b"+RECVB: "),
227 combinator::recognize(sequence::tuple((
229 bytes::streaming::take_until("\r\n"),
231 bytes::streaming::tag("\r\n"),
232 ))),
233 combinator::success(&b""[..]),
234 )),
235 sequence::tuple((
237 combinator::success(&b""[..]),
238 combinator::recognize(sequence::tuple((
239 bytes::streaming::tag(b"+UP_CNT: "),
240 bytes::streaming::take_until("\r\n"),
241 ))),
242 bytes::streaming::tag("\r\n"),
243 )),
244 sequence::tuple((
246 combinator::success(&b""[..]),
247 combinator::recognize(sequence::tuple((
248 bytes::streaming::tag(b"+DOWN_CNT: "),
249 bytes::streaming::take_until("\r\n"),
250 ))),
251 bytes::streaming::tag("\r\n"),
252 )),
253 ))(buf)?;
254 #[cfg(feature = "debug")]
255 trace!("Custom success ! [{:?}]", LossyStr(data));
256
257 Ok((data, head.len() + data.len() + tail.len()))
258 }
259}
260
261impl Digester for LoraE5Digester {
262 fn digest<'a>(&mut self, input: &'a [u8]) -> (DigestResult<'a>, usize) {
263 #[cfg(feature = "debug")]
264 let s = LossyStr(input);
265 #[cfg(feature = "debug")]
266 trace!("Digesting: {:?}", s);
267
268 let incomplete = (DigestResult::None, 0);
270
271 if input == b"OK\r\n" {
273 return (DigestResult::None, 4);
274 }
275
276 match parser::success_response(input) {
278 Ok((_, (result, len))) => return (result, len),
279 Err(nom::Err::Incomplete(_)) => return incomplete,
280 _ => {}
281 }
282
283 match <URCMessages as Parser>::parse(input) {
285 Ok((urc, len)) => return (DigestResult::Urc(urc), len),
286 Err(ParseError::Incomplete) => return incomplete,
287 _ => {}
288 }
289
290 match (LoraE5Digester::custom_success)(input) {
293 Ok((response, len)) => return (DigestResult::Response(Ok(response)), len),
294 Err(ParseError::Incomplete) => return incomplete,
295 _ => {}
296 }
297
298 match (LoraE5Digester::custom_error)(input) {
301 Ok((response, len)) => {
302 return (
303 DigestResult::Response(Err(InternalError::Custom(response))),
304 len,
305 )
306 }
307 Err(ParseError::Incomplete) => return incomplete,
308 _ => {}
309 }
310
311 if let Ok((_, (result, len))) = parser::error_response(input) {
313 return (result, len);
314 }
315
316 incomplete
318 }
319}