forked from NTUOSC/ntu-scanner-py
-
Notifications
You must be signed in to change notification settings - Fork 0
/
card_reader.py
105 lines (79 loc) · 3.19 KB
/
card_reader.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
import ctypes
C_PORT_USB = 100
C_BAUD_RATE = 115200
# TODO: set proper block here to retrieve the correct block ^.<
# C_TARGET_BLOCK = 1048
C_TARGET_SECTOR = C_TARGET_BLOCK // 4
class CardReaderException(Exception):
def __init__(self, func_name, ret, help=None):
msg = '{} fails with return value {}'.format(func_name, ret)
if help is not None:
msg += '; ' + help
super().__init__(msg)
self.return_value = ret
class CardReader:
library = None
@staticmethod
def initLibrary():
if hasattr(ctypes, 'WinDLL'):
CardReader.library = ctypes.WinDLL('dcrf32.dll')
else:
CardReader.library = ctypes.CDLL('Rf_linuxhidd8.o')
def __init__(self, doInitDevice=True):
if CardReader.library is None:
CardReader.initLibrary()
self.last_snr = None
self._icdev = None
self._strSize = None
if doInitDevice:
self.initDevice()
def initDevice(self):
icdev = CardReader.library.dc_init(C_PORT_USB, C_BAUD_RATE)
if icdev == 0:
raise RuntimeError('Failed to get the descriptor of the device.')
self._strSize = ctypes.create_string_buffer(8)
ret = CardReader.library.dc_getver(icdev, self._strSize)
if ret != 0:
raise CardReaderException('dc_getver', ret)
self._icdev = icdev
def getDescriptor(self):
return self._icdev
def loadKey(self, key, slot=0, type=0):
keyPtr = ctypes.c_char_p(key)
ret = CardReader.library.dc_load_key(self._icdev, slot, type, keyPtr)
if ret != 0:
raise CardReaderException('dc_load_key', ret)
def beep(self, dur=10):
ret = CardReader.library.dc_beep(self._icdev, dur)
if ret != 0:
raise CardReaderException('dc_beep', ret)
def readCard(self, returnStr=False):
icdev = self._icdev
lib = CardReader.library
if icdev is None:
raise RuntimeError('Device is not initialized yet!')
ret = lib.dc_reset(icdev, 0)
if ret != 0:
raise CardReaderException('dc_reset', ret)
tagtype = ctypes.c_uint()
ret = lib.dc_request(icdev, 0, ctypes.byref(tagtype))
if ret != 0:
raise CardReaderException('dc_request', ret, 'is the card on the tray?')
card_snr = ctypes.c_uint()
if lib.dc_anticoll(icdev, 0, ctypes.byref(card_snr)) != 0:
raise CardReaderException('dc_anticoll', ret)
# not knowing what this is for; save it anyways
self.last_snr = card_snr.value
ret = lib.dc_select(icdev, card_snr, self._strSize)
if ret != 0:
raise CardReaderException('dc_select', ret)
ret = lib.dc_authentication(icdev, 0, C_TARGET_SECTOR)
if ret != 0:
raise CardReaderException('dc_authentication', ret, 'check if the card is a valid ID card')
data = ctypes.create_string_buffer(16)
ret = lib.dc_read(icdev, C_TARGET_BLOCK, data)
if ret != 0:
raise CardReaderException('dc_read', ret, 'check if the card is a valid ID card')
if returnStr:
return data.value.decode('utf-8')
return data