comparison zb.py @ 6:9c499d923544

Many fixes. - Make AT_Cmd constructor smarter/useful. - Flesh out AT_Response, TX_*_Bit and TX_Status - Make writedata() and getdata() simpler to use (hold reference to serial port inside the class)
author darius@inchoate.localdomain
date Thu, 01 Nov 2007 16:30:36 +1030
parents 5d5963d542bc
children 579dedf5a1f1
comparison
equal deleted inserted replaced
5:5d5963d542bc 6:9c499d923544
20 PKT_TYPE = 0x08 20 PKT_TYPE = 0x08
21 PKT_DESC = "AT Command" 21 PKT_DESC = "AT Command"
22 22
23 def __init__(self, *args): 23 def __init__(self, *args):
24 if (len(args) == 1): 24 if (len(args) == 1):
25 super(AT_Cmd, self).__init__(args[0]) 25 if (type(args[0]) == type(str())):
26 super(AT_Cmd, self).__init__([])
27 self.cmd = args[0]
28 else:
29 super(AT_Cmd, self).__init__(args[0])
26 elif (len(args) == 2): 30 elif (len(args) == 2):
27 super(AT_Cmd, self).__init__([]) 31 super(AT_Cmd, self).__init__([])
28 self.cmd = args[0] 32 self.cmd = args[0]
29 if (args[1] != None): 33 self.cmdarg = args[1]
30 self.cmdarg = args[1]
31 else: 34 else:
32 raise TypeError("__init__ takes 1 list of ordinals or 2 strings") 35 raise TypeError("__init__ takes 1 list of ordinals, 1 string, or 2 strings")
36
37 self.data[0] = 1 # XXX: could be smarter about Frame ID
33 38
34 def setcmd(self, value): 39 def setcmd(self, value):
35 self.resize(2) 40 self.resize(3)
36 self.data[0] = ord(value[0]) 41 self.data[1] = ord(value[0])
37 self.data[1] = ord(value[1]) 42 self.data[2] = ord(value[1])
38 cmd = property(lambda s: chr(s.data[0]) + chr(s.data[1]), setcmd) 43 cmd = property(lambda s: chr(s.data[1]) + chr(s.data[2]), setcmd)
39 44
40 def setcmdarg(self, value): 45 def setcmdarg(self, value):
41 self.resize(2 + len(value)) 46 self.resize(3 + len(value))
42 self.data = self.data[0:2] + map(ord, value) 47 self.data = self.data[0:3] + map(ord, value)
43 def delcmdarg(self): 48 def delcmdarg(self):
44 self.data = self.data[0:2] 49 self.data = self.data[0:3]
45 cmdarg = property(lambda s: map(chr, s.data[2:]), setcmdarg, delcmdarg) 50 cmdarg = property(lambda s: map(chr, s.data[3:]), setcmdarg, delcmdarg)
46 51
47 class AT_Cmd_Queue(AT_Cmd): 52 class AT_Cmd_Queue(AT_Cmd):
48 PKT_TYPE = 0x09 53 PKT_TYPE = 0x09
49 PKT_DESC = "AT Command (queued)" 54 PKT_DESC = "AT Command (queued)"
50 55
51 class AT_Response(PktBase): 56 class AT_Response(PktBase):
52 PKT_TYPE = 0x88 57 PKT_TYPE = 0x88
53 PKT_DESC = "AT Command response" 58 PKT_DESC = "AT Command response"
59 frameid = property(lambda s: s.data[0], None)
60 cmd = property(lambda s: chr(s.data[1]) + chr(s.data[2]), None)
61 statusOK = property(lambda s: s.data[3] == 0, None)
62 payload = property(lambda s: s.data[4:], None)
54 63
55 class Modem_Status(PktBase): 64 class Modem_Status(PktBase):
56 PKT_TYPE = 0x8a 65 PKT_TYPE = 0x8a
57 PKT_DESC = "Modem Status" 66 PKT_DESC = "Modem Status"
58 67
122 PKT_TYPE = 0x82 131 PKT_TYPE = 0x82
123 PKT_DESC = "RXIO Packet: 64 bit address" 132 PKT_DESC = "RXIO Packet: 64 bit address"
124 ADDR_SIZE = 8 133 ADDR_SIZE = 8
125 134
126 class TX_16_Bit(RX_64_Bit): 135 class TX_16_Bit(RX_64_Bit):
127 PKT_TYPE = 0x00 136 PKT_TYPE = 0x01
128 PKT_DESC = "TX Packet: 16 bit address" 137 PKT_DESC = "TX Packet: 16 bit address"
129 138 ADDR_SIZE = 2
130 def setsender(self, value): 139
131 self.resize(self.ADDR_SIZE) 140 def __init__(self, *args):
141 if (len(args) == 1):
142 if (type(args[0]) == type(int())):
143 super(TX_16_Bit, self).__init__([])
144 self.recipient = args[0]
145 else:
146 super(TX_16_Bit, self).__init__(args[0])
147 elif (len(args) == 2):
148 super(TX_16_Bit, self).__init__([])
149 self.recipient = args[0]
150 self.payload = args[1]
151 else:
152 raise TypeError("__init__ takes 1 list of ordinals or 2 strings")
153
154 self.resize(self.ADDR_SIZE + 2)
155 self.data[0] = 1 # XXX: could be smarter about Frame ID
156 self.data[3] = 0 # XXX: should be able to set flags
157
158 def getrecipient(self):
159 value = 0
132 for i, j in zip(reversed(range(self.ADDR_SIZE)), range(0, self.ADDR_SIZE * 8, 8)): 160 for i, j in zip(reversed(range(self.ADDR_SIZE)), range(0, self.ADDR_SIZE * 8, 8)):
133 self.data[i] = (value & (0xff << j)) >> j 161 value |= self.data[i + 1] << j
134 sender = property(RX_64_Bit.getsender, setsender) 162 return value
135 163
136 class TX_64_Bit(RX_64_Bit): 164 def setrecipient(self, value):
165 self.resize(self.ADDR_SIZE + 1)
166 self.data[0] = 1 # XXX: could be smarter about Frame ID
167 for i, j in zip(reversed(range(self.ADDR_SIZE)), range(0, self.ADDR_SIZE * 8, 8)):
168 self.data[i + 1] = (value & (0xff << j)) >> j
169 recipient = property(getrecipient, setrecipient)
170
171 def setpayload(self, value):
172 self.resize(self.ADDR_SIZE + 2)
173 self.data[self.ADDR_SIZE + 2:] = value
174 payload = property(lambda s: s.data[self.ADDR_SIZE + 2:], setpayload)
175
176 class TX_64_Bit(TX_16_Bit):
137 PKT_TYPE = 0x00 177 PKT_TYPE = 0x00
138 PKT_DESC = "TX Packet: 64 bit address" 178 PKT_DESC = "TX Packet: 64 bit address"
179 ADDR_SIZE = 8
139 180
140 class TX_Status(PktBase): 181 class TX_Status(PktBase):
141 PKT_TYPE = 0x89 182 PKT_TYPE = 0x89
142 PKT_DESC = "TX Status" 183 PKT_DESC = "TX Status"
143 184 statusTxt = ['OK', 'No Ack', 'CCA failure', 'Purged']
185 frameid = property(lambda s: s.data[0], None)
186 status = property(lambda s: s.data[1], None)
187 statusMsg = property(lambda s: s.statusTxt[s.data[1]], None)
188
144 class Packets(object): 189 class Packets(object):
145 PKT_CLASSES = None 190 PKT_CLASSES = None
146 191
147 def Build(self, data): 192 def Build(self, data):
148 if (self.PKT_CLASSES == None): 193 if (self.PKT_CLASSES == None):
167 pkt = [0x7e] + [len(data) >> 8] + [len(data) & 0xff] + data + [0xff - pktsum] 212 pkt = [0x7e] + [len(data) >> 8] + [len(data) & 0xff] + data + [0xff - pktsum]
168 return(map(chr, pkt)) 213 return(map(chr, pkt))
169 214
170 Encapsulate = staticmethod(Encapsulate) 215 Encapsulate = staticmethod(Encapsulate)
171 216
172 def __init__(self): 217 def __init__(self, s):
173 print str(inspect.getmodule(self)) 218 print str(inspect.getmodule(self))
174 self.buffer = [] 219 self.buffer = []
175 self.state = 'init' 220 self.state = 'init'
176 self.packets = [] 221 self.packets = []
177 222
181 self.fr_err = 0 # Framing error 226 self.fr_err = 0 # Framing error
182 self.ck_err = 0 # Checksum error 227 self.ck_err = 0 # Checksum error
183 self.rx_cnt = 0 # Packet count 228 self.rx_cnt = 0 # Packet count
184 229
185 self.pktq = [] 230 self.pktq = []
186 231 self.s = s
187 def writedata(self, s, data): 232
188 s.write("".join(map(str, data))) 233 def writedata(self, data):
234 self.s.write("".join(map(str, data)))
189 235
190 def getdata(self, s): 236 def getdata(self):
191 l = [] 237 l = []
192 while (1): 238 while (1):
193 a = s.read() 239 a = self.s.read()
194 if (a == ''): 240 if (a == ''):
195 break 241 break
196 l.append(ord(a)) 242 l.append(ord(a))
197 243
198 return self.process(l) 244 return self.process(l)
227 self.buffer = [] 273 self.buffer = []
228 self.ck_err += 1 274 self.ck_err += 1
229 print "Checksum error, got 0x%02x, expected 0x%02x" % \ 275 print "Checksum error, got 0x%02x, expected 0x%02x" % \
230 (rxcksum, 0xff - pktsum) 276 (rxcksum, 0xff - pktsum)
231 else: 277 else:
232 #print "Got a packet - " + str(self.buffer) 278 print "Got a packet - " + str(self.buffer)
233 p = Packets.Build(self.buffer) 279 p = Packets.Build(self.buffer)
234 self.pktq.append(p) 280 self.pktq.append(p)
235 self.buffer = [] 281 self.buffer = []
236 pktcount += 1 282 pktcount += 1
237 self.rx_cnt += 1 283 self.rx_cnt += 1
262 adctest = [126, 0, 12, 131, 0, 5, 36, 0, 1, 2, 14, 0, 14, 3, 255, 50] 308 adctest = [126, 0, 12, 131, 0, 5, 36, 0, 1, 2, 14, 0, 14, 3, 255, 50]
263 309
264 # Exception 310 # Exception
265 badpkttypetest = [126, 0, 3, 10, 86, 76, 83] 311 badpkttypetest = [126, 0, 3, 10, 86, 76, 83]
266 312
267 up = Packets() 313 up = Packets(s)
268 up.process(goodtest) 314 up.process(goodtest)
269 up.process(badtest) 315 up.process(badtest)
270 up.process(adctest) 316 up.process(adctest)
271 print up.pktq.pop(0) 317 print up.pktq.pop(0)
272 print up.pktq.pop(0) 318 print up.pktq.pop(0)