NCS Mesh: How to get element index in sensor server get callback

I have multiple elements with multiple sensors (4x6 in total, all 4 elements has the same type of sensors). I need to find out which element called sensor get callback. In get callback arguments there is no server instance provided. How to identify to which element corresponds the callback? Otherwise I would need to implement 24 callback functions instead of 6 which would be not neat.

Parents
  • Hi, 

    I'm assuming you are talking about this callback: https://github.com/nrfconnect/sdk-nrf/blob/main/samples/bluetooth/mesh/sensor_server/src/model_handler.c#L69 

    True sending a server instance would help with this callback, if you are using exact same set of sensors (i.e. same "sensor[]" arrays) for all four model instances, as far as I can see, this seems impossible to resolve sensor server instance with current API.

    The workaround would be, to create four copies of the "sensors[]" array, maybe with different names (sensor1[], sensor2[], etc.) but the same contents, and pass them to the four model instances. Then inside the callback, using the given "*sensor" pointer find out which array it belongs to, and from the resolved array instance, use CONTAINER_OF() to get the server instance associated with it.

    Regards,
    Amanda

  • Hi Amanda, thank you for the answer!

    Then inside the callback, using the given "*sensor" pointer find out which array it belongs to, and from the resolved array instance, use CONTAINER_OF() to get the server instance associated with it.

    Not sure if I understood you properly. Below is what I have tried:

    for(int i = 0; i < ARRAY_SIZE(sensors1); i++)
    {
    	if(sensor == sensors1[i])
    	{
    		element_indx = CONTAINER_OF(sensors1, struct bt_mesh_sensor_srv, sensor_array)->model->elem_idx;
    		break;
    	}
    	else if(sensor == sensors2[i])
    	{
    		element_indx = CONTAINER_OF(sensors2, struct bt_mesh_sensor_srv, sensor_array)->model->elem_idx;
    		break;
    	}
    	else if(sensor == sensors3[i])
    	{
    		element_indx = CONTAINER_OF(sensors3, struct bt_mesh_sensor_srv, sensor_array)->model->elem_idx;
    		break;
    	}
    	else if(sensor == sensors4[i])
    	{
    		element_indx = CONTAINER_OF(sensors4, struct bt_mesh_sensor_srv, sensor_array)->model->elem_idx;
    		break;
    	}
    }

    Please correct me what is wrong, as I was not able to get the element index.

    create four copies of the "sensors[]" array

    But then all four will contain same pointers.

Reply
  • Hi Amanda, thank you for the answer!

    Then inside the callback, using the given "*sensor" pointer find out which array it belongs to, and from the resolved array instance, use CONTAINER_OF() to get the server instance associated with it.

    Not sure if I understood you properly. Below is what I have tried:

    for(int i = 0; i < ARRAY_SIZE(sensors1); i++)
    {
    	if(sensor == sensors1[i])
    	{
    		element_indx = CONTAINER_OF(sensors1, struct bt_mesh_sensor_srv, sensor_array)->model->elem_idx;
    		break;
    	}
    	else if(sensor == sensors2[i])
    	{
    		element_indx = CONTAINER_OF(sensors2, struct bt_mesh_sensor_srv, sensor_array)->model->elem_idx;
    		break;
    	}
    	else if(sensor == sensors3[i])
    	{
    		element_indx = CONTAINER_OF(sensors3, struct bt_mesh_sensor_srv, sensor_array)->model->elem_idx;
    		break;
    	}
    	else if(sensor == sensors4[i])
    	{
    		element_indx = CONTAINER_OF(sensors4, struct bt_mesh_sensor_srv, sensor_array)->model->elem_idx;
    		break;
    	}
    }

    Please correct me what is wrong, as I was not able to get the element index.

    create four copies of the "sensors[]" array

    But then all four will contain same pointers.

Children
  • Hi, 

    Yes, right, I need to correct this. To resolve the pointer, you would need four copies instances of sensors array, with each array having the same sensor types but as different variables. For example:

    static struct bt_mesh_sensor chip_temp1 = {
        .type = &bt_mesh_sensor_present_dev_op_temp,
        .get = chip_temp_get,
    };
     
    static struct bt_mesh_sensor chip_temp2 = {
        .type = &bt_mesh_sensor_present_dev_op_temp,
        .get = chip_temp_get,
    };
    
    
    static struct bt_mesh_sensor *const sensors1[] = {
        &chip_temp1,
    };
     
    static struct bt_mesh_sensor *const sensors2[] = {
        &chip_temp2,
    };

    This is not a very elegant solution, and we are indeed planning to add server contexts to callbacks. However, I'm not fully sure if we can release this update in the upcoming v1.9 release.

    -Amanda

Related