I am creating a very simple BLE mesh network. I have enabled both the provisioner and node roles on all devices. When I press a button on one device, it will begin provisioning all other devices within range. This part works fine.
Each device has a single vendor server. When the device state changes, any device is to publish a message to the all nodes address. The provisioner uses its configuration client to bind an app key to the servers on the other nodes, and also to set the publication address.
What I don't understand is what I need to do to get the provisioner device also publishing in exactly the same way. Here's what I've tried, extracted from the provisioner event handler:
if (param->provisioner_add_app_key_comp.err_code == 0)
prov_key.app_idx = param->provisioner_add_app_key_comp.app_idx;
esp_err_t err =
if (err != ESP_OK)
ESP_LOGE(TAG, "Failed to bind AppKey to vendor client");
if (param->provisioner_bind_app_key_to_model_comp.err_code == 0)
// Configure our local node to publish to 0xFFFF.
myPub.publish_addr = 0xFFFF;
myPub.retransmit = 0;
myPub.ttl = 7;
myPub.period = 0;
But when I call esp_ble_mesh_model_publish(), it expects a role. If I give it ROLE_NODE, I get an error that there's no appkey (even though I just bound it). If I give it ROLE_PROVISIONER, I get the error
E (970394) BLE_MESH: bt_mesh_set_client_model_role, Invalid parameter
E (970394) BLE_MESH: btc_ble_mesh_model_call_handler, Failed to set model role
Why does publish care what role I'm in? Isn't it just sending a message?
Any suggestions on getting this to work? I think I need to add the app key to the list of keys used when it publishes as a node, but I don't know how to do that locally (as opposed to using a configuration client on another node to set it up).