Tang Cheng | 396e825 | 2012-07-03 13:21:11 +0800 | [diff] [blame] | 1 | # -*- coding: utf-8 -*-
|
| 2 | '''
|
| 3 | Created on 2011-9-29
|
Tang Cheng | e90e9bb | 2012-07-03 13:38:01 +0800 | [diff] [blame^] | 4 | 读卡库程序
|
Tang Cheng | 396e825 | 2012-07-03 13:21:11 +0800 | [diff] [blame] | 5 | @author: cheng.tang
|
| 6 | '''
|
| 7 | from ctypes import *
|
| 8 | import codecs
|
| 9 |
|
| 10 | class CardOperatorError(Exception):
|
| 11 | def __init__(self,msg):
|
| 12 | Exception.__init__(self,msg)
|
| 13 |
|
| 14 | class 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 |
|