Beware that this post is related to an SDK in maintenance mode
More Info: Consider nRF Connect SDK for new designs
This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Bluetooth 5 BLE mesh: assert 0x0002DC36

Hi all,s

I have a couple of nrf52840 boards and i was testing the ble mesh light application. The application works fine, but i changed it so it will periodically set the LED on the server side. After a few transmissions (usually around 100 or 200 packets). Then i get the following assert in the light client application: (app_error_weak.c, 95, mesh assert at 0x0002DC36). I did a stack trace wich showed me that it is going wrong in the core_tx.c in line 105: 

NRF_MESH_ASSERT(m_packet.bearer_bitmap == 0)

it should be zero but it is obviously not. zero.., i have no clue why it is happening. It happens when i use a reliable transfer and an unreliable transfer.

Has anybody an idea about what is going wrong?

Thanks fot the help!

Parents
  • hello,

    Can I suggest that you provide the code snippet that you changed (or upload the server main.c file) and/or the logs, then we may be able to help you diagnose a bit further.

    Regards,

  • Hi, 

    Here is a code snippet from the client software that i have added.

    typedef struct test_settings //test parameters
    {
        int i;
        long n_time;            //transmissionperiod (example 500ms)
        int n_messages;         //total number of transmissions to be done
        //more parameters will be added later
    } test_settings;
    
    test_settings test_setup;
    
    typedef struct test_results //test results
    {
        int i_n_transmitted;    //counter (transmissions)
        //more parameters will be added later
    } test_results;
    
    test_results test_result;
    
    static uint8_t test_start_process = false; //toggle by a button press (button 1)
    
    
    /*
     * this function is repeatedly called by the main process (while())
     * everytime it checks wheter or not the wright amount of time (parameter eg 500ms) has passed 
     * if enough time passed => it will try to send simple_on_off_client_set => if succesfull, then the counter will be increased
     */
    
    int test_process()
    {
        test_parameter_setup();
    
         if(test_start_process == true) // global variable to start or stop a test (can also be stopped by an extern source)
         {
             if(current_time + test_setup.n_time <= timer_now())       //check if enough time has passed (example 500ms)
             {
                if(MAX_TRANSMISSIONS <  test_setup.n_messages)
                {
                    test_setup.n_messages = MAX_TRANSMISSIONS;
                }
    
    
                //__LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "timer %d\n", timer_now());            
       
                if(simple_on_off_client_set(m_clients, !hal_led_pin_get(13 + 1)) == NRF_SUCCESS)
                {
                    latencyTable[test_result.i_n_transmitted] = timer_now();
                   // SEGGER_RTT_printf(0, "transmitted = %d\n", test_result.i_n_transmitted);
                    __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "transmitted = %d\n", test_result.i_n_transmitted);
                    test_result.i_n_transmitted++;
                }
                else
                {
                    for(int j = 0; j < 500000; j++);
                }
                if(test_result.i_n_transmitted >= test_setup.n_messages)
                {
                    for(int j = 0; j < 200000; j++); // add some delay
    
                    test_start_process = false;      //after reaching the predetermined number of transmissions => stop the test
                    SEGGER_RTT_printf(0, "transmitted = %d\n", test_result.i_n_transmitted);
    
                    test_result.i_n_transmitted = 0; //reset transmission counter
                }
                current_time = timer_now();          //start timing
              }
              else
              {
                //do nothing
              }
         }
         else
         {
            //do nothing
         }
        return test_start_process;
    }

    Without the simple_on_off_client_set() function it is working, if i setup a time like for example 500ms it will approximately print every 1s that the timer has been increased. When i execute this code with the simple_on_off_client_set() function it will work for i couple of times, but when i give as parameter 500 messages it will hang somewhere. with the error code which i already mentioned before.

    The server part just contains a counter, everytime it receives a message it increments the counter. When i press a button there it prints the number.

    Regards

  • Hi guys,

    What ended up being the resolution to this problem? I think I have encountered something similar,

    I have 6 server nodes and 1 client, and they run fine for a while (each server pushes data every 3 secs). After some time has passed they start asserting one by one, all at the same line "NRF_MESH_ASSERT(m_packet.bearer_bitmap == 0);", I was able to confirm this with a debugger connected to each server node.

  • It might be a bug that leads to this error. Another customer reported a similar issue as you have seen. It might be that the stack is trying to send a segmented message , which is why m_packet.bearer_bitmap is non-zero. It could be that the node gets interrupted by a mesh packet & tries to relay this packet. During the relaying, the node will check whether m_packet.bearer_bitmap is zero, which then leads to the assert. Have you tried with mesh sdk v1.0.1 to see if you get the same assert?

  • I haven't yet tried v1.0.1. As soon as i have time to do this, i will try it. What would be the problem if you are trying to segment a message?

  • Do messages still get segmented if this is set: "reliable.message.force_segmented = false;". Would it be worthwhile to see if reducing the packet size from 20 bytes to something like 15 bytes help? I read somewhere on the forum that the maximum size before segmentation happens is 15 bytes, is that correct?

  • I believe the mesh specification says 11bytes payload (including opcode). i would think that force_segmented is to literally force segmentation to be on (it would be weird that you can turn this off). and if you try to transmit a frame which is to large, wouldn't it generate an error (if you could disable segmentation)? Or it should go wrong immediately, because you are (partially) missing data....

    I can be wrong of course.

Reply
  • I believe the mesh specification says 11bytes payload (including opcode). i would think that force_segmented is to literally force segmentation to be on (it would be weird that you can turn this off). and if you try to transmit a frame which is to large, wouldn't it generate an error (if you could disable segmentation)? Or it should go wrong immediately, because you are (partially) missing data....

    I can be wrong of course.

Children
Related