mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
ble mesh: update ble mesh console example (backport v4.1)
This commit is contained in:
parent
bac92d579f
commit
af3c81b68a
@ -5,6 +5,7 @@ set(COMPONENT_SRCS "ble_mesh_adapter.c"
|
||||
"ble_mesh_console_system.c"
|
||||
"ble_mesh_register_node_cmd.c"
|
||||
"ble_mesh_register_server_cmd.c"
|
||||
"ble_mesh_reg_gen_onoff_client_cmd.c"
|
||||
"register_bluetooth.c")
|
||||
|
||||
set(COMPONENT_ADD_INCLUDEDIRS ".")
|
||||
|
@ -29,8 +29,9 @@ esp_ble_mesh_model_t *ble_mesh_get_model(uint16_t model_id)
|
||||
model = &gen_onoff_srv_models[1];
|
||||
break;
|
||||
#if (CONFIG_BLE_MESH_GENERIC_ONOFF_CLI)
|
||||
// as server
|
||||
case ESP_BLE_MESH_MODEL_ID_GEN_ONOFF_CLI:
|
||||
model = &gen_onoff_cli_models[1];
|
||||
model = &gen_onoff_cli_models[2];
|
||||
break;
|
||||
#endif
|
||||
case ESP_BLE_MESH_VND_MODEL_ID_TEST_PERF_CLI:
|
||||
|
@ -13,7 +13,7 @@
|
||||
// limitations under the License.
|
||||
|
||||
#include "ble_mesh_cfg_srv_model.h"
|
||||
|
||||
#include "esp_ble_mesh_generic_model_api.h"
|
||||
uint8_t dev_uuid[16] = {0xdd, 0xdd};
|
||||
|
||||
#if CONFIG_BLE_MESH_NODE
|
||||
@ -40,9 +40,8 @@ esp_ble_mesh_prov_t prov = {
|
||||
};
|
||||
#endif //CONFIG_BLE_MESH_PROVISIONER
|
||||
|
||||
ESP_BLE_MESH_MODEL_PUB_DEFINE(model_pub_config, 2 + 1, ROLE_NODE);
|
||||
|
||||
esp_ble_mesh_model_pub_t vendor_model_pub_config;
|
||||
ESP_BLE_MESH_MODEL_PUB_DEFINE(model_pub_config, 2 + 1, ROLE_NODE);
|
||||
|
||||
// configure server module
|
||||
esp_ble_mesh_cfg_srv_t cfg_srv = {
|
||||
@ -96,16 +95,15 @@ esp_ble_mesh_comp_t config_client_comp = {
|
||||
};
|
||||
|
||||
// configure special module
|
||||
esp_ble_mesh_model_op_t gen_onoff_srv_model_op_config[] = {
|
||||
ESP_BLE_MESH_MODEL_OP(ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_GET, 0),
|
||||
ESP_BLE_MESH_MODEL_OP(ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_SET, 2),
|
||||
ESP_BLE_MESH_MODEL_OP(ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_SET_UNACK, 2),
|
||||
ESP_BLE_MESH_MODEL_OP_END,
|
||||
ESP_BLE_MESH_MODEL_PUB_DEFINE(onoff_pub_0, 2 + 3, ROLE_NODE);
|
||||
static esp_ble_mesh_gen_onoff_srv_t onoff_server = {
|
||||
.rsp_ctrl.get_auto_rsp = ESP_BLE_MESH_SERVER_RSP_BY_APP,
|
||||
.rsp_ctrl.set_auto_rsp = ESP_BLE_MESH_SERVER_RSP_BY_APP,
|
||||
};
|
||||
|
||||
esp_ble_mesh_model_t gen_onoff_srv_models[] = {
|
||||
ESP_BLE_MESH_MODEL_CFG_SRV(&cfg_srv),
|
||||
ESP_BLE_MESH_SIG_MODEL(ESP_BLE_MESH_MODEL_ID_GEN_ONOFF_SRV, gen_onoff_srv_model_op_config, &model_pub_config, NULL),
|
||||
ESP_BLE_MESH_MODEL_GEN_ONOFF_SRV(&onoff_pub_0, &onoff_server),
|
||||
};
|
||||
|
||||
esp_ble_mesh_elem_t gen_onoff_srv_elements[] = {
|
||||
@ -126,6 +124,7 @@ esp_ble_mesh_client_t gen_onoff_cli;
|
||||
esp_ble_mesh_model_t gen_onoff_cli_models[] = {
|
||||
ESP_BLE_MESH_MODEL_CFG_SRV(&cfg_srv),
|
||||
ESP_BLE_MESH_MODEL_CFG_CLI(&cfg_cli),
|
||||
ESP_BLE_MESH_MODEL_GEN_ONOFF_SRV(&onoff_pub_0, &onoff_server),
|
||||
ESP_BLE_MESH_MODEL_GEN_ONOFF_CLI(&model_pub_config, &gen_onoff_cli),
|
||||
};
|
||||
|
||||
|
@ -22,6 +22,11 @@ void ble_mesh_register_mesh_node(void);
|
||||
// Register mesh config server and generic server operation cmd
|
||||
void ble_mesh_register_server(void);
|
||||
|
||||
#if (CONFIG_BLE_MESH_GENERIC_ONOFF_CLI)
|
||||
// Register mesh client operation cmd
|
||||
void ble_mesh_register_gen_onoff_client(void);
|
||||
#endif
|
||||
|
||||
#if (CONFIG_BLE_MESH_CFG_CLI)
|
||||
// Register mesh config client operation cmd
|
||||
void ble_mesh_register_configuration_client_model(void);
|
||||
|
@ -66,10 +66,16 @@ int hexstr_2_bin(const char *hex, uint8_t *buf, uint32_t len)
|
||||
int get_value_string(char *value_in, char *buf)
|
||||
{
|
||||
int result = -1;
|
||||
|
||||
uint8_t loop = 0;
|
||||
uint16_t length = strlen(value_in);
|
||||
for(int i = 0; i<length; i++) {
|
||||
printf("%c", value_in[i]);
|
||||
|
||||
// address string, need sepcial test
|
||||
for (loop = 0; loop < 17 ; loop++) {
|
||||
if (loop % 3 == 2) {
|
||||
if (value_in[loop] == ':') {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (length > 2) {
|
||||
@ -85,7 +91,6 @@ int get_value_string(char *value_in, char *buf)
|
||||
strcpy(buf, value_in);
|
||||
result = 0;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -104,7 +109,6 @@ bool str_2_mac(uint8_t *str, uint8_t *dest)
|
||||
if (src_p[loop] != ':') {
|
||||
return false;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -126,6 +126,8 @@ esp_err_t bluetooth_init(void)
|
||||
return ret;
|
||||
}
|
||||
|
||||
esp_log_level_set("*", ESP_LOG_ERROR);
|
||||
esp_log_level_set("ble_mesh_node_console", ESP_LOG_INFO);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -153,6 +155,9 @@ void app_main(void)
|
||||
register_bluetooth();
|
||||
ble_mesh_register_mesh_node();
|
||||
ble_mesh_register_server();
|
||||
#if (CONFIG_BLE_MESH_GENERIC_ONOFF_CLI)
|
||||
ble_mesh_register_gen_onoff_client();
|
||||
#endif
|
||||
|
||||
/* Prompt to be printed before each line.
|
||||
* This can be customized, made dynamic, etc.
|
||||
@ -213,3 +218,4 @@ void app_main(void)
|
||||
linenoiseFree(line);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,180 @@
|
||||
// Copyright 2017-2019 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "esp_timer.h"
|
||||
#include "ble_mesh_adapter.h"
|
||||
|
||||
#if (CONFIG_BLE_MESH_GENERIC_ONOFF_CLI)
|
||||
typedef struct {
|
||||
struct arg_str *action_type;
|
||||
struct arg_int *op_en;
|
||||
struct arg_int *unicast_address;
|
||||
struct arg_int *onoff_state;
|
||||
struct arg_int *trans_id;
|
||||
struct arg_int *trans_time;
|
||||
struct arg_int *delay;
|
||||
struct arg_int *opcode;
|
||||
struct arg_int *appkey_idx;
|
||||
struct arg_int *role;
|
||||
struct arg_int *net_idx;
|
||||
struct arg_end *end;
|
||||
} ble_mesh_gen_onoff_state_t;
|
||||
ble_mesh_gen_onoff_state_t gen_onoff_state;
|
||||
|
||||
void ble_mesh_register_gen_onoff_client_command(void);
|
||||
void ble_mesh_generic_onoff_client_model_cb(esp_ble_mesh_generic_client_cb_event_t event,
|
||||
esp_ble_mesh_generic_client_cb_param_t *param);
|
||||
|
||||
void ble_mesh_register_gen_onoff_client(void)
|
||||
{
|
||||
ble_mesh_register_gen_onoff_client_command();
|
||||
}
|
||||
|
||||
void ble_mesh_generic_onoff_client_model_cb(esp_ble_mesh_generic_client_cb_event_t event,
|
||||
esp_ble_mesh_generic_client_cb_param_t *param)
|
||||
{
|
||||
uint32_t opcode = param->params->opcode;
|
||||
|
||||
ESP_LOGD(TAG, "enter %s: event is %d, error code is %d, opcode is 0x%x\n",
|
||||
__func__, event, param->error_code, opcode);
|
||||
|
||||
switch (event) {
|
||||
case ESP_BLE_MESH_GENERIC_CLIENT_GET_STATE_EVT: {
|
||||
switch (opcode) {
|
||||
case ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_GET:
|
||||
if (param->error_code == ESP_OK) {
|
||||
ESP_LOGI(TAG, "GenOnOffClient:GetStatus,OK,%d", param->status_cb.onoff_status.present_onoff);
|
||||
} else {
|
||||
ESP_LOGE(TAG, "GenOnOffClient:GetStatus,Fail,%d", param->error_code);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ESP_BLE_MESH_GENERIC_CLIENT_SET_STATE_EVT: {
|
||||
switch (opcode) {
|
||||
case ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_SET:
|
||||
if (param->error_code == ESP_OK) {
|
||||
ESP_LOGI(TAG, "GenOnOffClient:SetStatus,OK,%d", param->status_cb.onoff_status.present_onoff);
|
||||
} else {
|
||||
ESP_LOGE(TAG, "GenOnOffClient:SetStatus,Fail,%d", param->error_code);
|
||||
}
|
||||
break;
|
||||
case ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_SET_UNACK:
|
||||
if (param->error_code == ESP_OK) {
|
||||
ESP_LOGI(TAG, "GenOnOffClient:SetUNACK,OK");
|
||||
} else {
|
||||
ESP_LOGE(TAG, "GenOnOffClient:SetUNACK,Fail,%d", param->error_code);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ESP_BLE_MESH_GENERIC_CLIENT_PUBLISH_EVT: {
|
||||
if (param->error_code == ESP_OK) {
|
||||
ESP_LOGI(TAG, "GenOnOffClient:Publish,OK");
|
||||
} else {
|
||||
ESP_LOGE(TAG, "GenOnOffClient:Publish,Fail,%d", param->error_code);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ESP_BLE_MESH_GENERIC_CLIENT_TIMEOUT_EVT:
|
||||
ESP_LOGE(TAG, "GenOnOffClient:TimeOut,%d", param->error_code);
|
||||
break;
|
||||
case ESP_BLE_MESH_GENERIC_CLIENT_EVT_MAX:
|
||||
ESP_LOGE(TAG, "GenONOFFClient:InvalidEvt,%d", param->error_code);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
ESP_LOGD(TAG, "exit %s \n", __func__);
|
||||
}
|
||||
|
||||
int ble_mesh_generic_onoff_client_model(int argc, char **argv)
|
||||
{
|
||||
int err = ESP_OK;
|
||||
esp_ble_mesh_generic_client_set_state_t gen_client_set;
|
||||
esp_ble_mesh_generic_client_get_state_t gen_client_get;
|
||||
esp_ble_mesh_client_common_param_t onoff_common = {
|
||||
.msg_timeout = 0,
|
||||
.ctx.send_ttl = 7,
|
||||
};
|
||||
|
||||
ESP_LOGD(TAG, "enter %s\n", __func__);
|
||||
|
||||
int nerrors = arg_parse(argc, argv, (void **) &gen_onoff_state);
|
||||
if (nerrors != 0) {
|
||||
arg_print_errors(stderr, gen_onoff_state.end, argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
onoff_common.model = ble_mesh_get_model(ESP_BLE_MESH_MODEL_ID_GEN_ONOFF_CLI);
|
||||
|
||||
arg_int_to_value(gen_onoff_state.appkey_idx, onoff_common.ctx.app_idx, "appkey_index");
|
||||
arg_int_to_value(gen_onoff_state.opcode, onoff_common.opcode, "opcode");
|
||||
arg_int_to_value(gen_onoff_state.role, onoff_common.msg_role, "role");
|
||||
arg_int_to_value(gen_onoff_state.unicast_address, onoff_common.ctx.addr, "address");
|
||||
arg_int_to_value(gen_onoff_state.net_idx, onoff_common.ctx.net_idx, "network key index");
|
||||
arg_int_to_value(gen_onoff_state.op_en, gen_client_set.onoff_set.op_en, "op_en");
|
||||
arg_int_to_value(gen_onoff_state.onoff_state, gen_client_set.onoff_set.onoff, "onoff");
|
||||
arg_int_to_value(gen_onoff_state.trans_id, gen_client_set.onoff_set.tid, "tid");
|
||||
arg_int_to_value(gen_onoff_state.trans_time, gen_client_set.onoff_set.trans_time, "trans_time");
|
||||
arg_int_to_value(gen_onoff_state.delay, gen_client_set.onoff_set.delay, "delay");
|
||||
|
||||
if (gen_onoff_state.action_type->count != 0) {
|
||||
if (strcmp(gen_onoff_state.action_type->sval[0], "get") == 0) {
|
||||
err = esp_ble_mesh_generic_client_get_state(&onoff_common, &gen_client_get);
|
||||
} else if (strcmp(gen_onoff_state.action_type->sval[0], "set") == 0) {
|
||||
err = esp_ble_mesh_generic_client_set_state(&onoff_common, &gen_client_set);
|
||||
} else if (strcmp(gen_onoff_state.action_type->sval[0], "reg") == 0) {
|
||||
err = esp_ble_mesh_register_generic_client_callback(ble_mesh_generic_onoff_client_model_cb);
|
||||
if (err == ESP_OK) {
|
||||
ESP_LOGI(TAG, "GenONOFFClient:Reg,OK");
|
||||
}
|
||||
}
|
||||
}
|
||||
ESP_LOGD(TAG, "exit %s\n", __func__);
|
||||
return err;
|
||||
}
|
||||
|
||||
void ble_mesh_register_gen_onoff_client_command(void)
|
||||
{
|
||||
gen_onoff_state.action_type = arg_str1("z", NULL, "<action>", "action type");
|
||||
gen_onoff_state.opcode = arg_int0("o", NULL, "<opcode>", "message opcode");
|
||||
gen_onoff_state.appkey_idx = arg_int0("a", NULL, "<appkey>", "appkey index");
|
||||
gen_onoff_state.role = arg_int0("r", NULL, "<role>", "role");
|
||||
gen_onoff_state.unicast_address = arg_int0("u", NULL, "<address>", "unicast address");
|
||||
gen_onoff_state.net_idx = arg_int0("n", NULL, "<netkey index>", "network key index");
|
||||
gen_onoff_state.op_en = arg_int0("e", NULL, "<optional>", "whether optional parameters included");
|
||||
gen_onoff_state.onoff_state = arg_int0("s", NULL, "<state>", "present onoff state");
|
||||
gen_onoff_state.trans_id = arg_int0("i", NULL, "<identifier>", "transaction identifier");
|
||||
gen_onoff_state.trans_time = arg_int0("t", NULL, "<time>", "time to complete state transition");
|
||||
gen_onoff_state.delay = arg_int0("d", NULL, "<delay>", "indicate message execution delay");
|
||||
gen_onoff_state.end = arg_end(1);
|
||||
|
||||
const esp_console_cmd_t gen_onoff_state_cmd = {
|
||||
.command = "bmgocm",
|
||||
.help = "ble mesh generic onoff client model",
|
||||
.hint = NULL,
|
||||
.func = &ble_mesh_generic_onoff_client_model,
|
||||
.argtable = &gen_onoff_state,
|
||||
};
|
||||
ESP_ERROR_CHECK(esp_console_cmd_register(&gen_onoff_state_cmd));
|
||||
}
|
||||
|
||||
#endif
|
@ -22,6 +22,7 @@
|
||||
#include "esp_ble_mesh_defs.h"
|
||||
#include "esp_ble_mesh_common_api.h"
|
||||
#include "esp_ble_mesh_provisioning_api.h"
|
||||
#include "esp_ble_mesh_generic_model_api.h"
|
||||
|
||||
#include "ble_mesh_console_lib.h"
|
||||
#include "ble_mesh_adapter.h"
|
||||
@ -90,6 +91,8 @@ void ble_mesh_register_node_cmd(void);
|
||||
// Register callback function
|
||||
void ble_mesh_prov_cb(esp_ble_mesh_prov_cb_event_t event, esp_ble_mesh_prov_cb_param_t *param);
|
||||
void ble_mesh_model_cb(esp_ble_mesh_model_cb_event_t event, esp_ble_mesh_model_cb_param_t *param);
|
||||
void ble_mesh_generic_server_model_cb(esp_ble_mesh_generic_server_cb_event_t event,
|
||||
esp_ble_mesh_generic_server_cb_param_t *param);
|
||||
|
||||
|
||||
void ble_mesh_register_mesh_node(void)
|
||||
@ -103,14 +106,81 @@ int ble_mesh_register_node_cb(int argc, char** argv)
|
||||
ble_mesh_node_init();
|
||||
esp_ble_mesh_register_prov_callback(ble_mesh_prov_cb);
|
||||
esp_ble_mesh_register_custom_model_callback(ble_mesh_model_cb);
|
||||
esp_ble_mesh_register_generic_server_callback(ble_mesh_generic_server_model_cb);
|
||||
ESP_LOGI(TAG, "Node:Reg,OK");
|
||||
ESP_LOGD(TAG, "exit %s\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ble_mesh_generic_server_model_cb(esp_ble_mesh_generic_server_cb_event_t event,
|
||||
esp_ble_mesh_generic_server_cb_param_t *param)
|
||||
{
|
||||
uint32_t opcode = param->ctx.recv_op;
|
||||
uint8_t status;
|
||||
|
||||
ESP_LOGD(TAG, "enter %s: event is %d, opcode is 0x%x\n", __func__, event, opcode);
|
||||
|
||||
switch (event) {
|
||||
case ESP_BLE_MESH_GENERIC_SERVER_STATE_CHANGE_EVT:
|
||||
if (opcode == ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_SET) {
|
||||
ESP_LOGI(TAG, "GenOnOffServer:SetStatus,OK,%d", param->value.state_change.onoff_set.onoff);
|
||||
ble_mesh_node_set_state(param->value.state_change.onoff_set.onoff);
|
||||
} else if (opcode == ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_SET_UNACK) {
|
||||
ESP_LOGI(TAG, "GenOnOffServer:SetUnAck,OK,%d", param->value.state_change.onoff_set.onoff);
|
||||
ble_mesh_node_set_state(param->value.state_change.onoff_set.onoff);
|
||||
}
|
||||
break;
|
||||
case ESP_BLE_MESH_GENERIC_SERVER_RECV_GET_MSG_EVT: {
|
||||
switch (opcode) {
|
||||
case ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_GET:
|
||||
ESP_LOGI(TAG, "GenOnOffServer:GetStatus,OK");
|
||||
ble_mesh_node_get_state(status);
|
||||
esp_ble_mesh_server_model_send_msg(param->model, ¶m->ctx, ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_STATUS,
|
||||
sizeof(status), &status);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ESP_BLE_MESH_GENERIC_SERVER_RECV_SET_MSG_EVT: {
|
||||
if (opcode == ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_SET || opcode == ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_SET_UNACK) {
|
||||
esp_ble_mesh_gen_onoff_srv_t *srv = param->model->user_data;
|
||||
if (param->value.set.onoff.op_en == false) {
|
||||
srv->state.onoff = param->value.set.onoff.onoff;
|
||||
} else {
|
||||
/* TODO: Delay and state transition */
|
||||
srv->state.onoff = param->value.set.onoff.onoff;
|
||||
}
|
||||
}
|
||||
|
||||
switch (opcode) {
|
||||
case ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_SET:
|
||||
ESP_LOGI(TAG, "GenOnOffServer:SetStatus,OK,%d", param->value.set.onoff.onoff);
|
||||
ble_mesh_node_set_state(param->value.set.onoff.onoff);
|
||||
ble_mesh_node_get_state(status);
|
||||
esp_ble_mesh_server_model_send_msg(param->model, ¶m->ctx, ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_STATUS,
|
||||
sizeof(status), &status);
|
||||
break;
|
||||
case ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_SET_UNACK:
|
||||
ble_mesh_node_set_state(param->value.set.onoff.onoff);
|
||||
ESP_LOGI(TAG, "GenOnOffServer:SetUNACK,OK,%d", param->value.set.onoff.onoff);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
ESP_LOGD(TAG, "exit %s \n", __func__);
|
||||
}
|
||||
|
||||
void ble_mesh_prov_cb(esp_ble_mesh_prov_cb_event_t event, esp_ble_mesh_prov_cb_param_t *param)
|
||||
{
|
||||
ESP_LOGD(TAG, "enter %s, event = %d", __func__, event);
|
||||
|
||||
switch (event) {
|
||||
case ESP_BLE_MESH_PROV_REGISTER_COMP_EVT:
|
||||
ble_mesh_callback_check_err_code(param->prov_register_comp.err_code, "Provisioning:Register");
|
||||
@ -169,32 +239,15 @@ void ble_mesh_prov_cb(esp_ble_mesh_prov_cb_event_t event, esp_ble_mesh_prov_cb_p
|
||||
|
||||
void ble_mesh_model_cb(esp_ble_mesh_model_cb_event_t event, esp_ble_mesh_model_cb_param_t *param)
|
||||
{
|
||||
uint8_t status;
|
||||
uint16_t result;
|
||||
uint8_t data[4];
|
||||
|
||||
ESP_LOGD(TAG, "enter %s, event=%x\n", __func__, event);
|
||||
printf("enter %s, event=%x\n", __func__, event);
|
||||
|
||||
switch (event) {
|
||||
case ESP_BLE_MESH_MODEL_OPERATION_EVT:
|
||||
if (param->model_operation.model != NULL && param->model_operation.model->op != NULL) {
|
||||
if (param->model_operation.opcode == ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_GET) {
|
||||
ESP_LOGI(TAG, "Node:GetStatus,Success");
|
||||
ble_mesh_node_get_state(status);
|
||||
esp_ble_mesh_server_model_send_msg(param->model_operation.model, param->model_operation.ctx, ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_STATUS,
|
||||
sizeof(status), &status);
|
||||
} else if (param->model_operation.opcode == ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_SET) {
|
||||
ESP_LOGI(TAG, "Node:SetAck,Success,%d,%d,%d", param->model_operation.msg[0], param->model_operation.ctx->recv_ttl, param->model_operation.length);
|
||||
ble_mesh_node_set_state(param->model_operation.msg[0]);
|
||||
ble_mesh_node_get_state(status);
|
||||
esp_ble_mesh_server_model_send_msg(param->model_operation.model, param->model_operation.ctx, ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_STATUS,
|
||||
sizeof(status), &status);
|
||||
} else if (param->model_operation.opcode == ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_SET_UNACK) {
|
||||
ble_mesh_node_set_state(param->model_operation.msg[0]);
|
||||
ESP_LOGI(TAG, "Node:SetUnAck,Success,%d,%d", param->model_operation.msg[0], param->model_operation.ctx->recv_ttl);
|
||||
} else if (param->model_operation.opcode == ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_STATUS) {
|
||||
ESP_LOGI(TAG, "Node:Status,Success,%d", param->model_operation.length);
|
||||
} else if (param->model_operation.opcode == ESP_BLE_MESH_VND_MODEL_OP_TEST_PERF_SET) {
|
||||
if (param->model_operation.opcode == ESP_BLE_MESH_VND_MODEL_OP_TEST_PERF_SET) {
|
||||
ESP_LOGI(TAG, "VendorModel:SetAck,Success,%d", param->model_operation.ctx->recv_ttl);
|
||||
data[0] = param->model_operation.msg[0];
|
||||
data[1] = param->model_operation.msg[1];
|
||||
@ -316,14 +369,17 @@ int ble_mesh_init(int argc, char **argv)
|
||||
local_component = ble_mesh_get_component(component.model_type->ival[0]);
|
||||
|
||||
if (component.dev_uuid->count != 0) {
|
||||
device_uuid = malloc((16 + 1) * sizeof(uint8_t));
|
||||
device_uuid = malloc((ESP_BLE_MESH_OCTET16_LEN + 1) * sizeof(uint8_t));
|
||||
if (device_uuid == NULL) {
|
||||
ESP_LOGE(TAG, "ble mesh malloc failed, %d\n", __LINE__);
|
||||
}
|
||||
get_value_string((char *)component.dev_uuid->sval[0], (char *) device_uuid);
|
||||
memcpy(dev_uuid, device_uuid, 16);
|
||||
} else {
|
||||
memcpy(dev_uuid, esp_bt_dev_get_address(), 6);
|
||||
err = get_value_string((char *)component.dev_uuid->sval[0], (char *) device_uuid);
|
||||
if (err == ESP_OK) {
|
||||
memcpy(dev_uuid, device_uuid, ESP_BLE_MESH_OCTET16_LEN);
|
||||
} else {
|
||||
str_2_mac((uint8_t *)component.dev_uuid->sval[0], device_uuid);
|
||||
memcpy(dev_uuid, device_uuid, BD_ADDR_LEN);
|
||||
}
|
||||
}
|
||||
|
||||
err = esp_ble_mesh_init(&prov, local_component);
|
||||
|
@ -25,6 +25,9 @@ typedef struct {
|
||||
struct arg_int *opcode;
|
||||
struct arg_int *model;
|
||||
struct arg_int *role;
|
||||
struct arg_int *pub_addr;
|
||||
struct arg_int *app_index;
|
||||
struct arg_int *period;
|
||||
struct arg_end *end;
|
||||
} ble_mesh_publish_message;
|
||||
ble_mesh_publish_message msg_publish;
|
||||
@ -55,6 +58,29 @@ int ble_mesh_module_publish_message(int argc, char **argv)
|
||||
|
||||
arg_int_to_value(msg_publish.role, device_role, "device role");
|
||||
model = ble_mesh_get_model(msg_publish.model->ival[0]);
|
||||
if (msg_publish.role->count != 0) {
|
||||
device_role = msg_publish.role->ival[0];
|
||||
}
|
||||
|
||||
if (msg_publish.pub_addr->count != 0) {
|
||||
model->pub->publish_addr = msg_publish.pub_addr->ival[0];
|
||||
}
|
||||
|
||||
if (msg_publish.period->count != 0) {
|
||||
model->pub->period = msg_publish.period->ival[0];
|
||||
}
|
||||
|
||||
if (msg_publish.app_index->count != 0) {
|
||||
model->pub->app_idx = msg_publish.app_index->ival[0];
|
||||
}
|
||||
|
||||
if (msg_publish.data->count != 0) {
|
||||
length = strlen(msg_publish.data->sval[0]);
|
||||
data = malloc((length + 1) * sizeof(uint8_t));
|
||||
if (data != NULL) {
|
||||
err = get_value_string((char *)msg_publish.data->sval[0], (char *) data);
|
||||
}
|
||||
}
|
||||
|
||||
err = esp_ble_mesh_model_publish(model, msg_publish.opcode->ival[0], length, data, device_role);
|
||||
|
||||
@ -69,6 +95,9 @@ void ble_mesh_register_server_operation(void)
|
||||
msg_publish.opcode = arg_int1("o", NULL, "<opcode>", "operation opcode");
|
||||
msg_publish.model = arg_int1("m", NULL, "<module>", "module published to");
|
||||
msg_publish.role = arg_int1("r", NULL, "<role>", "device role");
|
||||
msg_publish.pub_addr = arg_int1("a", NULL, "<address>", "unicast address");
|
||||
msg_publish.app_index = arg_int1("i", NULL, "<app key>", "app key index");
|
||||
msg_publish.period = arg_int1("p", NULL, "<period>", "period");
|
||||
msg_publish.end = arg_end(1);
|
||||
|
||||
const esp_console_cmd_t msg_publish_cmd = {
|
||||
|
@ -14,10 +14,7 @@ CONFIG_BT_BTU_TASK_STACK_SIZE=4512
|
||||
CONFIG_BLE_MESH=y
|
||||
CONFIG_BLE_MESH_NODE=y
|
||||
CONFIG_BLE_MESH_PB_GATT=y
|
||||
CONFIG_BLE_MESH_TX_SEG_MSG_COUNT=10
|
||||
CONFIG_BLE_MESH_RX_SEG_MSG_COUNT=10
|
||||
CONFIG_BLE_MESH_TX_SEG_MSG_COUNT=3
|
||||
CONFIG_BLE_MESH_RX_SEG_MSG_COUNT=3
|
||||
CONFIG_BLE_MESH_CFG_CLI=y
|
||||
|
||||
CONFIG_ESP_CONSOLE_UART_BAUDRATE=921600
|
||||
CONFIG_ESPTOOLPY_BAUD_921600B=y
|
||||
CONFIG_ESPTOOLPY_MONITOR_BAUD_921600B=y
|
||||
CONFIG_BLE_MESH_GENERIC_ONOFF_CLI=y
|
||||
|
@ -1,4 +1,5 @@
|
||||
set(COMPONENT_SRCS "ble_mesh_adapter.c"
|
||||
"transaction.c"
|
||||
"ble_mesh_cfg_srv_model.c"
|
||||
"ble_mesh_console_lib.c"
|
||||
"ble_mesh_console_main.c"
|
||||
|
@ -82,27 +82,21 @@ void ble_mesh_node_init(void)
|
||||
uint16_t i;
|
||||
|
||||
for (i = 0; i < NODE_MAX_GROUP_CONFIG; i++) {
|
||||
ble_mesh_node_prestore_params[i].net_idx = 0xFFFF;
|
||||
ble_mesh_node_prestore_params[i].unicast_addr = 0xFFFF;
|
||||
}
|
||||
|
||||
ble_mesh_node_sema = xSemaphoreCreateMutex();
|
||||
if (!ble_mesh_node_sema) {
|
||||
ESP_LOGE(TAG, "%s failed to init, failed to create mesh node semaphore", __func__);
|
||||
ble_mesh_node_prestore_params[i].net_idx = ESP_BLE_MESH_KEY_UNUSED;
|
||||
ble_mesh_node_prestore_params[i].unicast_addr = ESP_BLE_MESH_ADDR_UNASSIGNED;
|
||||
}
|
||||
}
|
||||
|
||||
void ble_mesh_set_node_prestore_params(uint16_t netkey_index, uint16_t unicast_addr)
|
||||
{
|
||||
uint16_t i;
|
||||
xSemaphoreTake(ble_mesh_node_sema, portMAX_DELAY);
|
||||
for (i = 0; i < NODE_MAX_GROUP_CONFIG; i++) {
|
||||
if (ble_mesh_node_prestore_params[i].net_idx != 0xFFFF && ble_mesh_node_prestore_params[i].unicast_addr != 0xFFFF) {
|
||||
if (ble_mesh_node_prestore_params[i].net_idx != ESP_BLE_MESH_KEY_UNUSED
|
||||
&& ble_mesh_node_prestore_params[i].unicast_addr != ESP_BLE_MESH_ADDR_UNASSIGNED) {
|
||||
ble_mesh_node_prestore_params[i].net_idx = netkey_index;
|
||||
ble_mesh_node_prestore_params[i].unicast_addr = unicast_addr;
|
||||
}
|
||||
}
|
||||
xSemaphoreGive(ble_mesh_node_sema);
|
||||
}
|
||||
|
||||
void ble_mesh_create_send_data(char *data, uint16_t byte_num, uint16_t sequence_num, uint32_t opcode)
|
||||
@ -134,8 +128,6 @@ void ble_mesh_test_performance_client_model_get(void)
|
||||
uint32_t i, j;
|
||||
uint32_t sum_time = 0;
|
||||
|
||||
xSemaphoreTake(ble_mesh_test_perf_sema, portMAX_DELAY);
|
||||
|
||||
for (i = 0, j = 0; i < test_perf_statistics.test_num; i++) {
|
||||
if (test_perf_statistics.time[i] != 0) {
|
||||
sum_time += test_perf_statistics.time[i];
|
||||
@ -151,8 +143,6 @@ void ble_mesh_test_performance_client_model_get(void)
|
||||
|
||||
ESP_LOGI(TAG, "VendorModel:Statistics,%d,%d\n",
|
||||
test_perf_statistics.statistics, (sum_time / (j + 1)));
|
||||
|
||||
xSemaphoreGive(ble_mesh_test_perf_sema);
|
||||
}
|
||||
|
||||
void ble_mesh_test_performance_client_model_get_received_percent(void)
|
||||
@ -167,8 +157,6 @@ void ble_mesh_test_performance_client_model_get_received_percent(void)
|
||||
} statistics_time_performance;
|
||||
statistics_time_performance *statistics_time_percent;
|
||||
|
||||
xSemaphoreTake(ble_mesh_test_perf_sema, portMAX_DELAY);
|
||||
|
||||
time_level_num = ((max_time - min_time) / 50 + 1);
|
||||
statistics_time_percent = malloc(sizeof(statistics_time_performance) * time_level_num);
|
||||
|
||||
@ -199,14 +187,11 @@ void ble_mesh_test_performance_client_model_get_received_percent(void)
|
||||
printf("\n");
|
||||
|
||||
free(statistics_time_percent);
|
||||
xSemaphoreGive(ble_mesh_test_perf_sema);
|
||||
}
|
||||
|
||||
void ble_mesh_test_performance_client_model_accumulate_statistics(uint32_t value)
|
||||
{
|
||||
xSemaphoreTake(ble_mesh_test_perf_sema, portMAX_DELAY);
|
||||
test_perf_statistics.statistics += value;
|
||||
xSemaphoreGive(ble_mesh_test_perf_sema);
|
||||
}
|
||||
|
||||
int ble_mesh_test_performance_client_model_accumulate_time(uint16_t time, uint8_t *data, uint8_t ack_ttl, uint16_t length)
|
||||
@ -214,11 +199,9 @@ int ble_mesh_test_performance_client_model_accumulate_time(uint16_t time, uint8_
|
||||
uint16_t i;
|
||||
uint16_t sequence_num = 0;
|
||||
uint16_t node_received_ttl = 0;
|
||||
xSemaphoreTake(ble_mesh_test_perf_sema, portMAX_DELAY);
|
||||
|
||||
// received fail
|
||||
if (length != test_perf_statistics.test_length) {
|
||||
xSemaphoreGive(ble_mesh_test_perf_sema);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -231,7 +214,6 @@ int ble_mesh_test_performance_client_model_accumulate_time(uint16_t time, uint8_
|
||||
|
||||
for (i = 0; i < test_perf_statistics.test_num; i++) {
|
||||
if (test_perf_statistics.package_index[i] == sequence_num) {
|
||||
xSemaphoreGive(ble_mesh_test_perf_sema);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
@ -252,7 +234,6 @@ int ble_mesh_test_performance_client_model_accumulate_time(uint16_t time, uint8_
|
||||
}
|
||||
}
|
||||
|
||||
xSemaphoreGive(ble_mesh_test_perf_sema);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -23,7 +23,10 @@
|
||||
|
||||
#define TAG "ble_mesh_prov_console"
|
||||
|
||||
uint64_t start_time;
|
||||
#define TRANS_TYPE_MESH_PERF 0x01
|
||||
#define TRANS_MESH_SEND_MESSAGE 0x01
|
||||
#define TRANS_MESH_SEND_MESSAGE_EVT 0x01
|
||||
|
||||
typedef enum {
|
||||
VENDOR_MODEL_PERF_OPERATION_TYPE_GET = 1,
|
||||
VENDOR_MODEL_PERF_OPERATION_TYPE_SET,
|
||||
@ -62,40 +65,29 @@ ble_mesh_performance_statistics_t test_perf_statistics;
|
||||
|
||||
#define SEND_MESSAGE_TIMEOUT (30000/portTICK_RATE_MS)
|
||||
|
||||
extern SemaphoreHandle_t ble_mesh_node_sema;
|
||||
extern SemaphoreHandle_t ble_mesh_test_perf_send_sema;
|
||||
extern SemaphoreHandle_t ble_mesh_test_perf_sema;
|
||||
|
||||
#define arg_int_to_value(src_msg, dst_msg, message) do { \
|
||||
if (src_msg->count != 0) {\
|
||||
ESP_LOGD(TAG, " %s, %s\n", __func__, message);\
|
||||
dst_msg = src_msg->ival[0];\
|
||||
} \
|
||||
} while(0) \
|
||||
|
||||
#define ble_mesh_node_get_value(index, key, value) do { \
|
||||
uint16_t _index = 0; \
|
||||
xSemaphoreTake(ble_mesh_node_sema, portMAX_DELAY); \
|
||||
for (_index = 0; _index < NODE_MAX_GROUP_CONFIG; _index) { \
|
||||
if (node_set_prestore_params[_index].key == value) { \
|
||||
break; \
|
||||
} \
|
||||
} \
|
||||
index = _index; \
|
||||
xSemaphoreGive(ble_mesh_node_sema); \
|
||||
} while(0) \
|
||||
|
||||
#define ble_mesh_node_set_state(status) do { \
|
||||
xSemaphoreTake(ble_mesh_node_sema, portMAX_DELAY); \
|
||||
node_status.previous = node_status.current; \
|
||||
node_status.current = status; \
|
||||
xSemaphoreGive(ble_mesh_node_sema); \
|
||||
}while(0) \
|
||||
|
||||
#define ble_mesh_node_get_state(status) do { \
|
||||
xSemaphoreTake(ble_mesh_node_sema, portMAX_DELAY); \
|
||||
status = node_status.previous; \
|
||||
xSemaphoreGive(ble_mesh_node_sema); \
|
||||
}while(0) \
|
||||
|
||||
#define ble_mesh_callback_check_err_code(err_code, message) do { \
|
||||
|
@ -93,16 +93,16 @@ esp_ble_mesh_comp_t config_client_comp = {
|
||||
};
|
||||
|
||||
// configure special module
|
||||
esp_ble_mesh_model_op_t gen_onoff_srv_model_op_config[] = {
|
||||
ESP_BLE_MESH_MODEL_OP(ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_GET, 0),
|
||||
ESP_BLE_MESH_MODEL_OP(ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_SET, 2),
|
||||
ESP_BLE_MESH_MODEL_OP(ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_SET_UNACK, 2),
|
||||
ESP_BLE_MESH_MODEL_OP_END,
|
||||
};
|
||||
ESP_BLE_MESH_MODEL_PUB_DEFINE(onoff_pub_0, 2 + 3, ROLE_NODE);
|
||||
static esp_ble_mesh_gen_onoff_srv_t onoff_server = {
|
||||
.rsp_ctrl.get_auto_rsp = ESP_BLE_MESH_SERVER_RSP_BY_APP,
|
||||
.rsp_ctrl.set_auto_rsp = ESP_BLE_MESH_SERVER_RSP_BY_APP,
|
||||
};
|
||||
|
||||
|
||||
esp_ble_mesh_model_t gen_onoff_srv_models[] = {
|
||||
ESP_BLE_MESH_MODEL_CFG_SRV(&cfg_srv),
|
||||
ESP_BLE_MESH_SIG_MODEL(ESP_BLE_MESH_MODEL_ID_GEN_ONOFF_SRV, gen_onoff_srv_model_op_config, &model_pub_config, NULL),
|
||||
ESP_BLE_MESH_MODEL_GEN_ONOFF_SRV(&onoff_pub_0, &onoff_server),
|
||||
};
|
||||
|
||||
esp_ble_mesh_elem_t gen_onoff_srv_elements[] = {
|
||||
|
@ -129,6 +129,9 @@ esp_err_t bluetooth_init(void)
|
||||
return ret;
|
||||
}
|
||||
|
||||
esp_log_level_set("*", ESP_LOG_ERROR);
|
||||
esp_log_level_set("ble_mesh_prov_console", ESP_LOG_INFO);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -344,6 +344,8 @@ int ble_mesh_configuration_client_model_operation(int argc, char **argv)
|
||||
err = esp_ble_mesh_config_client_set_state(&client_common, (esp_ble_mesh_cfg_client_set_state_t *)&relay_set);
|
||||
} else if (strcmp(configuration_client_model_operation.set_state->sval[0], "pubset") == 0) {
|
||||
err = esp_ble_mesh_config_client_set_state(&client_common, (esp_ble_mesh_cfg_client_set_state_t *)&mod_pub_set);
|
||||
} else if (strcmp(configuration_client_model_operation.set_state->sval[0], "reset") == 0) {
|
||||
err = esp_ble_mesh_config_client_set_state(&client_common, NULL);
|
||||
}
|
||||
}
|
||||
} else if (strcmp(configuration_client_model_operation.action_type->sval[0], "reg") == 0) {
|
||||
|
@ -30,7 +30,7 @@ typedef struct {
|
||||
struct arg_int *net_idx;
|
||||
struct arg_end *end;
|
||||
} ble_mesh_gen_onoff_state_t;
|
||||
ble_mesh_gen_onoff_state_t gen_onoff_state;
|
||||
static ble_mesh_gen_onoff_state_t gen_onoff_state;
|
||||
|
||||
void ble_mesh_register_gen_onoff_client_command(void);
|
||||
void ble_mesh_generic_onoff_client_model_cb(esp_ble_mesh_generic_client_cb_event_t event,
|
||||
@ -124,6 +124,9 @@ int ble_mesh_generic_onoff_client_model(int argc, char **argv)
|
||||
}
|
||||
|
||||
onoff_common.model = ble_mesh_get_model(ESP_BLE_MESH_MODEL_ID_GEN_ONOFF_CLI);
|
||||
if (onoff_common.model == NULL) {
|
||||
ESP_LOGI(TAG, "GenONOFFClient:LoadModel,Fail");
|
||||
}
|
||||
|
||||
arg_int_to_value(gen_onoff_state.appkey_idx, onoff_common.ctx.app_idx, "appkey_index");
|
||||
arg_int_to_value(gen_onoff_state.opcode, onoff_common.opcode, "opcode");
|
||||
|
@ -20,9 +20,7 @@
|
||||
|
||||
#include "esp_ble_mesh_networking_api.h"
|
||||
#include "ble_mesh_adapter.h"
|
||||
|
||||
SemaphoreHandle_t ble_mesh_test_perf_send_sema;
|
||||
SemaphoreHandle_t ble_mesh_test_perf_sema;
|
||||
#include "transaction.h"
|
||||
|
||||
typedef struct {
|
||||
struct arg_str *action_type;
|
||||
@ -58,7 +56,9 @@ void ble_mesh_test_performance_client_model_throughput(void *params)
|
||||
{
|
||||
uint16_t i;
|
||||
uint8_t *data = NULL;
|
||||
uint64_t start_time;
|
||||
esp_ble_mesh_msg_ctx_t ctx;
|
||||
transaction_t *trans = NULL;
|
||||
ble_mesh_test_perf_throughput_data *profile_context = (ble_mesh_test_perf_throughput_data *)params;
|
||||
|
||||
ESP_LOGD(TAG, "enter %s\n", __func__);
|
||||
@ -77,16 +77,15 @@ void ble_mesh_test_performance_client_model_throughput(void *params)
|
||||
ESP_LOGE(TAG, " %s, %d, malloc fail\n", __func__, __LINE__);
|
||||
}
|
||||
|
||||
ble_mesh_test_perf_send_sema = xSemaphoreCreateMutex();
|
||||
xSemaphoreTake(ble_mesh_test_perf_send_sema, SEND_MESSAGE_TIMEOUT);
|
||||
|
||||
TRANSACTION_INIT(&trans, TRANS_TYPE_MESH_PERF, TRANS_MESH_SEND_MESSAGE,
|
||||
TRANS_MESH_SEND_MESSAGE_EVT, SEND_MESSAGE_TIMEOUT, &start_time, NULL);
|
||||
for (i = 1; i <= profile_context->test_num; i++) {
|
||||
ble_mesh_create_send_data((char *)data, profile_context->length, i, profile_context->opcode);
|
||||
start_time = esp_timer_get_time();
|
||||
esp_ble_mesh_client_model_send_msg(profile_context->model, &ctx, profile_context->opcode,
|
||||
profile_context->length, data, 8000, profile_context->need_ack, profile_context->device_role);
|
||||
ble_mesh_test_performance_client_model_accumulate_statistics(profile_context->length);
|
||||
xSemaphoreTake(ble_mesh_test_perf_send_sema, SEND_MESSAGE_TIMEOUT);
|
||||
transaction_run(trans);
|
||||
}
|
||||
|
||||
ESP_LOGI(TAG, "VendorModel:SendPackage,Finish");
|
||||
@ -111,7 +110,6 @@ int ble_mesh_test_performance_client_model(int argc, char **argv)
|
||||
model = ble_mesh_get_model(ESP_BLE_MESH_VND_MODEL_ID_TEST_PERF_CLI);
|
||||
|
||||
if (strcmp(test_perf_client_model.action_type->sval[0], "init") == 0) {
|
||||
ble_mesh_test_perf_sema = xSemaphoreCreateMutex();
|
||||
result = esp_ble_mesh_client_model_init(model);
|
||||
if (result == ESP_OK) {
|
||||
ESP_LOGI(TAG, "VendorClientModel:Init,OK");
|
||||
@ -158,6 +156,7 @@ int ble_mesh_test_performance_client_model_performance(int argc, char **argv)
|
||||
}
|
||||
|
||||
if (strcmp(test_perf_client_model_statistics.action_type->sval[0], "init") == 0) {
|
||||
init_transactions();
|
||||
result = ble_mesh_test_performance_client_model_init(test_perf_client_model_statistics.node_num->ival[0],
|
||||
test_perf_client_model_statistics.test_size->ival[0], test_perf_client_model_statistics.ttl->ival[0]);
|
||||
if (result == 0) {
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include "esp_ble_mesh_config_model_api.h"
|
||||
|
||||
#include "ble_mesh_adapter.h"
|
||||
#include "transaction.h"
|
||||
|
||||
typedef struct {
|
||||
struct arg_str *static_val;
|
||||
@ -63,8 +64,6 @@ ble_mesh_node_status node_status = {
|
||||
.current = 0x0,
|
||||
};
|
||||
|
||||
SemaphoreHandle_t ble_mesh_node_sema;
|
||||
|
||||
void ble_mesh_register_node_cmd(void);
|
||||
// Register callback function
|
||||
void ble_mesh_prov_cb(esp_ble_mesh_prov_cb_event_t event, esp_ble_mesh_prov_cb_param_t *param);
|
||||
@ -142,10 +141,10 @@ void ble_mesh_prov_cb(esp_ble_mesh_prov_cb_event_t event, esp_ble_mesh_prov_cb_p
|
||||
break;
|
||||
#if (CONFIG_BLE_MESH_PROVISIONER)
|
||||
case ESP_BLE_MESH_PROVISIONER_RECV_UNPROV_ADV_PKT_EVT:
|
||||
ESP_LOGI(TAG, "Provisioner recv unprovisioned device beacon:");
|
||||
ESP_LOGD(TAG, "Provisioner recv unprovisioned device beacon:");
|
||||
ESP_LOG_BUFFER_HEX("Device UUID %s", param->provisioner_recv_unprov_adv_pkt.dev_uuid, 16);
|
||||
ESP_LOG_BUFFER_HEX("Address %s", param->provisioner_recv_unprov_adv_pkt.addr, 6);
|
||||
ESP_LOGI(TAG, "Address type 0x%x, oob_info 0x%04x, adv_type 0x%x, bearer 0x%x",
|
||||
ESP_LOGD(TAG, "Address type 0x%x, oob_info 0x%04x, adv_type 0x%x, bearer 0x%x",
|
||||
param->provisioner_recv_unprov_adv_pkt.addr_type, param->provisioner_recv_unprov_adv_pkt.oob_info,
|
||||
param->provisioner_recv_unprov_adv_pkt.adv_type, param->provisioner_recv_unprov_adv_pkt.bearer);
|
||||
break;
|
||||
@ -200,8 +199,17 @@ void ble_mesh_model_cb(esp_ble_mesh_model_cb_event_t event, esp_ble_mesh_model_c
|
||||
{
|
||||
esp_err_t result = ESP_OK;
|
||||
uint8_t status;
|
||||
uint64_t *start_time = NULL;
|
||||
transaction_t *trans = NULL;
|
||||
|
||||
ESP_LOGD(TAG, "enter %s, event=%x\n", __func__, event);
|
||||
do {
|
||||
trans = transaction_get(TRANS_TYPE_MESH_PERF, TRANS_MESH_SEND_MESSAGE, trans);
|
||||
if (trans) {
|
||||
start_time = (uint64_t *)trans->input;
|
||||
break;
|
||||
}
|
||||
}while(trans);
|
||||
|
||||
switch (event) {
|
||||
case ESP_BLE_MESH_MODEL_OPERATION_EVT:
|
||||
@ -211,11 +219,17 @@ void ble_mesh_model_cb(esp_ble_mesh_model_cb_event_t event, esp_ble_mesh_model_c
|
||||
ble_mesh_node_get_state(status);
|
||||
result = esp_ble_mesh_server_model_send_msg(param->model_operation.model, param->model_operation.ctx, ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_STATUS,
|
||||
sizeof(status), &status);
|
||||
if (result != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Node:SendMsg,Fal");
|
||||
}
|
||||
} else if (param->model_operation.opcode == ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_SET) {
|
||||
ble_mesh_node_set_state(param->model_operation.msg[0]);
|
||||
ESP_LOGI(TAG, "Node:SetAck,OK,%d,%d", param->model_operation.msg[0], param->model_operation.ctx->recv_ttl);
|
||||
result = esp_ble_mesh_server_model_send_msg(param->model_operation.model, param->model_operation.ctx, ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_STATUS,
|
||||
sizeof(status), param->model_operation.msg);
|
||||
if (result != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Node:SendMsg,Fal");
|
||||
}
|
||||
} else if (param->model_operation.opcode == ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_SET_UNACK) {
|
||||
ble_mesh_node_set_state(param->model_operation.msg[0]);
|
||||
ESP_LOGI(TAG, "Node:SetUnAck,OK,%d,%d", param->model_operation.msg[0], param->model_operation.ctx->recv_ttl);
|
||||
@ -224,11 +238,12 @@ void ble_mesh_model_cb(esp_ble_mesh_model_cb_event_t event, esp_ble_mesh_model_c
|
||||
} else if (param->model_operation.opcode == ESP_BLE_MESH_VND_MODEL_OP_TEST_PERF_SET) {
|
||||
ESP_LOGI(TAG, "VendorModel:SetAck,OK,%d", param->model_operation.ctx->recv_ttl);
|
||||
} else if (param->model_operation.opcode == ESP_BLE_MESH_VND_MODEL_OP_TEST_PERF_STATUS) {
|
||||
uint64_t current_time = esp_timer_get_time();
|
||||
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);
|
||||
ESP_LOGI(TAG, "VendorModel:Status,OK,%d", param->model_operation.ctx->recv_ttl);
|
||||
if (ble_mesh_test_perf_send_sema != NULL && result == ESP_OK) {
|
||||
xSemaphoreGive(ble_mesh_test_perf_send_sema);
|
||||
if (trans) {
|
||||
uint64_t current_time = esp_timer_get_time();
|
||||
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);
|
||||
transaction_set_events(trans, TRANS_MESH_SEND_MESSAGE_EVT);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -245,10 +260,11 @@ void ble_mesh_model_cb(esp_ble_mesh_model_cb_event_t event, esp_ble_mesh_model_c
|
||||
break;
|
||||
case ESP_BLE_MESH_CLIENT_MODEL_RECV_PUBLISH_MSG_EVT:
|
||||
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]);
|
||||
uint64_t current_time = esp_timer_get_time();
|
||||
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);
|
||||
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) {
|
||||
xSemaphoreGive(ble_mesh_test_perf_send_sema);
|
||||
if (trans) {
|
||||
uint64_t current_time = esp_timer_get_time();
|
||||
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);
|
||||
transaction_set_events(trans, TRANS_MESH_SEND_MESSAGE_EVT);
|
||||
}
|
||||
break;
|
||||
case ESP_BLE_MESH_MODEL_PUBLISH_UPDATE_EVT:
|
||||
@ -256,8 +272,8 @@ void ble_mesh_model_cb(esp_ble_mesh_model_cb_event_t event, esp_ble_mesh_model_c
|
||||
break;
|
||||
case ESP_BLE_MESH_CLIENT_MODEL_SEND_TIMEOUT_EVT:
|
||||
ESP_LOGI(TAG, "Node:TimeOut, 0x%04X", param->client_send_timeout.opcode);
|
||||
if (ble_mesh_test_perf_send_sema != NULL) {
|
||||
xSemaphoreGive(ble_mesh_test_perf_send_sema);
|
||||
if (trans) {
|
||||
transaction_set_events(trans, TRANS_MESH_SEND_MESSAGE_EVT);
|
||||
}
|
||||
break;
|
||||
case ESP_BLE_MESH_MODEL_EVT_MAX:
|
||||
@ -317,7 +333,7 @@ static int ble_mesh_load_oob(int argc, char **argv)
|
||||
//parsing prov
|
||||
#if CONFIG_BLE_MESH_NODE
|
||||
prov.uuid = dev_uuid;
|
||||
memcpy(dev_uuid, esp_bt_dev_get_address(), 6);
|
||||
memcpy(dev_uuid, esp_bt_dev_get_address(), BD_ADDR_LEN);
|
||||
if (oob.static_val->count != 0) {
|
||||
static_val = malloc(oob.static_val_len->ival[0] + 1);
|
||||
if (static_val == NULL) {
|
||||
@ -353,7 +369,6 @@ static int ble_mesh_load_oob(int argc, char **argv)
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int ble_mesh_init(int argc, char **argv)
|
||||
{
|
||||
int err;
|
||||
|
@ -82,34 +82,11 @@ ble_mesh_provisioner_add_key_t provisioner_add_key;
|
||||
|
||||
void ble_mesh_regist_provisioner_cmd(void);
|
||||
|
||||
void ble_mesh_prov_adv_cb(const esp_ble_mesh_bd_addr_t addr, const esp_ble_mesh_addr_type_t addr_type, const uint8_t adv_type,
|
||||
const uint8_t *dev_uuid, uint16_t oob_info, esp_ble_mesh_prov_bearer_t bearer);
|
||||
|
||||
void ble_mesh_register_mesh_provisioner(void)
|
||||
{
|
||||
ble_mesh_regist_provisioner_cmd();
|
||||
}
|
||||
|
||||
void ble_mesh_prov_adv_cb(const esp_ble_mesh_bd_addr_t addr, const esp_ble_mesh_addr_type_t addr_type, const uint8_t adv_type,
|
||||
const uint8_t *dev_uuid, uint16_t oob_info, esp_ble_mesh_prov_bearer_t bearer)
|
||||
{
|
||||
ESP_LOGD(TAG, "enter %s\n", __func__);
|
||||
ESP_LOGI(TAG, "scan device address:");
|
||||
esp_log_buffer_hex(TAG, addr, sizeof(esp_ble_mesh_bd_addr_t));
|
||||
ESP_LOGI(TAG, "scan device uuid:");
|
||||
esp_log_buffer_hex(TAG, dev_uuid, 16);
|
||||
ESP_LOGD(TAG, "exit %s\n", __func__);
|
||||
}
|
||||
|
||||
int ble_mesh_provisioner_register(int argc, char** argv)
|
||||
{
|
||||
ESP_LOGD(TAG, "enter %s \n", __func__);
|
||||
// esp_ble_mesh_register_unprov_adv_pkt_callback(ble_mesh_prov_adv_cb);
|
||||
ESP_LOGI(TAG, "Provisioner:Reg,OK");
|
||||
ESP_LOGD(TAG, "exit %s \n", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ble_mesh_provision_address(int argc, char **argv)
|
||||
{
|
||||
esp_err_t err = ESP_OK;
|
||||
@ -126,27 +103,17 @@ int ble_mesh_provision_address(int argc, char **argv)
|
||||
arg_print_errors(stderr, provisioner_addr.end, argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
memcpy(device_addr.uuid, preset_addr_uuid, BD_ADDR_LEN);
|
||||
if (provisioner_addr.device_addr->count != 0) {
|
||||
if (provisioner_addr.device_uuid->count != 0) {
|
||||
del_dev.flag = BIT(0) | BIT(1);
|
||||
str_2_mac((uint8_t *)provisioner_addr.device_addr->sval[0], device_addr.uuid);
|
||||
str_2_mac((uint8_t *)provisioner_addr.device_addr->sval[0], del_dev.uuid);
|
||||
} else {
|
||||
del_dev.flag = BIT(0);
|
||||
memcpy(device_addr.uuid, preset_addr_uuid, 16);
|
||||
memcpy(del_dev.uuid, preset_addr_uuid, 16);
|
||||
}
|
||||
str_2_mac((uint8_t *)provisioner_addr.device_addr->sval[0], device_addr.addr);
|
||||
str_2_mac((uint8_t *)provisioner_addr.device_addr->sval[0], del_dev.addr);
|
||||
arg_int_to_value(provisioner_addr.addr_type, device_addr.addr_type, "address type");
|
||||
arg_int_to_value(provisioner_addr.addr_type, del_dev.addr_type, "address type");
|
||||
} else if (provisioner_addr.device_uuid->count != 0) {
|
||||
get_value_string((char *)provisioner_addr.device_uuid->sval[0], (char *)device_addr.uuid);
|
||||
get_value_string((char *)provisioner_addr.device_uuid->sval[0], (char *)del_dev.uuid);
|
||||
del_dev.flag = BIT(1);
|
||||
memcpy(device_addr.addr, preset_addr_uuid, 6);
|
||||
memcpy(del_dev.addr, preset_addr_uuid, 6);
|
||||
str_2_mac((uint8_t *)provisioner_addr.device_addr->sval[0], device_addr.uuid);
|
||||
str_2_mac((uint8_t *)provisioner_addr.device_addr->sval[0], del_dev.uuid);
|
||||
}
|
||||
|
||||
if (strcmp(provisioner_addr.add_del->sval[0], "add") == 0) {
|
||||
@ -157,6 +124,12 @@ int ble_mesh_provision_address(int argc, char **argv)
|
||||
err = esp_ble_mesh_provisioner_delete_dev(&del_dev);
|
||||
}
|
||||
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGI(TAG, "Provisioner:AddDelAddr,Fail,%d", err);
|
||||
} else {
|
||||
ESP_LOGI(TAG, "Provisioner:AddDelAddr,OK");
|
||||
}
|
||||
|
||||
ESP_LOGD(TAG, "exit %s \n", __func__);
|
||||
return err;
|
||||
}
|
||||
@ -249,6 +222,8 @@ int ble_mesh_provisioner_add_node(int argc, char **argv)
|
||||
result = bt_mesh_provisioner_store_node_info(&node_info);
|
||||
if (result == ESP_OK) {
|
||||
ESP_LOGI(TAG, "Provisioner:AddNodeInfo,OK\n");
|
||||
} else {
|
||||
ESP_LOGI(TAG, "Provisioner:AddNodeInfo,ERROR,%d\n", result);
|
||||
}
|
||||
|
||||
ESP_LOGD(TAG, "exit %s\n", __func__);
|
||||
@ -282,7 +257,7 @@ int ble_mesh_provisioner_add_key(int argc, char **argv)
|
||||
}
|
||||
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGI(TAG, "Provisioner:KeyAction,Fail");
|
||||
ESP_LOGI(TAG, "Provisioner:KeyAction,Fail,%d", err);
|
||||
} else {
|
||||
ESP_LOGI(TAG, "Provisioner:KeyAction,OK");
|
||||
}
|
||||
@ -314,7 +289,7 @@ int ble_mesh_provision_bind_local_model(int argc, char **argv)
|
||||
err = esp_ble_mesh_provisioner_bind_app_key_to_local_model(element_addr, app_idx, model_id, company_id);
|
||||
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Provisioner:BindModel,Fail,%x\n", err);
|
||||
ESP_LOGE(TAG, "Provisioner:BindModel,Fail,%d\n", err);
|
||||
} else {
|
||||
ESP_LOGI(TAG, "Provisioner:BindModel,OK\n");
|
||||
}
|
||||
@ -324,14 +299,6 @@ int ble_mesh_provision_bind_local_model(int argc, char **argv)
|
||||
|
||||
void ble_mesh_regist_provisioner_cmd(void)
|
||||
{
|
||||
const esp_console_cmd_t prov_register = {
|
||||
.command = "bmpreg",
|
||||
.help = "ble mesh provisioner: register callback",
|
||||
.hint = NULL,
|
||||
.func = &ble_mesh_provisioner_register,
|
||||
};
|
||||
ESP_ERROR_CHECK(esp_console_cmd_register(&prov_register));
|
||||
|
||||
provisioner_addr.add_del = arg_str1("z", NULL, "<add/delete>", "action type");
|
||||
provisioner_addr.device_addr = arg_str0("d", NULL, "<address>", "device address");
|
||||
provisioner_addr.device_uuid = arg_str0("u", NULL, "<uuid>", "device uuid");
|
||||
|
@ -0,0 +1,266 @@
|
||||
#include <stdio.h>
|
||||
|
||||
#include "sdkconfig.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/event_groups.h"
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/semphr.h"
|
||||
|
||||
#include "esp_timer.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_err.h"
|
||||
|
||||
#include "transaction.h"
|
||||
|
||||
|
||||
#define TAG "TRANS"
|
||||
|
||||
static transaction_t transactions[MAX_TRANSACTION_COUNT];
|
||||
static SemaphoreHandle_t trans_mutex;
|
||||
|
||||
static uint32_t utils_get_system_ts(void)
|
||||
{
|
||||
return esp_log_timestamp();
|
||||
}
|
||||
|
||||
static void transaction_reset(transaction_t *trans)
|
||||
{
|
||||
EventBits_t bits;
|
||||
|
||||
ESP_LOGV(TAG, "transaction reset: %x", (uint32_t) trans);
|
||||
// set to inactive state and clear all bits of the transaction
|
||||
xSemaphoreTakeRecursive(trans_mutex, portMAX_DELAY);
|
||||
trans->type = 0;
|
||||
trans->sub_type = 0;
|
||||
trans->current_bits = 0;
|
||||
bits = xEventGroupGetBits(trans->event_group);
|
||||
xEventGroupClearBits(trans->event_group, bits);
|
||||
trans->state = TRANSACTION_INACTIVE;
|
||||
trans->ret = ESP_OK;
|
||||
xSemaphoreGiveRecursive(trans_mutex);
|
||||
}
|
||||
|
||||
void transaction_deinit(transaction_t *trans)
|
||||
{
|
||||
if (trans != NULL) {
|
||||
transaction_reset(trans);
|
||||
}
|
||||
}
|
||||
|
||||
esp_err_t transaction_set_events(transaction_t *trans, EventBits_t events)
|
||||
{
|
||||
esp_err_t ret = ESP_OK;
|
||||
xSemaphoreTakeRecursive(trans_mutex, portMAX_DELAY);
|
||||
if (trans) {
|
||||
if (trans->state == TRANSACTION_INACTIVE) {
|
||||
ret = TRANS_RET_STATE_ERR;
|
||||
} else {
|
||||
// if the task (task A) setting current bits is with higher priority than the task (task B) run transaction,
|
||||
// current_bits might not be updated until task A yield (not it's only update in run_transaction function).
|
||||
// If task A set events and immediately use current_bits, current_bits is not correct.
|
||||
// update current_bits here to make sure it's updated
|
||||
trans->current_bits |= events;
|
||||
xEventGroupSetBits(trans->event_group, events);
|
||||
}
|
||||
ESP_LOGD(TAG, "transactions set events: %x, %x, %x, %x; ret: %x", (uint32_t) trans, trans->type, trans->sub_type, events, ret);
|
||||
} else {
|
||||
ret = TRANS_RET_INVALID_TRNSACTION;
|
||||
}
|
||||
xSemaphoreGiveRecursive(trans_mutex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
esp_err_t transaction_test_events(transaction_t *trans, EventBits_t events)
|
||||
{
|
||||
esp_err_t ret = TRANS_RET_TEST_EVENT_FAILED;
|
||||
|
||||
xSemaphoreTakeRecursive(trans_mutex, portMAX_DELAY);
|
||||
if (trans) {
|
||||
if (trans->state == TRANSACTION_INACTIVE) {
|
||||
ret = TRANS_RET_STATE_ERR;
|
||||
} else {
|
||||
if ((trans->current_bits & events) == events) {
|
||||
ret = ESP_OK;
|
||||
}
|
||||
}
|
||||
ESP_LOGV(TAG, "transactions test events: %x, %x; ret: %x", (uint32_t) trans, events, ret);
|
||||
} else {
|
||||
ret = TRANS_RET_INVALID_TRNSACTION;
|
||||
}
|
||||
xSemaphoreGiveRecursive(trans_mutex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
esp_err_t transaction_clear_events(transaction_t *trans, EventBits_t events)
|
||||
{
|
||||
esp_err_t ret = ESP_OK;
|
||||
xSemaphoreTakeRecursive(trans_mutex, portMAX_DELAY);
|
||||
if (trans) {
|
||||
if (trans->state == TRANSACTION_INACTIVE) {
|
||||
ret = TRANS_RET_STATE_ERR;
|
||||
} else {
|
||||
trans->current_bits &= ~events;
|
||||
xEventGroupClearBits(trans->event_group, events);
|
||||
}
|
||||
ESP_LOGD(TAG, "transactions clear events: %x, %x, %x, %x; ret: %x", (uint32_t) trans, trans->type, trans->sub_type, events, ret);
|
||||
} else {
|
||||
ret = TRANS_RET_INVALID_TRNSACTION;
|
||||
}
|
||||
xSemaphoreGiveRecursive(trans_mutex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
esp_err_t transaction_abort(transaction_t *trans, esp_err_t reason)
|
||||
{
|
||||
esp_err_t ret = ESP_OK;
|
||||
xSemaphoreTakeRecursive(trans_mutex, portMAX_DELAY);
|
||||
if (trans) {
|
||||
if (trans->state == TRANSACTION_INACTIVE) {
|
||||
ret = TRANS_RET_STATE_ERR;
|
||||
} else {
|
||||
trans->ret = reason;
|
||||
xEventGroupSetBits(trans->event_group, TRANSACTION_ABORT_EVENT);
|
||||
}
|
||||
ESP_LOGD(TAG, "transactions abort: %x, %x, %x, %x; ret: %x", (uint32_t) trans, trans->type, trans->sub_type, reason, ret);
|
||||
} else {
|
||||
ret = TRANS_RET_INVALID_TRNSACTION;
|
||||
}
|
||||
xSemaphoreGiveRecursive(trans_mutex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
esp_err_t transaction_init(transaction_t **trans, uint8_t type, uint32_t sub_type, EventBits_t wait_events, uint32_t timeout, void *input, void *output)
|
||||
{
|
||||
esp_err_t ret = ESP_OK;
|
||||
uint8_t i;
|
||||
|
||||
if ((wait_events & TRANSACTION_EVENT_MASK)
|
||||
&& wait_events != TRANSACTION_TIMEOUT_EVENT) {
|
||||
ret = TRANS_RET_EVENTS_CONFLICT;
|
||||
return ret;
|
||||
}
|
||||
|
||||
xSemaphoreTakeRecursive(trans_mutex, portMAX_DELAY);
|
||||
for (i = 0; i < MAX_TRANSACTION_COUNT; i++) {
|
||||
if ( transactions[i].state == TRANSACTION_INACTIVE ) {
|
||||
transactions[i].state = TRANSACTION_ACTIVE;
|
||||
*trans = &transactions[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( i == MAX_TRANSACTION_COUNT ) {
|
||||
ret = TRANS_RET_FAILED_TO_ALLOCATE;
|
||||
} else {
|
||||
// init transaction
|
||||
transactions[i].type = type;
|
||||
transactions[i].wait_events = wait_events;
|
||||
transactions[i].sub_type = sub_type;
|
||||
transactions[i].timeout = timeout;
|
||||
transactions[i].ret = ESP_OK;
|
||||
transactions[i].input = input;
|
||||
transactions[i].output = output;
|
||||
}
|
||||
xSemaphoreGiveRecursive(trans_mutex);
|
||||
|
||||
if (ret == ESP_OK) {
|
||||
ESP_LOGD(TAG, "transaction created: %x, %x, %x; ret: %x", type, sub_type, (uint32_t) *trans, ret);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
esp_err_t transaction_run(transaction_t *trans)
|
||||
{
|
||||
esp_err_t ret = ESP_OK;
|
||||
uint32_t start_time;
|
||||
int32_t wait_time;
|
||||
EventBits_t current_bits;
|
||||
|
||||
if (trans) {
|
||||
start_time = utils_get_system_ts();
|
||||
|
||||
// wait for wait events
|
||||
while (1) {
|
||||
//TODO: we didn't handle ts overflow
|
||||
wait_time = start_time + trans->timeout - utils_get_system_ts();
|
||||
|
||||
if ( wait_time < 0 ) {
|
||||
ESP_LOGI(TAG, "transaction timeout: %x, %x, %x, %x, %x", (uint32_t) trans, trans->type, trans->sub_type, trans->wait_events, trans->current_bits);
|
||||
ret = TRANS_RET_TIMEOUT;
|
||||
break;
|
||||
}
|
||||
|
||||
// trans->event_group and trans->wait_events will not be changed once trans is created, so we don't need protect them
|
||||
current_bits = xEventGroupWaitBits(trans->event_group, trans->wait_events | TRANSACTION_ABORT_EVENT,
|
||||
1, 0, wait_time/portTICK_RATE_MS);
|
||||
|
||||
xSemaphoreTakeRecursive(trans_mutex, portMAX_DELAY);
|
||||
trans->current_bits |= current_bits;
|
||||
|
||||
if (trans->current_bits == trans->wait_events) {
|
||||
// wait succeeded, we copy the trans->ret as ret of run transaction. This value could be changed by
|
||||
ret = trans->ret;
|
||||
xSemaphoreGiveRecursive(trans_mutex);
|
||||
break;
|
||||
} else if ( trans->current_bits & TRANSACTION_ABORT_EVENT ) {
|
||||
if ( trans->ret ) {
|
||||
// copy user defined ret value if it's set
|
||||
ret = trans->ret;
|
||||
} else {
|
||||
ret = TRANS_RET_ABORTED;
|
||||
}
|
||||
xSemaphoreGiveRecursive(trans_mutex);
|
||||
break;
|
||||
}
|
||||
xSemaphoreGiveRecursive(trans_mutex);
|
||||
}
|
||||
ESP_LOGD(TAG, "transaction run: %x, %x, %x; ret: %x", (uint32_t) trans, trans->type, trans->sub_type, ret);
|
||||
// reset after it's finished
|
||||
transaction_reset(trans);
|
||||
} else {
|
||||
ESP_LOGD(TAG, "transaction run: %x; ret: %x", (uint32_t) trans, ret);
|
||||
ret = TRANS_RET_INVALID_TRNSACTION;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
transaction_t *transaction_get(uint8_t type, uint32_t sub_type, transaction_t *start)
|
||||
{
|
||||
uint8_t i, start_index;
|
||||
transaction_t *trans = NULL;
|
||||
|
||||
if ( start == NULL ) {
|
||||
start_index = 0;
|
||||
} else {
|
||||
start_index = (start - transactions) + 1;
|
||||
}
|
||||
|
||||
xSemaphoreTakeRecursive(trans_mutex, portMAX_DELAY);
|
||||
for (i = start_index; i < MAX_TRANSACTION_COUNT; i++) {
|
||||
if ( transactions[i].state == TRANSACTION_ACTIVE ) {
|
||||
if ( (transactions[i].type == type) && (transactions[i].sub_type & sub_type) ) {
|
||||
trans = &transactions[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
xSemaphoreGiveRecursive(trans_mutex);
|
||||
|
||||
ESP_LOGV(TAG, "transaction get: %x, %x, %x, %x", type, sub_type, (uint32_t) start, (uint32_t) trans);
|
||||
return trans;
|
||||
}
|
||||
|
||||
void init_transactions(void)
|
||||
{
|
||||
uint8_t i;
|
||||
|
||||
ESP_LOGI(TAG, "init transactions");
|
||||
|
||||
trans_mutex = xSemaphoreCreateRecursiveMutex();
|
||||
|
||||
for (i = 0; i < MAX_TRANSACTION_COUNT; i++) {
|
||||
transactions[i].event_group = xEventGroupCreate();
|
||||
transaction_reset(&transactions[i]);
|
||||
}
|
||||
}
|
@ -0,0 +1,88 @@
|
||||
#ifndef __SSC_NIMBLE_TRANSACTION_H__
|
||||
#define __SSC_NIMBLE_TRANSACTION_H__
|
||||
|
||||
/* In esp-idf, bluetooth and wifi stack APIs are async (using callbacks).
|
||||
* transaction module provides a common method to let user transfer async APIs to sync transactions.
|
||||
*/
|
||||
|
||||
#include "sdkconfig.h"
|
||||
#include "esp_err.h"
|
||||
#include "freertos/event_groups.h"
|
||||
|
||||
#define MAX_TRANSACTION_COUNT 5
|
||||
|
||||
#define TRANSACTION_TYPE_ALL 0xFF
|
||||
|
||||
#define TRANSACTION_SUB_TYPE_ALL 0xFFFFFFFF
|
||||
|
||||
// The higher 12 bits of event is reversed for event group or transaction module.
|
||||
// Application can only use lower 20 bits of the event.
|
||||
#define TRANSACTION_TIMEOUT_EVENT 0x00100000UL // only wait for timeout
|
||||
#define TRANSACTION_ABORT_EVENT 0x00800000UL // this event is reserved for internal use only
|
||||
#define TRANSACTION_EVENT_MASK 0xFFF00000UL
|
||||
|
||||
|
||||
enum {
|
||||
TRANS_RET_ERROR_START = 0x10000,
|
||||
TRANS_RET_FAILED_TO_ALLOCATE,
|
||||
TRANS_RET_STATE_ERR,
|
||||
TRANS_RET_TEST_EVENT_FAILED,
|
||||
TRANS_RET_EVENTS_CONFLICT, // events bit conflicts with TRANSACTION_ABORT_EVENT
|
||||
TRANS_RET_INVALID_TRNSACTION,
|
||||
TRANS_RET_TIMEOUT,
|
||||
TRANS_RET_ABORTED
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
TRANSACTION_INACTIVE,
|
||||
TRANSACTION_ACTIVE,
|
||||
} transaction_state_t;
|
||||
|
||||
typedef struct {
|
||||
/* input data passed to callback */
|
||||
void *input;
|
||||
/* output data from callback */
|
||||
void *output;
|
||||
/* retrun value, can be set by callback or transaction module (like timeout, or other common errors)
|
||||
* transaction_run will return this member by default. */
|
||||
esp_err_t ret;
|
||||
// private member
|
||||
transaction_state_t state;
|
||||
uint8_t type;
|
||||
uint32_t sub_type;
|
||||
uint32_t timeout;
|
||||
EventBits_t wait_events;
|
||||
EventGroupHandle_t event_group;
|
||||
EventBits_t current_bits;
|
||||
} transaction_t;
|
||||
|
||||
|
||||
void init_transactions(void);
|
||||
|
||||
esp_err_t transaction_init(transaction_t **trans, uint8_t type, uint32_t sub_type, EventBits_t wait_events, uint32_t timeout, void *input, void *output);
|
||||
esp_err_t transaction_run(transaction_t *trans);
|
||||
|
||||
transaction_t *transaction_get(uint8_t type, uint32_t sub_type, transaction_t *start);
|
||||
|
||||
esp_err_t transaction_set_events(transaction_t *trans, EventBits_t events);
|
||||
esp_err_t transaction_test_events(transaction_t *trans, EventBits_t events);
|
||||
esp_err_t transaction_clear_events(transaction_t *trans, EventBits_t events);
|
||||
|
||||
esp_err_t transaction_abort(transaction_t *trans, esp_err_t reason);
|
||||
|
||||
#define TRANSACTION_INIT(trans, type, sub_type, wait_events, timeout, input, output) \
|
||||
ESP_ERROR_CHECK(transaction_init(trans, type, sub_type, wait_events, timeout, input, output))
|
||||
|
||||
|
||||
#define transaction_get_first(type, sub_type) transaction_get(type, sub_type, NULL)
|
||||
|
||||
|
||||
/* We declare all transaction type / sub type below */
|
||||
#define TRANS_TYPE_BLE_GAP 0x01
|
||||
#define TRANS_TYPE_BLE_GATTC 0x02
|
||||
#define TRANS_TYPE_BLE_GATTS 0x03
|
||||
#define TRANS_TYPE_WIFI 0x04
|
||||
#define TRANS_TYPE_BT 0x05
|
||||
|
||||
|
||||
#endif /* __SSC_NIMBLE_TRANSACTION_H__ */
|
@ -15,7 +15,11 @@ CONFIG_BLE_MESH_PROVISIONER=y
|
||||
CONFIG_BLE_MESH_PB_GATT=y
|
||||
CONFIG_BLE_MESH_PBA_SAME_TIME=10
|
||||
CONFIG_BLE_MESH_PBG_SAME_TIME=3
|
||||
CONFIG_BLE_MESH_TX_SEG_MSG_COUNT=10
|
||||
CONFIG_BLE_MESH_RX_SEG_MSG_COUNT=10
|
||||
CONFIG_BLE_MESH_TX_SEG_MSG_COUNT=3
|
||||
CONFIG_BLE_MESH_RX_SEG_MSG_COUNT=3
|
||||
CONFIG_BLE_MESH_CFG_CLI=y
|
||||
CONFIG_BLE_MESH_GENERIC_ONOFF_CLI=y
|
||||
CONFIG_BLE_MESH_GENERIC_ONOFF_CLI=y
|
||||
CONFIG_BLE_MESH_MAX_STORED_NODES=40
|
||||
CONFIG_BLE_MESH_MSG_CACHE_SIZE=60
|
||||
CONFIG_BLE_MESH_ADV_BUF_COUNT=200
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user