seeed_lora_e5_at_commands/lora/
responses.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
use crate::lora::types::{LoraJoinMode, LoraJoiningStartingStatus, LoraJoiningStatus};
use atat_derive::AtatResp;
use core::str::FromStr;
#[cfg(feature = "debug")]
use defmt::error;
use heapless::{String, Vec};
use serde_at::HexStr;

/// MODE Get/Set Response
#[derive(Debug, Clone, AtatResp, PartialEq)]
pub struct ModeGetSetResponse {
    pub mode: String<24>,
}

impl ModeGetSetResponse {
    pub fn mode(self) -> LoraJoinMode {
        self.into()
    }
}

/// ID ABP DevAddr Get/Set Response
#[derive(Debug, Clone, AtatResp, PartialEq)]
pub struct AbpDevAddrResponse {
    pub dev_addr_text: String<14>,
    pub dev_addr: HexStr<u32>,
}

/// ID OTAA DevEui Get/Set Response
#[derive(Debug, Clone, AtatResp, PartialEq)]
pub struct OtaaDevEuiResponse {
    pub dev_eui: HexStr<u64>,
}

/// ID OTAA AppEui Get/Set Response
#[derive(Debug, Clone, AtatResp, PartialEq)]
pub struct OtaaAppEuiResponse {
    pub app_eui: HexStr<u64>,
}

/// Port get/set response
#[derive(Debug, Clone, AtatResp, PartialEq)]
pub struct PortGetSetResponse {
    pub port: u8,
}

/// ADR get/set response
#[derive(Debug, Clone, AtatResp, PartialEq)]
pub struct AdrGetSetResponse {
    pub on: String<6>,
}

impl AdrGetSetResponse {
    pub fn is_on(&self) -> bool {
        self.on.as_str().eq("ON")
    }
}

/// Data rate get/set response
/// Example return US915 DR0 SF10 BW125K
#[derive(Debug, Clone, AtatResp, PartialEq)]
pub struct DataRateGetSetResponse {
    pub rate: String<42>,
}

/// LoRaWAN class get/set response
#[derive(Debug, Clone, AtatResp, PartialEq)]
pub struct LoRaWANClassGetSetResponse {
    pub class: String<2>,
}

/// AppKey Set response
#[derive(Debug, Clone, AtatResp, PartialEq)]
pub struct AppKeySetResponse {
    // APPKEY <32 char> = 41 char = 82 bytes
    pub response: String<82>,
}

/// Join response
#[derive(Debug, Clone, AtatResp, PartialEq)]
pub struct LoraOtaaJoinResponse {
    pub response: String<26>,
}

/// Auto join response
#[derive(Debug, Clone, AtatResp, PartialEq)]
pub struct LoraOtaaAutoJoinResponse {
    pub response: String<26>,
}

impl From<String<26>> for LoraJoiningStatus {
    fn from(value: String<26>) -> Self {
        match value.as_str() {
            "Starting" => LoraJoiningStatus::Starting(LoraJoiningStartingStatus::Starting),
            "NORMAL" => LoraJoiningStatus::Starting(LoraJoiningStartingStatus::Normal),
            "Join failed" => LoraJoiningStatus::Failed,
            "LoRaWAN modem is busy" => LoraJoiningStatus::Busy,
            x if x.starts_with("NetId") => {
                let mut parts = x.split(' ').skip(1);
                let net_id = parts.next();
                let dev_addr = parts.nth(1);
                match (net_id, dev_addr) {
                    (Some(net_id), Some(dev_addr)) => {
                        let net_id = net_id.try_into().unwrap();
                        let dev_addr = dev_addr.try_into().unwrap();
                        LoraJoiningStatus::Starting(LoraJoiningStartingStatus::Done(
                            net_id, dev_addr,
                        ))
                    }
                    _ => LoraJoiningStatus::Unknown,
                }
            }
            _ => LoraJoiningStatus::Unknown,
        }
    }
}

/// POWER force response
#[derive(Debug, Clone, AtatResp, PartialEq)]
pub struct TxPowerForceSetResponse {
    pub db_m: u8,
}

/// POWER table
#[derive(Debug, Clone, AtatResp, PartialEq)]
pub struct TxPowerTable {
    pub table: String<80>,
}

impl TxPowerTable {
    pub fn db_m_list(&self) -> Result<Vec<u8, 12>, atat::Error> {
        let mut ret = Vec::new();
        for i in self.table.as_str().split(' ').map(u8::from_str) {
            ret.push(i.map_err(|_e| {
                #[cfg(feature = "debug")]
                error!("Could not parse u8");
                atat::Error::Parse
            })?)
            .map_err(|e| {
                #[cfg(feature = "debug")]
                {
                    error!("Could not add u8 to return of tx power tables: {}", e);
                }
                atat::Error::Parse
            })?;
        }
        Ok(ret)
    }
}

/// REPEAT response
#[derive(Debug, Clone, AtatResp, PartialEq)]
pub struct RepeatGetSetResponse {
    pub repeat: u8,
}

/// RETRY response
#[derive(Debug, Clone, AtatResp, PartialEq)]
pub struct RetryGetSetResponse {
    pub retry: u8,
}

/// Max payload length response
#[derive(Debug, Clone, AtatResp, PartialEq)]
pub struct MaxPayloadLengthGetResponse {
    // LEN
    pub command: String<6>,
    pub max: u8,
}

/// Uplink/Downlink counter response
#[derive(Debug, Clone, AtatResp, PartialEq)]
pub struct UplinkDownlinkCounterGetResponse {
    pub uplink: u32,
    pub downlink: u32,
}

impl UplinkDownlinkCounterGetResponse {
    pub fn uplink(&self) -> u32 {
        self.uplink
    }

    pub fn downlink(&self) -> u32 {
        self.downlink
    }
}