bp35c0_j11/
response.rs

1use crate::*;
2
3use alloc::vec::Vec;
4
5#[derive(Copy, Clone, Eq, PartialEq, Debug)]
6#[cfg_attr(feature = "defmt", derive(defmt::Format))]
7pub struct TerminalInformation {
8    mac_address: u64,
9    pan_id: u16,
10    rssi: i8,
11}
12
13#[derive(Clone, Eq, PartialEq, Debug)]
14#[cfg_attr(feature = "defmt", derive(defmt::Format))]
15pub enum Response {
16    GetStatus {
17        result: u8,
18        global_block: GlobalBlockStatus,
19        route_b_block: RouteBBlockStatus,
20        han_block: HanBlockStatus,
21    },
22    GetOperationMode {
23        result: u8,
24        mode: OperationMode,
25        han_sleep: bool,
26        channel: Channel,
27        tx_power: TxPower,
28    },
29
30    SetOperationMode {
31        result: u8,
32    },
33    SetNeighborDiscoverySettings {
34        result: u8,
35    },
36    SetUartSettings {
37        result: u8,
38    },
39
40    OpenUdpPort {
41        result: u8,
42    },
43    CloseUdpPort {
44        result: u8,
45    },
46    TransmitData {
47        result: u8,
48        #[cfg_attr(feature = "defmt", defmt(Debug2Format))]
49        result_udp: Option<(u8, Vec<u8>)>,
50    },
51    DoActiveScan {
52        result: u8,
53    },
54
55    NotificationActiveScan {
56        channel: Channel,
57        #[cfg_attr(feature = "defmt", defmt(Debug2Format))]
58        terminal: Vec<TerminalInformation>,
59    },
60
61    GetVersionInformation {
62        result: u8,
63        firmware_id: u16,
64        major: u8,
65        minor: u8,
66        revision: u32,
67    },
68
69    NotificationUdpReceived {
70        source_address: u128,
71        source_port: u16,
72        destination_port: u16,
73        source_pan_id: u16,
74        source_type: u8,
75        encryption: u8,
76        rssi: i8,
77        #[cfg_attr(feature = "defmt", defmt(Debug2Format))]
78        data: Vec<u8>,
79    },
80    NotificationPoweredOn,
81    NotificationConnectionChanged {
82        state: u8,
83        mac_address: u64,
84        rssi: i8,
85    },
86    NotificationPanaAuthentication {
87        result: u8,
88        mac_address: u64,
89    },
90
91    GetRouteBEncryptionKey {
92        result: u8,
93        encryption_key: [u8; 16],
94    },
95    GetRouteBPanId {
96        result: u8,
97        pan_id: u16,
98    },
99
100    SetRouteBPanaAuthenticationInformation {
101        result: u8,
102    },
103
104    StartRouteBOperation {
105        result: u8,
106        terminal: Option<(Channel, TerminalInformation)>,
107    },
108    StartRouteBPana {
109        result: u8,
110    },
111    TerminateRouteBPana {
112        result: u8,
113    },
114    TerminateRouteBOperation {
115        result: u8,
116    },
117    RedoRouteBPanaAuthentication {
118        result: u8,
119    },
120
121    Unknown {
122        code: u16,
123        #[cfg_attr(feature = "defmt", defmt(Debug2Format))]
124        data: Vec<u8>,
125    },
126}
127
128fn make_response(code: u16, data: &[u8]) -> Response {
129    match (code, data) {
130        (0x2001, _) if data.len() == 4 => Response::GetStatus {
131            result: data[0],
132            global_block: data[1].into(),
133            route_b_block: data[2].into(),
134            han_block: data[3].into(),
135        },
136
137        (0x2107, _) if data.len() == 5 => Response::GetOperationMode {
138            result: data[0],
139            mode: data[1].into(),
140            han_sleep: data[2] != 0,
141            channel: data[3].into(),
142            tx_power: data[4].into(),
143        },
144
145        (0x205f, [d0]) => Response::SetOperationMode { result: *d0 },
146
147        (0x2101, [d0]) => Response::SetNeighborDiscoverySettings { result: *d0 },
148
149        (0x210a, [d0]) => Response::SetUartSettings { result: *d0 },
150
151        (0x2005, [d0]) => Response::OpenUdpPort { result: *d0 },
152
153        (0x2006, [d0]) => Response::CloseUdpPort { result: *d0 },
154
155        (0x2008, [result @ 0x01, result_udp, data @ ..]) if !data.is_empty() => {
156            Response::TransmitData {
157                result: *result,
158                result_udp: Some((*result_udp, data.into())),
159            }
160        }
161
162        (0x2008, [result]) => Response::TransmitData {
163            result: *result,
164            result_udp: None,
165        },
166
167        (0x2051, [d0]) => Response::DoActiveScan { result: *d0 },
168
169        (0x4051, [0x00, channel, n, data @ ..]) if data.len() == 11_usize * *n as usize => {
170            Response::NotificationActiveScan {
171                channel: (*channel).into(),
172                terminal: data
173                    .as_chunks::<11>()
174                    .0
175                    .iter()
176                    .map(|b| TerminalInformation {
177                        mac_address: u64::from_be_bytes(b[0..8].try_into().unwrap()),
178                        pan_id: u16::from_be_bytes(b[8..10].try_into().unwrap()),
179                        rssi: b[10] as _,
180                    })
181                    .collect(),
182            }
183        }
184
185        (0x4051, [0x01, channel]) => Response::NotificationActiveScan {
186            channel: (*channel).into(),
187            terminal: Vec::new(),
188        },
189
190        (0x206b, _) if data.len() == 9 => {
191            let result = data[0];
192            let firmware_id = u16::from_be_bytes(data[1..3].try_into().unwrap());
193            let major = data[3];
194            let minor = data[4];
195            let revision = u32::from_be_bytes(data[5..9].try_into().unwrap());
196            Response::GetVersionInformation {
197                result,
198                firmware_id,
199                major,
200                minor,
201                revision,
202            }
203        }
204
205        (0x6018, _)
206            if data
207                .get(25..27)
208                .and_then(|s| s.try_into().ok())
209                .map(|s| u16::from_be_bytes(s) as usize + 27)
210                == Some(data.len()) =>
211        {
212            Response::NotificationUdpReceived {
213                source_address: u128::from_be_bytes(data[0..16].try_into().unwrap()),
214                source_port: u16::from_be_bytes(data[16..18].try_into().unwrap()),
215                destination_port: u16::from_be_bytes(data[18..20].try_into().unwrap()),
216                source_pan_id: u16::from_be_bytes(data[20..22].try_into().unwrap()),
217                source_type: data[22],
218                encryption: data[23],
219                rssi: data[24] as _,
220                data: data[27..].into(),
221            }
222        }
223
224        (0x6019, []) => Response::NotificationPoweredOn,
225
226        (0x601a, _) if data.len() == 10 => Response::NotificationConnectionChanged {
227            state: data[0],
228            mac_address: u64::from_be_bytes(data[1..9].try_into().unwrap()),
229            rssi: data[9] as _,
230        },
231
232        (0x6028, _) if data.len() == 9 => Response::NotificationPanaAuthentication {
233            result: data[0],
234            mac_address: u64::from_be_bytes(data[1..9].try_into().unwrap()),
235        },
236
237        (0x2059, _) if data.len() == 17 => Response::GetRouteBEncryptionKey {
238            result: data[0],
239            encryption_key: {
240                let mut arr = [0; 16];
241                arr.copy_from_slice(&data[1..17]);
242                arr
243            },
244        },
245
246        (0x205e, _) if data.len() == 3 => {
247            let result = data[0];
248            let pan_id = u16::from_be_bytes(data[1..3].try_into().unwrap());
249            Response::GetRouteBPanId { result, pan_id }
250        }
251
252        (0x2054, [d0]) if data.len() == 1 => {
253            Response::SetRouteBPanaAuthenticationInformation { result: *d0 }
254        }
255
256        (0x2053, [result @ 0x01, data @ ..]) if data.len() == 12 => {
257            Response::StartRouteBOperation {
258                result: *result,
259                terminal: Some((
260                    data[0].into(),
261                    TerminalInformation {
262                        pan_id: u16::from_be_bytes(data[1..3].try_into().unwrap()),
263                        mac_address: u64::from_be_bytes(data[3..11].try_into().unwrap()),
264                        rssi: data[11] as _,
265                    },
266                )),
267            }
268        }
269
270        (0x2053, [d0]) => Response::StartRouteBOperation {
271            result: *d0,
272            terminal: None,
273        },
274
275        (0x2056, [d0]) => Response::StartRouteBPana { result: *d0 },
276
277        (0x2057, [d0]) => Response::TerminateRouteBPana { result: *d0 },
278
279        (0x2058, [d0]) => Response::TerminateRouteBOperation { result: *d0 },
280
281        (0x20d2, [d0]) => Response::RedoRouteBPanaAuthentication { result: *d0 },
282
283        _ => Response::Unknown {
284            code,
285            data: Vec::from(data),
286        },
287    }
288}
289
290#[derive(Copy, Clone, Debug)]
291#[cfg_attr(feature = "defmt", derive(defmt::Format))]
292pub enum State {
293    UniqueCode(u8),
294    Header {
295        ptr: usize,
296    },
297    Data {
298        ptr: usize,
299        code: u16,
300        sum: u16,
301        sum_current: u16,
302        len: usize,
303    },
304    Ready {
305        len: usize,
306        code: u16,
307    },
308}
309
310#[derive(Debug)]
311#[cfg_attr(feature = "defmt", derive(defmt::Format))]
312pub struct Parser {
313    buffer: [u8; 2048],
314    state: State,
315}
316
317const UNIQUE_CODE0: u8 = 0xd0;
318const UNIQUE_CODE1: u8 = 0xf9;
319const UNIQUE_CODE2: u8 = 0xee;
320const UNIQUE_CODE3: u8 = 0x5d;
321
322const HEADER_SUM_INIT: u16 =
323    UNIQUE_CODE0 as u16 + UNIQUE_CODE1 as u16 + UNIQUE_CODE2 as u16 + UNIQUE_CODE3 as u16;
324
325impl Default for State {
326    fn default() -> Self {
327        State::UniqueCode(UNIQUE_CODE0)
328    }
329}
330
331impl State {
332    fn next(self, buffer: &mut [u8], c: u8) -> State {
333        match self {
334            State::Ready { .. } => {
335                if c == UNIQUE_CODE0 {
336                    State::UniqueCode(UNIQUE_CODE1)
337                } else {
338                    State::default()
339                }
340            }
341
342            State::UniqueCode(expected) => match (c, expected) {
343                (UNIQUE_CODE0, UNIQUE_CODE0) => State::UniqueCode(UNIQUE_CODE1),
344                (UNIQUE_CODE1, UNIQUE_CODE1) => State::UniqueCode(UNIQUE_CODE2),
345                (UNIQUE_CODE2, UNIQUE_CODE2) => State::UniqueCode(UNIQUE_CODE3),
346                (UNIQUE_CODE3, UNIQUE_CODE3) => State::Header { ptr: 0 },
347                _ => State::default(),
348            },
349
350            State::Header { ptr } if ptr + 1 < 8 => {
351                buffer[ptr] = c;
352                State::Header { ptr: ptr + 1 }
353            }
354
355            State::Header { ptr } => {
356                buffer[ptr] = c;
357
358                let sum_header = u16::from_be_bytes([buffer[4], buffer[5]]);
359                if buffer[..4]
360                    .iter()
361                    .fold(HEADER_SUM_INIT, |acc, &x| acc + x as u16)
362                    != sum_header
363                {
364                    return State::default();
365                }
366
367                let len = u16::from_be_bytes([buffer[2], buffer[3]]);
368                if len < 4 || len as usize > buffer.len() {
369                    return State::default();
370                }
371
372                let code = u16::from_be_bytes([buffer[0], buffer[1]]);
373                let sum_data = u16::from_be_bytes([buffer[6], buffer[7]]);
374                if len == 4 && sum_data == 0 {
375                    State::Ready { len: 0, code }
376                } else {
377                    State::Data {
378                        ptr: 0,
379                        code,
380                        sum: sum_data,
381                        sum_current: 0,
382                        len: (len - 4).into(),
383                    }
384                }
385            }
386
387            State::Data {
388                ptr,
389                code,
390                sum,
391                sum_current,
392                len,
393            } if ptr + 1 < len => {
394                buffer[ptr] = c;
395                State::Data {
396                    ptr: ptr + 1,
397                    code,
398                    sum,
399                    sum_current: sum_current + c as u16,
400                    len,
401                }
402            }
403
404            State::Data {
405                ptr,
406                code,
407                sum,
408                sum_current,
409                len,
410            } => {
411                buffer[ptr] = c;
412                if sum_current + c as u16 != sum {
413                    return State::default();
414                }
415                State::Ready { len, code }
416            }
417        }
418    }
419}
420
421impl Default for Parser {
422    fn default() -> Self {
423        Parser {
424            buffer: [0; 2048],
425            state: State::default(),
426        }
427    }
428}
429
430impl Parser {
431    pub fn parse(&mut self, c: u8) -> Option<Response> {
432        self.state = self.state.next(&mut self.buffer, c);
433        match self.state {
434            State::Ready { len, code } => Some(make_response(code, &self.buffer[0..len])),
435            _ => None,
436        }
437    }
438}
439
440#[cfg(test)]
441mod tests {
442    extern crate std;
443    use crate::response::*;
444    use alloc::vec;
445
446    #[test]
447    fn test_parser() {
448        let mut p = Parser::default();
449
450        assert_eq!(p.parse(0xd0), None);
451        assert_eq!(p.parse(0xf9), None);
452        assert_eq!(p.parse(0xee), None);
453        assert_eq!(p.parse(0x5d), None);
454        assert_eq!(p.parse(0x20), None);
455        assert_eq!(p.parse(0x01), None);
456        assert_eq!(p.parse(0x00), None);
457        assert_eq!(p.parse(0x08), None);
458        assert_eq!(p.parse(0x03), None);
459        assert_eq!(p.parse(0x3d), None);
460        assert_eq!(p.parse(0x00), None);
461        assert_eq!(p.parse(0x07), None);
462        assert_eq!(p.parse(0x01), None);
463        assert_eq!(p.parse(0x02), None);
464        assert_eq!(p.parse(0x01), None);
465        assert_eq!(
466            p.parse(0x03),
467            Some(Response::GetStatus {
468                result: 0x01,
469                global_block: GlobalBlockStatus::Inactive,
470                route_b_block: RouteBBlockStatus::Inactive,
471                han_block: HanBlockStatus::Authentication,
472            })
473        );
474
475        assert_eq!(p.parse(0xd0), None);
476        assert_eq!(p.parse(0xf9), None);
477        assert_eq!(p.parse(0xee), None);
478        assert_eq!(p.parse(0x5d), None);
479        assert_eq!(p.parse(0x20), None);
480        assert_eq!(p.parse(0x5f), None);
481        assert_eq!(p.parse(0x00), None);
482        assert_eq!(p.parse(0x05), None);
483        assert_eq!(p.parse(0x03), None);
484        assert_eq!(p.parse(0x98), None);
485        assert_eq!(p.parse(0x00), None);
486        assert_eq!(p.parse(0x01), None);
487        assert_eq!(
488            p.parse(0x01),
489            Some(Response::SetOperationMode { result: 0x01 })
490        );
491
492        assert_eq!(p.parse(0xd0), None);
493        assert_eq!(p.parse(0xf9), None);
494        assert_eq!(p.parse(0xee), None);
495        assert_eq!(p.parse(0x5d), None);
496        assert_eq!(p.parse(0x21), None);
497        assert_eq!(p.parse(0x01), None);
498        assert_eq!(p.parse(0x00), None);
499        assert_eq!(p.parse(0x05), None);
500        assert_eq!(p.parse(0x03), None);
501        assert_eq!(p.parse(0x3b), None);
502        assert_eq!(p.parse(0x00), None);
503        assert_eq!(p.parse(0x01), None);
504        assert_eq!(
505            p.parse(0x01),
506            Some(Response::SetNeighborDiscoverySettings { result: 0x01 })
507        );
508
509        assert_eq!(p.parse(0xd0), None);
510        assert_eq!(p.parse(0xf9), None);
511        assert_eq!(p.parse(0xee), None);
512        assert_eq!(p.parse(0x5d), None);
513        assert_eq!(p.parse(0x21), None);
514        assert_eq!(p.parse(0x0a), None);
515        assert_eq!(p.parse(0x00), None);
516        assert_eq!(p.parse(0x05), None);
517        assert_eq!(p.parse(0x03), None);
518        assert_eq!(p.parse(0x44), None);
519        assert_eq!(p.parse(0x00), None);
520        assert_eq!(p.parse(0x01), None);
521        assert_eq!(
522            p.parse(0x01),
523            Some(Response::SetUartSettings { result: 0x01 })
524        );
525
526        assert_eq!(p.parse(0xd0), None);
527        assert_eq!(p.parse(0xf9), None);
528        assert_eq!(p.parse(0xee), None);
529        assert_eq!(p.parse(0x5d), None);
530        assert_eq!(p.parse(0x20), None);
531        assert_eq!(p.parse(0x05), None);
532        assert_eq!(p.parse(0x00), None);
533        assert_eq!(p.parse(0x05), None);
534        assert_eq!(p.parse(0x03), None);
535        assert_eq!(p.parse(0x3e), None);
536        assert_eq!(p.parse(0x00), None);
537        assert_eq!(p.parse(0x01), None);
538        assert_eq!(p.parse(0x01), Some(Response::OpenUdpPort { result: 0x01 }));
539
540        assert_eq!(p.parse(0xd0), None);
541        assert_eq!(p.parse(0xf9), None);
542        assert_eq!(p.parse(0xee), None);
543        assert_eq!(p.parse(0x5d), None);
544        assert_eq!(p.parse(0x20), None);
545        assert_eq!(p.parse(0x06), None);
546        assert_eq!(p.parse(0x00), None);
547        assert_eq!(p.parse(0x05), None);
548        assert_eq!(p.parse(0x03), None);
549        assert_eq!(p.parse(0x3f), None);
550        assert_eq!(p.parse(0x00), None);
551        assert_eq!(p.parse(0x01), None);
552        assert_eq!(p.parse(0x01), Some(Response::CloseUdpPort { result: 0x01 }));
553
554        assert_eq!(p.parse(0xd0), None);
555        assert_eq!(p.parse(0xf9), None);
556        assert_eq!(p.parse(0xee), None);
557        assert_eq!(p.parse(0x5d), None);
558        assert_eq!(p.parse(0x20), None);
559        assert_eq!(p.parse(0x08), None);
560        assert_eq!(p.parse(0x00), None);
561        assert_eq!(p.parse(0x05), None);
562        assert_eq!(p.parse(0x03), None);
563        assert_eq!(p.parse(0x41), None);
564        assert_eq!(p.parse(0x00), None);
565        assert_eq!(p.parse(0x02), None);
566        assert_eq!(
567            p.parse(0x02),
568            Some(Response::TransmitData {
569                result: 0x02,
570                result_udp: None,
571            })
572        );
573
574        assert_eq!(p.parse(0xd0), None);
575        assert_eq!(p.parse(0xf9), None);
576        assert_eq!(p.parse(0xee), None);
577        assert_eq!(p.parse(0x5d), None);
578        assert_eq!(p.parse(0x20), None);
579        assert_eq!(p.parse(0x08), None);
580        assert_eq!(p.parse(0x00), None);
581        assert_eq!(p.parse(0x09), None);
582        assert_eq!(p.parse(0x03), None);
583        assert_eq!(p.parse(0x45), None);
584        assert_eq!(p.parse(0x02), None);
585        assert_eq!(p.parse(0x7a), None);
586        assert_eq!(p.parse(0x01), None);
587        assert_eq!(p.parse(0x12), None);
588        assert_eq!(p.parse(0xab), None);
589        assert_eq!(p.parse(0xcd), None);
590        assert_eq!(
591            p.parse(0xef),
592            Some(Response::TransmitData {
593                result: 0x01,
594                result_udp: Some((0x12, vec![0xab, 0xcd, 0xef])),
595            })
596        );
597
598        assert_eq!(p.parse(0xd0), None);
599        assert_eq!(p.parse(0xf9), None);
600        assert_eq!(p.parse(0xee), None);
601        assert_eq!(p.parse(0x5d), None);
602        assert_eq!(p.parse(0x20), None);
603        assert_eq!(p.parse(0x51), None);
604        assert_eq!(p.parse(0x00), None);
605        assert_eq!(p.parse(0x05), None);
606        assert_eq!(p.parse(0x03), None);
607        assert_eq!(p.parse(0x8a), None);
608        assert_eq!(p.parse(0x00), None);
609        assert_eq!(p.parse(0x01), None);
610        assert_eq!(p.parse(0x01), Some(Response::DoActiveScan { result: 0x01 }));
611
612        assert_eq!(p.parse(0xd0), None);
613        assert_eq!(p.parse(0xf9), None);
614        assert_eq!(p.parse(0xee), None);
615        assert_eq!(p.parse(0x5d), None);
616        assert_eq!(p.parse(0x40), None);
617        assert_eq!(p.parse(0x51), None);
618        assert_eq!(p.parse(0x00), None);
619        assert_eq!(p.parse(0x06), None);
620        assert_eq!(p.parse(0x03), None);
621        assert_eq!(p.parse(0xab), None);
622        assert_eq!(p.parse(0x00), None);
623        assert_eq!(p.parse(0x08), None);
624        assert_eq!(p.parse(0x01), None);
625        assert_eq!(
626            p.parse(0x07),
627            Some(Response::NotificationActiveScan {
628                channel: Channel::Ch7F923p7MHz,
629                terminal: Vec::new()
630            })
631        );
632
633        assert_eq!(p.parse(0xd0), None);
634        assert_eq!(p.parse(0xf9), None);
635        assert_eq!(p.parse(0xee), None);
636        assert_eq!(p.parse(0x5d), None);
637        assert_eq!(p.parse(0x40), None);
638        assert_eq!(p.parse(0x51), None);
639        assert_eq!(p.parse(0x00), None);
640        assert_eq!(p.parse(0x1d), None);
641        assert_eq!(p.parse(0x03), None);
642        assert_eq!(p.parse(0xc2), None);
643        assert_eq!(p.parse(0x05), None);
644        assert_eq!(p.parse(0x1e), None);
645        assert_eq!(p.parse(0x00), None); // result
646        assert_eq!(p.parse(0x0c), None); // channel
647        assert_eq!(p.parse(0x02), None); // # of scans
648        assert_eq!(p.parse(0x00), None); // terminal[0].mac_address
649        assert_eq!(p.parse(0x01), None);
650        assert_eq!(p.parse(0x02), None);
651        assert_eq!(p.parse(0x03), None);
652        assert_eq!(p.parse(0x04), None);
653        assert_eq!(p.parse(0x05), None);
654        assert_eq!(p.parse(0x06), None);
655        assert_eq!(p.parse(0x07), None);
656        assert_eq!(p.parse(0xab), None); // terminal[0].pan_id
657        assert_eq!(p.parse(0xcd), None);
658        assert_eq!(p.parse(0xde), None); // terminal[0].rssi
659        assert_eq!(p.parse(0x00), None); // terminal[1].mac_address
660        assert_eq!(p.parse(0x10), None);
661        assert_eq!(p.parse(0x20), None);
662        assert_eq!(p.parse(0x30), None);
663        assert_eq!(p.parse(0x40), None);
664        assert_eq!(p.parse(0x50), None);
665        assert_eq!(p.parse(0x60), None);
666        assert_eq!(p.parse(0x70), None);
667        assert_eq!(p.parse(0x12), None); // terminal[1].pan_id
668        assert_eq!(p.parse(0x34), None);
669        assert_eq!(
670            p.parse(0x98), // terminal[1].rssi
671            Some(Response::NotificationActiveScan {
672                channel: Channel::Ch12F925p7MHz,
673                terminal: vec![
674                    TerminalInformation {
675                        mac_address: 0x0001020304050607,
676                        pan_id: 0xabcd,
677                        rssi: 0xde_u8 as i8,
678                    },
679                    TerminalInformation {
680                        mac_address: 0x0010203040506070,
681                        pan_id: 0x1234,
682                        rssi: 0x98_u8 as i8,
683                    },
684                ],
685            })
686        );
687
688        assert_eq!(p.parse(0xd0), None);
689        assert_eq!(p.parse(0xf9), None);
690        assert_eq!(p.parse(0xee), None);
691        assert_eq!(p.parse(0x5d), None);
692        assert_eq!(p.parse(0x20), None);
693        assert_eq!(p.parse(0x6b), None);
694        assert_eq!(p.parse(0x00), None);
695        assert_eq!(p.parse(0x0d), None);
696        assert_eq!(p.parse(0x03), None);
697        assert_eq!(p.parse(0xac), None);
698        assert_eq!(p.parse(0x00), None);
699        assert_eq!(p.parse(0xa8), None);
700        assert_eq!(p.parse(0x01), None);
701        assert_eq!(p.parse(0x04), None);
702        assert_eq!(p.parse(0x00), None);
703        assert_eq!(p.parse(0x01), None);
704        assert_eq!(p.parse(0x03), None);
705        assert_eq!(p.parse(0x00), None);
706        assert_eq!(p.parse(0x00), None);
707        assert_eq!(p.parse(0x15), None);
708        assert_eq!(
709            p.parse(0x8a),
710            Some(Response::GetVersionInformation {
711                result: 0x01,
712                firmware_id: 0x400,
713                major: 0x01,
714                minor: 0x03,
715                revision: 0x0000158a,
716            })
717        );
718
719        assert_eq!(p.parse(0xd0), None);
720        assert_eq!(p.parse(0xf9), None);
721        assert_eq!(p.parse(0xee), None);
722        assert_eq!(p.parse(0x5d), None);
723        assert_eq!(p.parse(0x60), None);
724        assert_eq!(p.parse(0x18), None);
725        assert_eq!(p.parse(0x00), None);
726        assert_eq!(p.parse(0x23), None);
727        assert_eq!(p.parse(0x03), None);
728        assert_eq!(p.parse(0xaf), None);
729        assert_eq!(p.parse(0x06), None);
730        assert_eq!(p.parse(0xde), None);
731        assert_eq!(p.parse(0xfe), None); // source_address
732        assert_eq!(p.parse(0x80), None);
733        assert_eq!(p.parse(0x00), None);
734        assert_eq!(p.parse(0x01), None);
735        assert_eq!(p.parse(0x02), None);
736        assert_eq!(p.parse(0x03), None);
737        assert_eq!(p.parse(0x04), None);
738        assert_eq!(p.parse(0x05), None);
739        assert_eq!(p.parse(0x06), None);
740        assert_eq!(p.parse(0x07), None);
741        assert_eq!(p.parse(0x08), None);
742        assert_eq!(p.parse(0x09), None);
743        assert_eq!(p.parse(0x0a), None);
744        assert_eq!(p.parse(0x0b), None);
745        assert_eq!(p.parse(0x0c), None);
746        assert_eq!(p.parse(0x0d), None);
747        assert_eq!(p.parse(0xab), None); // source_port
748        assert_eq!(p.parse(0xcd), None);
749        assert_eq!(p.parse(0x12), None); // destination_port
750        assert_eq!(p.parse(0x34), None);
751        assert_eq!(p.parse(0x56), None); // source_pan_id
752        assert_eq!(p.parse(0x78), None);
753        assert_eq!(p.parse(0x01), None); // source_type
754        assert_eq!(p.parse(0x02), None); // encryption
755        assert_eq!(p.parse(0xde), None); // rssi
756        assert_eq!(p.parse(0x00), None); // len
757        assert_eq!(p.parse(0x04), None);
758        assert_eq!(p.parse(0x98), None); // data
759        assert_eq!(p.parse(0x76), None);
760        assert_eq!(p.parse(0x54), None);
761        assert_eq!(
762            p.parse(0x32),
763            Some(Response::NotificationUdpReceived {
764                source_address: 0xfe80000102030405060708090a0b0c0d,
765                source_port: 0xabcd,
766                destination_port: 0x1234,
767                source_pan_id: 0x5678,
768                source_type: 0x01,
769                encryption: 0x02,
770                rssi: 0xde_u8 as i8,
771                data: vec![0x98, 0x76, 0x54, 0x32],
772            })
773        );
774
775        assert_eq!(p.parse(0xd0), None);
776        assert_eq!(p.parse(0xf9), None);
777        assert_eq!(p.parse(0xee), None);
778        assert_eq!(p.parse(0x5d), None);
779        assert_eq!(p.parse(0x60), None);
780        assert_eq!(p.parse(0x19), None);
781        assert_eq!(p.parse(0x00), None);
782        assert_eq!(p.parse(0x04), None);
783        assert_eq!(p.parse(0x03), None);
784        assert_eq!(p.parse(0x91), None);
785        assert_eq!(p.parse(0x00), None);
786        assert_eq!(p.parse(0x00), Some(Response::NotificationPoweredOn));
787
788        assert_eq!(p.parse(0xd0), None);
789        assert_eq!(p.parse(0xf9), None);
790        assert_eq!(p.parse(0xee), None);
791        assert_eq!(p.parse(0x5d), None);
792        assert_eq!(p.parse(0x60), None);
793        assert_eq!(p.parse(0x1a), None);
794        assert_eq!(p.parse(0x00), None);
795        assert_eq!(p.parse(0x0e), None);
796        assert_eq!(p.parse(0x03), None);
797        assert_eq!(p.parse(0x9c), None);
798        assert_eq!(p.parse(0x00), None);
799        assert_eq!(p.parse(0xfb), None);
800        assert_eq!(p.parse(0x01), None); // state
801        assert_eq!(p.parse(0x00), None); // mac_address
802        assert_eq!(p.parse(0x01), None);
803        assert_eq!(p.parse(0x02), None);
804        assert_eq!(p.parse(0x03), None);
805        assert_eq!(p.parse(0x04), None);
806        assert_eq!(p.parse(0x05), None);
807        assert_eq!(p.parse(0x06), None);
808        assert_eq!(p.parse(0x07), None);
809        assert_eq!(
810            p.parse(0xde), // terminal[0].rssi
811            Some(Response::NotificationConnectionChanged {
812                state: 0x01,
813                mac_address: 0x0001020304050607,
814                rssi: 0xde_u8 as i8,
815            })
816        );
817
818        assert_eq!(p.parse(0xd0), None);
819        assert_eq!(p.parse(0xf9), None);
820        assert_eq!(p.parse(0xee), None);
821        assert_eq!(p.parse(0x5d), None);
822        assert_eq!(p.parse(0x60), None);
823        assert_eq!(p.parse(0x28), None);
824        assert_eq!(p.parse(0x00), None);
825        assert_eq!(p.parse(0x0d), None);
826        assert_eq!(p.parse(0x03), None);
827        assert_eq!(p.parse(0xa9), None);
828        assert_eq!(p.parse(0x00), None);
829        assert_eq!(p.parse(0x1d), None);
830        assert_eq!(p.parse(0x01), None); // result
831        assert_eq!(p.parse(0x00), None); // mac_address
832        assert_eq!(p.parse(0x01), None);
833        assert_eq!(p.parse(0x02), None);
834        assert_eq!(p.parse(0x03), None);
835        assert_eq!(p.parse(0x04), None);
836        assert_eq!(p.parse(0x05), None);
837        assert_eq!(p.parse(0x06), None);
838        assert_eq!(
839            p.parse(0x07),
840            Some(Response::NotificationPanaAuthentication {
841                result: 0x01,
842                mac_address: 0x0001020304050607,
843            })
844        );
845
846        assert_eq!(p.parse(0xd0), None);
847        assert_eq!(p.parse(0xf9), None);
848        assert_eq!(p.parse(0xee), None);
849        assert_eq!(p.parse(0x5d), None);
850        assert_eq!(p.parse(0x20), None);
851        assert_eq!(p.parse(0x59), None);
852        assert_eq!(p.parse(0x00), None);
853        assert_eq!(p.parse(0x15), None);
854        assert_eq!(p.parse(0x03), None);
855        assert_eq!(p.parse(0xa2), None);
856        assert_eq!(p.parse(0x00), None);
857        assert_eq!(p.parse(0x79), None);
858        assert_eq!(p.parse(0x01), None);
859        assert_eq!(p.parse(0x00), None);
860        assert_eq!(p.parse(0x01), None);
861        assert_eq!(p.parse(0x02), None);
862        assert_eq!(p.parse(0x03), None);
863        assert_eq!(p.parse(0x04), None);
864        assert_eq!(p.parse(0x05), None);
865        assert_eq!(p.parse(0x06), None);
866        assert_eq!(p.parse(0x07), None);
867        assert_eq!(p.parse(0x08), None);
868        assert_eq!(p.parse(0x09), None);
869        assert_eq!(p.parse(0x0a), None);
870        assert_eq!(p.parse(0x0b), None);
871        assert_eq!(p.parse(0x0c), None);
872        assert_eq!(p.parse(0x0d), None);
873        assert_eq!(p.parse(0x0e), None);
874        assert_eq!(
875            p.parse(0x0f),
876            Some(Response::GetRouteBEncryptionKey {
877                result: 0x01,
878                encryption_key: [
879                    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c,
880                    0x0d, 0x0e, 0x0f
881                ]
882            })
883        );
884
885        assert_eq!(p.parse(0xd0), None);
886        assert_eq!(p.parse(0xf9), None);
887        assert_eq!(p.parse(0xee), None);
888        assert_eq!(p.parse(0x5d), None);
889        assert_eq!(p.parse(0x20), None);
890        assert_eq!(p.parse(0x5e), None);
891        assert_eq!(p.parse(0x00), None);
892        assert_eq!(p.parse(0x07), None);
893        assert_eq!(p.parse(0x03), None);
894        assert_eq!(p.parse(0x99), None);
895        assert_eq!(p.parse(0x00), None);
896        assert_eq!(p.parse(0x06), None);
897        assert_eq!(p.parse(0x01), None);
898        assert_eq!(p.parse(0x02), None);
899        assert_eq!(
900            p.parse(0x03),
901            Some(Response::GetRouteBPanId {
902                result: 0x01,
903                pan_id: 0x0203,
904            })
905        );
906
907        assert_eq!(p.parse(0xd0), None);
908        assert_eq!(p.parse(0xf9), None);
909        assert_eq!(p.parse(0xee), None);
910        assert_eq!(p.parse(0x5d), None);
911        assert_eq!(p.parse(0x20), None);
912        assert_eq!(p.parse(0x54), None);
913        assert_eq!(p.parse(0x00), None);
914        assert_eq!(p.parse(0x05), None);
915        assert_eq!(p.parse(0x03), None);
916        assert_eq!(p.parse(0x8d), None);
917        assert_eq!(p.parse(0x00), None);
918        assert_eq!(p.parse(0x01), None);
919        assert_eq!(
920            p.parse(0x01),
921            Some(Response::SetRouteBPanaAuthenticationInformation { result: 0x01 })
922        );
923
924        assert_eq!(p.parse(0xd0), None);
925        assert_eq!(p.parse(0xf9), None);
926        assert_eq!(p.parse(0xee), None);
927        assert_eq!(p.parse(0x5d), None);
928        assert_eq!(p.parse(0x20), None);
929        assert_eq!(p.parse(0x53), None);
930        assert_eq!(p.parse(0x00), None);
931        assert_eq!(p.parse(0x05), None);
932        assert_eq!(p.parse(0x03), None);
933        assert_eq!(p.parse(0x8c), None);
934        assert_eq!(p.parse(0x00), None);
935        assert_eq!(p.parse(0x02), None);
936        assert_eq!(
937            p.parse(0x02),
938            Some(Response::StartRouteBOperation {
939                result: 0x02,
940                terminal: None,
941            })
942        );
943
944        assert_eq!(p.parse(0xd0), None);
945        assert_eq!(p.parse(0xf9), None);
946        assert_eq!(p.parse(0xee), None);
947        assert_eq!(p.parse(0x5d), None);
948        assert_eq!(p.parse(0x20), None);
949        assert_eq!(p.parse(0x53), None);
950        assert_eq!(p.parse(0x00), None);
951        assert_eq!(p.parse(0x11), None);
952        assert_eq!(p.parse(0x03), None);
953        assert_eq!(p.parse(0x98), None);
954        assert_eq!(p.parse(0x02), None);
955        assert_eq!(p.parse(0x7b), None);
956        assert_eq!(p.parse(0x01), None);
957        assert_eq!(p.parse(0x08), None); // channel
958        assert_eq!(p.parse(0xab), None); // pan_id
959        assert_eq!(p.parse(0xcd), None);
960        assert_eq!(p.parse(0x00), None); // mac_address
961        assert_eq!(p.parse(0x01), None);
962        assert_eq!(p.parse(0x02), None);
963        assert_eq!(p.parse(0x03), None);
964        assert_eq!(p.parse(0x04), None);
965        assert_eq!(p.parse(0x05), None);
966        assert_eq!(p.parse(0x06), None);
967        assert_eq!(p.parse(0x07), None);
968        assert_eq!(
969            p.parse(0xde), // terminal[0].rssi
970            Some(Response::StartRouteBOperation {
971                result: 0x01,
972                terminal: Some((
973                    Channel::Ch8F924p1MHz,
974                    TerminalInformation {
975                        mac_address: 0x0001020304050607,
976                        pan_id: 0xabcd,
977                        rssi: 0xde_u8 as i8,
978                    }
979                )),
980            })
981        );
982
983        assert_eq!(p.parse(0xd0), None);
984        assert_eq!(p.parse(0xf9), None);
985        assert_eq!(p.parse(0xee), None);
986        assert_eq!(p.parse(0x5d), None);
987        assert_eq!(p.parse(0x20), None);
988        assert_eq!(p.parse(0x56), None);
989        assert_eq!(p.parse(0x00), None);
990        assert_eq!(p.parse(0x05), None);
991        assert_eq!(p.parse(0x03), None);
992        assert_eq!(p.parse(0x8f), None);
993        assert_eq!(p.parse(0x00), None);
994        assert_eq!(p.parse(0x01), None);
995        assert_eq!(
996            p.parse(0x01),
997            Some(Response::StartRouteBPana { result: 0x01 })
998        );
999
1000        assert_eq!(p.parse(0xd0), None);
1001        assert_eq!(p.parse(0xf9), None);
1002        assert_eq!(p.parse(0xee), None);
1003        assert_eq!(p.parse(0x5d), None);
1004        assert_eq!(p.parse(0x20), None);
1005        assert_eq!(p.parse(0x57), None);
1006        assert_eq!(p.parse(0x00), None);
1007        assert_eq!(p.parse(0x05), None);
1008        assert_eq!(p.parse(0x03), None);
1009        assert_eq!(p.parse(0x90), None);
1010        assert_eq!(p.parse(0x00), None);
1011        assert_eq!(p.parse(0x01), None);
1012        assert_eq!(
1013            p.parse(0x01),
1014            Some(Response::TerminateRouteBPana { result: 0x01 })
1015        );
1016
1017        assert_eq!(p.parse(0xd0), None);
1018        assert_eq!(p.parse(0xf9), None);
1019        assert_eq!(p.parse(0xee), None);
1020        assert_eq!(p.parse(0x5d), None);
1021        assert_eq!(p.parse(0x20), None);
1022        assert_eq!(p.parse(0x58), None);
1023        assert_eq!(p.parse(0x00), None);
1024        assert_eq!(p.parse(0x05), None);
1025        assert_eq!(p.parse(0x03), None);
1026        assert_eq!(p.parse(0x91), None);
1027        assert_eq!(p.parse(0x00), None);
1028        assert_eq!(p.parse(0x01), None);
1029        assert_eq!(
1030            p.parse(0x01),
1031            Some(Response::TerminateRouteBOperation { result: 0x01 })
1032        );
1033
1034        assert_eq!(p.parse(0xd0), None);
1035        assert_eq!(p.parse(0xf9), None);
1036        assert_eq!(p.parse(0xee), None);
1037        assert_eq!(p.parse(0x5d), None);
1038        assert_eq!(p.parse(0x20), None);
1039        assert_eq!(p.parse(0xd2), None);
1040        assert_eq!(p.parse(0x00), None);
1041        assert_eq!(p.parse(0x05), None);
1042        assert_eq!(p.parse(0x04), None);
1043        assert_eq!(p.parse(0x0b), None);
1044        assert_eq!(p.parse(0x00), None);
1045        assert_eq!(p.parse(0x01), None);
1046        assert_eq!(
1047            p.parse(0x01),
1048            Some(Response::RedoRouteBPanaAuthentication { result: 0x01 })
1049        );
1050    }
1051}