The command you are actually using is not what you might have expected.
The correct command APDU to get the UID/serial number/enumeration identifier with this reader is:
+------+------+------+------+------+
| CLA | INS | P1 | P2 | Le |
+------+------+------+------+------+
| 0xFF | 0xCA | 0x00 | 0x00 | 0x00 |
+------+------+------+------+------+
However, the constructor you are using is defined as:
public CommandAPDU(int cla, int ins, int p1, int p2, int ne);
So with
new CommandAPDU(0xFF, 0xCA, 0x00, 0x00, 0x00)
you are creating a C-APDU with the following parameters CLA = 0xFF
, INS = 0xCA
, P1 = 0x00
, P2 = 0x00
. So far this is the same as the above APDU. But the last parameter is Ne = 0x00
. Ne = 0
means that the number of expected response bytes is zero (whereas Le = 0 would mean that the number of expected response bytes is (up to) 256).
This results in effectively creating the following Case-1 APDU:
+------+------+------+------+
| CLA | INS | P1 | P2 |
+------+------+------+------+
| 0xFF | 0xCA | 0x00 | 0x00 |
+------+------+------+------+
So at most you will get the 2-byte status word as a response (either indicating success with 0x90 0x00
or indicating an error with a status code like 0x6X 0xXX
).
So you can either use a byte array to form your APDU:
new CommandAPDU(new byte[] { (byte)0xFF, (byte)0xCA, (byte)0x00, (byte)0x00, (byte)0x00 } )
Or you can specify a proper value for Ne
:
new CommandAPDU(0xFF, 0xCA, 0x00, 0x00, 256)