Question

I am using an NFC Tag Type 2. I am having a problem with 1-Byte ACK/NACK responses when calling a transceive() function running the Broadcom NFC Android stack. This problem doesn't happen with the NXP NFC Android stack. For example, the ACK response of a Write command is defined as 0xAh (according to the NFC Forum Tag Type 2 protocol). If the NFC tag replies something else rather than 0xAh, the Broadcom NFC stack will consider this as NACK. This issue doesn't occur in the NXP NFC stack.

Broadcom NFC stack

In /platform/packages/apps/Nfc/nci/jni/NativeNfcTag.cpp
In function “nativeNfcTag_doTransceive()” line 890

static jbyteArray nativeNfcTag_doTransceive (JNIEnv* e, jobject, jbyteArray data, jboolean raw, jintArray statusTargetLost)
    {
    ..
    ..
    if ((natTag.getProtocol () == NFA_PROTOCOL_T2T) &&
                natTag.isT2tNackResponse (sTransceiveData, sTransceiveDataLen))
            {
                isNack = true;
            }

            if (sTransceiveDataLen)
            {
                if (!isNack) {
                    // marshall data to java for return
                    result.reset(e->NewByteArray(sTransceiveDataLen));
                    if (result.get() != NULL) {
                        e->SetByteArrayRegion(result.get(), 0, sTransceiveDataLen, (jbyte *) sTransceiveData);
                    }
                    else
                        ALOGE ("%s: Failed to allocate java byte array", __FUNCTION__);
                } // else a nack is treated as a transceive failure to the upper layers

                free (sTransceiveData);
                sTransceiveData = NULL;
                sTransceiveDataLen = 0;
            }
       ..
       ..
}

When we look at function isT2tNackResponse() in /platform/packages/apps/Nfc/nci/jni/NfcTag.cpp line 1212

    bool NfcTag::isT2tNackResponse (const UINT8* response, UINT32 responseLen)
    {
        static const char fn [] = "NfcTag::isT2tNackResponse";
        bool isNack = false;

        if (responseLen == 1)
        {
            if (response[0] == 0xA) // line 1212: T2tNackResponse always returns NACK if the first byte is NOT 0xA 
                isNack = false; //an ACK response, so definitely not a NACK
            else
                isNack = true; //assume every value is a NACK
        }
        ALOGD ("%s: return %u", fn, isNack);
        return isNack;
}

NXP NFC stack

The same function in the NXP NFC stack In /platform/packages/apps/Nfc/nxp/jni/com_android_nfc_NativeNfcTag.cpp
In function “com_android_nfc_NativeNfcTag_doTransceive()” line 853

static jbyteArray com_android_nfc_NativeNfcTag_doTransceive(JNIEnv *e,
   jobject o, jbyteArray data, jboolean raw, jintArray statusTargetLost)
{

..
..
/* Copy results back to Java *
     * In case of NfcA and raw, also check the CRC in the response
     * and cut it off in the returned data.
     */
    if ((nfc_jni_transceive_buffer->length > 2) && checkResponseCrc) { // line 853
        if (crc_valid(nfc_jni_transceive_buffer->buffer, nfc_jni_transceive_buffer->length)) {
            result = e->NewByteArray(nfc_jni_transceive_buffer->length - 2);
            if (result != NULL) {
                e->SetByteArrayRegion(result, 0,
                 nfc_jni_transceive_buffer->length - 2,
                 (jbyte *)nfc_jni_transceive_buffer->buffer);
            }
        }
    } else {
        result = e->NewByteArray(nfc_jni_transceive_buffer->length);
        if (result != NULL) {
            e->SetByteArrayRegion(result, 0,
             nfc_jni_transceive_buffer->length,
             (jbyte *)nfc_jni_transceive_buffer->buffer);
        }
    }
..
..
}

In the NXP NFC stack, everything is forwarded to Java and returned to the transceive() function.

Any help/comment would be appreciated. Thank you.

Was it helpful?

Solution

This is a known issue. The problem is actually with the NFC Forum NCI standard, on which the Broadcom stack is based. The protocol messages in the NCI standard do not distinguish between 4-bit ACK/NAK responses and normal responses of 1 byte (+ CRC, which is stripped). Both are represented by a single byte. The Broadcom stack (has to) interpret them as ACK/NAK. Hopefully, this will soon be fixed in an update to the standard and the software stack.

OTHER TIPS

Is this an issue only for NFC Forum Tag Type 2? In the code, it seems that the other tag types aren't effected by this. Tag Type 3,4 and NfcV's 1-Byte raw data won't be filtered. I didn't follow the discussion in the NFC Forum. What's the main reason we need to distinguish between 4-bit responses and 1-byte data?

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top