2

我通过对 PySerial 的愚蠢误用成功地重现地冻结了 OS X(至少是键盘和鼠标输入)。尽管电源按钮起作用,但键盘和鼠标完全停止响应。我还没有找到实际的错误,但我很惊讶这样的事情甚至是可能的。那么问题来了:这怎么可能?

附上代码:

#!/usr/bin/env python3


from hashlib import *
from serial import *
from sqlalchemy import *
from sqlalchemy.orm import *
from sqlalchemy.ext.declarative import *


engine = create_engine('sqlite:///Cards.data', echo=True)
Base = declarative_base()


class Card (Base):
    __tablename__ = 'cards'

    id     = Column(Integer, primary_key=True)
    track1 = Column(String)
    track2 = Column(String)
    track3 = Column(String)
    name   = Column(String)
    room   = Column(String)

    def __init__ (self, track1, tack2, track3, name=None, room=None):
        self.track1 = track1
        self.track2 = track2
        self.track3 = track3
        self.name   = name
        self.room   = room

    def __repr__ (self):
        return '<%s>' % (hashlib.sha256(self.track1+self.track2+self.track3).hexdigest()[:4])


ESC           = b'\x1B'
FS            = b'\x1C'
ACK           = b'\x1B\x79'
RESET         = b'\x1B\x61'
READ_ISO      = b'\x1B\x72'
WRITE_ISO     = b'\x1B\x77'
COM_TEST      = b'\x1B\x65'
ALL_LED_OFF   = b'\x1B\x81'
ALL_LED_ON    = b'\x1B\x82'
GREEN_LED_ON  = b'\x1B\x83'
YELLOW_LED_ON = b'\x1B\x84'
RED_LED_ON    = b'\x1B\x85'
SENSOR_TEST   = b'\x1B\x86'
RAM_TEST      = b'\x1B\x87'

DEVICES       = ['/dev/cu.usbserial', '/dev/ttyUSB0']
BAUD_RATE     = 9600


class MSR605 (object):

    def __init__ (self, device=None):
        self._connect(device)

    def readCard (self):
        pass

    def eraseCard (self, t1=True, t2=True, t3=True):
        flags = (t1 and 1 or 0) | (t2 and 2 or 0) | (t3 and 4 or 0)
        self._send('\x63', chr(flags))
        self._read_status()

    def setBPI (self, t1_density, t2_density, t3_density):
        self._send('\x62', t1_density and '\xD2' or '\x4B')
        self._read_status()
        self._send('\x62', t2_density and '\xA1' or '\xA0')
        self._read_status()
        self._send('\x62', t3_density and '\xC1' or '\xC0')
        self._read_status()

    def setBPC (self, t1, t2, t3):
        self._send('\x6F', chr(t1), chr(t2), chr(t3))
        self._expect(ESC + '\x30' + chr(t1) + chr(t2) + chr(t3))

    def _connect (self, device=None):
        if not device:
            for d in DEVICES:
                self._device = device
                try:
                    self._serial = Serial(d,BAUD_RATE)
                    self._write(RESET)
                    self._write(COM_TEST)
                    self._expect(ESC)
                    self._expect(b'y')
                    return
                except: pass
        self._device
        self._serial = None
        raise ConnectionError()

    def _expect (self, data):
        result = self.read(len(data))
        if result != data: raise ReadError()

    def _send (self, command, *args):
        self.flushInput()
        self.flushOutput()
        self.write(ESC + command + b''.join(args))

    def _status (self):
        exceptions = {
            b'\x31': ReadWriteError,
            b'\x32': CommandFormatError,
            b'\x34': CommandError,
            b'\x39': SwipeError,
            b'\x41': SetError,
        }
        self._expect(self.ESC_CHR)
        status = self.read(1)
        if status in exceptions:
            raise exceptions[status]()
        return status

    def _read (self, length=None):
        if length: return self._serial.read(length)
        else:      return self._serial.read()

    def _write (self, data):
        self._serial.write(data)

    class MSR605Error (Exception): pass
    class CommandError (MSR605Error): pass
    class CommandFormatError (MSR605Error): pass
    class ConnectionError (MSR605Error): pass
    class ReadError (MSR605Error): pass
    class ReadWriteError (MSR605Error): pass
    class SetError (MSR605Error): pass
    class SwipeError (MSR605Error): pass


if __name__ == '__main__':
    Base.metadata.create_all(engine)
    msr = MSR605()
    card = msr.readCard()
    print(card)
4

1 回答 1

2

它不是 PySerial,而是驱动程序。无论是 Apple 的驱动程序还是您安装的第 3 方驱动程序(如果您安装了)都是单独的讨论。但是驱动程序显然在内核中混搭了 USB 子系统,这会杀死您的鼠标和键盘。

于 2013-01-30T22:55:50.600 回答