This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

access_model_publish() return NRF_ERROR_FORBIDDEN

Hi,

I have a mesh device (door sensor) with cell battery powered.

When triggered, the device power on, do mesh stack init and start mesh stack, publish a mesh message, and then system off in seconds.

The issue is that access_model_publish() always return NRF_ERROR_FORBIDDEN if call this funtion immediately after mesh_stack_start(), the error was caused by net_state_seqnum_alloc():590 in net_state.c. If move access_model_publish() into a timer with at least 15ms delay, it works.

After some investigation, i found m_net_state.seqnum_max_available was set to current seqnum when boot up, then increase a number (default is 8192) to generate new available seqnum and write to next seqnum block in flash. Until flash write complete, m_net_state.seqnum_max_available will change to the new value. the time of flash write is the root cause of this issue.

In spec, the max time to write one word is 338us, erase one page is 2.05~89.7ms. so i think 100ms delay is enough.

Please correct me if there's any mistake. Thanks.

Best regards,

Pendy

  • Hello,

    Yes. I believe the assumtion that you must wait until the sequence number is updated is correct.

    I am sorry, but I don't have the setup that you have now, and I will not be able to physically test anything before january. But if you somehow can use one of the callbacks that occurs when the sequence number is updated, and use this event to trigger the access_model_publish, then perhaps that is better, if you want to use a delay that is as short as possible, but still be guaranteed that it is not too early. Try to monitor the log when you turn on the device (or reset the device) to see if there are any of the events you can piggy back.

    Best regards,

    Edvin

  • When I reboot my device the following call tree gets made:
    start() >> mesh_stack_start() >> nrf_mesh_enable() >> network_enable() >> net_state_enable() >> restored_result_apply()

    in restored_result_apply(), we see:

    static void restored_result_apply(void)
    {
        ...
        ...
        /* Regardless of flash contents, we must allocate the next block of sequence numbers before we
         * start sending. We set the seqnum max to the seqnum, and trigger the allocation, so no
         * sequence numbers are spent before we get the allocation stored. */
        m_net_state.seqnum_max_available = m_net_state.seqnum;
        seqnum_block_allocate();
    }
    

    So now my sequence number is immediately at the maximum available value. As my application progresses, a new sequence number never gets allocated, and I am never able to send my message. Currently both are equal to 0x2000 for me.

  • Hello,

    Please create a new ticket with some more information. What SDK versions you use, does this happen every time, or only after a certain number of resets? How to reproduce it, and so on.

    Best regards,

    Edvin

Related