seeed_lora_e5_at_commands/
urc.rs1use crate::client::asynch::JoinStatus;
7use crate::lora::urc::{JoinUrc, MessageHexSend, MessageReceived};
8use crate::signal::Signal;
9use atat::digest::ParseError;
10use atat::{
11 nom::{branch, bytes, combinator, sequence},
12 AtatUrc, Parser,
13};
14use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
15
16#[cfg(feature = "debug")]
17use embassy_sync::pipe::Pipe;
18
19#[derive(Debug, PartialEq, Clone)]
21pub enum URCMessages {
22 Unknown,
24 Join(JoinUrc),
26 MessageHexSend(MessageHexSend),
28 MessageReceived(MessageReceived),
30}
31
32pub struct ReceivedMessage {
33 pub port: u8,
34 pub payload: [u8; 243],
35 pub length: usize,
36}
37
38pub struct MessageStats {
39 pub rxwin: u8,
40 pub rssi: i8,
41 pub snr: f32,
42}
43
44pub enum SentMessage {
45 Failed,
46 Success(MessageStats),
47}
48
49pub static LAST_LORA_MESSAGE_RECEIVED: Signal<CriticalSectionRawMutex, ReceivedMessage> =
50 Signal::new();
51pub static LORA_MESSAGE_RECEIVED_COUNT: Signal<CriticalSectionRawMutex, u32> = Signal::new();
52pub static LORA_MESSAGE_RECEIVED_STATS: Signal<CriticalSectionRawMutex, MessageStats> =
53 Signal::new();
54pub static LAST_LORA_MESSAGE_SENT: Signal<CriticalSectionRawMutex, MessageStats> = Signal::new();
55pub static LORA_JOIN_STATUS: Signal<CriticalSectionRawMutex, JoinStatus> = Signal::new();
56
57#[cfg(feature = "debug")]
58pub static LORA_LATEST_BUF: Pipe<CriticalSectionRawMutex, 50> = Pipe::new();
59
60impl URCMessages {}
61
62impl AtatUrc for URCMessages {
63 type Response = Self;
64
65 fn parse(resp: &[u8]) -> Option<Self::Response> {
66 match resp {
67 b if b.starts_with(b"+JOIN: ") => JoinUrc::parse(resp).ok().map(URCMessages::Join),
68 b if b.starts_with(b"+MSGHEX: ") || b.starts_with(b"+CMSGHEX: ") => {
69 MessageHexSend::parse(resp)
70 .ok()
71 .map(URCMessages::MessageHexSend)
72 }
73 b if b.starts_with(b"+MSG: ") => MessageReceived::parse(resp)
74 .ok()
75 .map(URCMessages::MessageReceived),
76 _ => None,
77 }
78 }
79}
80
81impl Parser for URCMessages {
82 fn parse(buf: &[u8]) -> Result<(&[u8], usize), ParseError> {
83 match buf {
85 b if b.starts_with(b"+JOIN: Auto-Join ") => return Err(ParseError::NoMatch),
86 b if b.starts_with(b"+JOIN: Start") => return Err(ParseError::NoMatch),
87 _ => {}
88 }
89
90 let (_reminder, (head, data, tail)) = branch::alt((
91 sequence::tuple((
93 combinator::success(&b""[..]),
94 combinator::recognize(sequence::tuple((
95 bytes::streaming::tag("+JOIN: "),
96 bytes::streaming::take_until("\r\n"),
97 ))),
98 bytes::streaming::tag("\r\n"),
99 )),
100 sequence::tuple((
102 combinator::success(&b""[..]),
103 combinator::recognize(sequence::tuple((
104 branch::alt((
105 bytes::streaming::tag("+MSGHEX: "),
106 bytes::streaming::tag("+CMSGHEX: "),
107 )),
108 bytes::streaming::take_until("\r\n"),
109 ))),
110 bytes::streaming::tag("\r\n"),
111 )),
112 sequence::tuple((
114 combinator::success(&b""[..]),
115 combinator::recognize(sequence::tuple((
116 bytes::streaming::tag("+MSG: "),
117 bytes::streaming::take_until("\r\n"),
118 ))),
119 bytes::streaming::tag("\r\n"),
120 )),
121 ))(buf)?;
122 Ok((data, head.len() + data.len() + tail.len()))
123 }
124}