8
votes

I am working on an Application using the IsoDep Tag Tech to issue APDU commands to an NFC enabled card.

UPDATE: So the issues seen below seem related to the power requirements of the cards I am using, when I use a different card with lower power requirements the below symptoms don't occur as frequently.

I have followed the documentation explicitly and have a successful managed to implement the protocol. However with mixed success I am experiencing some issues with the NFC lower level libraries beyond the control of my code.

I have implemented the following:

  • Foreground dispatching of a Pending Intent.
  • The intent has a tech filter for IsoDep.class and action:
    • ACTION_TAG_DISCOVERED
  • Once the I then extract the Tag from the Intent Extra Issue APDU commands and process the responses

The issue is that I have noticed a couple of things:

On the Nexus S the position of the card is dependent on a successful communication flow, if it is not in the sweet spot I will receive an IOException If I get too many IOExceptions because the card has moved or not remained in the RF field I start to see the following excpetions (see below) I was wondering if anyone else had seen these issues? In my onResume method I don't have any logic to prevent multiple calls to the NFCAdapter instance of the method: enableForegroundDispatch, should I be doing this.

Thanks in advance for any help.

Sample Exception 1

06-16 12:08:43.351: ERROR/NFC(661): NFC service dead - attempting to recover
06-16 12:08:43.351: ERROR/NFC(661): android.os.DeadObjectException
06-16 12:08:43.351: ERROR/NFC(661):     at android.os.BinderProxy.transact(Native     Method)
06-16 12:08:43.351: ERROR/NFC(661):     at android.nfc.INfcAdapter$Stub$Proxy.enableForegroundDispatch(INfcAdapter.java:528)
06-16 12:08:43.351: ERROR/NFC(661):     at android.nfc.NfcAdapter.enableForegroundDispatch(NfcAdapter.java:494)
06-16 12:08:43.351: ERROR/NFC(661):     at myClass.onResume(MyClass.java:406)
06-16 12:08:43.351: ERROR/NFC(661):     at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1150)
06-16 12:08:43.351: ERROR/NFC(661):     at android.app.Activity.performResume(Activity.java:3832)
06-16 12:08:43.351: ERROR/NFC(661):     at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2110)
06-16 12:08:43.351: ERROR/NFC(661):     at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:2135)
06-16 12:08:43.351: ERROR/NFC(661):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1668)
06-16 12:08:43.351: ERROR/NFC(661):     at android.app.ActivityThread.access$1500(ActivityThread.java:117)
06-16 12:08:43.351: ERROR/NFC(661):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:931)
06-16 12:08:43.351: ERROR/NFC(661):     at android.os.Handler.dispatchMessage(Handler.java:99)
06-16 12:08:43.351: ERROR/NFC(661):     at android.os.Looper.loop(Looper.java:130)
06-16 12:08:43.351: ERROR/NFC(661):     at android.app.ActivityThread.main(ActivityThread.java:3683)
06-16 12:08:43.351: ERROR/NFC(661):     at java.lang.reflect.Method.invokeNative(Native Method)
06-16 12:08:43.351: ERROR/NFC(661):     at java.lang.reflect.Method.invoke(Method.java:507)
06-16 12:08:43.351: ERROR/NFC(661):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
06-16 12:08:43.351: ERROR/NFC(661):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
06-16 12:08:43.351: ERROR/NFC(661):     at dalvik.system.NativeStart.main(Native Method)

Sample Exception 2

06-16 12:08:18.316: ERROR/MyClass(661): IOException in APDU commands: transceive failed
06-16 12:08:18.316: WARN/System.err(661): java.io.IOException: transceive failed
06-16 12:08:18.324: WARN/System.err(661):     at android.nfc.tech.BasicTagTechnology.transceive(BasicTagTechnology.java:144)
06-16 12:08:18.324: WARN/System.err(661):     at android.nfc.tech.IsoDep.transceive(IsoDep.java:159)
06-16 12:08:18.328: WARN/System.err(661):     at myClass.handleTagRead(MyClass.java:117)
06-16 12:08:18.328: WARN/System.err(661):     at myClass.onNewIntent(MyClass.java:84)
06-16 12:08:18.332: WARN/System.err(661):     at android.app.Instrumentation.callActivityOnNewIntent(Instrumentation.java:1119)
06-16 12:08:18.332: WARN/System.err(661):     at android.app.ActivityThread.deliverNewIntents(ActivityThread.java:1722)
06-16 12:08:18.335: WARN/System.err(661):     at android.app.ActivityThread.performNewIntents(ActivityThread.java:1734)
06-16 12:08:18.335: WARN/System.err(661):     at android.app.ActivityThread.handleNewIntent(ActivityThread.java:1742)
06-16 12:08:18.339: WARN/System.err(661):     at android.app.ActivityThread.access$2300(ActivityThread.java:117)
06-16 12:08:18.343: WARN/System.err(661):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:978)
06-16 12:08:18.343: WARN/System.err(661):     at android.os.Handler.dispatchMessage(Handler.java:99)
06-16 12:08:18.347: WARN/System.err(661):     at android.os.Looper.loop(Looper.java:130)
06-16 12:08:18.347: WARN/System.err(661):     at android.app.ActivityThread.main(ActivityThread.java:3683)
06-16 12:08:18.351: WARN/System.err(661):     at java.lang.reflect.Method.invokeNative(Native Method)
06-16 12:08:18.351: WARN/System.err(661):     at java.lang.reflect.Method.invoke(Method.java:507)
06-16 12:08:18.355: WARN/System.err(661):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
06-16 12:08:18.355: WARN/System.err(661):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
06-16 12:08:18.359: WARN/System.err(661):     at dalvik.system.NativeStart.main(Native Method)
06-16 12:08:18.359: DEBUG/MyClass(661): Setting up for ForegroundDispatch for NFC ISO DEP
06-16 12:08:18.492: DEBUG/NativeNfcTag(871): Tag lost, restarting polling loop
06-16 12:08:19.269: WARN/NfcService(871): Failed to connect to tag
06-16 12:08:23.980: ERROR/NFC JNI(871): phLibNfc_RemoteDev_Connect(RW) returned 0x00ff[NFCSTATUS_FAILED]
06-16 12:08:23.980: WARN/NfcService(871): Failed to connect to tag
06-16 12:08:23.980: ERROR/NFC JNI(871): doDisconnect() - Target already disconnected

