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