blob: 188e9a24dd1c018e2417dc9e98b6aefce0d378fd [file] [log] [blame]
Tang Cheng396e8252012-07-03 13:21:11 +08001# -*- coding: utf-8 -*-
2'''
3Created on 2011-9-29
Tang Chenge90e9bb2012-07-03 13:38:01 +08004读卡库程序
Tang Cheng396e8252012-07-03 13:21:11 +08005@author: cheng.tang
6'''
7from ctypes import *
8import codecs
9
10class CardOperatorError(Exception):
11 def __init__(self,msg):
12 Exception.__init__(self,msg)
13
14class py_decard:
15 MODE_ALL = 1
16 MODE_IDLE = 0
17 ERROR_RET_NONE = 0
18 ERROR_RAISE_EXP = 1
19 dll_handle = None
20 dll_name = 'dcrf32.dll'
21 device_handle = None
22 error_method = ERROR_RET_NONE
23
24 @staticmethod
25 def _do_load_dll():
26 if py_decard.dll_handle <> None:
27 return
28 py_decard.dll_handle = windll.LoadLibrary(py_decard.dll_name)
29
30 @staticmethod
31 def setup(**kwdargs):
32 if kwdargs.has_key("error_method"):
33 py_decard.error_method = kwdargs["error_method"]
34
35 ####################################################################
36 def __init__(self):
37 py_decard._do_load_dll()
38 self.card_mode = 'contactless'
39 self.ic_port = 0
40
41 def set_card_mode(self,mode='cotactless',icport=-1):
42 self.card_mode = mode
43 if self.card_mode <> 'contactless':
44 self.ic_port = icport
45
46 def setsamport(self,port):
47 self.sam_port = self._get_sam_port(port)
48 ats_buffer = create_string_buffer('\000' * 256)
49 ats_len = c_char('\000')
50
51 py_decard.dll_handle.dc_setcpu(py_decard.device_handle,self.sam_port)
52 ret = py_decard.dll_handle.dc_cpureset(py_decard.device_handle,byref(ats_len),ats_buffer)
53 if ret <> 0:
54 return self.error('CPUCard ats error')
55 l = ord(ats_len.value)
56 r = ats_buffer.raw[:l]
57 #print codecs.encode(r,'hex')
58 return r
59
60 def error(self,error):
61 if py_decard.error_method == py_decard.ERROR_RET_NONE:
62 return None
63 raise CardOperatorError(error)
64
65
66 def open_port(self,port,baud):
67 if py_decard.dll_handle == None:
68 raise RuntimeError( py_decard.dll_name + ' not load ')
69 if py_decard.device_handle <> None:
70 return True
71
72 dev_handle = py_decard.dll_handle.dc_init(port,baud)
73 if dev_handle <= 0:
74 return False
75 py_decard.device_handle = dev_handle
76 return True
77
78 def close_port(self):
79 if py_decard.device_handle == None:
80 return
81 py_decard.dll_handle.dc_exit(py_decard.device_handle)
82 py_decard.device_handle = None
83
84 def request_card(self):
85 if self.card_mode == 'contactless':
86 py_decard.dll_handle.dc_reset(py_decard.device_handle,1)
87 cardphyno = create_string_buffer('\000' * 64)
88 ret = py_decard.dll_handle.dc_card_hex(py_decard.device_handle,
89 py_decard.MODE_ALL,
90 cardphyno)
91 if ret == 0:
92 return cardphyno.value
93 return self.error('Request Card Error')
94 else:
95 return ''
96
97 def cpucard_ats(self):
98 ats_buffer = create_string_buffer('\000' * 256)
99 ats_len = c_char('\000')
100 if self.card_mode == 'contactless':
101 py_decard.dll_handle.dc_pro_reset.restype = c_short
102 ret = py_decard.dll_handle.dc_pro_reset(py_decard.device_handle,byref(ats_len),ats_buffer)
103 if ret <> 0:
104 return self.error('CPUCard ats error')
105 l = ord(ats_len.value)
106 r = ats_buffer.raw[:l]
107 #print codecs.encode(r,'hex')
108 return r
109 else:
110 py_decard.dll_handle.dc_setcpu(py_decard.device_handle,self._get_sam_port(self.ic_port))
111 ret = py_decard.dll_handle.dc_cpureset(py_decard.device_handle,byref(ats_len),ats_buffer)
112 if ret <> 0:
113 return self.error('CPUCard ats error')
114 l = ord(ats_len.value)
115 r = ats_buffer.raw[:l]
116 #print codecs.encode(r,'hex')
117 return r
118
119 def _get_sam_port(self,port):
120 if port == 1:
121 return 0x0c
122 elif port == 2:
123 return 0x0d
124 elif port == 3:
125 return 0x0e
126 elif port == 4:
127 return 0x0f
128 else:
129 self.error('samport error')
130
131 def _do_apdu(self,command):
132 response = create_string_buffer('\000' * 256)
133 resplen = c_char('\000')
134 if self.card_mode == 'contactless':
135 py_decard.dll_handle.dc_pro_commandlink.restype = c_short
136 ret = py_decard.dll_handle.dc_pro_commandlink(py_decard.device_handle,len(command),
137 command,byref(resplen),response,7,56)
138 else:
139 ret = py_decard.dll_handle.dc_cpuapdu(py_decard.device_handle,len(command),
140 command,byref(resplen),response)
141
142 if ret <> 0:
143 command_header = codecs.encode(command,'hex')
144 return self.error('CPUCard apdu command : %s ,ret=%d' % (command_header,ret))
145 return response.raw[:ord(resplen.value)]
146
147 def cpucard_apdu(self,command):
148 current_resp = self._do_apdu(command)
149 if ord(current_resp[-2]) == 0x61 and ord(current_resp[-1]) > 0x00:
150 cmd = '\x00\xC0\x00\x00' + current_resp[-1]
151 #print "get response : %s" % codecs.encode(cmd,'hex')
152 return self._do_apdu(cmd)
153 else:
154 return current_resp
155
156 def cpucard_apdu_hex(self,command):
157 cmd_result = command.replace(' ','')
158 resp = self.cpucard_apdu(codecs.decode(cmd_result,'hex'))
159 if resp == None:
160 return None
161 return codecs.encode(resp,'hex').upper()
162
163 def _do_sam_apdu(self,command):
164 response = create_string_buffer('\000' * 256)
165 resplen = c_char('\000')
166 ret = py_decard.dll_handle.dc_cpuapdu(py_decard.device_handle,len(command),
167 command,byref(resplen),response)
168
169 if ret <> 0:
170 command_header = codecs.encode(command,'hex')
171 return self.error('CPUCard apdu command : %s ,ret=%d' % (command_header,ret))
172 return response.raw[:ord(resplen.value)]
173
174 def sam_apdu(self,command):
175 current_resp = self._do_sam_apdu(command)
176 if ord(current_resp[-2]) == 0x61 and ord(current_resp[-1]) > 0x00:
177 cmd = '\x00\xC0\x00\x00' + current_resp[-1]
178 #print "get response : %s" % codecs.encode(cmd,'hex')
179 return self._do_sam_apdu(cmd)
180 else:
181 return current_resp
182
183 def sam_apdu_hex(self,command):
184 cmd_result = command.replace(' ','')
185 resp = self.sam_apdu(codecs.decode(cmd_result,'hex'))
186 if resp == None:
187 return None
188 return codecs.encode(resp,'hex').upper()
189
190
191 def beep(self):
192 py_decard.dll_handle.dc_beep(py_decard.device_handle,10)
193