Skip to content

Instantly share code, notes, and snippets.

@lucasssvaz
Last active October 27, 2025 03:36
Show Gist options
  • Select an option

  • Save lucasssvaz/bd105988aaf72ec291ecf94ecc2c692d to your computer and use it in GitHub Desktop.

Select an option

Save lucasssvaz/bd105988aaf72ec291ecf94ecc2c692d to your computer and use it in GitHub Desktop.

Revisions

  1. lucasssvaz revised this gist Apr 8, 2024. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion README.md
    Original file line number Diff line number Diff line change
    @@ -3,4 +3,4 @@
    These are modified files to be able to compile the ble_mesh.ino example.
    Note that a compilation error will still occur as the libraries need to be recompiled with [these configs](https://github.com/espressif/esp-idf/blob/release/v5.1/examples/bluetooth/esp_ble_mesh/ble_mesh_node/onoff_server/sdkconfig.defaults).

    This is based on the [ESP-IDF Example](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/esp-ble-mesh/ble-mesh-index.html#getting-started-with-esp-ble-mesh)
    This is based on the [ESP-IDF Example](https://docs.espressif.com/projects/esp-idf/en/release-v5.1/esp32/api-guides/esp-ble-mesh/ble-mesh-index.html#getting-started-with-esp-ble-mesh)
  2. lucasssvaz revised this gist Apr 8, 2024. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion README.md
    Original file line number Diff line number Diff line change
    @@ -1,6 +1,6 @@
    # BLE Mesh Example

    These are modified files to be able to compile the ble_mesh.ino example.
    Note that a compilation error will still occur as the libraries need to be recompiled with [these configs](https://github.com/espressif/esp-idf/blob/master/examples/bluetooth/esp_ble_mesh/ble_mesh_node/onoff_server/sdkconfig.defaults)
    Note that a compilation error will still occur as the libraries need to be recompiled with [these configs](https://github.com/espressif/esp-idf/blob/release/v5.1/examples/bluetooth/esp_ble_mesh/ble_mesh_node/onoff_server/sdkconfig.defaults).

    This is based on the [ESP-IDF Example](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/esp-ble-mesh/ble-mesh-index.html#getting-started-with-esp-ble-mesh)
  3. lucasssvaz revised this gist Sep 12, 2023. 3 changed files with 300 additions and 1647 deletions.
    594 changes: 271 additions & 323 deletions ble_mesh.ino
    Original file line number Diff line number Diff line change
    @@ -1,4 +1,5 @@
    #include "BLEDevice.h"
    #include "esp_bt.h"
    #include "esp_bt_main.h"
    #include "esp_bt_device.h"
    #include "esp_ble_mesh_defs.h"
    #include "esp_ble_mesh_common_api.h"
    @@ -8,37 +9,45 @@
    #include "esp_ble_mesh_generic_model_api.h"
    #include "esp_ble_mesh_local_data_operation_api.h"

    #define LED_R 25
    #define LED_G 26
    #define LED_B 27
    #define LED_ON 1
    #define LED_OFF 0

    #define CID_ESP 0x02E5

    struct led_state_s
    {
    uint8_t current;
    uint8_t previous;
    uint8_t pin;
    char *name;
    #define LED_R GPIO_NUM_25
    #define LED_G GPIO_NUM_26
    #define LED_B GPIO_NUM_27

    #define LED_ON 1
    #define LED_OFF 0

    struct _led_state {
    uint8_t current;
    uint8_t previous;
    uint8_t pin;
    char *name;
    };

    struct led_state_s led_state[3] = {
    {LED_OFF, LED_OFF, LED_R, "red"},
    {LED_OFF, LED_OFF, LED_G, "green"},
    {LED_OFF, LED_OFF, LED_B, "blue"}};
    struct _led_state led_state[3] = {
    { LED_OFF, LED_OFF, LED_R, "red" },
    { LED_OFF, LED_OFF, LED_G, "green" },
    { LED_OFF, LED_OFF, LED_B, "blue" },
    };

    static uint8_t dev_uuid[16] = {0xdd, 0xdd};
    static uint8_t dev_uuid[16] = { 0xdd, 0xdd };

    static esp_ble_mesh_cfg_srv_t config_server = {
    /* 3 transmissions with 20ms interval */
    .net_transmit = ESP_BLE_MESH_TRANSMIT(2, 20),
    .relay = ESP_BLE_MESH_RELAY_DISABLED,
    .relay_retransmit = ESP_BLE_MESH_TRANSMIT(2, 20),
    .beacon = ESP_BLE_MESH_BEACON_ENABLED,
    #if defined(CONFIG_BLE_MESH_GATT_PROXY_SERVER)
    .gatt_proxy = ESP_BLE_MESH_GATT_PROXY_ENABLED,
    #else
    .gatt_proxy = ESP_BLE_MESH_GATT_PROXY_NOT_SUPPORTED,
    #endif
    #if defined(CONFIG_BLE_MESH_FRIEND)
    .friend_state = ESP_BLE_MESH_FRIEND_ENABLED,
    #else
    .friend_state = ESP_BLE_MESH_FRIEND_NOT_SUPPORTED,
    #endif
    .default_ttl = 7,
    };

    @@ -47,23 +56,23 @@ static esp_ble_mesh_gen_onoff_srv_t onoff_server_0 = {
    .rsp_ctrl = {
    .get_auto_rsp = ESP_BLE_MESH_SERVER_AUTO_RSP,
    .set_auto_rsp = ESP_BLE_MESH_SERVER_AUTO_RSP,
    },
    }
    };

    ESP_BLE_MESH_MODEL_PUB_DEFINE(onoff_pub_1, 2 + 3, ROLE_NODE);
    static esp_ble_mesh_gen_onoff_srv_t onoff_server_1 = {
    .rsp_ctrl = {
    .get_auto_rsp = ESP_BLE_MESH_SERVER_RSP_BY_APP,
    .set_auto_rsp = ESP_BLE_MESH_SERVER_RSP_BY_APP,
    },
    }
    };

    ESP_BLE_MESH_MODEL_PUB_DEFINE(onoff_pub_2, 2 + 3, ROLE_NODE);
    static esp_ble_mesh_gen_onoff_srv_t onoff_server_2 = {
    .rsp_ctrl = {
    .get_auto_rsp = ESP_BLE_MESH_SERVER_AUTO_RSP,
    .set_auto_rsp = ESP_BLE_MESH_SERVER_RSP_BY_APP,
    },
    }
    };

    static esp_ble_mesh_model_t root_models[] = {
    @@ -105,374 +114,313 @@ static esp_ble_mesh_prov_t provision = {
    #endif
    };

    static void board_led_init(void)
    void ble_mesh_get_dev_uuid(uint8_t *dev_uuid)
    {
    for (int i = 0; i < 3; i++)
    {
    pinMode(led_state[i].pin, OUTPUT);
    digitalWrite(led_state[i].pin, LED_OFF);
    led_state[i].previous = LED_OFF;
    }
    if (dev_uuid == NULL) {
    printf("%s, Invalid device uuid\n", __func__);
    return;
    }

    /* Copy device address to the device uuid with offset equals to 2 here.
    * The first two bytes is used for matching device uuid by Provisioner.
    * And using device address here is to avoid using the same device uuid
    * by different unprovisioned devices.
    */
    memcpy(dev_uuid + 2, esp_bt_dev_get_address(), BD_ADDR_LEN);
    }

    void board_led_operation(uint8_t pin, uint8_t onoff)
    esp_err_t bluetooth_init(void)
    {
    for (int i = 0; i < 3; i++)
    {
    if (led_state[i].pin != pin)
    {
    continue;
    esp_err_t ret;

    ESP_ERROR_CHECK(esp_bt_controller_mem_release(ESP_BT_MODE_CLASSIC_BT));

    esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT();
    ret = esp_bt_controller_init(&bt_cfg);
    if (ret) {
    printf("%s initialize controller failed\n", __func__);
    return ret;
    }

    if (onoff == led_state[i].previous)
    {
    printf("led %s is already %s\n",
    led_state[i].name, (onoff ? "on" : "off"));
    return;
    ret = esp_bt_controller_enable(ESP_BT_MODE_BLE);
    if (ret) {
    printf("%s enable controller failed\n", __func__);
    return ret;
    }
    ret = esp_bluedroid_init();
    if (ret) {
    printf("%s init bluetooth failed\n", __func__);
    return ret;
    }
    ret = esp_bluedroid_enable();
    if (ret) {
    printf("%s enable bluetooth failed\n", __func__);
    return ret;
    }

    return ret;
    }

    digitalWrite(pin, onoff);
    led_state[i].previous = onoff;
    return;
    }
    void board_led_operation(uint8_t pin, uint8_t onoff)
    {
    for (int i = 0; i < 3; i++) {
    if (led_state[i].pin != pin) {
    continue;
    }
    if (onoff == led_state[i].previous) {
    printf("led %s is already %s\n",
    led_state[i].name, (onoff ? "on" : "off"));
    return;
    }
    digitalWrite(pin, onoff);
    led_state[i].previous = onoff;
    return;
    }

    printf("LED is not found!\n");
    printf("LED is not found!\n");
    }

    void ble_mesh_get_dev_uuid(uint8_t *dev_uuid)
    static void board_led_init(void)
    {
    if (dev_uuid == NULL)
    {
    printf("%s, Invalid device uuid\n", __func__);
    return;
    }

    /* Copy device address to the device uuid with offset equals to 2 here.
    * The first two bytes is used for matching device uuid by Provisioner.
    * And using device address here is to avoid using the same device uuid
    * by different unprovisioned devices.
    */
    memcpy(dev_uuid + 2, esp_bt_dev_get_address(), BD_ADDR_LEN);
    for (int i = 0; i < 3; i++) {
    pinMode(led_state[i].pin, OUTPUT);
    digitalWrite(led_state[i].pin, LED_OFF);
    led_state[i].previous = LED_OFF;
    }
    }

    static void prov_complete(uint16_t net_idx, uint16_t addr, uint8_t flags, uint32_t iv_index)
    {
    printf("net_idx: 0x%04x, addr: 0x%04x\n", net_idx, addr);
    printf("flags: 0x%02x, iv_index: 0x%08\n" PRIx32, flags, iv_index);
    board_led_operation(LED_G, LED_OFF);
    printf("net_idx: 0x%04x, addr: 0x%04x\n", net_idx, addr);
    printf("flags: 0x%02x, iv_index: 0x%08\n" PRIx32, flags, iv_index);
    board_led_operation(LED_G, LED_OFF);
    }

    static void example_changeled_state_s(esp_ble_mesh_model_t *model,
    esp_ble_mesh_msg_ctx_t *ctx, uint8_t onoff)
    static void example_change_led_state(esp_ble_mesh_model_t *model,
    esp_ble_mesh_msg_ctx_t *ctx, uint8_t onoff)
    {
    uint16_t primary_addr = esp_ble_mesh_get_primary_element_address();
    uint8_t elem_count = esp_ble_mesh_get_element_count();
    struct led_state_s *led = NULL;
    uint8_t i;

    if (ESP_BLE_MESH_ADDR_IS_UNICAST(ctx->recv_dst))
    {
    for (i = 0; i < elem_count; i++)
    {
    if (ctx->recv_dst == (primary_addr + i))
    {
    led = &led_state[i];
    uint16_t primary_addr = esp_ble_mesh_get_primary_element_address();
    uint8_t elem_count = esp_ble_mesh_get_element_count();
    struct _led_state *led = NULL;
    uint8_t i;

    if (ESP_BLE_MESH_ADDR_IS_UNICAST(ctx->recv_dst)) {
    for (i = 0; i < elem_count; i++) {
    if (ctx->recv_dst == (primary_addr + i)) {
    led = &led_state[i];
    board_led_operation(led->pin, onoff);
    }
    }
    } else if (ESP_BLE_MESH_ADDR_IS_GROUP(ctx->recv_dst)) {
    if (esp_ble_mesh_is_model_subscribed_to_group(model, ctx->recv_dst)) {
    led = &led_state[model->element->element_addr - primary_addr];
    board_led_operation(led->pin, onoff);
    }
    } else if (ctx->recv_dst == 0xFFFF) {
    led = &led_state[model->element->element_addr - primary_addr];
    board_led_operation(led->pin, onoff);
    }
    }
    }
    else if (ESP_BLE_MESH_ADDR_IS_GROUP(ctx->recv_dst))
    {
    if (esp_ble_mesh_is_model_subscribed_to_group(model, ctx->recv_dst))
    {
    led = &led_state[model->element->element_addr - primary_addr];
    board_led_operation(led->pin, onoff);
    }
    }
    else if (ctx->recv_dst == 0xFFFF)
    {
    led = &led_state[model->element->element_addr - primary_addr];
    board_led_operation(led->pin, onoff);
    }
    }

    static void example_handle_gen_onoff_msg(esp_ble_mesh_model_t *model,
    esp_ble_mesh_msg_ctx_t *ctx,
    esp_ble_mesh_server_recv_gen_onoff_set_t *set)
    {
    esp_ble_mesh_gen_onoff_srv_t *srv = (esp_ble_mesh_gen_onoff_srv_t *)model->user_data;

    switch (ctx->recv_op)
    {
    case ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_GET:
    esp_ble_mesh_server_model_send_msg(model,
    ctx,
    ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_STATUS,
    sizeof(srv->state.onoff),
    &srv->state.onoff);
    break;

    case ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_SET:
    case ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_SET_UNACK:
    if (set->op_en == false)
    {
    srv->state.onoff = set->onoff;
    }
    else
    {
    /* TODO: Delay and state transition */
    srv->state.onoff = set->onoff;
    }
    if (ctx->recv_op == ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_SET)
    {
    esp_ble_mesh_server_model_send_msg(model,
    ctx,
    ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_STATUS,
    sizeof(srv->state.onoff),
    &srv->state.onoff);
    esp_ble_mesh_gen_onoff_srv_t *srv = (esp_ble_mesh_gen_onoff_srv_t *) model->user_data;

    switch (ctx->recv_op) {
    case ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_GET:
    esp_ble_mesh_server_model_send_msg(model, ctx,
    ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_STATUS, sizeof(srv->state.onoff), &srv->state.onoff);
    break;
    case ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_SET:
    case ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_SET_UNACK:
    if (set->op_en == false) {
    srv->state.onoff = set->onoff;
    } else {
    /* TODO: Delay and state transition */
    srv->state.onoff = set->onoff;
    }
    if (ctx->recv_op == ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_SET) {
    esp_ble_mesh_server_model_send_msg(model, ctx,
    ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_STATUS, sizeof(srv->state.onoff), &srv->state.onoff);
    }
    esp_ble_mesh_model_publish(model, ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_STATUS,
    sizeof(srv->state.onoff), &srv->state.onoff, ROLE_NODE);
    example_change_led_state(model, ctx, srv->state.onoff);
    break;
    default:
    break;
    }

    esp_ble_mesh_model_publish(model,
    ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_STATUS,
    sizeof(srv->state.onoff),
    &srv->state.onoff,
    ROLE_NODE);

    example_changeled_state_s(model, ctx, srv->state.onoff);
    break;

    default:
    break;
    }
    }

    static void example_ble_mesh_provisioning_cb(esp_ble_mesh_prov_cb_event_t event,
    esp_ble_mesh_prov_cb_param_t *param)
    {
    switch (event)
    {
    case ESP_BLE_MESH_PROV_REGISTER_COMP_EVT:
    printf("ESP_BLE_MESH_PROV_REGISTER_COMP_EVT, err_code %d\n", param->prov_register_comp.err_code);
    break;

    case ESP_BLE_MESH_NODE_PROV_ENABLE_COMP_EVT:
    printf("ESP_BLE_MESH_NODE_PROV_ENABLE_COMP_EVT, err_code %d\n", param->node_prov_enable_comp.err_code);
    break;

    case ESP_BLE_MESH_NODE_PROV_LINK_OPEN_EVT:
    printf("ESP_BLE_MESH_NODE_PROV_LINK_OPEN_EVT, bearer %s\n",
    param->node_prov_link_open.bearer == ESP_BLE_MESH_PROV_ADV ? "PB-ADV" : "PB-GATT");
    break;

    case ESP_BLE_MESH_NODE_PROV_LINK_CLOSE_EVT:
    printf("ESP_BLE_MESH_NODE_PROV_LINK_CLOSE_EVT, bearer %s\n",
    param->node_prov_link_close.bearer == ESP_BLE_MESH_PROV_ADV ? "PB-ADV" : "PB-GATT");
    break;

    case ESP_BLE_MESH_NODE_PROV_COMPLETE_EVT:
    printf("ESP_BLE_MESH_NODE_PROV_COMPLETE_EVT\n");
    prov_complete(param->node_prov_complete.net_idx, param->node_prov_complete.addr,
    param->node_prov_complete.flags, param->node_prov_complete.iv_index);
    break;

    case ESP_BLE_MESH_NODE_PROV_RESET_EVT:
    printf("ESP_BLE_MESH_NODE_PROV_RESET_EVT\n");
    break;

    case ESP_BLE_MESH_NODE_SET_UNPROV_DEV_NAME_COMP_EVT:
    printf("ESP_BLE_MESH_NODE_SET_UNPROV_DEV_NAME_COMP_EVT, err_code %d\n", param->node_set_unprov_dev_name_comp.err_code);
    break;

    default:
    break;
    }
    switch (event) {
    case ESP_BLE_MESH_PROV_REGISTER_COMP_EVT:
    printf("ESP_BLE_MESH_PROV_REGISTER_COMP_EVT, err_code %d\n", param->prov_register_comp.err_code);
    break;
    case ESP_BLE_MESH_NODE_PROV_ENABLE_COMP_EVT:
    printf("ESP_BLE_MESH_NODE_PROV_ENABLE_COMP_EVT, err_code %d\n", param->node_prov_enable_comp.err_code);
    break;
    case ESP_BLE_MESH_NODE_PROV_LINK_OPEN_EVT:
    printf("ESP_BLE_MESH_NODE_PROV_LINK_OPEN_EVT, bearer %s\n",
    param->node_prov_link_open.bearer == ESP_BLE_MESH_PROV_ADV ? "PB-ADV" : "PB-GATT");
    break;
    case ESP_BLE_MESH_NODE_PROV_LINK_CLOSE_EVT:
    printf("ESP_BLE_MESH_NODE_PROV_LINK_CLOSE_EVT, bearer %s\n",
    param->node_prov_link_close.bearer == ESP_BLE_MESH_PROV_ADV ? "PB-ADV" : "PB-GATT");
    break;
    case ESP_BLE_MESH_NODE_PROV_COMPLETE_EVT:
    printf("ESP_BLE_MESH_NODE_PROV_COMPLETE_EVT\n");
    prov_complete(param->node_prov_complete.net_idx, param->node_prov_complete.addr,
    param->node_prov_complete.flags, param->node_prov_complete.iv_index);
    break;
    case ESP_BLE_MESH_NODE_PROV_RESET_EVT:
    printf("ESP_BLE_MESH_NODE_PROV_RESET_EVT\n");
    break;
    case ESP_BLE_MESH_NODE_SET_UNPROV_DEV_NAME_COMP_EVT:
    printf("ESP_BLE_MESH_NODE_SET_UNPROV_DEV_NAME_COMP_EVT, err_code %d\n", param->node_set_unprov_dev_name_comp.err_code);
    break;
    default:
    break;
    }
    }

    static void example_ble_mesh_generic_server_cb(esp_ble_mesh_generic_server_cb_event_t event,
    esp_ble_mesh_generic_server_cb_param_t *param)
    {
    esp_ble_mesh_gen_onoff_srv_t *srv;
    printf("event 0x%02x, opcode 0x%04" PRIx32 ", src 0x%04x, dst 0x%04x\n",
    event, param->ctx.recv_op, param->ctx.addr, param->ctx.recv_dst);

    switch (event)
    {
    case ESP_BLE_MESH_GENERIC_SERVER_STATE_CHANGE_EVT:
    printf("ESP_BLE_MESH_GENERIC_SERVER_STATE_CHANGE_EVT\n");
    if (param->ctx.recv_op == ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_SET ||
    param->ctx.recv_op == ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_SET_UNACK)
    {
    printf("onoff 0x%02x\n", param->value.state_change.onoff_set.onoff);
    example_changeled_state_s(param->model, &param->ctx, param->value.state_change.onoff_set.onoff);
    }
    break;

    case ESP_BLE_MESH_GENERIC_SERVER_RECV_GET_MSG_EVT:
    printf("ESP_BLE_MESH_GENERIC_SERVER_RECV_GET_MSG_EVT\n");
    if (param->ctx.recv_op == ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_GET)
    {
    srv = (esp_ble_mesh_gen_onoff_srv_t *)param->model->user_data;
    printf("onoff 0x%02x\n", srv->state.onoff);
    example_handle_gen_onoff_msg(param->model, &param->ctx, NULL);
    }
    break;

    case ESP_BLE_MESH_GENERIC_SERVER_RECV_SET_MSG_EVT:
    printf("ESP_BLE_MESH_GENERIC_SERVER_RECV_SET_MSG_EVT\n");
    if (param->ctx.recv_op == ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_SET ||
    param->ctx.recv_op == ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_SET_UNACK)
    {
    printf("onoff 0x%02x, tid 0x%02x\n", param->value.set.onoff.onoff, param->value.set.onoff.tid);
    if (param->value.set.onoff.op_en)
    {
    printf("trans_time 0x%02x, delay 0x%02x\n",
    param->value.set.onoff.trans_time, param->value.set.onoff.delay);
    }
    example_handle_gen_onoff_msg(param->model, &param->ctx, &param->value.set.onoff);
    esp_ble_mesh_gen_onoff_srv_t *srv;
    printf("event 0x%02x, opcode 0x%04" PRIx32 ", src 0x%04x, dst 0x%04x\n",
    event, param->ctx.recv_op, param->ctx.addr, param->ctx.recv_dst);

    switch (event) {
    case ESP_BLE_MESH_GENERIC_SERVER_STATE_CHANGE_EVT:
    printf("ESP_BLE_MESH_GENERIC_SERVER_STATE_CHANGE_EVT\n");
    if (param->ctx.recv_op == ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_SET ||
    param->ctx.recv_op == ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_SET_UNACK) {
    printf("onoff 0x%02x\n", param->value.state_change.onoff_set.onoff);
    example_change_led_state(param->model, &param->ctx, param->value.state_change.onoff_set.onoff);
    }
    break;
    case ESP_BLE_MESH_GENERIC_SERVER_RECV_GET_MSG_EVT:
    printf("ESP_BLE_MESH_GENERIC_SERVER_RECV_GET_MSG_EVT\n");
    if (param->ctx.recv_op == ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_GET) {
    srv = (esp_ble_mesh_gen_onoff_srv_t *) param->model->user_data;
    printf("onoff 0x%02x\n", srv->state.onoff);
    example_handle_gen_onoff_msg(param->model, &param->ctx, NULL);
    }
    break;
    case ESP_BLE_MESH_GENERIC_SERVER_RECV_SET_MSG_EVT:
    printf("ESP_BLE_MESH_GENERIC_SERVER_RECV_SET_MSG_EVT\n");
    if (param->ctx.recv_op == ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_SET ||
    param->ctx.recv_op == ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_SET_UNACK) {
    printf("onoff 0x%02x, tid 0x%02x\n", param->value.set.onoff.onoff, param->value.set.onoff.tid);
    if (param->value.set.onoff.op_en) {
    printf("trans_time 0x%02x, delay 0x%02x\n",
    param->value.set.onoff.trans_time, param->value.set.onoff.delay);
    }
    example_handle_gen_onoff_msg(param->model, &param->ctx, &param->value.set.onoff);
    }
    break;
    default:
    printf("Unknown Generic Server event 0x%02x\n", event);
    break;
    }
    break;

    default:
    printf("Unknown Generic Server event 0x%02x\n", event);
    break;
    }
    }

    static void example_ble_mesh_config_server_cb(esp_ble_mesh_cfg_server_cb_event_t event,
    esp_ble_mesh_cfg_server_cb_param_t *param)
    {
    if (event == ESP_BLE_MESH_CFG_SERVER_STATE_CHANGE_EVT)
    {
    switch (param->ctx.recv_op)
    {
    case ESP_BLE_MESH_MODEL_OP_APP_KEY_ADD:
    printf("ESP_BLE_MESH_MODEL_OP_APP_KEY_ADD\n");
    printf("net_idx 0x%04x, app_idx 0x%04x\n",
    param->value.state_change.appkey_add.net_idx,
    param->value.state_change.appkey_add.app_idx);
    ESP_LOG_BUFFER_HEX("AppKey", param->value.state_change.appkey_add.app_key, 16);
    break;

    case ESP_BLE_MESH_MODEL_OP_MODEL_APP_BIND:
    printf("ESP_BLE_MESH_MODEL_OP_MODEL_APP_BIND\n");
    printf("elem_addr 0x%04x, app_idx 0x%04x, cid 0x%04x, mod_id 0x%04x\n",
    param->value.state_change.mod_app_bind.element_addr,
    param->value.state_change.mod_app_bind.app_idx,
    param->value.state_change.mod_app_bind.company_id,
    param->value.state_change.mod_app_bind.model_id);
    break;

    case ESP_BLE_MESH_MODEL_OP_MODEL_SUB_ADD:
    printf("ESP_BLE_MESH_MODEL_OP_MODEL_SUB_ADD\n");
    printf("elem_addr 0x%04x, sub_addr 0x%04x, cid 0x%04x, mod_id 0x%04x\n",
    param->value.state_change.mod_sub_add.element_addr,
    param->value.state_change.mod_sub_add.sub_addr,
    param->value.state_change.mod_sub_add.company_id,
    param->value.state_change.mod_sub_add.model_id);
    break;

    default:
    break;
    if (event == ESP_BLE_MESH_CFG_SERVER_STATE_CHANGE_EVT) {
    switch (param->ctx.recv_op) {
    case ESP_BLE_MESH_MODEL_OP_APP_KEY_ADD:
    printf("ESP_BLE_MESH_MODEL_OP_APP_KEY_ADD\n");
    printf("net_idx 0x%04x, app_idx 0x%04x\n",
    param->value.state_change.appkey_add.net_idx,
    param->value.state_change.appkey_add.app_idx);
    printf("AppKey: \n");
    for (int i = 0; i < 16; i++) {
    printf("%02x", param->value.state_change.appkey_add.app_key[i]);
    }
    printf("\n");
    break;
    case ESP_BLE_MESH_MODEL_OP_MODEL_APP_BIND:
    printf("ESP_BLE_MESH_MODEL_OP_MODEL_APP_BIND\n");
    printf("elem_addr 0x%04x, app_idx 0x%04x, cid 0x%04x, mod_id 0x%04x\n",
    param->value.state_change.mod_app_bind.element_addr,
    param->value.state_change.mod_app_bind.app_idx,
    param->value.state_change.mod_app_bind.company_id,
    param->value.state_change.mod_app_bind.model_id);
    break;
    case ESP_BLE_MESH_MODEL_OP_MODEL_SUB_ADD:
    printf("ESP_BLE_MESH_MODEL_OP_MODEL_SUB_ADD\n");
    printf("elem_addr 0x%04x, sub_addr 0x%04x, cid 0x%04x, mod_id 0x%04x\n",
    param->value.state_change.mod_sub_add.element_addr,
    param->value.state_change.mod_sub_add.sub_addr,
    param->value.state_change.mod_sub_add.company_id,
    param->value.state_change.mod_sub_add.model_id);
    break;
    default:
    break;
    }
    }
    }
    }

    /*
    esp_err_t bluetooth_init(void)
    static esp_err_t ble_mesh_init(void)
    {
    esp_err_t ret;
    esp_err_t err = ESP_OK;

    ESP_ERROR_CHECK(esp_bt_controller_mem_release(ESP_BT_MODE_CLASSIC_BT));
    esp_ble_mesh_register_prov_callback(example_ble_mesh_provisioning_cb);
    esp_ble_mesh_register_config_server_callback(example_ble_mesh_config_server_cb);
    esp_ble_mesh_register_generic_server_callback(example_ble_mesh_generic_server_cb);

    esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT();
    ret = esp_bt_controller_init(&bt_cfg);
    if (ret)
    {
    printf("%s initialize controller failed\n", __func__);
    return ret;
    }
    ret = esp_bt_controller_enable(ESP_BT_MODE_BLE);
    if (ret)
    {
    printf("%s enable controller failed\n", __func__);
    return ret;
    }
    ret = esp_bluedroid_init();
    if (ret)
    {
    printf("%s init bluetooth failed\n", __func__);
    return ret;
    }
    ret = esp_bluedroid_enable();
    if (ret)
    {
    printf("%s enable bluetooth failed\n", __func__);
    return ret;
    }
    return ret;
    }
    */
    err = esp_ble_mesh_init(&provision, &composition);
    if (err != ESP_OK) {
    printf("Failed to initialize mesh stack (err %d)\n", err);
    return err;
    }

    static int ble_mesh_init(void)
    {
    esp_err_t err = ESP_OK;
    uint32_t flags = ESP_BLE_MESH_PROV_ADV | ESP_BLE_MESH_PROV_GATT;
    err = esp_ble_mesh_node_prov_enable((esp_ble_mesh_prov_bearer_t) flags);
    if (err != ESP_OK) {
    printf("Failed to enable mesh node (err %d)\n", err);
    return err;
    }

    esp_ble_mesh_register_prov_callback(example_ble_mesh_provisioning_cb);
    esp_ble_mesh_register_config_server_callback(example_ble_mesh_config_server_cb);
    esp_ble_mesh_register_generic_server_callback(example_ble_mesh_generic_server_cb);
    printf("BLE Mesh Node initialized\n");

    err = esp_ble_mesh_init(&provision, &composition);
    if (err != ESP_OK)
    {
    printf("Failed to initialize mesh stack (err %d)\n", err);
    return err;
    }
    board_led_operation(LED_G, LED_ON);

    int prov_flags = (ESP_BLE_MESH_PROV_ADV | ESP_BLE_MESH_PROV_GATT);
    err = esp_ble_mesh_node_prov_enable((esp_ble_mesh_prov_bearer_t)prov_flags);
    if (err != ESP_OK)
    {
    printf("Failed to enable mesh node (err %d)\n", err);
    return err;
    }

    printf("BLE Mesh Node initialized\n");

    board_led_operation(LED_G, LED_ON);

    return err;
    }

    void setup(void)
    {
    int ret;
    esp_err_t err;

    // Open serial communications and wait for port to open:
    Serial.begin(115200);
    while (!Serial)
    {
    ; // wait for serial port to connect. Needed for native USB port only
    }
    Serial.begin(115200);

    printf("Initializing...\n");
    printf("Initializing...\n");

    board_led_init();
    board_led_init();

    BLEDevice::init("");
    err = bluetooth_init();
    if (err) {
    printf("esp32_bluetooth_init failed (err %d)\n", err);
    return;
    }

    ble_mesh_get_dev_uuid(dev_uuid);
    ble_mesh_get_dev_uuid(dev_uuid);

    /* Initialize the Bluetooth Mesh Subsystem */
    ret = ble_mesh_init();
    if (ret)
    {
    printf("Bluetooth mesh init failed (err %d)\n", ret);
    }
    /* Initialize the Bluetooth Mesh Subsystem */
    err = ble_mesh_init();
    if (err) {
    printf("Bluetooth mesh init failed (err %d)\n", err);
    }
    }

    void loop(void)
    {
    delay(1);
    }
    57 changes: 29 additions & 28 deletions esp_ble_mesh_defs.h
    Original file line number Diff line number Diff line change
    @@ -261,41 +261,41 @@ typedef enum {
    #define ESP_BLE_MESH_MODEL_OP_3(b0, cid) ((((b0) << 16) | 0xC00000) | (cid))

    /*!< This macro is associated with BLE_MESH_MODEL_CB in mesh_access.h */
    #define ESP_BLE_MESH_SIG_MODEL(_id, _op, _pub, _user_data) \
    { \
    .model_id = (_id), \
    .pub = _pub, \
    .keys = { \
    ESP_BLE_MESH_KEY_UNUSED, \
    ESP_BLE_MESH_KEY_UNUSED, \
    ESP_BLE_MESH_KEY_UNUSED \
    }, \
    .groups = { \
    ESP_BLE_MESH_ADDR_UNASSIGNED, \
    ESP_BLE_MESH_ADDR_UNASSIGNED, \
    ESP_BLE_MESH_ADDR_UNASSIGNED \
    }, \
    .op = _op, \
    .user_data = _user_data, \
    #define ESP_BLE_MESH_SIG_MODEL(_id, _op, _pub, _user_data) \
    { \
    .model_id = (_id), \
    .pub = _pub, \
    .keys = { \
    ESP_BLE_MESH_KEY_UNUSED, \
    ESP_BLE_MESH_KEY_UNUSED, \
    ESP_BLE_MESH_KEY_UNUSED, \
    }, \
    .groups = { \
    ESP_BLE_MESH_ADDR_UNASSIGNED, \
    ESP_BLE_MESH_ADDR_UNASSIGNED, \
    ESP_BLE_MESH_ADDR_UNASSIGNED, \
    }, \
    .op = _op, \
    .user_data = _user_data, \
    }

    /*!< This macro is associated with BLE_MESH_MODEL_VND_CB in mesh_access.h */
    #define ESP_BLE_MESH_VENDOR_MODEL(_company, _id, _op, _pub, _user_data) \
    { \
    .vnd.company_id = (_company), \
    .vnd.model_id = (_id), \
    .op = _op, \
    .pub = _pub, \
    .keys = { \
    ESP_BLE_MESH_KEY_UNUSED, \
    ESP_BLE_MESH_KEY_UNUSED, \
    ESP_BLE_MESH_KEY_UNUSED \
    }, \
    ESP_BLE_MESH_KEY_UNUSED, \
    ESP_BLE_MESH_KEY_UNUSED, \
    ESP_BLE_MESH_KEY_UNUSED, \
    }, \
    .groups = { \
    ESP_BLE_MESH_ADDR_UNASSIGNED, \
    ESP_BLE_MESH_ADDR_UNASSIGNED, \
    ESP_BLE_MESH_ADDR_UNASSIGNED \
    }, \
    ESP_BLE_MESH_ADDR_UNASSIGNED, \
    ESP_BLE_MESH_ADDR_UNASSIGNED, \
    ESP_BLE_MESH_ADDR_UNASSIGNED, \
    }, \
    .op = _op, \
    .user_data = _user_data, \
    }

    @@ -475,6 +475,7 @@ typedef struct {
    #endif /* CONFIG_BLE_MESH_DEINIT */
    } esp_ble_mesh_model_cbs_t;


    /** Abstraction that describes a Mesh Model instance.
    * This structure is associated with struct bt_mesh_model in mesh_access.h
    */
    @@ -863,7 +864,7 @@ typedef enum {
    ESP_BLE_MESH_PROVISIONER_SET_HEARTBEAT_FILTER_TYPE_COMP_EVT, /*!< Provisioner set the heartbeat filter type completion event */
    ESP_BLE_MESH_PROVISIONER_SET_HEARTBEAT_FILTER_INFO_COMP_EVT, /*!< Provisioner set the heartbeat filter information completion event */
    ESP_BLE_MESH_PROVISIONER_RECV_HEARTBEAT_MESSAGE_EVT, /*!< Provisioner receive heartbeat message event */
    ESP_BLE_MESH_PROVISIONER_DRIECT_ERASE_SETTINGS_COMP_EVT, /*!< Provisioner directly erase settings completion event */
    ESP_BLE_MESH_PROVISIONER_DIRECT_ERASE_SETTINGS_COMP_EVT, /*!< Provisioner directly erase settings completion event */
    ESP_BLE_MESH_PROVISIONER_OPEN_SETTINGS_WITH_INDEX_COMP_EVT, /*!< Provisioner open settings with index completion event */
    ESP_BLE_MESH_PROVISIONER_OPEN_SETTINGS_WITH_UID_COMP_EVT, /*!< Provisioner open settings with user id completion event */
    ESP_BLE_MESH_PROVISIONER_CLOSE_SETTINGS_WITH_INDEX_COMP_EVT, /*!< Provisioner close settings with index completion event */
    @@ -1273,11 +1274,11 @@ typedef union {
    int8_t rssi; /*!< RSSI of the heartbeat message */
    } provisioner_recv_heartbeat; /*!< Event parameters of ESP_BLE_MESH_PROVISIONER_RECV_HEARTBEAT_MESSAGE_EVT */
    /**
    * @brief ESP_BLE_MESH_PROVISIONER_DRIECT_ERASE_SETTINGS_COMP_EVT
    * @brief ESP_BLE_MESH_PROVISIONER_DIRECT_ERASE_SETTINGS_COMP_EVT
    */
    struct {
    int err_code; /*!< Indicate the result of directly erasing settings by the Provisioner */
    } provisioner_direct_erase_settings_comp; /*!< Event parameters of ESP_BLE_MESH_PROVISIONER_DRIECT_ERASE_SETTINGS_COMP_EVT */
    } provisioner_direct_erase_settings_comp; /*!< Event parameters of ESP_BLE_MESH_PROVISIONER_DIRECT_ERASE_SETTINGS_COMP_EVT */
    /**
    * @brief ESP_BLE_MESH_PROVISIONER_OPEN_SETTINGS_WITH_INDEX_COMP_EVT
    */
    1,296 changes: 0 additions & 1,296 deletions esp_ble_mesh_generic_model_api.h
    Original file line number Diff line number Diff line change
    @@ -1,1296 +0,0 @@
    /*
    * SPDX-FileCopyrightText: 2017-2021 Espressif Systems (Shanghai) CO LTD
    *
    * SPDX-License-Identifier: Apache-2.0
    */

    /** @file
    * @brief Bluetooth Mesh Generic Client Model APIs.
    */

    #ifndef _ESP_BLE_MESH_GENERIC_MODEL_API_H_
    #define _ESP_BLE_MESH_GENERIC_MODEL_API_H_

    #include "esp_ble_mesh_defs.h"

    #ifdef __cplusplus
    extern "C" {
    #endif

    /** @def ESP_BLE_MESH_MODEL_GEN_ONOFF_CLI
    *
    * @brief Define a new Generic OnOff Client Model.
    *
    * @note This API needs to be called for each element on which
    * the application needs to have a Generic OnOff Client Model.
    *
    * @param cli_pub Pointer to the unique struct esp_ble_mesh_model_pub_t.
    * @param cli_data Pointer to the unique struct esp_ble_mesh_client_t.
    *
    * @return New Generic OnOff Client Model instance.
    */
    #define ESP_BLE_MESH_MODEL_GEN_ONOFF_CLI(cli_pub, cli_data) \
    ESP_BLE_MESH_SIG_MODEL(ESP_BLE_MESH_MODEL_ID_GEN_ONOFF_CLI, \
    NULL, cli_pub, cli_data)

    /** @def ESP_BLE_MESH_MODEL_GEN_LEVEL_CLI
    *
    * @brief Define a new Generic Level Client Model.
    *
    * @note This API needs to be called for each element on which
    * the application needs to have a Generic Level Client Model.
    *
    * @param cli_pub Pointer to the unique struct esp_ble_mesh_model_pub_t.
    * @param cli_data Pointer to the unique struct esp_ble_mesh_client_t.
    *
    * @return New Generic Level Client Model instance.
    */

    #define ESP_BLE_MESH_MODEL_GEN_LEVEL_CLI(cli_pub, cli_data) \
    ESP_BLE_MESH_SIG_MODEL(ESP_BLE_MESH_MODEL_ID_GEN_LEVEL_CLI, \
    NULL, cli_pub, cli_data)

    /** @def ESP_BLE_MESH_MODEL_GEN_DEF_TRANS_TIME_CLI
    *
    * @brief Define a new Generic Default Transition Time Client Model.
    *
    * @note This API needs to be called for each element on which
    * the application needs to have a Generic Default Transition
    * Time Client Model.
    *
    * @param cli_pub Pointer to the unique struct esp_ble_mesh_model_pub_t.
    * @param cli_data Pointer to the unique struct esp_ble_mesh_client_t.
    *
    * @return New Generic Default Transition Time Client Model instance.
    */
    #define ESP_BLE_MESH_MODEL_GEN_DEF_TRANS_TIME_CLI(cli_pub, cli_data) \
    ESP_BLE_MESH_SIG_MODEL(ESP_BLE_MESH_MODEL_ID_GEN_DEF_TRANS_TIME_CLI, \
    NULL, cli_pub, cli_data)

    /** @def ESP_BLE_MESH_MODEL_GEN_POWER_ONOFF_CLI
    *
    * @brief Define a new Generic Power OnOff Client Model.
    *
    * @note This API needs to be called for each element on which
    * the application needs to have a Generic Power OnOff Client Model.
    *
    * @param cli_pub Pointer to the unique struct esp_ble_mesh_model_pub_t.
    * @param cli_data Pointer to the unique struct esp_ble_mesh_client_t.
    *
    * @return New Generic Power OnOff Client Model instance.
    */
    #define ESP_BLE_MESH_MODEL_GEN_POWER_ONOFF_CLI(cli_pub, cli_data) \
    ESP_BLE_MESH_SIG_MODEL(ESP_BLE_MESH_MODEL_ID_GEN_POWER_ONOFF_CLI, \
    NULL, cli_pub, cli_data)

    /** @def ESP_BLE_MESH_MODEL_GEN_POWER_LEVEL_CLI
    *
    * @brief Define a new Generic Power Level Client Model.
    *
    * @note This API needs to be called for each element on which
    * the application needs to have a Generic Power Level Client Model.
    *
    * @param cli_pub Pointer to the unique struct esp_ble_mesh_model_pub_t.
    * @param cli_data Pointer to the unique struct esp_ble_mesh_client_t.
    *
    * @return New Generic Power Level Client Model instance.
    */
    #define ESP_BLE_MESH_MODEL_GEN_POWER_LEVEL_CLI(cli_pub, cli_data) \
    ESP_BLE_MESH_SIG_MODEL(ESP_BLE_MESH_MODEL_ID_GEN_POWER_LEVEL_CLI, \
    NULL, cli_pub, cli_data)

    /** @def ESP_BLE_MESH_MODEL_GEN_BATTERY_CLI
    *
    * @brief Define a new Generic Battery Client Model.
    *
    * @note This API needs to be called for each element on which
    * the application needs to have a Generic Battery Client Model.
    *
    * @param cli_pub Pointer to the unique struct esp_ble_mesh_model_pub_t.
    * @param cli_data Pointer to the unique struct esp_ble_mesh_client_t.
    *
    * @return New Generic Battery Client Model instance.
    */
    #define ESP_BLE_MESH_MODEL_GEN_BATTERY_CLI(cli_pub, cli_data) \
    ESP_BLE_MESH_SIG_MODEL(ESP_BLE_MESH_MODEL_ID_GEN_BATTERY_CLI, \
    NULL, cli_pub, cli_data)

    /** @def ESP_BLE_MESH_MODEL_GEN_LOCATION_CLI
    *
    * @brief Define a new Generic Location Client Model.
    *
    * @note This API needs to be called for each element on which
    * the application needs to have a Generic Location Client Model.
    *
    * @param cli_pub Pointer to the unique struct esp_ble_mesh_model_pub_t.
    * @param cli_data Pointer to the unique struct esp_ble_mesh_client_t.
    *
    * @return New Generic Location Client Model instance.
    */
    #define ESP_BLE_MESH_MODEL_GEN_LOCATION_CLI(cli_pub, cli_data) \
    ESP_BLE_MESH_SIG_MODEL(ESP_BLE_MESH_MODEL_ID_GEN_LOCATION_CLI, \
    NULL, cli_pub, cli_data)

    /** @def ESP_BLE_MESH_MODEL_GEN_PROPERTY_CLI
    *
    * @brief Define a new Generic Property Client Model.
    *
    * @note This API needs to be called for each element on which
    * the application needs to have a Generic Property Client Model.
    *
    * @param cli_pub Pointer to the unique struct esp_ble_mesh_model_pub_t.
    * @param cli_data Pointer to the unique struct esp_ble_mesh_client_t.
    *
    * @return New Generic Location Client Model instance.
    */
    #define ESP_BLE_MESH_MODEL_GEN_PROPERTY_CLI(cli_pub, cli_data) \
    ESP_BLE_MESH_SIG_MODEL(ESP_BLE_MESH_MODEL_ID_GEN_PROP_CLI, \
    NULL, cli_pub, cli_data)

    /**
    * @brief Bluetooth Mesh Generic Client Model Get and Set parameters structure.
    */

    /** Parameters of Generic OnOff Set. */
    typedef struct {
    bool op_en; /*!< Indicate if optional parameters are included */
    uint8_t onoff; /*!< Target value of Generic OnOff state */
    uint8_t tid; /*!< Transaction ID */
    uint8_t trans_time; /*!< Time to complete state transition (optional) */
    uint8_t delay; /*!< Indicate message execution delay (C.1) */
    } esp_ble_mesh_gen_onoff_set_t;

    /** Parameters of Generic Level Set. */
    typedef struct {
    bool op_en; /*!< Indicate if optional parameters are included */
    int16_t level; /*!< Target value of Generic Level state */
    uint8_t tid; /*!< Transaction ID */
    uint8_t trans_time; /*!< Time to complete state transition (optional) */
    uint8_t delay; /*!< Indicate message execution delay (C.1) */
    } esp_ble_mesh_gen_level_set_t;

    /** Parameters of Generic Delta Set. */
    typedef struct {
    bool op_en; /*!< Indicate if optional parameters are included */
    int32_t level; /*!< Delta change of Generic Level state */
    uint8_t tid; /*!< Transaction ID */
    uint8_t trans_time; /*!< Time to complete state transition (optional) */
    uint8_t delay; /*!< Indicate message execution delay (C.1) */
    } esp_ble_mesh_gen_delta_set_t;

    /** Parameters of Generic Move Set. */
    typedef struct {
    bool op_en; /*!< Indicate if optional parameters are included */
    int16_t delta_level; /*!< Delta Level step to calculate Move speed for Generic Level state */
    uint8_t tid; /*!< Transaction ID */
    uint8_t trans_time; /*!< Time to complete state transition (optional) */
    uint8_t delay; /*!< Indicate message execution delay (C.1) */
    } esp_ble_mesh_gen_move_set_t;

    /** Parameter of Generic Default Transition Time Set. */
    typedef struct {
    uint8_t trans_time; /*!< The value of the Generic Default Transition Time state */
    } esp_ble_mesh_gen_def_trans_time_set_t;

    /** Parameter of Generic OnPowerUp Set. */
    typedef struct {
    uint8_t onpowerup; /*!< The value of the Generic OnPowerUp state */
    } esp_ble_mesh_gen_onpowerup_set_t;

    /** Parameters of Generic Power Level Set. */
    typedef struct {
    bool op_en; /*!< Indicate if optional parameters are included */
    uint16_t power; /*!< Target value of Generic Power Actual state */
    uint8_t tid; /*!< Transaction ID */
    uint8_t trans_time; /*!< Time to complete state transition (optional) */
    uint8_t delay; /*!< Indicate message execution delay (C.1) */
    } esp_ble_mesh_gen_power_level_set_t;

    /** Parameter of Generic Power Default Set. */
    typedef struct {
    uint16_t power; /*!< The value of the Generic Power Default state */
    } esp_ble_mesh_gen_power_default_set_t;

    /** Parameters of Generic Power Range Set. */
    typedef struct {
    uint16_t range_min; /*!< Value of Range Min field of Generic Power Range state */
    uint16_t range_max; /*!< Value of Range Max field of Generic Power Range state */
    } esp_ble_mesh_gen_power_range_set_t;

    /** Parameters of Generic Location Global Set. */
    typedef struct {
    int32_t global_latitude; /*!< Global Coordinates (Latitude) */
    int32_t global_longitude; /*!< Global Coordinates (Longitude) */
    int16_t global_altitude; /*!< Global Altitude */
    } esp_ble_mesh_gen_loc_global_set_t;

    /** Parameters of Generic Location Local Set. */
    typedef struct {
    int16_t local_north; /*!< Local Coordinates (North) */
    int16_t local_east; /*!< Local Coordinates (East) */
    int16_t local_altitude; /*!< Local Altitude */
    uint8_t floor_number; /*!< Floor Number */
    uint16_t uncertainty; /*!< Uncertainty */
    } esp_ble_mesh_gen_loc_local_set_t;

    /** Parameter of Generic User Property Get. */
    typedef struct {
    uint16_t property_id; /*!< Property ID identifying a Generic User Property */
    } esp_ble_mesh_gen_user_property_get_t;

    /** Parameters of Generic User Property Set. */
    typedef struct {
    uint16_t property_id; /*!< Property ID identifying a Generic User Property */
    struct net_buf_simple *property_value; /*!< Raw value for the User Property */
    } esp_ble_mesh_gen_user_property_set_t;

    /** Parameter of Generic Admin Property Get. */
    typedef struct {
    uint16_t property_id; /*!< Property ID identifying a Generic Admin Property */
    } esp_ble_mesh_gen_admin_property_get_t;

    /** Parameters of Generic Admin Property Set. */
    typedef struct {
    uint16_t property_id; /*!< Property ID identifying a Generic Admin Property */
    uint8_t user_access; /*!< Enumeration indicating user access */
    struct net_buf_simple *property_value; /*!< Raw value for the Admin Property */
    } esp_ble_mesh_gen_admin_property_set_t;

    /** Parameter of Generic Manufacturer Property Get. */
    typedef struct {
    uint16_t property_id; /*!< Property ID identifying a Generic Manufacturer Property */
    } esp_ble_mesh_gen_manufacturer_property_get_t;

    /** Parameters of Generic Manufacturer Property Set. */
    typedef struct {
    uint16_t property_id; /*!< Property ID identifying a Generic Manufacturer Property */
    uint8_t user_access; /*!< Enumeration indicating user access */
    } esp_ble_mesh_gen_manufacturer_property_set_t;

    /** Parameter of Generic Client Properties Get. */
    typedef struct {
    uint16_t property_id; /*!< A starting Client Property ID present within an element */
    } esp_ble_mesh_gen_client_properties_get_t;

    /**
    * @brief Generic Client Model get message union
    */
    typedef union {
    esp_ble_mesh_gen_user_property_get_t user_property_get; /*!< For ESP_BLE_MESH_MODEL_OP_GEN_USER_PROPERTY_GET */
    esp_ble_mesh_gen_admin_property_get_t admin_property_get; /*!< For ESP_BLE_MESH_MODEL_OP_GEN_ADMIN_PROPERTY_GET*/
    esp_ble_mesh_gen_manufacturer_property_get_t manufacturer_property_get; /*!< For ESP_BLE_MESH_MODEL_OP_GEN_MANUFACTURER_PROPERTY_SET */
    esp_ble_mesh_gen_client_properties_get_t client_properties_get; /*!< For ESP_BLE_MESH_MODEL_OP_GEN_CLIENT_PROPERTIES_GET */
    } esp_ble_mesh_generic_client_get_state_t;

    /**
    * @brief Generic Client Model set message union
    */
    typedef union {
    esp_ble_mesh_gen_onoff_set_t onoff_set; /*!< For ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_SET & ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_SET_UNACK */
    esp_ble_mesh_gen_level_set_t level_set; /*!< For ESP_BLE_MESH_MODEL_OP_GEN_LEVEL_SET & ESP_BLE_MESH_MODEL_OP_GEN_LEVEL_SET_UNACK */
    esp_ble_mesh_gen_delta_set_t delta_set; /*!< For ESP_BLE_MESH_MODEL_OP_GEN_DELTA_SET & ESP_BLE_MESH_MODEL_OP_GEN_DELTA_SET_UNACK */
    esp_ble_mesh_gen_move_set_t move_set; /*!< For ESP_BLE_MESH_MODEL_OP_GEN_MOVE_SET & ESP_BLE_MESH_MODEL_OP_GEN_MOVE_SET_UNACK */
    esp_ble_mesh_gen_def_trans_time_set_t def_trans_time_set; /*!< For ESP_BLE_MESH_MODEL_OP_GEN_DEF_TRANS_TIME_SET & ESP_BLE_MESH_MODEL_OP_GEN_DEF_TRANS_TIME_SET_UNACK */
    esp_ble_mesh_gen_onpowerup_set_t power_set; /*!< For ESP_BLE_MESH_MODEL_OP_GEN_ONPOWERUP_SET & ESP_BLE_MESH_MODEL_OP_GEN_ONPOWERUP_SET_UNACK */
    esp_ble_mesh_gen_power_level_set_t power_level_set; /*!< For ESP_BLE_MESH_MODEL_OP_GEN_POWER_LEVEL_SET & ESP_BLE_MESH_MODEL_OP_GEN_POWER_LEVEL_SET_UNACK */
    esp_ble_mesh_gen_power_default_set_t power_default_set; /*!< For ESP_BLE_MESH_MODEL_OP_GEN_POWER_DEFAULT_SET & ESP_BLE_MESH_MODEL_OP_GEN_POWER_DEFAULT_SET_UNACK */
    esp_ble_mesh_gen_power_range_set_t power_range_set; /*!< For ESP_BLE_MESH_MODEL_OP_GEN_POWER_RANGE_SET & ESP_BLE_MESH_MODEL_OP_GEN_POWER_RANGE_SET_UNACK */
    esp_ble_mesh_gen_loc_global_set_t loc_global_set; /*!< For ESP_BLE_MESH_MODEL_OP_GEN_LOC_GLOBAL_SET & ESP_BLE_MESH_MODEL_OP_GEN_LOC_GLOBAL_SET_UNACK */
    esp_ble_mesh_gen_loc_local_set_t loc_local_set; /*!< For ESP_BLE_MESH_MODEL_OP_GEN_LOC_LOCAL_SET & ESP_BLE_MESH_MODEL_OP_GEN_LOC_LOCAL_SET_UNACK */
    esp_ble_mesh_gen_user_property_set_t user_property_set; /*!< For ESP_BLE_MESH_MODEL_OP_GEN_USER_PROPERTY_SET & ESP_BLE_MESH_MODEL_OP_GEN_USER_PROPERTY_SET_UNACK */
    esp_ble_mesh_gen_admin_property_set_t admin_property_set; /*!< For ESP_BLE_MESH_MODEL_OP_GEN_ADMIN_PROPERTY_SET & ESP_BLE_MESH_MODEL_OP_GEN_ADMIN_PROPERTY_SET_UNACK */
    esp_ble_mesh_gen_manufacturer_property_set_t manufacturer_property_set; /*!< For ESP_BLE_MESH_MODEL_OP_GEN_MANUFACTURER_PROPERTY_SET & ESP_BLE_MESH_MODEL_OP_GEN_MANUFACTURER_PROPERTY_SET_UNACK */
    } esp_ble_mesh_generic_client_set_state_t;

    /**
    * @brief Bluetooth Mesh Generic Client Model Get and Set callback parameters structure.
    */

    /** Parameters of Generic OnOff Status. */
    typedef struct {
    bool op_en; /*!< Indicate if optional parameters are included */
    uint8_t present_onoff; /*!< Current value of Generic OnOff state */
    uint8_t target_onoff; /*!< Target value of Generic OnOff state (optional) */
    uint8_t remain_time; /*!< Time to complete state transition (C.1) */
    } esp_ble_mesh_gen_onoff_status_cb_t;

    /** Parameters of Generic Level Status. */
    typedef struct {
    bool op_en; /*!< Indicate if optional parameters are included */
    int16_t present_level; /*!< Current value of Generic Level state */
    int16_t target_level; /*!< Target value of the Generic Level state (optional) */
    uint8_t remain_time; /*!< Time to complete state transition (C.1) */
    } esp_ble_mesh_gen_level_status_cb_t;

    /** Parameter of Generic Default Transition Time Status. */
    typedef struct {
    uint8_t trans_time; /*!< The value of the Generic Default Transition Time state */
    } esp_ble_mesh_gen_def_trans_time_status_cb_t;

    /** Parameter of Generic OnPowerUp Status. */
    typedef struct {
    uint8_t onpowerup; /*!< The value of the Generic OnPowerUp state */
    } esp_ble_mesh_gen_onpowerup_status_cb_t;

    /** Parameters of Generic Power Level Status. */
    typedef struct {
    bool op_en; /*!< Indicate if optional parameters are included */
    uint16_t present_power; /*!< Current value of Generic Power Actual state */
    uint16_t target_power; /*!< Target value of Generic Power Actual state (optional) */
    uint8_t remain_time; /*!< Time to complete state transition (C.1) */
    } esp_ble_mesh_gen_power_level_status_cb_t;

    /** Parameter of Generic Power Last Status. */
    typedef struct {
    uint16_t power; /*!< The value of the Generic Power Last state */
    } esp_ble_mesh_gen_power_last_status_cb_t;

    /** Parameter of Generic Power Default Status. */
    typedef struct {
    uint16_t power; /*!< The value of the Generic Default Last state */
    } esp_ble_mesh_gen_power_default_status_cb_t;

    /** Parameters of Generic Power Range Status. */
    typedef struct {
    uint8_t status_code; /*!< Status Code for the request message */
    uint16_t range_min; /*!< Value of Range Min field of Generic Power Range state */
    uint16_t range_max; /*!< Value of Range Max field of Generic Power Range state */
    } esp_ble_mesh_gen_power_range_status_cb_t;

    /** Parameters of Generic Battery Status. */
    typedef struct {
    uint32_t battery_level : 8; /*!< Value of Generic Battery Level state */
    uint32_t time_to_discharge : 24; /*!< Value of Generic Battery Time to Discharge state */
    uint32_t time_to_charge : 24; /*!< Value of Generic Battery Time to Charge state */
    uint32_t flags : 8; /*!< Value of Generic Battery Flags state */
    } esp_ble_mesh_gen_battery_status_cb_t;

    /** Parameters of Generic Location Global Status. */
    typedef struct {
    int32_t global_latitude; /*!< Global Coordinates (Latitude) */
    int32_t global_longitude; /*!< Global Coordinates (Longitude) */
    int16_t global_altitude; /*!< Global Altitude */
    } esp_ble_mesh_gen_loc_global_status_cb_t;

    /** Parameters of Generic Location Local Status. */
    typedef struct {
    int16_t local_north; /*!< Local Coordinates (North) */
    int16_t local_east; /*!< Local Coordinates (East) */
    int16_t local_altitude; /*!< Local Altitude */
    uint8_t floor_number; /*!< Floor Number */
    uint16_t uncertainty; /*!< Uncertainty */
    } esp_ble_mesh_gen_loc_local_status_cb_t;

    /** Parameter of Generic User Properties Status. */
    typedef struct {
    struct net_buf_simple *property_ids; /*!< Buffer contains a sequence of N User Property IDs */
    } esp_ble_mesh_gen_user_properties_status_cb_t;

    /** Parameters of Generic User Property Status. */
    typedef struct {
    bool op_en; /*!< Indicate if optional parameters are included */
    uint16_t property_id; /*!< Property ID identifying a Generic User Property */
    uint8_t user_access; /*!< Enumeration indicating user access (optional) */
    struct net_buf_simple *property_value; /*!< Raw value for the User Property (C.1) */
    } esp_ble_mesh_gen_user_property_status_cb_t;

    /** Parameter of Generic Admin Properties Status. */
    typedef struct {
    struct net_buf_simple *property_ids; /*!< Buffer contains a sequence of N Admin Property IDs */
    } esp_ble_mesh_gen_admin_properties_status_cb_t;

    /** Parameters of Generic Admin Property Status. */
    typedef struct {
    bool op_en; /*!< Indicate if optional parameters are included */
    uint16_t property_id; /*!< Property ID identifying a Generic Admin Property */
    uint8_t user_access; /*!< Enumeration indicating user access (optional) */
    struct net_buf_simple *property_value; /*!< Raw value for the Admin Property (C.1) */
    } esp_ble_mesh_gen_admin_property_status_cb_t;

    /** Parameter of Generic Manufacturer Properties Status. */
    typedef struct {
    struct net_buf_simple *property_ids; /*!< Buffer contains a sequence of N Manufacturer Property IDs */
    } esp_ble_mesh_gen_manufacturer_properties_status_cb_t;

    /** Parameters of Generic Manufacturer Property Status. */
    typedef struct {
    bool op_en; /*!< Indicate if optional parameters are included */
    uint16_t property_id; /*!< Property ID identifying a Generic Manufacturer Property */
    uint8_t user_access; /*!< Enumeration indicating user access (optional) */
    struct net_buf_simple *property_value; /*!< Raw value for the Manufacturer Property (C.1) */
    } esp_ble_mesh_gen_manufacturer_property_status_cb_t;

    /** Parameter of Generic Client Properties Status. */
    typedef struct {
    struct net_buf_simple *property_ids; /*!< Buffer contains a sequence of N Client Property IDs */
    } esp_ble_mesh_gen_client_properties_status_cb_t;

    /**
    * @brief Generic Client Model received message union
    */
    typedef union {
    esp_ble_mesh_gen_onoff_status_cb_t onoff_status; /*!< For ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_STATUS */
    esp_ble_mesh_gen_level_status_cb_t level_status; /*!< For ESP_BLE_MESH_MODEL_OP_GEN_LEVEL_STATUS */
    esp_ble_mesh_gen_def_trans_time_status_cb_t def_trans_time_status; /*!< For ESP_BLE_MESH_MODEL_OP_GEN_DEF_TRANS_TIME_STATUS */
    esp_ble_mesh_gen_onpowerup_status_cb_t onpowerup_status; /*!< For ESP_BLE_MESH_MODEL_OP_GEN_ONPOWERUP_STATUS */
    esp_ble_mesh_gen_power_level_status_cb_t power_level_status; /*!< For ESP_BLE_MESH_MODEL_OP_GEN_POWER_LEVEL_STATUS */
    esp_ble_mesh_gen_power_last_status_cb_t power_last_status; /*!< For ESP_BLE_MESH_MODEL_OP_GEN_POWER_LAST_STATUS */
    esp_ble_mesh_gen_power_default_status_cb_t power_default_status; /*!< For ESP_BLE_MESH_MODEL_OP_GEN_POWER_DEFAULT_STATUS */
    esp_ble_mesh_gen_power_range_status_cb_t power_range_status; /*!< For ESP_BLE_MESH_MODEL_OP_GEN_POWER_RANGE_STATUS */
    esp_ble_mesh_gen_battery_status_cb_t battery_status; /*!< For ESP_BLE_MESH_MODEL_OP_GEN_BATTERY_STATUS */
    esp_ble_mesh_gen_loc_global_status_cb_t location_global_status; /*!< For ESP_BLE_MESH_MODEL_OP_GEN_LOC_GLOBAL_STATUS */
    esp_ble_mesh_gen_loc_local_status_cb_t location_local_status; /*!< ESP_BLE_MESH_MODEL_OP_GEN_LOC_LOCAL_STATUS */
    esp_ble_mesh_gen_user_properties_status_cb_t user_properties_status; /*!< ESP_BLE_MESH_MODEL_OP_GEN_USER_PROPERTIES_STATUS */
    esp_ble_mesh_gen_user_property_status_cb_t user_property_status; /*!< ESP_BLE_MESH_MODEL_OP_GEN_USER_PROPERTY_STATUS */
    esp_ble_mesh_gen_admin_properties_status_cb_t admin_properties_status; /*!< ESP_BLE_MESH_MODEL_OP_GEN_ADMIN_PROPERTIES_STATUS */
    esp_ble_mesh_gen_admin_property_status_cb_t admin_property_status; /*!< ESP_BLE_MESH_MODEL_OP_GEN_ADMIN_PROPERTY_STATUS */
    esp_ble_mesh_gen_manufacturer_properties_status_cb_t manufacturer_properties_status; /*!< ESP_BLE_MESH_MODEL_OP_GEN_MANUFACTURER_PROPERTIES_STATUS */
    esp_ble_mesh_gen_manufacturer_property_status_cb_t manufacturer_property_status; /*!< ESP_BLE_MESH_MODEL_OP_GEN_MANUFACTURER_PROPERTY_STATUS */
    esp_ble_mesh_gen_client_properties_status_cb_t client_properties_status; /*!< ESP_BLE_MESH_MODEL_OP_GEN_CLIENT_PROPERTIES_STATUS */
    } esp_ble_mesh_gen_client_status_cb_t;

    /** Generic Client Model callback parameters */
    typedef struct {
    int error_code; /*!< Appropriate error code */
    esp_ble_mesh_client_common_param_t *params; /*!< The client common parameters. */
    esp_ble_mesh_gen_client_status_cb_t status_cb; /*!< The generic status message callback values */
    } esp_ble_mesh_generic_client_cb_param_t;

    /** This enum value is the event of Generic Client Model */
    typedef enum {
    ESP_BLE_MESH_GENERIC_CLIENT_GET_STATE_EVT,
    ESP_BLE_MESH_GENERIC_CLIENT_SET_STATE_EVT,
    ESP_BLE_MESH_GENERIC_CLIENT_PUBLISH_EVT,
    ESP_BLE_MESH_GENERIC_CLIENT_TIMEOUT_EVT,
    ESP_BLE_MESH_GENERIC_CLIENT_EVT_MAX,
    } esp_ble_mesh_generic_client_cb_event_t;

    /**
    * @brief Bluetooth Mesh Generic Client Model function.
    */

    /**
    * @brief Generic Client Model callback function type
    * @param event: Event type
    * @param param: Pointer to callback parameter
    */
    typedef void (* esp_ble_mesh_generic_client_cb_t)(esp_ble_mesh_generic_client_cb_event_t event,
    esp_ble_mesh_generic_client_cb_param_t *param);

    /**
    * @brief Register BLE Mesh Generic Client Model callback.
    *
    * @param[in] callback: Pointer to the callback function.
    *
    * @return ESP_OK on success or error code otherwise.
    *
    */
    esp_err_t esp_ble_mesh_register_generic_client_callback(esp_ble_mesh_generic_client_cb_t callback);

    /**
    * @brief Get the value of Generic Server Model states using the Generic Client Model get messages.
    *
    * @note If you want to find the opcodes and corresponding meanings accepted by this API,
    * please refer to esp_ble_mesh_generic_message_opcode_t in esp_ble_mesh_defs.h
    *
    * @param[in] params: Pointer to BLE Mesh common client parameters.
    * @param[in] get_state: Pointer to generic get message value.
    * Shall not be set to NULL.
    *
    * @return ESP_OK on success or error code otherwise.
    *
    */
    esp_err_t esp_ble_mesh_generic_client_get_state(esp_ble_mesh_client_common_param_t *params,
    esp_ble_mesh_generic_client_get_state_t *get_state);

    /**
    * @brief Set the value of Generic Server Model states using the Generic Client Model set messages.
    *
    * @note If you want to find the opcodes and corresponding meanings accepted by this API,
    * please refer to esp_ble_mesh_generic_message_opcode_t in esp_ble_mesh_defs.h
    *
    * @param[in] params: Pointer to BLE Mesh common client parameters.
    * @param[in] set_state: Pointer to generic set message value.
    * Shall not be set to NULL.
    *
    * @return ESP_OK on success or error code otherwise.
    *
    */
    esp_err_t esp_ble_mesh_generic_client_set_state(esp_ble_mesh_client_common_param_t *params,
    esp_ble_mesh_generic_client_set_state_t *set_state);

    /**
    * @brief Generic Server Models related context.
    */

    /** @def ESP_BLE_MESH_MODEL_GEN_ONOFF_SRV
    *
    * @brief Define a new Generic OnOff Server Model.
    *
    * @note 1. The Generic OnOff Server Model is a root model.
    * 2. This model shall support model publication and model subscription.
    *
    * @param srv_pub Pointer to the unique struct esp_ble_mesh_model_pub_t.
    * @param srv_data Pointer to the unique struct esp_ble_mesh_gen_onoff_srv_t.
    *
    * @return New Generic OnOff Server Model instance.
    */
    #define ESP_BLE_MESH_MODEL_GEN_ONOFF_SRV(srv_pub, srv_data) \
    ESP_BLE_MESH_SIG_MODEL(ESP_BLE_MESH_MODEL_ID_GEN_ONOFF_SRV, \
    NULL, srv_pub, srv_data)

    /** @def ESP_BLE_MESH_MODEL_GEN_LEVEL_SRV
    *
    * @brief Define a new Generic Level Server Model.
    *
    * @note 1. The Generic Level Server Model is a root model.
    * 2. This model shall support model publication and model subscription.
    *
    * @param srv_pub Pointer to the unique struct esp_ble_mesh_model_pub_t.
    * @param srv_data Pointer to the unique struct esp_ble_mesh_gen_level_srv_t.
    *
    * @return New Generic Level Server Model instance.
    */
    #define ESP_BLE_MESH_MODEL_GEN_LEVEL_SRV(srv_pub, srv_data) \
    ESP_BLE_MESH_SIG_MODEL(ESP_BLE_MESH_MODEL_ID_GEN_LEVEL_SRV, \
    NULL, srv_pub, srv_data)

    /** @def ESP_BLE_MESH_MODEL_GEN_DEF_TRANS_TIME_SRV
    *
    * @brief Define a new Generic Default Transition Time Server Model.
    *
    * @note 1. The Generic Default Transition Time Server Model is a root model.
    * 2. This model shall support model publication and model subscription.
    *
    * @param srv_pub Pointer to the unique struct esp_ble_mesh_model_pub_t.
    * @param srv_data Pointer to the unique struct esp_ble_mesh_gen_def_trans_time_srv_t.
    *
    * @return New Generic Default Transition Time Server Model instance.
    */
    #define ESP_BLE_MESH_MODEL_GEN_DEF_TRANS_TIME_SRV(srv_pub, srv_data) \
    ESP_BLE_MESH_SIG_MODEL(ESP_BLE_MESH_MODEL_ID_GEN_DEF_TRANS_TIME_SRV, \
    NULL, srv_pub, srv_data)

    /** @def ESP_BLE_MESH_MODEL_GEN_POWER_ONOFF_SRV
    *
    * @brief Define a new Generic Power OnOff Server Model.
    *
    * @note 1. The Generic Power OnOff Server model extends the Generic OnOff Server
    * model. When this model is present on an element, the corresponding
    * Generic Power OnOff Setup Server model shall also be present.
    * 2. This model may be used to represent a variety of devices that do not
    * fit any of the model descriptions that have been defined but support
    * the generic properties of On/Off.
    * 3. This model shall support model publication and model subscription.
    *
    * @param srv_pub Pointer to the unique struct esp_ble_mesh_model_pub_t.
    * @param srv_data Pointer to the unique struct esp_ble_mesh_gen_power_onoff_srv_t.
    *
    * @return New Generic Power OnOff Server Model instance.
    */
    #define ESP_BLE_MESH_MODEL_GEN_POWER_ONOFF_SRV(srv_pub, srv_data) \
    ESP_BLE_MESH_SIG_MODEL(ESP_BLE_MESH_MODEL_ID_GEN_POWER_ONOFF_SRV, \
    NULL, srv_pub, srv_data)

    /** @def ESP_BLE_MESH_MODEL_GEN_POWER_ONOFF_SETUP_SRV
    *
    * @brief Define a new Generic Power OnOff Setup Server Model.
    *
    * @note 1. The Generic Power OnOff Setup Server model extends the Generic Power
    * OnOff Server model and the Generic Default Transition Time Server model.
    * 2. This model shall support model subscription.
    *
    * @param srv_pub Pointer to the unique struct esp_ble_mesh_model_pub_t.
    * @param srv_data Pointer to the unique struct esp_ble_mesh_gen_power_onoff_setup_srv_t.
    *
    * @return New Generic Power OnOff Setup Server Model instance.
    */
    #define ESP_BLE_MESH_MODEL_GEN_POWER_ONOFF_SETUP_SRV(srv_pub, srv_data) \
    ESP_BLE_MESH_SIG_MODEL(ESP_BLE_MESH_MODEL_ID_GEN_POWER_ONOFF_SETUP_SRV, \
    NULL, srv_pub, srv_data)

    /** @def ESP_BLE_MESH_MODEL_GEN_POWER_LEVEL_SRV
    *
    * @brief Define a new Generic Power Level Server Model.
    *
    * @note 1. The Generic Power Level Server model extends the Generic Power OnOff
    * Server model and the Generic Level Server model. When this model is
    * present on an Element, the corresponding Generic Power Level Setup
    * Server model shall also be present.
    * 2. This model shall support model publication and model subscription.
    *
    * @param srv_pub Pointer to the unique struct esp_ble_mesh_model_pub_t.
    * @param srv_data Pointer to the unique struct esp_ble_mesh_gen_power_level_srv_t.
    *
    * @return New Generic Power Level Server Model instance.
    */
    #define ESP_BLE_MESH_MODEL_GEN_POWER_LEVEL_SRV(srv_pub, srv_data) \
    ESP_BLE_MESH_SIG_MODEL(ESP_BLE_MESH_MODEL_ID_GEN_POWER_LEVEL_SRV, \
    NULL, srv_pub, srv_data)

    /** @def ESP_BLE_MESH_MODEL_GEN_POWER_LEVEL_SETUP_SRV
    *
    * @brief Define a new Generic Power Level Setup Server Model.
    *
    * @note 1. The Generic Power Level Setup Server model extends the Generic Power
    * Level Server model and the Generic Power OnOff Setup Server model.
    * 2. This model shall support model subscription.
    *
    * @param srv_pub Pointer to the unique struct esp_ble_mesh_model_pub_t.
    * @param srv_data Pointer to the unique struct esp_ble_mesh_gen_power_level_setup_srv_t.
    *
    * @return New Generic Power Level Setup Server Model instance.
    */
    #define ESP_BLE_MESH_MODEL_GEN_POWER_LEVEL_SETUP_SRV(srv_pub, srv_data) \
    ESP_BLE_MESH_SIG_MODEL(ESP_BLE_MESH_MODEL_ID_GEN_POWER_LEVEL_SETUP_SRV, \
    NULL, srv_pub, srv_data)

    /** @def ESP_BLE_MESH_MODEL_GEN_BATTERY_SRV
    *
    * @brief Define a new Generic Battery Server Model.
    *
    * @note 1. The Generic Battery Server Model is a root model.
    * 2. This model shall support model publication and model subscription.
    * 3. The model may be used to represent an element that is powered by a battery.
    *
    * @param srv_pub Pointer to the unique struct esp_ble_mesh_model_pub_t.
    * @param srv_data Pointer to the unique struct esp_ble_mesh_gen_battery_srv_t.
    *
    * @return New Generic Battery Server Model instance.
    */
    #define ESP_BLE_MESH_MODEL_GEN_BATTERY_SRV(srv_pub, srv_data) \
    ESP_BLE_MESH_SIG_MODEL(ESP_BLE_MESH_MODEL_ID_GEN_BATTERY_SRV, \
    NULL, srv_pub, srv_data)

    /** @def ESP_BLE_MESH_MODEL_GEN_LOCATION_SRV
    *
    * @brief Define a new Generic Location Server Model.
    *
    * @note 1. The Generic Location Server model is a root model. When this model
    * is present on an Element, the corresponding Generic Location Setup
    * Server model shall also be present.
    * 2. This model shall support model publication and model subscription.
    * 3. The model may be used to represent an element that knows its
    * location (global or local).
    *
    * @param srv_pub Pointer to the unique struct esp_ble_mesh_model_pub_t.
    * @param srv_data Pointer to the unique struct esp_ble_mesh_gen_location_srv_t.
    *
    * @return New Generic Location Server Model instance.
    */
    #define ESP_BLE_MESH_MODEL_GEN_LOCATION_SRV(srv_pub, srv_data) \
    ESP_BLE_MESH_SIG_MODEL(ESP_BLE_MESH_MODEL_ID_GEN_LOCATION_SRV, \
    NULL, srv_pub, srv_data)

    /** @def ESP_BLE_MESH_MODEL_GEN_LOCATION_SETUP_SRV
    *
    * @brief Define a new Generic Location Setup Server Model.
    *
    * @note 1. The Generic Location Setup Server model extends the Generic Location
    * Server model.
    * 2. This model shall support model subscription.
    *
    * @param srv_pub Pointer to the unique struct esp_ble_mesh_model_pub_t.
    * @param srv_data Pointer to the unique struct esp_ble_mesh_gen_location_setup_srv_t.
    *
    * @return New Generic Location Setup Server Model instance.
    */
    #define ESP_BLE_MESH_MODEL_GEN_LOCATION_SETUP_SRV(srv_pub, srv_data) \
    ESP_BLE_MESH_SIG_MODEL(ESP_BLE_MESH_MODEL_ID_GEN_LOCATION_SETUP_SRV, \
    NULL, srv_pub, srv_data)

    /** @def ESP_BLE_MESH_MODEL_GEN_USER_PROP_SRV
    *
    * @brief Define a new Generic User Property Server Model.
    *
    * @note 1. The Generic User Property Server model is a root model.
    * 2. This model shall support model publication and model subscription.
    *
    * @param srv_pub Pointer to the unique struct esp_ble_mesh_model_pub_t.
    * @param srv_data Pointer to the unique struct esp_ble_mesh_gen_user_prop_srv_t.
    *
    * @return New Generic User Property Server Model instance.
    */
    #define ESP_BLE_MESH_MODEL_GEN_USER_PROP_SRV(srv_pub, srv_data) \
    ESP_BLE_MESH_SIG_MODEL(ESP_BLE_MESH_MODEL_ID_GEN_USER_PROP_SRV, \
    NULL, srv_pub, srv_data)

    /** @def ESP_BLE_MESH_MODEL_GEN_ADMIN_PROP_SRV
    *
    * @brief Define a new Generic Admin Property Server Model.
    *
    * @note 1. The Generic Admin Property Server model extends the Generic User
    * Property Server model.
    * 2. This model shall support model publication and model subscription.
    *
    * @param srv_pub Pointer to the unique struct esp_ble_mesh_model_pub_t.
    * @param srv_data Pointer to the unique struct esp_ble_mesh_gen_admin_prop_srv_t.
    *
    * @return New Generic Admin Property Server Model instance.
    */
    #define ESP_BLE_MESH_MODEL_GEN_ADMIN_PROP_SRV(srv_pub, srv_data) \
    ESP_BLE_MESH_SIG_MODEL(ESP_BLE_MESH_MODEL_ID_GEN_ADMIN_PROP_SRV, \
    NULL, srv_pub, srv_data)

    /** @def ESP_BLE_MESH_MODEL_GEN_MANUFACTURER_PROP_SRV
    *
    * @brief Define a new Generic Manufacturer Property Server Model.
    *
    * @note 1. The Generic Manufacturer Property Server model extends the Generic
    * User Property Server model.
    * 2. This model shall support model publication and model subscription.
    *
    * @param srv_pub Pointer to the unique struct esp_ble_mesh_model_pub_t.
    * @param srv_data Pointer to the unique struct esp_ble_mesh_gen_manu_prop_srv_t.
    *
    * @return New Generic Manufacturer Property Server Model instance.
    */
    #define ESP_BLE_MESH_MODEL_GEN_MANUFACTURER_PROP_SRV(srv_pub, srv_data) \
    ESP_BLE_MESH_SIG_MODEL(ESP_BLE_MESH_MODEL_ID_GEN_MANUFACTURER_PROP_SRV, \
    NULL, srv_pub, srv_data)

    /** @def ESP_BLE_MESH_MODEL_GEN_CLIENT_PROP_SRV
    *
    * @brief Define a new Generic User Property Server Model.
    *
    * @note 1. The Generic Client Property Server model is a root model.
    * 2. This model shall support model publication and model subscription.
    *
    * @param srv_pub Pointer to the unique struct esp_ble_mesh_model_pub_t.
    * @param srv_data Pointer to the unique struct esp_ble_mesh_gen_client_prop_srv_t.
    *
    * @return New Generic Client Property Server Model instance.
    */
    #define ESP_BLE_MESH_MODEL_GEN_CLIENT_PROP_SRV(srv_pub, srv_data) \
    ESP_BLE_MESH_SIG_MODEL(ESP_BLE_MESH_MODEL_ID_GEN_CLIENT_PROP_SRV, \
    NULL, srv_pub, srv_data)

    /** Parameters of Generic OnOff state */
    typedef struct {
    uint8_t onoff; /*!< The present value of the Generic OnOff state */
    uint8_t target_onoff; /*!< The target value of the Generic OnOff state */
    } esp_ble_mesh_gen_onoff_state_t;

    /** User data of Generic OnOff Server Model */
    typedef struct {
    esp_ble_mesh_model_t *model; /*!< Pointer to the Generic OnOff Server Model. Initialized internally. */
    esp_ble_mesh_server_rsp_ctrl_t rsp_ctrl; /*!< Response control of the server model received messages */
    esp_ble_mesh_gen_onoff_state_t state; /*!< Parameters of the Generic OnOff state */
    esp_ble_mesh_last_msg_info_t last; /*!< Parameters of the last received set message */
    esp_ble_mesh_state_transition_t transition; /*!< Parameters of state transition */
    } esp_ble_mesh_gen_onoff_srv_t;

    /** Parameters of Generic Level state */
    typedef struct {
    int16_t level; /*!< The present value of the Generic Level state */
    int16_t target_level; /*!< The target value of the Generic Level state */

    /**
    * When a new transaction starts, level should be set to last_last, and use
    * "level + incoming delta" to calculate the target level. In another word,
    * "last_level" is used to record "level" of the last transaction, and
    * "last_delta" is used to record the previously received delta_level value.
    */
    int16_t last_level; /*!< The last value of the Generic Level state */
    int32_t last_delta; /*!< The last delta change of the Generic Level state */

    bool move_start; /*!< Indicate if the transition of the Generic Level state has been started */
    bool positive; /*!< Indicate if the transition is positive or negative */
    } esp_ble_mesh_gen_level_state_t;

    /** User data of Generic Level Server Model */
    typedef struct {
    esp_ble_mesh_model_t *model; /*!< Pointer to the Generic Level Server Model. Initialized internally. */
    esp_ble_mesh_server_rsp_ctrl_t rsp_ctrl; /*!< Response control of the server model received messages */
    esp_ble_mesh_gen_level_state_t state; /*!< Parameters of the Generic Level state */
    esp_ble_mesh_last_msg_info_t last; /*!< Parameters of the last received set message */
    esp_ble_mesh_state_transition_t transition; /*!< Parameters of state transition */
    int32_t tt_delta_level; /*!< Delta change value of level state transition */
    } esp_ble_mesh_gen_level_srv_t;

    /** Parameter of Generic Default Transition Time state */
    typedef struct {
    uint8_t trans_time; /*!< The value of the Generic Default Transition Time state */
    } esp_ble_mesh_gen_def_trans_time_state_t;

    /** User data of Generic Default Transition Time Server Model */
    typedef struct {
    esp_ble_mesh_model_t *model; /*!< Pointer to the Generic Default Transition Time Server Model. Initialized internally. */
    esp_ble_mesh_server_rsp_ctrl_t rsp_ctrl; /*!< Response control of the server model received messages */
    esp_ble_mesh_gen_def_trans_time_state_t state; /*!< Parameters of the Generic Default Transition Time state */
    } esp_ble_mesh_gen_def_trans_time_srv_t;

    /** Parameter of Generic OnPowerUp state */
    typedef struct {
    uint8_t onpowerup; /*!< The value of the Generic OnPowerUp state */
    } esp_ble_mesh_gen_onpowerup_state_t;

    /** User data of Generic Power OnOff Server Model */
    typedef struct {
    esp_ble_mesh_model_t *model; /*!< Pointer to the Generic Power OnOff Server Model. Initialized internally. */
    esp_ble_mesh_server_rsp_ctrl_t rsp_ctrl; /*!< Response control of the server model received messages */
    esp_ble_mesh_gen_onpowerup_state_t *state; /*!< Parameters of the Generic OnPowerUp state */
    } esp_ble_mesh_gen_power_onoff_srv_t;

    /** User data of Generic Power OnOff Setup Server Model */
    typedef struct {
    esp_ble_mesh_model_t *model; /*!< Pointer to the Generic Power OnOff Setup Server Model. Initialized internally. */
    esp_ble_mesh_server_rsp_ctrl_t rsp_ctrl; /*!< Response control of the server model received messages */
    esp_ble_mesh_gen_onpowerup_state_t *state; /*!< Parameters of the Generic OnPowerUp state */
    } esp_ble_mesh_gen_power_onoff_setup_srv_t;

    /** Parameters of Generic Power Level state */
    typedef struct {
    uint16_t power_actual; /*!< The present value of the Generic Power Actual state */
    uint16_t target_power_actual; /*!< The target value of the Generic Power Actual state */

    uint16_t power_last; /*!< The value of the Generic Power Last state */
    uint16_t power_default; /*!< The value of the Generic Power Default state */

    uint8_t status_code; /*!< The status code of setting Generic Power Range state */
    uint16_t power_range_min; /*!< The minimum value of the Generic Power Range state */
    uint16_t power_range_max; /*!< The maximum value of the Generic Power Range state */
    } esp_ble_mesh_gen_power_level_state_t;

    /** User data of Generic Power Level Server Model */
    typedef struct {
    esp_ble_mesh_model_t *model; /*!< Pointer to the Generic Power Level Server Model. Initialized internally. */
    esp_ble_mesh_server_rsp_ctrl_t rsp_ctrl; /*!< Response control of the server model received messages */
    esp_ble_mesh_gen_power_level_state_t *state; /*!< Parameters of the Generic Power Level state */
    esp_ble_mesh_last_msg_info_t last; /*!< Parameters of the last received set message */
    esp_ble_mesh_state_transition_t transition; /*!< Parameters of state transition */
    int32_t tt_delta_level; /*!< Delta change value of level state transition */
    } esp_ble_mesh_gen_power_level_srv_t;

    /** User data of Generic Power Level Setup Server Model */
    typedef struct {
    esp_ble_mesh_model_t *model; /*!< Pointer to the Generic Power Level Setup Server Model. Initialized internally. */
    esp_ble_mesh_server_rsp_ctrl_t rsp_ctrl; /*!< Response control of the server model received messages */
    esp_ble_mesh_gen_power_level_state_t *state; /*!< Parameters of the Generic Power Level state */
    } esp_ble_mesh_gen_power_level_setup_srv_t;

    /** Parameters of Generic Battery state */
    typedef struct {
    uint32_t battery_level : 8, /*!< The value of the Generic Battery Level state */
    time_to_discharge : 24; /*!< The value of the Generic Battery Time to Discharge state */
    uint32_t time_to_charge : 24, /*!< The value of the Generic Battery Time to Charge state */
    battery_flags : 8; /*!< The value of the Generic Battery Flags state */
    } esp_ble_mesh_gen_battery_state_t;

    /** User data of Generic Battery Server Model */
    typedef struct {
    esp_ble_mesh_model_t *model; /*!< Pointer to the Generic Battery Server Model. Initialized internally. */
    esp_ble_mesh_server_rsp_ctrl_t rsp_ctrl; /*!< Response control of the server model received messages */
    esp_ble_mesh_gen_battery_state_t state; /*!< Parameters of the Generic Battery state */
    } esp_ble_mesh_gen_battery_srv_t;

    /** Parameters of Generic Location state */
    typedef struct {
    int32_t global_latitude; /*!< The value of the Global Latitude field */
    int32_t global_longitude; /*!< The value of the Global Longitude field */
    int16_t global_altitude; /*!< The value of the Global Altitude field */
    int16_t local_north; /*!< The value of the Local North field */
    int16_t local_east; /*!< The value of the Local East field */
    int16_t local_altitude; /*!< The value of the Local Altitude field */
    uint8_t floor_number; /*!< The value of the Floor Number field */
    uint16_t uncertainty; /*!< The value of the Uncertainty field */
    } esp_ble_mesh_gen_location_state_t;

    /** User data of Generic Location Server Model */
    typedef struct {
    esp_ble_mesh_model_t *model; /*!< Pointer to the Generic Location Server Model. Initialized internally. */
    esp_ble_mesh_server_rsp_ctrl_t rsp_ctrl; /*!< Response control of the server model received messages */
    esp_ble_mesh_gen_location_state_t *state; /*!< Parameters of the Generic Location state */
    } esp_ble_mesh_gen_location_srv_t;

    /** User data of Generic Location Setup Server Model */
    typedef struct {
    esp_ble_mesh_model_t *model; /*!< Pointer to the Generic Location Setup Server Model. Initialized internally. */
    esp_ble_mesh_server_rsp_ctrl_t rsp_ctrl; /*!< Response control of the server model received messages */
    esp_ble_mesh_gen_location_state_t *state; /*!< Parameters of the Generic Location state */
    } esp_ble_mesh_gen_location_setup_srv_t;

    /** This enum value is the access value of Generic User Property */
    typedef enum {
    ESP_BLE_MESH_GEN_USER_ACCESS_PROHIBIT,
    ESP_BLE_MESH_GEN_USER_ACCESS_READ,
    ESP_BLE_MESH_GEN_USER_ACCESS_WRITE,
    ESP_BLE_MESH_GEN_USER_ACCESS_READ_WRITE,
    } esp_ble_mesh_gen_user_prop_access_t;

    /** This enum value is the access value of Generic Admin Property */
    typedef enum {
    ESP_BLE_MESH_GEN_ADMIN_NOT_USER_PROP,
    ESP_BLE_MESH_GEN_ADMIN_ACCESS_READ,
    ESP_BLE_MESH_GEN_ADMIN_ACCESS_WRITE,
    ESP_BLE_MESH_GEN_ADMIN_ACCESS_READ_WRITE,
    } esp_ble_mesh_gen_admin_prop_access_t;

    /** This enum value is the access value of Generic Manufacturer Property */
    typedef enum {
    ESP_BLE_MESH_GEN_MANU_NOT_USER_PROP,
    ESP_BLE_MESH_GEN_MANU_ACCESS_READ,
    } esp_ble_mesh_gen_manu_prop_access_t;

    /** Parameters of Generic Property states */
    typedef struct {
    uint16_t id; /*!< The value of User/Admin/Manufacturer Property ID */
    uint8_t user_access; /*!< The value of User Access field */
    uint8_t admin_access; /*!< The value of Admin Access field */
    uint8_t manu_access; /*!< The value of Manufacturer Access field */
    struct net_buf_simple *val; /*!< The value of User/Admin/Manufacturer Property */
    } esp_ble_mesh_generic_property_t;

    /** User data of Generic User Property Server Model */
    typedef struct {
    esp_ble_mesh_model_t *model; /*!< Pointer to the Generic User Property Server Model. Initialized internally. */
    esp_ble_mesh_server_rsp_ctrl_t rsp_ctrl; /*!< Response control of the server model received messages */
    uint8_t property_count; /*!< Generic User Property count */
    esp_ble_mesh_generic_property_t *properties; /*!< Parameters of the Generic User Property state */
    } esp_ble_mesh_gen_user_prop_srv_t;

    /** User data of Generic Admin Property Server Model */
    typedef struct {
    esp_ble_mesh_model_t *model; /*!< Pointer to the Generic Admin Property Server Model. Initialized internally. */
    esp_ble_mesh_server_rsp_ctrl_t rsp_ctrl; /*!< Response control of the server model received messages */
    uint8_t property_count; /*!< Generic Admin Property count */
    esp_ble_mesh_generic_property_t *properties; /*!< Parameters of the Generic Admin Property state */
    } esp_ble_mesh_gen_admin_prop_srv_t;

    /** User data of Generic Manufacturer Property Server Model */
    typedef struct {
    esp_ble_mesh_model_t *model; /*!< Pointer to the Generic Manufacturer Property Server Model. Initialized internally. */
    esp_ble_mesh_server_rsp_ctrl_t rsp_ctrl; /*!< Response control of the server model received messages */
    uint8_t property_count; /*!< Generic Manufacturer Property count */
    esp_ble_mesh_generic_property_t *properties; /*!< Parameters of the Generic Manufacturer Property state */
    } esp_ble_mesh_gen_manu_prop_srv_t;

    /** User data of Generic Client Property Server Model */
    typedef struct {
    esp_ble_mesh_model_t *model; /*!< Pointer to the Generic Client Property Server Model. Initialized internally. */
    esp_ble_mesh_server_rsp_ctrl_t rsp_ctrl; /*!< Response control of the server model received messages */
    uint8_t id_count; /*!< Generic Client Property ID count */
    uint16_t *property_ids; /*!< Parameters of the Generic Client Property state */
    } esp_ble_mesh_gen_client_prop_srv_t;

    /** Parameter of Generic OnOff Set state change event */
    typedef struct {
    uint8_t onoff; /*!< The value of Generic OnOff state */
    } esp_ble_mesh_state_change_gen_onoff_set_t;

    /** Parameter of Generic Level Set state change event */
    typedef struct {
    int16_t level; /*!< The value of Generic Level state */
    } esp_ble_mesh_state_change_gen_level_set_t;

    /** Parameter of Generic Delta Set state change event */
    typedef struct {
    int16_t level; /*!< The value of Generic Level state */
    } esp_ble_mesh_state_change_gen_delta_set_t;

    /** Parameter of Generic Move Set state change event */
    typedef struct {
    int16_t level; /*!< The value of Generic Level state */
    } esp_ble_mesh_state_change_gen_move_set_t;

    /** Parameter of Generic Default Transition Time Set state change event */
    typedef struct {
    uint8_t trans_time; /*!< The value of Generic Default Transition Time state */
    } esp_ble_mesh_state_change_gen_def_trans_time_set_t;

    /** Parameter of Generic OnPowerUp Set state change event */
    typedef struct {
    uint8_t onpowerup; /*!< The value of Generic OnPowerUp state */
    } esp_ble_mesh_state_change_gen_onpowerup_set_t;

    /** Parameter of Generic Power Level Set state change event */
    typedef struct {
    uint16_t power; /*!< The value of Generic Power Actual state */
    } esp_ble_mesh_state_change_gen_power_level_set_t;

    /** Parameter of Generic Power Default Set state change event */
    typedef struct {
    uint16_t power; /*!< The value of Generic Power Default state */
    } esp_ble_mesh_state_change_gen_power_default_set_t;

    /** Parameters of Generic Power Range Set state change event */
    typedef struct {
    uint16_t range_min; /*!< The minimum value of Generic Power Range state */
    uint16_t range_max; /*!< The maximum value of Generic Power Range state */
    } esp_ble_mesh_state_change_gen_power_range_set_t;

    /** Parameters of Generic Location Global Set state change event */
    typedef struct {
    int32_t latitude; /*!< The Global Latitude value of Generic Location state */
    int32_t longitude; /*!< The Global Longitude value of Generic Location state */
    int16_t altitude; /*!< The Global Altitude value of Generic Location state */
    } esp_ble_mesh_state_change_gen_loc_global_set_t;

    /** Parameters of Generic Location Local Set state change event */
    typedef struct {
    int16_t north; /*!< The Local North value of Generic Location state */
    int16_t east; /*!< The Local East value of Generic Location state */
    int16_t altitude; /*!< The Local Altitude value of Generic Location state */
    uint8_t floor_number; /*!< The Floor Number value of Generic Location state */
    uint16_t uncertainty; /*!< The Uncertainty value of Generic Location state */
    } esp_ble_mesh_state_change_gen_loc_local_set_t;

    /** Parameters of Generic User Property Set state change event */
    typedef struct {
    uint16_t id; /*!< The property id of Generic User Property state */
    struct net_buf_simple *value; /*!< The property value of Generic User Property state */
    } esp_ble_mesh_state_change_gen_user_property_set_t;

    /** Parameters of Generic Admin Property Set state change event */
    typedef struct {
    uint16_t id; /*!< The property id of Generic Admin Property state */
    uint8_t access; /*!< The property access of Generic Admin Property state */
    struct net_buf_simple *value; /*!< The property value of Generic Admin Property state */
    } esp_ble_mesh_state_change_gen_admin_property_set_t;

    /** Parameters of Generic Manufacturer Property Set state change event */
    typedef struct {
    uint16_t id; /*!< The property id of Generic Manufacturer Property state */
    uint8_t access; /*!< The property value of Generic Manufacturer Property state */
    } esp_ble_mesh_state_change_gen_manu_property_set_t;

    /**
    * @brief Generic Server Model state change value union
    */
    typedef union {
    /**
    * The recv_op in ctx can be used to decide which state is changed.
    */
    esp_ble_mesh_state_change_gen_onoff_set_t onoff_set; /*!< Generic OnOff Set */
    esp_ble_mesh_state_change_gen_level_set_t level_set; /*!< Generic Level Set */
    esp_ble_mesh_state_change_gen_delta_set_t delta_set; /*!< Generic Delta Set */
    esp_ble_mesh_state_change_gen_move_set_t move_set; /*!< Generic Move Set */
    esp_ble_mesh_state_change_gen_def_trans_time_set_t def_trans_time_set; /*!< Generic Default Transition Time Set */
    esp_ble_mesh_state_change_gen_onpowerup_set_t onpowerup_set; /*!< Generic OnPowerUp Set */
    esp_ble_mesh_state_change_gen_power_level_set_t power_level_set; /*!< Generic Power Level Set */
    esp_ble_mesh_state_change_gen_power_default_set_t power_default_set; /*!< Generic Power Default Set */
    esp_ble_mesh_state_change_gen_power_range_set_t power_range_set; /*!< Generic Power Range Set */
    esp_ble_mesh_state_change_gen_loc_global_set_t loc_global_set; /*!< Generic Location Global Set */
    esp_ble_mesh_state_change_gen_loc_local_set_t loc_local_set; /*!< Generic Location Local Set */
    esp_ble_mesh_state_change_gen_user_property_set_t user_property_set; /*!< Generic User Property Set */
    esp_ble_mesh_state_change_gen_admin_property_set_t admin_property_set; /*!< Generic Admin Property Set */
    esp_ble_mesh_state_change_gen_manu_property_set_t manu_property_set; /*!< Generic Manufacturer Property Set */
    } esp_ble_mesh_generic_server_state_change_t;

    /** Context of the received Generic User Property Get message */
    typedef struct {
    uint16_t property_id; /*!< Property ID identifying a Generic User Property */
    } esp_ble_mesh_server_recv_gen_user_property_get_t;

    /** Context of the received Generic Admin Property Get message */
    typedef struct {
    uint16_t property_id; /*!< Property ID identifying a Generic Admin Property */
    } esp_ble_mesh_server_recv_gen_admin_property_get_t;

    /** Context of the received Generic Manufacturer Property message */
    typedef struct {
    uint16_t property_id; /*!< Property ID identifying a Generic Manufacturer Property */
    } esp_ble_mesh_server_recv_gen_manufacturer_property_get_t;

    /** Context of the received Generic Client Properties Get message */
    typedef struct {
    uint16_t property_id; /*!< A starting Client Property ID present within an element */
    } esp_ble_mesh_server_recv_gen_client_properties_get_t;

    /**
    * @brief Generic Server Model received get message union
    */
    typedef union {
    esp_ble_mesh_server_recv_gen_user_property_get_t user_property; /*!< Generic User Property Get */
    esp_ble_mesh_server_recv_gen_admin_property_get_t admin_property; /*!< Generic Admin Property Get */
    esp_ble_mesh_server_recv_gen_manufacturer_property_get_t manu_property; /*!< Generic Manufacturer Property Get */
    esp_ble_mesh_server_recv_gen_client_properties_get_t client_properties; /*!< Generic Client Properties Get */
    } esp_ble_mesh_generic_server_recv_get_msg_t;

    /** Context of the received Generic OnOff Set message */
    typedef struct {
    bool op_en; /*!< Indicate if optional parameters are included */
    uint8_t onoff; /*!< Target value of Generic OnOff state */
    uint8_t tid; /*!< Transaction ID */
    uint8_t trans_time; /*!< Time to complete state transition (optional) */
    uint8_t delay; /*!< Indicate message execution delay (C.1) */
    } esp_ble_mesh_server_recv_gen_onoff_set_t;

    /** Context of the received Generic Level Set message */
    typedef struct {
    bool op_en; /*!< Indicate if optional parameters are included */
    int16_t level; /*!< Target value of Generic Level state */
    uint8_t tid; /*!< Transaction ID */
    uint8_t trans_time; /*!< Time to complete state transition (optional) */
    uint8_t delay; /*!< Indicate message execution delay (C.1) */
    } esp_ble_mesh_server_recv_gen_level_set_t;

    /** Context of the received Generic Delta Set message */
    typedef struct {
    bool op_en; /*!< Indicate if optional parameters are included */
    int32_t delta_level; /*!< Delta change of Generic Level state */
    uint8_t tid; /*!< Transaction ID */
    uint8_t trans_time; /*!< Time to complete state transition (optional) */
    uint8_t delay; /*!< Indicate message execution delay (C.1) */
    } esp_ble_mesh_server_recv_gen_delta_set_t;

    /** Context of the received Generic Move Set message */
    typedef struct {
    bool op_en; /*!< Indicate if optional parameters are included */
    int16_t delta_level; /*!< Delta Level step to calculate Move speed for Generic Level state */
    uint8_t tid; /*!< Transaction ID */
    uint8_t trans_time; /*!< Time to complete state transition (optional) */
    uint8_t delay; /*!< Indicate message execution delay (C.1) */
    } esp_ble_mesh_server_recv_gen_move_set_t;

    /** Context of the received Generic Default Transition Time Set message */
    typedef struct {
    uint8_t trans_time; /*!< The value of the Generic Default Transition Time state */
    } esp_ble_mesh_server_recv_gen_def_trans_time_set_t;

    /** Context of the received Generic OnPowerUp Set message */
    typedef struct {
    uint8_t onpowerup; /*!< The value of the Generic OnPowerUp state */
    } esp_ble_mesh_server_recv_gen_onpowerup_set_t;

    /** Context of the received Generic Power Level Set message */
    typedef struct {
    bool op_en; /*!< Indicate if optional parameters are included */
    uint16_t power; /*!< Target value of Generic Power Actual state */
    uint8_t tid; /*!< Transaction ID */
    uint8_t trans_time; /*!< Time to complete state transition (optional) */
    uint8_t delay; /*!< Indicate message execution delay (C.1) */
    } esp_ble_mesh_server_recv_gen_power_level_set_t;

    /** Context of the received Generic Power Default Set message */
    typedef struct {
    uint16_t power; /*!< The value of the Generic Power Default state */
    } esp_ble_mesh_server_recv_gen_power_default_set_t;

    /** Context of the received Generic Power Range Set message */
    typedef struct {
    uint16_t range_min; /*!< Value of Range Min field of Generic Power Range state */
    uint16_t range_max; /*!< Value of Range Max field of Generic Power Range state */
    } esp_ble_mesh_server_recv_gen_power_range_set_t;

    /** Context of the received Generic Location Global Set message */
    typedef struct {
    int32_t global_latitude; /*!< Global Coordinates (Latitude) */
    int32_t global_longitude; /*!< Global Coordinates (Longitude) */
    int16_t global_altitude; /*!< Global Altitude */
    } esp_ble_mesh_server_recv_gen_loc_global_set_t;

    /** Context of the received Generic Location Local Set message */
    typedef struct {
    int16_t local_north; /*!< Local Coordinates (North) */
    int16_t local_east; /*!< Local Coordinates (East) */
    int16_t local_altitude; /*!< Local Altitude */
    uint8_t floor_number; /*!< Floor Number */
    uint16_t uncertainty; /*!< Uncertainty */
    } esp_ble_mesh_server_recv_gen_loc_local_set_t;

    /** Context of the received Generic User Property Set message */
    typedef struct {
    uint16_t property_id; /*!< Property ID identifying a Generic User Property */
    struct net_buf_simple *property_value; /*!< Raw value for the User Property */
    } esp_ble_mesh_server_recv_gen_user_property_set_t;

    /** Context of the received Generic Admin Property Set message */
    typedef struct {
    uint16_t property_id; /*!< Property ID identifying a Generic Admin Property */
    uint8_t user_access; /*!< Enumeration indicating user access */
    struct net_buf_simple *property_value; /*!< Raw value for the Admin Property */
    } esp_ble_mesh_server_recv_gen_admin_property_set_t;

    /** Context of the received Generic Manufacturer Property Set message */
    typedef struct {
    uint16_t property_id; /*!< Property ID identifying a Generic Manufacturer Property */
    uint8_t user_access; /*!< Enumeration indicating user access */
    } esp_ble_mesh_server_recv_gen_manufacturer_property_set_t;

    /**
    * @brief Generic Server Model received set message union
    */
    typedef union {
    esp_ble_mesh_server_recv_gen_onoff_set_t onoff; /*!< Generic OnOff Set/Generic OnOff Set Unack */
    esp_ble_mesh_server_recv_gen_level_set_t level; /*!< Generic Level Set/Generic Level Set Unack */
    esp_ble_mesh_server_recv_gen_delta_set_t delta; /*!< Generic Delta Set/Generic Delta Set Unack */
    esp_ble_mesh_server_recv_gen_move_set_t move; /*!< Generic Move Set/Generic Move Set Unack */
    esp_ble_mesh_server_recv_gen_def_trans_time_set_t def_trans_time; /*!< Generic Default Transition Time Set/Generic Default Transition Time Set Unack */
    esp_ble_mesh_server_recv_gen_onpowerup_set_t onpowerup; /*!< Generic OnPowerUp Set/Generic OnPowerUp Set Unack */
    esp_ble_mesh_server_recv_gen_power_level_set_t power_level; /*!< Generic Power Level Set/Generic Power Level Set Unack */
    esp_ble_mesh_server_recv_gen_power_default_set_t power_default; /*!< Generic Power Default Set/Generic Power Default Set Unack */
    esp_ble_mesh_server_recv_gen_power_range_set_t power_range; /*!< Generic Power Range Set/Generic Power Range Set Unack */
    esp_ble_mesh_server_recv_gen_loc_global_set_t location_global; /*!< Generic Location Global Set/Generic Location Global Set Unack */
    esp_ble_mesh_server_recv_gen_loc_local_set_t location_local; /*!< Generic Location Local Set/Generic Location Local Set Unack */
    esp_ble_mesh_server_recv_gen_user_property_set_t user_property; /*!< Generic User Property Set/Generic User Property Set Unack */
    esp_ble_mesh_server_recv_gen_admin_property_set_t admin_property; /*!< Generic Admin Property Set/Generic Admin Property Set Unack */
    esp_ble_mesh_server_recv_gen_manufacturer_property_set_t manu_property; /*!< Generic Manufacturer Property Set/Generic Manufacturer Property Set Unack */
    } esp_ble_mesh_generic_server_recv_set_msg_t;

    /**
    * @brief Generic Server Model callback value union
    */
    typedef union {
    esp_ble_mesh_generic_server_state_change_t state_change; /*!< ESP_BLE_MESH_GENERIC_SERVER_STATE_CHANGE_EVT */
    esp_ble_mesh_generic_server_recv_get_msg_t get; /*!< ESP_BLE_MESH_GENERIC_SERVER_RECV_GET_MSG_EVT */
    esp_ble_mesh_generic_server_recv_set_msg_t set; /*!< ESP_BLE_MESH_GENERIC_SERVER_RECV_SET_MSG_EVT */
    } esp_ble_mesh_generic_server_cb_value_t;

    /** Generic Server Model callback parameters */
    typedef struct {
    esp_ble_mesh_model_t *model; /*!< Pointer to Generic Server Models */
    esp_ble_mesh_msg_ctx_t ctx; /*!< Context of the received messages */
    esp_ble_mesh_generic_server_cb_value_t value; /*!< Value of the received Generic Messages */
    } esp_ble_mesh_generic_server_cb_param_t;

    /** This enum value is the event of Generic Server Model */
    typedef enum {
    /**
    * 1. When get_auto_rsp is set to ESP_BLE_MESH_SERVER_AUTO_RSP, no event will be
    * callback to the application layer when Generic Get messages are received.
    * 2. When set_auto_rsp is set to ESP_BLE_MESH_SERVER_AUTO_RSP, this event will
    * be callback to the application layer when Generic Set/Set Unack messages
    * are received.
    */
    ESP_BLE_MESH_GENERIC_SERVER_STATE_CHANGE_EVT,
    /**
    * When get_auto_rsp is set to ESP_BLE_MESH_SERVER_RSP_BY_APP, this event will be
    * callback to the application layer when Generic Get messages are received.
    */
    ESP_BLE_MESH_GENERIC_SERVER_RECV_GET_MSG_EVT,
    /**
    * When set_auto_rsp is set to ESP_BLE_MESH_SERVER_RSP_BY_APP, this event will be
    * callback to the application layer when Generic Set/Set Unack messages are received.
    */
    ESP_BLE_MESH_GENERIC_SERVER_RECV_SET_MSG_EVT,
    ESP_BLE_MESH_GENERIC_SERVER_EVT_MAX,
    } esp_ble_mesh_generic_server_cb_event_t;

    /**
    * @brief Bluetooth Mesh Generic Server Model function.
    */

    /**
    * @brief Generic Server Model callback function type
    * @param event: Event type
    * @param param: Pointer to callback parameter
    */
    typedef void (* esp_ble_mesh_generic_server_cb_t)(esp_ble_mesh_generic_server_cb_event_t event,
    esp_ble_mesh_generic_server_cb_param_t *param);

    /**
    * @brief Register BLE Mesh Generic Server Model callback.
    *
    * @param[in] callback: Pointer to the callback function.
    *
    * @return ESP_OK on success or error code otherwise.
    *
    */
    esp_err_t esp_ble_mesh_register_generic_server_callback(esp_ble_mesh_generic_server_cb_t callback);

    #ifdef __cplusplus
    }
    #endif

    #endif /* _ESP_BLE_MESH_GENERIC_MODEL_API_H_ */
  4. lucasssvaz created this gist Aug 31, 2023.
    6 changes: 6 additions & 0 deletions README.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,6 @@
    # BLE Mesh Example

    These are modified files to be able to compile the ble_mesh.ino example.
    Note that a compilation error will still occur as the libraries need to be recompiled with [these configs](https://github.com/espressif/esp-idf/blob/master/examples/bluetooth/esp_ble_mesh/ble_mesh_node/onoff_server/sdkconfig.defaults)

    This is based on the [ESP-IDF Example](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/esp-ble-mesh/ble-mesh-index.html#getting-started-with-esp-ble-mesh)
    478 changes: 478 additions & 0 deletions ble_mesh.ino
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,478 @@
    #include "BLEDevice.h"
    #include "esp_bt_device.h"
    #include "esp_ble_mesh_defs.h"
    #include "esp_ble_mesh_common_api.h"
    #include "esp_ble_mesh_networking_api.h"
    #include "esp_ble_mesh_provisioning_api.h"
    #include "esp_ble_mesh_config_model_api.h"
    #include "esp_ble_mesh_generic_model_api.h"
    #include "esp_ble_mesh_local_data_operation_api.h"

    #define LED_R 25
    #define LED_G 26
    #define LED_B 27
    #define LED_ON 1
    #define LED_OFF 0

    #define CID_ESP 0x02E5

    struct led_state_s
    {
    uint8_t current;
    uint8_t previous;
    uint8_t pin;
    char *name;
    };

    struct led_state_s led_state[3] = {
    {LED_OFF, LED_OFF, LED_R, "red"},
    {LED_OFF, LED_OFF, LED_G, "green"},
    {LED_OFF, LED_OFF, LED_B, "blue"}};

    static uint8_t dev_uuid[16] = {0xdd, 0xdd};

    static esp_ble_mesh_cfg_srv_t config_server = {
    /* 3 transmissions with 20ms interval */
    .net_transmit = ESP_BLE_MESH_TRANSMIT(2, 20),
    .relay = ESP_BLE_MESH_RELAY_DISABLED,
    .relay_retransmit = ESP_BLE_MESH_TRANSMIT(2, 20),
    .beacon = ESP_BLE_MESH_BEACON_ENABLED,
    .gatt_proxy = ESP_BLE_MESH_GATT_PROXY_NOT_SUPPORTED,
    .friend_state = ESP_BLE_MESH_FRIEND_NOT_SUPPORTED,
    .default_ttl = 7,
    };

    ESP_BLE_MESH_MODEL_PUB_DEFINE(onoff_pub_0, 2 + 3, ROLE_NODE);
    static esp_ble_mesh_gen_onoff_srv_t onoff_server_0 = {
    .rsp_ctrl = {
    .get_auto_rsp = ESP_BLE_MESH_SERVER_AUTO_RSP,
    .set_auto_rsp = ESP_BLE_MESH_SERVER_AUTO_RSP,
    },
    };

    ESP_BLE_MESH_MODEL_PUB_DEFINE(onoff_pub_1, 2 + 3, ROLE_NODE);
    static esp_ble_mesh_gen_onoff_srv_t onoff_server_1 = {
    .rsp_ctrl = {
    .get_auto_rsp = ESP_BLE_MESH_SERVER_RSP_BY_APP,
    .set_auto_rsp = ESP_BLE_MESH_SERVER_RSP_BY_APP,
    },
    };

    ESP_BLE_MESH_MODEL_PUB_DEFINE(onoff_pub_2, 2 + 3, ROLE_NODE);
    static esp_ble_mesh_gen_onoff_srv_t onoff_server_2 = {
    .rsp_ctrl = {
    .get_auto_rsp = ESP_BLE_MESH_SERVER_AUTO_RSP,
    .set_auto_rsp = ESP_BLE_MESH_SERVER_RSP_BY_APP,
    },
    };

    static esp_ble_mesh_model_t root_models[] = {
    ESP_BLE_MESH_MODEL_CFG_SRV(&config_server),
    ESP_BLE_MESH_MODEL_GEN_ONOFF_SRV(&onoff_pub_0, &onoff_server_0),
    };

    static esp_ble_mesh_model_t extend_model_0[] = {
    ESP_BLE_MESH_MODEL_GEN_ONOFF_SRV(&onoff_pub_1, &onoff_server_1),
    };

    static esp_ble_mesh_model_t extend_model_1[] = {
    ESP_BLE_MESH_MODEL_GEN_ONOFF_SRV(&onoff_pub_2, &onoff_server_2),
    };

    static esp_ble_mesh_elem_t elements[] = {
    ESP_BLE_MESH_ELEMENT(0, root_models, ESP_BLE_MESH_MODEL_NONE),
    ESP_BLE_MESH_ELEMENT(0, extend_model_0, ESP_BLE_MESH_MODEL_NONE),
    ESP_BLE_MESH_ELEMENT(0, extend_model_1, ESP_BLE_MESH_MODEL_NONE),
    };

    static esp_ble_mesh_comp_t composition = {
    .cid = CID_ESP,
    .element_count = ARRAY_SIZE(elements),
    .elements = elements,
    };

    /* Disable OOB security for SILabs Android app */
    static esp_ble_mesh_prov_t provision = {
    .uuid = dev_uuid,
    #if 0
    .output_size = 4,
    .output_actions = ESP_BLE_MESH_DISPLAY_NUMBER,
    .input_actions = ESP_BLE_MESH_PUSH,
    .input_size = 4,
    #else
    .output_size = 0,
    .output_actions = 0,
    #endif
    };

    static void board_led_init(void)
    {
    for (int i = 0; i < 3; i++)
    {
    pinMode(led_state[i].pin, OUTPUT);
    digitalWrite(led_state[i].pin, LED_OFF);
    led_state[i].previous = LED_OFF;
    }
    }

    void board_led_operation(uint8_t pin, uint8_t onoff)
    {
    for (int i = 0; i < 3; i++)
    {
    if (led_state[i].pin != pin)
    {
    continue;
    }

    if (onoff == led_state[i].previous)
    {
    printf("led %s is already %s\n",
    led_state[i].name, (onoff ? "on" : "off"));
    return;
    }

    digitalWrite(pin, onoff);
    led_state[i].previous = onoff;
    return;
    }

    printf("LED is not found!\n");
    }

    void ble_mesh_get_dev_uuid(uint8_t *dev_uuid)
    {
    if (dev_uuid == NULL)
    {
    printf("%s, Invalid device uuid\n", __func__);
    return;
    }

    /* Copy device address to the device uuid with offset equals to 2 here.
    * The first two bytes is used for matching device uuid by Provisioner.
    * And using device address here is to avoid using the same device uuid
    * by different unprovisioned devices.
    */
    memcpy(dev_uuid + 2, esp_bt_dev_get_address(), BD_ADDR_LEN);
    }

    static void prov_complete(uint16_t net_idx, uint16_t addr, uint8_t flags, uint32_t iv_index)
    {
    printf("net_idx: 0x%04x, addr: 0x%04x\n", net_idx, addr);
    printf("flags: 0x%02x, iv_index: 0x%08\n" PRIx32, flags, iv_index);
    board_led_operation(LED_G, LED_OFF);
    }

    static void example_changeled_state_s(esp_ble_mesh_model_t *model,
    esp_ble_mesh_msg_ctx_t *ctx, uint8_t onoff)
    {
    uint16_t primary_addr = esp_ble_mesh_get_primary_element_address();
    uint8_t elem_count = esp_ble_mesh_get_element_count();
    struct led_state_s *led = NULL;
    uint8_t i;

    if (ESP_BLE_MESH_ADDR_IS_UNICAST(ctx->recv_dst))
    {
    for (i = 0; i < elem_count; i++)
    {
    if (ctx->recv_dst == (primary_addr + i))
    {
    led = &led_state[i];
    board_led_operation(led->pin, onoff);
    }
    }
    }
    else if (ESP_BLE_MESH_ADDR_IS_GROUP(ctx->recv_dst))
    {
    if (esp_ble_mesh_is_model_subscribed_to_group(model, ctx->recv_dst))
    {
    led = &led_state[model->element->element_addr - primary_addr];
    board_led_operation(led->pin, onoff);
    }
    }
    else if (ctx->recv_dst == 0xFFFF)
    {
    led = &led_state[model->element->element_addr - primary_addr];
    board_led_operation(led->pin, onoff);
    }
    }

    static void example_handle_gen_onoff_msg(esp_ble_mesh_model_t *model,
    esp_ble_mesh_msg_ctx_t *ctx,
    esp_ble_mesh_server_recv_gen_onoff_set_t *set)
    {
    esp_ble_mesh_gen_onoff_srv_t *srv = (esp_ble_mesh_gen_onoff_srv_t *)model->user_data;

    switch (ctx->recv_op)
    {
    case ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_GET:
    esp_ble_mesh_server_model_send_msg(model,
    ctx,
    ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_STATUS,
    sizeof(srv->state.onoff),
    &srv->state.onoff);
    break;

    case ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_SET:
    case ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_SET_UNACK:
    if (set->op_en == false)
    {
    srv->state.onoff = set->onoff;
    }
    else
    {
    /* TODO: Delay and state transition */
    srv->state.onoff = set->onoff;
    }
    if (ctx->recv_op == ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_SET)
    {
    esp_ble_mesh_server_model_send_msg(model,
    ctx,
    ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_STATUS,
    sizeof(srv->state.onoff),
    &srv->state.onoff);
    }

    esp_ble_mesh_model_publish(model,
    ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_STATUS,
    sizeof(srv->state.onoff),
    &srv->state.onoff,
    ROLE_NODE);

    example_changeled_state_s(model, ctx, srv->state.onoff);
    break;

    default:
    break;
    }
    }

    static void example_ble_mesh_provisioning_cb(esp_ble_mesh_prov_cb_event_t event,
    esp_ble_mesh_prov_cb_param_t *param)
    {
    switch (event)
    {
    case ESP_BLE_MESH_PROV_REGISTER_COMP_EVT:
    printf("ESP_BLE_MESH_PROV_REGISTER_COMP_EVT, err_code %d\n", param->prov_register_comp.err_code);
    break;

    case ESP_BLE_MESH_NODE_PROV_ENABLE_COMP_EVT:
    printf("ESP_BLE_MESH_NODE_PROV_ENABLE_COMP_EVT, err_code %d\n", param->node_prov_enable_comp.err_code);
    break;

    case ESP_BLE_MESH_NODE_PROV_LINK_OPEN_EVT:
    printf("ESP_BLE_MESH_NODE_PROV_LINK_OPEN_EVT, bearer %s\n",
    param->node_prov_link_open.bearer == ESP_BLE_MESH_PROV_ADV ? "PB-ADV" : "PB-GATT");
    break;

    case ESP_BLE_MESH_NODE_PROV_LINK_CLOSE_EVT:
    printf("ESP_BLE_MESH_NODE_PROV_LINK_CLOSE_EVT, bearer %s\n",
    param->node_prov_link_close.bearer == ESP_BLE_MESH_PROV_ADV ? "PB-ADV" : "PB-GATT");
    break;

    case ESP_BLE_MESH_NODE_PROV_COMPLETE_EVT:
    printf("ESP_BLE_MESH_NODE_PROV_COMPLETE_EVT\n");
    prov_complete(param->node_prov_complete.net_idx, param->node_prov_complete.addr,
    param->node_prov_complete.flags, param->node_prov_complete.iv_index);
    break;

    case ESP_BLE_MESH_NODE_PROV_RESET_EVT:
    printf("ESP_BLE_MESH_NODE_PROV_RESET_EVT\n");
    break;

    case ESP_BLE_MESH_NODE_SET_UNPROV_DEV_NAME_COMP_EVT:
    printf("ESP_BLE_MESH_NODE_SET_UNPROV_DEV_NAME_COMP_EVT, err_code %d\n", param->node_set_unprov_dev_name_comp.err_code);
    break;

    default:
    break;
    }
    }

    static void example_ble_mesh_generic_server_cb(esp_ble_mesh_generic_server_cb_event_t event,
    esp_ble_mesh_generic_server_cb_param_t *param)
    {
    esp_ble_mesh_gen_onoff_srv_t *srv;
    printf("event 0x%02x, opcode 0x%04" PRIx32 ", src 0x%04x, dst 0x%04x\n",
    event, param->ctx.recv_op, param->ctx.addr, param->ctx.recv_dst);

    switch (event)
    {
    case ESP_BLE_MESH_GENERIC_SERVER_STATE_CHANGE_EVT:
    printf("ESP_BLE_MESH_GENERIC_SERVER_STATE_CHANGE_EVT\n");
    if (param->ctx.recv_op == ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_SET ||
    param->ctx.recv_op == ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_SET_UNACK)
    {
    printf("onoff 0x%02x\n", param->value.state_change.onoff_set.onoff);
    example_changeled_state_s(param->model, &param->ctx, param->value.state_change.onoff_set.onoff);
    }
    break;

    case ESP_BLE_MESH_GENERIC_SERVER_RECV_GET_MSG_EVT:
    printf("ESP_BLE_MESH_GENERIC_SERVER_RECV_GET_MSG_EVT\n");
    if (param->ctx.recv_op == ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_GET)
    {
    srv = (esp_ble_mesh_gen_onoff_srv_t *)param->model->user_data;
    printf("onoff 0x%02x\n", srv->state.onoff);
    example_handle_gen_onoff_msg(param->model, &param->ctx, NULL);
    }
    break;

    case ESP_BLE_MESH_GENERIC_SERVER_RECV_SET_MSG_EVT:
    printf("ESP_BLE_MESH_GENERIC_SERVER_RECV_SET_MSG_EVT\n");
    if (param->ctx.recv_op == ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_SET ||
    param->ctx.recv_op == ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_SET_UNACK)
    {
    printf("onoff 0x%02x, tid 0x%02x\n", param->value.set.onoff.onoff, param->value.set.onoff.tid);
    if (param->value.set.onoff.op_en)
    {
    printf("trans_time 0x%02x, delay 0x%02x\n",
    param->value.set.onoff.trans_time, param->value.set.onoff.delay);
    }
    example_handle_gen_onoff_msg(param->model, &param->ctx, &param->value.set.onoff);
    }
    break;

    default:
    printf("Unknown Generic Server event 0x%02x\n", event);
    break;
    }
    }

    static void example_ble_mesh_config_server_cb(esp_ble_mesh_cfg_server_cb_event_t event,
    esp_ble_mesh_cfg_server_cb_param_t *param)
    {
    if (event == ESP_BLE_MESH_CFG_SERVER_STATE_CHANGE_EVT)
    {
    switch (param->ctx.recv_op)
    {
    case ESP_BLE_MESH_MODEL_OP_APP_KEY_ADD:
    printf("ESP_BLE_MESH_MODEL_OP_APP_KEY_ADD\n");
    printf("net_idx 0x%04x, app_idx 0x%04x\n",
    param->value.state_change.appkey_add.net_idx,
    param->value.state_change.appkey_add.app_idx);
    ESP_LOG_BUFFER_HEX("AppKey", param->value.state_change.appkey_add.app_key, 16);
    break;

    case ESP_BLE_MESH_MODEL_OP_MODEL_APP_BIND:
    printf("ESP_BLE_MESH_MODEL_OP_MODEL_APP_BIND\n");
    printf("elem_addr 0x%04x, app_idx 0x%04x, cid 0x%04x, mod_id 0x%04x\n",
    param->value.state_change.mod_app_bind.element_addr,
    param->value.state_change.mod_app_bind.app_idx,
    param->value.state_change.mod_app_bind.company_id,
    param->value.state_change.mod_app_bind.model_id);
    break;

    case ESP_BLE_MESH_MODEL_OP_MODEL_SUB_ADD:
    printf("ESP_BLE_MESH_MODEL_OP_MODEL_SUB_ADD\n");
    printf("elem_addr 0x%04x, sub_addr 0x%04x, cid 0x%04x, mod_id 0x%04x\n",
    param->value.state_change.mod_sub_add.element_addr,
    param->value.state_change.mod_sub_add.sub_addr,
    param->value.state_change.mod_sub_add.company_id,
    param->value.state_change.mod_sub_add.model_id);
    break;

    default:
    break;
    }
    }
    }

    /*
    esp_err_t bluetooth_init(void)
    {
    esp_err_t ret;
    ESP_ERROR_CHECK(esp_bt_controller_mem_release(ESP_BT_MODE_CLASSIC_BT));
    esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT();
    ret = esp_bt_controller_init(&bt_cfg);
    if (ret)
    {
    printf("%s initialize controller failed\n", __func__);
    return ret;
    }
    ret = esp_bt_controller_enable(ESP_BT_MODE_BLE);
    if (ret)
    {
    printf("%s enable controller failed\n", __func__);
    return ret;
    }
    ret = esp_bluedroid_init();
    if (ret)
    {
    printf("%s init bluetooth failed\n", __func__);
    return ret;
    }
    ret = esp_bluedroid_enable();
    if (ret)
    {
    printf("%s enable bluetooth failed\n", __func__);
    return ret;
    }
    return ret;
    }
    */

    static int ble_mesh_init(void)
    {
    esp_err_t err = ESP_OK;

    esp_ble_mesh_register_prov_callback(example_ble_mesh_provisioning_cb);
    esp_ble_mesh_register_config_server_callback(example_ble_mesh_config_server_cb);
    esp_ble_mesh_register_generic_server_callback(example_ble_mesh_generic_server_cb);

    err = esp_ble_mesh_init(&provision, &composition);
    if (err != ESP_OK)
    {
    printf("Failed to initialize mesh stack (err %d)\n", err);
    return err;
    }

    int prov_flags = (ESP_BLE_MESH_PROV_ADV | ESP_BLE_MESH_PROV_GATT);
    err = esp_ble_mesh_node_prov_enable((esp_ble_mesh_prov_bearer_t)prov_flags);
    if (err != ESP_OK)
    {
    printf("Failed to enable mesh node (err %d)\n", err);
    return err;
    }

    printf("BLE Mesh Node initialized\n");

    board_led_operation(LED_G, LED_ON);

    return err;
    }

    void setup(void)
    {
    int ret;

    // Open serial communications and wait for port to open:
    Serial.begin(115200);
    while (!Serial)
    {
    ; // wait for serial port to connect. Needed for native USB port only
    }

    printf("Initializing...\n");

    board_led_init();

    BLEDevice::init("");

    ble_mesh_get_dev_uuid(dev_uuid);

    /* Initialize the Bluetooth Mesh Subsystem */
    ret = ble_mesh_init();
    if (ret)
    {
    printf("Bluetooth mesh init failed (err %d)\n", ret);
    }
    }

    void loop(void)
    {
    delay(1);
    }
    2,287 changes: 2,287 additions & 0 deletions esp_ble_mesh_defs.h
    2,287 additions, 0 deletions not shown because the diff is too large. Please use a local Git client to view these changes.
    1,296 changes: 1,296 additions & 0 deletions esp_ble_mesh_generic_model_api.h
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,1296 @@
    /*
    * SPDX-FileCopyrightText: 2017-2021 Espressif Systems (Shanghai) CO LTD
    *
    * SPDX-License-Identifier: Apache-2.0
    */

    /** @file
    * @brief Bluetooth Mesh Generic Client Model APIs.
    */

    #ifndef _ESP_BLE_MESH_GENERIC_MODEL_API_H_
    #define _ESP_BLE_MESH_GENERIC_MODEL_API_H_

    #include "esp_ble_mesh_defs.h"

    #ifdef __cplusplus
    extern "C" {
    #endif

    /** @def ESP_BLE_MESH_MODEL_GEN_ONOFF_CLI
    *
    * @brief Define a new Generic OnOff Client Model.
    *
    * @note This API needs to be called for each element on which
    * the application needs to have a Generic OnOff Client Model.
    *
    * @param cli_pub Pointer to the unique struct esp_ble_mesh_model_pub_t.
    * @param cli_data Pointer to the unique struct esp_ble_mesh_client_t.
    *
    * @return New Generic OnOff Client Model instance.
    */
    #define ESP_BLE_MESH_MODEL_GEN_ONOFF_CLI(cli_pub, cli_data) \
    ESP_BLE_MESH_SIG_MODEL(ESP_BLE_MESH_MODEL_ID_GEN_ONOFF_CLI, \
    NULL, cli_pub, cli_data)

    /** @def ESP_BLE_MESH_MODEL_GEN_LEVEL_CLI
    *
    * @brief Define a new Generic Level Client Model.
    *
    * @note This API needs to be called for each element on which
    * the application needs to have a Generic Level Client Model.
    *
    * @param cli_pub Pointer to the unique struct esp_ble_mesh_model_pub_t.
    * @param cli_data Pointer to the unique struct esp_ble_mesh_client_t.
    *
    * @return New Generic Level Client Model instance.
    */

    #define ESP_BLE_MESH_MODEL_GEN_LEVEL_CLI(cli_pub, cli_data) \
    ESP_BLE_MESH_SIG_MODEL(ESP_BLE_MESH_MODEL_ID_GEN_LEVEL_CLI, \
    NULL, cli_pub, cli_data)

    /** @def ESP_BLE_MESH_MODEL_GEN_DEF_TRANS_TIME_CLI
    *
    * @brief Define a new Generic Default Transition Time Client Model.
    *
    * @note This API needs to be called for each element on which
    * the application needs to have a Generic Default Transition
    * Time Client Model.
    *
    * @param cli_pub Pointer to the unique struct esp_ble_mesh_model_pub_t.
    * @param cli_data Pointer to the unique struct esp_ble_mesh_client_t.
    *
    * @return New Generic Default Transition Time Client Model instance.
    */
    #define ESP_BLE_MESH_MODEL_GEN_DEF_TRANS_TIME_CLI(cli_pub, cli_data) \
    ESP_BLE_MESH_SIG_MODEL(ESP_BLE_MESH_MODEL_ID_GEN_DEF_TRANS_TIME_CLI, \
    NULL, cli_pub, cli_data)

    /** @def ESP_BLE_MESH_MODEL_GEN_POWER_ONOFF_CLI
    *
    * @brief Define a new Generic Power OnOff Client Model.
    *
    * @note This API needs to be called for each element on which
    * the application needs to have a Generic Power OnOff Client Model.
    *
    * @param cli_pub Pointer to the unique struct esp_ble_mesh_model_pub_t.
    * @param cli_data Pointer to the unique struct esp_ble_mesh_client_t.
    *
    * @return New Generic Power OnOff Client Model instance.
    */
    #define ESP_BLE_MESH_MODEL_GEN_POWER_ONOFF_CLI(cli_pub, cli_data) \
    ESP_BLE_MESH_SIG_MODEL(ESP_BLE_MESH_MODEL_ID_GEN_POWER_ONOFF_CLI, \
    NULL, cli_pub, cli_data)

    /** @def ESP_BLE_MESH_MODEL_GEN_POWER_LEVEL_CLI
    *
    * @brief Define a new Generic Power Level Client Model.
    *
    * @note This API needs to be called for each element on which
    * the application needs to have a Generic Power Level Client Model.
    *
    * @param cli_pub Pointer to the unique struct esp_ble_mesh_model_pub_t.
    * @param cli_data Pointer to the unique struct esp_ble_mesh_client_t.
    *
    * @return New Generic Power Level Client Model instance.
    */
    #define ESP_BLE_MESH_MODEL_GEN_POWER_LEVEL_CLI(cli_pub, cli_data) \
    ESP_BLE_MESH_SIG_MODEL(ESP_BLE_MESH_MODEL_ID_GEN_POWER_LEVEL_CLI, \
    NULL, cli_pub, cli_data)

    /** @def ESP_BLE_MESH_MODEL_GEN_BATTERY_CLI
    *
    * @brief Define a new Generic Battery Client Model.
    *
    * @note This API needs to be called for each element on which
    * the application needs to have a Generic Battery Client Model.
    *
    * @param cli_pub Pointer to the unique struct esp_ble_mesh_model_pub_t.
    * @param cli_data Pointer to the unique struct esp_ble_mesh_client_t.
    *
    * @return New Generic Battery Client Model instance.
    */
    #define ESP_BLE_MESH_MODEL_GEN_BATTERY_CLI(cli_pub, cli_data) \
    ESP_BLE_MESH_SIG_MODEL(ESP_BLE_MESH_MODEL_ID_GEN_BATTERY_CLI, \
    NULL, cli_pub, cli_data)

    /** @def ESP_BLE_MESH_MODEL_GEN_LOCATION_CLI
    *
    * @brief Define a new Generic Location Client Model.
    *
    * @note This API needs to be called for each element on which
    * the application needs to have a Generic Location Client Model.
    *
    * @param cli_pub Pointer to the unique struct esp_ble_mesh_model_pub_t.
    * @param cli_data Pointer to the unique struct esp_ble_mesh_client_t.
    *
    * @return New Generic Location Client Model instance.
    */
    #define ESP_BLE_MESH_MODEL_GEN_LOCATION_CLI(cli_pub, cli_data) \
    ESP_BLE_MESH_SIG_MODEL(ESP_BLE_MESH_MODEL_ID_GEN_LOCATION_CLI, \
    NULL, cli_pub, cli_data)

    /** @def ESP_BLE_MESH_MODEL_GEN_PROPERTY_CLI
    *
    * @brief Define a new Generic Property Client Model.
    *
    * @note This API needs to be called for each element on which
    * the application needs to have a Generic Property Client Model.
    *
    * @param cli_pub Pointer to the unique struct esp_ble_mesh_model_pub_t.
    * @param cli_data Pointer to the unique struct esp_ble_mesh_client_t.
    *
    * @return New Generic Location Client Model instance.
    */
    #define ESP_BLE_MESH_MODEL_GEN_PROPERTY_CLI(cli_pub, cli_data) \
    ESP_BLE_MESH_SIG_MODEL(ESP_BLE_MESH_MODEL_ID_GEN_PROP_CLI, \
    NULL, cli_pub, cli_data)

    /**
    * @brief Bluetooth Mesh Generic Client Model Get and Set parameters structure.
    */

    /** Parameters of Generic OnOff Set. */
    typedef struct {
    bool op_en; /*!< Indicate if optional parameters are included */
    uint8_t onoff; /*!< Target value of Generic OnOff state */
    uint8_t tid; /*!< Transaction ID */
    uint8_t trans_time; /*!< Time to complete state transition (optional) */
    uint8_t delay; /*!< Indicate message execution delay (C.1) */
    } esp_ble_mesh_gen_onoff_set_t;

    /** Parameters of Generic Level Set. */
    typedef struct {
    bool op_en; /*!< Indicate if optional parameters are included */
    int16_t level; /*!< Target value of Generic Level state */
    uint8_t tid; /*!< Transaction ID */
    uint8_t trans_time; /*!< Time to complete state transition (optional) */
    uint8_t delay; /*!< Indicate message execution delay (C.1) */
    } esp_ble_mesh_gen_level_set_t;

    /** Parameters of Generic Delta Set. */
    typedef struct {
    bool op_en; /*!< Indicate if optional parameters are included */
    int32_t level; /*!< Delta change of Generic Level state */
    uint8_t tid; /*!< Transaction ID */
    uint8_t trans_time; /*!< Time to complete state transition (optional) */
    uint8_t delay; /*!< Indicate message execution delay (C.1) */
    } esp_ble_mesh_gen_delta_set_t;

    /** Parameters of Generic Move Set. */
    typedef struct {
    bool op_en; /*!< Indicate if optional parameters are included */
    int16_t delta_level; /*!< Delta Level step to calculate Move speed for Generic Level state */
    uint8_t tid; /*!< Transaction ID */
    uint8_t trans_time; /*!< Time to complete state transition (optional) */
    uint8_t delay; /*!< Indicate message execution delay (C.1) */
    } esp_ble_mesh_gen_move_set_t;

    /** Parameter of Generic Default Transition Time Set. */
    typedef struct {
    uint8_t trans_time; /*!< The value of the Generic Default Transition Time state */
    } esp_ble_mesh_gen_def_trans_time_set_t;

    /** Parameter of Generic OnPowerUp Set. */
    typedef struct {
    uint8_t onpowerup; /*!< The value of the Generic OnPowerUp state */
    } esp_ble_mesh_gen_onpowerup_set_t;

    /** Parameters of Generic Power Level Set. */
    typedef struct {
    bool op_en; /*!< Indicate if optional parameters are included */
    uint16_t power; /*!< Target value of Generic Power Actual state */
    uint8_t tid; /*!< Transaction ID */
    uint8_t trans_time; /*!< Time to complete state transition (optional) */
    uint8_t delay; /*!< Indicate message execution delay (C.1) */
    } esp_ble_mesh_gen_power_level_set_t;

    /** Parameter of Generic Power Default Set. */
    typedef struct {
    uint16_t power; /*!< The value of the Generic Power Default state */
    } esp_ble_mesh_gen_power_default_set_t;

    /** Parameters of Generic Power Range Set. */
    typedef struct {
    uint16_t range_min; /*!< Value of Range Min field of Generic Power Range state */
    uint16_t range_max; /*!< Value of Range Max field of Generic Power Range state */
    } esp_ble_mesh_gen_power_range_set_t;

    /** Parameters of Generic Location Global Set. */
    typedef struct {
    int32_t global_latitude; /*!< Global Coordinates (Latitude) */
    int32_t global_longitude; /*!< Global Coordinates (Longitude) */
    int16_t global_altitude; /*!< Global Altitude */
    } esp_ble_mesh_gen_loc_global_set_t;

    /** Parameters of Generic Location Local Set. */
    typedef struct {
    int16_t local_north; /*!< Local Coordinates (North) */
    int16_t local_east; /*!< Local Coordinates (East) */
    int16_t local_altitude; /*!< Local Altitude */
    uint8_t floor_number; /*!< Floor Number */
    uint16_t uncertainty; /*!< Uncertainty */
    } esp_ble_mesh_gen_loc_local_set_t;

    /** Parameter of Generic User Property Get. */
    typedef struct {
    uint16_t property_id; /*!< Property ID identifying a Generic User Property */
    } esp_ble_mesh_gen_user_property_get_t;

    /** Parameters of Generic User Property Set. */
    typedef struct {
    uint16_t property_id; /*!< Property ID identifying a Generic User Property */
    struct net_buf_simple *property_value; /*!< Raw value for the User Property */
    } esp_ble_mesh_gen_user_property_set_t;

    /** Parameter of Generic Admin Property Get. */
    typedef struct {
    uint16_t property_id; /*!< Property ID identifying a Generic Admin Property */
    } esp_ble_mesh_gen_admin_property_get_t;

    /** Parameters of Generic Admin Property Set. */
    typedef struct {
    uint16_t property_id; /*!< Property ID identifying a Generic Admin Property */
    uint8_t user_access; /*!< Enumeration indicating user access */
    struct net_buf_simple *property_value; /*!< Raw value for the Admin Property */
    } esp_ble_mesh_gen_admin_property_set_t;

    /** Parameter of Generic Manufacturer Property Get. */
    typedef struct {
    uint16_t property_id; /*!< Property ID identifying a Generic Manufacturer Property */
    } esp_ble_mesh_gen_manufacturer_property_get_t;

    /** Parameters of Generic Manufacturer Property Set. */
    typedef struct {
    uint16_t property_id; /*!< Property ID identifying a Generic Manufacturer Property */
    uint8_t user_access; /*!< Enumeration indicating user access */
    } esp_ble_mesh_gen_manufacturer_property_set_t;

    /** Parameter of Generic Client Properties Get. */
    typedef struct {
    uint16_t property_id; /*!< A starting Client Property ID present within an element */
    } esp_ble_mesh_gen_client_properties_get_t;

    /**
    * @brief Generic Client Model get message union
    */
    typedef union {
    esp_ble_mesh_gen_user_property_get_t user_property_get; /*!< For ESP_BLE_MESH_MODEL_OP_GEN_USER_PROPERTY_GET */
    esp_ble_mesh_gen_admin_property_get_t admin_property_get; /*!< For ESP_BLE_MESH_MODEL_OP_GEN_ADMIN_PROPERTY_GET*/
    esp_ble_mesh_gen_manufacturer_property_get_t manufacturer_property_get; /*!< For ESP_BLE_MESH_MODEL_OP_GEN_MANUFACTURER_PROPERTY_SET */
    esp_ble_mesh_gen_client_properties_get_t client_properties_get; /*!< For ESP_BLE_MESH_MODEL_OP_GEN_CLIENT_PROPERTIES_GET */
    } esp_ble_mesh_generic_client_get_state_t;

    /**
    * @brief Generic Client Model set message union
    */
    typedef union {
    esp_ble_mesh_gen_onoff_set_t onoff_set; /*!< For ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_SET & ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_SET_UNACK */
    esp_ble_mesh_gen_level_set_t level_set; /*!< For ESP_BLE_MESH_MODEL_OP_GEN_LEVEL_SET & ESP_BLE_MESH_MODEL_OP_GEN_LEVEL_SET_UNACK */
    esp_ble_mesh_gen_delta_set_t delta_set; /*!< For ESP_BLE_MESH_MODEL_OP_GEN_DELTA_SET & ESP_BLE_MESH_MODEL_OP_GEN_DELTA_SET_UNACK */
    esp_ble_mesh_gen_move_set_t move_set; /*!< For ESP_BLE_MESH_MODEL_OP_GEN_MOVE_SET & ESP_BLE_MESH_MODEL_OP_GEN_MOVE_SET_UNACK */
    esp_ble_mesh_gen_def_trans_time_set_t def_trans_time_set; /*!< For ESP_BLE_MESH_MODEL_OP_GEN_DEF_TRANS_TIME_SET & ESP_BLE_MESH_MODEL_OP_GEN_DEF_TRANS_TIME_SET_UNACK */
    esp_ble_mesh_gen_onpowerup_set_t power_set; /*!< For ESP_BLE_MESH_MODEL_OP_GEN_ONPOWERUP_SET & ESP_BLE_MESH_MODEL_OP_GEN_ONPOWERUP_SET_UNACK */
    esp_ble_mesh_gen_power_level_set_t power_level_set; /*!< For ESP_BLE_MESH_MODEL_OP_GEN_POWER_LEVEL_SET & ESP_BLE_MESH_MODEL_OP_GEN_POWER_LEVEL_SET_UNACK */
    esp_ble_mesh_gen_power_default_set_t power_default_set; /*!< For ESP_BLE_MESH_MODEL_OP_GEN_POWER_DEFAULT_SET & ESP_BLE_MESH_MODEL_OP_GEN_POWER_DEFAULT_SET_UNACK */
    esp_ble_mesh_gen_power_range_set_t power_range_set; /*!< For ESP_BLE_MESH_MODEL_OP_GEN_POWER_RANGE_SET & ESP_BLE_MESH_MODEL_OP_GEN_POWER_RANGE_SET_UNACK */
    esp_ble_mesh_gen_loc_global_set_t loc_global_set; /*!< For ESP_BLE_MESH_MODEL_OP_GEN_LOC_GLOBAL_SET & ESP_BLE_MESH_MODEL_OP_GEN_LOC_GLOBAL_SET_UNACK */
    esp_ble_mesh_gen_loc_local_set_t loc_local_set; /*!< For ESP_BLE_MESH_MODEL_OP_GEN_LOC_LOCAL_SET & ESP_BLE_MESH_MODEL_OP_GEN_LOC_LOCAL_SET_UNACK */
    esp_ble_mesh_gen_user_property_set_t user_property_set; /*!< For ESP_BLE_MESH_MODEL_OP_GEN_USER_PROPERTY_SET & ESP_BLE_MESH_MODEL_OP_GEN_USER_PROPERTY_SET_UNACK */
    esp_ble_mesh_gen_admin_property_set_t admin_property_set; /*!< For ESP_BLE_MESH_MODEL_OP_GEN_ADMIN_PROPERTY_SET & ESP_BLE_MESH_MODEL_OP_GEN_ADMIN_PROPERTY_SET_UNACK */
    esp_ble_mesh_gen_manufacturer_property_set_t manufacturer_property_set; /*!< For ESP_BLE_MESH_MODEL_OP_GEN_MANUFACTURER_PROPERTY_SET & ESP_BLE_MESH_MODEL_OP_GEN_MANUFACTURER_PROPERTY_SET_UNACK */
    } esp_ble_mesh_generic_client_set_state_t;

    /**
    * @brief Bluetooth Mesh Generic Client Model Get and Set callback parameters structure.
    */

    /** Parameters of Generic OnOff Status. */
    typedef struct {
    bool op_en; /*!< Indicate if optional parameters are included */
    uint8_t present_onoff; /*!< Current value of Generic OnOff state */
    uint8_t target_onoff; /*!< Target value of Generic OnOff state (optional) */
    uint8_t remain_time; /*!< Time to complete state transition (C.1) */
    } esp_ble_mesh_gen_onoff_status_cb_t;

    /** Parameters of Generic Level Status. */
    typedef struct {
    bool op_en; /*!< Indicate if optional parameters are included */
    int16_t present_level; /*!< Current value of Generic Level state */
    int16_t target_level; /*!< Target value of the Generic Level state (optional) */
    uint8_t remain_time; /*!< Time to complete state transition (C.1) */
    } esp_ble_mesh_gen_level_status_cb_t;

    /** Parameter of Generic Default Transition Time Status. */
    typedef struct {
    uint8_t trans_time; /*!< The value of the Generic Default Transition Time state */
    } esp_ble_mesh_gen_def_trans_time_status_cb_t;

    /** Parameter of Generic OnPowerUp Status. */
    typedef struct {
    uint8_t onpowerup; /*!< The value of the Generic OnPowerUp state */
    } esp_ble_mesh_gen_onpowerup_status_cb_t;

    /** Parameters of Generic Power Level Status. */
    typedef struct {
    bool op_en; /*!< Indicate if optional parameters are included */
    uint16_t present_power; /*!< Current value of Generic Power Actual state */
    uint16_t target_power; /*!< Target value of Generic Power Actual state (optional) */
    uint8_t remain_time; /*!< Time to complete state transition (C.1) */
    } esp_ble_mesh_gen_power_level_status_cb_t;

    /** Parameter of Generic Power Last Status. */
    typedef struct {
    uint16_t power; /*!< The value of the Generic Power Last state */
    } esp_ble_mesh_gen_power_last_status_cb_t;

    /** Parameter of Generic Power Default Status. */
    typedef struct {
    uint16_t power; /*!< The value of the Generic Default Last state */
    } esp_ble_mesh_gen_power_default_status_cb_t;

    /** Parameters of Generic Power Range Status. */
    typedef struct {
    uint8_t status_code; /*!< Status Code for the request message */
    uint16_t range_min; /*!< Value of Range Min field of Generic Power Range state */
    uint16_t range_max; /*!< Value of Range Max field of Generic Power Range state */
    } esp_ble_mesh_gen_power_range_status_cb_t;

    /** Parameters of Generic Battery Status. */
    typedef struct {
    uint32_t battery_level : 8; /*!< Value of Generic Battery Level state */
    uint32_t time_to_discharge : 24; /*!< Value of Generic Battery Time to Discharge state */
    uint32_t time_to_charge : 24; /*!< Value of Generic Battery Time to Charge state */
    uint32_t flags : 8; /*!< Value of Generic Battery Flags state */
    } esp_ble_mesh_gen_battery_status_cb_t;

    /** Parameters of Generic Location Global Status. */
    typedef struct {
    int32_t global_latitude; /*!< Global Coordinates (Latitude) */
    int32_t global_longitude; /*!< Global Coordinates (Longitude) */
    int16_t global_altitude; /*!< Global Altitude */
    } esp_ble_mesh_gen_loc_global_status_cb_t;

    /** Parameters of Generic Location Local Status. */
    typedef struct {
    int16_t local_north; /*!< Local Coordinates (North) */
    int16_t local_east; /*!< Local Coordinates (East) */
    int16_t local_altitude; /*!< Local Altitude */
    uint8_t floor_number; /*!< Floor Number */
    uint16_t uncertainty; /*!< Uncertainty */
    } esp_ble_mesh_gen_loc_local_status_cb_t;

    /** Parameter of Generic User Properties Status. */
    typedef struct {
    struct net_buf_simple *property_ids; /*!< Buffer contains a sequence of N User Property IDs */
    } esp_ble_mesh_gen_user_properties_status_cb_t;

    /** Parameters of Generic User Property Status. */
    typedef struct {
    bool op_en; /*!< Indicate if optional parameters are included */
    uint16_t property_id; /*!< Property ID identifying a Generic User Property */
    uint8_t user_access; /*!< Enumeration indicating user access (optional) */
    struct net_buf_simple *property_value; /*!< Raw value for the User Property (C.1) */
    } esp_ble_mesh_gen_user_property_status_cb_t;

    /** Parameter of Generic Admin Properties Status. */
    typedef struct {
    struct net_buf_simple *property_ids; /*!< Buffer contains a sequence of N Admin Property IDs */
    } esp_ble_mesh_gen_admin_properties_status_cb_t;

    /** Parameters of Generic Admin Property Status. */
    typedef struct {
    bool op_en; /*!< Indicate if optional parameters are included */
    uint16_t property_id; /*!< Property ID identifying a Generic Admin Property */
    uint8_t user_access; /*!< Enumeration indicating user access (optional) */
    struct net_buf_simple *property_value; /*!< Raw value for the Admin Property (C.1) */
    } esp_ble_mesh_gen_admin_property_status_cb_t;

    /** Parameter of Generic Manufacturer Properties Status. */
    typedef struct {
    struct net_buf_simple *property_ids; /*!< Buffer contains a sequence of N Manufacturer Property IDs */
    } esp_ble_mesh_gen_manufacturer_properties_status_cb_t;

    /** Parameters of Generic Manufacturer Property Status. */
    typedef struct {
    bool op_en; /*!< Indicate if optional parameters are included */
    uint16_t property_id; /*!< Property ID identifying a Generic Manufacturer Property */
    uint8_t user_access; /*!< Enumeration indicating user access (optional) */
    struct net_buf_simple *property_value; /*!< Raw value for the Manufacturer Property (C.1) */
    } esp_ble_mesh_gen_manufacturer_property_status_cb_t;

    /** Parameter of Generic Client Properties Status. */
    typedef struct {
    struct net_buf_simple *property_ids; /*!< Buffer contains a sequence of N Client Property IDs */
    } esp_ble_mesh_gen_client_properties_status_cb_t;

    /**
    * @brief Generic Client Model received message union
    */
    typedef union {
    esp_ble_mesh_gen_onoff_status_cb_t onoff_status; /*!< For ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_STATUS */
    esp_ble_mesh_gen_level_status_cb_t level_status; /*!< For ESP_BLE_MESH_MODEL_OP_GEN_LEVEL_STATUS */
    esp_ble_mesh_gen_def_trans_time_status_cb_t def_trans_time_status; /*!< For ESP_BLE_MESH_MODEL_OP_GEN_DEF_TRANS_TIME_STATUS */
    esp_ble_mesh_gen_onpowerup_status_cb_t onpowerup_status; /*!< For ESP_BLE_MESH_MODEL_OP_GEN_ONPOWERUP_STATUS */
    esp_ble_mesh_gen_power_level_status_cb_t power_level_status; /*!< For ESP_BLE_MESH_MODEL_OP_GEN_POWER_LEVEL_STATUS */
    esp_ble_mesh_gen_power_last_status_cb_t power_last_status; /*!< For ESP_BLE_MESH_MODEL_OP_GEN_POWER_LAST_STATUS */
    esp_ble_mesh_gen_power_default_status_cb_t power_default_status; /*!< For ESP_BLE_MESH_MODEL_OP_GEN_POWER_DEFAULT_STATUS */
    esp_ble_mesh_gen_power_range_status_cb_t power_range_status; /*!< For ESP_BLE_MESH_MODEL_OP_GEN_POWER_RANGE_STATUS */
    esp_ble_mesh_gen_battery_status_cb_t battery_status; /*!< For ESP_BLE_MESH_MODEL_OP_GEN_BATTERY_STATUS */
    esp_ble_mesh_gen_loc_global_status_cb_t location_global_status; /*!< For ESP_BLE_MESH_MODEL_OP_GEN_LOC_GLOBAL_STATUS */
    esp_ble_mesh_gen_loc_local_status_cb_t location_local_status; /*!< ESP_BLE_MESH_MODEL_OP_GEN_LOC_LOCAL_STATUS */
    esp_ble_mesh_gen_user_properties_status_cb_t user_properties_status; /*!< ESP_BLE_MESH_MODEL_OP_GEN_USER_PROPERTIES_STATUS */
    esp_ble_mesh_gen_user_property_status_cb_t user_property_status; /*!< ESP_BLE_MESH_MODEL_OP_GEN_USER_PROPERTY_STATUS */
    esp_ble_mesh_gen_admin_properties_status_cb_t admin_properties_status; /*!< ESP_BLE_MESH_MODEL_OP_GEN_ADMIN_PROPERTIES_STATUS */
    esp_ble_mesh_gen_admin_property_status_cb_t admin_property_status; /*!< ESP_BLE_MESH_MODEL_OP_GEN_ADMIN_PROPERTY_STATUS */
    esp_ble_mesh_gen_manufacturer_properties_status_cb_t manufacturer_properties_status; /*!< ESP_BLE_MESH_MODEL_OP_GEN_MANUFACTURER_PROPERTIES_STATUS */
    esp_ble_mesh_gen_manufacturer_property_status_cb_t manufacturer_property_status; /*!< ESP_BLE_MESH_MODEL_OP_GEN_MANUFACTURER_PROPERTY_STATUS */
    esp_ble_mesh_gen_client_properties_status_cb_t client_properties_status; /*!< ESP_BLE_MESH_MODEL_OP_GEN_CLIENT_PROPERTIES_STATUS */
    } esp_ble_mesh_gen_client_status_cb_t;

    /** Generic Client Model callback parameters */
    typedef struct {
    int error_code; /*!< Appropriate error code */
    esp_ble_mesh_client_common_param_t *params; /*!< The client common parameters. */
    esp_ble_mesh_gen_client_status_cb_t status_cb; /*!< The generic status message callback values */
    } esp_ble_mesh_generic_client_cb_param_t;

    /** This enum value is the event of Generic Client Model */
    typedef enum {
    ESP_BLE_MESH_GENERIC_CLIENT_GET_STATE_EVT,
    ESP_BLE_MESH_GENERIC_CLIENT_SET_STATE_EVT,
    ESP_BLE_MESH_GENERIC_CLIENT_PUBLISH_EVT,
    ESP_BLE_MESH_GENERIC_CLIENT_TIMEOUT_EVT,
    ESP_BLE_MESH_GENERIC_CLIENT_EVT_MAX,
    } esp_ble_mesh_generic_client_cb_event_t;

    /**
    * @brief Bluetooth Mesh Generic Client Model function.
    */

    /**
    * @brief Generic Client Model callback function type
    * @param event: Event type
    * @param param: Pointer to callback parameter
    */
    typedef void (* esp_ble_mesh_generic_client_cb_t)(esp_ble_mesh_generic_client_cb_event_t event,
    esp_ble_mesh_generic_client_cb_param_t *param);

    /**
    * @brief Register BLE Mesh Generic Client Model callback.
    *
    * @param[in] callback: Pointer to the callback function.
    *
    * @return ESP_OK on success or error code otherwise.
    *
    */
    esp_err_t esp_ble_mesh_register_generic_client_callback(esp_ble_mesh_generic_client_cb_t callback);

    /**
    * @brief Get the value of Generic Server Model states using the Generic Client Model get messages.
    *
    * @note If you want to find the opcodes and corresponding meanings accepted by this API,
    * please refer to esp_ble_mesh_generic_message_opcode_t in esp_ble_mesh_defs.h
    *
    * @param[in] params: Pointer to BLE Mesh common client parameters.
    * @param[in] get_state: Pointer to generic get message value.
    * Shall not be set to NULL.
    *
    * @return ESP_OK on success or error code otherwise.
    *
    */
    esp_err_t esp_ble_mesh_generic_client_get_state(esp_ble_mesh_client_common_param_t *params,
    esp_ble_mesh_generic_client_get_state_t *get_state);

    /**
    * @brief Set the value of Generic Server Model states using the Generic Client Model set messages.
    *
    * @note If you want to find the opcodes and corresponding meanings accepted by this API,
    * please refer to esp_ble_mesh_generic_message_opcode_t in esp_ble_mesh_defs.h
    *
    * @param[in] params: Pointer to BLE Mesh common client parameters.
    * @param[in] set_state: Pointer to generic set message value.
    * Shall not be set to NULL.
    *
    * @return ESP_OK on success or error code otherwise.
    *
    */
    esp_err_t esp_ble_mesh_generic_client_set_state(esp_ble_mesh_client_common_param_t *params,
    esp_ble_mesh_generic_client_set_state_t *set_state);

    /**
    * @brief Generic Server Models related context.
    */

    /** @def ESP_BLE_MESH_MODEL_GEN_ONOFF_SRV
    *
    * @brief Define a new Generic OnOff Server Model.
    *
    * @note 1. The Generic OnOff Server Model is a root model.
    * 2. This model shall support model publication and model subscription.
    *
    * @param srv_pub Pointer to the unique struct esp_ble_mesh_model_pub_t.
    * @param srv_data Pointer to the unique struct esp_ble_mesh_gen_onoff_srv_t.
    *
    * @return New Generic OnOff Server Model instance.
    */
    #define ESP_BLE_MESH_MODEL_GEN_ONOFF_SRV(srv_pub, srv_data) \
    ESP_BLE_MESH_SIG_MODEL(ESP_BLE_MESH_MODEL_ID_GEN_ONOFF_SRV, \
    NULL, srv_pub, srv_data)

    /** @def ESP_BLE_MESH_MODEL_GEN_LEVEL_SRV
    *
    * @brief Define a new Generic Level Server Model.
    *
    * @note 1. The Generic Level Server Model is a root model.
    * 2. This model shall support model publication and model subscription.
    *
    * @param srv_pub Pointer to the unique struct esp_ble_mesh_model_pub_t.
    * @param srv_data Pointer to the unique struct esp_ble_mesh_gen_level_srv_t.
    *
    * @return New Generic Level Server Model instance.
    */
    #define ESP_BLE_MESH_MODEL_GEN_LEVEL_SRV(srv_pub, srv_data) \
    ESP_BLE_MESH_SIG_MODEL(ESP_BLE_MESH_MODEL_ID_GEN_LEVEL_SRV, \
    NULL, srv_pub, srv_data)

    /** @def ESP_BLE_MESH_MODEL_GEN_DEF_TRANS_TIME_SRV
    *
    * @brief Define a new Generic Default Transition Time Server Model.
    *
    * @note 1. The Generic Default Transition Time Server Model is a root model.
    * 2. This model shall support model publication and model subscription.
    *
    * @param srv_pub Pointer to the unique struct esp_ble_mesh_model_pub_t.
    * @param srv_data Pointer to the unique struct esp_ble_mesh_gen_def_trans_time_srv_t.
    *
    * @return New Generic Default Transition Time Server Model instance.
    */
    #define ESP_BLE_MESH_MODEL_GEN_DEF_TRANS_TIME_SRV(srv_pub, srv_data) \
    ESP_BLE_MESH_SIG_MODEL(ESP_BLE_MESH_MODEL_ID_GEN_DEF_TRANS_TIME_SRV, \
    NULL, srv_pub, srv_data)

    /** @def ESP_BLE_MESH_MODEL_GEN_POWER_ONOFF_SRV
    *
    * @brief Define a new Generic Power OnOff Server Model.
    *
    * @note 1. The Generic Power OnOff Server model extends the Generic OnOff Server
    * model. When this model is present on an element, the corresponding
    * Generic Power OnOff Setup Server model shall also be present.
    * 2. This model may be used to represent a variety of devices that do not
    * fit any of the model descriptions that have been defined but support
    * the generic properties of On/Off.
    * 3. This model shall support model publication and model subscription.
    *
    * @param srv_pub Pointer to the unique struct esp_ble_mesh_model_pub_t.
    * @param srv_data Pointer to the unique struct esp_ble_mesh_gen_power_onoff_srv_t.
    *
    * @return New Generic Power OnOff Server Model instance.
    */
    #define ESP_BLE_MESH_MODEL_GEN_POWER_ONOFF_SRV(srv_pub, srv_data) \
    ESP_BLE_MESH_SIG_MODEL(ESP_BLE_MESH_MODEL_ID_GEN_POWER_ONOFF_SRV, \
    NULL, srv_pub, srv_data)

    /** @def ESP_BLE_MESH_MODEL_GEN_POWER_ONOFF_SETUP_SRV
    *
    * @brief Define a new Generic Power OnOff Setup Server Model.
    *
    * @note 1. The Generic Power OnOff Setup Server model extends the Generic Power
    * OnOff Server model and the Generic Default Transition Time Server model.
    * 2. This model shall support model subscription.
    *
    * @param srv_pub Pointer to the unique struct esp_ble_mesh_model_pub_t.
    * @param srv_data Pointer to the unique struct esp_ble_mesh_gen_power_onoff_setup_srv_t.
    *
    * @return New Generic Power OnOff Setup Server Model instance.
    */
    #define ESP_BLE_MESH_MODEL_GEN_POWER_ONOFF_SETUP_SRV(srv_pub, srv_data) \
    ESP_BLE_MESH_SIG_MODEL(ESP_BLE_MESH_MODEL_ID_GEN_POWER_ONOFF_SETUP_SRV, \
    NULL, srv_pub, srv_data)

    /** @def ESP_BLE_MESH_MODEL_GEN_POWER_LEVEL_SRV
    *
    * @brief Define a new Generic Power Level Server Model.
    *
    * @note 1. The Generic Power Level Server model extends the Generic Power OnOff
    * Server model and the Generic Level Server model. When this model is
    * present on an Element, the corresponding Generic Power Level Setup
    * Server model shall also be present.
    * 2. This model shall support model publication and model subscription.
    *
    * @param srv_pub Pointer to the unique struct esp_ble_mesh_model_pub_t.
    * @param srv_data Pointer to the unique struct esp_ble_mesh_gen_power_level_srv_t.
    *
    * @return New Generic Power Level Server Model instance.
    */
    #define ESP_BLE_MESH_MODEL_GEN_POWER_LEVEL_SRV(srv_pub, srv_data) \
    ESP_BLE_MESH_SIG_MODEL(ESP_BLE_MESH_MODEL_ID_GEN_POWER_LEVEL_SRV, \
    NULL, srv_pub, srv_data)

    /** @def ESP_BLE_MESH_MODEL_GEN_POWER_LEVEL_SETUP_SRV
    *
    * @brief Define a new Generic Power Level Setup Server Model.
    *
    * @note 1. The Generic Power Level Setup Server model extends the Generic Power
    * Level Server model and the Generic Power OnOff Setup Server model.
    * 2. This model shall support model subscription.
    *
    * @param srv_pub Pointer to the unique struct esp_ble_mesh_model_pub_t.
    * @param srv_data Pointer to the unique struct esp_ble_mesh_gen_power_level_setup_srv_t.
    *
    * @return New Generic Power Level Setup Server Model instance.
    */
    #define ESP_BLE_MESH_MODEL_GEN_POWER_LEVEL_SETUP_SRV(srv_pub, srv_data) \
    ESP_BLE_MESH_SIG_MODEL(ESP_BLE_MESH_MODEL_ID_GEN_POWER_LEVEL_SETUP_SRV, \
    NULL, srv_pub, srv_data)

    /** @def ESP_BLE_MESH_MODEL_GEN_BATTERY_SRV
    *
    * @brief Define a new Generic Battery Server Model.
    *
    * @note 1. The Generic Battery Server Model is a root model.
    * 2. This model shall support model publication and model subscription.
    * 3. The model may be used to represent an element that is powered by a battery.
    *
    * @param srv_pub Pointer to the unique struct esp_ble_mesh_model_pub_t.
    * @param srv_data Pointer to the unique struct esp_ble_mesh_gen_battery_srv_t.
    *
    * @return New Generic Battery Server Model instance.
    */
    #define ESP_BLE_MESH_MODEL_GEN_BATTERY_SRV(srv_pub, srv_data) \
    ESP_BLE_MESH_SIG_MODEL(ESP_BLE_MESH_MODEL_ID_GEN_BATTERY_SRV, \
    NULL, srv_pub, srv_data)

    /** @def ESP_BLE_MESH_MODEL_GEN_LOCATION_SRV
    *
    * @brief Define a new Generic Location Server Model.
    *
    * @note 1. The Generic Location Server model is a root model. When this model
    * is present on an Element, the corresponding Generic Location Setup
    * Server model shall also be present.
    * 2. This model shall support model publication and model subscription.
    * 3. The model may be used to represent an element that knows its
    * location (global or local).
    *
    * @param srv_pub Pointer to the unique struct esp_ble_mesh_model_pub_t.
    * @param srv_data Pointer to the unique struct esp_ble_mesh_gen_location_srv_t.
    *
    * @return New Generic Location Server Model instance.
    */
    #define ESP_BLE_MESH_MODEL_GEN_LOCATION_SRV(srv_pub, srv_data) \
    ESP_BLE_MESH_SIG_MODEL(ESP_BLE_MESH_MODEL_ID_GEN_LOCATION_SRV, \
    NULL, srv_pub, srv_data)

    /** @def ESP_BLE_MESH_MODEL_GEN_LOCATION_SETUP_SRV
    *
    * @brief Define a new Generic Location Setup Server Model.
    *
    * @note 1. The Generic Location Setup Server model extends the Generic Location
    * Server model.
    * 2. This model shall support model subscription.
    *
    * @param srv_pub Pointer to the unique struct esp_ble_mesh_model_pub_t.
    * @param srv_data Pointer to the unique struct esp_ble_mesh_gen_location_setup_srv_t.
    *
    * @return New Generic Location Setup Server Model instance.
    */
    #define ESP_BLE_MESH_MODEL_GEN_LOCATION_SETUP_SRV(srv_pub, srv_data) \
    ESP_BLE_MESH_SIG_MODEL(ESP_BLE_MESH_MODEL_ID_GEN_LOCATION_SETUP_SRV, \
    NULL, srv_pub, srv_data)

    /** @def ESP_BLE_MESH_MODEL_GEN_USER_PROP_SRV
    *
    * @brief Define a new Generic User Property Server Model.
    *
    * @note 1. The Generic User Property Server model is a root model.
    * 2. This model shall support model publication and model subscription.
    *
    * @param srv_pub Pointer to the unique struct esp_ble_mesh_model_pub_t.
    * @param srv_data Pointer to the unique struct esp_ble_mesh_gen_user_prop_srv_t.
    *
    * @return New Generic User Property Server Model instance.
    */
    #define ESP_BLE_MESH_MODEL_GEN_USER_PROP_SRV(srv_pub, srv_data) \
    ESP_BLE_MESH_SIG_MODEL(ESP_BLE_MESH_MODEL_ID_GEN_USER_PROP_SRV, \
    NULL, srv_pub, srv_data)

    /** @def ESP_BLE_MESH_MODEL_GEN_ADMIN_PROP_SRV
    *
    * @brief Define a new Generic Admin Property Server Model.
    *
    * @note 1. The Generic Admin Property Server model extends the Generic User
    * Property Server model.
    * 2. This model shall support model publication and model subscription.
    *
    * @param srv_pub Pointer to the unique struct esp_ble_mesh_model_pub_t.
    * @param srv_data Pointer to the unique struct esp_ble_mesh_gen_admin_prop_srv_t.
    *
    * @return New Generic Admin Property Server Model instance.
    */
    #define ESP_BLE_MESH_MODEL_GEN_ADMIN_PROP_SRV(srv_pub, srv_data) \
    ESP_BLE_MESH_SIG_MODEL(ESP_BLE_MESH_MODEL_ID_GEN_ADMIN_PROP_SRV, \
    NULL, srv_pub, srv_data)

    /** @def ESP_BLE_MESH_MODEL_GEN_MANUFACTURER_PROP_SRV
    *
    * @brief Define a new Generic Manufacturer Property Server Model.
    *
    * @note 1. The Generic Manufacturer Property Server model extends the Generic
    * User Property Server model.
    * 2. This model shall support model publication and model subscription.
    *
    * @param srv_pub Pointer to the unique struct esp_ble_mesh_model_pub_t.
    * @param srv_data Pointer to the unique struct esp_ble_mesh_gen_manu_prop_srv_t.
    *
    * @return New Generic Manufacturer Property Server Model instance.
    */
    #define ESP_BLE_MESH_MODEL_GEN_MANUFACTURER_PROP_SRV(srv_pub, srv_data) \
    ESP_BLE_MESH_SIG_MODEL(ESP_BLE_MESH_MODEL_ID_GEN_MANUFACTURER_PROP_SRV, \
    NULL, srv_pub, srv_data)

    /** @def ESP_BLE_MESH_MODEL_GEN_CLIENT_PROP_SRV
    *
    * @brief Define a new Generic User Property Server Model.
    *
    * @note 1. The Generic Client Property Server model is a root model.
    * 2. This model shall support model publication and model subscription.
    *
    * @param srv_pub Pointer to the unique struct esp_ble_mesh_model_pub_t.
    * @param srv_data Pointer to the unique struct esp_ble_mesh_gen_client_prop_srv_t.
    *
    * @return New Generic Client Property Server Model instance.
    */
    #define ESP_BLE_MESH_MODEL_GEN_CLIENT_PROP_SRV(srv_pub, srv_data) \
    ESP_BLE_MESH_SIG_MODEL(ESP_BLE_MESH_MODEL_ID_GEN_CLIENT_PROP_SRV, \
    NULL, srv_pub, srv_data)

    /** Parameters of Generic OnOff state */
    typedef struct {
    uint8_t onoff; /*!< The present value of the Generic OnOff state */
    uint8_t target_onoff; /*!< The target value of the Generic OnOff state */
    } esp_ble_mesh_gen_onoff_state_t;

    /** User data of Generic OnOff Server Model */
    typedef struct {
    esp_ble_mesh_model_t *model; /*!< Pointer to the Generic OnOff Server Model. Initialized internally. */
    esp_ble_mesh_server_rsp_ctrl_t rsp_ctrl; /*!< Response control of the server model received messages */
    esp_ble_mesh_gen_onoff_state_t state; /*!< Parameters of the Generic OnOff state */
    esp_ble_mesh_last_msg_info_t last; /*!< Parameters of the last received set message */
    esp_ble_mesh_state_transition_t transition; /*!< Parameters of state transition */
    } esp_ble_mesh_gen_onoff_srv_t;

    /** Parameters of Generic Level state */
    typedef struct {
    int16_t level; /*!< The present value of the Generic Level state */
    int16_t target_level; /*!< The target value of the Generic Level state */

    /**
    * When a new transaction starts, level should be set to last_last, and use
    * "level + incoming delta" to calculate the target level. In another word,
    * "last_level" is used to record "level" of the last transaction, and
    * "last_delta" is used to record the previously received delta_level value.
    */
    int16_t last_level; /*!< The last value of the Generic Level state */
    int32_t last_delta; /*!< The last delta change of the Generic Level state */

    bool move_start; /*!< Indicate if the transition of the Generic Level state has been started */
    bool positive; /*!< Indicate if the transition is positive or negative */
    } esp_ble_mesh_gen_level_state_t;

    /** User data of Generic Level Server Model */
    typedef struct {
    esp_ble_mesh_model_t *model; /*!< Pointer to the Generic Level Server Model. Initialized internally. */
    esp_ble_mesh_server_rsp_ctrl_t rsp_ctrl; /*!< Response control of the server model received messages */
    esp_ble_mesh_gen_level_state_t state; /*!< Parameters of the Generic Level state */
    esp_ble_mesh_last_msg_info_t last; /*!< Parameters of the last received set message */
    esp_ble_mesh_state_transition_t transition; /*!< Parameters of state transition */
    int32_t tt_delta_level; /*!< Delta change value of level state transition */
    } esp_ble_mesh_gen_level_srv_t;

    /** Parameter of Generic Default Transition Time state */
    typedef struct {
    uint8_t trans_time; /*!< The value of the Generic Default Transition Time state */
    } esp_ble_mesh_gen_def_trans_time_state_t;

    /** User data of Generic Default Transition Time Server Model */
    typedef struct {
    esp_ble_mesh_model_t *model; /*!< Pointer to the Generic Default Transition Time Server Model. Initialized internally. */
    esp_ble_mesh_server_rsp_ctrl_t rsp_ctrl; /*!< Response control of the server model received messages */
    esp_ble_mesh_gen_def_trans_time_state_t state; /*!< Parameters of the Generic Default Transition Time state */
    } esp_ble_mesh_gen_def_trans_time_srv_t;

    /** Parameter of Generic OnPowerUp state */
    typedef struct {
    uint8_t onpowerup; /*!< The value of the Generic OnPowerUp state */
    } esp_ble_mesh_gen_onpowerup_state_t;

    /** User data of Generic Power OnOff Server Model */
    typedef struct {
    esp_ble_mesh_model_t *model; /*!< Pointer to the Generic Power OnOff Server Model. Initialized internally. */
    esp_ble_mesh_server_rsp_ctrl_t rsp_ctrl; /*!< Response control of the server model received messages */
    esp_ble_mesh_gen_onpowerup_state_t *state; /*!< Parameters of the Generic OnPowerUp state */
    } esp_ble_mesh_gen_power_onoff_srv_t;

    /** User data of Generic Power OnOff Setup Server Model */
    typedef struct {
    esp_ble_mesh_model_t *model; /*!< Pointer to the Generic Power OnOff Setup Server Model. Initialized internally. */
    esp_ble_mesh_server_rsp_ctrl_t rsp_ctrl; /*!< Response control of the server model received messages */
    esp_ble_mesh_gen_onpowerup_state_t *state; /*!< Parameters of the Generic OnPowerUp state */
    } esp_ble_mesh_gen_power_onoff_setup_srv_t;

    /** Parameters of Generic Power Level state */
    typedef struct {
    uint16_t power_actual; /*!< The present value of the Generic Power Actual state */
    uint16_t target_power_actual; /*!< The target value of the Generic Power Actual state */

    uint16_t power_last; /*!< The value of the Generic Power Last state */
    uint16_t power_default; /*!< The value of the Generic Power Default state */

    uint8_t status_code; /*!< The status code of setting Generic Power Range state */
    uint16_t power_range_min; /*!< The minimum value of the Generic Power Range state */
    uint16_t power_range_max; /*!< The maximum value of the Generic Power Range state */
    } esp_ble_mesh_gen_power_level_state_t;

    /** User data of Generic Power Level Server Model */
    typedef struct {
    esp_ble_mesh_model_t *model; /*!< Pointer to the Generic Power Level Server Model. Initialized internally. */
    esp_ble_mesh_server_rsp_ctrl_t rsp_ctrl; /*!< Response control of the server model received messages */
    esp_ble_mesh_gen_power_level_state_t *state; /*!< Parameters of the Generic Power Level state */
    esp_ble_mesh_last_msg_info_t last; /*!< Parameters of the last received set message */
    esp_ble_mesh_state_transition_t transition; /*!< Parameters of state transition */
    int32_t tt_delta_level; /*!< Delta change value of level state transition */
    } esp_ble_mesh_gen_power_level_srv_t;

    /** User data of Generic Power Level Setup Server Model */
    typedef struct {
    esp_ble_mesh_model_t *model; /*!< Pointer to the Generic Power Level Setup Server Model. Initialized internally. */
    esp_ble_mesh_server_rsp_ctrl_t rsp_ctrl; /*!< Response control of the server model received messages */
    esp_ble_mesh_gen_power_level_state_t *state; /*!< Parameters of the Generic Power Level state */
    } esp_ble_mesh_gen_power_level_setup_srv_t;

    /** Parameters of Generic Battery state */
    typedef struct {
    uint32_t battery_level : 8, /*!< The value of the Generic Battery Level state */
    time_to_discharge : 24; /*!< The value of the Generic Battery Time to Discharge state */
    uint32_t time_to_charge : 24, /*!< The value of the Generic Battery Time to Charge state */
    battery_flags : 8; /*!< The value of the Generic Battery Flags state */
    } esp_ble_mesh_gen_battery_state_t;

    /** User data of Generic Battery Server Model */
    typedef struct {
    esp_ble_mesh_model_t *model; /*!< Pointer to the Generic Battery Server Model. Initialized internally. */
    esp_ble_mesh_server_rsp_ctrl_t rsp_ctrl; /*!< Response control of the server model received messages */
    esp_ble_mesh_gen_battery_state_t state; /*!< Parameters of the Generic Battery state */
    } esp_ble_mesh_gen_battery_srv_t;

    /** Parameters of Generic Location state */
    typedef struct {
    int32_t global_latitude; /*!< The value of the Global Latitude field */
    int32_t global_longitude; /*!< The value of the Global Longitude field */
    int16_t global_altitude; /*!< The value of the Global Altitude field */
    int16_t local_north; /*!< The value of the Local North field */
    int16_t local_east; /*!< The value of the Local East field */
    int16_t local_altitude; /*!< The value of the Local Altitude field */
    uint8_t floor_number; /*!< The value of the Floor Number field */
    uint16_t uncertainty; /*!< The value of the Uncertainty field */
    } esp_ble_mesh_gen_location_state_t;

    /** User data of Generic Location Server Model */
    typedef struct {
    esp_ble_mesh_model_t *model; /*!< Pointer to the Generic Location Server Model. Initialized internally. */
    esp_ble_mesh_server_rsp_ctrl_t rsp_ctrl; /*!< Response control of the server model received messages */
    esp_ble_mesh_gen_location_state_t *state; /*!< Parameters of the Generic Location state */
    } esp_ble_mesh_gen_location_srv_t;

    /** User data of Generic Location Setup Server Model */
    typedef struct {
    esp_ble_mesh_model_t *model; /*!< Pointer to the Generic Location Setup Server Model. Initialized internally. */
    esp_ble_mesh_server_rsp_ctrl_t rsp_ctrl; /*!< Response control of the server model received messages */
    esp_ble_mesh_gen_location_state_t *state; /*!< Parameters of the Generic Location state */
    } esp_ble_mesh_gen_location_setup_srv_t;

    /** This enum value is the access value of Generic User Property */
    typedef enum {
    ESP_BLE_MESH_GEN_USER_ACCESS_PROHIBIT,
    ESP_BLE_MESH_GEN_USER_ACCESS_READ,
    ESP_BLE_MESH_GEN_USER_ACCESS_WRITE,
    ESP_BLE_MESH_GEN_USER_ACCESS_READ_WRITE,
    } esp_ble_mesh_gen_user_prop_access_t;

    /** This enum value is the access value of Generic Admin Property */
    typedef enum {
    ESP_BLE_MESH_GEN_ADMIN_NOT_USER_PROP,
    ESP_BLE_MESH_GEN_ADMIN_ACCESS_READ,
    ESP_BLE_MESH_GEN_ADMIN_ACCESS_WRITE,
    ESP_BLE_MESH_GEN_ADMIN_ACCESS_READ_WRITE,
    } esp_ble_mesh_gen_admin_prop_access_t;

    /** This enum value is the access value of Generic Manufacturer Property */
    typedef enum {
    ESP_BLE_MESH_GEN_MANU_NOT_USER_PROP,
    ESP_BLE_MESH_GEN_MANU_ACCESS_READ,
    } esp_ble_mesh_gen_manu_prop_access_t;

    /** Parameters of Generic Property states */
    typedef struct {
    uint16_t id; /*!< The value of User/Admin/Manufacturer Property ID */
    uint8_t user_access; /*!< The value of User Access field */
    uint8_t admin_access; /*!< The value of Admin Access field */
    uint8_t manu_access; /*!< The value of Manufacturer Access field */
    struct net_buf_simple *val; /*!< The value of User/Admin/Manufacturer Property */
    } esp_ble_mesh_generic_property_t;

    /** User data of Generic User Property Server Model */
    typedef struct {
    esp_ble_mesh_model_t *model; /*!< Pointer to the Generic User Property Server Model. Initialized internally. */
    esp_ble_mesh_server_rsp_ctrl_t rsp_ctrl; /*!< Response control of the server model received messages */
    uint8_t property_count; /*!< Generic User Property count */
    esp_ble_mesh_generic_property_t *properties; /*!< Parameters of the Generic User Property state */
    } esp_ble_mesh_gen_user_prop_srv_t;

    /** User data of Generic Admin Property Server Model */
    typedef struct {
    esp_ble_mesh_model_t *model; /*!< Pointer to the Generic Admin Property Server Model. Initialized internally. */
    esp_ble_mesh_server_rsp_ctrl_t rsp_ctrl; /*!< Response control of the server model received messages */
    uint8_t property_count; /*!< Generic Admin Property count */
    esp_ble_mesh_generic_property_t *properties; /*!< Parameters of the Generic Admin Property state */
    } esp_ble_mesh_gen_admin_prop_srv_t;

    /** User data of Generic Manufacturer Property Server Model */
    typedef struct {
    esp_ble_mesh_model_t *model; /*!< Pointer to the Generic Manufacturer Property Server Model. Initialized internally. */
    esp_ble_mesh_server_rsp_ctrl_t rsp_ctrl; /*!< Response control of the server model received messages */
    uint8_t property_count; /*!< Generic Manufacturer Property count */
    esp_ble_mesh_generic_property_t *properties; /*!< Parameters of the Generic Manufacturer Property state */
    } esp_ble_mesh_gen_manu_prop_srv_t;

    /** User data of Generic Client Property Server Model */
    typedef struct {
    esp_ble_mesh_model_t *model; /*!< Pointer to the Generic Client Property Server Model. Initialized internally. */
    esp_ble_mesh_server_rsp_ctrl_t rsp_ctrl; /*!< Response control of the server model received messages */
    uint8_t id_count; /*!< Generic Client Property ID count */
    uint16_t *property_ids; /*!< Parameters of the Generic Client Property state */
    } esp_ble_mesh_gen_client_prop_srv_t;

    /** Parameter of Generic OnOff Set state change event */
    typedef struct {
    uint8_t onoff; /*!< The value of Generic OnOff state */
    } esp_ble_mesh_state_change_gen_onoff_set_t;

    /** Parameter of Generic Level Set state change event */
    typedef struct {
    int16_t level; /*!< The value of Generic Level state */
    } esp_ble_mesh_state_change_gen_level_set_t;

    /** Parameter of Generic Delta Set state change event */
    typedef struct {
    int16_t level; /*!< The value of Generic Level state */
    } esp_ble_mesh_state_change_gen_delta_set_t;

    /** Parameter of Generic Move Set state change event */
    typedef struct {
    int16_t level; /*!< The value of Generic Level state */
    } esp_ble_mesh_state_change_gen_move_set_t;

    /** Parameter of Generic Default Transition Time Set state change event */
    typedef struct {
    uint8_t trans_time; /*!< The value of Generic Default Transition Time state */
    } esp_ble_mesh_state_change_gen_def_trans_time_set_t;

    /** Parameter of Generic OnPowerUp Set state change event */
    typedef struct {
    uint8_t onpowerup; /*!< The value of Generic OnPowerUp state */
    } esp_ble_mesh_state_change_gen_onpowerup_set_t;

    /** Parameter of Generic Power Level Set state change event */
    typedef struct {
    uint16_t power; /*!< The value of Generic Power Actual state */
    } esp_ble_mesh_state_change_gen_power_level_set_t;

    /** Parameter of Generic Power Default Set state change event */
    typedef struct {
    uint16_t power; /*!< The value of Generic Power Default state */
    } esp_ble_mesh_state_change_gen_power_default_set_t;

    /** Parameters of Generic Power Range Set state change event */
    typedef struct {
    uint16_t range_min; /*!< The minimum value of Generic Power Range state */
    uint16_t range_max; /*!< The maximum value of Generic Power Range state */
    } esp_ble_mesh_state_change_gen_power_range_set_t;

    /** Parameters of Generic Location Global Set state change event */
    typedef struct {
    int32_t latitude; /*!< The Global Latitude value of Generic Location state */
    int32_t longitude; /*!< The Global Longitude value of Generic Location state */
    int16_t altitude; /*!< The Global Altitude value of Generic Location state */
    } esp_ble_mesh_state_change_gen_loc_global_set_t;

    /** Parameters of Generic Location Local Set state change event */
    typedef struct {
    int16_t north; /*!< The Local North value of Generic Location state */
    int16_t east; /*!< The Local East value of Generic Location state */
    int16_t altitude; /*!< The Local Altitude value of Generic Location state */
    uint8_t floor_number; /*!< The Floor Number value of Generic Location state */
    uint16_t uncertainty; /*!< The Uncertainty value of Generic Location state */
    } esp_ble_mesh_state_change_gen_loc_local_set_t;

    /** Parameters of Generic User Property Set state change event */
    typedef struct {
    uint16_t id; /*!< The property id of Generic User Property state */
    struct net_buf_simple *value; /*!< The property value of Generic User Property state */
    } esp_ble_mesh_state_change_gen_user_property_set_t;

    /** Parameters of Generic Admin Property Set state change event */
    typedef struct {
    uint16_t id; /*!< The property id of Generic Admin Property state */
    uint8_t access; /*!< The property access of Generic Admin Property state */
    struct net_buf_simple *value; /*!< The property value of Generic Admin Property state */
    } esp_ble_mesh_state_change_gen_admin_property_set_t;

    /** Parameters of Generic Manufacturer Property Set state change event */
    typedef struct {
    uint16_t id; /*!< The property id of Generic Manufacturer Property state */
    uint8_t access; /*!< The property value of Generic Manufacturer Property state */
    } esp_ble_mesh_state_change_gen_manu_property_set_t;

    /**
    * @brief Generic Server Model state change value union
    */
    typedef union {
    /**
    * The recv_op in ctx can be used to decide which state is changed.
    */
    esp_ble_mesh_state_change_gen_onoff_set_t onoff_set; /*!< Generic OnOff Set */
    esp_ble_mesh_state_change_gen_level_set_t level_set; /*!< Generic Level Set */
    esp_ble_mesh_state_change_gen_delta_set_t delta_set; /*!< Generic Delta Set */
    esp_ble_mesh_state_change_gen_move_set_t move_set; /*!< Generic Move Set */
    esp_ble_mesh_state_change_gen_def_trans_time_set_t def_trans_time_set; /*!< Generic Default Transition Time Set */
    esp_ble_mesh_state_change_gen_onpowerup_set_t onpowerup_set; /*!< Generic OnPowerUp Set */
    esp_ble_mesh_state_change_gen_power_level_set_t power_level_set; /*!< Generic Power Level Set */
    esp_ble_mesh_state_change_gen_power_default_set_t power_default_set; /*!< Generic Power Default Set */
    esp_ble_mesh_state_change_gen_power_range_set_t power_range_set; /*!< Generic Power Range Set */
    esp_ble_mesh_state_change_gen_loc_global_set_t loc_global_set; /*!< Generic Location Global Set */
    esp_ble_mesh_state_change_gen_loc_local_set_t loc_local_set; /*!< Generic Location Local Set */
    esp_ble_mesh_state_change_gen_user_property_set_t user_property_set; /*!< Generic User Property Set */
    esp_ble_mesh_state_change_gen_admin_property_set_t admin_property_set; /*!< Generic Admin Property Set */
    esp_ble_mesh_state_change_gen_manu_property_set_t manu_property_set; /*!< Generic Manufacturer Property Set */
    } esp_ble_mesh_generic_server_state_change_t;

    /** Context of the received Generic User Property Get message */
    typedef struct {
    uint16_t property_id; /*!< Property ID identifying a Generic User Property */
    } esp_ble_mesh_server_recv_gen_user_property_get_t;

    /** Context of the received Generic Admin Property Get message */
    typedef struct {
    uint16_t property_id; /*!< Property ID identifying a Generic Admin Property */
    } esp_ble_mesh_server_recv_gen_admin_property_get_t;

    /** Context of the received Generic Manufacturer Property message */
    typedef struct {
    uint16_t property_id; /*!< Property ID identifying a Generic Manufacturer Property */
    } esp_ble_mesh_server_recv_gen_manufacturer_property_get_t;

    /** Context of the received Generic Client Properties Get message */
    typedef struct {
    uint16_t property_id; /*!< A starting Client Property ID present within an element */
    } esp_ble_mesh_server_recv_gen_client_properties_get_t;

    /**
    * @brief Generic Server Model received get message union
    */
    typedef union {
    esp_ble_mesh_server_recv_gen_user_property_get_t user_property; /*!< Generic User Property Get */
    esp_ble_mesh_server_recv_gen_admin_property_get_t admin_property; /*!< Generic Admin Property Get */
    esp_ble_mesh_server_recv_gen_manufacturer_property_get_t manu_property; /*!< Generic Manufacturer Property Get */
    esp_ble_mesh_server_recv_gen_client_properties_get_t client_properties; /*!< Generic Client Properties Get */
    } esp_ble_mesh_generic_server_recv_get_msg_t;

    /** Context of the received Generic OnOff Set message */
    typedef struct {
    bool op_en; /*!< Indicate if optional parameters are included */
    uint8_t onoff; /*!< Target value of Generic OnOff state */
    uint8_t tid; /*!< Transaction ID */
    uint8_t trans_time; /*!< Time to complete state transition (optional) */
    uint8_t delay; /*!< Indicate message execution delay (C.1) */
    } esp_ble_mesh_server_recv_gen_onoff_set_t;

    /** Context of the received Generic Level Set message */
    typedef struct {
    bool op_en; /*!< Indicate if optional parameters are included */
    int16_t level; /*!< Target value of Generic Level state */
    uint8_t tid; /*!< Transaction ID */
    uint8_t trans_time; /*!< Time to complete state transition (optional) */
    uint8_t delay; /*!< Indicate message execution delay (C.1) */
    } esp_ble_mesh_server_recv_gen_level_set_t;

    /** Context of the received Generic Delta Set message */
    typedef struct {
    bool op_en; /*!< Indicate if optional parameters are included */
    int32_t delta_level; /*!< Delta change of Generic Level state */
    uint8_t tid; /*!< Transaction ID */
    uint8_t trans_time; /*!< Time to complete state transition (optional) */
    uint8_t delay; /*!< Indicate message execution delay (C.1) */
    } esp_ble_mesh_server_recv_gen_delta_set_t;

    /** Context of the received Generic Move Set message */
    typedef struct {
    bool op_en; /*!< Indicate if optional parameters are included */
    int16_t delta_level; /*!< Delta Level step to calculate Move speed for Generic Level state */
    uint8_t tid; /*!< Transaction ID */
    uint8_t trans_time; /*!< Time to complete state transition (optional) */
    uint8_t delay; /*!< Indicate message execution delay (C.1) */
    } esp_ble_mesh_server_recv_gen_move_set_t;

    /** Context of the received Generic Default Transition Time Set message */
    typedef struct {
    uint8_t trans_time; /*!< The value of the Generic Default Transition Time state */
    } esp_ble_mesh_server_recv_gen_def_trans_time_set_t;

    /** Context of the received Generic OnPowerUp Set message */
    typedef struct {
    uint8_t onpowerup; /*!< The value of the Generic OnPowerUp state */
    } esp_ble_mesh_server_recv_gen_onpowerup_set_t;

    /** Context of the received Generic Power Level Set message */
    typedef struct {
    bool op_en; /*!< Indicate if optional parameters are included */
    uint16_t power; /*!< Target value of Generic Power Actual state */
    uint8_t tid; /*!< Transaction ID */
    uint8_t trans_time; /*!< Time to complete state transition (optional) */
    uint8_t delay; /*!< Indicate message execution delay (C.1) */
    } esp_ble_mesh_server_recv_gen_power_level_set_t;

    /** Context of the received Generic Power Default Set message */
    typedef struct {
    uint16_t power; /*!< The value of the Generic Power Default state */
    } esp_ble_mesh_server_recv_gen_power_default_set_t;

    /** Context of the received Generic Power Range Set message */
    typedef struct {
    uint16_t range_min; /*!< Value of Range Min field of Generic Power Range state */
    uint16_t range_max; /*!< Value of Range Max field of Generic Power Range state */
    } esp_ble_mesh_server_recv_gen_power_range_set_t;

    /** Context of the received Generic Location Global Set message */
    typedef struct {
    int32_t global_latitude; /*!< Global Coordinates (Latitude) */
    int32_t global_longitude; /*!< Global Coordinates (Longitude) */
    int16_t global_altitude; /*!< Global Altitude */
    } esp_ble_mesh_server_recv_gen_loc_global_set_t;

    /** Context of the received Generic Location Local Set message */
    typedef struct {
    int16_t local_north; /*!< Local Coordinates (North) */
    int16_t local_east; /*!< Local Coordinates (East) */
    int16_t local_altitude; /*!< Local Altitude */
    uint8_t floor_number; /*!< Floor Number */
    uint16_t uncertainty; /*!< Uncertainty */
    } esp_ble_mesh_server_recv_gen_loc_local_set_t;

    /** Context of the received Generic User Property Set message */
    typedef struct {
    uint16_t property_id; /*!< Property ID identifying a Generic User Property */
    struct net_buf_simple *property_value; /*!< Raw value for the User Property */
    } esp_ble_mesh_server_recv_gen_user_property_set_t;

    /** Context of the received Generic Admin Property Set message */
    typedef struct {
    uint16_t property_id; /*!< Property ID identifying a Generic Admin Property */
    uint8_t user_access; /*!< Enumeration indicating user access */
    struct net_buf_simple *property_value; /*!< Raw value for the Admin Property */
    } esp_ble_mesh_server_recv_gen_admin_property_set_t;

    /** Context of the received Generic Manufacturer Property Set message */
    typedef struct {
    uint16_t property_id; /*!< Property ID identifying a Generic Manufacturer Property */
    uint8_t user_access; /*!< Enumeration indicating user access */
    } esp_ble_mesh_server_recv_gen_manufacturer_property_set_t;

    /**
    * @brief Generic Server Model received set message union
    */
    typedef union {
    esp_ble_mesh_server_recv_gen_onoff_set_t onoff; /*!< Generic OnOff Set/Generic OnOff Set Unack */
    esp_ble_mesh_server_recv_gen_level_set_t level; /*!< Generic Level Set/Generic Level Set Unack */
    esp_ble_mesh_server_recv_gen_delta_set_t delta; /*!< Generic Delta Set/Generic Delta Set Unack */
    esp_ble_mesh_server_recv_gen_move_set_t move; /*!< Generic Move Set/Generic Move Set Unack */
    esp_ble_mesh_server_recv_gen_def_trans_time_set_t def_trans_time; /*!< Generic Default Transition Time Set/Generic Default Transition Time Set Unack */
    esp_ble_mesh_server_recv_gen_onpowerup_set_t onpowerup; /*!< Generic OnPowerUp Set/Generic OnPowerUp Set Unack */
    esp_ble_mesh_server_recv_gen_power_level_set_t power_level; /*!< Generic Power Level Set/Generic Power Level Set Unack */
    esp_ble_mesh_server_recv_gen_power_default_set_t power_default; /*!< Generic Power Default Set/Generic Power Default Set Unack */
    esp_ble_mesh_server_recv_gen_power_range_set_t power_range; /*!< Generic Power Range Set/Generic Power Range Set Unack */
    esp_ble_mesh_server_recv_gen_loc_global_set_t location_global; /*!< Generic Location Global Set/Generic Location Global Set Unack */
    esp_ble_mesh_server_recv_gen_loc_local_set_t location_local; /*!< Generic Location Local Set/Generic Location Local Set Unack */
    esp_ble_mesh_server_recv_gen_user_property_set_t user_property; /*!< Generic User Property Set/Generic User Property Set Unack */
    esp_ble_mesh_server_recv_gen_admin_property_set_t admin_property; /*!< Generic Admin Property Set/Generic Admin Property Set Unack */
    esp_ble_mesh_server_recv_gen_manufacturer_property_set_t manu_property; /*!< Generic Manufacturer Property Set/Generic Manufacturer Property Set Unack */
    } esp_ble_mesh_generic_server_recv_set_msg_t;

    /**
    * @brief Generic Server Model callback value union
    */
    typedef union {
    esp_ble_mesh_generic_server_state_change_t state_change; /*!< ESP_BLE_MESH_GENERIC_SERVER_STATE_CHANGE_EVT */
    esp_ble_mesh_generic_server_recv_get_msg_t get; /*!< ESP_BLE_MESH_GENERIC_SERVER_RECV_GET_MSG_EVT */
    esp_ble_mesh_generic_server_recv_set_msg_t set; /*!< ESP_BLE_MESH_GENERIC_SERVER_RECV_SET_MSG_EVT */
    } esp_ble_mesh_generic_server_cb_value_t;

    /** Generic Server Model callback parameters */
    typedef struct {
    esp_ble_mesh_model_t *model; /*!< Pointer to Generic Server Models */
    esp_ble_mesh_msg_ctx_t ctx; /*!< Context of the received messages */
    esp_ble_mesh_generic_server_cb_value_t value; /*!< Value of the received Generic Messages */
    } esp_ble_mesh_generic_server_cb_param_t;

    /** This enum value is the event of Generic Server Model */
    typedef enum {
    /**
    * 1. When get_auto_rsp is set to ESP_BLE_MESH_SERVER_AUTO_RSP, no event will be
    * callback to the application layer when Generic Get messages are received.
    * 2. When set_auto_rsp is set to ESP_BLE_MESH_SERVER_AUTO_RSP, this event will
    * be callback to the application layer when Generic Set/Set Unack messages
    * are received.
    */
    ESP_BLE_MESH_GENERIC_SERVER_STATE_CHANGE_EVT,
    /**
    * When get_auto_rsp is set to ESP_BLE_MESH_SERVER_RSP_BY_APP, this event will be
    * callback to the application layer when Generic Get messages are received.
    */
    ESP_BLE_MESH_GENERIC_SERVER_RECV_GET_MSG_EVT,
    /**
    * When set_auto_rsp is set to ESP_BLE_MESH_SERVER_RSP_BY_APP, this event will be
    * callback to the application layer when Generic Set/Set Unack messages are received.
    */
    ESP_BLE_MESH_GENERIC_SERVER_RECV_SET_MSG_EVT,
    ESP_BLE_MESH_GENERIC_SERVER_EVT_MAX,
    } esp_ble_mesh_generic_server_cb_event_t;

    /**
    * @brief Bluetooth Mesh Generic Server Model function.
    */

    /**
    * @brief Generic Server Model callback function type
    * @param event: Event type
    * @param param: Pointer to callback parameter
    */
    typedef void (* esp_ble_mesh_generic_server_cb_t)(esp_ble_mesh_generic_server_cb_event_t event,
    esp_ble_mesh_generic_server_cb_param_t *param);

    /**
    * @brief Register BLE Mesh Generic Server Model callback.
    *
    * @param[in] callback: Pointer to the callback function.
    *
    * @return ESP_OK on success or error code otherwise.
    *
    */
    esp_err_t esp_ble_mesh_register_generic_server_callback(esp_ble_mesh_generic_server_cb_t callback);

    #ifdef __cplusplus
    }
    #endif

    #endif /* _ESP_BLE_MESH_GENERIC_MODEL_API_H_ */