X-Git-Url: https://git.ucc.asn.au/?p=uccvend-vendserver.git;a=blobdiff_plain;f=sql-edition%2Fservers%2FMIFAREDriver.py;fp=sql-edition%2Fservers%2FMIFAREDriver.py;h=0000000000000000000000000000000000000000;hp=6248f60c2934b2e2135c8a97899561116dd2c5bc;hb=6c130dc942392ccc8b7ffa0ec2ede5f9327f99e6;hpb=e423f11f190d685156cb557319b169d2b79b752f;ds=sidebyside diff --git a/sql-edition/servers/MIFAREDriver.py b/sql-edition/servers/MIFAREDriver.py deleted file mode 100644 index 6248f60..0000000 --- a/sql-edition/servers/MIFAREDriver.py +++ /dev/null @@ -1,189 +0,0 @@ -#!/usr/bin/env python2.5 - -'''mifare - a library for interacting with MIFARE readers. -Written by David Adam -Requires Python 2.5. - -Licensed under an MIT-style license: see LICENSE file for details. -''' - -import serial, logging - -xor = lambda x, y: x ^ y -def checksum(string): - return chr(reduce(xor, [ord(i) for i in string])) - - -class MIFAREException(Exception): - pass - - -class MIFARECommunicationException(MIFAREException): - pass - - -class MIFAREAuthenticationException(MIFAREException): - pass - - -class MIFAREReader: - '''An interface to a particular MIFARE reader.''' - - def __init__(self, io): - '''Returns an interface to a MIFARE reader given a file-like object. - The file-like object is generally a pyserial Serial object.''' - self.io = io - if isinstance(self.io, serial.Serial): - self.io.setTimeout(2) - self.address = '\x00\x00' - - def get_absolute_block(self, vector): - if vector[0] < 32: - return vector[0] * 4 + vector[1] - else: - # Sectors below 32 are 4 blocks - # Sectors above are 16 blocks - # 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): - '''Constructs a packet for the supplied data string, sends it to the - MIFARE reader, then returns the response (if any) to the commmand.''' - - # Occasionally the reader inserts extra trailing characters into its - # responses, so flush the buffers if possible beforehand. - if isinstance(self.io, serial.Serial): - self.io.flushInput() - self.io.flushOutput() - - # XXX - Needs more error checking. - data = '\x00' + self.address + data - packet = '\xAA\xBB' + chr(len(data)) + data + checksum(data) - self.io.write(packet) - response = '' - header = self.io.read(2) - if header == '\xaa\xbb': - length = ord(self.io.read(1)) - data = self.io.read(length) - packet_xsum = self.io.read(1) - if checksum(data) == packet_xsum and len(data) == length: - # Strip off separator and address header - return data[3:] - else: - raise MIFARECommunicationException, "Invalid response received" - - def set_antenna(self, state = True): - """Turn the card reader's antenna on or off (no return value)""" - command = '\x0C\x01' + chr(int(state)) - response = self.send_packet(command) - if response == '\x0c\x01\x00': - return None - else: - raise MIFAREException, 'command failed: set_antenna (%s)' % state - - def select_card(self, include_halted = False): - """Selects a card and returns a tuple of (serial number, capacity). - - If include_halted is set, may select a card that halt() has previously - been called on.""" - - # Request type of card available - command = command = '\x01\x02' - if include_halted: - command += '\x52' - else: - command += '\x26' - - card_type_response = self.send_packet(command) - - if card_type_response == None or card_type_response[2] == '\x14': - raise MIFAREException, "select_card: no card available" - card_type = card_type_response[3:5] - - if card_type == '\x44\x00': # MIFARE UltraLight - raise NotImplementedError, "UltraLight card selected - no functions available" - - else: - # Otherwise, must be a standard MIFARE card. - # Anticollision - command = '\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) - 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): - """Log in to a block using the six-byte key. - - Use a keytype of 1 to use key B.""" - sector = self.get_absolute_block((blockvect[0], 0)) - - if len(key) != 6: - raise ValueError, 'key must be a six-byte string' - - keytype = 96 + keytype - - data = chr(keytype) + chr(sector) + key - - result = self.send_packet('\x07\x02' + data) - if ord(result[2]) == 22: - raise MIFAREAuthenticationException, "incorrect key provided" - - return - - def read_block(self, blockvect): - "Read the 16-byte block at vector (sector, block)." - block = self.get_absolute_block(blockvect) - - result = self.send_packet('\x08\x02' + chr(block)) - return result[3:19] - - def write_block(self, blockvect, data): - """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 - - def write_key(self, key): - pass - - def value_block_increment(self, blocknum, increment): - pass - - def value_block_decrement(self, blocknum, decrement): - pass - - def copy_block(self, source, dest): - pass - - def halt(self): - """Halt the current card - no further transactions will be performed with it.""" - self.send_packet('\x04\x02') - - def set_led(self, red = False, green = False): - led_state = 0 - if red: - led_state += 1 - if green: - led_state += 2 - self.send_packet('\x07\x01' + chr(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)) - - def reset(self): - pass