410 lines
21 KiB
Markdown
410 lines
21 KiB
Markdown
|
# 1. Introduction
|
|||
|
## 1.1 Demo Function
|
|||
|
|
|||
|
This demo is used for fast provisioning networks. It takes no more than 60 seconds to provisioning 100 devices in this demo.
|
|||
|
|
|||
|
This demo must be used with the EspBleMesh app. For details about how to use the EspBleMesh app, please click [here](EspBleMesh.md).
|
|||
|
|
|||
|
## 1.2 Node Composition
|
|||
|
|
|||
|
This demo has only one element, where the following five Models are implemented:
|
|||
|
|
|||
|
- The **Configuration Server** Model is used to represent a mesh network configuration of a device.
|
|||
|
- The **Configuration Client** Model is used to represent an element that can control and monitor the configuration of a node.
|
|||
|
- The **Generic OnOff Server** Model implements the node's Onoff state.
|
|||
|
- The **Vendor Server** Model implements the node's `fast_prov_server` state.
|
|||
|
- The **Vendor Client** Model is used to control the `fast_prov_server` state, which defines the fast provisioning behavior of a node.
|
|||
|
|
|||
|
|
|||
|
## 2. Code Analysis
|
|||
|
|
|||
|
Code initialization part reference [Initializing the Bluetooth and Initializing the BLE Mesh](../../../ble_mesh_wifi_coexist/tutorial%20%20%20%20%20%20/ble_mesh_wifi_coexist.md)
|
|||
|
|
|||
|
### 2.1 Data Structure
|
|||
|
|
|||
|
This section introduces the `example_fast_prov_server_t` strut for this demo, and its variables in groups.
|
|||
|
|
|||
|
```
|
|||
|
typedef struct {
|
|||
|
esp_ble_mesh_model_t *model; /* Fast Prov Server Model pointer */
|
|||
|
ATOMIC_DEFINE(srv_flags, SRV_MAX_FLAGS);
|
|||
|
|
|||
|
bool primary_role; /* Indicate if the device is a Primary Provisioner */
|
|||
|
uint8_t max_node_num; /* The maximum number of devices can be provisioned by the Provisioner */
|
|||
|
uint8_t prov_node_cnt; /* Number of self-provisioned nodes */
|
|||
|
uint16_t app_idx; /* AppKey index of the application key added by other Provisioner */
|
|||
|
uint16_t top_address; /* Address of the device(e.g. phone) which triggers fast provisioning */
|
|||
|
|
|||
|
esp_ble_mesh_msg_ctx_t ctx; /* the context stored for sending fast prov status message */
|
|||
|
struct fast_prov_info_set *set_info; /* Used to store received fast prov info set context */
|
|||
|
|
|||
|
uint16_t node_addr_cnt; /* Number of node address shall be received */
|
|||
|
uint16_t unicast_min; /* Minimum unicast address can be send to other nodes */
|
|||
|
uint16_t unicast_max; /* Maximum unicast address can be send to other nodes */
|
|||
|
uint16_t unicast_cur; /* Current unicast address can be assigned */
|
|||
|
uint16_t unicast_step; /* Unicast address change step */
|
|||
|
uint8_t flags; /* Flags state */
|
|||
|
uint32_t iv_index; /* Iv_index state */
|
|||
|
uint16_t net_idx; /* Netkey index state */
|
|||
|
uint16_t group_addr; /* Subscribed group address */
|
|||
|
uint16_t prim_prov_addr; /* Unicast address of Primary Provisioner */
|
|||
|
uint8_t match_val[16]; /* Match value to be compared with unprovisioned device UUID */
|
|||
|
uint8_t match_len; /* Length of match value to be compared */
|
|||
|
|
|||
|
uint8_t pend_act; /* Pending action to be performed */
|
|||
|
uint8_t state; /* Fast prov state -> 0: idle, 1: pend, 2: active */
|
|||
|
|
|||
|
struct k_delayed_work disable_fast_prov_timer; /* Used to disable fast provisioning */
|
|||
|
struct k_delayed_work gatt_proxy_enable_timer; /* Used to Mesh GATT Proxy functionality */
|
|||
|
} __attribute__((packed)) example_fast_prov_server_t;
|
|||
|
```
|
|||
|
|
|||
|
|
|||
|
#### 2.1.1 Provisioner Role and State
|
|||
|
|
|||
|
Different provisioners have different behaviors and it’s helpful to understand the concepts of different roles so you can better understand the codes.
|
|||
|
|
|||
|
In the struct, there are three variables that are related to roles and states, which are described in the following table:
|
|||
|
|
|||
|
| Variable Name |Description |
|
|||
|
| ---------------------|------------------------- |
|
|||
|
| `primary_role` | Provisioner identity |
|
|||
|
| `state` | Fast provisioner state (0: idle, 1: pend, 2: active) |
|
|||
|
| `srv_flags` | Flags (`DISABLE_FAST_PROV_START`,`GATT_PROXY_ENABLE_START`,`RELAY_PROXY_DISABLED`,`SRV_MAX_FLAGS`) |
|
|||
|
|
|||
|
Among which, there are four roles in this demo (`primary_role`):
|
|||
|
|
|||
|
* Phone - Top Provisioner
|
|||
|
* The device that has been provisioned by Phone - Primary Provisioner
|
|||
|
* Devices that have been provisioned and changed to the role of a provisioner - Temporary Provisioner
|
|||
|
* Devices that have been provisioned but not changed to the role of a provisioner - Node
|
|||
|
|
|||
|
|
|||
|
#### 2.1.2 Provisioner Address Management
|
|||
|
|
|||
|
The provisioner address management is used to assign a unicast address to each node, so as to prevent address conflicts by allocating address in an equally manner. Each provisioner has its own address range and a maximum number of the nodes it can provisioned. The provisioner will allocate a subset of its address range to the nodes it has provisioned.
|
|||
|
|
|||
|
Example: A top provisioner's address range is 0 to 100 and the maximum number of nodes it can provisioned is 5. The provisioner address management will assign subsets of address range to these 5 nodes, which are 1 to 20, 21 to 40, 41 to 60, 61 to 80 and 81 to 100.
|
|||
|
|
|||
|
The variables that are related to the address management are described in the following table:
|
|||
|
|
|||
|
| Variable Name |Description |
|
|||
|
| ----------------------|------------------------- |
|
|||
|
| `unicast_min` | Minimum unicast address can be allocated to other nodes |
|
|||
|
| `unicast_max` | Maximum unicast address can be allocated to other nodes |
|
|||
|
| `unicast_cur` | Current unicast address |
|
|||
|
| `unicast_step` | Unicast address change step Offset|
|
|||
|
|
|||
|
#### 2.1.3 Provisioner Cache Data
|
|||
|
|
|||
|
The cache data is required, so a node can change its role to become a provisioner. During this process, the `esp_ble_mesh_set_fast_prov_info` and `esp_ble_mesh_set_fast_prov_action` APIs are called.
|
|||
|
|
|||
|
The node's cache data, which are described in the following table, is sent by the provisioner.
|
|||
|
|
|||
|
| Variable Name |Description |
|
|||
|
| ----------------------|------------------------- |
|
|||
|
| `flags` |Flags state|
|
|||
|
| `iv_index` |Iv_index state|
|
|||
|
| `net_idx` |Netkey index state |
|
|||
|
| `group_addr` |Subscribed group address |
|
|||
|
| `prim_prov_addr` |Unicast address of Primary Provisioner |
|
|||
|
| `match_val[16]` |Match value to be compared with unprovisioned device UUID |
|
|||
|
| `match_len` | Length of match value to be compared |
|
|||
|
| `max_node_num` | The maximum number of devices can be provisioned by the Provisioner |
|
|||
|
| `prov_node_cnt` | Number of self-provisioned nodes |
|
|||
|
| `app_idx` | AppKey index of the application key added by other Provisioner |
|
|||
|
| `top_address` | Address of the device(e.g. phone) which triggers fast provisioning |
|
|||
|
|
|||
|
|
|||
|
#### 2.1.4 Provisioner Timer
|
|||
|
|
|||
|
There are two timers in this demo, which are:
|
|||
|
|
|||
|
1. `gatt_proxy_enable_timer` is used to enable Mesh GATT Proxy functionality.
|
|||
|
* The timer starts or resets and starts when a Temporary Provisioner provisions an unprovisioned device.
|
|||
|
* The Temporary Provisioner will send a message (Address information) to the Primary Provisioner.
|
|||
|
2. `disable_fast_prov_timer` is used to disable the provisioning capabilities.
|
|||
|
* The node starts the timer when it receives a **Generic OnOff Get/Set/Set Unack** message sent by the EspBleMesh app. The group address should be used if you want to disable the provisioning capabilities of all nodes.
|
|||
|
|
|||
|
The variables that are related to these two timers are described below:
|
|||
|
|
|||
|
| Variable Name |Description |
|
|||
|
| ----------------------|------------------------- |
|
|||
|
| `disable_fast_prov_timer` |Used to disable fast provisioning|
|
|||
|
| `gatt_proxy_enable_timer` |Used to enable Mesh GATT Proxy functionality|
|
|||
|
|
|||
|
### 2.2 Model Definition
|
|||
|
|
|||
|
#### 2.2.1 Vendor Server Model
|
|||
|
|
|||
|
The **Vendor Server** Model implements the node's `fast_prov_server` state, which has been covered in the previous section.
|
|||
|
|
|||
|
```c
|
|||
|
example_fast_prov_server_t fast_prov_server = {
|
|||
|
.primary_role = false,
|
|||
|
.max_node_num = 6,
|
|||
|
.prov_node_cnt = 0x0,
|
|||
|
.unicast_min = ESP_BLE_MESH_ADDR_UNASSIGNED,
|
|||
|
.unicast_max = ESP_BLE_MESH_ADDR_UNASSIGNED,
|
|||
|
.unicast_cur = ESP_BLE_MESH_ADDR_UNASSIGNED,
|
|||
|
.unicast_step = 0x0,
|
|||
|
.flags = 0x0,
|
|||
|
.iv_index = 0x0,
|
|||
|
.net_idx = ESP_BLE_MESH_KEY_UNUSED,
|
|||
|
.app_idx = ESP_BLE_MESH_KEY_UNUSED,
|
|||
|
.group_addr = ESP_BLE_MESH_ADDR_UNASSIGNED,
|
|||
|
.prim_prov_addr = ESP_BLE_MESH_ADDR_UNASSIGNED,
|
|||
|
.match_len = 0x0,
|
|||
|
.pend_act = FAST_PROV_ACT_NONE,
|
|||
|
.state = STATE_IDLE,
|
|||
|
};
|
|||
|
```
|
|||
|
|
|||
|
The `fast_prov_srv_op` is used to register the minimum length of messages. For example, the minimum length of the `ESP_BLE_MESH_VND_MODEL_OP_FAST_PROV_INFO_SET` message is registered as 3 octets.
|
|||
|
|
|||
|
```c
|
|||
|
static esp_ble_mesh_model_op_t fast_prov_srv_op[] = {
|
|||
|
{ ESP_BLE_MESH_VND_MODEL_OP_FAST_PROV_INFO_SET, 3, NULL },
|
|||
|
{ ESP_BLE_MESH_VND_MODEL_OP_FAST_PROV_NET_KEY_ADD, 16, NULL },
|
|||
|
{ ESP_BLE_MESH_VND_MODEL_OP_FAST_PROV_NODE_ADDR, 2, NULL },
|
|||
|
{ ESP_BLE_MESH_VND_MODEL_OP_FAST_PROV_NODE_ADDR_GET, 0, NULL },
|
|||
|
ESP_BLE_MESH_MODEL_OP_END,
|
|||
|
};
|
|||
|
|
|||
|
```
|
|||
|
The `example_fast_prov_server_init` function is used to register the callback function triggered when the timers timeout, and initializes the Model-related variables in the data struct.
|
|||
|
|
|||
|
```c
|
|||
|
err = example_fast_prov_server_init(&vnd_models[0]);
|
|||
|
if (err != ESP_OK) {
|
|||
|
ESP_LOGE(TAG, "%s: Failed to initialize fast prov server model", __func__);
|
|||
|
return err;
|
|||
|
}
|
|||
|
```
|
|||
|
|
|||
|
The `fast_prov_server` struct represents the Vendor server's states. The `CID_ESP` and `ESP_BLE_MESH_VND_MODEL_ID_FAST_PROV_SRV` constants, which consist of the vendor server Model's Model id `ESP_BLE_MESH_VND_MODEL_ID_FAST_PROV_SRV`, are used to identity the Vendor server Model.
|
|||
|
|
|||
|
|
|||
|
```c
|
|||
|
static esp_ble_mesh_model_t vnd_models[] = {
|
|||
|
ESP_BLE_MESH_VENDOR_MODEL(CID_ESP, ESP_BLE_MESH_VND_MODEL_ID_FAST_PROV_SRV,
|
|||
|
fast_prov_srv_op, NULL, &fast_prov_server),
|
|||
|
};
|
|||
|
static esp_ble_mesh_elem_t elements[] = {
|
|||
|
ESP_BLE_MESH_ELEMENT(0, root_models, vnd_models),
|
|||
|
};
|
|||
|
```
|
|||
|
|
|||
|
|
|||
|
#### 2.2.2 Vendor Client Model
|
|||
|
|
|||
|
The **Vendor Client** Model is used to control the `fast_prov_server` state, which defines the fast provisioning behavior of a node.
|
|||
|
|
|||
|
The `fast_prov_cli_op_pair` struct is used to register the corresponding message acknowledgements.
|
|||
|
|
|||
|
```c
|
|||
|
static const esp_ble_mesh_client_op_pair_t fast_prov_cli_op_pair[] = {
|
|||
|
{ ESP_BLE_MESH_VND_MODEL_OP_FAST_PROV_INFO_SET, ESP_BLE_MESH_VND_MODEL_OP_FAST_PROV_INFO_STATUS },
|
|||
|
{ ESP_BLE_MESH_VND_MODEL_OP_FAST_PROV_NET_KEY_ADD, ESP_BLE_MESH_VND_MODEL_OP_FAST_PROV_NET_KEY_STATUS },
|
|||
|
{ ESP_BLE_MESH_VND_MODEL_OP_FAST_PROV_NODE_ADDR, ESP_BLE_MESH_VND_MODEL_OP_FAST_PROV_NODE_ADDR_ACK },
|
|||
|
{ ESP_BLE_MESH_VND_MODEL_OP_FAST_PROV_NODE_ADDR_GET, ESP_BLE_MESH_VND_MODEL_OP_FAST_PROV_NODE_ADDR_STATUS },
|
|||
|
};
|
|||
|
```
|
|||
|
|
|||
|
Example: The **Vendor Client** Model sends message with an opcode of `ESP_BLE_MESH_VND_MODEL_OP_FAST_PROV_INFO_SET`, which requires the **Vendor Server** Model to respond with a message with an opcode of `ESP_BLE_MESH_VND_MODEL_OP_FAST_PROV_INFO_STATUS`. After that, the **Vendor Client** Model times out if it receives no corresponding acknowledgement.
|
|||
|
|
|||
|
```c
|
|||
|
static const esp_ble_mesh_client_op_pair_t fast_prov_cli_op_pair[] = {
|
|||
|
{ ESP_BLE_MESH_VND_MODEL_OP_FAST_PROV_INFO_SET, ESP_BLE_MESH_VND_MODEL_OP_FAST_PROV_INFO_STATUS },
|
|||
|
};
|
|||
|
```
|
|||
|
Note that you can also use the code below if you don't want the **Vendor Client** Model to wait for acknowledgement from the server Model, which means the client Model will never time out.
|
|||
|
|
|||
|
```c
|
|||
|
static const esp_ble_mesh_client_op_pair_t fast_prov_cli_op_pair[] = {
|
|||
|
{ ESP_BLE_MESH_VND_MODEL_OP_FAST_PROV_INFO_SET, NULL },
|
|||
|
};
|
|||
|
```
|
|||
|
|
|||
|
The `esp_ble_mesh_client_model_init` API is used to register the callback function triggered when the timers timeout, and initializes the Model-related variables in the data struct.
|
|||
|
|
|||
|
```c
|
|||
|
err = esp_ble_mesh_client_model_init(&vnd_models[1]);
|
|||
|
if (err != ESP_OK) {
|
|||
|
ESP_LOGE(TAG, "%s: Failed to initialize fast prov client Model", __func__);
|
|||
|
return err;
|
|||
|
}
|
|||
|
```
|
|||
|
|
|||
|
The `CID_ESP` and `ESP_BLE_MESH_VND_MODEL_ID_FAST_PROV_CLI` constants, which consist of the vendor client Model's Model id `ESP_BLE_MESH_VND_MODEL_ID_FAST_PROV_CLI`, are used to identity the Vendor client Model.
|
|||
|
|
|||
|
```c
|
|||
|
|
|||
|
esp_ble_mesh_client_t fast_prov_client = {
|
|||
|
.op_pair_size = ARRAY_SIZE(fast_prov_cli_op_pair),
|
|||
|
.op_pair = fast_prov_cli_op_pair,
|
|||
|
};
|
|||
|
|
|||
|
static esp_ble_mesh_model_op_t fast_prov_cli_op[] = {
|
|||
|
{ ESP_BLE_MESH_VND_MODEL_OP_FAST_PROV_INFO_STATUS, 1, NULL },
|
|||
|
{ ESP_BLE_MESH_VND_MODEL_OP_FAST_PROV_NET_KEY_STATUS, 2, NULL },
|
|||
|
{ ESP_BLE_MESH_VND_MODEL_OP_FAST_PROV_NODE_ADDR_ACK, 0, NULL },
|
|||
|
ESP_BLE_MESH_MODEL_OP_END,
|
|||
|
};
|
|||
|
|
|||
|
static esp_ble_mesh_model_t vnd_models[] = {
|
|||
|
ESP_BLE_MESH_VENDOR_MODEL(CID_ESP, ESP_BLE_MESH_VND_MODEL_ID_FAST_PROV_CLI,
|
|||
|
fast_prov_cli_op, NULL, &fast_prov_client),
|
|||
|
};
|
|||
|
static esp_ble_mesh_elem_t elements[] = {
|
|||
|
ESP_BLE_MESH_ELEMENT(0, root_models, vnd_models),
|
|||
|
};
|
|||
|
|
|||
|
```
|
|||
|
|
|||
|
## 2.3 Message Opcode
|
|||
|
|
|||
|
"Opcode-send" represents the message that the client sends to the server.
|
|||
|
|
|||
|
"Opcode-ack" represents the message that the server sends to the client.
|
|||
|
|
|||
|
* INFO_SET
|
|||
|
|
|||
|
|Meaning | Opcode-send | Opcode-ack |
|
|||
|
| -----| ------------- | -------------|
|
|||
|
|Opcode| `ESP_BLE_MESH_VND_MODEL_OP_FAST_PROV_INFO_SET` | `ESP_BLE_MESH_VND_MODEL_OP_FAST_PROV_INFO_STATUS` |
|
|||
|
|Function| This message contains all the information as a Provisioner |Checks each field of the Provisioner information and set the corresponding flag bit. The returned status is variable.|
|
|||
|
|Parameter|structfast_prov_info_set|status_bit_mask, status_ctx_flag, status_unicast, status_net_idx, status_group, status_pri_prov, status_match, status_action|
|
|||
|
|
|||
|
|
|||
|
* NODE_ADDR
|
|||
|
|
|||
|
|Meaning | Opcode-send | Opcode-ack |
|
|||
|
| -----| ------------- | -------------|
|
|||
|
|Opcode| `ESP_BLE_MESH_VND_MODEL_OP_FAST_PROV_NODE_ADDR` | `ESP_BLE_MESH_VND_MODEL_OP_FAST_PROV_NODE_ADDR_ACK` |
|
|||
|
|Function| Temporary Provisioner reports the address of the node it has provisioned. |Used to check if the message was sent successfully. |
|
|||
|
|Parameter| Address array |NA |
|
|||
|
|
|||
|
* ADDR_GET
|
|||
|
|
|||
|
|Meaning | Opcode-send | Opcode-ack |
|
|||
|
| -----| ------------- | -------------|
|
|||
|
|Opcode| `ESP_BLE_MESH_VND_MODEL_OP_FAST_PROV_NODE_ADDR_GET` | `ESP_BLE_MESH_VND_MODEL_OP_FAST_PROV_NODE_ADDR_STATUS` |
|
|||
|
|Function|Top Provisioner gets the address of all nodes obtained from Primary Provisioner. | Returns the address of all nodes, but does not contain its own. |
|
|||
|
|Parameter|NA |Address array |
|
|||
|
|
|||
|
* NET_KEY_ADD
|
|||
|
|
|||
|
|Meaning | Opcode-send | Opcode-ack |
|
|||
|
| -----| ------------- | -------------|
|
|||
|
|Opcode | `ESP_BLE_MESH_VND_MODEL_OP_FAST_PROV_NET_KEY_ADD` | `ESP_BLE_MESH_VND_MODEL_OP_FAST_PROV_NET_KEY_STATUS` |
|
|||
|
|Function| Reserved for later use | Reserved for later use |
|
|||
|
|Parameter| NA | NA |
|
|||
|
|
|||
|
|
|||
|
### 2.4 Callback Function
|
|||
|
#### 2.4.1 The Callback function for the Vendor Server Model
|
|||
|
|
|||
|
```c
|
|||
|
esp_ble_mesh_register_custom_model_callback(example_ble_mesh_custom_model_cb);
|
|||
|
esp_ble_mesh_register_prov_callback(example_ble_mesh_provisioning_cb);
|
|||
|
```
|
|||
|
|
|||
|
1. The callback function will be triggered when the **Vendor Server** Model:
|
|||
|
* Receives a message that indicates the Onoff state of the client Model; or
|
|||
|
* Calls any APIs that send messages.
|
|||
|
|
|||
|
2. The events that this callback function handle:
|
|||
|
|
|||
|
* Generic Onoff Server Model
|
|||
|
|
|||
|
| Event Name | Opcode |Description |
|
|||
|
| ------------- | ------------|------------------------------------------- |
|
|||
|
| ESP_BLE_MESH_MODEL_OPERATION_EVT|ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_SET | This event is triggered when the **Generic Onoff Server** model receives the `ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_SET` message |
|
|||
|
| ESP_BLE_MESH_MODEL_OPERATION_EVT|ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_SET_UNACK| This event is triggered when the **Generic Onoff Server** model receives the `ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_SET_UNACK` message. |
|
|||
|
|
|||
|
* Vendor Server Model
|
|||
|
|
|||
|
| Event Name | Opcode |Description |
|
|||
|
| ------------- | ------------|------------------------------------------- |
|
|||
|
| ESP_BLE_MESH_MODEL_OPERATION_EVT | ESP_BLE_MESH_VND_MODEL_OP_FAST_PROV_INFO_SET | This event is triggered when the **Vendor Server** model receives the `ESP_BLE_MESH_VND_MODEL_OP_FAST_PROV_INFO_SET` message.|
|
|||
|
| ESP_BLE_MESH_MODEL_OPERATION_EVT | ESP_BLE_MESH_VND_MODEL_OP_FAST_PROV_NODE_ADDR | This event is triggered when the **Vendor Server** model receives the `ESP_BLE_MESH_VND_MODEL_OP_FAST_PROV_NODE_ADDR` message.|
|
|||
|
| ESP_BLE_MESH_MODEL_OPERATION_EVT | ESP_BLE_MESH_VND_MODEL_OP_FAST_PROV_NODE_ADDR_GET | This event is triggered when the **Vendor Server** model receives the `ESP_BLE_MESH_VND_MODEL_OP_FAST_PROV_NODE_ADDR_GET` message.|
|
|||
|
|
|||
|
* The **Configuration Client** Model
|
|||
|
|
|||
|
| Event Name | Opcode |Description |
|
|||
|
| ------------- | ------------|------------------------------------------- |
|
|||
|
|ESP_BLE_MESH_SET_FAST_PROV_INFO_COMP_EVT| NA| This event is triggered when the `esp_ble_mesh_set_fast_prov_info` API is called. |
|
|||
|
|ESP_BLE_MESH_SET_FAST_PROV_ACTION_COMP_EVT| NA| This event is triggered when the `esp_ble_mesh_set_fast_prov_action` API is called. |
|
|||
|
|ESP_BLE_MESH_CFG_CLIENT_SET_STATE_EVT|ESP_BLE_MESH_MODEL_OP_APP_KEY_ADD|This event is triggered when the **Configuration Server** model receives and further triggers an API calling to send `ESP_BLE_MESH_VND_MODEL_OP_FAST_PROV_INFO_SET` message. |
|
|||
|
|ESP_BLE_MESH_CFG_CLIENT_TIMEOUT_EVT|ESP_BLE_MESH_MODEL_OP_APP_KEY_ADD|This event is triggered when the API `example_send_config_appkey_add` times out.|
|
|||
|
|
|||
|
#### 2.4.2 The Vendor Client Model
|
|||
|
|
|||
|
```c
|
|||
|
esp_ble_mesh_register_custom_model_callback(example_ble_mesh_custom_model_cb);
|
|||
|
```
|
|||
|
|
|||
|
1. The callback function will be triggered when the **Vendor Client** model:
|
|||
|
* Receives any message sent by the vendor server Model; or
|
|||
|
* Calls any APIs that send messages.
|
|||
|
|
|||
|
2. The events that this callback function handle:
|
|||
|
|
|||
|
| Event Name | Opcode |Description |
|
|||
|
| ------------- | ------------|------------------------------------------- |
|
|||
|
| ESP_BLE_MESH_MODEL_OPERATION_EVT | ESP_BLE_MESH_VND_MODEL_OP_FAST_PROV_INFO_STATUS | This event is triggered when the **Vendor Client** model receives the `ESP_BLE_MESH_VND_MODEL_OP_FAST_PROV_INFO_STATUS` message.|
|
|||
|
| ESP_BLE_MESH_MODEL_OPERATION_EVT | ESP_BLE_MESH_VND_MODEL_OP_FAST_PROV_NET_KEY_STATUS | This event is triggered when the **Vendor Client** model receives the `ESP_BLE_MESH_VND_MODEL_OP_FAST_PROV_NET_KEY_STATUS` message.|
|
|||
|
| ESP_BLE_MESH_MODEL_OPERATION_EVT | ESP_BLE_MESH_VND_MODEL_OP_FAST_PROV_NODE_ADDR_ACK | This event is triggered when the **Vendor Client** model receives the `ESP_BLE_MESH_VND_MODEL_OP_FAST_PROV_NODE_ADDR_ACK` message |
|
|||
|
| ESP_BLE_MESH_CLIENT_MODEL_SEND_TIMEOUT_EVT | client_send_timeout.opcode | This event is triggered when the API `esp_ble_mesh_client_model_send_msg` times out.|
|
|||
|
|
|||
|
### 2.5 Message Sending
|
|||
|
#### 2.5.1 The Vendor Client sends messages
|
|||
|
|
|||
|
The Vendor Client Model calls the `esp_ble_mesh_client_model_send_msg` API to send messages to the Vendor Server Model.
|
|||
|
|
|||
|
| Parameter Name |Description |
|
|||
|
| ----------------------|------------------------- |
|
|||
|
| `model` | The pointer to the client Model struct |
|
|||
|
| `ctx.net_idx` | The NetKey Index of the subnet through which the message is sent |
|
|||
|
| `ctx.app_idx` | The AppKey Index for the message encryption |
|
|||
|
| `ctx.addr` | The address of the destination nodes |
|
|||
|
| `ctx.send_ttl`| The TTL State, which determines how many times a message can be relayed|
|
|||
|
| `ctx.send_rel`| This parameter determines whether the Model will wait for an acknowledgment after sending a message |
|
|||
|
| `opcode` | The message opcode |
|
|||
|
| `msg->len` | The length of the `msg->data`|
|
|||
|
| `msg->data` | The pointer to sent data|
|
|||
|
| `msg_timeout` | The maximum duration (4000 ms by default) that the Model waits for an acknowledgment. |
|
|||
|
|`true` | True: an acknowledgement is required; False: no acknowledgement is required |
|
|||
|
| `msg_role` | The role of a message (node/provisioner) |
|
|||
|
|
|||
|
```c
|
|||
|
esp_ble_mesh_msg_ctx_t ctx = {
|
|||
|
.net_idx = info->net_idx,
|
|||
|
.app_idx = info->app_idx,
|
|||
|
.addr = info->dst,
|
|||
|
.send_rel = false,
|
|||
|
.send_ttl = 0,
|
|||
|
};
|
|||
|
err = esp_ble_mesh_client_model_send_msg(model, &ctx,
|
|||
|
ESP_BLE_MESH_VND_MODEL_OP_FAST_PROV_INFO_SET,
|
|||
|
msg->len, msg->data, info->timeout, true, info->role);
|
|||
|
```
|
|||
|
|
|||
|
#### 2.5.2 The Vendor Server sends messages
|
|||
|
|
|||
|
The **Vendor Server** Model has to bind its Appkey before calling the `esp_ble_mesh_server_model_send_msg` API to send a message.
|
|||
|
|
|||
|
```c
|
|||
|
esp_ble_mesh_server_model_send_msg(model, ctx, ESP_BLE_MESH_VND_MODEL_OP_FAST_PROV_INFO_STATUS,
|
|||
|
msg->len ,msg->data );
|
|||
|
```
|
|||
|
The **Vendor Server** Model calls the `esp_ble_mesh_model_publish` API to publish messages. Only the Models that have subscribed to this destination address receive the published messages.
|
|||
|
|
|||
|
```c
|
|||
|
esp_err_t esp_ble_mesh_model_publish(esp_ble_mesh_model_t *model, uint32_t opcode,
|
|||
|
uint16_t length, uint8_t *data,
|
|||
|
esp_ble_mesh_dev_role_t device_role);
|
|||
|
```
|