1 package com.android.cts.verifier.nfc.hce; 2 3 import android.annotation.TargetApi; 4 import android.content.ComponentName; 5 import android.content.Intent; 6 import android.nfc.cardemulation.HostApduService; 7 import android.os.Bundle; 8 import android.util.Log; 9 10 import java.util.Arrays; 11 12 @TargetApi(19) 13 public abstract class HceService extends HostApduService { 14 final static String TAG = "HceService"; 15 16 final static int STATE_IDLE = 0; 17 final static int STATE_IN_PROGRESS = 1; 18 final static int STATE_FAILED = 2; 19 20 // Variables below only used on main thread 21 String[] mCommandApdus = null; 22 String[] mResponseApdus = null; 23 int mApduIndex = 0; 24 int mState = STATE_IDLE; 25 long mStartTime; 26 27 public void initialize(String[] commandApdus, String[] responseApdus) { 28 mCommandApdus = commandApdus; 29 mResponseApdus = responseApdus; 30 } 31 32 @Override 33 public void onDeactivated(int arg0) { 34 mApduIndex = 0; 35 mState = STATE_IDLE; 36 } 37 38 public abstract ComponentName getComponent(); 39 40 public void onApduSequenceComplete() { 41 Intent completionIntent = new Intent(HceUtils.ACTION_APDU_SEQUENCE_COMPLETE); 42 completionIntent.putExtra(HceUtils.EXTRA_COMPONENT, getComponent()); 43 completionIntent.putExtra(HceUtils.EXTRA_DURATION, 44 System.currentTimeMillis() - mStartTime); 45 sendBroadcast(completionIntent); 46 } 47 48 public void onApduSequenceError() { 49 Intent errorIntent = new Intent(HceUtils.ACTION_APDU_SEQUENCE_ERROR); 50 sendBroadcast(errorIntent); 51 } 52 53 @Override 54 public byte[] processCommandApdu(byte[] arg0, Bundle arg1) { 55 if (mState == STATE_FAILED) { 56 // Don't accept any more APDUs until deactivated 57 return null; 58 } 59 60 if (mState == STATE_IDLE) { 61 mState = STATE_IN_PROGRESS; 62 mStartTime = System.currentTimeMillis(); 63 } 64 65 if (mApduIndex >= mCommandApdus.length) { 66 Log.d(TAG, "Ignoring command APDU; protocol complete."); 67 // Ignore new APDUs after completion 68 return null; 69 } else { 70 if (!Arrays.equals(HceUtils.hexStringToBytes(mCommandApdus[mApduIndex]), arg0)) { 71 Log.d(TAG, "Unexpected command APDU: " + HceUtils.getHexBytes("", arg0)); 72 onApduSequenceError(); 73 return null; 74 } else { 75 // Send corresponding response APDU 76 byte[] responseApdu = HceUtils.hexStringToBytes(mResponseApdus[mApduIndex]); 77 mApduIndex++; 78 if (mApduIndex == mCommandApdus.length) { 79 // Test passed 80 onApduSequenceComplete(); 81 } 82 return responseApdu; 83 } 84 } 85 } 86 } 87