annotate zb.py @ 15:a472d6eab97e

Play back the last 5 lines to newly connected clients rather than 1.
author darius@Inchoate
date Sat, 17 Jan 2009 21:43:59 +1030
parents 729f2393f296
children c6ee9eae9e49
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
11
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
1 #
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
2 # Code to talk to MaxStream ZigBee modules in API (no escaped
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
3 # characters)
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
4 #
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
5 # Copyright (c) 2009
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
6 # Daniel O'Connor <darius@dons.net.au>. All rights reserved.
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
7 #
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
8 # Redistribution and use in source and binary forms, with or without
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
9 # modification, are permitted provided that the following conditions
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
10 # are met:
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
11 # 1. Redistributions of source code must retain the above copyright
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
12 # notice, this list of conditions and the following disclaimer.
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
13 # 2. Redistributions in binary form must reproduce the above copyright
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
14 # notice, this list of conditions and the following disclaimer in the
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
15 # documentation and/or other materials provided with the distribution.
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
16 #
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
17 # THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
18 # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
19 # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
20 # ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
21 # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
22 # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
23 # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
24 # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
25 # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
26 # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
27 # SUCH DAMAGE.
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
28 #
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
29 """MaxStream ZigBee module API interface
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
30
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
31 This code expects the module to be in API mode 1 (no escape
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
32 characters), ie you have done something like..
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
33 +++
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
34 ATAP=1
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
35 ATWR
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
36 ATCN
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
37
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
38 See here for details
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
39 http://www.digi.com/products/wireless/point-multipoint/xbee-series1-moduledocs.jsp
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
40 """
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
41
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
42 import inspect
1
b5d8ec0ffd21 Lots of changes..
darius@inchoate.localdomain
parents: 0
diff changeset
43
9
d147529ad2db Switch to only reading RX pkts and writing TX pkts to make things simpler.
darius@inchoate.localdomain
parents: 8
diff changeset
44 def easyord(i):
11
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
45 """Helper function to return the ordinal of a string, or just the
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
46 passed in value"""
9
d147529ad2db Switch to only reading RX pkts and writing TX pkts to make things simpler.
darius@inchoate.localdomain
parents: 8
diff changeset
47 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
48 return i
d147529ad2db Switch to only reading RX pkts and writing TX pkts to make things simpler.
darius@inchoate.localdomain
parents: 8
diff changeset
49 else:
d147529ad2db Switch to only reading RX pkts and writing TX pkts to make things simpler.
darius@inchoate.localdomain
parents: 8
diff changeset
50 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
51
1
b5d8ec0ffd21 Lots of changes..
darius@inchoate.localdomain
parents: 0
diff changeset
52 class PktBase(object):
11
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
53 """Base class for all packet types"""
9
d147529ad2db Switch to only reading RX pkts and writing TX pkts to make things simpler.
darius@inchoate.localdomain
parents: 8
diff changeset
54 PKT_MAXLEN = 2 ** 16
11
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
55 PKT_TYPE = None
9
d147529ad2db Switch to only reading RX pkts and writing TX pkts to make things simpler.
darius@inchoate.localdomain
parents: 8
diff changeset
56
10
4c91fdfc862e - Further changes to make things cleaner (ie RX packets are "read only" etc).
darius@inchoate.localdomain
parents: 9
diff changeset
57 def __init__(self):
11
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
58 #print "Constructing " + self.__class__.__name__
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
59 pass
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
60
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
61 def Encapsulate(self):
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
62 """Encapsulate the packet"""
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
63 return Packets.Encapsulate([self.PKT_TYPE] + self.data)
1
b5d8ec0ffd21 Lots of changes..
darius@inchoate.localdomain
parents: 0
diff changeset
64
11
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
65 def Pack(self):
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
66 """Return string version of encapsulated packet"""
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
67 return reduce(lambda x, y: str(x) + str(y), self.Encapsulate())
1
b5d8ec0ffd21 Lots of changes..
darius@inchoate.localdomain
parents: 0
diff changeset
68
4
ed7abe6f59c2 Many fixes (again)
darius@inchoate.localdomain
parents: 3
diff changeset
69 def resize(self, dlen):
ed7abe6f59c2 Many fixes (again)
darius@inchoate.localdomain
parents: 3
diff changeset
70 """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
71 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
72 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
73
11
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
74 @staticmethod
9
d147529ad2db Switch to only reading RX pkts and writing TX pkts to make things simpler.
darius@inchoate.localdomain
parents: 8
diff changeset
75 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
76 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
77 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
78
d147529ad2db Switch to only reading RX pkts and writing TX pkts to make things simpler.
darius@inchoate.localdomain
parents: 8
diff changeset
79 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
80 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
81 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
82 (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
83
d147529ad2db Switch to only reading RX pkts and writing TX pkts to make things simpler.
darius@inchoate.localdomain
parents: 8
diff changeset
84 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
85 """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
86
13
729f2393f296 Auto increment frame ID when creating a TX packet.
darius@Inchoate
parents: 11
diff changeset
87 frameidcounter = 0
729f2393f296 Auto increment frame ID when creating a TX packet.
darius@Inchoate
parents: 11
diff changeset
88
11
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
89 def __init__(self):
13
729f2393f296 Auto increment frame ID when creating a TX packet.
darius@Inchoate
parents: 11
diff changeset
90 self._frameid = self.getNextFrameId()
729f2393f296 Auto increment frame ID when creating a TX packet.
darius@Inchoate
parents: 11
diff changeset
91
729f2393f296 Auto increment frame ID when creating a TX packet.
darius@Inchoate
parents: 11
diff changeset
92 @classmethod
729f2393f296 Auto increment frame ID when creating a TX packet.
darius@Inchoate
parents: 11
diff changeset
93 def getNextFrameId(clss):
729f2393f296 Auto increment frame ID when creating a TX packet.
darius@Inchoate
parents: 11
diff changeset
94 """Generate the next frame ID, skip 0 as it will cause the module to not send a response back"""
729f2393f296 Auto increment frame ID when creating a TX packet.
darius@Inchoate
parents: 11
diff changeset
95 clss.frameidcounter = (clss.frameidcounter + 1) % 255
729f2393f296 Auto increment frame ID when creating a TX packet.
darius@Inchoate
parents: 11
diff changeset
96
729f2393f296 Auto increment frame ID when creating a TX packet.
darius@Inchoate
parents: 11
diff changeset
97 if clss.frameidcounter == 0:
729f2393f296 Auto increment frame ID when creating a TX packet.
darius@Inchoate
parents: 11
diff changeset
98 clss.frameidcounter = 1
729f2393f296 Auto increment frame ID when creating a TX packet.
darius@Inchoate
parents: 11
diff changeset
99
729f2393f296 Auto increment frame ID when creating a TX packet.
darius@Inchoate
parents: 11
diff changeset
100 return clss.frameidcounter
729f2393f296 Auto increment frame ID when creating a TX packet.
darius@Inchoate
parents: 11
diff changeset
101
9
d147529ad2db Switch to only reading RX pkts and writing TX pkts to make things simpler.
darius@inchoate.localdomain
parents: 8
diff changeset
102 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
103 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
104 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
105 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
106 frameid = property(lambda s: s._frameid, setframeid)
4
ed7abe6f59c2 Many fixes (again)
darius@inchoate.localdomain
parents: 3
diff changeset
107
11
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
108 class AT_Cmd(TXPkts):
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
109 """AT command packet"""
9
d147529ad2db Switch to only reading RX pkts and writing TX pkts to make things simpler.
darius@inchoate.localdomain
parents: 8
diff changeset
110
1
b5d8ec0ffd21 Lots of changes..
darius@inchoate.localdomain
parents: 0
diff changeset
111 PKT_TYPE = 0x08
b5d8ec0ffd21 Lots of changes..
darius@inchoate.localdomain
parents: 0
diff changeset
112 PKT_DESC = "AT Command"
b5d8ec0ffd21 Lots of changes..
darius@inchoate.localdomain
parents: 0
diff changeset
113
10
4c91fdfc862e - Further changes to make things cleaner (ie RX packets are "read only" etc).
darius@inchoate.localdomain
parents: 9
diff changeset
114 def __init__(self, cmd = None, cmdarg = None):
11
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
115 self.frameid = 1 # XXX: why do I need to dupe this?
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
116 self.cmdarg = []
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
117
10
4c91fdfc862e - Further changes to make things cleaner (ie RX packets are "read only" etc).
darius@inchoate.localdomain
parents: 9
diff changeset
118 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
119 if (cmd != None):
4c91fdfc862e - Further changes to make things cleaner (ie RX packets are "read only" etc).
darius@inchoate.localdomain
parents: 9
diff changeset
120 self.cmd = cmd
4c91fdfc862e - Further changes to make things cleaner (ie RX packets are "read only" etc).
darius@inchoate.localdomain
parents: 9
diff changeset
121 if (cmdarg != None):
4c91fdfc862e - Further changes to make things cleaner (ie RX packets are "read only" etc).
darius@inchoate.localdomain
parents: 9
diff changeset
122 self.cmdarg = cmdarg
9
d147529ad2db Switch to only reading RX pkts and writing TX pkts to make things simpler.
darius@inchoate.localdomain
parents: 8
diff changeset
123
4
ed7abe6f59c2 Many fixes (again)
darius@inchoate.localdomain
parents: 3
diff changeset
124 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
125 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
126 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
127 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
128 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
129 cmd = property(lambda s: s._cmd, setcmd)
4
ed7abe6f59c2 Many fixes (again)
darius@inchoate.localdomain
parents: 3
diff changeset
130
ed7abe6f59c2 Many fixes (again)
darius@inchoate.localdomain
parents: 3
diff changeset
131 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
132 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
133 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
134 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
135
d147529ad2db Switch to only reading RX pkts and writing TX pkts to make things simpler.
darius@inchoate.localdomain
parents: 8
diff changeset
136 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
137 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
138 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
139
4
ed7abe6f59c2 Many fixes (again)
darius@inchoate.localdomain
parents: 3
diff changeset
140 class AT_Cmd_Queue(AT_Cmd):
11
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
141 """Queued AT command packet"""
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
142
1
b5d8ec0ffd21 Lots of changes..
darius@inchoate.localdomain
parents: 0
diff changeset
143 PKT_TYPE = 0x09
b5d8ec0ffd21 Lots of changes..
darius@inchoate.localdomain
parents: 0
diff changeset
144 PKT_DESC = "AT Command (queued)"
b5d8ec0ffd21 Lots of changes..
darius@inchoate.localdomain
parents: 0
diff changeset
145
b5d8ec0ffd21 Lots of changes..
darius@inchoate.localdomain
parents: 0
diff changeset
146 class AT_Response(PktBase):
11
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
147 """Response from an AT command packet"""
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
148
1
b5d8ec0ffd21 Lots of changes..
darius@inchoate.localdomain
parents: 0
diff changeset
149 PKT_TYPE = 0x88
b5d8ec0ffd21 Lots of changes..
darius@inchoate.localdomain
parents: 0
diff changeset
150 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
151 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
152 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
153 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
154 payload = property(lambda s: s._data[4:], None)
1
b5d8ec0ffd21 Lots of changes..
darius@inchoate.localdomain
parents: 0
diff changeset
155
11
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
156 def __init__(self, data = []):
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
157 super(AT_Response, self).__init__()
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
158 self._data = data
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
159
1
b5d8ec0ffd21 Lots of changes..
darius@inchoate.localdomain
parents: 0
diff changeset
160 class Modem_Status(PktBase):
b5d8ec0ffd21 Lots of changes..
darius@inchoate.localdomain
parents: 0
diff changeset
161 PKT_TYPE = 0x8a
b5d8ec0ffd21 Lots of changes..
darius@inchoate.localdomain
parents: 0
diff changeset
162 PKT_DESC = "Modem Status"
b5d8ec0ffd21 Lots of changes..
darius@inchoate.localdomain
parents: 0
diff changeset
163
b5d8ec0ffd21 Lots of changes..
darius@inchoate.localdomain
parents: 0
diff changeset
164 class RX_16_Bit(PktBase):
11
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
165 """RX packet from a remote module (16 bit)"""
1
b5d8ec0ffd21 Lots of changes..
darius@inchoate.localdomain
parents: 0
diff changeset
166 PKT_TYPE = 0x81
b5d8ec0ffd21 Lots of changes..
darius@inchoate.localdomain
parents: 0
diff changeset
167 PKT_DESC = "RX Packet: 16 bit address"
4
ed7abe6f59c2 Many fixes (again)
darius@inchoate.localdomain
parents: 3
diff changeset
168 ADDR_SIZE = 2
11
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
169 ADRBCASTMSK = 0x01
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
170 PANBCASTMSK = 0x02
4
ed7abe6f59c2 Many fixes (again)
darius@inchoate.localdomain
parents: 3
diff changeset
171
10
4c91fdfc862e - Further changes to make things cleaner (ie RX packets are "read only" etc).
darius@inchoate.localdomain
parents: 9
diff changeset
172 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
173 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
174 self._data = data
11
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
175
8
9f0808b13454 Use non-blocking serial access. Add __str__ method for RX packets.
darius@inchoate.localdomain
parents: 7
diff changeset
176 def __str__(self):
11
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
177 return "RX_%d_Bit 0x%0*x (%ddBm) -> %s" % (self.ADDR_SIZE * 8, self.ADDR_SIZE * 2,
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
178 self.sender, self.rssi, self.payloadstr)
4
ed7abe6f59c2 Many fixes (again)
darius@inchoate.localdomain
parents: 3
diff changeset
179 def getsender(self):
ed7abe6f59c2 Many fixes (again)
darius@inchoate.localdomain
parents: 3
diff changeset
180 value = 0
11
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
181 # Done this way so we can reuse the code for the 64 bit version
4
ed7abe6f59c2 Many fixes (again)
darius@inchoate.localdomain
parents: 3
diff changeset
182 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
183 value |= self._data[i] << j
4
ed7abe6f59c2 Many fixes (again)
darius@inchoate.localdomain
parents: 3
diff changeset
184 return value
11
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
185 #: Source module address
5
5d5963d542bc More tidyups & fixes.
darius@inchoate.localdomain
parents: 4
diff changeset
186 sender = property(getsender, None)
5d5963d542bc More tidyups & fixes.
darius@inchoate.localdomain
parents: 4
diff changeset
187
11
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
188 def isAdrBcast(self):
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
189 """Is this an address broadcast packet?"""
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
190 return self.flags & self.ADRBCASTMSK
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
191
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
192 def isPanBcast(self):
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
193 """Is this an PAN broadcast packet?"""
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
194 return self.flags & self.PANBCASTMSK
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
195
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
196 #: RX signal strength (dBm)
9
d147529ad2db Switch to only reading RX pkts and writing TX pkts to make things simpler.
darius@inchoate.localdomain
parents: 8
diff changeset
197 rssi = property(lambda s: -1 * s._data[s.ADDR_SIZE], None)
1
b5d8ec0ffd21 Lots of changes..
darius@inchoate.localdomain
parents: 0
diff changeset
198
11
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
199 #: Return flag byte
9
d147529ad2db Switch to only reading RX pkts and writing TX pkts to make things simpler.
darius@inchoate.localdomain
parents: 8
diff changeset
200 flags = property(lambda s: s._data[s.ADDR_SIZE + 1], None)
4
ed7abe6f59c2 Many fixes (again)
darius@inchoate.localdomain
parents: 3
diff changeset
201
11
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
202 #: Payload (list of ords)
9
d147529ad2db Switch to only reading RX pkts and writing TX pkts to make things simpler.
darius@inchoate.localdomain
parents: 8
diff changeset
203 payload = property(lambda s: s._data[s.ADDR_SIZE + 2:], None)
11
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
204
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
205 #: String version of payload
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
206 def payloadstr(self):
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
207 return reduce(lambda a, b: a + chr(b), self.payload, "")
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
208 payloadstr = property(payloadstr, None)
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
209
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
210
4
ed7abe6f59c2 Many fixes (again)
darius@inchoate.localdomain
parents: 3
diff changeset
211 class RX_64_Bit(RX_16_Bit):
ed7abe6f59c2 Many fixes (again)
darius@inchoate.localdomain
parents: 3
diff changeset
212 PKT_TYPE = 0x80
ed7abe6f59c2 Many fixes (again)
darius@inchoate.localdomain
parents: 3
diff changeset
213 PKT_DESC = "RX Packet: 64 bit address"
ed7abe6f59c2 Many fixes (again)
darius@inchoate.localdomain
parents: 3
diff changeset
214 ADDR_SIZE = 8
ed7abe6f59c2 Many fixes (again)
darius@inchoate.localdomain
parents: 3
diff changeset
215
ed7abe6f59c2 Many fixes (again)
darius@inchoate.localdomain
parents: 3
diff changeset
216 class RXIO_16_Bit(RX_16_Bit):
11
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
217 """RX I/O packet from remote module (16 bit).
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
218
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
219 This is sent when a remote module is configured to send data based on its IO or DAC pins
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
220 """
1
b5d8ec0ffd21 Lots of changes..
darius@inchoate.localdomain
parents: 0
diff changeset
221 PKT_TYPE = 0x83
b5d8ec0ffd21 Lots of changes..
darius@inchoate.localdomain
parents: 0
diff changeset
222 PKT_DESC = "RXIO Packet: 16 bit address"
b5d8ec0ffd21 Lots of changes..
darius@inchoate.localdomain
parents: 0
diff changeset
223
9
d147529ad2db Switch to only reading RX pkts and writing TX pkts to make things simpler.
darius@inchoate.localdomain
parents: 8
diff changeset
224 nsamples = property(lambda s: s._data[s.ADDR_SIZE + 2])
5
5d5963d542bc More tidyups & fixes.
darius@inchoate.localdomain
parents: 4
diff changeset
225
9
d147529ad2db Switch to only reading RX pkts and writing TX pkts to make things simpler.
darius@inchoate.localdomain
parents: 8
diff changeset
226 mask = property(lambda s: s._data[s.ADDR_SIZE + 3] << 8 | s._data[s.ADDR_SIZE + 4])
4
ed7abe6f59c2 Many fixes (again)
darius@inchoate.localdomain
parents: 3
diff changeset
227
1
b5d8ec0ffd21 Lots of changes..
darius@inchoate.localdomain
parents: 0
diff changeset
228 def __str__(self):
4
ed7abe6f59c2 Many fixes (again)
darius@inchoate.localdomain
parents: 3
diff changeset
229 rtn = "0x%0*x (%ddBm) -> %d samples, mask 0x%04x" % (self.ADDR_SIZE * 2, self.sender,
ed7abe6f59c2 Many fixes (again)
darius@inchoate.localdomain
parents: 3
diff changeset
230 self.rssi, self.nsamples, self.mask)
1
b5d8ec0ffd21 Lots of changes..
darius@inchoate.localdomain
parents: 0
diff changeset
231 # Any DIO lines enabled?
4
ed7abe6f59c2 Many fixes (again)
darius@inchoate.localdomain
parents: 3
diff changeset
232 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
233 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
234 self._data[self.ADDR_SIZE + 6])
4
ed7abe6f59c2 Many fixes (again)
darius@inchoate.localdomain
parents: 3
diff changeset
235 offs = self.ADDR_SIZE + 7
1
b5d8ec0ffd21 Lots of changes..
darius@inchoate.localdomain
parents: 0
diff changeset
236 else:
4
ed7abe6f59c2 Many fixes (again)
darius@inchoate.localdomain
parents: 3
diff changeset
237 offs = self.ADDR_SIZE + 5
1
b5d8ec0ffd21 Lots of changes..
darius@inchoate.localdomain
parents: 0
diff changeset
238
b5d8ec0ffd21 Lots of changes..
darius@inchoate.localdomain
parents: 0
diff changeset
239 # Any ADC lines enabled?
4
ed7abe6f59c2 Many fixes (again)
darius@inchoate.localdomain
parents: 3
diff changeset
240 if (self.mask | 0x7e00):
1
b5d8ec0ffd21 Lots of changes..
darius@inchoate.localdomain
parents: 0
diff changeset
241 for i in range(6):
4
ed7abe6f59c2 Many fixes (again)
darius@inchoate.localdomain
parents: 3
diff changeset
242 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
243 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
244 self._data[offs + 1])
1
b5d8ec0ffd21 Lots of changes..
darius@inchoate.localdomain
parents: 0
diff changeset
245 offs = offs + 2
b5d8ec0ffd21 Lots of changes..
darius@inchoate.localdomain
parents: 0
diff changeset
246 return rtn
b5d8ec0ffd21 Lots of changes..
darius@inchoate.localdomain
parents: 0
diff changeset
247
5
5d5963d542bc More tidyups & fixes.
darius@inchoate.localdomain
parents: 4
diff changeset
248 class RXIO_64_Bit(RXIO_16_Bit):
4
ed7abe6f59c2 Many fixes (again)
darius@inchoate.localdomain
parents: 3
diff changeset
249 PKT_TYPE = 0x82
ed7abe6f59c2 Many fixes (again)
darius@inchoate.localdomain
parents: 3
diff changeset
250 PKT_DESC = "RXIO Packet: 64 bit address"
ed7abe6f59c2 Many fixes (again)
darius@inchoate.localdomain
parents: 3
diff changeset
251 ADDR_SIZE = 8
ed7abe6f59c2 Many fixes (again)
darius@inchoate.localdomain
parents: 3
diff changeset
252
9
d147529ad2db Switch to only reading RX pkts and writing TX pkts to make things simpler.
darius@inchoate.localdomain
parents: 8
diff changeset
253 class TX_16_Bit(TXPkts):
11
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
254 """Transmit to a 16 bit destination"""
6
9c499d923544 Many fixes.
darius@inchoate.localdomain
parents: 5
diff changeset
255 PKT_TYPE = 0x01
4
ed7abe6f59c2 Many fixes (again)
darius@inchoate.localdomain
parents: 3
diff changeset
256 PKT_DESC = "TX Packet: 16 bit address"
6
9c499d923544 Many fixes.
darius@inchoate.localdomain
parents: 5
diff changeset
257 ADDR_SIZE = 2
11
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
258 #: Flag to disable ACK
9
d147529ad2db Switch to only reading RX pkts and writing TX pkts to make things simpler.
darius@inchoate.localdomain
parents: 8
diff changeset
259 FLG_DISABLE_ACK = 0x01
11
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
260 #: Send to broadcast PAN ID
9
d147529ad2db Switch to only reading RX pkts and writing TX pkts to make things simpler.
darius@inchoate.localdomain
parents: 8
diff changeset
261 FLG_BCAST_PANID = 0x04
11
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
262 #: Maximum size payload we can send
9
d147529ad2db Switch to only reading RX pkts and writing TX pkts to make things simpler.
darius@inchoate.localdomain
parents: 8
diff changeset
263 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
264
6
9c499d923544 Many fixes.
darius@inchoate.localdomain
parents: 5
diff changeset
265 def __init__(self, *args):
11
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
266 """Takes 0 to 2 arguments. First is the recipient, the second is the payload (string)"""
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
267 self._flags = 0
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
268 self.payload = []
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
269
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
270 if len(args) == 0:
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
271 pass
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
272 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
273 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
274 self.recipient = args[0]
11
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
275 elif len(args) == 2:
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
276 super(TX_16_Bit, self).__init__()
6
9c499d923544 Many fixes.
darius@inchoate.localdomain
parents: 5
diff changeset
277 self.recipient = args[0]
9c499d923544 Many fixes.
darius@inchoate.localdomain
parents: 5
diff changeset
278 self.payload = args[1]
9c499d923544 Many fixes.
darius@inchoate.localdomain
parents: 5
diff changeset
279 else:
11
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
280 raise TypeError("incorrect number of arguments");
4
ed7abe6f59c2 Many fixes (again)
darius@inchoate.localdomain
parents: 3
diff changeset
281
11
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
282 def __str__(self):
13
729f2393f296 Auto increment frame ID when creating a TX packet.
darius@Inchoate
parents: 11
diff changeset
283 return "TX_%d_Bit ID: %d 0x%0*x <- %s" % (self.ADDR_SIZE * 8, self._frameid, self.ADDR_SIZE * 2,
729f2393f296 Auto increment frame ID when creating a TX packet.
darius@Inchoate
parents: 11
diff changeset
284 self.recipient, self.payload)
11
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
285
9
d147529ad2db Switch to only reading RX pkts and writing TX pkts to make things simpler.
darius@inchoate.localdomain
parents: 8
diff changeset
286 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
287 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
288 raise ValueError("value out of range must be between 0 and %d" % (2 ** self.ADDR_SIZE))
6
9c499d923544 Many fixes.
darius@inchoate.localdomain
parents: 5
diff changeset
289
9
d147529ad2db Switch to only reading RX pkts and writing TX pkts to make things simpler.
darius@inchoate.localdomain
parents: 8
diff changeset
290 self._recipient = value
11
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
291
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
292 """Destination address of the packet"""
9
d147529ad2db Switch to only reading RX pkts and writing TX pkts to make things simpler.
darius@inchoate.localdomain
parents: 8
diff changeset
293 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
294
d147529ad2db Switch to only reading RX pkts and writing TX pkts to make things simpler.
darius@inchoate.localdomain
parents: 8
diff changeset
295 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
296 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
297 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
298
d147529ad2db Switch to only reading RX pkts and writing TX pkts to make things simpler.
darius@inchoate.localdomain
parents: 8
diff changeset
299 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
300 flags = property(lambda s: s._flags, setflags)
5
5d5963d542bc More tidyups & fixes.
darius@inchoate.localdomain
parents: 4
diff changeset
301
6
9c499d923544 Many fixes.
darius@inchoate.localdomain
parents: 5
diff changeset
302 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
303 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
304 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
305 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
306
11
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
307 def payloadstr(self):
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
308 return reduce(lambda a, b: a + chr(b), self.payload, "")
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
309 payloadstr = property(payloadstr, None)
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
310
9
d147529ad2db Switch to only reading RX pkts and writing TX pkts to make things simpler.
darius@inchoate.localdomain
parents: 8
diff changeset
311 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
312 data = [self.frameid]
11
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
313 for i, j in zip(reversed(range(self.ADDR_SIZE)), reversed(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
314 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
315 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
316 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
317 return(data)
d147529ad2db Switch to only reading RX pkts and writing TX pkts to make things simpler.
darius@inchoate.localdomain
parents: 8
diff changeset
318 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
319
6
9c499d923544 Many fixes.
darius@inchoate.localdomain
parents: 5
diff changeset
320 class TX_64_Bit(TX_16_Bit):
1
b5d8ec0ffd21 Lots of changes..
darius@inchoate.localdomain
parents: 0
diff changeset
321 PKT_TYPE = 0x00
b5d8ec0ffd21 Lots of changes..
darius@inchoate.localdomain
parents: 0
diff changeset
322 PKT_DESC = "TX Packet: 64 bit address"
6
9c499d923544 Many fixes.
darius@inchoate.localdomain
parents: 5
diff changeset
323 ADDR_SIZE = 8
1
b5d8ec0ffd21 Lots of changes..
darius@inchoate.localdomain
parents: 0
diff changeset
324
b5d8ec0ffd21 Lots of changes..
darius@inchoate.localdomain
parents: 0
diff changeset
325 class TX_Status(PktBase):
b5d8ec0ffd21 Lots of changes..
darius@inchoate.localdomain
parents: 0
diff changeset
326 PKT_TYPE = 0x89
b5d8ec0ffd21 Lots of changes..
darius@inchoate.localdomain
parents: 0
diff changeset
327 PKT_DESC = "TX Status"
6
9c499d923544 Many fixes.
darius@inchoate.localdomain
parents: 5
diff changeset
328 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
329 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
330 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
331 statusMsg = property(lambda s: s.statusTxt[s._data[1]], None)
11
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
332
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
333 def __init__(self, data = []):
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
334 super(TX_Status, self).__init__()
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
335 self._data = data
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
336
1
b5d8ec0ffd21 Lots of changes..
darius@inchoate.localdomain
parents: 0
diff changeset
337 class Packets(object):
11
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
338 """Packet parsing class (misnamed)"""
4
ed7abe6f59c2 Many fixes (again)
darius@inchoate.localdomain
parents: 3
diff changeset
339 PKT_CLASSES = None
11
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
340
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
341 @classmethod
4
ed7abe6f59c2 Many fixes (again)
darius@inchoate.localdomain
parents: 3
diff changeset
342 def Build(self, data):
11
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
343 """Build a packet from data"""
4
ed7abe6f59c2 Many fixes (again)
darius@inchoate.localdomain
parents: 3
diff changeset
344 if (self.PKT_CLASSES == None):
ed7abe6f59c2 Many fixes (again)
darius@inchoate.localdomain
parents: 3
diff changeset
345 m = inspect.getmodule(self)
ed7abe6f59c2 Many fixes (again)
darius@inchoate.localdomain
parents: 3
diff changeset
346 # Generate list of objects from their names
ed7abe6f59c2 Many fixes (again)
darius@inchoate.localdomain
parents: 3
diff changeset
347 mobjs = map(lambda n: m.__dict__[n], m.__dict__)
ed7abe6f59c2 Many fixes (again)
darius@inchoate.localdomain
parents: 3
diff changeset
348 # Find all the classes
ed7abe6f59c2 Many fixes (again)
darius@inchoate.localdomain
parents: 3
diff changeset
349 pktclasses = filter(inspect.isclass, mobjs)
ed7abe6f59c2 Many fixes (again)
darius@inchoate.localdomain
parents: 3
diff changeset
350 # Find all subclasses of PktBase (but not PktBase itself)
ed7abe6f59c2 Many fixes (again)
darius@inchoate.localdomain
parents: 3
diff changeset
351 pktclasses = filter(lambda s: issubclass(s, m.PktBase) and s != m.PktBase, pktclasses)
ed7abe6f59c2 Many fixes (again)
darius@inchoate.localdomain
parents: 3
diff changeset
352 self.PKT_CLASSES = pktclasses
ed7abe6f59c2 Many fixes (again)
darius@inchoate.localdomain
parents: 3
diff changeset
353
ed7abe6f59c2 Many fixes (again)
darius@inchoate.localdomain
parents: 3
diff changeset
354 for p in self.PKT_CLASSES:
1
b5d8ec0ffd21 Lots of changes..
darius@inchoate.localdomain
parents: 0
diff changeset
355 if (p.PKT_TYPE == data[0]):
11
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
356 #print "Matched " + str(p.PKT_TYPE)
1
b5d8ec0ffd21 Lots of changes..
darius@inchoate.localdomain
parents: 0
diff changeset
357 return(p(data[1:]))
4
ed7abe6f59c2 Many fixes (again)
darius@inchoate.localdomain
parents: 3
diff changeset
358
ed7abe6f59c2 Many fixes (again)
darius@inchoate.localdomain
parents: 3
diff changeset
359 raise ValueError("Unknown packet type 0x%02x" % (data[0]))
1
b5d8ec0ffd21 Lots of changes..
darius@inchoate.localdomain
parents: 0
diff changeset
360
11
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
361 @staticmethod
1
b5d8ec0ffd21 Lots of changes..
darius@inchoate.localdomain
parents: 0
diff changeset
362 def Encapsulate(data):
11
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
363 """Encapsulate a packet so it can be sent to the module. Calculates checksum etc.."""
1
b5d8ec0ffd21 Lots of changes..
darius@inchoate.localdomain
parents: 0
diff changeset
364 pktsum = reduce(lambda x, y: x + y, data) & 0xff
b5d8ec0ffd21 Lots of changes..
darius@inchoate.localdomain
parents: 0
diff changeset
365 pkt = [0x7e] + [len(data) >> 8] + [len(data) & 0xff] + data + [0xff - pktsum]
b5d8ec0ffd21 Lots of changes..
darius@inchoate.localdomain
parents: 0
diff changeset
366 return(map(chr, pkt))
b5d8ec0ffd21 Lots of changes..
darius@inchoate.localdomain
parents: 0
diff changeset
367
10
4c91fdfc862e - Further changes to make things cleaner (ie RX packets are "read only" etc).
darius@inchoate.localdomain
parents: 9
diff changeset
368 def __init__(self, s = None):
11
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
369 """Init class, if s is passed in it is used for reading & writing data"""
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
370 #print str(inspect.getmodule(self))
1
b5d8ec0ffd21 Lots of changes..
darius@inchoate.localdomain
parents: 0
diff changeset
371 self.buffer = []
b5d8ec0ffd21 Lots of changes..
darius@inchoate.localdomain
parents: 0
diff changeset
372 self.state = 'init'
b5d8ec0ffd21 Lots of changes..
darius@inchoate.localdomain
parents: 0
diff changeset
373 self.packets = []
b5d8ec0ffd21 Lots of changes..
darius@inchoate.localdomain
parents: 0
diff changeset
374
b5d8ec0ffd21 Lots of changes..
darius@inchoate.localdomain
parents: 0
diff changeset
375 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
376 self._dataleft = 0
1
b5d8ec0ffd21 Lots of changes..
darius@inchoate.localdomain
parents: 0
diff changeset
377
b5d8ec0ffd21 Lots of changes..
darius@inchoate.localdomain
parents: 0
diff changeset
378 self.fr_err = 0 # Framing error
b5d8ec0ffd21 Lots of changes..
darius@inchoate.localdomain
parents: 0
diff changeset
379 self.ck_err = 0 # Checksum error
b5d8ec0ffd21 Lots of changes..
darius@inchoate.localdomain
parents: 0
diff changeset
380 self.rx_cnt = 0 # Packet count
b5d8ec0ffd21 Lots of changes..
darius@inchoate.localdomain
parents: 0
diff changeset
381
b5d8ec0ffd21 Lots of changes..
darius@inchoate.localdomain
parents: 0
diff changeset
382 self.pktq = []
11
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
383 self.s = s # Output handle for convenience methods
6
9c499d923544 Many fixes.
darius@inchoate.localdomain
parents: 5
diff changeset
384
9c499d923544 Many fixes.
darius@inchoate.localdomain
parents: 5
diff changeset
385 def writedata(self, data):
11
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
386 """Convenience method to write data"""
6
9c499d923544 Many fixes.
darius@inchoate.localdomain
parents: 5
diff changeset
387 self.s.write("".join(map(str, data)))
5
5d5963d542bc More tidyups & fixes.
darius@inchoate.localdomain
parents: 4
diff changeset
388
6
9c499d923544 Many fixes.
darius@inchoate.localdomain
parents: 5
diff changeset
389 def getdata(self):
11
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
390 """Read data until nothing is available (assumes non-blocking) and process it"""
1
b5d8ec0ffd21 Lots of changes..
darius@inchoate.localdomain
parents: 0
diff changeset
391 l = []
11
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
392 while 1:
6
9c499d923544 Many fixes.
darius@inchoate.localdomain
parents: 5
diff changeset
393 a = self.s.read()
11
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
394 if a == '':
1
b5d8ec0ffd21 Lots of changes..
darius@inchoate.localdomain
parents: 0
diff changeset
395 break
5
5d5963d542bc More tidyups & fixes.
darius@inchoate.localdomain
parents: 4
diff changeset
396 l.append(ord(a))
1
b5d8ec0ffd21 Lots of changes..
darius@inchoate.localdomain
parents: 0
diff changeset
397
b5d8ec0ffd21 Lots of changes..
darius@inchoate.localdomain
parents: 0
diff changeset
398 return self.process(l)
b5d8ec0ffd21 Lots of changes..
darius@inchoate.localdomain
parents: 0
diff changeset
399
11
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
400 def processstr(self, data):
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
401 """Process a string of data"""
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
402 return self.process(map(ord, data))
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
403
1
b5d8ec0ffd21 Lots of changes..
darius@inchoate.localdomain
parents: 0
diff changeset
404 def process(self, data):
11
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
405 """Process (ordinal) data through the state machine.
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
406
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
407 Returns the number of packets in the queue when finished. Updates
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
408 various internal counters too.
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
409 """
1
b5d8ec0ffd21 Lots of changes..
darius@inchoate.localdomain
parents: 0
diff changeset
410 pktcount = 0
b5d8ec0ffd21 Lots of changes..
darius@inchoate.localdomain
parents: 0
diff changeset
411 for d in data:
b5d8ec0ffd21 Lots of changes..
darius@inchoate.localdomain
parents: 0
diff changeset
412 if (self.state == 'init'):
5
5d5963d542bc More tidyups & fixes.
darius@inchoate.localdomain
parents: 4
diff changeset
413 if (d != 0x7e):
11
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
414 print "Framing error, got 0x%02x, expected 0x7e" % d
4
ed7abe6f59c2 Many fixes (again)
darius@inchoate.localdomain
parents: 3
diff changeset
415 self.fr_err += 1
1
b5d8ec0ffd21 Lots of changes..
darius@inchoate.localdomain
parents: 0
diff changeset
416 continue
b5d8ec0ffd21 Lots of changes..
darius@inchoate.localdomain
parents: 0
diff changeset
417
b5d8ec0ffd21 Lots of changes..
darius@inchoate.localdomain
parents: 0
diff changeset
418 self.state = 'sizemsb'
b5d8ec0ffd21 Lots of changes..
darius@inchoate.localdomain
parents: 0
diff changeset
419 elif (self.state == 'sizemsb'):
5
5d5963d542bc More tidyups & fixes.
darius@inchoate.localdomain
parents: 4
diff changeset
420 self.bufmsb = d
1
b5d8ec0ffd21 Lots of changes..
darius@inchoate.localdomain
parents: 0
diff changeset
421 self.state = 'sizelsb'
b5d8ec0ffd21 Lots of changes..
darius@inchoate.localdomain
parents: 0
diff changeset
422 elif (self.state == 'sizelsb'):
7
579dedf5a1f1 Rejoin line break, left over from removal of struct.
darius@inchoate.localdomain
parents: 6
diff changeset
423 self.dataleft = self.bufmsb << 8 | d
1
b5d8ec0ffd21 Lots of changes..
darius@inchoate.localdomain
parents: 0
diff changeset
424 self.state = 'data'
b5d8ec0ffd21 Lots of changes..
darius@inchoate.localdomain
parents: 0
diff changeset
425 elif (self.state == 'data'):
5
5d5963d542bc More tidyups & fixes.
darius@inchoate.localdomain
parents: 4
diff changeset
426 self.buffer.append(d)
1
b5d8ec0ffd21 Lots of changes..
darius@inchoate.localdomain
parents: 0
diff changeset
427 self.dataleft = self.dataleft - 1
b5d8ec0ffd21 Lots of changes..
darius@inchoate.localdomain
parents: 0
diff changeset
428 if (self.dataleft == 0):
b5d8ec0ffd21 Lots of changes..
darius@inchoate.localdomain
parents: 0
diff changeset
429 self.state = 'cksum'
b5d8ec0ffd21 Lots of changes..
darius@inchoate.localdomain
parents: 0
diff changeset
430 elif (self.state == 'cksum'):
b5d8ec0ffd21 Lots of changes..
darius@inchoate.localdomain
parents: 0
diff changeset
431 pktsum = reduce(lambda x, y: x + y, self.buffer) & 0xff
5
5d5963d542bc More tidyups & fixes.
darius@inchoate.localdomain
parents: 4
diff changeset
432 rxcksum = d
1
b5d8ec0ffd21 Lots of changes..
darius@inchoate.localdomain
parents: 0
diff changeset
433 self.state = 'init'
b5d8ec0ffd21 Lots of changes..
darius@inchoate.localdomain
parents: 0
diff changeset
434 if (pktsum + rxcksum != 0xff):
b5d8ec0ffd21 Lots of changes..
darius@inchoate.localdomain
parents: 0
diff changeset
435 self.buffer = []
4
ed7abe6f59c2 Many fixes (again)
darius@inchoate.localdomain
parents: 3
diff changeset
436 self.ck_err += 1
1
b5d8ec0ffd21 Lots of changes..
darius@inchoate.localdomain
parents: 0
diff changeset
437 print "Checksum error, got 0x%02x, expected 0x%02x" % \
b5d8ec0ffd21 Lots of changes..
darius@inchoate.localdomain
parents: 0
diff changeset
438 (rxcksum, 0xff - pktsum)
b5d8ec0ffd21 Lots of changes..
darius@inchoate.localdomain
parents: 0
diff changeset
439 else:
11
75f785a09e2e Add license.
darius@Inchoate
parents: 10
diff changeset
440 #print "Got a packet - " + str(self.buffer)
1
b5d8ec0ffd21 Lots of changes..
darius@inchoate.localdomain
parents: 0
diff changeset
441 p = Packets.Build(self.buffer)
b5d8ec0ffd21 Lots of changes..
darius@inchoate.localdomain
parents: 0
diff changeset
442 self.pktq.append(p)
b5d8ec0ffd21 Lots of changes..
darius@inchoate.localdomain
parents: 0
diff changeset
443 self.buffer = []
4
ed7abe6f59c2 Many fixes (again)
darius@inchoate.localdomain
parents: 3
diff changeset
444 pktcount += 1
ed7abe6f59c2 Many fixes (again)
darius@inchoate.localdomain
parents: 3
diff changeset
445 self.rx_cnt += 1
1
b5d8ec0ffd21 Lots of changes..
darius@inchoate.localdomain
parents: 0
diff changeset
446 else:
b5d8ec0ffd21 Lots of changes..
darius@inchoate.localdomain
parents: 0
diff changeset
447 print "Invalid state %s! Resetting" % (self.state)
b5d8ec0ffd21 Lots of changes..
darius@inchoate.localdomain
parents: 0
diff changeset
448 self.state = 'init'
b5d8ec0ffd21 Lots of changes..
darius@inchoate.localdomain
parents: 0
diff changeset
449
b5d8ec0ffd21 Lots of changes..
darius@inchoate.localdomain
parents: 0
diff changeset
450 return pktcount
b5d8ec0ffd21 Lots of changes..
darius@inchoate.localdomain
parents: 0
diff changeset
451