I made a simple test application for quick debugging. I send some bytes, print what I sent on the phones screen and print what I receive.
When I send WRONG commands I get the corresponding error codes in the two byte SW1SW2.
I can also call my own command and override SW1SW2 with my own values and I can get them.
Here's the problem: When I send a CORRECT command the transceive command fails with the informative exception "Transceive failed".
If I send the correct command, but override SW1SW2 to something other than 90 00 then I get the SW value I set, but NO response data. (likely because the card does not send ODATA when SW1SW2 <> 90 00)
So how come I'm so sure I sent correct commands? Well other than messing with my own test command I called the GetAppId command - which failed saying I have to define AppId in the card.
So I define it in the card, send the same command and transceive fails.
So I'm pretty sure the problem is that transceiving fails when there is ODATA, but I do not understand WHY or how to FIX it.. help please!
EDIT: My card is the 7.5 D contactless basiccard from ZeitControl.
EDIT2: I have set the timeout to 2000ms with no change in behavior. I'm trying to return a single byte of data and the system command I called also doesn't sound heavy.
Then I downloaded and attached the Android source and debugged. There was some segments it would still not go into - but the card seems to return null on valid commands unless I return some manually set SW1SW2 in which case that is the only thing received.
EDIT3: The system command I tried was:
192 14 0 0 0
(or C0 0E 00 00 00)
(or CLA INS P1 P2 Lc)
I'm not 100% sure I'm doing that one correctly, but I have tried with various lengths (up to 22) of Le and without Le as above and only without does it not give me 6700 (wrong Le/Lc)
Of course instead of 6700 it returns null it seems...
The other command is my own defined as 20 0A (value as Byte) and no P1/P2 specified in the .BAS file.
I call that one with:
32 10 1 0 1
(or 20 0A 01 00 01)
(or CLA INS Lc IDATA Le)
This should mean 1 byte data in, set to 0, and 1 byte expected out (+ SW1/SW2 as always).
(Setting P1/P2 gives 6700 so unless defined in the command declaration I dont think they should be there)
This also returns null. I Expect 00 90 00 to be returned here. (if I set "value" to 00 that is)
I'm using a HTC One X.
EDIT4:
MinSdk version = 14 and target 18.
if(bitcoinCard != null){
try {
String sentmsg, receivedmsg;
byte[] send = getBytes(commandBytes.getText().toString());
byte[] data = null;
if(send != null){
bitcoinCard.setTimeout(2000);
data = bitcoinCard.transceive(send);
}
//bitcoinCard.close();
/*if(data != null && data.length == 2)
{
mainLabel.setText("SW1SW2: " + (data[0] < 0 ? -data[0] +
128 : data[0]) + " " + (data[1] < 0 ? -data[1] + 128 : data[1]));
}else */if (data != null && send != null)
{
sentmsg = "" + (send[0] < 0 ? send[0] + 256 : send[0]);
for(int i = 1; i < send.length; i++)
{
sentmsg = sentmsg + " " + (send[i] < 0 ? send[i] +
256 : send[i]);
}
receivedmsg = "" + (data[0] < 0 ? data[0] + 256 : data[0]);
for(int i = 1; i < data.length; i++)
{
receivedmsg = receivedmsg + " " + (data[i] < 0 ? data[i] + 256 : data[i]);
}
mainLabel.setText("Sent: " + sentmsg + "\n" +
"Response: " +
receivedmsg);
}else
{
mainLabel.setText("Sent or received null.");
}
} catch (IOException e) {
mainLabel.setText("Tried to talk to card, but had error: " +
e.getMessage());
}
}