blob: 188e9a24dd1c018e2417dc9e98b6aefce0d378fd [file] [log] [blame]
# -*- coding: utf-8 -*-
'''
Created on 2011-9-29
读卡库程序
@author: cheng.tang
'''
from ctypes import *
import codecs
class CardOperatorError(Exception):
def __init__(self,msg):
Exception.__init__(self,msg)
class py_decard:
MODE_ALL = 1
MODE_IDLE = 0
ERROR_RET_NONE = 0
ERROR_RAISE_EXP = 1
dll_handle = None
dll_name = 'dcrf32.dll'
device_handle = None
error_method = ERROR_RET_NONE
@staticmethod
def _do_load_dll():
if py_decard.dll_handle <> None:
return
py_decard.dll_handle = windll.LoadLibrary(py_decard.dll_name)
@staticmethod
def setup(**kwdargs):
if kwdargs.has_key("error_method"):
py_decard.error_method = kwdargs["error_method"]
####################################################################
def __init__(self):
py_decard._do_load_dll()
self.card_mode = 'contactless'
self.ic_port = 0
def set_card_mode(self,mode='cotactless',icport=-1):
self.card_mode = mode
if self.card_mode <> 'contactless':
self.ic_port = icport
def setsamport(self,port):
self.sam_port = self._get_sam_port(port)
ats_buffer = create_string_buffer('\000' * 256)
ats_len = c_char('\000')
py_decard.dll_handle.dc_setcpu(py_decard.device_handle,self.sam_port)
ret = py_decard.dll_handle.dc_cpureset(py_decard.device_handle,byref(ats_len),ats_buffer)
if ret <> 0:
return self.error('CPUCard ats error')
l = ord(ats_len.value)
r = ats_buffer.raw[:l]
#print codecs.encode(r,'hex')
return r
def error(self,error):
if py_decard.error_method == py_decard.ERROR_RET_NONE:
return None
raise CardOperatorError(error)
def open_port(self,port,baud):
if py_decard.dll_handle == None:
raise RuntimeError( py_decard.dll_name + ' not load ')
if py_decard.device_handle <> None:
return True
dev_handle = py_decard.dll_handle.dc_init(port,baud)
if dev_handle <= 0:
return False
py_decard.device_handle = dev_handle
return True
def close_port(self):
if py_decard.device_handle == None:
return
py_decard.dll_handle.dc_exit(py_decard.device_handle)
py_decard.device_handle = None
def request_card(self):
if self.card_mode == 'contactless':
py_decard.dll_handle.dc_reset(py_decard.device_handle,1)
cardphyno = create_string_buffer('\000' * 64)
ret = py_decard.dll_handle.dc_card_hex(py_decard.device_handle,
py_decard.MODE_ALL,
cardphyno)
if ret == 0:
return cardphyno.value
return self.error('Request Card Error')
else:
return ''
def cpucard_ats(self):
ats_buffer = create_string_buffer('\000' * 256)
ats_len = c_char('\000')
if self.card_mode == 'contactless':
py_decard.dll_handle.dc_pro_reset.restype = c_short
ret = py_decard.dll_handle.dc_pro_reset(py_decard.device_handle,byref(ats_len),ats_buffer)
if ret <> 0:
return self.error('CPUCard ats error')
l = ord(ats_len.value)
r = ats_buffer.raw[:l]
#print codecs.encode(r,'hex')
return r
else:
py_decard.dll_handle.dc_setcpu(py_decard.device_handle,self._get_sam_port(self.ic_port))
ret = py_decard.dll_handle.dc_cpureset(py_decard.device_handle,byref(ats_len),ats_buffer)
if ret <> 0:
return self.error('CPUCard ats error')
l = ord(ats_len.value)
r = ats_buffer.raw[:l]
#print codecs.encode(r,'hex')
return r
def _get_sam_port(self,port):
if port == 1:
return 0x0c
elif port == 2:
return 0x0d
elif port == 3:
return 0x0e
elif port == 4:
return 0x0f
else:
self.error('samport error')
def _do_apdu(self,command):
response = create_string_buffer('\000' * 256)
resplen = c_char('\000')
if self.card_mode == 'contactless':
py_decard.dll_handle.dc_pro_commandlink.restype = c_short
ret = py_decard.dll_handle.dc_pro_commandlink(py_decard.device_handle,len(command),
command,byref(resplen),response,7,56)
else:
ret = py_decard.dll_handle.dc_cpuapdu(py_decard.device_handle,len(command),
command,byref(resplen),response)
if ret <> 0:
command_header = codecs.encode(command,'hex')
return self.error('CPUCard apdu command : %s ,ret=%d' % (command_header,ret))
return response.raw[:ord(resplen.value)]
def cpucard_apdu(self,command):
current_resp = self._do_apdu(command)
if ord(current_resp[-2]) == 0x61 and ord(current_resp[-1]) > 0x00:
cmd = '\x00\xC0\x00\x00' + current_resp[-1]
#print "get response : %s" % codecs.encode(cmd,'hex')
return self._do_apdu(cmd)
else:
return current_resp
def cpucard_apdu_hex(self,command):
cmd_result = command.replace(' ','')
resp = self.cpucard_apdu(codecs.decode(cmd_result,'hex'))
if resp == None:
return None
return codecs.encode(resp,'hex').upper()
def _do_sam_apdu(self,command):
response = create_string_buffer('\000' * 256)
resplen = c_char('\000')
ret = py_decard.dll_handle.dc_cpuapdu(py_decard.device_handle,len(command),
command,byref(resplen),response)
if ret <> 0:
command_header = codecs.encode(command,'hex')
return self.error('CPUCard apdu command : %s ,ret=%d' % (command_header,ret))
return response.raw[:ord(resplen.value)]
def sam_apdu(self,command):
current_resp = self._do_sam_apdu(command)
if ord(current_resp[-2]) == 0x61 and ord(current_resp[-1]) > 0x00:
cmd = '\x00\xC0\x00\x00' + current_resp[-1]
#print "get response : %s" % codecs.encode(cmd,'hex')
return self._do_sam_apdu(cmd)
else:
return current_resp
def sam_apdu_hex(self,command):
cmd_result = command.replace(' ','')
resp = self.sam_apdu(codecs.decode(cmd_result,'hex'))
if resp == None:
return None
return codecs.encode(resp,'hex').upper()
def beep(self):
py_decard.dll_handle.dc_beep(py_decard.device_handle,10)