espressif / esp-idf

Espressif IoT Development Framework. Official development framework for Espressif SoCs.
Apache License 2.0
13.67k stars 7.29k forks source link

ESP32: Communication between server and client on BLE-mesh (IDFGH-8273) #9759

Open francescogenovasi opened 2 years ago

francescogenovasi commented 2 years ago

Answers checklist.

IDF version.

ESP-IDF v5.0-dev-4257-g508661b03e

Operating System used.

macOS

How did you build your project?

CLion IDE

If you are using Windows, please specify command line type.

No response

What is the expected behavior?

In my project there are:

### I want to send my model from SERVER to PROVISONER and from BEACON to SERVER

My model is:

typedef struct __attribute__((packed)) {
    uint8_t uuid[16];
    uint16_t major;
    uint16_t minor;
    int rssi;
    double distance; // d = 10^( (A - RSSI) / (10*N) )
    int counter; 
} model_ibeacon_data_t;

The function

     esp_err_t esp_ble_mesh_server_model_send_msg(esp_ble_mesh_model_t *model, esp_ble_mesh_msg_ctx_t *ctx, uint32_t opcode, uint16_t length, uint8_t *data);

sends data from the SERVER to the PROVISONER. The data are captured in the PROVISONER with

     model_ibeacon_data_t ibeacon_response = *(model_ibeacon_data_t *)param->client_recv_publish_msg.msg;

The function

esp_err_t esp_ble_mesh_client_model_send_msg(esp_ble_mesh_model_t *model, esp_ble_mesh_msg_ctx_t *ctx, uint32_t opcode, uint16_t length, uint8_t *data, int32_t msg_timeout, bool need_rsp,vesp_ble_mesh_dev_role_t device_role);

sends data from BEACON to the SERVER. The data are captured in the SERVER with

model_ibeacon_data_t ibeacon_resp = *(model_ibeacon_data_t *) param->model_operation.model->user_data;

What is the actual behavior?

the communication between SERVER and PROVISONER works but the communication between BEACON and SERVER doesn't works. If I want to print the received data on the SERVER it prints zeros in all of the model's fields

UUID: : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
BLE_MESH: MESH MESSAGE SENT - MAJOR: 0, MINOR: 0, RSSI: -72 distance: 1.284386 - Counter #52

Steps to reproduce.

The BEACON's code is:

esp_err_t ble_beacon_mesh_send(void){
    esp_ble_mesh_msg_ctx_t ctx = {0};
    uint32_t opcode;
    esp_err_t err = ESP_OK;
    opcode = ESP_BLE_MESH_IBEACON_MODEL_OP_BEACON;

    ctx.net_idx = prov_key.net_idx;
    ctx.app_idx = prov_key.app_idx;
    ctx.addr = ESP_BLE_MESH_GROUP_PUB_ADDR;
    ctx.send_ttl = 7;
    ctx.send_rel = false;

    ESP_LOG_BUFFER_HEX("dev_uuid bbb", dev_uuid, 16);
    model_ibeacon_data_t *ibeacon_resp123 = (model_ibeacon_data_t *) ibeacon_model_client.model->user_data;
    ibeacon_resp123->major = 777;
    ibeacon_resp123->minor = 777;
    ibeacon_resp123->rssi = 777;
    ibeacon_resp123->distance = 777;
    ibeacon_resp123->counter = 777;
    ESP_LOGI("ibeacon_resp123: ", "MAJOR: %hu, MINOR: %d, RSSI: %d distance: %f - Counter #%d - \n",
             ibeacon_resp123->major, ibeacon_resp123->minor, ibeacon_resp123->rssi, ibeacon_resp123->distance, ibeacon_resp123->counter);
    err = esp_ble_mesh_client_model_send_msg(ibeacon_model_client.model, &ctx, opcode, sizeof(ibeacon_resp123), (uint8_t *) &ibeacon_resp123, 0, false, ROLE_NODE);
    if (err != ESP_OK) {
        ESP_LOGE("SEND_GET", "Sending error\n");
    }else {
        ESP_LOGI("SEND","Beaconing message sent");
    }
    return err;
}

The SERVER's code is:

