diff --git a/VendServer/MIFAREDriver.py b/VendServer/MIFAREDriver.py index 5961383da7647bc7ce674f5d9a11affedba3d304..54b4af4492fd3b65aa3a2e961a8ae37df5ba2c3c 100644 --- a/VendServer/MIFAREDriver.py +++ b/VendServer/MIFAREDriver.py @@ -11,8 +11,8 @@ import serial, logging from functools import reduce xor = lambda x, y: x ^ y -def checksum(string): - return chr(reduce(xor, [ord(i) for i in string])) +def checksum(data: bytes): + return bytes[reduce(xor, data)] class MIFAREException(Exception): @@ -36,7 +36,7 @@ class MIFAREReader: self.io = io if isinstance(self.io, serial.Serial): self.io.setTimeout = 2 - self.address = '\x00\x00' + self.address = b'\x00\x00' def get_absolute_block(self, vector): if vector[0] < 32: @@ -47,7 +47,7 @@ class MIFAREReader: # Thus, sector 32 starts at block 128, 33 at 144, and so on return 128 + (vector[0] - 32) * 16 + vector[1] - def send_packet(self, data): + def send_packet(self, data: bytes): '''Constructs a packet for the supplied data string, sends it to the MIFARE reader, then returns the response (if any) to the commmand.''' @@ -58,12 +58,12 @@ class MIFAREReader: self.io.flushOutput() # XXX - Needs more error checking. - data = '\x00' + self.address + data - packet = '\xAA\xBB' + chr(len(data)) + data + checksum(data) + data = b'\x00' + self.address + data + packet = bytes([0xAA, 0xBB, len(data)]) + data + checksum(data) self.io.write(packet) response = '' header = self.io.read(2) - if header == '\xaa\xbb': + if header == b'\xaa\xbb': length = ord(self.io.read(1)) data = self.io.read(length) packet_xsum = self.io.read(1) @@ -75,9 +75,9 @@ class MIFAREReader: def set_antenna(self, state = True): """Turn the card reader's antenna on or off (no return value)""" - command = '\x0C\x01' + chr(int(state)) + command = bytes([0xc, 0x1, int(state)]) response = self.send_packet(command) - if response == '\x0c\x01\x00': + if response == b'\x0c\x01\x00': return None else: raise MIFAREException('command failed: set_antenna (%s)' % state) @@ -89,44 +89,44 @@ class MIFAREReader: been called on.""" # Request type of card available - command = command = '\x01\x02' + command = command = b'\x01\x02' if include_halted: - command += '\x52' + command += b'\x52' else: - command += '\x26' + command += b'\x26' card_type_response = self.send_packet(command) - if card_type_response == None or card_type_response[2] == '\x14': + if card_type_response == None or card_type_response[2] == 0x14: raise MIFAREException("select_card: no card available") card_type = card_type_response[3:5] - if card_type == '\x44\x00': # MIFARE UltraLight + if card_type == b'\x44\x00': # MIFARE UltraLight #raise NotImplementedError, "UltraLight card selected - no functions available" - # HACK by JAH: The response format isn't fully known yet (official driver reads 7 bytes from offset +9 in the raw response) + # HACK by TPG: The response format isn't fully known yet (official driver reads 7 bytes from offset +9 in the raw response) # - This code effectively reads all bytes after +9 (AA, BB, len, and three skilled by `send_packet`, then three skipped here) # - Official driver has `AA` bytes followed by `00` (encoded/decoded) - command = '\x12\x02' + command = b'\x12\x02' serial = self.send_packet(command)[3:] capacity = 0 return (serial, capacity) else: # Otherwise, must be a standard MIFARE card. # Anticollision - command = '\x02\x02\x04' + command = b'\x02\x02\x04' # No error handling on this command serial = self.send_packet(command)[3:] # Select the card for use try: - select_response = self.send_packet('\x03\x02' + serial) + select_response = self.send_packet(b'\x03\x02' + serial) capacity = ord(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 return (serial, capacity) - def sector_login(self, blockvect, key, keytype=0): + def sector_login(self, blockvect, key: bytes, keytype=0): """Log in to a block using the six-byte key. Use a keytype of 1 to use key B.""" @@ -137,9 +137,9 @@ class MIFAREReader: keytype = 96 + keytype - data = chr(keytype) + chr(sector) + key + data = bytes([keytype, sector]) + key - result = self.send_packet('\x07\x02' + data) + result = self.send_packet(b'\x07\x02' + data) if ord(result[2]) == 22: raise MIFAREAuthenticationException("incorrect key provided") @@ -149,17 +149,17 @@ class MIFAREReader: "Read the 16-byte block at vector (sector, block)." block = self.get_absolute_block(blockvect) - result = self.send_packet('\x08\x02' + chr(block)) + result = self.send_packet( bytes([0x08,0x02, block]) ) return result[3:19] - def write_block(self, blockvect, data): + def write_block(self, blockvect, data: bytes): """Write the 16 bytes in data to the block at vector (sector, block).""" block = self.get_absolute_block(blockvect) if len(data) != 16: raise ValueError("invalid data length - must be 16 bytes") - result = self.send_packet('\x09\x02' + chr(block) + data) - return + result = self.send_packet( bytes([0x09,0x02,block]) + data ) + return #result[3:19] def write_key(self, key): pass @@ -175,7 +175,7 @@ class MIFAREReader: def halt(self): """Halt the current card - no further transactions will be performed with it.""" - self.send_packet('\x04\x02') + self.send_packet(b'\x04\x02') def set_led(self, red = False, green = False): led_state = 0 @@ -183,14 +183,14 @@ class MIFAREReader: led_state += 1 if green: led_state += 2 - self.send_packet('\x07\x01' + chr(led_state)) + self.send_packet(bytes([0x07,0x01, led_state])) def beep(self, length): '''Beep for a specified length of milliseconds.''' length = int(round(length / 10.)) if length > 255: length = 255 - self.send_packet('\x06\x01' + chr(length)) + self.send_packet(bytes([0x06,0x01, length])) def reset(self): pass