diff --git a/VendServer/MIFAREDriver.py b/VendServer/MIFAREDriver.py index 54b4af4492fd3b65aa3a2e961a8ae37df5ba2c3c..852a9056f9119c1e73953d6ae0b5d26d7af04d37 100644 --- a/VendServer/MIFAREDriver.py +++ b/VendServer/MIFAREDriver.py @@ -12,7 +12,7 @@ from functools import reduce xor = lambda x, y: x ^ y def checksum(data: bytes): - return bytes[reduce(xor, data)] + return bytes([reduce(xor, data)]) class MIFAREException(Exception): @@ -60,11 +60,12 @@ class MIFAREReader: # XXX - Needs more error checking. data = b'\x00' + self.address + data packet = bytes([0xAA, 0xBB, len(data)]) + data + checksum(data) + #print("send_packet: {!r}".format(packet)) self.io.write(packet) response = '' header = self.io.read(2) if header == b'\xaa\xbb': - length = ord(self.io.read(1)) + length = self.io.read(1)[0] data = self.io.read(length) packet_xsum = self.io.read(1) if checksum(data) == packet_xsum and len(data) == length: @@ -120,7 +121,7 @@ class MIFAREReader: # Select the card for use try: select_response = self.send_packet(b'\x03\x02' + serial) - capacity = ord(select_response[3]) + capacity = select_response[3] except IndexError: logging.warning('Tried to select card but failed: card_type %s, serial %s, select_response %s' % (card_type.__repr__(), serial.__repr__(), select_response.__repr__())) capacity = 0 @@ -140,7 +141,7 @@ class MIFAREReader: data = bytes([keytype, sector]) + key result = self.send_packet(b'\x07\x02' + data) - if ord(result[2]) == 22: + if result[2] == 22: raise MIFAREAuthenticationException("incorrect key provided") return diff --git a/VendServer/OpenDispense.py b/VendServer/OpenDispense.py index 859a1f5da3aab8dfd0754ac4926d6c06acb6d669..c42f235d0db5d30b27de13109d07b065cebba510 100644 --- a/VendServer/OpenDispense.py +++ b/VendServer/OpenDispense.py @@ -134,7 +134,7 @@ class OpenDispense(DispenseInterface): self._loggedIn = False self._username = None - card_base64 = base64.b64encode(cardId) + card_base64 = base64.b64encode(cardId).decode('utf-8') if card_base64 in CARD_BLACKLIST: logging.info("Blacklisted card base64:%s" % (card_base64,)) @@ -144,9 +144,10 @@ class OpenDispense(DispenseInterface): if conn is None: logging.error("getting username for card {}: Unable to open connection".format(card_base64)) return False - rsp = conn.send_command("AUTHCARD %s" % (card_base64,)) + cmd = "AUTHCARD %s" % (card_base64,) + rsp = conn.send_command(cmd) if not rsp.startswith("200 "): - logging.info("Rejected card base64:%s" % (card_base64,)) + logging.info("%s failed: Rejected card base64:%s: rsp %r" % (cmd, card_base64, rsp)) return False username = rsp.split('=')[1].strip() logging.info("Accepted card base64:%s for %s" % (card_base64,username,)) diff --git a/VendServer/SerialClient.py b/VendServer/SerialClient.py index 3880cb0d41363e8292453ecc2826552c37266d95..280109b8838f5628fd3ad4a4c088fc4de0a34d37 100644 --- a/VendServer/SerialClient.py +++ b/VendServer/SerialClient.py @@ -19,8 +19,8 @@ class SerialClient: ) - self.rfh = self.ser - self.wfh = self.ser + self.rfh = ReadWrapper(self.ser) + self.wfh = WriteWrapper(self.ser) self.wfh.write('B\n') def get_fh(self): @@ -28,6 +28,22 @@ class SerialClient: def __del__(self): pass +class WriteWrapper: + def __init__(self, fh): + self.fh = fh + def write(self, s: str): + return self.fh.write(s.encode('utf-8')) + def flush(self): + return self.fh.flush() +class ReadWrapper: + def __init__(self, fh): + self.fh = fh + def fileno(self): + return self.fh.fileno() + def read(self, count) -> str: + return self.fh.read(count).decode('utf-8') + def readline(self) -> str: + return self.fh.readline().decode('utf-8') if __name__ == '__main__': diff --git a/VendServer/VendServer.py b/VendServer/VendServer.py index 8c7e48a059a4016ef6aad58ed748da1aeece465d..8ed6d2edd2177bdf1b41b2f29de0c541da6a4ac1 100755 --- a/VendServer/VendServer.py +++ b/VendServer/VendServer.py @@ -1069,6 +1069,15 @@ def main(argv=None): logging.error('Vend Server finished unexpectedly, restarting') except KeyboardInterrupt: logging.info("Killed by signal, cleaning up") + # NOTE: When debugging deadlocks, enable this + if options.crash: + (exc_type, exc_value, exc_traceback) = sys.exc_info() + tb = format_tb(exc_traceback, 20) + del exc_traceback + logging.info("Traceback:") + for event in tb: + for line in event.strip().split('\n'): + logging.critical(' '+line) clean_up_nicely(options, config_opts) logging.warning("Vend Server stopped") break @@ -1085,7 +1094,7 @@ def main(argv=None): logging.critical("Message: " + str(exc_value)) logging.critical("Traceback:") for event in tb: - for line in event.split('\n'): + for line in event.strip().split('\n'): logging.critical(' '+line) logging.critical("This message should be considered a bug in the Vend Server.") logging.critical("Please report this to someone who can fix it.")