]> granicus.if.org Git - esp-idf/blob
dc96f7907920f08fd8534287dfc7208ac63e065e
[esp-idf] /
1 // Copyright 2017-2019 Espressif Systems (Shanghai) PTE LTD
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #include "soc/soc.h"
16 #include "esp_bt.h"
17 #include "esp_bt_device.h"
18
19 #include "esp_ble_mesh_defs.h"
20 #include "esp_ble_mesh_common_api.h"
21 #include "esp_ble_mesh_provisioning_api.h"
22 #include "esp_ble_mesh_networking_api.h"
23 #include "esp_ble_mesh_config_model_api.h"
24
25 #include "ble_mesh_adapter.h"
26
27 typedef struct {
28     struct arg_str *static_val;
29     struct arg_int *static_val_len;
30     struct arg_int *output_size;
31     struct arg_int *output_actions;
32     struct arg_int *input_size;
33     struct arg_int *input_actions;
34     struct arg_int *prov_start_address;
35     struct arg_end *end;
36 } ble_mesh_prov_t;
37 static ble_mesh_prov_t oob;
38
39 typedef struct {
40     struct arg_int *model_type;
41     struct arg_int *config_index;
42     struct arg_int *pub_config;
43     struct arg_end *end;
44 } ble_mesh_comp_t;
45 static ble_mesh_comp_t component;
46
47 typedef struct {
48     struct arg_int *bearer;
49     struct arg_int *enable;
50     struct arg_end *end;
51 } ble_mesh_bearer_t;
52 static ble_mesh_bearer_t bearer;
53
54 typedef struct {
55     struct arg_str *action_type;
56     struct arg_int *tx_sense_power;
57     struct arg_end *end;
58 } ble_mesh_tx_sense_power;
59 static ble_mesh_tx_sense_power power_set;
60
61 ble_mesh_node_status node_status = {
62     .previous = 0x0,
63     .current = 0x0,
64 };
65
66 SemaphoreHandle_t ble_mesh_node_sema;
67
68 void ble_mesh_register_node_cmd(void);
69 // Register callback function
70 void ble_mesh_prov_cb(esp_ble_mesh_prov_cb_event_t event, esp_ble_mesh_prov_cb_param_t *param);
71 void ble_mesh_model_cb(esp_ble_mesh_model_cb_event_t event, esp_ble_mesh_model_cb_param_t *param);
72
73
74 void ble_mesh_register_mesh_node(void)
75 {
76     ble_mesh_register_node_cmd();
77 }
78
79 int ble_mesh_register_node_cb(void)
80 {
81     ESP_LOGD(TAG, "enter %s\n", __func__);
82     ble_mesh_node_init();
83     esp_ble_mesh_register_prov_callback(ble_mesh_prov_cb);
84     esp_ble_mesh_register_custom_model_callback(ble_mesh_model_cb);
85     ESP_LOGI(TAG, "Node:Reg,OK");
86     ESP_LOGD(TAG, "exit %s\n", __func__);
87     return 0;
88 }
89
90 void ble_mesh_prov_cb(esp_ble_mesh_prov_cb_event_t event, esp_ble_mesh_prov_cb_param_t *param)
91 {
92     ESP_LOGD(TAG, "enter %s, event = %d", __func__, event);
93     switch (event) {
94     case ESP_BLE_MESH_PROV_REGISTER_COMP_EVT:
95         ble_mesh_callback_check_err_code(param->prov_register_comp.err_code, "Provisioning:Register");
96         break;
97     case ESP_BLE_MESH_NODE_PROV_ENABLE_COMP_EVT:
98         ble_mesh_callback_check_err_code(param->node_prov_enable_comp.err_code, "Node:EnBearer");
99         break;
100     case ESP_BLE_MESH_NODE_PROV_DISABLE_COMP_EVT:
101         ble_mesh_callback_check_err_code(param->node_prov_disable_comp.err_code, "Node:DisBearer");
102         break;
103     case ESP_BLE_MESH_NODE_PROV_LINK_OPEN_EVT:
104         ESP_LOGI(TAG, "Node:LinkOpen,OK,%d", param->node_prov_link_open.bearer);
105         break;
106     case ESP_BLE_MESH_NODE_PROV_LINK_CLOSE_EVT:
107         ESP_LOGI(TAG, "Node:LinkClose,OK,%d", param->node_prov_link_close.bearer);
108         break;
109     case ESP_BLE_MESH_NODE_PROV_OUTPUT_NUMBER_EVT:
110         ESP_LOGI(TAG, "Node:OutPut,%d,%d", param->node_prov_output_num.action, param->node_prov_output_num.number);
111         break;
112     case ESP_BLE_MESH_NODE_PROV_OUTPUT_STRING_EVT:
113         ESP_LOGI(TAG, "Node:OutPutStr,%s", param->node_prov_output_str.string);
114         break;
115     case ESP_BLE_MESH_NODE_PROV_INPUT_EVT:
116         ESP_LOGI(TAG, "Node:InPut,%d,%d", param->node_prov_input.action, param->node_prov_input.size);
117         break;
118     case ESP_BLE_MESH_NODE_PROV_COMPLETE_EVT:
119         ESP_LOGI(TAG, "Node:OK,%d,%d", param->node_prov_complete.net_idx, param->node_prov_complete.addr);
120         ble_mesh_set_node_prestore_params(param->node_prov_complete.net_idx, param->node_prov_complete.addr);
121         break;
122     case ESP_BLE_MESH_NODE_PROV_RESET_EVT:
123         ESP_LOGI(TAG, "Node:Reset");
124         break;
125     case ESP_BLE_MESH_NODE_PROV_INPUT_NUMBER_COMP_EVT:
126         ble_mesh_callback_check_err_code(param->node_prov_input_num_comp.err_code, "Node:InputNum");
127         break;
128     case ESP_BLE_MESH_NODE_PROV_INPUT_STRING_COMP_EVT:
129         ble_mesh_callback_check_err_code(param->node_prov_input_str_comp.err_code, "Node:InputStr");
130         break;
131     case ESP_BLE_MESH_NODE_SET_UNPROV_DEV_NAME_COMP_EVT:
132         ble_mesh_callback_check_err_code(param->node_set_unprov_dev_name_comp.err_code, "Node:SetName");
133         break;
134     case ESP_BLE_MESH_NODE_PROXY_IDENTITY_ENABLE_COMP_EVT:
135         ble_mesh_callback_check_err_code(param->node_proxy_identity_enable_comp.err_code, "Node:ProxyIndentity");
136         break;
137     case ESP_BLE_MESH_NODE_PROXY_GATT_ENABLE_COMP_EVT:
138         ble_mesh_callback_check_err_code(param->node_proxy_gatt_enable_comp.err_code, "Node:EnProxyGatt");
139         break;
140     case ESP_BLE_MESH_NODE_PROXY_GATT_DISABLE_COMP_EVT:
141         ble_mesh_callback_check_err_code(param->node_proxy_gatt_disable_comp.err_code, "Node:DisProxyGatt");
142         break;
143 #if (CONFIG_BLE_MESH_PROVISIONER)
144     case ESP_BLE_MESH_PROVISIONER_RECV_UNPROV_ADV_PKT_EVT:
145         ESP_LOGI(TAG, "Provisioner recv unprovisioned device beacon:");
146         ESP_LOG_BUFFER_HEX("Device UUID %s", param->provisioner_recv_unprov_adv_pkt.dev_uuid, 16);
147         ESP_LOG_BUFFER_HEX("Address %s", param->provisioner_recv_unprov_adv_pkt.addr, 6);
148         ESP_LOGI(TAG, "Address type 0x%x, oob_info 0x%04x, adv_type 0x%x, bearer 0x%x",
149             param->provisioner_recv_unprov_adv_pkt.addr_type, param->provisioner_recv_unprov_adv_pkt.oob_info,
150             param->provisioner_recv_unprov_adv_pkt.adv_type, param->provisioner_recv_unprov_adv_pkt.bearer);
151         break;
152     case ESP_BLE_MESH_PROVISIONER_PROV_LINK_OPEN_EVT:
153         ESP_LOGI(TAG, "Provisioner:LinkOpen,OK,%d", param->provisioner_prov_link_open.bearer);
154         break;
155     case ESP_BLE_MESH_PROVISIONER_PROV_LINK_CLOSE_EVT:
156         ESP_LOGI(TAG, "Provisioner:LinkClose,OK,%d,%d",
157                  param->provisioner_prov_link_close.bearer, param->provisioner_prov_link_close.reason);
158         break;
159     case ESP_BLE_MESH_PROVISIONER_ADD_UNPROV_DEV_COMP_EVT:
160         ble_mesh_callback_check_err_code(param->provisioner_add_unprov_dev_comp.err_code, "Provisioner:DevAdd");
161         break;
162     case ESP_BLE_MESH_PROVISIONER_DELETE_DEV_COMP_EVT:
163         ble_mesh_callback_check_err_code(param->provisioner_delete_dev_comp.err_code, "Provisioner:DevDel");
164         break;
165     case ESP_BLE_MESH_PROVISIONER_PROV_COMPLETE_EVT:
166         ESP_LOGI(TAG, "Provisioner:OK,%d,%d", param->provisioner_prov_complete.netkey_idx, param->provisioner_prov_complete.unicast_addr);
167         break;
168     case ESP_BLE_MESH_PROVISIONER_PROV_ENABLE_COMP_EVT:
169         ble_mesh_callback_check_err_code(param->provisioner_prov_enable_comp.err_code, "Provisioner:EnBearer");
170         break;
171     case ESP_BLE_MESH_PROVISIONER_PROV_DISABLE_COMP_EVT:
172         ble_mesh_callback_check_err_code(param->provisioner_prov_disable_comp.err_code, "Provisioner:DisBearer");
173         break;
174     case ESP_BLE_MESH_PROVISIONER_SET_DEV_UUID_MATCH_COMP_EVT:
175         ble_mesh_callback_check_err_code(param->provisioner_set_dev_uuid_match_comp.err_code, "Provisioner:UuidMatch");
176         break;
177     case ESP_BLE_MESH_PROVISIONER_SET_PROV_DATA_INFO_COMP_EVT:
178         ble_mesh_callback_check_err_code(param->provisioner_set_prov_data_info_comp.err_code, "Provisioner:DataInfo");
179         break;
180     case ESP_BLE_MESH_PROVISIONER_SET_NODE_NAME_COMP_EVT:
181         ble_mesh_callback_check_err_code(param->provisioner_set_node_name_comp.err_code, "Provisioner:NodeName");
182         break;
183     case ESP_BLE_MESH_PROVISIONER_ADD_LOCAL_APP_KEY_COMP_EVT:
184         ble_mesh_callback_check_err_code(param->provisioner_add_app_key_comp.err_code, "Provisioner:AppKeyAdd");
185         break;
186     case ESP_BLE_MESH_PROVISIONER_BIND_APP_KEY_TO_MODEL_COMP_EVT:
187         ble_mesh_callback_check_err_code(param->provisioner_bind_app_key_to_model_comp.err_code, "Provisioner:AppKeyBind");
188         break;
189     case ESP_BLE_MESH_PROVISIONER_ADD_LOCAL_NET_KEY_COMP_EVT:
190         ble_mesh_callback_check_err_code(param->provisioner_add_net_key_comp.err_code, "Provisioner:NetKeyAdd");
191         break;
192 #endif
193     default:
194         break;
195     }
196     ESP_LOGD(TAG, "exit %s\n", __func__);
197 }
198
199 void ble_mesh_model_cb(esp_ble_mesh_model_cb_event_t event, esp_ble_mesh_model_cb_param_t *param)
200 {
201     esp_err_t result = ESP_OK;
202     uint8_t status;
203
204     ESP_LOGD(TAG, "enter %s, event=%x\n", __func__, event);
205
206     switch (event) {
207     case ESP_BLE_MESH_MODEL_OPERATION_EVT:
208         if (param->model_operation.model != NULL && param->model_operation.model->op != NULL) {
209             if (param->model_operation.opcode == ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_GET) {
210                 ESP_LOGI(TAG, "Node:GetStatus,OK");
211                 ble_mesh_node_get_state(status);
212                 result = esp_ble_mesh_server_model_send_msg(param->model_operation.model, param->model_operation.ctx, ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_STATUS,
213                          sizeof(status), &status);
214             } else if (param->model_operation.opcode == ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_SET) {
215                 ble_mesh_node_set_state(param->model_operation.msg[0]);
216                 ESP_LOGI(TAG, "Node:SetAck,OK,%d,%d", param->model_operation.msg[0], param->model_operation.ctx->recv_ttl);
217                 result = esp_ble_mesh_server_model_send_msg(param->model_operation.model, param->model_operation.ctx, ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_STATUS,
218                          sizeof(status), param->model_operation.msg);
219             } else if (param->model_operation.opcode == ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_SET_UNACK) {
220                 ble_mesh_node_set_state(param->model_operation.msg[0]);
221                 ESP_LOGI(TAG, "Node:SetUnAck,OK,%d,%d", param->model_operation.msg[0], param->model_operation.ctx->recv_ttl);
222             } else if (param->model_operation.opcode == ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_STATUS) {
223                 ESP_LOGI(TAG, "Node:Status,Success,%d", param->model_operation.length);
224             } else if (param->model_operation.opcode == ESP_BLE_MESH_VND_MODEL_OP_TEST_PERF_SET) {
225                 ESP_LOGI(TAG, "VendorModel:SetAck,OK,%d", param->model_operation.ctx->recv_ttl);
226             } else if (param->model_operation.opcode == ESP_BLE_MESH_VND_MODEL_OP_TEST_PERF_STATUS) {
227                 uint64_t current_time = esp_timer_get_time();
228                 result = ble_mesh_test_performance_client_model_accumulate_time(((uint32_t)(current_time - start_time) / 1000), param->model_operation.msg, param->model_operation.ctx->recv_ttl, param->model_operation.length);
229                 ESP_LOGI(TAG, "VendorModel:Status,OK,%d", param->model_operation.ctx->recv_ttl);
230                 if (ble_mesh_test_perf_send_sema != NULL && result == ESP_OK) {
231                     xSemaphoreGive(ble_mesh_test_perf_send_sema);
232                 }
233             }
234         }
235         break;
236     case ESP_BLE_MESH_MODEL_SEND_COMP_EVT:
237         if (param->model_send_comp.err_code == ESP_OK) {
238             ESP_LOGI(TAG, "Node:ModelSend,OK");
239         } else {
240             ESP_LOGE(TAG, "Node:ModelSend,Fail,%d,0x%X,0x%04X", param->model_send_comp.err_code, param->model_send_comp.model->model_id, param->model_send_comp.model->op->opcode);
241         }
242         break;
243     case ESP_BLE_MESH_MODEL_PUBLISH_COMP_EVT:
244         ESP_LOGI(TAG, "Node:PublishSend,OK,0x%X,%d", param->model_publish_comp.model->model_id, param->model_publish_comp.model->pub->msg->len);
245         break;
246     case ESP_BLE_MESH_CLIENT_MODEL_RECV_PUBLISH_MSG_EVT:
247         ESP_LOGI(TAG, "Node:PublishReceive,OK,0x%04X,%d,%d", param->client_recv_publish_msg.opcode, param->client_recv_publish_msg.length, param->client_recv_publish_msg.msg[1]);
248         uint64_t current_time = esp_timer_get_time();
249         result = ble_mesh_test_performance_client_model_accumulate_time(((uint32_t)(current_time - start_time) / 2000), param->client_recv_publish_msg.msg, param->client_recv_publish_msg.ctx->recv_ttl, param->client_recv_publish_msg.length);
250         if (ble_mesh_test_perf_send_sema != NULL && param->client_recv_publish_msg.msg[2] == VENDOR_MODEL_PERF_OPERATION_TYPE_SET_UNACK && result == ESP_OK) {
251             xSemaphoreGive(ble_mesh_test_perf_send_sema);
252         }
253         break;
254     case ESP_BLE_MESH_MODEL_PUBLISH_UPDATE_EVT:
255         ESP_LOGI(TAG, "Node:PublishUpdate,OK");
256         break;
257     case ESP_BLE_MESH_CLIENT_MODEL_SEND_TIMEOUT_EVT:
258         ESP_LOGI(TAG, "Node:TimeOut, 0x%04X", param->client_send_timeout.opcode);
259         if (ble_mesh_test_perf_send_sema != NULL) {
260             xSemaphoreGive(ble_mesh_test_perf_send_sema);
261         }
262         break;
263     case ESP_BLE_MESH_MODEL_EVT_MAX:
264         ESP_LOGI(TAG, "Node:MaxEvt");
265         break;
266     default:
267         break;
268     }
269
270     ESP_LOGD(TAG, "exit %s\n", __func__);
271 }
272
273 int ble_mesh_power_set(int argc, char **argv)
274 {
275     esp_err_t result = ESP_OK;
276     int nerrors = arg_parse(argc, argv, (void **) &power_set);
277
278     ESP_LOGD(TAG, "enter %s\n", __func__);
279
280     if (nerrors != 0) {
281         arg_print_errors(stderr, power_set.end, argv[0]);
282         return 1;
283     }
284
285     if (strcmp(power_set.action_type->sval[0], "tx") == 0) {
286         result = esp_ble_tx_power_set(ESP_BLE_PWR_TYPE_ADV, power_set.tx_sense_power->ival[0]);
287     } else if (strcmp(power_set.action_type->sval[0], "sense") == 0) {
288         uint32_t *reg = (uint32_t *)(0x6001c07c);
289         int reg_addr = 0x6001c07c;
290         uint32_t flag = 0x00FF0000;
291         uint32_t sense_new = power_set.tx_sense_power->ival[0];
292         uint32_t reg_to_write = ((*reg) &= ~flag) | ((256 - sense_new) << 16);
293         REG_WRITE(reg_addr, reg_to_write);
294
295     }
296
297     if (result == ESP_OK) {
298         ESP_LOGI(TAG, "Node:SetPower,OK\n");
299     }
300
301     ESP_LOGD(TAG, "exit %s\n", __func__);
302     return result;
303 }
304
305 static int ble_mesh_load_oob(int argc, char **argv)
306 {
307     uint8_t *static_val;
308
309     ESP_LOGD(TAG, "enter %s \n", __func__);
310
311     int nerrors = arg_parse(argc, argv, (void **) &oob);
312     if (nerrors != 0) {
313         arg_print_errors(stderr, oob.end, argv[0]);
314         return 1;
315     }
316
317     //parsing prov
318 #if CONFIG_BLE_MESH_NODE
319     prov.uuid = dev_uuid;
320     memcpy(dev_uuid, esp_bt_dev_get_address(), 6);
321     if (oob.static_val->count != 0) {
322         static_val = malloc(oob.static_val_len->ival[0] + 1);
323         if (static_val == NULL) {
324             ESP_LOGE(TAG, "malloc fail,%s,%d\n", __func__, __LINE__);
325         }
326         get_value_string((char *)oob.static_val->sval[0], (char *)static_val);
327         prov.static_val = static_val;
328     }
329
330     arg_int_to_value(oob.static_val_len, prov.static_val_len, "static value length");
331     arg_int_to_value(oob.output_size, prov.output_size, "output size");
332     arg_int_to_value(oob.output_actions, prov.output_actions, "output actions");
333     arg_int_to_value(oob.input_size, prov.input_size, "input size");
334     arg_int_to_value(oob.input_actions, prov.input_actions, "input actions");
335 #endif
336
337 #if CONFIG_BLE_MESH_PROVISIONER
338     if (oob.static_val->count != 0) {
339         static_val = malloc(oob.static_val_len->ival[0] + 1);
340         if (static_val == NULL) {
341             ESP_LOGE(TAG, "malloc fail,%s,%d\n", __func__, __LINE__);
342         }
343         get_value_string((char *)oob.static_val->sval[0], (char *)static_val);
344         prov.prov_static_oob_val = static_val;
345     }
346     arg_int_to_value(oob.prov_start_address, prov.prov_start_address, "provisioner start address");
347     arg_int_to_value(oob.static_val_len, prov.prov_static_oob_len, "provisioner static value length");
348 #endif
349
350     ESP_LOGI(TAG, "OOB:Load,OK\n");
351
352     ESP_LOGD(TAG, "exit %s\n", __func__);
353     return 0;
354 }
355
356
357 int ble_mesh_init(int argc, char **argv)
358 {
359     int err;
360     esp_ble_mesh_comp_t *local_component = NULL;
361
362     int nerrors = arg_parse(argc, argv, (void **) &component);
363     if (nerrors != 0) {
364         arg_print_errors(stderr, component.end, argv[0]);
365         return 1;
366     }
367
368     ESP_LOGD(TAG, "enter %s, module %x\n", __func__, component.model_type->ival[0]);
369     local_component = ble_mesh_get_component(component.model_type->ival[0]);
370
371
372     err = esp_ble_mesh_init(&prov, local_component);
373     if (err) {
374         ESP_LOGE(TAG, "Initializing mesh failed (err %d)\n", err);
375         return err;
376     }
377
378     ESP_LOGD(TAG, "exit %s\n", __func__);
379     return err;
380 }
381
382 int ble_mesh_provisioner_enable_bearer(int argc, char **argv)
383 {
384     esp_err_t  err = 0;
385
386     ESP_LOGD(TAG, "enter %s \n", __func__);
387
388     int nerrors = arg_parse(argc, argv, (void **) &bearer);
389     if (nerrors != 0) {
390         arg_print_errors(stderr, bearer.end, argv[0]);
391         return 1;
392     }
393
394     if (bearer.enable->count != 0) {
395         if (bearer.enable->ival[0]) {
396             err = esp_ble_mesh_provisioner_prov_enable(bearer.bearer->ival[0]);
397         } else {
398             err = esp_ble_mesh_provisioner_prov_disable(bearer.bearer->ival[0]);
399         }
400     } else {
401         return 1;
402     }
403
404     ESP_LOGD(TAG, "exit %s\n", __func__);
405     return err;
406 }
407
408 void ble_mesh_register_node_cmd(void)
409 {
410     const esp_console_cmd_t register_cmd = {
411         .command  = "bmreg",
412         .help = "ble mesh: provisioner/node register callback",
413         .hint = NULL,
414         .func = &ble_mesh_register_node_cb,
415     };
416     ESP_ERROR_CHECK(esp_console_cmd_register(&register_cmd));
417     oob.static_val = arg_str0("s", NULL, "<value>", "Static OOB value");
418     oob.static_val_len = arg_int0("l", NULL, "<length>", "Static OOB value length");
419     oob.output_size = arg_int0("x", NULL, "<size>", "Maximum size of Output OOB");
420     oob.output_actions = arg_int0("o", NULL, "<actions>", "Supported Output OOB Actions");
421     oob.input_size = arg_int0("y", NULL, "<size>", "Maximum size of Input OOB");
422     oob.input_actions = arg_int0("i", NULL, "<actions>", "Supported Input OOB Actions");
423     oob.prov_start_address = arg_int0("p", NULL, "<address>", "start address assigned by provisioner");
424     oob.prov_start_address->ival[0] = 0x0005;
425     oob.end = arg_end(1);
426
427     const esp_console_cmd_t oob_cmd = {
428         .command = "bmoob",
429         .help = "ble mesh: provisioner/node config OOB parameters",
430         .hint = NULL,
431         .func = &ble_mesh_load_oob,
432         .argtable = &oob,
433     };
434     ESP_ERROR_CHECK( esp_console_cmd_register(&oob_cmd) );
435
436     component.model_type = arg_int0("m", NULL, "<model>", "mesh model");
437     component.config_index = arg_int0("c", NULL, "<index>", "mesh model op");
438     component.config_index->ival[0] = 0; // set default value
439     component.pub_config = arg_int0("p", NULL, "<publish>", "publish message buffer");
440     component.end = arg_end(1);
441
442     const esp_console_cmd_t model_cmd = {
443         .command = "bminit",
444         .help = "ble mesh: provisioner/node init",
445         .hint = NULL,
446         .func = &ble_mesh_init,
447         .argtable = &component,
448     };
449     ESP_ERROR_CHECK( esp_console_cmd_register(&model_cmd) );
450
451     bearer.bearer = arg_int0("b", NULL, "<bearer>", "supported bearer");
452     bearer.enable = arg_int0("e", NULL, "<enable/disable>", "bearers node supported");
453     bearer.end = arg_end(1);
454
455     const esp_console_cmd_t bearer_cmd = {
456         .command = "bmpbearer",
457         .help = "ble mesh provisioner: enable/disable different bearers",
458         .hint = NULL,
459         .func = &ble_mesh_provisioner_enable_bearer,
460         .argtable = &bearer,
461     };
462     ESP_ERROR_CHECK(esp_console_cmd_register(&bearer_cmd));
463
464     power_set.tx_sense_power = arg_int0("t", NULL, "<power>", "tx power or sense");
465     power_set.action_type = arg_str1("z", NULL, "<action>", "action type");
466     power_set.end = arg_end(1);
467
468     const esp_console_cmd_t power_set_cmd = {
469         .command = "bmtxpower",
470         .help = "ble mesh: set tx power or sense",
471         .hint = NULL,
472         .func = &ble_mesh_power_set,
473         .argtable = &power_set,
474     };
475     ESP_ERROR_CHECK(esp_console_cmd_register(&power_set_cmd));
476 }