annotate zb.py @ 14:ac60a9244bdf

Use proper telnet protocol classes. Means we use raw/character at a time stuff and don't get extra echos. Keeps track of each line to log it to the file as well as printing the last seen line on client connect.
author darius@Inchoate
date Sat, 17 Jan 2009 14:42:51 +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