我通过对 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)