Page 1 of 1

BLE MESH Generic Properties Server Property Value Becomes Null

Posted: Wed Jul 26, 2023 11:23 pm
by jtmopti
I am using the ESP-IDF to create a BLE MESH Network. Currently I am trying to create a Generic Manufacturers Property Server to make some properties of the device available on the network. Everything is working with the exception that I am not able to utilize the struct net_buf_simple *val within the esp_ble_mesh_generic_property_t struct to store the value of the properties as val->data becomes NULL. This results in a Guru Meditation Error: Core 0 panic'ed (Load access fault). Exception was unhandled.

Actually, I can see that the address of val->data is changing frequently (my code doesn't touch it after setup) but is always NULL in the generic_server_callback where it obviously needs to be accessed to send the response.

Some code snippets that show the relevant setup of the properties server:

Code: Select all

static esp_ble_mesh_gen_manu_prop_srv_t my_prop_server = {
    .rsp_ctrl.get_auto_rsp = ESP_BLE_MESH_SERVER_RSP_BY_APP,
    .rsp_ctrl.set_auto_rsp =  ESP_BLE_MESH_SERVER_RSP_BY_APP,
    .rsp_ctrl.status_auto_rsp = ESP_BLE_MESH_SERVER_RSP_BY_APP,  
};

ESP_BLE_MESH_MODEL_PUB_DEFINE(my_properties_server_pub, 2 + 8, ROLE_NODE);


esp_ble_mesh_generic_property_t *my_prop;
esp_ble_mesh_generic_property_t properties[1];
uint8_t property_info[5] = {0};

static void init_properties_server(){
    extract_property_value(); // fills the above array with correct data
    
    my_prop = (esp_ble_mesh_generic_property_t*)calloc(1, sizeof(esp_ble_mesh_generic_property_t));

    my_prop->id = 0x0011;
    my_prop->user_access = ESP_BLE_MESH_GEN_USER_ACCESS_READ;
    my_prop->admin_access = ESP_BLE_MESH_GEN_ADMIN_ACCESS_READ;
    my_prop->manu_access = ESP_BLE_MESH_GEN_MANU_ACCESS_READ;
    my_prop->val = NET_BUF_SIMPLE(5);
    net_buf_simple_init_with_data(my_prop->val, property_info, 5);

    properties[0] = *pulse_fw_version_prop;

    my_prop_server.property_count = 1;
    my_prop_server.properties = properties;
}
And the callback (all code is in same file):

Code: Select all

static void my_generic_server_cb(esp_ble_mesh_generic_server_cb_event_t event, 
                                        esp_ble_mesh_generic_server_cb_param_t *param){
    switch(event){
        case ESP_BLE_MESH_GENERIC_SERVER_RECV_GET_MSG_EVT:
            if(*(&param->ctx.recv_op) == ESP_BLE_MESH_MODEL_OP_GEN_MANUFACTURER_PROPERTIES_GET){
                 switch(*(&param->value.get.manu_property.property_id)){
                     case 0x0011:
                     	uint8_t data[8] = {0x00, 0x11, ESP_BLE_MESH_GEN_USER_ACCESS_READ};
                        memcpy(&data[3], my_prop_server.properties[0].val->data, 5);    // ERROR HAPPENS HERE
                        esp_ble_mesh_server_model_send_msg(param->model, &param->ctx, ESP_BLE_MESH_MODEL_OP_GEN_MANUFACTURER_PROPERTY_STATUS,
                                                    2+1+5, data);
                        break;
                    default: 
                        ESP_LOGI(TAG, "Manufacturer Property Get Unknown: 0x%X", *(&param->value.get.manu_property.property_id));
                        break;
                 }                
            }
            else
            {
                ESP_LOGI(TAG, "Received Generic Server Get, opcode: %lu", *(&param->ctx.recv_op));
            }
            break;
        default:
            ESP_LOGI(TAG, "Unhandled Generic Server event"); 
    }
    
    ESP_LOGI(TAG, "Generic server event 0x%02x", event);
};

I have done some debugging of the this trying to see why/how this becomes NULL and all I've found is that the address of the data in the net buffer is changing a lot. So something is messing with it - no where else does my code touch it. So some underlying parts of the IDF must be?

These properties are manufacturer properties that never change during run time, so I expect to be able to set them once at boot and then anytime there is a get for it then I will be able to get it out of the model to send back. Is this an incorrect assumption? Is this not where the value of the property should be stored?

Thanks for any suggestions as to why this would be changing.