What is the maximum URL length that can be transmitted via NFC using the nRF52840?

Hello everyone,

I appreciate your understanding as I'm a newcomer here.

I'm actively engaged in developing a demo app that's designed to transmit URLs to smartphones through NFC, usign the uri_nfc demo provided by Nordic.

I've encountered a query regarding the maximum URL length that can be transmitted. Are there any limitations to this, and if so, is there a way to modify or extend this parameter?

As of now, I'm working with NFC Type 2 tags, and I've observed that the maximum URL length I can send is capped at 255 characters.

Your insights and guidance on this matter would be greatly appreciated.

Thank you for your assistance and support.

Parents
  • Hi,

    Generally, the maximum payload length depend on the SR flag. If SR is 1, the length field is 1 byte, making 255 the max. If SR is 0, the length field is 4 byte long, allowing longer payloads.

    Which demo are you referring to, and which SDK are you using?

  • Hi,

    I see the same when I test the URI Message Example. First of all, m_ndef_msg_buf needs to be made larger (is is 256 in the example by default). However, things will still not work with a longer than 255 byte message, as the length given by the third parameter to nfc_uri_msg_encode is a uint8_t. You should also see a warning when you build with a long URL because of that. This is also the size of uri_data_len of uri_payload_desc_t.

    I am not able to find any indication that the URI should be limited to 255 bytes though, so it should be OK to modify this, and that works when I test on my end.

    I made these few changes to the SDK:

    diff --git a/components/nfc/ndef/uri/nfc_uri_msg.c b/components/nfc/ndef/uri/nfc_uri_msg.c
    index fb21b33..b1b4cdd 100644
    --- a/components/nfc/ndef/uri/nfc_uri_msg.c
    +++ b/components/nfc/ndef/uri/nfc_uri_msg.c
    @@ -46,7 +46,7 @@
     
     ret_code_t nfc_uri_msg_encode( nfc_uri_id_t          uri_id_code,
                                    uint8_t const * const p_uri_data,
    -                               uint8_t               uri_data_len,
    +                               uint32_t              uri_data_len,
                                    uint8_t       *       p_buf,
                                    uint32_t      *       p_len)
     {
    diff --git a/components/nfc/ndef/uri/nfc_uri_msg.h b/components/nfc/ndef/uri/nfc_uri_msg.h
    index 35cfa5d..d91a3d4 100644
    --- a/components/nfc/ndef/uri/nfc_uri_msg.h
    +++ b/components/nfc/ndef/uri/nfc_uri_msg.h
    @@ -80,7 +80,7 @@ extern "C" {
      */
     ret_code_t nfc_uri_msg_encode( nfc_uri_id_t           uri_id_code,
                                    uint8_t const *  const p_uri_data,
    -                               uint8_t                uri_data_len,
    +                               uint32_t                uri_data_len,
                                    uint8_t       *        p_buf,
                                    uint32_t      *        p_len);
     
    diff --git a/components/nfc/ndef/uri/nfc_uri_rec.h b/components/nfc/ndef/uri/nfc_uri_rec.h
    index 25c04a2..5d6583d 100644
    --- a/components/nfc/ndef/uri/nfc_uri_rec.h
    +++ b/components/nfc/ndef/uri/nfc_uri_rec.h
    @@ -110,7 +110,7 @@ typedef struct
     {
         nfc_uri_id_t    uri_id_code;  /**< URI identifier code. */
         uint8_t const * p_uri_data;   /**< Pointer to a URI string. */
    -    uint8_t         uri_data_len; /**< Length of the URI string. */
    +    uint32_t        uri_data_len; /**< Length of the URI string. */
     } uri_payload_desc_t;
     
     /**

    so this is designed for maximum 8 bit in this implementation.

    And then these changes to the URI Message Example to test it:

    diff --git a/examples/nfc/record_url/main.c b/examples/nfc/record_url/main.c
    index 7ca2b40..be604fb 100644
    --- a/examples/nfc/record_url/main.c
    +++ b/examples/nfc/record_url/main.c
    @@ -57,10 +57,10 @@
     #include "nrf_log_default_backends.h"
     
     /** @snippet [NFC URI usage_0] */
    -static const uint8_t m_url[] =
    -    {'n', 'o', 'r', 'd', 'i', 'c', 's', 'e', 'm', 'i', '.', 'c', 'o', 'm'}; //URL "nordicsemi.com"
    +static const char m_url[] =
    +"google.com/search?q=nrk&sca_esv=573727491&sxsrf=AM9HkKnUxnVQ3iGCYFXCXlc9gausejoDZQ%3A1697443832246&ei=-O8sZeHcDpXnxc8P0cKXqAg&ved=0ahUKEwjhuJaFj_qBAxWVc_EDHVHhBYUQ4dUDCA8&uact=5&oq=nrk&gs_lp=Egxnd3Mtd2l6LXNlcnAiA25yazIHECMYsAMYJzIHECMYsAMYJzIHECMYsAMYJzIKEAAYRxjWBBiwAzIKEAAYRxjWBBiwAzIKEAAYRxjWBBiwAzIKEAAYRxjWBBiwAzIKEAAYRxjWBBiwAzIKEAAYRxjWBBiwAzIKEAAYRxjWBBiwA0iLCVAAWABwAXgBkAEAmAEAoAEAqgEAuAEDyAEA4gMEGAAgQYgGAZAGCg&sclient=gws-wiz-serp";
     
    -uint8_t m_ndef_msg_buf[256];
    +uint8_t m_ndef_msg_buf[512]; // 256 Increase!
     /** @snippet [NFC URI usage_0] */
     /**
      * @brief Callback function for handling NFC events.
    @@ -119,8 +119,8 @@ int main(void)
     
         /* Encode URI message into buffer */
         err_code = nfc_uri_msg_encode( NFC_URI_HTTP_WWW,
    -                                   m_url,
    -                                   sizeof(m_url),
    +                                   (uint8_t*) m_url,
    +                                   sizeof(m_url) - 1,
                                        m_ndef_msg_buf,
                                        &len);
     

    This works well on my end.

Reply
  • Hi,

    I see the same when I test the URI Message Example. First of all, m_ndef_msg_buf needs to be made larger (is is 256 in the example by default). However, things will still not work with a longer than 255 byte message, as the length given by the third parameter to nfc_uri_msg_encode is a uint8_t. You should also see a warning when you build with a long URL because of that. This is also the size of uri_data_len of uri_payload_desc_t.

    I am not able to find any indication that the URI should be limited to 255 bytes though, so it should be OK to modify this, and that works when I test on my end.

    I made these few changes to the SDK:

    diff --git a/components/nfc/ndef/uri/nfc_uri_msg.c b/components/nfc/ndef/uri/nfc_uri_msg.c
    index fb21b33..b1b4cdd 100644
    --- a/components/nfc/ndef/uri/nfc_uri_msg.c
    +++ b/components/nfc/ndef/uri/nfc_uri_msg.c
    @@ -46,7 +46,7 @@
     
     ret_code_t nfc_uri_msg_encode( nfc_uri_id_t          uri_id_code,
                                    uint8_t const * const p_uri_data,
    -                               uint8_t               uri_data_len,
    +                               uint32_t              uri_data_len,
                                    uint8_t       *       p_buf,
                                    uint32_t      *       p_len)
     {
    diff --git a/components/nfc/ndef/uri/nfc_uri_msg.h b/components/nfc/ndef/uri/nfc_uri_msg.h
    index 35cfa5d..d91a3d4 100644
    --- a/components/nfc/ndef/uri/nfc_uri_msg.h
    +++ b/components/nfc/ndef/uri/nfc_uri_msg.h
    @@ -80,7 +80,7 @@ extern "C" {
      */
     ret_code_t nfc_uri_msg_encode( nfc_uri_id_t           uri_id_code,
                                    uint8_t const *  const p_uri_data,
    -                               uint8_t                uri_data_len,
    +                               uint32_t                uri_data_len,
                                    uint8_t       *        p_buf,
                                    uint32_t      *        p_len);
     
    diff --git a/components/nfc/ndef/uri/nfc_uri_rec.h b/components/nfc/ndef/uri/nfc_uri_rec.h
    index 25c04a2..5d6583d 100644
    --- a/components/nfc/ndef/uri/nfc_uri_rec.h
    +++ b/components/nfc/ndef/uri/nfc_uri_rec.h
    @@ -110,7 +110,7 @@ typedef struct
     {
         nfc_uri_id_t    uri_id_code;  /**< URI identifier code. */
         uint8_t const * p_uri_data;   /**< Pointer to a URI string. */
    -    uint8_t         uri_data_len; /**< Length of the URI string. */
    +    uint32_t        uri_data_len; /**< Length of the URI string. */
     } uri_payload_desc_t;
     
     /**

    so this is designed for maximum 8 bit in this implementation.

    And then these changes to the URI Message Example to test it:

    diff --git a/examples/nfc/record_url/main.c b/examples/nfc/record_url/main.c
    index 7ca2b40..be604fb 100644
    --- a/examples/nfc/record_url/main.c
    +++ b/examples/nfc/record_url/main.c
    @@ -57,10 +57,10 @@
     #include "nrf_log_default_backends.h"
     
     /** @snippet [NFC URI usage_0] */
    -static const uint8_t m_url[] =
    -    {'n', 'o', 'r', 'd', 'i', 'c', 's', 'e', 'm', 'i', '.', 'c', 'o', 'm'}; //URL "nordicsemi.com"
    +static const char m_url[] =
    +"google.com/search?q=nrk&sca_esv=573727491&sxsrf=AM9HkKnUxnVQ3iGCYFXCXlc9gausejoDZQ%3A1697443832246&ei=-O8sZeHcDpXnxc8P0cKXqAg&ved=0ahUKEwjhuJaFj_qBAxWVc_EDHVHhBYUQ4dUDCA8&uact=5&oq=nrk&gs_lp=Egxnd3Mtd2l6LXNlcnAiA25yazIHECMYsAMYJzIHECMYsAMYJzIHECMYsAMYJzIKEAAYRxjWBBiwAzIKEAAYRxjWBBiwAzIKEAAYRxjWBBiwAzIKEAAYRxjWBBiwAzIKEAAYRxjWBBiwAzIKEAAYRxjWBBiwAzIKEAAYRxjWBBiwA0iLCVAAWABwAXgBkAEAmAEAoAEAqgEAuAEDyAEA4gMEGAAgQYgGAZAGCg&sclient=gws-wiz-serp";
     
    -uint8_t m_ndef_msg_buf[256];
    +uint8_t m_ndef_msg_buf[512]; // 256 Increase!
     /** @snippet [NFC URI usage_0] */
     /**
      * @brief Callback function for handling NFC events.
    @@ -119,8 +119,8 @@ int main(void)
     
         /* Encode URI message into buffer */
         err_code = nfc_uri_msg_encode( NFC_URI_HTTP_WWW,
    -                                   m_url,
    -                                   sizeof(m_url),
    +                                   (uint8_t*) m_url,
    +                                   sizeof(m_url) - 1,
                                        m_ndef_msg_buf,
                                        &len);
     

    This works well on my end.

Children
  • Thanks for the quick reply! Smiley

    I've tested your code, and it appears to work correctly. However, I'd like to maximize the allowed URL length, which isn't specified in the Infocenter. It simply returns an error if the size is too large.

    The maximum URL length I've been able to send is exactly 988 characters, as defined in the NFC_T2T_MAX_PAYLOAD_SIZE macro:

    #define NFC_T2T_MAX_PAYLOAD_SIZE 988 ///< Maximum NDEF message size.

    I've attempted to modify this macro, but increasing the URL length beyond 988 characters triggers the following error:

    00> <error> app: ERROR 12 [NRF_ERROR_DATA_SIZE]
    00> 
    00> PC at: 0x00005573
    00> 
    00> <error> app: End of error report

    Unfortunately, I don't have access to the nfc_t2t_payload_set function, as it's likely written in assembler.

    What can I do to increase this length?

    Please take a look at my code (the provided URL is used to count characters. The letters after the .com have been used to demonstrate that the maximum length is 988 characters).

    static const char m_url[] =
    "perdigo.gerardbayego.com/?AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n\
    AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA n\
    AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA n\
    AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA n\
    AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
    
    uint8_t m_ndef_msg_buf[10000];
    /** @snippet [NFC URI usage_0] */
    /**
     * @brief Callback function for handling NFC events.
     */
    static void nfc_callback(void * p_context, nfc_t2t_event_t event, const uint8_t * p_data, size_t data_length)
    {
        (void)p_context;
    
        switch (event)
        {
            case NFC_T2T_EVENT_FIELD_ON:
                bsp_board_led_on(BSP_BOARD_LED_0);
                break;
    
            case NFC_T2T_EVENT_FIELD_OFF:
                bsp_board_led_off(BSP_BOARD_LED_0);
                break;
    
            default:
                break;
        }
    }
    
    
    /**
     *@brief Function for initializing logging.
     */
    static void log_init(void)
    {
        ret_code_t err_code = NRF_LOG_INIT(NULL);
        APP_ERROR_CHECK(err_code);
    
        NRF_LOG_DEFAULT_BACKENDS_INIT();
    }
    
    
    /**
     * @brief Function for application main entry.
     */
    int main(void)
    {
        uint32_t  err_code;
    
        log_init();
    
        /* Configure LED-pins as outputs */
        bsp_board_init(BSP_INIT_LEDS);
    
        /* Set up NFC */
        err_code = nfc_t2t_setup(nfc_callback, NULL);
        APP_ERROR_CHECK(err_code);
    
        /** @snippet [NFC URI usage_1] */
        /* Provide information about available buffer size to encoding function */
        uint32_t len = sizeof(m_ndef_msg_buf);
    
        /* Encode URI message into buffer */
        err_code = nfc_uri_msg_encode( NFC_URI_HTTPS,
                                       (uint8_t*)(m_url),
                                       sizeof(m_url) - 1,
                                       m_ndef_msg_buf,
                                       &len);
    
        SEGGER_RTT_printf(0, "len: %d\n", len);
    
        APP_ERROR_CHECK(err_code);
        /** @snippet [NFC URI usage_1] */
    
        /* Set created message as the NFC payload */
        err_code = nfc_t2t_payload_set(m_ndef_msg_buf, len);
        APP_ERROR_CHECK(err_code);
    
        /* Start sensing NFC field */
        err_code = nfc_t2t_emulation_start();
        APP_ERROR_CHECK(err_code);
    
        while (1)
        {
            NRF_LOG_FLUSH();
            __WFE();
        }
    }

    Thank you very much!

  • Hi,

    You cannot change NFC_T2T_MAX_PAYLOAD_SIZE to something else than 988. The library is distributed as binary, and the value used internally will be 988 even if you change it. So this is an absolute maximum.

  • Oh, as I thought...

    Well, thank you very much for your time and your helpful answers!"

Related