mt_interface/
lib.rs

1pub const SOF: u8 = 0xFE;
2pub const MT_CMD_ID_SUB_SYS: u8 = 0x1F;
3pub const MT_CMD_ID_TYPE: u8 = 0xE0;
4pub const MT_CMD_ID_TYPE_SHIFT: usize = 5;
5pub const MT_CMD_BASE_CAP: usize = 5; // SOF(1) + MTCMD(3) + FCS(1)
6
7pub enum MtCommandType {
8    POLL = 0x00,
9    SREQ = 0x20,
10    AREQ = 0x40,
11    SRSP = 0x60,
12}
13
14pub enum Subsystem {
15    Reserved = 0x00,
16    SYSInterface = 0x01,
17    MACInterface = 0x02,
18    NWKInterface = 0x03,
19    AFInterface = 0x04,
20    ZDOInterface = 0x05,
21    SAPIInterface = 0x06,
22    UTILInterface = 0x07,
23    DEBUGInterface = 0x08,
24    APPInterface = 0x09,
25    APPConfig = 0x0F,
26    GreenPower = 0x15,
27}
28
29pub enum MtCommandSubsystem {}
30pub struct MtCommandId {
31    cmd0: u8,
32    cmd1: u8,
33}
34
35pub trait CommandId {
36    fn subsystem(&self) -> u8;
37    fn cmd_type(&self) -> u8;
38    fn cmd_id(&self) -> u8;
39}
40
41impl CommandId for MtCommandId {
42    fn subsystem(&self) -> u8 {
43        self.cmd0 & MT_CMD_ID_SUB_SYS
44    }
45
46    fn cmd_type(&self) -> u8 {
47        (self.cmd0 & MT_CMD_ID_TYPE) >> MT_CMD_ID_TYPE_SHIFT
48    }
49
50    fn cmd_id(&self) -> u8 {
51        self.cmd1
52    }
53}
54
55impl MtCommandId {
56    fn empty() -> Self {
57        MtCommandId { cmd0: 0, cmd1: 0 }
58    }
59}
60
61impl Default for MtCommandId {
62    fn default() -> Self {
63        MtCommandId::empty()
64    }
65}
66
67// TODO implement for MtCommand
68pub trait Command {
69    fn len(&self) -> u8;
70    fn cmd(&self) -> [u8; 2];
71    fn data(&self) -> [u8];
72}
73
74pub struct MtCommand {
75    data_len: u8,
76    cmd: MtCommandId,
77    data: [u8; 256],
78}
79
80impl MtCommand {
81    fn empty() -> Self {
82        MtCommand {
83            data_len: 0,
84            cmd: MtCommandId::empty(),
85            data: [0; 256],
86        }
87    }
88}
89
90impl Default for MtCommand {
91    fn default() -> Self {
92        MtCommand::empty()
93    }
94}
95
96pub struct GeneralSerialPacket {
97    mt_cmd: MtCommand,
98    fcs: u8,
99}
100
101impl GeneralSerialPacket {
102    fn from_cmd(mt_cmd: MtCommand) -> Self {
103        let cmd_id = &mt_cmd.cmd;
104
105        let fcs = cmd_id.cmd0
106            ^ cmd_id.cmd1
107            ^ mt_cmd.data[0..(mt_cmd.data_len as usize)]
108                .iter()
109                .fold(0, |x, y| x ^ y);
110
111        GeneralSerialPacket {
112            mt_cmd: mt_cmd,
113            fcs: fcs,
114        }
115    }
116
117    fn to_frame(&self) -> Vec<u8> {
118        //TODO change the len()
119        let mut frame = Vec::with_capacity(MT_CMD_BASE_CAP + (self.mt_cmd.data_len as usize));
120        frame.push(SOF);
121        frame.push(self.mt_cmd.cmd.cmd0);
122        frame.push(self.mt_cmd.cmd.cmd1);
123        self.mt_cmd.data.iter().for_each(|d| frame.push(*d));
124        frame.push(self.fcs);
125
126        frame
127    }
128}