1

I have a card reader (MagTec MSR100) that I want to use to read information of of the magnetic strip of cards. When I plug in the card reader, the computer interprets the card reader as if it were a keyboard, sending the corresponding keypresses to standard input for whatever application I'm in (terminal, vim, etc.). What I'd really like to do is to capture the output that comes specifically from this device and not from the keyboard.

I have read permissions on the device (for me, /dev/usb/hiddev0), and when I try the following code

f = open('/dev/usb/hiddev0', 'r')
f.readline()

in Python and swipe the card, the information encoded in the magnetic strip (something like %6091430968014=FIRST/LAST?) appears as if I just typed it in, and the call to readline does not return. How can I listen to the input from this specific device?

Miles Yucht
  • 538
  • 5
  • 12
  • The problem may be that the device is not sending a carriage return of "enter key" at the end of the data. You could try reading using `read()` instead to avoid waiting for enter. Ultimately, to figure out exactly what the device sends and when, or to make it send something different, you're probably going to have to hunt around in the documentation for the device and/or contact the device maker. – BrenBarn Apr 13 '13 at 23:56
  • I'm pretty sure it is sending a carriage return because if I swipe it while in terminal, it tries to execute the string like a command. Maybe I wasn't so clear, but I want to capture this string. If I use a command like `input()` which reads from stdin, I can capture this text. Is there possibly another way I could distinguish between keyboard text and text from a card swipe? – Miles Yucht Apr 14 '13 at 00:33
  • If the device identifies itself as a keyboard you will have a tough time. Do you have the device documentation? I'm not able to find anything about "MagTec MSR100" on the web. – BrenBarn Apr 14 '13 at 01:05
  • One possibility might be to look at the timings between consecutive keys presses. If the keys come in sufficiently fast, it's very unlikely that they came from a human typing on a keyboard. – Wesley Baugh Apr 14 '13 at 02:48

1 Answers1

0

If you're using Linux, try the Python module evdev.

from evdev import InputDevice, categorize, ecodes

# Initialize card reader
swiper = InputDevice("/dev/input/event0") # magswipe card reader

scancodes = {
    # Scancode: ASCIICode
    0: None, 1: u'ESC', 2: u'1', 3: u'2', 4: u'3', 5: u'4', 6: u'5', 7: u'6', 8: u'7', 9: u'8',
    10: u'9', 11: u'0', 12: u'-', 13: u'=', 14: u'BKSP', 15: u'TAB', 16: u'Q', 17: u'W', 18: u'E', 19: u'R',
    20: u'T', 21: u'Y', 22: u'U', 23: u'I', 24: u'O', 25: u'P', 26: u'[', 27: u']', 28: u'CRLF', 29: u'LCTRL',
    30: u'A', 31: u'S', 32: u'D', 33: u'F', 34: u'G', 35: u'H', 36: u'J', 37: u'K', 38: u'L', 39: u';',
    40: u'"', 41: u'`', 42: u'LSHFT', 43: u'\\', 44: u'Z', 45: u'X', 46: u'C', 47: u'V', 48: u'B', 49: u'N',
    50: u'M', 51: u',', 52: u'.', 53: u'/', 54: u'RSHFT', 57: u' ', 100: u'?'
}

def read_card(lcd_line_1, lcd_line_2):
    while True:
        # listen to card swiper
        for event in swiper.read_loop():
            if event.type == ecodes.EV_KEY:
                data = categorize(event)  # Save the event temporarily to introspect it
                if data.keystate == 1:  # Down events only
                    key_lookup = scancodes.get(data.scancode) or u'UNKNOWN:{}'.format(data.scancode)  # Lookup or return UNKNOWN:XX
                    print(key_lookup)