1#![no_std]
2
3extern crate alloc;
4
5use core::convert::From;
6use core::ops::{Range, RangeFrom};
7
8#[derive(Copy, Clone, Eq, PartialEq, Debug)]
9#[cfg_attr(feature = "defmt", derive(defmt::Format))]
10pub enum GlobalBlockStatus {
11 Inactive,
12 Active,
13 Unknown(u8),
14}
15
16impl From<u8> for GlobalBlockStatus {
17 fn from(v: u8) -> Self {
18 match v {
19 0x02 => GlobalBlockStatus::Inactive,
20 0x03 => GlobalBlockStatus::Active,
21 _ => GlobalBlockStatus::Unknown(v),
22 }
23 }
24}
25
26impl From<GlobalBlockStatus> for u8 {
27 fn from(v: GlobalBlockStatus) -> Self {
28 match v {
29 GlobalBlockStatus::Inactive => 0x02,
30 GlobalBlockStatus::Active => 0x03,
31 GlobalBlockStatus::Unknown(v) => v,
32 }
33 }
34}
35
36#[derive(Copy, Clone, Eq, PartialEq, Debug)]
37#[cfg_attr(feature = "defmt", derive(defmt::Format))]
38pub enum RouteBBlockStatus {
39 Inactive,
40 Active,
41 Authentication,
42 Unknown(u8),
43}
44
45impl From<u8> for RouteBBlockStatus {
46 fn from(v: u8) -> Self {
47 match v {
48 0x01 => RouteBBlockStatus::Inactive,
49 0x02 => RouteBBlockStatus::Active,
50 0x03 => RouteBBlockStatus::Authentication,
51 _ => RouteBBlockStatus::Unknown(v),
52 }
53 }
54}
55
56impl From<RouteBBlockStatus> for u8 {
57 fn from(v: RouteBBlockStatus) -> Self {
58 match v {
59 RouteBBlockStatus::Inactive => 0x01,
60 RouteBBlockStatus::Active => 0x02,
61 RouteBBlockStatus::Authentication => 0x03,
62 RouteBBlockStatus::Unknown(v) => v,
63 }
64 }
65}
66
67#[derive(Copy, Clone, Eq, PartialEq, Debug)]
68#[cfg_attr(feature = "defmt", derive(defmt::Format))]
69pub enum HanBlockStatus {
70 Inactive,
71 Active,
72 Authentication,
73 Unknown(u8),
74}
75
76impl From<u8> for HanBlockStatus {
77 fn from(v: u8) -> Self {
78 match v {
79 0x01 => HanBlockStatus::Inactive,
80 0x02 => HanBlockStatus::Active,
81 0x03 => HanBlockStatus::Authentication,
82 _ => HanBlockStatus::Unknown(v),
83 }
84 }
85}
86
87impl From<HanBlockStatus> for u8 {
88 fn from(v: HanBlockStatus) -> Self {
89 match v {
90 HanBlockStatus::Inactive => 0x01,
91 HanBlockStatus::Active => 0x02,
92 HanBlockStatus::Authentication => 0x03,
93 HanBlockStatus::Unknown(v) => v,
94 }
95 }
96}
97
98#[derive(Copy, Clone, Eq, PartialEq, Debug)]
99#[cfg_attr(feature = "defmt", derive(defmt::Format))]
100pub enum OperationMode {
101 HanPanCoordinator,
102 HanCoordinator,
103 HanEndDevice,
104 Dual,
105 Unknown(u8),
106}
107
108impl From<u8> for OperationMode {
109 fn from(v: u8) -> Self {
110 match v {
111 0x01 => OperationMode::HanPanCoordinator,
112 0x02 => OperationMode::HanCoordinator,
113 0x03 => OperationMode::HanEndDevice,
114 0x05 => OperationMode::Dual,
115 _ => OperationMode::Unknown(v),
116 }
117 }
118}
119
120impl From<OperationMode> for u8 {
121 fn from(v: OperationMode) -> Self {
122 match v {
123 OperationMode::HanPanCoordinator => 0x01,
124 OperationMode::HanCoordinator => 0x02,
125 OperationMode::HanEndDevice => 0x03,
126 OperationMode::Dual => 0x05,
127 OperationMode::Unknown(v) => v,
128 }
129 }
130}
131
132#[derive(Copy, Clone, Eq, PartialEq, Debug)]
133#[cfg_attr(feature = "defmt", derive(defmt::Format))]
134pub enum Channel {
135 Ch4F922p5MHz,
136 Ch5F922p9MHz,
137 Ch6F923p3MHz,
138 Ch7F923p7MHz,
139 Ch8F924p1MHz,
140 Ch9F924p5MHz,
141 Ch10F924p9MHz,
142 Ch11F925p3MHz,
143 Ch12F925p7MHz,
144 Ch13F926p1MHz,
145 Ch14F926p5MHz,
146 Ch15F926p9MHz,
147 Ch16F927p3MHz,
148 Ch17F927p7MHz,
149 Unknown(u8),
150}
151
152impl From<u8> for Channel {
153 fn from(v: u8) -> Self {
154 match v {
155 0x04 => Channel::Ch4F922p5MHz,
156 0x05 => Channel::Ch5F922p9MHz,
157 0x06 => Channel::Ch6F923p3MHz,
158 0x07 => Channel::Ch7F923p7MHz,
159 0x08 => Channel::Ch8F924p1MHz,
160 0x09 => Channel::Ch9F924p5MHz,
161 0x0a => Channel::Ch10F924p9MHz,
162 0x0b => Channel::Ch11F925p3MHz,
163 0x0c => Channel::Ch12F925p7MHz,
164 0x0d => Channel::Ch13F926p1MHz,
165 0x0e => Channel::Ch14F926p5MHz,
166 0x0f => Channel::Ch15F926p9MHz,
167 0x10 => Channel::Ch16F927p3MHz,
168 0x11 => Channel::Ch17F927p7MHz,
169 _ => Channel::Unknown(v),
170 }
171 }
172}
173
174impl From<Channel> for u8 {
175 fn from(v: Channel) -> Self {
176 match v {
177 Channel::Ch4F922p5MHz => 0x04,
178 Channel::Ch5F922p9MHz => 0x05,
179 Channel::Ch6F923p3MHz => 0x06,
180 Channel::Ch7F923p7MHz => 0x07,
181 Channel::Ch8F924p1MHz => 0x08,
182 Channel::Ch9F924p5MHz => 0x09,
183 Channel::Ch10F924p9MHz => 0x0a,
184 Channel::Ch11F925p3MHz => 0x0b,
185 Channel::Ch12F925p7MHz => 0x0c,
186 Channel::Ch13F926p1MHz => 0x0d,
187 Channel::Ch14F926p5MHz => 0x0e,
188 Channel::Ch15F926p9MHz => 0x0f,
189 Channel::Ch16F927p3MHz => 0x10,
190 Channel::Ch17F927p7MHz => 0x11,
191 Channel::Unknown(v) => v,
192 }
193 }
194}
195
196#[derive(Copy, Clone, Eq, PartialEq, Debug)]
197#[cfg_attr(feature = "defmt", derive(defmt::Format))]
198pub enum TxPower {
199 P20mW,
200 P10mW,
201 P1mW,
202 Unknown(u8),
203}
204
205impl From<u8> for TxPower {
206 fn from(v: u8) -> Self {
207 match v {
208 0x00 => TxPower::P20mW,
209 0x01 => TxPower::P10mW,
210 0x02 => TxPower::P1mW,
211 _ => TxPower::Unknown(v),
212 }
213 }
214}
215
216impl From<TxPower> for u8 {
217 fn from(v: TxPower) -> Self {
218 match v {
219 TxPower::P20mW => 0x00,
220 TxPower::P10mW => 0x01,
221 TxPower::P1mW => 0x02,
222 TxPower::Unknown(v) => v,
223 }
224 }
225}
226
227#[derive(Copy, Clone, Eq, PartialEq, Debug)]
228#[cfg_attr(feature = "defmt", derive(defmt::Format))]
229pub enum ScanDuration {
230 T19p28ms,
231 T38p56ms,
232 T77p12ms,
233 T154p24ms,
234 T308p48ms,
235 T616p96ms,
236 T1233p92ms,
237 T2467p84ms,
238 T4935p68ms,
239 T9871p36ms,
240 T19742p72ms,
241 T39485p44ms,
242 T78970p88ms,
243 T157941p76ms,
244 Unknown(u8),
245}
246
247impl From<u8> for ScanDuration {
248 fn from(v: u8) -> Self {
249 match v {
250 0x01 => ScanDuration::T19p28ms,
251 0x02 => ScanDuration::T38p56ms,
252 0x03 => ScanDuration::T77p12ms,
253 0x04 => ScanDuration::T154p24ms,
254 0x05 => ScanDuration::T308p48ms,
255 0x06 => ScanDuration::T616p96ms,
256 0x07 => ScanDuration::T1233p92ms,
257 0x08 => ScanDuration::T2467p84ms,
258 0x09 => ScanDuration::T4935p68ms,
259 0x0a => ScanDuration::T9871p36ms,
260 0x0b => ScanDuration::T19742p72ms,
261 0x0c => ScanDuration::T39485p44ms,
262 0x0d => ScanDuration::T78970p88ms,
263 0x0e => ScanDuration::T157941p76ms,
264 _ => ScanDuration::Unknown(v),
265 }
266 }
267}
268
269impl From<ScanDuration> for u8 {
270 fn from(v: ScanDuration) -> Self {
271 match v {
272 ScanDuration::T19p28ms => 0x01,
273 ScanDuration::T38p56ms => 0x02,
274 ScanDuration::T77p12ms => 0x03,
275 ScanDuration::T154p24ms => 0x04,
276 ScanDuration::T308p48ms => 0x05,
277 ScanDuration::T616p96ms => 0x06,
278 ScanDuration::T1233p92ms => 0x07,
279 ScanDuration::T2467p84ms => 0x08,
280 ScanDuration::T4935p68ms => 0x09,
281 ScanDuration::T9871p36ms => 0x0a,
282 ScanDuration::T19742p72ms => 0x0b,
283 ScanDuration::T39485p44ms => 0x0c,
284 ScanDuration::T78970p88ms => 0x0d,
285 ScanDuration::T157941p76ms => 0x0e,
286 ScanDuration::Unknown(v) => v,
287 }
288 }
289}
290
291const COMMAND_RANGE_UNIQUE_CODE: Range<usize> = 0..4;
292const COMMAND_RANGE_COMMAND_CODE: Range<usize> = 4..6;
293const COMMAND_RANGE_MESSAGE_LEN: Range<usize> = 6..8;
294const COMMAND_RANGE_HEADER_SUM: Range<usize> = 8..10;
295const COMMAND_RANGE_DATA_SUM: Range<usize> = 10..12;
296const COMMAND_RANGE_DATA: RangeFrom<usize> = 12..;
297
298mod command;
299pub use command::*;
300
301mod response;
302pub use response::*;
303
304#[cfg(test)]
305mod tests {
306 extern crate std;
307 use crate::*;
308
309 #[test]
310 fn test_global_block_satatus() {
311 assert_eq!(GlobalBlockStatus::from(0x02u8), GlobalBlockStatus::Inactive);
312 assert_eq!(GlobalBlockStatus::from(0x03u8), GlobalBlockStatus::Active);
313 assert_eq!(
314 GlobalBlockStatus::from(0x7fu8),
315 GlobalBlockStatus::Unknown(0x7f)
316 );
317
318 assert_eq!(u8::from(GlobalBlockStatus::Inactive), 0x02);
319 assert_eq!(u8::from(GlobalBlockStatus::Active), 0x03);
320 assert_eq!(u8::from(GlobalBlockStatus::Unknown(0x7f)), 0x7f);
321 }
322
323 #[test]
324 fn test_route_b_block_satatus() {
325 assert_eq!(RouteBBlockStatus::from(0x01u8), RouteBBlockStatus::Inactive);
326 assert_eq!(RouteBBlockStatus::from(0x02u8), RouteBBlockStatus::Active);
327 assert_eq!(
328 RouteBBlockStatus::from(0x03u8),
329 RouteBBlockStatus::Authentication
330 );
331 assert_eq!(
332 RouteBBlockStatus::from(0x7fu8),
333 RouteBBlockStatus::Unknown(0x7f)
334 );
335
336 assert_eq!(u8::from(RouteBBlockStatus::Inactive), 0x01);
337 assert_eq!(u8::from(RouteBBlockStatus::Active), 0x02);
338 assert_eq!(u8::from(RouteBBlockStatus::Authentication), 0x03);
339 assert_eq!(u8::from(RouteBBlockStatus::Unknown(0x7f)), 0x7f);
340 }
341
342 #[test]
343 fn test_han_block_satatus() {
344 assert_eq!(HanBlockStatus::from(0x01u8), HanBlockStatus::Inactive);
345 assert_eq!(HanBlockStatus::from(0x02u8), HanBlockStatus::Active);
346 assert_eq!(HanBlockStatus::from(0x03u8), HanBlockStatus::Authentication);
347 assert_eq!(HanBlockStatus::from(0x7fu8), HanBlockStatus::Unknown(0x7f));
348
349 assert_eq!(u8::from(HanBlockStatus::Inactive), 0x01);
350 assert_eq!(u8::from(HanBlockStatus::Active), 0x02);
351 assert_eq!(u8::from(HanBlockStatus::Authentication), 0x03);
352 assert_eq!(u8::from(HanBlockStatus::Unknown(0x7f)), 0x7f);
353 }
354
355 #[test]
356 fn test_operation_mode() {
357 assert_eq!(
358 OperationMode::from(0x01u8),
359 OperationMode::HanPanCoordinator
360 );
361 assert_eq!(OperationMode::from(0x02u8), OperationMode::HanCoordinator);
362 assert_eq!(OperationMode::from(0x03u8), OperationMode::HanEndDevice);
363 assert_eq!(OperationMode::from(0x05u8), OperationMode::Dual);
364 assert_eq!(OperationMode::from(0x7fu8), OperationMode::Unknown(0x7f));
365
366 assert_eq!(u8::from(OperationMode::HanPanCoordinator), 0x01);
367 assert_eq!(u8::from(OperationMode::HanCoordinator), 0x02);
368 assert_eq!(u8::from(OperationMode::HanEndDevice), 0x03);
369 assert_eq!(u8::from(OperationMode::Dual), 0x05);
370 assert_eq!(u8::from(OperationMode::Unknown(0x7f)), 0x7f);
371 }
372
373 #[test]
374 fn test_channel() {
375 assert_eq!(Channel::from(0x04u8), Channel::Ch4F922p5MHz);
376 assert_eq!(Channel::from(0x05u8), Channel::Ch5F922p9MHz);
377 assert_eq!(Channel::from(0x06u8), Channel::Ch6F923p3MHz);
378 assert_eq!(Channel::from(0x07u8), Channel::Ch7F923p7MHz);
379 assert_eq!(Channel::from(0x08u8), Channel::Ch8F924p1MHz);
380 assert_eq!(Channel::from(0x09u8), Channel::Ch9F924p5MHz);
381 assert_eq!(Channel::from(0x0au8), Channel::Ch10F924p9MHz);
382 assert_eq!(Channel::from(0x0bu8), Channel::Ch11F925p3MHz);
383 assert_eq!(Channel::from(0x0cu8), Channel::Ch12F925p7MHz);
384 assert_eq!(Channel::from(0x0du8), Channel::Ch13F926p1MHz);
385 assert_eq!(Channel::from(0x0eu8), Channel::Ch14F926p5MHz);
386 assert_eq!(Channel::from(0x0fu8), Channel::Ch15F926p9MHz);
387 assert_eq!(Channel::from(0x10u8), Channel::Ch16F927p3MHz);
388 assert_eq!(Channel::from(0x11u8), Channel::Ch17F927p7MHz);
389 assert_eq!(Channel::from(0x7fu8), Channel::Unknown(0x7f));
390
391 assert_eq!(u8::from(Channel::Ch4F922p5MHz), 0x04);
392 assert_eq!(u8::from(Channel::Ch5F922p9MHz), 0x05);
393 assert_eq!(u8::from(Channel::Ch6F923p3MHz), 0x06);
394 assert_eq!(u8::from(Channel::Ch7F923p7MHz), 0x07);
395 assert_eq!(u8::from(Channel::Ch8F924p1MHz), 0x08);
396 assert_eq!(u8::from(Channel::Ch9F924p5MHz), 0x09);
397 assert_eq!(u8::from(Channel::Ch10F924p9MHz), 0x0a);
398 assert_eq!(u8::from(Channel::Ch11F925p3MHz), 0x0b);
399 assert_eq!(u8::from(Channel::Ch12F925p7MHz), 0x0c);
400 assert_eq!(u8::from(Channel::Ch13F926p1MHz), 0x0d);
401 assert_eq!(u8::from(Channel::Ch14F926p5MHz), 0x0e);
402 assert_eq!(u8::from(Channel::Ch15F926p9MHz), 0x0f);
403 assert_eq!(u8::from(Channel::Ch16F927p3MHz), 0x10);
404 assert_eq!(u8::from(Channel::Ch17F927p7MHz), 0x11);
405 assert_eq!(u8::from(Channel::Unknown(0x7f)), 0x7f);
406 }
407
408 #[test]
409 fn test_tx_power() {
410 assert_eq!(TxPower::from(0x00u8), TxPower::P20mW);
411 assert_eq!(TxPower::from(0x01u8), TxPower::P10mW);
412 assert_eq!(TxPower::from(0x02u8), TxPower::P1mW);
413 assert_eq!(TxPower::from(0x7fu8), TxPower::Unknown(0x7f));
414
415 assert_eq!(u8::from(TxPower::P20mW), 0x00);
416 assert_eq!(u8::from(TxPower::P10mW), 0x01);
417 assert_eq!(u8::from(TxPower::P1mW), 0x02);
418 assert_eq!(u8::from(TxPower::Unknown(0x7f)), 0x7f);
419 }
420}