def __init__(self, dispatcher, devname): "Constructor. devname - serial port devname" self.dispatcher = dispatcher self.stream = RCSerialStream(devname) self._next_pkt_id = 0
class Host(object): "Interface to the hardware" def __init__(self, dispatcher, devname): "Constructor. devname - serial port devname" self.dispatcher = dispatcher self.stream = RCSerialStream(devname) self._next_pkt_id = 0 def send_raw(self, buf): "Send raw data without any checksuming and headers" #print "Sending: %s" % (", ".join(["0x%02x" % a for a in buf])) buf = ''.join([chr(a) for a in buf]) with self.stream.get_writer() as writer: writer.write_bytes(buf) writer.flush() def flush(self): self.stream.flush() def send(self, pkt): "Immediately pushes packet to the serial port" buf = [0x5a] _crc = 0 for data in [len(pkt)] + list(pkt): if type(data) == str and len(data) == 1: data = ord(data) _crc = crc(_crc, data) buf.append(data) buf.append(_crc) self.send_raw(buf) def loop(self): "Infinitely reads serial input and parses packets" with self.stream.get_reader() as reader: while True: # waiting for preamble while True: data = ord(reader.read_bytes(1)) if data == 0x5a: break # reading packet length _crc = 0 pktlen = ord(reader.read_bytes(1)) _crc = crc(_crc, pktlen) # reading packet data if pktlen > 0: data = [] for d in reader.read_bytes(pktlen): d = ord(d) data.append(d) _crc = crc(_crc, d) # reading CRC _crc = crc(_crc, ord(reader.read_bytes(1))) # checking CRC if _crc == 0: #print "Packet received successfully: %s" % (", ".join(["0x%02x" % d for d in data])) self.dispatcher.receive(data) def available(self): "Check whether host is available" req = HostEchoRequest() try: return self.dispatcher.request(req, timeout=3) except TimeoutError: return False def calibrate_baudrate(self): "Perform baud rate calibration" req = BaudRateCalibrationRequest() try: return self.dispatcher.request(req, timeout=3) except TimeoutError: raise BaudRateCalibrationError() def next_pkt_id(self): self._next_pkt_id = (self._next_pkt_id + 1) % 256 return self._next_pkt_id