I want to send an APDU with a length of 1699 bytes via NFC (class IsoDep) to a Java Card smartcard. I get the error
java.io.IOException: Transceive length exceeds supported maximum
My phone is a Samsung Galaxy S7.
I use extended-length in my applet on the card. I have verified that the card supports extended length. I tested this via pyapdutool by sending an APDU with 4000 bytes to the card.
I found that when I write this code, the result is false:
final Tag t = (Tag) tag;
myTag = IsoDep.get(t);
boolean result = myTag.isExtendedLengthApduSupported();
I have this in my manifest:
<activity
android:name=".test"
android:label="@string/title_test"
android:launchMode="singleTop"
android:theme="@style/AppTheme.NoActionBar" >
<action android:name="android.nfc.action.TAG_DISCOVERED" />
<category android:name="android.intent.category.DEFAULT" />
<intent-filter>
<action android:name="android.nfc.action.NDEF_DISCOVERED" />
</intent-filter>
</activity>
How can I send an APDU with 1699 bytes (or any length greater than 261 bytes) through Android NFC?
Short answer: You can't easily do that.
You already found out that IsoDep does not "support" extended-length APDUs on your device (i.e. isoDep.isExtendedLengthApduSupported() returns false). In fact this does not mean that you can't send extended-length APDUs through the IsoDep object. It actually only means that the IsoDep object won't properly split extended-length APDUs across more than two ISO-DEP blocks and consequently an APDU that is longer than 261 bytes will be assumed to exceed the transmit buffer size. You should still be able to send extended-length APDUs with sizes <= 261 bytes.
So isoDep.isExtendedLengthApduSupported() actually indicates if you can send more than 261 bytes in one ISO-DEP transceive.
What you could do to overcome this problem is to not use the IsoDep object at all and, instead, manually implement ISO-DEP (the ISO/IEC 14443-4 transmission protocol) on top of the NfcA object (if your card is based on NFC-A / ISO/IEC 14443 Type A) or the NfcB object (if your card is based on NFC-B / ISO/IEC 14443 Type B and if your device supports exchanging data over the NfcB object). You could then split your extended-length APDUs into ISO-DEP blocks that are small enough for the transceive buffer of the NFC controller (typically 253 bytes including the header bytes, excluding the CRC bytes). However, handling the ISO-DEP protocol yourself also means that you have to take care of proper ISO-DEP activation, of handling block numbering, block acknowledgements, timeouts, waiting-time extension, etc. Which is rather complicated, and particularly timeouts are not easy to observe due to the delays through the Android NFC stack.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With