I'm trying to read a smartcard via my LG P710 Optimus L7 2.
I'm following this tutorial
I can select the "1PAY.SYS.DDF01" directory
I can select the Application
But I can't perform an "GET PROCESSING OPTIONS" It always result in an 6700 error (Lc or Le wrong)
here is my code
NfcAdapter mNFCAdapter;
Intent intent;
PendingIntent pendingIntent;
private TextView mTextView;
String[][] techList;
IntentFilter[] filters = new IntentFilter[3];
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mTextView = (TextView) findViewById(R.id.title);
mNFCAdapter = NfcAdapter.getDefaultAdapter(this);
intent = new Intent(getApplicationContext(), getClass());
intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
pendingIntent = PendingIntent.getActivity(getApplicationContext(), 0, intent, 0);
techList = new String[][]{
new String[]
{ MifareClassic.class.getName() },
new String[]
{ IsoDep.class.getName() }
};
filters[0] = new IntentFilter();
filters[0].addAction(NfcAdapter.ACTION_NDEF_DISCOVERED);
filters[0].addCategory(Intent.CATEGORY_DEFAULT);
// add type of tag data you want to have - here ndef -> plain text
try {
filters[0].addDataType(MIME_TEXT_PLAIN);
} catch (MalformedMimeTypeException e) {
e.printStackTrace();
}
filters[1] = new IntentFilter();
filters[1].addAction(NfcAdapter.ACTION_TAG_DISCOVERED);
filters[1].addCategory(Intent.CATEGORY_DEFAULT);
filters[2] = new IntentFilter();
filters[2].addAction(NfcAdapter.ACTION_TECH_DISCOVERED);
filters[2].addCategory(Intent.CATEGORY_DEFAULT);
}
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
String action = intent.getAction();
mTextView.setText(action);
Toast.makeText(getApplicationContext(), action, Toast.LENGTH_SHORT).show();
Tag tagFromIntent = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
IsoDep tagIsoDep;
if((tagIsoDep = IsoDep.get(tagFromIntent)) != null)
if(handleIsoDep(tagIsoDep))
return;
}
private boolean handleIsoDep(IsoDep tag){
try{
tag.connect();
tag.setTimeout(20);
byte[] responseAPDU;
//2PAY.SYS.DDF01
byte[] select_Dir = new byte[]{
(byte)0x00, (byte)0xa4, (byte)0x04, (byte)0x00, (byte)0x0e,
(byte)0x32, (byte)0x50, (byte)0x41, (byte)0x59, (byte)0x2e,
(byte)0x53, (byte)0x59, (byte)0x53, (byte)0x2e, (byte)0x44,
(byte)0x44, (byte)0x46, (byte)0x30, (byte)0x31
};
//Select CC Applet
byte[] select_Applet = new byte[]{
(byte)0x00, (byte)0xa4, (byte)0x04, (byte)0x00, (byte)7,
(byte)0xa0, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x04,
(byte)0x30, (byte)0x60
};
//Send GET PROCESSING OPTIONS command
byte[] Send_Get = new byte[]{
(byte)0x80,(byte)0xA8,(byte)0x00,(byte)0x00,(byte)0x02,
(byte)0x83,(byte)0x00,
(byte)0x00
};
responseAPDU = tag.transceive(select_Dir);
mTextView.setText(mTextView.getText() + handleResponse(responseAPDU));
this returns the APDU-Statusword 9000 -> success
responseAPDU = tag.transceive(select_Applet);
mTextView.setText(mTextView.getText() + handleResponse(responseAPDU));
this returns the APDU-Statusword 9000 -> success
responseAPDU = tag.transceive(Send_Get);
mTextView.setText(mTextView.getText() + handleResponse(responseAPDU));
and this one is making problems: it returns 6700 -> wrong Lc or Le
mTextView.setText(mTextView.getText() + "\n\nDone");
tag.close();
} catch (IOException e) {
e.printStackTrace();
return false;
}
return true;
}
The function handleResponse just parses the "responseAPDU" from Binary to Hex an highlights the Statusword
Can anybody tell my what is going wrong? or just help me out?
PS sry for bad english ;)
As response to my application-select I get:
6f298407a0000000043060a51e50074d41455354524f5f2d046465656e9f38039f5c08bf0c059f4d020b0a9000
6F -> FCI Template 29
84 -> DF Name 07 A0 00 00 00 04 30 60
A5 -> FCI Properietary Template 1E
50 -> Application Lable 07 4D 41 45 53 54 52 4F 5F 2D 04 64 65 6E
9F38 -> PDOL 03 9F 5C 08
BF0C -> FCI Issuer Data 05
9F4D -> Log Entry 02 0B
0A Additional Issuer Data
But I don't know what ive to insert into the Data fild from the GET PROCESSING OPTIONS.
Iv'e red the guidelines in EMV Book 3, section "5.4 Rules for Using a Data Object List (DOL)".
So do I just have to set the data field 83 03 9F 5C 08
and Lc = 5?
In order to help you, the entire ADPU dialog (commands/responses) would be needed.
However, based on your code : hardcoding your select_Dir and select_Applet commands is correct, but you can't hardcode the GET PROCESSING OPTIONS command whose syntax depends on the response of the card (ICC) to your select_Applet command.
EMV 4.3 Book 1, "Table 45: SELECT Response Message Data Field (FCI) of an ADF", explains that a successful card response to the SELECT command contains a "Processing Options Data Object List" (PDOL, tag 9F38). That's the list of fields required by the card to process the transaction (ex : amount, ...). These fields values are to be returned to the card by the terminal (your phone) through the GET PROCESSING OPTIONS command data field (tag 83), as documented in EMV 4.3 book 3, section "6.5.8.3 Data Field Sent in the Command Message" :
Knowing that :
You have identified the PDOL requested by the card as : 9F38 -> 03 9F 5C 08. The 03 tells you the PDOL is 3 bytes long. 9F5C is the tag of the requested field, 08 is the length of the field value that is to be returned by the phone.
Tag 9F5C is defined in EMV Contactless 2.3 Book C2 kernel 2 specification, section "A.1.59 DS Requested Operator ID". The DS Requested Operator ID is defined as
I'm not familiar with this tag, so I can't tell you what a proper value is. However, here is what the data field of the GET PROCESSING OPTIONS command should look like, assuming a DS Requested Operator ID has value 01 02 03 04 05 06 07 08, and given the Data Object List formatting guidelines in EMV Book 3, section "5.4 Rules for Using a Data Object List (DOL)" :
and Lc = 10