Mercurial > ~darius > hgwebdir.cgi > ZigBee
annotate zb.py @ 9:d147529ad2db
Switch to only reading RX pkts and writing TX pkts to make things simpler.
Add AT reply test case.
author | darius@inchoate.localdomain |
---|---|
date | Mon, 05 Nov 2007 23:35:52 +1030 |
parents | 9f0808b13454 |
children | 4c91fdfc862e |
rev | line source |
---|---|
4 | 1 import serial, inspect |
1 | 2 |
9
d147529ad2db
Switch to only reading RX pkts and writing TX pkts to make things simpler.
darius@inchoate.localdomain
parents:
8
diff
changeset
|
3 def easyord(i): |
d147529ad2db
Switch to only reading RX pkts and writing TX pkts to make things simpler.
darius@inchoate.localdomain
parents:
8
diff
changeset
|
4 if (type(i) != type(str())): |
d147529ad2db
Switch to only reading RX pkts and writing TX pkts to make things simpler.
darius@inchoate.localdomain
parents:
8
diff
changeset
|
5 return i |
d147529ad2db
Switch to only reading RX pkts and writing TX pkts to make things simpler.
darius@inchoate.localdomain
parents:
8
diff
changeset
|
6 else: |
d147529ad2db
Switch to only reading RX pkts and writing TX pkts to make things simpler.
darius@inchoate.localdomain
parents:
8
diff
changeset
|
7 return ord(i) |
d147529ad2db
Switch to only reading RX pkts and writing TX pkts to make things simpler.
darius@inchoate.localdomain
parents:
8
diff
changeset
|
8 |
1 | 9 class PktBase(object): |
9
d147529ad2db
Switch to only reading RX pkts and writing TX pkts to make things simpler.
darius@inchoate.localdomain
parents:
8
diff
changeset
|
10 PKT_MAXLEN = 2 ** 16 |
d147529ad2db
Switch to only reading RX pkts and writing TX pkts to make things simpler.
darius@inchoate.localdomain
parents:
8
diff
changeset
|
11 |
4 | 12 def __init__(self, data = []): |
9
d147529ad2db
Switch to only reading RX pkts and writing TX pkts to make things simpler.
darius@inchoate.localdomain
parents:
8
diff
changeset
|
13 self._data = data |
1 | 14 print "Constructing " + self.__class__.__name__ |
15 | |
4 | 16 def Encapsulate(self): |
17 return Packets.Encapsulate([self.PKT_TYPE] + self.data) | |
1 | 18 |
4 | 19 def resize(self, dlen): |
20 """Ensure the data list can hold at least len elements (0 fill)""" | |
9
d147529ad2db
Switch to only reading RX pkts and writing TX pkts to make things simpler.
darius@inchoate.localdomain
parents:
8
diff
changeset
|
21 if (len(self._data) < dlen): |
d147529ad2db
Switch to only reading RX pkts and writing TX pkts to make things simpler.
darius@inchoate.localdomain
parents:
8
diff
changeset
|
22 self._data = (self._data + [0] * dlen)[0:dlen] |
d147529ad2db
Switch to only reading RX pkts and writing TX pkts to make things simpler.
darius@inchoate.localdomain
parents:
8
diff
changeset
|
23 |
d147529ad2db
Switch to only reading RX pkts and writing TX pkts to make things simpler.
darius@inchoate.localdomain
parents:
8
diff
changeset
|
24 def _checklist(list, min = 0, max = 255, maxlen = None): |
d147529ad2db
Switch to only reading RX pkts and writing TX pkts to make things simpler.
darius@inchoate.localdomain
parents:
8
diff
changeset
|
25 if (maxlen != None and len(list) > maxlen): |
d147529ad2db
Switch to only reading RX pkts and writing TX pkts to make things simpler.
darius@inchoate.localdomain
parents:
8
diff
changeset
|
26 raise ValueError("must have %d elements" % (maxlen)) |
d147529ad2db
Switch to only reading RX pkts and writing TX pkts to make things simpler.
darius@inchoate.localdomain
parents:
8
diff
changeset
|
27 |
d147529ad2db
Switch to only reading RX pkts and writing TX pkts to make things simpler.
darius@inchoate.localdomain
parents:
8
diff
changeset
|
28 for i in xrange(len(list)): |
d147529ad2db
Switch to only reading RX pkts and writing TX pkts to make things simpler.
darius@inchoate.localdomain
parents:
8
diff
changeset
|
29 if (easyord(list[i]) < min or easyord(list[i]) > max): |
d147529ad2db
Switch to only reading RX pkts and writing TX pkts to make things simpler.
darius@inchoate.localdomain
parents:
8
diff
changeset
|
30 raise ValueError("element %d (= %d) out of range must be between %d and %d inclusive" % |
d147529ad2db
Switch to only reading RX pkts and writing TX pkts to make things simpler.
darius@inchoate.localdomain
parents:
8
diff
changeset
|
31 (i, ord(list[i]), min, max)) |
d147529ad2db
Switch to only reading RX pkts and writing TX pkts to make things simpler.
darius@inchoate.localdomain
parents:
8
diff
changeset
|
32 _checklist = staticmethod(_checklist) |
d147529ad2db
Switch to only reading RX pkts and writing TX pkts to make things simpler.
darius@inchoate.localdomain
parents:
8
diff
changeset
|
33 |
d147529ad2db
Switch to only reading RX pkts and writing TX pkts to make things simpler.
darius@inchoate.localdomain
parents:
8
diff
changeset
|
34 class TXPkts(PktBase): |
d147529ad2db
Switch to only reading RX pkts and writing TX pkts to make things simpler.
darius@inchoate.localdomain
parents:
8
diff
changeset
|
35 """Base class for all packets that go to the module""" |
d147529ad2db
Switch to only reading RX pkts and writing TX pkts to make things simpler.
darius@inchoate.localdomain
parents:
8
diff
changeset
|
36 def setframeid(self, value): |
d147529ad2db
Switch to only reading RX pkts and writing TX pkts to make things simpler.
darius@inchoate.localdomain
parents:
8
diff
changeset
|
37 if (value < 0 or value > 255): |
d147529ad2db
Switch to only reading RX pkts and writing TX pkts to make things simpler.
darius@inchoate.localdomain
parents:
8
diff
changeset
|
38 raise ValueError("FrameID must be 0-255") |
d147529ad2db
Switch to only reading RX pkts and writing TX pkts to make things simpler.
darius@inchoate.localdomain
parents:
8
diff
changeset
|
39 self._frameid = value |
d147529ad2db
Switch to only reading RX pkts and writing TX pkts to make things simpler.
darius@inchoate.localdomain
parents:
8
diff
changeset
|
40 frameid = property(lambda s: s._frameid, setframeid) |
4 | 41 |
9
d147529ad2db
Switch to only reading RX pkts and writing TX pkts to make things simpler.
darius@inchoate.localdomain
parents:
8
diff
changeset
|
42 |
d147529ad2db
Switch to only reading RX pkts and writing TX pkts to make things simpler.
darius@inchoate.localdomain
parents:
8
diff
changeset
|
43 class AT_Cmd(TXPkts): |
1 | 44 PKT_TYPE = 0x08 |
45 PKT_DESC = "AT Command" | |
46 | |
4 | 47 def __init__(self, *args): |
48 if (len(args) == 1): | |
6 | 49 if (type(args[0]) == type(str())): |
50 super(AT_Cmd, self).__init__([]) | |
51 self.cmd = args[0] | |
52 else: | |
53 super(AT_Cmd, self).__init__(args[0]) | |
4 | 54 elif (len(args) == 2): |
55 super(AT_Cmd, self).__init__([]) | |
56 self.cmd = args[0] | |
6 | 57 self.cmdarg = args[1] |
4 | 58 else: |
6 | 59 raise TypeError("__init__ takes 1 list of ordinals, 1 string, or 2 strings") |
9
d147529ad2db
Switch to only reading RX pkts and writing TX pkts to make things simpler.
darius@inchoate.localdomain
parents:
8
diff
changeset
|
60 self.frameid = 0 |
d147529ad2db
Switch to only reading RX pkts and writing TX pkts to make things simpler.
darius@inchoate.localdomain
parents:
8
diff
changeset
|
61 self.cmdarg = [] |
d147529ad2db
Switch to only reading RX pkts and writing TX pkts to make things simpler.
darius@inchoate.localdomain
parents:
8
diff
changeset
|
62 |
4 | 63 def setcmd(self, value): |
9
d147529ad2db
Switch to only reading RX pkts and writing TX pkts to make things simpler.
darius@inchoate.localdomain
parents:
8
diff
changeset
|
64 if (len(value) != 2): |
d147529ad2db
Switch to only reading RX pkts and writing TX pkts to make things simpler.
darius@inchoate.localdomain
parents:
8
diff
changeset
|
65 raise ValueError("must have 2 elements") |
d147529ad2db
Switch to only reading RX pkts and writing TX pkts to make things simpler.
darius@inchoate.localdomain
parents:
8
diff
changeset
|
66 self._checklist(value, ord('0'), ord('z')) |
d147529ad2db
Switch to only reading RX pkts and writing TX pkts to make things simpler.
darius@inchoate.localdomain
parents:
8
diff
changeset
|
67 self._cmd = value |
d147529ad2db
Switch to only reading RX pkts and writing TX pkts to make things simpler.
darius@inchoate.localdomain
parents:
8
diff
changeset
|
68 cmd = property(lambda s: s._cmd, setcmd) |
4 | 69 |
70 def setcmdarg(self, value): | |
9
d147529ad2db
Switch to only reading RX pkts and writing TX pkts to make things simpler.
darius@inchoate.localdomain
parents:
8
diff
changeset
|
71 self._checklist(value, maxlen = self.PKT_MAXLEN - 3) |
d147529ad2db
Switch to only reading RX pkts and writing TX pkts to make things simpler.
darius@inchoate.localdomain
parents:
8
diff
changeset
|
72 self._cmdarg = value |
d147529ad2db
Switch to only reading RX pkts and writing TX pkts to make things simpler.
darius@inchoate.localdomain
parents:
8
diff
changeset
|
73 cmdarg = property(lambda s: s._cmdarg, setcmdarg) |
d147529ad2db
Switch to only reading RX pkts and writing TX pkts to make things simpler.
darius@inchoate.localdomain
parents:
8
diff
changeset
|
74 |
d147529ad2db
Switch to only reading RX pkts and writing TX pkts to make things simpler.
darius@inchoate.localdomain
parents:
8
diff
changeset
|
75 def getdata(self): |
d147529ad2db
Switch to only reading RX pkts and writing TX pkts to make things simpler.
darius@inchoate.localdomain
parents:
8
diff
changeset
|
76 return([self.frameid] + map(ord, self.cmd) + map(easyord, self.cmdarg)) |
d147529ad2db
Switch to only reading RX pkts and writing TX pkts to make things simpler.
darius@inchoate.localdomain
parents:
8
diff
changeset
|
77 data = property(getdata) |
d147529ad2db
Switch to only reading RX pkts and writing TX pkts to make things simpler.
darius@inchoate.localdomain
parents:
8
diff
changeset
|
78 |
4 | 79 class AT_Cmd_Queue(AT_Cmd): |
1 | 80 PKT_TYPE = 0x09 |
81 PKT_DESC = "AT Command (queued)" | |
82 | |
83 class AT_Response(PktBase): | |
84 PKT_TYPE = 0x88 | |
85 PKT_DESC = "AT Command response" | |
9
d147529ad2db
Switch to only reading RX pkts and writing TX pkts to make things simpler.
darius@inchoate.localdomain
parents:
8
diff
changeset
|
86 frameid = property(lambda s: s._data[0], None) |
d147529ad2db
Switch to only reading RX pkts and writing TX pkts to make things simpler.
darius@inchoate.localdomain
parents:
8
diff
changeset
|
87 cmd = property(lambda s: chr(s._data[1]) + chr(s._data[2]), None) |
d147529ad2db
Switch to only reading RX pkts and writing TX pkts to make things simpler.
darius@inchoate.localdomain
parents:
8
diff
changeset
|
88 statusOK = property(lambda s: s._data[3] == 0, None) |
d147529ad2db
Switch to only reading RX pkts and writing TX pkts to make things simpler.
darius@inchoate.localdomain
parents:
8
diff
changeset
|
89 payload = property(lambda s: s._data[4:], None) |
1 | 90 |
91 class Modem_Status(PktBase): | |
92 PKT_TYPE = 0x8a | |
93 PKT_DESC = "Modem Status" | |
94 | |
95 class RX_16_Bit(PktBase): | |
96 PKT_TYPE = 0x81 | |
97 PKT_DESC = "RX Packet: 16 bit address" | |
4 | 98 ADDR_SIZE = 2 |
99 | |
8
9f0808b13454
Use non-blocking serial access. Add __str__ method for RX packets.
darius@inchoate.localdomain
parents:
7
diff
changeset
|
100 def __str__(self): |
9f0808b13454
Use non-blocking serial access. Add __str__ method for RX packets.
darius@inchoate.localdomain
parents:
7
diff
changeset
|
101 return "0x%0*x (%ddBm) -> %s" % (self.ADDR_SIZE * 2, self.sender, |
9f0808b13454
Use non-blocking serial access. Add __str__ method for RX packets.
darius@inchoate.localdomain
parents:
7
diff
changeset
|
102 self.rssi, str(self.payload)) |
9f0808b13454
Use non-blocking serial access. Add __str__ method for RX packets.
darius@inchoate.localdomain
parents:
7
diff
changeset
|
103 |
4 | 104 def getsender(self): |
105 value = 0 | |
106 for i, j in zip(reversed(range(self.ADDR_SIZE)), range(0, self.ADDR_SIZE * 8, 8)): | |
9
d147529ad2db
Switch to only reading RX pkts and writing TX pkts to make things simpler.
darius@inchoate.localdomain
parents:
8
diff
changeset
|
107 value |= self._data[i] << j |
4 | 108 return value |
5 | 109 sender = property(getsender, None) |
110 | |
9
d147529ad2db
Switch to only reading RX pkts and writing TX pkts to make things simpler.
darius@inchoate.localdomain
parents:
8
diff
changeset
|
111 rssi = property(lambda s: -1 * s._data[s.ADDR_SIZE], None) |
1 | 112 |
9
d147529ad2db
Switch to only reading RX pkts and writing TX pkts to make things simpler.
darius@inchoate.localdomain
parents:
8
diff
changeset
|
113 flags = property(lambda s: s._data[s.ADDR_SIZE + 1], None) |
4 | 114 |
9
d147529ad2db
Switch to only reading RX pkts and writing TX pkts to make things simpler.
darius@inchoate.localdomain
parents:
8
diff
changeset
|
115 payload = property(lambda s: s._data[s.ADDR_SIZE + 2:], None) |
5 | 116 |
4 | 117 class RX_64_Bit(RX_16_Bit): |
118 PKT_TYPE = 0x80 | |
119 PKT_DESC = "RX Packet: 64 bit address" | |
120 ADDR_SIZE = 8 | |
121 | |
122 class RXIO_16_Bit(RX_16_Bit): | |
1 | 123 PKT_TYPE = 0x83 |
124 PKT_DESC = "RXIO Packet: 16 bit address" | |
125 | |
9
d147529ad2db
Switch to only reading RX pkts and writing TX pkts to make things simpler.
darius@inchoate.localdomain
parents:
8
diff
changeset
|
126 nsamples = property(lambda s: s._data[s.ADDR_SIZE + 2]) |
5 | 127 |
9
d147529ad2db
Switch to only reading RX pkts and writing TX pkts to make things simpler.
darius@inchoate.localdomain
parents:
8
diff
changeset
|
128 mask = property(lambda s: s._data[s.ADDR_SIZE + 3] << 8 | s._data[s.ADDR_SIZE + 4]) |
4 | 129 |
1 | 130 def __str__(self): |
4 | 131 rtn = "0x%0*x (%ddBm) -> %d samples, mask 0x%04x" % (self.ADDR_SIZE * 2, self.sender, |
132 self.rssi, self.nsamples, self.mask) | |
1 | 133 # Any DIO lines enabled? |
4 | 134 if (self.mask | 0x01ff): |
9
d147529ad2db
Switch to only reading RX pkts and writing TX pkts to make things simpler.
darius@inchoate.localdomain
parents:
8
diff
changeset
|
135 rtn = rtn + ", DIO - 0x%03x" % (self._data[self.ADDR_SIZE + 5] << 8 | |
d147529ad2db
Switch to only reading RX pkts and writing TX pkts to make things simpler.
darius@inchoate.localdomain
parents:
8
diff
changeset
|
136 self._data[self.ADDR_SIZE + 6]) |
4 | 137 offs = self.ADDR_SIZE + 7 |
1 | 138 else: |
4 | 139 offs = self.ADDR_SIZE + 5 |
1 | 140 |
141 # Any ADC lines enabled? | |
4 | 142 if (self.mask | 0x7e00): |
1 | 143 for i in range(6): |
4 | 144 if (self.mask & 1 << (i + 9)): |
9
d147529ad2db
Switch to only reading RX pkts and writing TX pkts to make things simpler.
darius@inchoate.localdomain
parents:
8
diff
changeset
|
145 rtn = rtn + ", ADC%d - 0x%02x" % (i, self._data[offs] << 8 | |
d147529ad2db
Switch to only reading RX pkts and writing TX pkts to make things simpler.
darius@inchoate.localdomain
parents:
8
diff
changeset
|
146 self._data[offs + 1]) |
1 | 147 offs = offs + 2 |
148 return rtn | |
149 | |
5 | 150 class RXIO_64_Bit(RXIO_16_Bit): |
4 | 151 PKT_TYPE = 0x82 |
152 PKT_DESC = "RXIO Packet: 64 bit address" | |
153 ADDR_SIZE = 8 | |
154 | |
9
d147529ad2db
Switch to only reading RX pkts and writing TX pkts to make things simpler.
darius@inchoate.localdomain
parents:
8
diff
changeset
|
155 class TX_16_Bit(TXPkts): |
6 | 156 PKT_TYPE = 0x01 |
4 | 157 PKT_DESC = "TX Packet: 16 bit address" |
6 | 158 ADDR_SIZE = 2 |
9
d147529ad2db
Switch to only reading RX pkts and writing TX pkts to make things simpler.
darius@inchoate.localdomain
parents:
8
diff
changeset
|
159 FLG_DISABLE_ACK = 0x01 |
d147529ad2db
Switch to only reading RX pkts and writing TX pkts to make things simpler.
darius@inchoate.localdomain
parents:
8
diff
changeset
|
160 FLG_BCAST_PANID = 0x04 |
d147529ad2db
Switch to only reading RX pkts and writing TX pkts to make things simpler.
darius@inchoate.localdomain
parents:
8
diff
changeset
|
161 PKT_MAX_PAYLOAD = 100 |
d147529ad2db
Switch to only reading RX pkts and writing TX pkts to make things simpler.
darius@inchoate.localdomain
parents:
8
diff
changeset
|
162 |
6 | 163 def __init__(self, *args): |
164 if (len(args) == 1): | |
9
d147529ad2db
Switch to only reading RX pkts and writing TX pkts to make things simpler.
darius@inchoate.localdomain
parents:
8
diff
changeset
|
165 super(TX_16_Bit, self).__init__() |
d147529ad2db
Switch to only reading RX pkts and writing TX pkts to make things simpler.
darius@inchoate.localdomain
parents:
8
diff
changeset
|
166 self.recipient = args[0] |
6 | 167 elif (len(args) == 2): |
168 super(TX_16_Bit, self).__init__([]) | |
169 self.recipient = args[0] | |
170 self.payload = args[1] | |
171 else: | |
172 raise TypeError("__init__ takes 1 list of ordinals or 2 strings") | |
4 | 173 |
9
d147529ad2db
Switch to only reading RX pkts and writing TX pkts to make things simpler.
darius@inchoate.localdomain
parents:
8
diff
changeset
|
174 self.frameid = 0 |
d147529ad2db
Switch to only reading RX pkts and writing TX pkts to make things simpler.
darius@inchoate.localdomain
parents:
8
diff
changeset
|
175 self.flags = 0 |
d147529ad2db
Switch to only reading RX pkts and writing TX pkts to make things simpler.
darius@inchoate.localdomain
parents:
8
diff
changeset
|
176 self.payload = [] |
d147529ad2db
Switch to only reading RX pkts and writing TX pkts to make things simpler.
darius@inchoate.localdomain
parents:
8
diff
changeset
|
177 |
d147529ad2db
Switch to only reading RX pkts and writing TX pkts to make things simpler.
darius@inchoate.localdomain
parents:
8
diff
changeset
|
178 def setrecipient(self, value): |
d147529ad2db
Switch to only reading RX pkts and writing TX pkts to make things simpler.
darius@inchoate.localdomain
parents:
8
diff
changeset
|
179 if (value < 0 or value > 2 ** (self.ADDR_SIZE * 8)): |
d147529ad2db
Switch to only reading RX pkts and writing TX pkts to make things simpler.
darius@inchoate.localdomain
parents:
8
diff
changeset
|
180 raise ValueError("value out of range must be between 0 and %d" % (2 ** self.ADDR_SIZE)) |
6 | 181 |
9
d147529ad2db
Switch to only reading RX pkts and writing TX pkts to make things simpler.
darius@inchoate.localdomain
parents:
8
diff
changeset
|
182 self._recipient = value |
d147529ad2db
Switch to only reading RX pkts and writing TX pkts to make things simpler.
darius@inchoate.localdomain
parents:
8
diff
changeset
|
183 recipient = property(lambda s: s._recipient, setrecipient) |
d147529ad2db
Switch to only reading RX pkts and writing TX pkts to make things simpler.
darius@inchoate.localdomain
parents:
8
diff
changeset
|
184 |
d147529ad2db
Switch to only reading RX pkts and writing TX pkts to make things simpler.
darius@inchoate.localdomain
parents:
8
diff
changeset
|
185 def setflags(self, value): |
d147529ad2db
Switch to only reading RX pkts and writing TX pkts to make things simpler.
darius@inchoate.localdomain
parents:
8
diff
changeset
|
186 if (value < 0 or value > 255): |
d147529ad2db
Switch to only reading RX pkts and writing TX pkts to make things simpler.
darius@inchoate.localdomain
parents:
8
diff
changeset
|
187 raise ValueError("Value must be between 0 and 255 inclusive") |
d147529ad2db
Switch to only reading RX pkts and writing TX pkts to make things simpler.
darius@inchoate.localdomain
parents:
8
diff
changeset
|
188 |
d147529ad2db
Switch to only reading RX pkts and writing TX pkts to make things simpler.
darius@inchoate.localdomain
parents:
8
diff
changeset
|
189 self._flags = value |
d147529ad2db
Switch to only reading RX pkts and writing TX pkts to make things simpler.
darius@inchoate.localdomain
parents:
8
diff
changeset
|
190 flags = property(lambda s: s._flags, setflags) |
5 | 191 |
6 | 192 def setpayload(self, value): |
9
d147529ad2db
Switch to only reading RX pkts and writing TX pkts to make things simpler.
darius@inchoate.localdomain
parents:
8
diff
changeset
|
193 self._checklist(value, maxlen = self.PKT_MAX_PAYLOAD) |
d147529ad2db
Switch to only reading RX pkts and writing TX pkts to make things simpler.
darius@inchoate.localdomain
parents:
8
diff
changeset
|
194 self._payload = value |
d147529ad2db
Switch to only reading RX pkts and writing TX pkts to make things simpler.
darius@inchoate.localdomain
parents:
8
diff
changeset
|
195 payload = property(lambda s: s._payload, setpayload) |
d147529ad2db
Switch to only reading RX pkts and writing TX pkts to make things simpler.
darius@inchoate.localdomain
parents:
8
diff
changeset
|
196 |
d147529ad2db
Switch to only reading RX pkts and writing TX pkts to make things simpler.
darius@inchoate.localdomain
parents:
8
diff
changeset
|
197 def getdata(self): |
d147529ad2db
Switch to only reading RX pkts and writing TX pkts to make things simpler.
darius@inchoate.localdomain
parents:
8
diff
changeset
|
198 data = [self.frameid] |
d147529ad2db
Switch to only reading RX pkts and writing TX pkts to make things simpler.
darius@inchoate.localdomain
parents:
8
diff
changeset
|
199 for i, j in zip(reversed(range(self.ADDR_SIZE)), range(0, self.ADDR_SIZE * 8, 8)): |
d147529ad2db
Switch to only reading RX pkts and writing TX pkts to make things simpler.
darius@inchoate.localdomain
parents:
8
diff
changeset
|
200 data.append((self.recipient & (0xff << j)) >> j) |
d147529ad2db
Switch to only reading RX pkts and writing TX pkts to make things simpler.
darius@inchoate.localdomain
parents:
8
diff
changeset
|
201 data.append(self.flags) |
d147529ad2db
Switch to only reading RX pkts and writing TX pkts to make things simpler.
darius@inchoate.localdomain
parents:
8
diff
changeset
|
202 data.extend(map(easyord, self.payload)) |
d147529ad2db
Switch to only reading RX pkts and writing TX pkts to make things simpler.
darius@inchoate.localdomain
parents:
8
diff
changeset
|
203 return(data) |
d147529ad2db
Switch to only reading RX pkts and writing TX pkts to make things simpler.
darius@inchoate.localdomain
parents:
8
diff
changeset
|
204 data = property(getdata) |
d147529ad2db
Switch to only reading RX pkts and writing TX pkts to make things simpler.
darius@inchoate.localdomain
parents:
8
diff
changeset
|
205 |
6 | 206 class TX_64_Bit(TX_16_Bit): |
1 | 207 PKT_TYPE = 0x00 |
208 PKT_DESC = "TX Packet: 64 bit address" | |
6 | 209 ADDR_SIZE = 8 |
1 | 210 |
211 class TX_Status(PktBase): | |
212 PKT_TYPE = 0x89 | |
213 PKT_DESC = "TX Status" | |
6 | 214 statusTxt = ['OK', 'No Ack', 'CCA failure', 'Purged'] |
9
d147529ad2db
Switch to only reading RX pkts and writing TX pkts to make things simpler.
darius@inchoate.localdomain
parents:
8
diff
changeset
|
215 frameid = property(lambda s: s._data[0], None) |
d147529ad2db
Switch to only reading RX pkts and writing TX pkts to make things simpler.
darius@inchoate.localdomain
parents:
8
diff
changeset
|
216 status = property(lambda s: s._data[1], None) |
d147529ad2db
Switch to only reading RX pkts and writing TX pkts to make things simpler.
darius@inchoate.localdomain
parents:
8
diff
changeset
|
217 statusMsg = property(lambda s: s.statusTxt[s._data[1]], None) |
6 | 218 |
1 | 219 class Packets(object): |
4 | 220 PKT_CLASSES = None |
1 | 221 |
4 | 222 def Build(self, data): |
223 if (self.PKT_CLASSES == None): | |
224 m = inspect.getmodule(self) | |
225 # Generate list of objects from their names | |
226 mobjs = map(lambda n: m.__dict__[n], m.__dict__) | |
227 # Find all the classes | |
228 pktclasses = filter(inspect.isclass, mobjs) | |
229 # Find all subclasses of PktBase (but not PktBase itself) | |
230 pktclasses = filter(lambda s: issubclass(s, m.PktBase) and s != m.PktBase, pktclasses) | |
231 self.PKT_CLASSES = pktclasses | |
232 | |
233 for p in self.PKT_CLASSES: | |
1 | 234 if (p.PKT_TYPE == data[0]): |
235 return(p(data[1:])) | |
4 | 236 |
237 raise ValueError("Unknown packet type 0x%02x" % (data[0])) | |
238 Build = classmethod(Build) | |
1 | 239 |
240 def Encapsulate(data): | |
241 pktsum = reduce(lambda x, y: x + y, data) & 0xff | |
242 pkt = [0x7e] + [len(data) >> 8] + [len(data) & 0xff] + data + [0xff - pktsum] | |
243 return(map(chr, pkt)) | |
244 | |
245 Encapsulate = staticmethod(Encapsulate) | |
246 | |
6 | 247 def __init__(self, s): |
4 | 248 print str(inspect.getmodule(self)) |
1 | 249 self.buffer = [] |
250 self.state = 'init' | |
251 self.packets = [] | |
252 | |
253 self.bufmsb = 0 | |
9
d147529ad2db
Switch to only reading RX pkts and writing TX pkts to make things simpler.
darius@inchoate.localdomain
parents:
8
diff
changeset
|
254 self._dataleft = 0 |
1 | 255 |
256 self.fr_err = 0 # Framing error | |
257 self.ck_err = 0 # Checksum error | |
258 self.rx_cnt = 0 # Packet count | |
259 | |
260 self.pktq = [] | |
6 | 261 self.s = s |
262 | |
263 def writedata(self, data): | |
264 self.s.write("".join(map(str, data))) | |
5 | 265 |
6 | 266 def getdata(self): |
1 | 267 l = [] |
268 while (1): | |
6 | 269 a = self.s.read() |
1 | 270 if (a == ''): |
271 break | |
5 | 272 l.append(ord(a)) |
1 | 273 |
274 return self.process(l) | |
275 | |
276 def process(self, data): | |
277 pktcount = 0 | |
278 for d in data: | |
279 if (self.state == 'init'): | |
5 | 280 if (d != 0x7e): |
281 print "Framing error, got 0x%02x, expected 0x7e" % (d) | |
4 | 282 self.fr_err += 1 |
1 | 283 continue |
284 | |
285 self.state = 'sizemsb' | |
286 elif (self.state == 'sizemsb'): | |
5 | 287 self.bufmsb = d |
1 | 288 self.state = 'sizelsb' |
289 elif (self.state == 'sizelsb'): | |
7
579dedf5a1f1
Rejoin line break, left over from removal of struct.
darius@inchoate.localdomain
parents:
6
diff
changeset
|
290 self.dataleft = self.bufmsb << 8 | d |
1 | 291 self.state = 'data' |
292 elif (self.state == 'data'): | |
5 | 293 self.buffer.append(d) |
1 | 294 self.dataleft = self.dataleft - 1 |
295 if (self.dataleft == 0): | |
296 self.state = 'cksum' | |
297 elif (self.state == 'cksum'): | |
298 pktsum = reduce(lambda x, y: x + y, self.buffer) & 0xff | |
5 | 299 rxcksum = d |
1 | 300 self.state = 'init' |
301 if (pktsum + rxcksum != 0xff): | |
302 self.buffer = [] | |
4 | 303 self.ck_err += 1 |
1 | 304 print "Checksum error, got 0x%02x, expected 0x%02x" % \ |
305 (rxcksum, 0xff - pktsum) | |
306 else: | |
6 | 307 print "Got a packet - " + str(self.buffer) |
1 | 308 p = Packets.Build(self.buffer) |
309 self.pktq.append(p) | |
310 self.buffer = [] | |
4 | 311 pktcount += 1 |
312 self.rx_cnt += 1 | |
1 | 313 else: |
314 print "Invalid state %s! Resetting" % (self.state) | |
315 self.state = 'init' | |
316 | |
317 return pktcount | |
318 | |
319 #for c in dir(): | |
320 # if (issubclass(c, PktBase)): | |
321 # print .. | |
0
bdcdd8380d94
Some test routines & framework for talking to MaxStream ZigBee modules.
darius@inchoate.localdomain
parents:
diff
changeset
|
322 |
bdcdd8380d94
Some test routines & framework for talking to MaxStream ZigBee modules.
darius@inchoate.localdomain
parents:
diff
changeset
|
323 s = serial.Serial(port='/dev/cuad0', baudrate=9600, bytesize=8, parity='N', \ |
bdcdd8380d94
Some test routines & framework for talking to MaxStream ZigBee modules.
darius@inchoate.localdomain
parents:
diff
changeset
|
324 stopbits=1, rtscts=0) |
8
9f0808b13454
Use non-blocking serial access. Add __str__ method for RX packets.
darius@inchoate.localdomain
parents:
7
diff
changeset
|
325 # Non-blocking |
9f0808b13454
Use non-blocking serial access. Add __str__ method for RX packets.
darius@inchoate.localdomain
parents:
7
diff
changeset
|
326 s.timeout = 0 |
0
bdcdd8380d94
Some test routines & framework for talking to MaxStream ZigBee modules.
darius@inchoate.localdomain
parents:
diff
changeset
|
327 #s.write('+++') |
bdcdd8380d94
Some test routines & framework for talking to MaxStream ZigBee modules.
darius@inchoate.localdomain
parents:
diff
changeset
|
328 #s.readline(eol='\r') |
bdcdd8380d94
Some test routines & framework for talking to MaxStream ZigBee modules.
darius@inchoate.localdomain
parents:
diff
changeset
|
329 |
4 | 330 |
331 # 0x0001 (-36dBm) -> 1 samples, mask 0x000f, DIO - 0x00f | |
5 | 332 goodtest = [126, 0, 10, 131, 0, 1, 36, 0, 1, 0, 15, 0, 15, 56] |
4 | 333 |
334 # Checksum error | |
5 | 335 badtest = [126, 0, 10, 131, 0, 1, 36, 0, 1, 0, 15, 0, 14, 56] |
4 | 336 |
337 #0x0005 (-36dBm) -> 1 samples, mask 0x020e, DIO - 0x00e, ADC0 - 0x3ff | |
5 | 338 adctest = [126, 0, 12, 131, 0, 5, 36, 0, 1, 2, 14, 0, 14, 3, 255, 50] |
4 | 339 |
340 # Exception | |
5 | 341 badpkttypetest = [126, 0, 3, 10, 86, 76, 83] |
4 | 342 |
9
d147529ad2db
Switch to only reading RX pkts and writing TX pkts to make things simpler.
darius@inchoate.localdomain
parents:
8
diff
changeset
|
343 # Frame ID = 0, Cmd = 'VL', Status = OK, Value = 'VL Result' |
d147529ad2db
Switch to only reading RX pkts and writing TX pkts to make things simpler.
darius@inchoate.localdomain
parents:
8
diff
changeset
|
344 atreply = [126, 0, 14, 136, 0, 86, 76, 0, 86, 76, 32, 82, 101, 115, 117, 108, 116, 148] |
d147529ad2db
Switch to only reading RX pkts and writing TX pkts to make things simpler.
darius@inchoate.localdomain
parents:
8
diff
changeset
|
345 |
6 | 346 up = Packets(s) |
1 | 347 up.process(goodtest) |
3
7bf4d4265339
Pop off the packets we test with.
darius@inchoate.localdomain
parents:
1
diff
changeset
|
348 up.process(badtest) |
7bf4d4265339
Pop off the packets we test with.
darius@inchoate.localdomain
parents:
1
diff
changeset
|
349 up.process(adctest) |
7bf4d4265339
Pop off the packets we test with.
darius@inchoate.localdomain
parents:
1
diff
changeset
|
350 print up.pktq.pop(0) |
7bf4d4265339
Pop off the packets we test with.
darius@inchoate.localdomain
parents:
1
diff
changeset
|
351 print up.pktq.pop(0) |
0
bdcdd8380d94
Some test routines & framework for talking to MaxStream ZigBee modules.
darius@inchoate.localdomain
parents:
diff
changeset
|
352 |