Andreas
Andreas

Reputation: 81

NFC ADPU CLA=0x03, what does that mean?

I setup an emulation of a type-4 NFC Tag with a microcontroller and a NFC frontend. The first step is just display a text message to an NFC smartphone, after sending the NDEF message to the NFC reader (the phone) it is displayed as expected, but then the reader sends an additional ADPU command:

0x02 PCB
0x03 CLA
0xB0 INS
0x00
0x00
0x01

What is the meaning of CLA=0x03?

Does it mean that something went wrong with the last response-ADPU?

What does the reader expect now from the tag?

I checked the ISO7816, but didn't find an explanation there

I would expect that the reader should release the tag after getting the final NDEF message, or should I just put my NFC frontend into idle mode?

Thanks for inputs, Andreas

        case AMS_WF_NDEF_READ_REQ:
            if ((nBytesInFIFO==6)
            &(fifoData[0]==0x03) // PCB header byte
            &(fifoData[1]==0x00) // ATPDU: CLA instruction class
            &(fifoData[2]==0xB0) // ATPDU: INS instruction code (B0=SELECT-FILE, see ISO7816, table-11)
            &(fifoData[3]==0x00) // ATPDU: P1  instruction parameter #1, P1 and P2 are the offset for reading
            &(fifoData[4]==0x02) // ATPDU: P2  instruction parameter #2
            &(fifoData[5]==0x0A))// ATPDU: Lc  Length of data field in the reply
            {
                sprintf_P(str,PSTR("NDEF-RD-RQST\n"));  uart_puts(str);
                ams_resp(0x0A+3,        // num parameter, depends on the data length info from reader
                         0x03,          // PCB header
                         0xD1,          // NDEF header 
                         0x01,          //      type length
                         0x06,          //      payload length
                         0x54,          //      type, for example: 'T'=Text
                         0x02,          //
                         0x65,0x6E,     //      language code, for example: "en"
                         0x6F,0x6B,0x0A,//      payload
                         0x90,0x00);    // OK
                ams_state=AMS_WF_PCD_SEL_BY_DF_NAME; // back to initial state
            }

Upvotes: 1

Views: 1482

Answers (1)

Michael Roland
Michael Roland

Reputation: 40851

The command you receive 03 B0 00 00 01 is a READ_BINARY command (issued on logical channel 3) for the last selected file. This is typical behavior of the libnfc-nci NFC stack (and thus present on all devices with Broadcom NFC chipset). The NFC stack tries to read one byte of the NDEF file (of an NFC Forum Type 4 tag) with this command. This is known to interfere with many applications as it may happen in the middle of other commands sent by an app.

The libnfc-nci NFC stack (incorrectly) implemented sending a READ_BINARY command (00 B0 00 00 01) on the basic channel (logical channel 0) as a presence check mechanism to detect if a tag is still there or has been removed from the NFC reader. Devices based on libnfc-nxp (NXP chipsets) correctly use the presence check mechanism described in ISO 14443-4. This is a known and unfixed bug for quite a while: issue #58773.

To overcome resulting problems of this type of "presence check", several alternative approaches for the presence check were implemented in newer versions of libnfc-nci:

  • READ_BINARY on channel 0 00 B0 00 00 01: This was the default for the first generations of libnfc-nci and was used on most devices with Broadcom chipset up to Android 4.4.4.
  • READ_BINARY on channel 3 03 B0 00 00 01: This has been implemented as an alternative to sending the READ_BINARY command on channel 0. It seems that the idea behind this was to avoid interference with any ongoing communication on channel 0. However, from what I found it seems that channel 3 is never opened (neither explicit through MANAGE_LOGICAL_CHANNEL nor implicit through a SELECT command). Hence, this might still cause issues on some (many?) cards.
  • ISO/IEC 14443 deactivation and re-activation of the card.
  • ISO/IEC 14443 conformant presence check using empty I-blocks.

The presence check mechanism is set up through the /system/etc/libnfc-bcrm.conf config file. See libnfc-bcrm.conf starting on line 250.

Upvotes: 3

Related Questions