void custom_ibeacon_server_callback(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:
            switch (param->model_operation.opcode) {
                case ESP_BLE_MESH_IBEACON_MODEL_OP_GET:;
                    model_ibeacon_data_t ibeacon_resp = *(model_ibeacon_data_t *) param->model_operation.model->user_data;

                    // print received data
                    esp_log_buffer_hex("UUID: ", ibeacon_resp.uuid, ESP_UUID_LEN_128);
                    ESP_LOGI(BLUETOOTH_MESH_TAG, "MESH MESSAGE SENT - MAJOR: %hu, MINOR: %d, RSSI: %d distance: %f - Counter #%d - \n",
                             ibeacon_resp.major, ibeacon_resp.minor, ibeacon_resp.rssi, ibeacon_resp.distance, ibeacon_resp.counter);

                    // send data from SERVER to PROVISONER
                    esp_err_t ib_err = esp_ble_mesh_server_model_send_msg(param->model_operation.model,
                                                                       param->model_operation.ctx,
                                                                       ESP_BLE_MESH_IBEACON_MODEL_OP_STATUS,
                                                                       sizeof(ibeacon_resp), (uint8_t *) &ibeacon_resp);
                    if (ib_err) {
                        ESP_LOGE(BLUETOOTH_MESH_TAG, "Failed to send message 0x%06x",
                                 ESP_BLE_MESH_IBEACON_MODEL_OP_STATUS);
                    }
                    break;
                case ESP_BLE_MESH_IBEACON_MODEL_OP_BEACON:;
                    int rssi = param->model_operation.ctx->recv_rssi;

                    model_ibeacon_data_t ibeaconData = *(model_ibeacon_data_t *) param->model_operation.model->user_data;

                    esp_log_buffer_hex("received from beacon, UUID:", ibeaconData.uuid, 16);
                    ESP_LOGI("received from beacon", "major: %d, minor: %d", ibeaconData.major, ibeaconData.minor);
                break;
                default:
                    break;
            }
            break;
        default:
            break;
    }
}

The PROVISONER's code is:

static void custom_ibeacon_client_callback(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:
            switch(param->model_operation.opcode){
                case ESP_BLE_MESH_IBEACON_MODEL_OP_STATUS:;
                    model_ibeacon_data_t ibeacon_response = *(model_ibeacon_data_t *)param->client_recv_publish_msg.msg;
                    uint8_t *uuid = get_uuid_from_addr(param->client_recv_publish_msg.ctx->addr);
                    // received data from SERVER are:
                    esp_log_buffer_hex("UUID: ", uuid, ESP_UUID_LEN_128);
                    ESP_LOGI("RECEIVED DATA:", "distance: %f", ibeacon_response.distance);
                    esp_log_buffer_hex("RECEIVED DATA: UUID ", ibeacon_response.uuid, ESP_UUID_LEN_128);
                    ESP_LOGI("RECEIVED DATA", "MAJOR: %hu, MINOR: %d, RSSI: %d distance: %f - Counter #%d - \n",
                             ibeacon_response.major, ibeacon_response.minor, ibeacon_response.rssi, ibeacon_response.distance, ibeacon_response.counter);
                    break;
            }
            break;
        default:
            break;
    }
}

Build or installation Logs.

No response

More Information.

I tried to do the following tests:

But I found the same results

JiaLWang commented 2 years ago

Hi @francescogenovasi There is something wrong in your SERVER's code. You can have a try with modifying the code model_ibeacon_data_t ibeacon_resp = *(model_ibeacon_data_t *) param->model_operation.model->user_data; to model_ibeacon_data_t ibeacon_resp = *(model_ibeacon_data_t *) param->model_operation.msg;.

Hope it can help you.

jiabuda commented 2 years ago

I am confused about SERVER's code, after the SERVER get data from BEACON, it call esp_ble_mesh_server_model_send_msg() to the Provisioner, the second argument ctx seems to be wrong?

ctx.addr is the beacon's address, isn't it? so the msg will send back to the BEACON instead of the Provisioner?

forx157 commented 2 years ago

hi, @jiabuda , the beacon's msg's dst address seems like a group address. Dose the server subscribe that group address? provisioner maybe subscribed that group address so that it can receive successfully.

francescogenovasi commented 1 year ago

unfortunately @JiaLWang your solution doesn't work. I tried it in SERVER's code in ESP_BLE_MESH_IBEACON_MODEL_OP_GET: case and in ESP_BLE_MESH_IBEACON_MODEL_OP_BEACON: case and then the esp32 is rebooting itself unexpectedly (I think that it founds some errors) thanks anyway

francescogenovasi commented 1 year ago

@jiabuda ctx.addr is the group address in which there are the BEACON, the PROVIONER and the SERVER

@forx157 yes, in SERVER's code (after provisioning) there is the following line esp_ble_mesh_model_subscribe_group_addr(esp_ble_mesh_get_primary_element_address(), CID_ESP,ESP_BLE_MESH_IBEACON_MODEL_ID_SERVER,ESP_BLE_MESH_GROUP_PUB_ADDR ); (obviously the ESP_BLE_MESH_GROUP_PUB_ADDR is the same)

forx157 commented 1 year ago

Hi, @francescogenovasi Dose the problem solved? if not, could you provide us with some log files(beacon, server, proversioner)?