|
@@ -0,0 +1,617 @@
|
|
|
+package com.yijia.zthandpos.pos.test;
|
|
|
+
|
|
|
+import android.graphics.Color;
|
|
|
+import android.os.Bundle;
|
|
|
+import android.os.Handler;
|
|
|
+import android.os.HandlerThread;
|
|
|
+import android.os.Looper;
|
|
|
+import android.os.Message;
|
|
|
+import android.text.method.ScrollingMovementMethod;
|
|
|
+import android.util.Log;
|
|
|
+import android.view.View;
|
|
|
+import android.view.View.OnClickListener;
|
|
|
+import android.view.Window;
|
|
|
+import android.widget.Button;
|
|
|
+import android.widget.TextView;
|
|
|
+
|
|
|
+import com.szzt.sdk.device.Constants;
|
|
|
+import com.szzt.sdk.device.card.ContactlessCardReader;
|
|
|
+import com.szzt.sdk.device.card.SmartCardReader;
|
|
|
+import com.szzt.sdk.device.emv.EMV_STATUS;
|
|
|
+import com.szzt.sdk.device.emv.EmvInterface;
|
|
|
+import com.szzt.sdk.device.pinpad.PinPad;
|
|
|
+import com.szzt.sdk.device.pinpad.PinPad.OnSendKeyListerner;
|
|
|
+import com.yijia.zthandpos.pos.BaseActivity;
|
|
|
+import com.yijia.zthandpos.pos.R;
|
|
|
+import com.yijia.zthandpos.pos.utils.HexDump;
|
|
|
+import com.yijia.zthandpos.pos.utils.MessageManager;
|
|
|
+import com.yijia.zthandpos.pos.utils.Shower;
|
|
|
+import com.yijia.zthandpos.pos.utils.StringUtil;
|
|
|
+import com.yijia.zthandpos.pos.utils.StringUtility;
|
|
|
+
|
|
|
+import java.io.BufferedReader;
|
|
|
+import java.io.InputStreamReader;
|
|
|
+import java.util.ArrayList;
|
|
|
+
|
|
|
+public class EMVActivity extends BaseActivity {
|
|
|
+ private static final int MSG_WAIT_FOR_CARD = 0;
|
|
|
+ private MessageManager messageManager;
|
|
|
+ private EmvInterface emvInterface;
|
|
|
+ private PinPad pinPad;
|
|
|
+ private Button mClearButton;
|
|
|
+ private Button mEmvStart;
|
|
|
+ private Button mEmvClose;
|
|
|
+ private Button mEmvElectronic;
|
|
|
+ private Button mElectronicCashInquiry;
|
|
|
+ private Button mEmvSetParam;
|
|
|
+ private HandlerThread mWaitForCardHandlerThread;
|
|
|
+ volatile boolean mIsWaitingForCard = false;
|
|
|
+ volatile boolean mHasCard = false;
|
|
|
+ private MyHandler myHandler;
|
|
|
+ private static ArrayList<byte[]> mAIDParams;
|
|
|
+ private static ArrayList<byte[]> mCAPKParams;
|
|
|
+
|
|
|
+ private static ArrayList<String> mAIDParamInString;
|
|
|
+ private static ArrayList<String> mCAPKParamInString;
|
|
|
+
|
|
|
+ private static String mTermInfo;
|
|
|
+ private Shower shower ;
|
|
|
+ private byte mTransType=EmvInterface.TRANS_GOODS_SERVICE;
|
|
|
+ private static final int EMV_WAIT_CARD = 113;
|
|
|
+ private static final int EMV_ELECTRO_CASH_WAIT_CARD = 114;
|
|
|
+ private static final int EMV_ELECT_TRANS_WAIT_CARD = 115;
|
|
|
+ private class MyHandler extends Handler {
|
|
|
+ public MyHandler(Looper looper) {
|
|
|
+ super(looper);
|
|
|
+ }
|
|
|
+ public void handleMessage(Message m) {
|
|
|
+ int what = m.what;
|
|
|
+ if(what == EmvInterface.EMV_PROCESS_MSG){
|
|
|
+ int status = m.arg1;
|
|
|
+ int retcode = m.arg2;
|
|
|
+ EmvTest(status,retcode);
|
|
|
+ }else if(what == EmvInterface.EMV_CARD_MSG){
|
|
|
+ int removed = m.arg1;
|
|
|
+ if(removed == EmvInterface.CARD_REMOVED){
|
|
|
+
|
|
|
+ }
|
|
|
+ }else if (what == MSG_WAIT_FOR_CARD) {
|
|
|
+ }else if (what == EMV_WAIT_CARD) {
|
|
|
+ messageManager.AppendInfoMessageInUiThread(shower.getString(R.string.msg_emv_wait_card),
|
|
|
+ Color.GREEN);
|
|
|
+ }else if(what == EMV_ELECTRO_CASH_WAIT_CARD)
|
|
|
+ {
|
|
|
+ messageManager.AppendInfoMessageInUiThread(shower.getString(R.string.info_get_electro_cash),
|
|
|
+ Color.GREEN);
|
|
|
+ }else if(what == EMV_ELECT_TRANS_WAIT_CARD)
|
|
|
+ {
|
|
|
+ messageManager.AppendInfoMessageInUiThread(shower.getString(R.string.info_emv_elect_trans_wait_card),
|
|
|
+ Color.GREEN);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ private final Handler handler=new Handler(Looper.getMainLooper());
|
|
|
+ //接触卡 isEmvInit:true 电子现金 ; false:联机交易
|
|
|
+ private void smart_emv(boolean isEmvInit){
|
|
|
+ if (!mIsWaitingForCard) {
|
|
|
+ mIsWaitingForCard = true;
|
|
|
+ int result = smartCardReader.waitForCard(0, Constants.WAIT_INFINITE);
|
|
|
+ if (result < 0) {
|
|
|
+ messageManager.AppendInfoMessageInUiThread(shower.getString(R.string.info_card_contact)+shower.getString(R.string.msg_card_read_error));
|
|
|
+ } else {
|
|
|
+ contactlessCardReader.close();
|
|
|
+ messageManager.AppendInfoMessageInUiThread("Contact card");
|
|
|
+ byte[] data=new byte[256];
|
|
|
+ int ret=smartCardReader.powerOn(0, data);
|
|
|
+ if(ret>0){
|
|
|
+ if(!isEmvInit)
|
|
|
+ {
|
|
|
+ smart();
|
|
|
+ }else{
|
|
|
+ EmvInit(data, EmvInterface.READER_TYPE_CONTACT_CARD);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+ mIsWaitingForCard = false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private void smart(){
|
|
|
+ emvInterface.setForceOnline(1);
|
|
|
+ emvInterface.initialize(myHandler);
|
|
|
+ byte[] term = HexDump.hexStringToByteArray("9F660436800080");
|
|
|
+ emvInterface.setTerminalParam(term);
|
|
|
+ emvInterface.preprocess(1);
|
|
|
+ emvInterface.setCardType( EmvInterface.READER_TYPE_CONTACT_CARD);
|
|
|
+ emvInterface.setTransAmount(1);
|
|
|
+ emvInterface.setTransType(EmvInterface.TRANS_GOODS_SERVICE);
|
|
|
+ emvInterface.process();
|
|
|
+ }
|
|
|
+ private void EmvInit(byte[] atr,int result) {
|
|
|
+ emvInterface.initialize(myHandler);
|
|
|
+ emvInterface.preprocess(0);
|
|
|
+ emvInterface.setTransAmount(1);
|
|
|
+ emvInterface.setCardType(result);
|
|
|
+ emvInterface.setTransType(mTransType);
|
|
|
+ emvInterface.process();
|
|
|
+ }
|
|
|
+ //非接卡 isEmvInit:false电子现金 ;true:联机交易
|
|
|
+ volatile boolean mIsWaitingForCard2 = false;
|
|
|
+ private void contact_emv(boolean isEmvInit){
|
|
|
+ if (!mIsWaitingForCard2) {
|
|
|
+ mIsWaitingForCard2 = true;
|
|
|
+ int result = contactlessCardReader.waitForCard(Constants.WAIT_INFINITE);
|
|
|
+ if (result < 0) {
|
|
|
+ messageManager.AppendInfoMessageInUiThread(shower.getString(R.string.info_card_contactless)+shower.getString(R.string.msg_card_read_error));
|
|
|
+
|
|
|
+ } else {
|
|
|
+ smartCardReader.close();
|
|
|
+ handler.post(new Runnable() {
|
|
|
+ @Override
|
|
|
+ public void run() {
|
|
|
+ messageManager.AppendInfoMessage("Contactless card");
|
|
|
+ }
|
|
|
+ });
|
|
|
+ byte[] data=new byte[256];
|
|
|
+ int ret=contactlessCardReader.powerOn( data);
|
|
|
+ if(ret>0){
|
|
|
+ if(!isEmvInit)
|
|
|
+ {
|
|
|
+ emvInterface.setForceOnline(1);
|
|
|
+ emvInterface.initialize(myHandler);
|
|
|
+ byte[] term = HexDump.hexStringToByteArray("9F660436800080");
|
|
|
+ emvInterface.setTerminalParam(term);
|
|
|
+ emvInterface.preprocess(1);
|
|
|
+ emvInterface.setCardType( EmvInterface.READER_TYPE_CONTACTLESS_CARD);
|
|
|
+ emvInterface.setTransAmount(1);
|
|
|
+ emvInterface.setTransType(EmvInterface.TRANS_GOODS_SERVICE);
|
|
|
+ emvInterface.process();
|
|
|
+ }else{
|
|
|
+ EmvInit(data, EmvInterface.READER_TYPE_CONTACTLESS_CARD);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ mIsWaitingForCard2 = false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ protected void onCreate(Bundle savedInstanceState) {
|
|
|
+ super.onCreate(savedInstanceState);
|
|
|
+ requestWindowFeature(Window.FEATURE_NO_TITLE);
|
|
|
+ setContentView(R.layout.activity_emv);
|
|
|
+ shower = new Shower(this);
|
|
|
+ boolean isConnected = mainApplication.isDeviceManagerConnetcted();
|
|
|
+ init(isConnected);
|
|
|
+ loadEmvParam();
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void onResume() {
|
|
|
+ messageManager.AppendInfoMessage(shower.getString(R.string.test_emv));
|
|
|
+ if (mWaitForCardHandlerThread == null) {
|
|
|
+ mWaitForCardHandlerThread = new HandlerThread("wait_for_card");
|
|
|
+ }
|
|
|
+ mWaitForCardHandlerThread.start();
|
|
|
+ myHandler = new MyHandler(mWaitForCardHandlerThread.getLooper());
|
|
|
+ super.onResume();
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void onDestroy() {
|
|
|
+ emvInterface.processExit();
|
|
|
+ myHandler.removeMessages(MSG_WAIT_FOR_CARD);
|
|
|
+ myHandler.getLooper().quit();
|
|
|
+ myHandler = null;
|
|
|
+ mWaitForCardHandlerThread = null;
|
|
|
+ mIsWaitingForCard = false;
|
|
|
+ mIsWaitingForCard2 = false ;
|
|
|
+ pinPad.close();
|
|
|
+ super.onDestroy();
|
|
|
+ }
|
|
|
+
|
|
|
+ private SmartCardReader smartCardReader = null ;
|
|
|
+ private ContactlessCardReader contactlessCardReader = null ;
|
|
|
+ private void init(boolean isConnected) {
|
|
|
+ if (messageManager == null) {
|
|
|
+ TextView text = (TextView) findViewById(R.id.emv_text);
|
|
|
+ text.setMovementMethod(ScrollingMovementMethod.getInstance());
|
|
|
+ messageManager = new MessageManager(this, text);
|
|
|
+ mClearButton = (Button) findViewById(R.id.emv_clear);
|
|
|
+ mClearButton.setOnClickListener(listener);
|
|
|
+ mEmvStart = (Button) findViewById(R.id.emv_start);
|
|
|
+ mEmvStart.setOnClickListener(listener);
|
|
|
+ mEmvClose = (Button) findViewById(R.id.emv_stop);
|
|
|
+ mEmvClose.setOnClickListener(listener);
|
|
|
+ mEmvElectronic = (Button) findViewById(R.id.emv_electronic_cash);
|
|
|
+ mEmvElectronic.setOnClickListener(listener);
|
|
|
+ mElectronicCashInquiry = (Button) findViewById(R.id.emv_electronic_cash_inquiry);
|
|
|
+ mElectronicCashInquiry.setOnClickListener(listener);
|
|
|
+ mEmvSetParam = (Button) findViewById(R.id.emv_set_param);
|
|
|
+ mEmvSetParam.setOnClickListener(listener);
|
|
|
+ emvInterface = mainApplication.getEmvInterface();
|
|
|
+ smartCardReader = mainApplication.getSmartCardReader();
|
|
|
+ contactlessCardReader = mainApplication.getContactlessCardReader();
|
|
|
+ pinPad = mainApplication.getPinPad();
|
|
|
+ }
|
|
|
+ mClearButton.setEnabled(isConnected);
|
|
|
+ mEmvStart.setEnabled(isConnected);
|
|
|
+ mEmvClose.setEnabled(isConnected);
|
|
|
+ }
|
|
|
+
|
|
|
+ private final OnClickListener listener = new OnClickListener() {
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void onClick(View v) {
|
|
|
+ switch (v.getId()) {
|
|
|
+ case R.id.emv_clear:
|
|
|
+ messageManager.clear();
|
|
|
+ break;
|
|
|
+ //联机交易
|
|
|
+ case R.id.emv_start:
|
|
|
+ myHandler.sendEmptyMessage(EMV_WAIT_CARD);
|
|
|
+ mTransType=EmvInterface.TRANS_GOODS_SERVICE;
|
|
|
+ openCardRead(false);
|
|
|
+ break;
|
|
|
+ //电子现金查询
|
|
|
+ case R.id.emv_electronic_cash_inquiry:
|
|
|
+ myHandler.sendEmptyMessage(EMV_ELECTRO_CASH_WAIT_CARD);
|
|
|
+ mTransType = (byte) 0xF4;
|
|
|
+ openCardRead(true);
|
|
|
+ break;
|
|
|
+ //电子现金交易
|
|
|
+ case R.id.emv_electronic_cash:
|
|
|
+ myHandler.sendEmptyMessage(EMV_ELECT_TRANS_WAIT_CARD);
|
|
|
+ mTransType=EmvInterface.TRANS_GOODS_SERVICE;
|
|
|
+ openCardRead(true);
|
|
|
+ break;
|
|
|
+ //设置参数
|
|
|
+ case R.id.emv_set_param:
|
|
|
+ emvSetParam();
|
|
|
+ break;
|
|
|
+ //停止测试
|
|
|
+ case R.id.emv_stop:
|
|
|
+ closeReader();
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ //非接卡、接触卡
|
|
|
+ private void openCardRead(final boolean isEmvInit){
|
|
|
+ int res = smartCardReader.open(0, new SmartCardReader.SCReaderListener() {
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void notify(int nSlotIndex, int nEvent) {
|
|
|
+
|
|
|
+ }
|
|
|
+ });
|
|
|
+ if(res>=0){
|
|
|
+ new Thread(){
|
|
|
+ public void run(){
|
|
|
+ smart_emv(isEmvInit);
|
|
|
+ }
|
|
|
+ }.start();
|
|
|
+ }
|
|
|
+
|
|
|
+ int res2 = contactlessCardReader.open();
|
|
|
+ if(res2>=0){
|
|
|
+ new Thread(){
|
|
|
+ public void run(){
|
|
|
+ contact_emv(isEmvInit);
|
|
|
+ }
|
|
|
+ }.start();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ //设置参数
|
|
|
+ private void emvSetParam(){
|
|
|
+ new Thread(new Runnable() {
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void run() {
|
|
|
+ loadEmvParam();
|
|
|
+ setEmvParam();
|
|
|
+ }
|
|
|
+ }).start();
|
|
|
+ }
|
|
|
+ private void loadEmvParam(){
|
|
|
+ if(mAIDParams == null){
|
|
|
+ mAIDParams = new ArrayList<byte[]>();
|
|
|
+ mCAPKParams = new ArrayList<byte[]>();
|
|
|
+ mAIDParamInString = new ArrayList<String>();
|
|
|
+ mCAPKParamInString = new ArrayList<String>();
|
|
|
+ }
|
|
|
+ if(mAIDParams.size() != 0 || mCAPKParams.size() != 0){
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ try {
|
|
|
+ InputStreamReader inputReader = new InputStreamReader(
|
|
|
+ getResources().openRawResource(R.raw.params));
|
|
|
+ BufferedReader bufferedReader = new BufferedReader(inputReader);
|
|
|
+ ArrayList<byte[]> activeList = null;
|
|
|
+ ArrayList<String> stringList = null;
|
|
|
+ while(true){
|
|
|
+ String line = bufferedReader.readLine();
|
|
|
+ if(line == null)
|
|
|
+ break;
|
|
|
+ if(line.startsWith("AID=")){
|
|
|
+ activeList = mAIDParams;
|
|
|
+ stringList = mAIDParamInString;
|
|
|
+ continue;
|
|
|
+ }else if(line.startsWith("CAPK=")){
|
|
|
+ activeList = mCAPKParams;
|
|
|
+ stringList = mCAPKParamInString;
|
|
|
+ continue;
|
|
|
+ }else if(line.startsWith("TERM=")){
|
|
|
+ line = bufferedReader.readLine();
|
|
|
+ mTermInfo = line;
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ stringList.add(line);
|
|
|
+ byte[] data = StringUtil.hexString2bytes(line);
|
|
|
+ activeList.add(data);
|
|
|
+ }
|
|
|
+ bufferedReader.close();
|
|
|
+ inputReader.close();
|
|
|
+ } catch (Exception e) {
|
|
|
+ messageManager.AppendInfoMessageInUiThread(
|
|
|
+ shower.getString(R.string.msg_emv_load_para_error) + e.getMessage());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private void setEmvParam() {
|
|
|
+ int index = 0;
|
|
|
+ for(byte[] param:mAIDParams){
|
|
|
+ int nret = emvInterface.updateAidParam(1, param);
|
|
|
+ messageManager.AppendInfoMessageInUiThread(shower.getString(R.string.msg_emv_init_aid) + (index)
|
|
|
+ +"]=" + mAIDParamInString.get(index++) + " = " + nret);
|
|
|
+ }
|
|
|
+ index = 0;
|
|
|
+ for(byte[] param:mCAPKParams){
|
|
|
+ int nret = emvInterface.updateCAPKParam(1, param);
|
|
|
+ messageManager.AppendInfoMessageInUiThread(shower.getString(R.string.msg_emv_init_capk) + (index)
|
|
|
+ +"]=" + mCAPKParamInString.get(index++) + " = " + nret);
|
|
|
+ }
|
|
|
+ if(mTermInfo != null){
|
|
|
+ int nret = emvInterface.setTerminalParam(StringUtil.hexString2bytes(mTermInfo));
|
|
|
+ messageManager.AppendInfoMessageInUiThread(shower.getString(R.string.msg_emv_init_teminal)+nret);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private void EmvTest(int status,int retcode) {
|
|
|
+ Log.e("EmvTest", "status:"+status+" retcode:"+retcode);
|
|
|
+ if(status == EmvInterface.STATUS_CONTINUE){
|
|
|
+ switch(retcode){
|
|
|
+ //请求选择候选应用列表
|
|
|
+ case EMV_STATUS.EMV_REQ_SEL_CANDIDATES:
|
|
|
+ //请求再次选择候选列表
|
|
|
+ case EMV_STATUS.EMV_REQ_SEL_CANDIDATES_AGAIN:
|
|
|
+ byte[] candidateList = new byte[300];
|
|
|
+ int length = emvInterface.getCardCandidateList(candidateList);
|
|
|
+ if(length <= 0){
|
|
|
+ emvInterface.process();
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ int nret = emvInterface.setCardCandidateListResult(10);
|
|
|
+ messageManager.AppendInfoMessageInUiThread(shower.getString(R.string.msg_emv_sum_up)+length +
|
|
|
+ shower.getString(R.string.msg_emv_apps) + shower.getString(R.string.msg_emv_chose_app)
|
|
|
+ + nret);
|
|
|
+ emvInterface.process();
|
|
|
+ break;
|
|
|
+ //请求持卡人输入联机pin
|
|
|
+ case EMV_STATUS.EMV_REQ_ONLINE_PIN:
|
|
|
+ //输入联机pin
|
|
|
+ onlinePinPad();
|
|
|
+ break;
|
|
|
+ //请求联机交易
|
|
|
+ case EMV_STATUS.EMV_REQ_GO_ONLINE:
|
|
|
+ byte[] data=new byte[256];
|
|
|
+ byte[] recvFiled55=new byte[256];
|
|
|
+ int index=0;
|
|
|
+ int[] tag=new int[]{0x82,0x84,0x95,0x9F26,0x9F27,0x9F10,0x9F37,0x9F36,0x9A,0x9C,0x9F02,0x5F2A,0x9F1A,0x9F03,0x9F33,0x9F34,0x9F35,0x9F1E,0x9F09,0x9F41};
|
|
|
+ for(int i=0;i<tag.length;i++){
|
|
|
+ int len=emvInterface.getTagData(tag[i], data);
|
|
|
+ if(len>0){
|
|
|
+ Log.e("tag", tag[i]+"-->"+StringUtility.ByteArrayToString(data, len));
|
|
|
+ int tagIndex;
|
|
|
+ if(tag[i]>0xFF){
|
|
|
+ Log.e("status", "status-->"+(tag[i]>>8)+"-->"+(tag[i]<<8));
|
|
|
+ tagIndex=recvFiled55[index++]=(byte)(tag[i]/0xff);
|
|
|
+ }
|
|
|
+ recvFiled55[index++]=(byte)(tag[i]&0xff);
|
|
|
+ recvFiled55[index++]=(byte) len;
|
|
|
+ System.arraycopy(data, 0, recvFiled55, index, len);
|
|
|
+ index+=len;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ byte[] filed55=new byte[index];
|
|
|
+ System.arraycopy(recvFiled55, 0, filed55, 0, index);
|
|
|
+ emvInterface.setOnlineResult(2, filed55, filed55.length);
|
|
|
+ emvInterface.process();
|
|
|
+ break;
|
|
|
+ //得到卡号
|
|
|
+ case EMV_STATUS.EMV_REQ_CARD_CONFIRM:
|
|
|
+ byte[] tagData = new byte[100];
|
|
|
+ int tagDataLength = emvInterface.getTagData(0x57, tagData);
|
|
|
+ cardNumber = StringUtility.getStringFormat(tagData, tagDataLength);
|
|
|
+ messageManager.AppendInfoMessageInUiThread(shower.getString(R.string.msg_emv_card_num)
|
|
|
+ + cardNumber);
|
|
|
+ emvInterface.process();
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ emvInterface.process();
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ //完成状态
|
|
|
+ else if(status == EmvInterface.STATUS_COMPLETION){
|
|
|
+ messageManager.AppendInfoMessageInUiThread(shower.getString(R.string.msg_emv_trade_over));
|
|
|
+ //电子现金余额查询
|
|
|
+ if ((mTransType & 0xFF) == 0xF4) {
|
|
|
+ if (retcode == 100) {
|
|
|
+ byte[] temp = new byte[32];
|
|
|
+ String amount = "0.00";
|
|
|
+ emvInterface.getICCTagData(0x9F79, temp);
|
|
|
+ int ret = emvInterface.getTagData(0x9F79, temp);
|
|
|
+ if (ret >= 0) {
|
|
|
+ amount = HexDump.decBytesToHex(temp, ret);
|
|
|
+ }
|
|
|
+ messageManager.AppendInfoMessageInUiThread(shower.getString(R.string.info_emv_elect_cash_balance)
|
|
|
+ + String.format("%.2f",
|
|
|
+ Integer.parseInt(amount) * 1.0 / 100));
|
|
|
+ }
|
|
|
+ }else if ((mTransType & 0xFF) == 0xF0){
|
|
|
+ if (retcode == 100){
|
|
|
+ byte[] sum = new byte[1];
|
|
|
+ emvInterface.getTransLog(0x101, sum);
|
|
|
+ System.out.println("sum:" + sum[0]);
|
|
|
+ byte[] fmt_dol = new byte[60];
|
|
|
+ byte[] rec_val = new byte[256];
|
|
|
+ for (int i=1; i<=sum[0]; i++){
|
|
|
+ int index = 0;
|
|
|
+
|
|
|
+ int len = emvInterface.getTransLog(0x102, fmt_dol);
|
|
|
+ System.out.println("fmt_dol:" + HexDump.decBytesToHex(fmt_dol));
|
|
|
+
|
|
|
+ len = emvInterface.getTransLog(i, rec_val);
|
|
|
+ System.out.println("rec_val:" + HexDump.decBytesToHex(rec_val, len));
|
|
|
+
|
|
|
+ StringBuffer stringBuffer = new StringBuffer();
|
|
|
+
|
|
|
+ index = 0;
|
|
|
+ stringBuffer.append("9A03");
|
|
|
+ stringBuffer.append(HexDump.toHexString(rec_val, index, 3));
|
|
|
+ index += 3;
|
|
|
+ stringBuffer.append("9F2103");
|
|
|
+ stringBuffer.append(HexDump.toHexString(rec_val, index, 3));
|
|
|
+ index += 3;
|
|
|
+ stringBuffer.append("9F0206");
|
|
|
+ stringBuffer.append(HexDump.toHexString(rec_val, index, 6));
|
|
|
+ index += 6;
|
|
|
+ index += 6;
|
|
|
+ stringBuffer.append("9F1A02");
|
|
|
+ stringBuffer.append(HexDump.toHexString(rec_val, index, 2));
|
|
|
+ index += 2;
|
|
|
+ stringBuffer.append("5F2A02");
|
|
|
+ stringBuffer.append(HexDump.toHexString(rec_val, index, 2));
|
|
|
+
|
|
|
+ index += 2;
|
|
|
+ stringBuffer.append("9F4E14");
|
|
|
+ stringBuffer.append(HexDump.toHexString(rec_val, index, 20));
|
|
|
+ index += 20;
|
|
|
+ stringBuffer.append("9C01");
|
|
|
+ stringBuffer.append(HexDump.toHexString(rec_val, index, 1));
|
|
|
+ index += 1;
|
|
|
+ stringBuffer.append("9F3602");
|
|
|
+ stringBuffer.append(HexDump.toHexString(rec_val, index, 2));
|
|
|
+
|
|
|
+ messageManager.AppendInfoMessageInUiThread(stringBuffer.toString());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }else if ((mTransType & 0xFF) == 0xF2){
|
|
|
+ if (retcode == 100){
|
|
|
+ String cardSN = "0" + HexDump.decBytesToHex(getTag(0x5F34));
|
|
|
+ System.out.println("cardSN:" + cardSN);
|
|
|
+ String cardNO = HexDump.decBytesToHex(getTag(0x5A));
|
|
|
+ System.out.println("cardNO:" + cardNO);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ byte[] data=new byte[1024];
|
|
|
+ emvInterface.getTransLog(0, data);
|
|
|
+ }else if(status == EmvInterface.STATUS_ERROR){
|
|
|
+ messageManager.AppendInfoMessageInUiThread("Ic error");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ //获取交易日志
|
|
|
+ private byte[] getTag(int tagInt){
|
|
|
+ byte[] temp = new byte[256];
|
|
|
+ byte[] result = null;
|
|
|
+ int ret = emvInterface.getTagData(tagInt, temp);
|
|
|
+ if (ret <= 0) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ result = new byte[ret];
|
|
|
+ System.arraycopy(temp, 0, result, 0, ret);
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+ private String cardNumber = "";
|
|
|
+ private final int mainKey = 2;
|
|
|
+ //密码键盘
|
|
|
+ private void onlinePinPad() {
|
|
|
+ int ret = pinPad.open(new OnSendKeyListerner() {
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void onSendKey(int keyCode) {
|
|
|
+ messageManager.AppendInfoMessageInUiThread("keyCode-->"+keyCode);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ if(ret >=0)
|
|
|
+ {
|
|
|
+ updateMainKey();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ //下载主密钥
|
|
|
+ private void updateMainKey() {
|
|
|
+ byte[] oldKey = HexDump.hexStringToByteArray("701A5B3D7F6E891C56A46A18C1CD5C0A");
|
|
|
+ byte[] newkey = HexDump.hexStringToByteArray("701A5B3D7F6E891C56A46A18C1CD5C0A");
|
|
|
+ int ret = pinPad.updateMasterKey(mainKey, oldKey, newkey);
|
|
|
+ if(ret >=0)
|
|
|
+ updateWorkKey();
|
|
|
+ else
|
|
|
+ closePinpad(1);
|
|
|
+ }
|
|
|
+ private void closePinpad(int type){
|
|
|
+ if(type == 1)
|
|
|
+ messageManager.AppendInfoMessageInUiThread(shower.getString(R.string.msg_pinpad_main_key_error));
|
|
|
+ else if(type == 2)
|
|
|
+ messageManager.AppendInfoMessageInUiThread(shower.getString(R.string.msg_pinpad_wk_error));
|
|
|
+ pinPad.close();
|
|
|
+ }
|
|
|
+ //下载工作密钥
|
|
|
+ private void updateWorkKey() {
|
|
|
+ byte[] pinkey = HexDump.hexStringToByteArray("5A7C9B2D21EDF2907ED9F72A5CFB6EC5");
|
|
|
+ int ret = pinPad.updateUserKey(mainKey, 0,mainKey, pinkey);
|
|
|
+ if(ret >=0)
|
|
|
+ pinPadOnline();
|
|
|
+ else
|
|
|
+ closePinpad(2);
|
|
|
+ }
|
|
|
+ //获取联机pin
|
|
|
+ private void pinPadOnline() {
|
|
|
+ int limit = pinPad.setPinLimit(new byte[]{4,6,8});
|
|
|
+ messageManager.AppendInfoMessageInUiThread("setLimit:"+limit);
|
|
|
+ byte[] arryASCIICardNumber = cardNumber.getBytes();
|
|
|
+ int nTimeout_MS = 10000;
|
|
|
+ int nFlagSound = 1;
|
|
|
+ messageManager.AppendInfoMessageInUiThread(shower.getString(R.string.info_emv_input_pwd));
|
|
|
+ pinPad.calculatePinBlock(mainKey, arryASCIICardNumber, nTimeout_MS, nFlagSound,new PinPad.OnInputResultListener() {
|
|
|
+ @Override
|
|
|
+ public void onInputResult(int ret, byte[] result) {
|
|
|
+ if(ret>0){
|
|
|
+ messageManager.AppendInfoMessageInUiThread("result-->"+StringUtility.ByteArrayToString(result, ret));
|
|
|
+ emvInterface.setOnlinePinEntered(0,new byte[]{1,2,3,4,5,6,7,8},8);
|
|
|
+ int t = emvInterface.process();
|
|
|
+ messageManager.AppendInfoMessageInUiThread(shower.getString(R.string.info_emv_transformation_ret)+t);
|
|
|
+ }else{
|
|
|
+ messageManager.AppendInfoMessageInUiThread("pin"+shower.getString(R.string.btn_pinpad_encrypt)+shower.getString(R.string.info_failed));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ private void closeReader(){
|
|
|
+ boolean flag = false;
|
|
|
+ flag = contactlessCardReader.close() >=0;
|
|
|
+ flag &= smartCardReader.close()>=0;
|
|
|
+ if(flag)
|
|
|
+ {
|
|
|
+ messageManager.AppendInfoMessageInUiThread(shower.getString(R.string.btn_emv_close)+shower.getString(R.string.info_success));
|
|
|
+ }else{
|
|
|
+ messageManager.AppendInfoMessageInUiThread(shower.getString(R.string.btn_emv_close)+shower.getString(R.string.info_failed));
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|