Sample Exception 3

06-16 12:08:15.468: DEBUG/MyClass(661): Recieved a TAG
06-16 12:08:15.468: DEBUG/MyClass(661): Supported Technology of for recieve    d tag: android.nfc.tech.IsoDep
06-16 12:08:15.468: DEBUG/MyClass(661): Supported Technology of for recieved tag: android.nfc.tech.NfcA
06-16 12:08:15.468: DEBUG/MyClass(661): Supported Technology of for recieved tag: android.nfc.tech.MifareClassic
06-16 12:08:15.484: ERROR/MyClass(661): Failed to connect to aTag Reason: null
06-16 12:08:15.484: WARN/System.err(661): java.io.IOException
06-16 12:08:15.484: WARN/System.err(661):     at android.nfc.tech.BasicTagTechnology.connect(BasicTagTechnology.java:81)
06-16 12:08:15.484: WARN/System.err(661):     at android.nfc.tech.IsoDep.connect(IsoDep.java:39)
06-16 12:08:15.484: WARN/System.err(661):     at myClass.handleTagRead(ConfirmPaymentScreen.java:107)
06-16 12:08:15.484: WARN/System.err(661):     at myClass.onNewIntent(ConfirmPaymentScreen.java:84)
06-16 12:08:15.484: WARN/System.err(661):     at android.app.Instrumentation.callActivityOnNewIntent(Instrumentation.java:1119)
06-16 12:08:15.484: WARN/System.err(661):     at android.app.ActivityThread.deliverNewIntents(ActivityThread.java:1722)
06-16 12:08:15.484: WARN/System.err(661):     at android.app.ActivityThread.performNewIntents(ActivityThread.java:1734)
06-16 12:08:15.484: WARN/System.err(661):     at android.app.ActivityThread.handleNewIntent(ActivityThread.java:1742)
06-16 12:08:15.484: WARN/System.err(661):     at android.app.ActivityThread.access$2300(ActivityThread.java:117)
06-16 12:08:15.484: WARN/System.err(661):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:978)
06-16 12:08:15.484: WARN/System.err(661):     at android.os.Handler.dispatchMessage(Handler.java:99)
06-16 12:08:15.484: WARN/System.err(661):     at android.os.Looper.loop(Looper.java:130)
06-16 12:08:15.484: WARN/System.err(661):     at android.app.ActivityThread.main(ActivityThread.java:3683)
06-16 12:08:15.484: WARN/System.err(661):     at java.lang.reflect.Method.invokeNative(Native Method)
06-16 12:08:15.484: WARN/System.err(661):     at java.lang.reflect.Method.invoke(Method.java:507)
06-16 12:08:15.484: WARN/System.err(661):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
06-16 12:08:15.484: WARN/System.err(661):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
06-16 12:08:15.484: WARN/System.err(661):     at dalvik.system.NativeStart.main(Native Method)
06-16 12:08:15.484: DEBUG/MyClass(661): Failed to connect to tag
06-16 12:08:15.484: DEBUG/MyClass(661): Setting up for ForegroundDispatch for NFC ISO DEP
06-16 12:08:15.609: ERROR/NFC JNI(871): phLibNfc_RemoteDev_CheckPresence() returned 0x0095[NFCSTATUS_INVALID_HANDLE]
06-16 12:08:15.609: DEBUG/NativeNfcTag(871): Tag lost, restarting polling loop
06-16 12:08:15.609: ERROR/NFC JNI(871): phLibNfc_RemoteDev_Disconnect(294f58) returned 0x0095[NFCSTATUS_INVALID_HANDLE]
2

2 Answers

4
votes

So I know what is causing this, some of the RFID tags I was trying to read had a higher power consumption requirement than the phone was capable of. The upsetting thing was/is the phone falls over if it gets in a bad place for too long...

0
votes

Is lack of rf power to the tag still the answer here? I have self powered nt3h2xxx series tags that exhibit the same behavior on a recent phone (Nokia 3): nfca.tranceive(0xA2/0xA6...) writes data to the tag successfully (after later inspection) but throws "Transceive failed" below. While nfca.tranceive(read commands) work fine.

W/System.err: java.io.IOException: Transceive failed W/System.err: at android.nfc.TransceiveResult.getResponseOrThrow(TransceiveResult.java:52) W/System.err: at android.nfc.tech.BasicTagTechnology.transceive(BasicTagTechnology.java:151) W/System.err: at android.nfc.tech.NfcA.transceive(NfcA.java:120)

Maybe my tag coil isnt sufficiently large to pull-down the 4-bit ACK response to the successful tag fast write. While a tag read is ok since the tag response has many more bits (just guessing here).

Workaround was to catch the tranceive IOexception and ignore it. Then after all is done, do a fast read from the tag to see if the fast write worked.