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

Too many method calls in serial interface (or any other) callback causes strange behavior in nRF Mesh SDK

Hi,

I'm using SDK v3.2 and I'm extending the lighting example. I'm developing an extension to the provisioner, to inform a back-end about the configuration of the subnet it is part of. For that, I use the existing serial interface handler. However, I also want to know the Network ID derived from the NetKey. For that, I use the Application serial command. Within that command, I define a more specific opcode, which leads to the underlying code:

static void serial_interface_cb(const uint8_t* p_data, uint32_t length)
{
    NRF_MESH_ASSERT(length > 0);

    switch(p_data[0])
    {
        case BLUESS_OPCODE_NETWORK_ID_DISCOVERY_SERIAL_COMMAND:
            ; // Empty statement
            mesh_key_index_t p_key_list[DSM_SUBNET_MAX_LIMIT];
            uint32_t p_count = DSM_SUBNET_MAX_LIMIT;

            dsm_subnet_get_all(p_key_list, &p_count);

            uint32_t length = sizeof(bluess_serial_opcode_t) + p_count * NRF_MESH_NETID_SIZE;
            uint32_t index = 0;

            uint8_t p_serial[length];

            p_serial[index] = BLUESS_OPCODE_NETWORK_ID_DISCOVERY_SERIAL_EVENT;
            index += sizeof(bluess_serial_opcode_t);


            for(uint32_t i = 0 ; i < p_count ; i++){
                nrf_mesh_beacon_secmat_t * p_secmat;
               
                uint8_t key = 0;
                uint32_t status = dsm_subnet_key_get(dsm_net_key_index_to_subnet_handle(p_key_list[i]), &key);
                if(status == NRF_SUCCESS){
                    status = nrf_mesh_keygen_beacon_secmat(&key, p_secmat);
                }
                
                memcpy(&p_serial[index], &p_secmat->net_id[0], NRF_MESH_NETID_SIZE);
                index += NRF_MESH_NETID_SIZE;
            }
            nrf_mesh_serial_tx(p_serial, length);
            break;
    }
}

As the provisioner is only part of one subnet, p_count will become equal to 1. This is the case from the start of the for-loop. However, I notice that during the for-loop, suddenly p_count becomes much larger, causing the loop to run endlessly. When commenting out the whole code within the for-loop, the callback is completed as it should, without p_count changing in between. At first glance, it seems that to many method calls within a callback, causes issues... Is there any explanation for this?

Kind regards,

Mathias

  • Hi Terje,

    Probably it'll be the callback function lasting for too long then.

    Could it be that when it lasts to long, other parts of the stack behave strangely and for some reason (part of) the heap gets cleared? That could be an explanation.

    Kind regards,

    Mathias

  • Hi,

    Trouble is we don't use a heap, so the stack growing into the (non-existing) heap shouldn't happen. Also, the stack is shared between SoftDevice and application, so no colliding stacks... Not quite sure what happens on a stack overflow, though.

    I am more curious as to how you determined p_count changed. How did you read that / output it?

    Regards,
    Terje

  • Via logging over JLink, which I understand I should avoid in a callback...

    But I think you're right about a status not returning NRF_SUCCESS... If I change nrf_mesh_beacon_secmat_t * p_secmat; to nrf_mesh_beacon_secmat_t p_secmat = {0}; and status = nrf_mesh_keygen_beacon_secmat(&key, p_secmat); to status = nrf_mesh_keygen_beacon_secmat(&key, &p_secmat);, then it works. So I think it was because of NULL pointers.

    Anyway, learned a lot today, also about the fact that the board doesn't use a heap. Thanks!

  • Hi,

    Of course! I see it as well now. Yes, that uninitialized pointer would definitely be an error. It is always important in C to be aware of where to allocate (and deallocate) memory, even if you only use the stack and static variables.

    By the way, it is perfectly possible to use a heap on the nRF SoCs, even though we tend not to use one in our SDKs.

    Regards,
    Terje

Related