Using NFC Library in 'raw' APDU mode : how to set FWI/FWTX?

Custom device using nrf5340, with NFC card emulation functionality.

To use the NFC, I understand that I should use the supplied nfc_t4t library (binary) and its api. I have this working ok for type 4 card emulation using the NDEF application functionality built in to the library..

I now need to create an application that will emulate other functions, and so I am trying to the use the library in 'raw APDU' mode. This is basically working, but I have run into a timeout issue : certain elements of my APDU processing can take some 10's of ms, and this is apparently causing my nfc reader to timeout its request. This causes the library to have some issues : I get logs like this:

[00:05:13.375,488] <err> nfc_platform: Tried to read data pointer: 4 bytes, read 0.
[00:05:13.375,488] <err> nfc_platform: Reading nfc ring buffer failed, resetting ring buffer.

 I think these are basically when I do the nfc_t4t_response_pdu_send() call to send the response PDU. Any ideas on what this means for my operation?

The reader never manages to get a valid response, this seems to be related to the time it takes for my code to process the APDU (around 35ms for a basic select operation, due to it being sent to a ISO7816 contact card for processing...). In the NFC spec I see this:

"When the Card Emulator needs more time than the defined FWT to process the received block, it uses an S(WTX) request for a waiting time extension. An S(WTX) request contains a 1-byte INF field as specified in Table 84"

How can I tell the library that I want it to send this S(WTX) frame? It seems it needs to be sent for each received command? The only param I see to set is the FWI (which sets the max FWT as I understand it). When I try to set this to the max (before doing nfc_t4t_setup()) :

                uint32_t fwi = NFC_T4T_FWI_MAX_VAL_EMV;
                if ((ret=nfc_t4t_parameter_set(NFC_T4T_PARAM_FWI, &fwi, sizeof(fwi)))!=0) {
                    log_warn("nfcmgr: t4t fwi set fails (%d)",ret);
                }
Then it gives me an error -22
Doing a get of the FWI_MAX says its set to 4.
Is there a way to get the library to tell the reader that I want to increase the waiting timeout for a specific received command?
thanks
Parents
  • Then it gives me an error -22

    Ok, I have fixed my problem with nfc_t4t_parameter_set(), it needs the parameter value to be a uint8_t.

    So now I can set the FWI to be 8 max. By my calculation, this should make the reader apply a FWT of around 77ms

    (FWT = (256 x 16/Fc) x 2^FWI, Fc=13.56MHz, FWI=8 -> 77ms)

    The FWI is correctly taken into acount on the reader (it reports it as 8, and calculates the FWT=77ms)

    However, any delay in responding that is over 2-3ms fail to work.... and gets the same logs:

    [00:05:13.375,488] <err> nfc_platform: Tried to read data pointer: 4 bytes, read 0.
    [00:05:13.375,488] <err> nfc_platform: Reading nfc ring buffer failed, resetting ring buffer.

    So, maybe its not the reader timing out, but the library? Can anyone shed some light on the this lib? As its supplied only as a binary blob, I can't see what is actually happening....

  • Hi,

    Great to hear that you fixed the problem with nfc_t4t_parameter_set().

    I will ask about the other issue internally. Can you upload the complete device log?

    Best regards,
    Marte

  • Hi,

    I got an update from the developers.

    By default, the frame wait time in the T4T library is set to about 4.8 ms, as the Frame Wait Time (FWI) parameter is 4. If the application does not provide the response PDU within this time, the tag automatically transmits a request to extend the wait time. It will keep sending the request until the response PDU is ready or the reader refuses to accept more extensions. 

    You can use a higher FWI by changing it through nfc_t4t_parameter_set(). The max value is defined by NFC_T4T_PARAM_FWI_MAX and should be 8 for the nRF5340.

    Best regards,
    Marte

  • By default, the frame wait time in the T4T library is set to about 4.8 ms, as the Frame Wait Time (FWI) parameter is 4. If the application does not provide the response PDU within this time, the tag automatically transmits a request to extend the wait time. It will keep sending the request until the response PDU is ready or the reader refuses to accept more extensions. 

    ok, this is good news and what I hoped would be the behaviour.

    You can use a higher FWI by changing it through nfc_t4t_parameter_set(). The max value is defined by NFC_T4T_PARAM_FWI_MAX and should be 8 for the nRF5340.

    This is exactly what my code does before calling setup/emulation_start():

                    // Increase the wait time for any NFC readers as APDU processing may be slower (especially if talking to ISO7816 card)
                    uint8_t fwi = 8;   // NFC_T4T_FWI_MAX_VAL_EMV;     // ==7 for EMV spec. 8 is the max the lib will accept.
                    if ((ret=nfc_t4t_parameter_set(NFC_T4T_PARAM_FWI, &fwi, sizeof(fwi)))!=0) {
                        log_warn("nfcmgr: t4t fwi set fails (%d)",ret);
                    }

                    // register with nfc_t4t
                    if ((ret = nfc_t4t_setup(_nfc_t4t_apdu_cb, &_ctx))!=0) {
                        log_warn("nfcmgr : t4t fail setup for APDU (%d)", ret);
                        // This is fatal error
                        return false;
                    }
                    if ((ret = nfc_t4t_emulation_start())!=0) {
                        log_warn("nfcmgr: t4t apdu emul start fails (%d)",ret);
                    }
                    size_t plen=sizeof(fwi);
                    if ((ret = nfc_t4t_parameter_get(NFC_T4T_PARAM_FWI, &fwi, &plen))!=0) {
                        log_warn("nfcmgr: t4t fwi get fails (%d)",ret);
                    }
                    log_warn("nfcmgr : type 4 APDU started, fwi=%d", fwi);
    And the fwi value is retrieved by the log is indeed set to 8, and the reader confirms this (if I do a read using application code that responds immediately)
    However, whenever the response from my code takes longer than around 4-5ms (delay to call nfc_t4t_response_pdu_send()), the reader never seems to get a response at all.... Is there a way to see a log from the library showing its operation?
    Maybe it doesn't like the 'requst for extension' message? 
    If the application does not provide the response PDU within this time, the tag automatically transmits a request to extend the wait time

    Is this always sent after 4.8ms, or after the updated FWT (77ms)?

    Thanks!

  • Hi,

    I will ask the developers about this.

    Which version of the nRF Connect SDK are you using?

    Best regards,
    Marte

  • Which version of the nRF Connect SDK are you using?

    2.9.0

  • Hi,

    Thank you, I have forwarded this to the developers. I cannot comment on the schedule since this needs to be prioritized against other tasks. Please get in touch with RSM if this is critical.

    Best regards,
    Marte

Reply Children
Related