BLE-MESH - Spontaneously send a message from a provisioned node to the provisioner

ZacDaMan
Posts: 47
Joined: Wed Dec 22, 2021 7:40 pm

BLE-MESH - Spontaneously send a message from a provisioned node to the provisioner

Postby ZacDaMan » Tue Nov 29, 2022 3:45 am

I'm setting up a BLE mesh with just two devices, a provisioner and a node, using the sensor_server and sensor_client examples as starting points, with the sensor_client being the provisioner. I want the node, the sensor_server, to send a message to the provisioner every 10 seconds or so, without first having to receive a message from the provisioner, ie via the button press included in the example.

How do I go about this? What information do I need? The calls to

Code: Select all

esp_ble_mesh_server_model_send_msg()
that the example makes are all in response to a message from the provisioner, and pass through the param->model and param->ctx received from that. If I want to just send a message, even a single byte, how? Do I need to retrieve/store the app/net key? I'm assuming I'll need the hard-coded PROV_OWN_ADDRESS of the provisioner to send the message to. Are there any example that show a node spontaneously messaging the provisioner like this?

ZacDaMan
Posts: 47
Joined: Wed Dec 22, 2021 7:40 pm

Re: BLE-MESH - Spontaneously send a message from a provisioned node to the provisioner

Postby ZacDaMan » Mon Dec 05, 2022 3:56 am

Tried a couple of things so far, no luck. Tried adding

Code: Select all

esp_ble_mesh_msg_ctx_t test_ctx
and filling it in with the address of the provisioner but it didn't get through.

ZacDaMan
Posts: 47
Joined: Wed Dec 22, 2021 7:40 pm

Re: BLE-MESH - Spontaneously send a message from a provisioned node to the provisioner

Postby ZacDaMan » Mon Dec 05, 2022 11:49 pm

OK I modified the code so after provisioning, the provisioner sends a normal request, and the provisioned node saves the model and ctx from that request.

Code: Select all

	test_model = param->model;
        test_ctx = param->ctx;
I then use those to send a message to the provisioner when a button is pressed:

Code: Select all

void button2_msg(){
    ESP_LOGI(TAG, "BUTTON 2 PRESS");
    esp_err_t err = esp_ble_mesh_server_model_send_msg(test_model, &test_ctx,
            ESP_BLE_MESH_MODEL_OP_GEN_USER_PROPERTY_STATUS, 6, (uint8_t*)"Hello");
    if (err) {
        ESP_LOGE(TAG, "Send message failed (err %d)", err);
        return;
    }
}
This doesn't return an error, so I think it's working? I don't know how to receive it on the other end though - what callback would this trigger?

ZacDaMan
Posts: 47
Joined: Wed Dec 22, 2021 7:40 pm

Re: BLE-MESH - Spontaneously send a message from a provisioned node to the provisioner

Postby ZacDaMan » Tue Dec 06, 2022 9:09 pm

It didn't feel like I was getting anywhere, so I switched to using the vendor_client and vendor_server examples, as I was able to send a string using that example - still only in response to a message from the provisioner though. I tried pulling out the code from the callback that responds, but it still doesn't seem to be doing anything. Here's the working code that sends a string in response to a button push from the provisioner (note the line where I copy the details to test_ctx for future use):

Code: Select all

static void example_ble_mesh_custom_model_cb(esp_ble_mesh_model_cb_event_t event,
                                             esp_ble_mesh_model_cb_param_t *param)
{
    switch (event) {
    case ESP_BLE_MESH_MODEL_OPERATION_EVT:
        if (param->model_operation.opcode == ESP_BLE_MESH_VND_MODEL_OP_SEND) {
            uint16_t tid = *(uint16_t *)param->model_operation.msg;
            test_ctx = *param->model_operation.ctx;
            ESP_LOGI(TAG, "Recv 0x%06x, tid 0x%04x", param->model_operation.opcode, tid);
            char *mydata = "TEST STRING PASSING";
            ESP_LOGI(TAG, "NetKey Index: 0x%06x", param->model_operation.ctx->net_idx);
            esp_err_t err = esp_ble_mesh_server_model_send_msg(&vnd_models[0],
                    param->model_operation.ctx, ESP_BLE_MESH_VND_MODEL_OP_STATUS,
                    strlen(mydata)+1, (uint8_t *)mydata);
            if (err) {
                ESP_LOGE(TAG, "Failed to send message 0x%06x", ESP_BLE_MESH_VND_MODEL_OP_STATUS);
            }
        }
        break;
And here's the code on the provisioner side of things that triggers the ESP_BLE_MESH_MODEL_OPERATION_EVT (runs when the button is pushed):

Code: Select all

void example_ble_mesh_send_vendor_message(bool resend)
{
    esp_ble_mesh_msg_ctx_t ctx = {0};
    uint32_t opcode;
    esp_err_t err;

    ctx.net_idx = prov_key.net_idx;
    ctx.app_idx = prov_key.app_idx;
    ctx.addr = store.server_addr;
    ctx.send_ttl = MSG_SEND_TTL;
    ctx.send_rel = MSG_SEND_REL;
    opcode = ESP_BLE_MESH_VND_MODEL_OP_SEND;

    if (resend == false) {
        store.vnd_tid++;
    }

    err = esp_ble_mesh_client_model_send_msg(vendor_client.model, &ctx, opcode,
            sizeof(store.vnd_tid), (uint8_t *)&store.vnd_tid, MSG_TIMEOUT, true, MSG_ROLE);
    if (err != ESP_OK) {
        ESP_LOGE(TAG, "Failed to send vendor message 0x%06x", opcode);
        return;
    }

    mesh_example_info_store(); /* Store proper mesh example info */
}
I tried to make my own function that would run on a button push instead of a mesh callback:

Code: Select all

void button_cb_msg(){
        char *mydata = "TEST STRING PASSING";
        esp_err_t err = esp_ble_mesh_server_model_send_msg(&vnd_models[0],
                &test_ctx, ESP_BLE_MESH_VND_MODEL_OP_STATUS,
                strlen(mydata)+1, (uint8_t *)mydata);
        if (err) {
            ESP_LOGE(TAG, "Failed to send message 0x%06x", ESP_BLE_MESH_VND_MODEL_OP_STATUS);
        }
}
And this runs without error, but I don't see the message appear on the provisioner's side of things like I do when the first callback runs. Am I copying the ctx wrong maybe?

ixtreme3
Posts: 7
Joined: Sat May 13, 2023 10:00 am

Re: BLE-MESH - Spontaneously send a message from a provisioned node to the provisioner

Postby ixtreme3 » Sun May 14, 2023 2:52 pm

I faced the same problem as you and I had exactly the same thoughts - save ctx after provisioning and try to send a message. Can you please tell me if it worked out for you in the end? Maybe you found another solution or modified an existing one... :roll:

Who is online

Users browsing this forum: No registered users and 94 guests