Project

General

Profile

Statistics
| Revision:

root / trunk / common / common.py @ 225

History | View | Annotate | Download (4.7 KB)

1
"""
2
  This file is part of Tooltron.
3
 
4
  Tooltron is free software: you can redistribute it and/or modify
5
  it under the terms of the Lesser GNU General Public License as published by
6
  the Free Software Foundation, either version 3 of the License, or
7
  (at your option) any later version.
8
 
9
  Tooltron is distributed in the hope that it will be useful,
10
  but WITHOUT ANY WARRANTY; without even the implied warranty of
11
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
  Lesser GNU General Public License for more details.
13
  You should have received a copy of the Lesser GNU General Public License
14
  along with Tooltron.  If not, see <http://www.gnu.org/licenses/>.
15

16
  Copyright 2009 Bradford Neuman <bneuman@andrew.cmu.edu>
17

18
"""
19

    
20
####
21
# This file contains common code for both manualTron and the real tooltron server
22

    
23
import serial
24
import sys
25

    
26
keypadTimeout = 11 #in seconds
27

    
28
TT_GET_KEY = 'k'
29
TT_SEND_KEY = 's' ############ put this in tooltron.py
30
TT_ACK     = 'a'
31
TT_NACK    = 'n'
32
TT_TO      = 'f'
33
TT_TIMEOUT = 't'
34
TT_ON      = 'o'
35
TT_PING    = 'g'
36
TT_BOOT    = 'b'
37
TT_PROGRAM_MODE = 'p'
38
TT_RESET = 'r'
39
TT_PING = 'g'
40
TT_BAD = 0
41
TT_PROGM = 'p'
42
TT_PROGD = 'd'
43

    
44

    
45
MAX_PAYLOAD_LEN = 32
46

    
47
BAUD_RATE = 9600
48

    
49
#fails until a warning is sent
50
MAX_TOOL_FAILS = 5
51

    
52
bus = None
53

    
54
class BusException(Exception):
55
    def __str__(self):
56
        return "Bus Not Init'd"
57

    
58
def printMsg(msg):
59
    if len(msg) < 5:
60
        print "ERROR: trying to print message thats too small!"
61
        return
62
    if msg[0] == '^':
63
        print '^',
64
    else:
65
        print str(ord(msg[0]))
66

    
67
    for c in msg[1:]:
68
        print str(ord(c)),
69

    
70
    print
71

    
72

    
73
#tn is an actual tool number
74
# ^ <src> <dest> <cmd> <plen> <payload> <crc>
75
def sendMessage(tn, cmd, msg):
76
    global bus
77
    if bus == None:
78
        raise BusException
79
    if len(msg) > MAX_PAYLOAD_LEN:
80
        print "ERROR: message too long! max size is " + str(MAX_PAYLOAD_LEN)
81
    else:
82
        body = chr(1) + chr(tn) + cmd + chr(len(msg)) + msg
83
        crc = 0
84
        for c in body:
85
            crc = crc ^ ord(c)
86
        msg = '^' + body + chr(crc)
87
        print "sending packet to tool",tn
88
        printMsg(msg)
89
        bus.write(msg)
90

    
91
def sendTool(t):
92
    tn = t
93
    print "seding power to tool ID",tn
94
    sendMessage(tn, TT_ON, "")
95

    
96
def sendKeyRequest():
97
   print "seding key request"
98
   sendMessage(2, TT_GET_KEY, "")
99

    
100
def sendAck(toolNum):
101
   print "seding ACK to",toolNum
102
   sendMessage(toolNum, TT_ACK, "")
103

    
104
def sendNack(toolNum):
105
   print "seding ACK to",toolNum
106
   sendMessage(toolNum, TT_NACK, "")
107

    
108
# This function eats the rest of the packet where data is what we have so far
109
def flushPacket(data):
110
    global bus
111
    if bus == None:
112
        raise BusException
113

    
114
    while len(data) < 6:
115
        c = bus.read(1)
116
        #print "("+str(ord(c))+")"
117
        data += c
118

    
119
    plen = data[4]
120
    if plen > 0:
121
        bus.read(ord(plen))
122

    
123

    
124
#reads until a timeout
125
def readInf():
126
    c = ' '
127
    while c != '':
128
        c = bus.read(1)
129
        if c != '':
130
            print "<" + str(ord(c)) + ">"
131

    
132
# Returns [src, dest, cmd, data]
133
def readMessage():
134
    global bus
135
    if bus == None:
136
        raise BusException
137

    
138
    start = bus.read(1)
139
    if start == '^':
140
        src = bus.read(1)
141
        if src == chr(1): #reflection
142
            print "(reflection)"
143
            flushPacket('^' + src)
144
            return readMessage()
145

    
146
        dest = bus.read(1)
147
        cmd = bus.read(1)
148
        plen = bus.read(1)
149
        data = bus.read(ord(plen))
150
        x = bus.read(1)
151

    
152
        print "got packet"
153
        printMsg('^' + src + dest + cmd + plen + data + x)
154

    
155
        crc = ord(src) ^ ord(dest) ^ ord(cmd) ^ ord(plen)
156
        for d in data:
157
            crc ^= ord(d)
158

    
159
        if crc == ord(x):
160
            return [src, dest, cmd, data]
161
        else:
162
            print "xor fail. got", str(ord(x)), "should have been got",crc
163
            return None
164
    else:
165
        if start == '':
166
            print "ERROR: timeout on start delim"
167
        else:
168
            print "ERROR: did not get start delimiter: "+str(ord(start))
169
        return None
170

    
171
def readKey():
172
   m = readMessage()
173
   if m == None:
174
      return None
175
   [src, dest, cmd, data] = m
176
   if cmd == TT_SEND_KEY:
177
      return data[0]
178
   else:
179
      return None
180

    
181
#returns [src, dest, command] or [] on error
182
# because of reflection, this will quietly ignore packets send by the server
183
def readTool():
184
    m = readMessage()
185
    if m == None:
186
        return None
187
    [src, dest, cmd, data] = m
188
    return [src, dest, cmd]
189

    
190
def checkAck(t):
191
    tn = t
192
    m = readTool()
193
    if m==None:
194
        print "timeout"
195
        return False
196
    [src,dest,cmd] = m
197
    return cmd == TT_ACK
198

    
199

    
200
def initBus(filename):
201
    global bus
202

    
203
    bus = serial.Serial(filename, BAUD_RATE, timeout = 2)
204
    bus.flushInput()
205
    print bus
206

    
207
    return True