diff --git a/examples/bluetooth/esp_ble_mesh/ble_mesh_client_model/main/ble_mesh_demo_main.c b/examples/bluetooth/esp_ble_mesh/ble_mesh_client_model/main/ble_mesh_demo_main.c deleted file mode 100644 index e54637bcb..000000000 --- a/examples/bluetooth/esp_ble_mesh/ble_mesh_client_model/main/ble_mesh_demo_main.c +++ /dev/null @@ -1,496 +0,0 @@ -/* main.c - Application main entry point */ - -/* - * Copyright (c) 2017 Intel Corporation - * Additional Copyright (c) 2018 Espressif Systems (Shanghai) PTE LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include - -#include "esp_log.h" -#include "nvs_flash.h" - -#include "esp_ble_mesh_common_api.h" -#include "esp_ble_mesh_provisioning_api.h" -#include "esp_ble_mesh_networking_api.h" -#include "esp_ble_mesh_config_model_api.h" -#include "esp_ble_mesh_generic_model_api.h" - -#include "board.h" -#include "ble_mesh_demo_init.h" - -#define CID_ESP 0x02E5 - -#define MSG_SEND_TTL 3 -#define MSG_SEND_REL false -#define MSG_TIMEOUT 0 /* 0 indicates that timeout value from menuconfig will be used */ -#define MSG_ROLE ROLE_NODE - -extern struct _led_state led_state[3]; - -static uint8_t dev_uuid[16] = { 0xdd, 0xdd }; -static uint16_t node_net_idx = ESP_BLE_MESH_KEY_UNUSED; -static uint16_t node_app_idx = ESP_BLE_MESH_KEY_UNUSED; -static uint8_t remote_onoff = LED_OFF; - -/* The remote node address shall be input through UART1, see board.c */ -uint16_t remote_addr = ESP_BLE_MESH_ADDR_UNASSIGNED; - -static esp_ble_mesh_client_t onoff_client; - -static esp_ble_mesh_cfg_srv_t config_server = { - .relay = ESP_BLE_MESH_RELAY_DISABLED, - .beacon = ESP_BLE_MESH_BEACON_ENABLED, -#if defined(CONFIG_BLE_MESH_FRIEND) - .friend_state = ESP_BLE_MESH_FRIEND_ENABLED, -#else - .friend_state = ESP_BLE_MESH_FRIEND_NOT_SUPPORTED, -#endif -#if defined(CONFIG_BLE_MESH_GATT_PROXY_SERVER) - .gatt_proxy = ESP_BLE_MESH_GATT_PROXY_ENABLED, -#else - .gatt_proxy = ESP_BLE_MESH_GATT_PROXY_NOT_SUPPORTED, -#endif - .default_ttl = 7, - - /* 3 transmissions with 20ms interval */ - .net_transmit = ESP_BLE_MESH_TRANSMIT(2, 20), - .relay_retransmit = ESP_BLE_MESH_TRANSMIT(2, 20), -}; - -ESP_BLE_MESH_MODEL_PUB_DEFINE(onoff_srv_pub, 2 + 1, MSG_ROLE); -ESP_BLE_MESH_MODEL_PUB_DEFINE(onoff_cli_pub, 2 + 1, MSG_ROLE); - -static esp_ble_mesh_model_op_t onoff_op[] = { - 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), - /* Each model operation struct array must use this terminator - * as the end tag of the operation uint. */ - ESP_BLE_MESH_MODEL_OP_END, -}; - -static esp_ble_mesh_model_t root_models[] = { - ESP_BLE_MESH_MODEL_CFG_SRV(&config_server), - ESP_BLE_MESH_SIG_MODEL(ESP_BLE_MESH_MODEL_ID_GEN_ONOFF_SRV, onoff_op, - &onoff_srv_pub, &led_state[0]), - ESP_BLE_MESH_MODEL_GEN_ONOFF_CLI(&onoff_cli_pub, &onoff_client), -}; - -static esp_ble_mesh_elem_t elements[] = { - ESP_BLE_MESH_ELEMENT(0, root_models, ESP_BLE_MESH_MODEL_NONE), -}; - -static esp_ble_mesh_comp_t composition = { - .cid = CID_ESP, - .elements = elements, - .element_count = ARRAY_SIZE(elements), -}; - -/* Disable OOB security for SILabs Android app */ -static esp_ble_mesh_prov_t provision = { - .uuid = dev_uuid, -#if 0 - .output_size = 4, - .output_actions = ESP_BLE_MESH_DISPLAY_NUMBER, - .input_actions = ESP_BLE_MESH_PUSH, - .input_size = 4, -#else - .output_size = 0, - .output_actions = 0, -#endif -}; - -static int output_number(esp_ble_mesh_output_action_t action, uint32_t number) -{ - board_output_number(action, number); - return 0; -} - -static void prov_complete(uint16_t net_idx, uint16_t addr, uint8_t flags, uint32_t iv_index) -{ - ESP_LOGI(TAG, "net_idx: 0x%04x, addr: 0x%04x", net_idx, addr); - ESP_LOGI(TAG, "flags: 0x%02x, iv_index: 0x%08x", flags, iv_index); - board_prov_complete(); - node_net_idx = net_idx; -} - -static void gen_onoff_get_handler(esp_ble_mesh_model_t *model, - esp_ble_mesh_msg_ctx_t *ctx, - uint16_t length, uint8_t *data) -{ - struct _led_state *led = (struct _led_state *)model->user_data; - uint8_t send_data; - esp_err_t err; - - ESP_LOGI(TAG, "%s, addr 0x%04x onoff 0x%02x", __func__, model->element->element_addr, led->current); - - send_data = led->current; - /* Send Generic OnOff Status as a response to Generic OnOff Get */ - err = esp_ble_mesh_server_model_send_msg(model, ctx, ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_STATUS, - sizeof(send_data), &send_data); - if (err != ESP_OK) { - ESP_LOGE(TAG, "%s: Generic OnOff Status failed", __func__); - return; - } -} - -static void gen_onoff_set_unack_handler(esp_ble_mesh_model_t *model, - esp_ble_mesh_msg_ctx_t *ctx, - uint16_t length, uint8_t *data) -{ - struct _led_state *led = (struct _led_state *)model->user_data; - uint8_t prev_onoff; - esp_err_t err; - - prev_onoff = led->previous; - led->current = data[0]; - remote_onoff = led->current; - - ESP_LOGI(TAG, "%s, addr 0x%04x onoff 0x%02x", __func__, model->element->element_addr, led->current); - - board_led_operation(led->pin, led->current); - - /* If Generic OnOff state is changed, and the publish address of Generic OnOff Server - * model is valid, Generic OnOff Status will be published. - */ - if (prev_onoff != led->current && model->pub->publish_addr != ESP_BLE_MESH_ADDR_UNASSIGNED) { - ESP_LOGI(TAG, "Publish previous 0x%02x current 0x%02x", prev_onoff, led->current); - err = esp_ble_mesh_model_publish(model, ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_STATUS, - sizeof(led->current), &led->current, ROLE_NODE); - if (err != ESP_OK) { - ESP_LOGE(TAG, "%s: Publish Generic OnOff Status failed", __func__); - return; - } - } -} - -static void gen_onoff_set_handler(esp_ble_mesh_model_t *model, - esp_ble_mesh_msg_ctx_t *ctx, - uint16_t length, uint8_t *data) -{ - struct net_buf_simple *msg = model->pub->msg; - struct _led_state *led = (struct _led_state *)model->user_data; - uint8_t prev_onoff, send_data; - esp_err_t err; - - prev_onoff = led->previous; - led->current = data[0]; - remote_onoff = led->current; - - ESP_LOGI(TAG, "%s, addr 0x%04x onoff 0x%02x", __func__, model->element->element_addr, led->current); - - board_led_operation(led->pin, led->current); - - send_data = led->current; - /* Send Generic OnOff Status as a response to Generic OnOff Get */ - err = esp_ble_mesh_server_model_send_msg(model, ctx, ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_STATUS, - sizeof(send_data), &send_data); - if (err != ESP_OK) { - ESP_LOGE(TAG, "%s: Generic OnOff Status failed", __func__); - return; - } - - /* If Generic OnOff state is changed, and the publish address of Generic OnOff Server - * model is valid, Generic OnOff Status will be published. - */ - if (prev_onoff != led->current && model->pub->publish_addr != ESP_BLE_MESH_ADDR_UNASSIGNED) { - ESP_LOGI(TAG, "Publish previous 0x%02x current 0x%02x", prev_onoff, led->current); - bt_mesh_model_msg_init(msg, ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_STATUS); - err = esp_ble_mesh_model_publish(model, ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_STATUS, - sizeof(send_data), &send_data, ROLE_NODE); - if (err != ESP_OK) { - ESP_LOGE(TAG, "%s: Publish Generic OnOff Status failed", __func__); - return; - } - } -} - -static char *esp_ble_mesh_prov_event_to_str(esp_ble_mesh_prov_cb_event_t event) -{ - switch (event) { - case ESP_BLE_MESH_PROV_REGISTER_COMP_EVT: - return "ESP_BLE_MESH_PROV_REGISTER_COMP_EVT"; - case ESP_BLE_MESH_NODE_PROV_ENABLE_COMP_EVT: - return "ESP_BLE_MESH_NODE_PROV_ENABLE_COMP_EVT"; - case ESP_BLE_MESH_NODE_PROV_LINK_OPEN_EVT: - return "ESP_BLE_MESH_NODE_PROV_LINK_OPEN_EVT"; - case ESP_BLE_MESH_NODE_PROV_LINK_CLOSE_EVT: - return "ESP_BLE_MESH_NODE_PROV_LINK_CLOSE_EVT"; - case ESP_BLE_MESH_NODE_PROV_OUTPUT_NUMBER_EVT: - return "ESP_BLE_MESH_NODE_PROV_OUTPUT_NUMBER_EVT"; - case ESP_BLE_MESH_NODE_PROV_OUTPUT_STRING_EVT: - return "ESP_BLE_MESH_NODE_PROV_OUTPUT_STRING_EVT"; - case ESP_BLE_MESH_NODE_PROV_INPUT_EVT: - return "ESP_BLE_MESH_NODE_PROV_INPUT_EVT"; - case ESP_BLE_MESH_NODE_PROV_COMPLETE_EVT: - return "ESP_BLE_MESH_NODE_PROV_COMPLETE_EVT"; - case ESP_BLE_MESH_NODE_PROV_RESET_EVT: - return "ESP_BLE_MESH_NODE_PROV_RESET_EVT"; - default: - return "Invalid BLE Mesh provision event"; - } - - return NULL; -} - -static void esp_ble_mesh_prov_cb(esp_ble_mesh_prov_cb_event_t event, - esp_ble_mesh_prov_cb_param_t *param) -{ - ESP_LOGI(TAG, "%s, event = %s", __func__, esp_ble_mesh_prov_event_to_str(event)); - - switch (event) { - case ESP_BLE_MESH_PROV_REGISTER_COMP_EVT: - ESP_LOGI(TAG, "ESP_BLE_MESH_PROV_REGISTER_COMP_EVT, err_code %d", param->prov_register_comp.err_code); - break; - case ESP_BLE_MESH_NODE_PROV_ENABLE_COMP_EVT: - ESP_LOGI(TAG, "ESP_BLE_MESH_NODE_PROV_ENABLE_COMP_EVT, err_code %d", param->node_prov_enable_comp.err_code); - break; - case ESP_BLE_MESH_NODE_PROV_LINK_OPEN_EVT: - ESP_LOGI(TAG, "ESP_BLE_MESH_NODE_PROV_LINK_OPEN_EVT, bearer %s", - param->node_prov_link_open.bearer == ESP_BLE_MESH_PROV_ADV ? "PB-ADV" : "PB-GATT"); - break; - case ESP_BLE_MESH_NODE_PROV_LINK_CLOSE_EVT: - ESP_LOGI(TAG, "ESP_BLE_MESH_NODE_PROV_LINK_CLOSE_EVT, bearer %s", - param->node_prov_link_close.bearer == ESP_BLE_MESH_PROV_ADV ? "PB-ADV" : "PB-GATT"); - break; - case ESP_BLE_MESH_NODE_PROV_OUTPUT_NUMBER_EVT: - output_number(param->node_prov_output_num.action, param->node_prov_output_num.number); - break; - case ESP_BLE_MESH_NODE_PROV_OUTPUT_STRING_EVT: - break; - case ESP_BLE_MESH_NODE_PROV_INPUT_EVT: - break; - case ESP_BLE_MESH_NODE_PROV_COMPLETE_EVT: - prov_complete(param->node_prov_complete.net_idx, param->node_prov_complete.addr, - param->node_prov_complete.flags, param->node_prov_complete.iv_index); - break; - case ESP_BLE_MESH_NODE_PROV_RESET_EVT: - break; - case ESP_BLE_MESH_NODE_SET_UNPROV_DEV_NAME_COMP_EVT: - ESP_LOGI(TAG, "ESP_BLE_MESH_NODE_SET_UNPROV_DEV_NAME_COMP_EVT, err_code %d", param->node_set_unprov_dev_name_comp.err_code); - break; - default: - break; - } - - return; -} - -static esp_err_t esp_ble_mesh_set_msg_common(esp_ble_mesh_client_common_param_t *common, - esp_ble_mesh_generic_client_set_state_t *set, - esp_ble_mesh_model_t *model, uint32_t opcode, - uint8_t onoff) -{ - if (!common || !set || !model) { - return ESP_ERR_INVALID_ARG; - } - - common->opcode = opcode; - common->model = model; - common->ctx.net_idx = node_net_idx; - common->ctx.app_idx = node_app_idx; - common->ctx.addr = remote_addr; - common->ctx.send_ttl = MSG_SEND_TTL; - common->ctx.send_rel = MSG_SEND_REL; - common->msg_timeout = MSG_TIMEOUT; - common->msg_role = MSG_ROLE; - set->onoff_set.op_en = false; - set->onoff_set.onoff = onoff; - set->onoff_set.tid = 0x0; - - return ESP_OK; -} - - -static void esp_ble_mesh_model_cb(esp_ble_mesh_model_cb_event_t event, - esp_ble_mesh_model_cb_param_t *param) -{ - esp_ble_mesh_client_common_param_t common = {0}; - int err; - - switch (event) { - case ESP_BLE_MESH_MODEL_OPERATION_EVT: { - if (!param->model_operation.model || !param->model_operation.model->op || !param->model_operation.ctx) { - ESP_LOGE(TAG, "ESP_BLE_MESH_MODEL_OPERATION_EVT parameter is NULL"); - return; - } - if (node_app_idx == ESP_BLE_MESH_KEY_UNUSED) { - /* Generic OnOff Server/Client Models need to bind with the same app key */ - node_app_idx = param->model_operation.ctx->app_idx; - } - switch (param->model_operation.opcode) { - case ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_GET: - gen_onoff_get_handler(param->model_operation.model, param->model_operation.ctx, - param->model_operation.length, param->model_operation.msg); - break; - case ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_SET: { - esp_ble_mesh_generic_client_set_state_t set_state = {0}; - gen_onoff_set_handler(param->model_operation.model, param->model_operation.ctx, - param->model_operation.length, param->model_operation.msg); - /* This node has a Generic OnOff Client and Server Model. - * When Generic OnOff Server Model receives a Generic OnOff Set message, after - * this message is been handled, the Generic OnOff Client Model will send the - * Generic OnOff Set message to another node(contains Generic OnOff Server Model) - * identified by the remote_addr. - */ - esp_ble_mesh_set_msg_common(&common, &set_state, onoff_client.model, - ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_SET, remote_onoff); - err = esp_ble_mesh_generic_client_set_state(&common, &set_state); - if (err != ESP_OK) { - ESP_LOGE(TAG, "%s: Generic OnOff Set failed", __func__); - return; - } - break; - } - case ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_SET_UNACK: { - esp_ble_mesh_generic_client_set_state_t set_state = {0}; - gen_onoff_set_unack_handler(param->model_operation.model, param->model_operation.ctx, - param->model_operation.length, param->model_operation.msg); - /* This node has a Generic OnOff Client and Server Model. - * When Generic OnOff Client Model receives a Generic OnOff Set Unack message, - * after this message is been handled, the Generic OnOff Client Model will send - * the Generic OnOff Set Unack message to another node(contains Generic OnOff - * Server Model) identified by the remote_addr. - */ - esp_ble_mesh_set_msg_common(&common, &set_state, onoff_client.model, - ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_SET_UNACK, remote_onoff); - err = esp_ble_mesh_generic_client_set_state(&common, &set_state); - if (err != ESP_OK) { - ESP_LOGE(TAG, "%s: Generic OnOff Set Unack failed", __func__); - return; - } - break; - } - default: - break; - } - break; - } - case ESP_BLE_MESH_MODEL_SEND_COMP_EVT: - break; - case ESP_BLE_MESH_MODEL_PUBLISH_COMP_EVT: - break; - default: - break; - } - return; -} - -static void esp_ble_mesh_generic_cb(esp_ble_mesh_generic_client_cb_event_t event, - esp_ble_mesh_generic_client_cb_param_t *param) -{ - uint32_t opcode; - int err; - - ESP_LOGI(TAG, "%s: event is %d, error code is %d, opcode is 0x%x", - __func__, event, param->error_code, param->params->opcode); - - opcode = param->params->opcode; - - switch (event) { - case ESP_BLE_MESH_GENERIC_CLIENT_GET_STATE_EVT: - ESP_LOGI(TAG, "ESP_BLE_MESH_GENERIC_CLIENT_GET_STATE_EVT"); - switch (opcode) { - case ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_GET: - ESP_LOGI(TAG, "ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_GET: onoff %d", param->status_cb.onoff_status.present_onoff); - break; - default: - break; - } - break; - case ESP_BLE_MESH_GENERIC_CLIENT_SET_STATE_EVT: - ESP_LOGI(TAG, "ESP_BLE_MESH_GENERIC_CLIENT_SET_STATE_EVT"); - switch (opcode) { - case ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_SET: - ESP_LOGI(TAG, "ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_SET: onoff %d", param->status_cb.onoff_status.present_onoff); - break; - default: - break; - } - break; - case ESP_BLE_MESH_GENERIC_CLIENT_PUBLISH_EVT: - ESP_LOGI(TAG, "ESP_BLE_MESH_GENERIC_CLIENT_PUBLISH_EVT"); - break; - case ESP_BLE_MESH_GENERIC_CLIENT_TIMEOUT_EVT: { - ESP_LOGI(TAG, "ESP_BLE_MESH_GENERIC_CLIENT_TIMEOUT_EVT"); - switch (opcode) { - case ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_SET: { - esp_ble_mesh_client_common_param_t common = {0}; - esp_ble_mesh_generic_client_set_state_t set_state = {0}; - /* If failed to get the response of Generic OnOff Set, resend Generic OnOff Set */ - esp_ble_mesh_set_msg_common(&common, &set_state, onoff_client.model, - ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_SET, remote_onoff); - err = esp_ble_mesh_generic_client_set_state(&common, &set_state); - if (err != ESP_OK) { - ESP_LOGE(TAG, "%s: Generic OnOff Set failed", __func__); - return; - } - break; - } - default: - break; - } - break; - } - default: - break; - } - return; -} - -static int ble_mesh_init(void) -{ - int err = 0; - - esp_ble_mesh_register_prov_callback(esp_ble_mesh_prov_cb); - esp_ble_mesh_register_custom_model_callback(esp_ble_mesh_model_cb); - esp_ble_mesh_register_generic_client_callback(esp_ble_mesh_generic_cb); - - err = esp_ble_mesh_init(&provision, &composition); - if (err) { - ESP_LOGE(TAG, "Initializing mesh failed (err %d)", err); - return err; - } - - esp_ble_mesh_node_prov_enable(ESP_BLE_MESH_PROV_ADV | ESP_BLE_MESH_PROV_GATT); - - ESP_LOGI(TAG, "BLE Mesh Node initialized"); - - board_led_operation(LED_G, LED_ON); - - return err; -} - -void app_main(void) -{ - int err; - - ESP_LOGI(TAG, "Initializing..."); - - board_init(); - - err = nvs_flash_init(); - if (err == ESP_ERR_NVS_NO_FREE_PAGES) { - ESP_ERROR_CHECK(nvs_flash_erase()); - err = nvs_flash_init(); - } - ESP_ERROR_CHECK(err); - - err = bluetooth_init(); - if (err) { - ESP_LOGE(TAG, "esp32_bluetooth_init failed (err %d)", err); - return; - } - - ble_mesh_get_dev_uuid(dev_uuid); - - /* Initialize the Bluetooth Mesh Subsystem */ - err = ble_mesh_init(); - if (err) { - ESP_LOGE(TAG, "Bluetooth mesh init failed (err %d)", err); - } -} diff --git a/examples/bluetooth/esp_ble_mesh/ble_mesh_client_model/main/board.c b/examples/bluetooth/esp_ble_mesh/ble_mesh_client_model/main/board.c deleted file mode 100644 index d81bc5881..000000000 --- a/examples/bluetooth/esp_ble_mesh/ble_mesh_client_model/main/board.c +++ /dev/null @@ -1,115 +0,0 @@ -/* board.c - Board-specific hooks */ - -/* - * Copyright (c) 2017 Intel Corporation - * Additional Copyright (c) 2018 Espressif Systems (Shanghai) PTE LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include - -#include "freertos/FreeRTOS.h" -#include "freertos/task.h" -#include "freertos/event_groups.h" - -#include "driver/uart.h" -#include "esp_log.h" - -#include "esp_ble_mesh_provisioning_api.h" -#include "board.h" - -#define TAG "BOARD" - -#define MESH_UART_NUM UART_NUM_1 -#define MESH_UART (&UART1) - -#define UART_BUF_SIZE 128 - -#define UART1_TX_PIN GPIO_NUM_16 -#define UART1_RX_PIN GPIO_NUM_17 - -extern uint16_t remote_addr; - -struct _led_state led_state[3] = { - { LED_OFF, LED_OFF, LED_R, "red" }, - { LED_OFF, LED_OFF, LED_G, "green" }, - { LED_OFF, LED_OFF, LED_B, "blue" }, -}; - -void board_output_number(esp_ble_mesh_output_action_t action, uint32_t number) -{ - ESP_LOGI(TAG, "Board output number %d", number); -} - -void board_prov_complete(void) -{ - board_led_operation(LED_G, LED_OFF); -} - -void board_led_operation(uint8_t pin, uint8_t onoff) -{ - for (int i = 0; i < ARRAY_SIZE(led_state); i++) { - if (led_state[i].pin != pin) { - continue; - } - if (onoff == led_state[i].previous) { - ESP_LOGW(TAG, "led %s is already %s", - led_state[i].name, (onoff ? "on" : "off")); - return; - } - gpio_set_level(pin, onoff); - led_state[i].previous = onoff; - return; - } - ESP_LOGE(TAG, "LED is not found!"); -} - -static void board_uart_task(void *p) -{ - uint8_t *data = calloc(1, UART_BUF_SIZE); - uint32_t input; - - while (1) { - int len = uart_read_bytes(MESH_UART_NUM, data, UART_BUF_SIZE, 100 / portTICK_RATE_MS); - if (len > 0) { - input = strtoul((const char *)data, NULL, 16); - remote_addr = input & 0xFFFF; - ESP_LOGI(TAG, "%s: input 0x%08x, remote_addr 0x%04x", __func__, input, remote_addr); - memset(data, 0, UART_BUF_SIZE); - } - } - - vTaskDelete(NULL); -} - -static void board_led_init(void) -{ - for (int i = 0; i < ARRAY_SIZE(led_state); i++) { - gpio_pad_select_gpio(led_state[i].pin); - gpio_set_direction(led_state[i].pin, GPIO_MODE_OUTPUT); - gpio_set_level(led_state[i].pin, LED_OFF); - led_state[i].previous = LED_OFF; - } -} - -static void board_uart_init(void) -{ - uart_config_t uart_config = { - .baud_rate = 115200, - .data_bits = UART_DATA_8_BITS, - .parity = UART_PARITY_DISABLE, - .stop_bits = UART_STOP_BITS_1, - .flow_ctrl = UART_HW_FLOWCTRL_DISABLE - }; - uart_param_config(MESH_UART_NUM, &uart_config); - uart_set_pin(MESH_UART_NUM, UART1_TX_PIN, UART1_RX_PIN, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE); - uart_driver_install(MESH_UART_NUM, UART_BUF_SIZE * 2, 0, 0, NULL, 0); -} - -void board_init(void) -{ - board_led_init(); - board_uart_init(); - xTaskCreate(board_uart_task, "board_uart_task", 2048, NULL, 5, NULL); -} diff --git a/examples/bluetooth/esp_ble_mesh/ble_mesh_fast_provision/ble_mesh_fast_prov_client/main/ble_mesh_demo_main.c b/examples/bluetooth/esp_ble_mesh/ble_mesh_fast_provision/ble_mesh_fast_prov_client/main/ble_mesh_demo_main.c index 73f443227..27e93638d 100644 --- a/examples/bluetooth/esp_ble_mesh/ble_mesh_fast_provision/ble_mesh_fast_prov_client/main/ble_mesh_demo_main.c +++ b/examples/bluetooth/esp_ble_mesh/ble_mesh_fast_provision/ble_mesh_fast_prov_client/main/ble_mesh_demo_main.c @@ -574,7 +574,7 @@ static esp_err_t ble_mesh_init(void) void app_main(void) { - int err; + esp_err_t err; ESP_LOGI(TAG, "Initializing..."); diff --git a/examples/bluetooth/esp_ble_mesh/ble_mesh_fast_provision/ble_mesh_fast_prov_server/main/ble_mesh_demo_main.c b/examples/bluetooth/esp_ble_mesh/ble_mesh_fast_provision/ble_mesh_fast_prov_server/main/ble_mesh_demo_main.c index d701a042b..2bf300309 100644 --- a/examples/bluetooth/esp_ble_mesh/ble_mesh_fast_provision/ble_mesh_fast_prov_server/main/ble_mesh_demo_main.c +++ b/examples/bluetooth/esp_ble_mesh/ble_mesh_fast_provision/ble_mesh_fast_prov_server/main/ble_mesh_demo_main.c @@ -24,6 +24,7 @@ #include "esp_ble_mesh_provisioning_api.h" #include "esp_ble_mesh_config_model_api.h" #include "esp_ble_mesh_generic_model_api.h" +#include "esp_ble_mesh_local_data_operation_api.h" #include "board.h" #include "esp_fast_prov_operation.h" @@ -95,15 +96,12 @@ example_fast_prov_server_t fast_prov_server = { .state = STATE_IDLE, }; -static esp_ble_mesh_model_op_t onoff_op[] = { - 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, 2 + 3, ROLE_FAST_PROV); +static esp_ble_mesh_gen_onoff_srv_t onoff_server = { + .rsp_ctrl.get_auto_rsp = ESP_BLE_MESH_SERVER_AUTO_RSP, + .rsp_ctrl.set_auto_rsp = ESP_BLE_MESH_SERVER_AUTO_RSP, }; -ESP_BLE_MESH_MODEL_PUB_DEFINE(onoff_pub, 2 + 1, ROLE_FAST_PROV); - static esp_ble_mesh_model_op_t fast_prov_srv_op[] = { ESP_BLE_MESH_MODEL_OP(ESP_BLE_MESH_VND_MODEL_OP_FAST_PROV_INFO_SET, 3), ESP_BLE_MESH_MODEL_OP(ESP_BLE_MESH_VND_MODEL_OP_FAST_PROV_NET_KEY_ADD, 16), @@ -124,8 +122,7 @@ static esp_ble_mesh_model_op_t fast_prov_cli_op[] = { static esp_ble_mesh_model_t root_models[] = { ESP_BLE_MESH_MODEL_CFG_SRV(&config_server), ESP_BLE_MESH_MODEL_CFG_CLI(&config_client), - ESP_BLE_MESH_SIG_MODEL(ESP_BLE_MESH_MODEL_ID_GEN_ONOFF_SRV, onoff_op, - &onoff_pub, &led_state[1]), + ESP_BLE_MESH_MODEL_GEN_ONOFF_SRV(&onoff_pub, &onoff_server), }; static esp_ble_mesh_model_t vnd_models[] = { @@ -158,29 +155,11 @@ static esp_ble_mesh_prov_t prov = { .iv_index = 0x00, }; -static void gen_onoff_get_handler(esp_ble_mesh_model_t *model, - esp_ble_mesh_msg_ctx_t *ctx, - uint16_t len, uint8_t *data) +static void example_change_led_state(uint8_t onoff) { - struct _led_state *led = NULL; - uint8_t send_data; - esp_err_t err; + struct _led_state *led = &led_state[1]; - led = (struct _led_state *)model->user_data; - if (!led) { - ESP_LOGE(TAG, "%s: Failed to get generic onoff server model user_data", __func__); - return; - } - - send_data = led->current; - - /* Sends Generic OnOff Status as a reponse to Generic OnOff Get */ - err = esp_ble_mesh_server_model_send_msg(model, ctx, ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_STATUS, - sizeof(send_data), &send_data); - if (err != ESP_OK) { - ESP_LOGE(TAG, "%s: Failed to send Generic OnOff Status message", __func__); - return; - } + board_led_operation(led->pin, onoff); /* When the node receives the first Generic OnOff Get/Set/Set Unack message, it will * start the timer used to disable fast provisioning functionality. @@ -190,37 +169,6 @@ static void gen_onoff_get_handler(esp_ble_mesh_model_t *model, } } -static void gen_onoff_set_unack_handler(esp_ble_mesh_model_t *model, - esp_ble_mesh_msg_ctx_t *ctx, - uint16_t len, uint8_t *data) -{ - struct _led_state *led = NULL; - - led = (struct _led_state *)model->user_data; - if (!led) { - ESP_LOGE(TAG, "%s: Failed to get generic onoff server model user_data", __func__); - return; - } - - led->current = data[0]; - gpio_set_level(led->pin, led->current); - - /* When the node receives the first Generic OnOff Get/Set/Set Unack message, it will - * start the timer used to disable fast provisioning functionality. - */ - if (!bt_mesh_atomic_test_and_set_bit(fast_prov_server.srv_flags, DISABLE_FAST_PROV_START)) { - k_delayed_work_submit(&fast_prov_server.disable_fast_prov_timer, DISABLE_FAST_PROV_TIMEOUT); - } -} - -static void gen_onoff_set_handler(esp_ble_mesh_model_t *model, - esp_ble_mesh_msg_ctx_t *ctx, - uint16_t len, uint8_t *data) -{ - gen_onoff_set_unack_handler(model, ctx, len, data); - gen_onoff_get_handler(model, ctx, len, data); -} - static void node_prov_complete(uint16_t net_idx, uint16_t addr, uint8_t flags, uint32_t iv_index) { ESP_LOGI(TAG, "net_idx: 0x%04x, unicast_addr: 0x%04x", net_idx, addr); @@ -484,14 +432,6 @@ static void example_ble_mesh_custom_model_cb(esp_ble_mesh_model_cb_event_t event } opcode = param->model_operation.opcode; switch (opcode) { - case ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_SET: - gen_onoff_set_handler(param->model_operation.model, param->model_operation.ctx, - param->model_operation.length, param->model_operation.msg); - break; - case ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_SET_UNACK: - gen_onoff_set_unack_handler(param->model_operation.model, param->model_operation.ctx, - param->model_operation.length, param->model_operation.msg); - break; case ESP_BLE_MESH_VND_MODEL_OP_FAST_PROV_INFO_SET: case ESP_BLE_MESH_VND_MODEL_OP_FAST_PROV_NET_KEY_ADD: case ESP_BLE_MESH_VND_MODEL_OP_FAST_PROV_NODE_ADDR: @@ -724,6 +664,27 @@ static void example_ble_mesh_config_server_cb(esp_ble_mesh_cfg_server_cb_event_t } } +static void example_ble_mesh_generic_server_cb(esp_ble_mesh_generic_server_cb_event_t event, + esp_ble_mesh_generic_server_cb_param_t *param) +{ + ESP_LOGI(TAG, "event 0x%02x, opcode 0x%04x, src 0x%04x, dst 0x%04x", + event, param->ctx.recv_op, param->ctx.addr, param->ctx.recv_dst); + + switch (event) { + case ESP_BLE_MESH_GENERIC_SERVER_STATE_CHANGE_EVT: + ESP_LOGI(TAG, "ESP_BLE_MESH_GENERIC_SERVER_STATE_CHANGE_EVT"); + if (param->ctx.recv_op == ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_SET || + param->ctx.recv_op == ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_SET_UNACK) { + ESP_LOGI(TAG, "onoff 0x%02x", param->value.state_change.onoff_set.onoff); + example_change_led_state(param->value.state_change.onoff_set.onoff); + } + break; + default: + ESP_LOGW(TAG, "Unknown Generic Server event 0x%02x", event); + break; + } +} + static esp_err_t ble_mesh_init(void) { esp_err_t err; @@ -732,6 +693,7 @@ static esp_err_t ble_mesh_init(void) esp_ble_mesh_register_custom_model_callback(example_ble_mesh_custom_model_cb); esp_ble_mesh_register_config_client_callback(example_ble_mesh_config_client_cb); esp_ble_mesh_register_config_server_callback(example_ble_mesh_config_server_cb); + esp_ble_mesh_register_generic_server_callback(example_ble_mesh_generic_server_cb); err = esp_ble_mesh_init(&prov, &comp); if (err != ESP_OK) { diff --git a/examples/bluetooth/esp_ble_mesh/ble_mesh_node/main/ble_mesh_demo_main.c b/examples/bluetooth/esp_ble_mesh/ble_mesh_node/main/ble_mesh_demo_main.c deleted file mode 100644 index 27a53c3c3..000000000 --- a/examples/bluetooth/esp_ble_mesh/ble_mesh_node/main/ble_mesh_demo_main.c +++ /dev/null @@ -1,358 +0,0 @@ -/* main.c - Application main entry point */ - -/* - * Copyright (c) 2017 Intel Corporation - * Additional Copyright (c) 2018 Espressif Systems (Shanghai) PTE LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include - -#include "esp_log.h" -#include "nvs_flash.h" - -#include "esp_ble_mesh_defs.h" -#include "esp_ble_mesh_common_api.h" -#include "esp_ble_mesh_networking_api.h" -#include "esp_ble_mesh_provisioning_api.h" -#include "esp_ble_mesh_config_model_api.h" - -#include "board.h" -#include "ble_mesh_demo_init.h" - -#define CID_ESP 0x02E5 - -extern struct _led_state led_state[3]; - -static uint8_t dev_uuid[16] = { 0xdd, 0xdd }; - -static esp_ble_mesh_cfg_srv_t config_server = { - .relay = ESP_BLE_MESH_RELAY_DISABLED, - .beacon = ESP_BLE_MESH_BEACON_ENABLED, -#if defined(CONFIG_BLE_MESH_FRIEND) - .friend_state = ESP_BLE_MESH_FRIEND_ENABLED, -#else - .friend_state = ESP_BLE_MESH_FRIEND_NOT_SUPPORTED, -#endif -#if defined(CONFIG_BLE_MESH_GATT_PROXY_SERVER) - .gatt_proxy = ESP_BLE_MESH_GATT_PROXY_ENABLED, -#else - .gatt_proxy = ESP_BLE_MESH_GATT_PROXY_NOT_SUPPORTED, -#endif - .default_ttl = 7, - /* 3 transmissions with 20ms interval */ - .net_transmit = ESP_BLE_MESH_TRANSMIT(2, 20), - .relay_retransmit = ESP_BLE_MESH_TRANSMIT(2, 20), -}; - -ESP_BLE_MESH_MODEL_PUB_DEFINE(onoff_pub, 2 + 1, ROLE_NODE); - -static esp_ble_mesh_model_op_t onoff_op[] = { - 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), - /* Each model operation struct array must use this terminator - * as the end tag of the operation uint. */ - ESP_BLE_MESH_MODEL_OP_END, -}; - -static esp_ble_mesh_model_t root_models[] = { - ESP_BLE_MESH_MODEL_CFG_SRV(&config_server), - ESP_BLE_MESH_SIG_MODEL(ESP_BLE_MESH_MODEL_ID_GEN_ONOFF_SRV, onoff_op, - &onoff_pub, &led_state[0]), -}; - -static esp_ble_mesh_model_t extend_model_0[] = { - ESP_BLE_MESH_SIG_MODEL(ESP_BLE_MESH_MODEL_ID_GEN_ONOFF_SRV, onoff_op, - &onoff_pub, &led_state[1]), -}; - -static esp_ble_mesh_model_t extend_model_1[] = { - ESP_BLE_MESH_SIG_MODEL(ESP_BLE_MESH_MODEL_ID_GEN_ONOFF_SRV, onoff_op, - &onoff_pub, &led_state[2]), -}; - -static esp_ble_mesh_elem_t elements[] = { - ESP_BLE_MESH_ELEMENT(0, root_models, ESP_BLE_MESH_MODEL_NONE), - ESP_BLE_MESH_ELEMENT(0, extend_model_0, ESP_BLE_MESH_MODEL_NONE), - ESP_BLE_MESH_ELEMENT(0, extend_model_1, ESP_BLE_MESH_MODEL_NONE), -}; - -static esp_ble_mesh_comp_t composition = { - .cid = CID_ESP, - .elements = elements, - .element_count = ARRAY_SIZE(elements), -}; - -/* Disable OOB security for SILabs Android app */ -static esp_ble_mesh_prov_t provision = { - .uuid = dev_uuid, -#if 0 - .output_size = 4, - .output_actions = ESP_BLE_MESH_DISPLAY_NUMBER, - .input_actions = ESP_BLE_MESH_PUSH, - .input_size = 4, -#else - .output_size = 0, - .output_actions = 0, -#endif -}; - -static int output_number(esp_ble_mesh_output_action_t action, uint32_t number) -{ - board_output_number(action, number); - return 0; -} - -static void prov_complete(uint16_t net_idx, uint16_t addr, uint8_t flags, uint32_t iv_index) -{ - ESP_LOGI(TAG, "net_idx: 0x%04x, addr: 0x%04x", net_idx, addr); - ESP_LOGI(TAG, "flags: 0x%02x, iv_index: 0x%08x", flags, iv_index); - board_prov_complete(); -} - -static void gen_onoff_get_handler(esp_ble_mesh_model_t *model, - esp_ble_mesh_msg_ctx_t *ctx, - uint16_t length, uint8_t *data) -{ - struct _led_state *led = (struct _led_state *)model->user_data; - uint8_t send_data; - esp_err_t err; - - ESP_LOGI(TAG, "%s, addr 0x%04x onoff 0x%02x", __func__, model->element->element_addr, led->current); - - send_data = led->current; - /* Send Generic OnOff Status as a response to Generic OnOff Get */ - err = esp_ble_mesh_server_model_send_msg(model, ctx, ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_STATUS, - sizeof(send_data), &send_data); - if (err != ESP_OK) { - ESP_LOGE(TAG, "%s: Generic OnOff Status failed", __func__); - return; - } -} - -static void gen_onoff_set_unack_handler(esp_ble_mesh_model_t *model, - esp_ble_mesh_msg_ctx_t *ctx, - uint16_t length, uint8_t *data) -{ - struct _led_state *led = (struct _led_state *)model->user_data; - uint8_t prev_onoff; - esp_err_t err; - - prev_onoff = led->previous; - led->current = data[0]; - - ESP_LOGI(TAG, "%s, addr 0x%04x onoff 0x%02x", __func__, model->element->element_addr, led->current); - - board_led_operation(led->pin, led->current); - - /* If Generic OnOff state is changed, and the publish address of Generic OnOff Server - * model is valid, Generic OnOff Status will be published. - */ - if (prev_onoff != led->current && model->pub->publish_addr != ESP_BLE_MESH_ADDR_UNASSIGNED) { - ESP_LOGI(TAG, "Publish previous 0x%02x current 0x%02x", prev_onoff, led->current); - err = esp_ble_mesh_model_publish(model, ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_STATUS, - sizeof(led->current), &led->current, ROLE_NODE); - if (err != ESP_OK) { - ESP_LOGE(TAG, "%s: Publish Generic OnOff Status failed", __func__); - return; - } - } -} - -static void gen_onoff_set_handler(esp_ble_mesh_model_t *model, - esp_ble_mesh_msg_ctx_t *ctx, - uint16_t length, uint8_t *data) -{ - struct _led_state *led = (struct _led_state *)model->user_data; - uint8_t prev_onoff, send_data; - esp_err_t err; - - prev_onoff = led->previous; - led->current = data[0]; - - ESP_LOGI(TAG, "%s, addr 0x%04x onoff 0x%02x", __func__, model->element->element_addr, led->current); - - board_led_operation(led->pin, led->current); - - send_data = led->current; - /* Send Generic OnOff Status as a response to Generic OnOff Get */ - err = esp_ble_mesh_server_model_send_msg(model, ctx, ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_STATUS, - sizeof(send_data), &send_data); - if (err != ESP_OK) { - ESP_LOGE(TAG, "%s: Generic OnOff Status failed", __func__); - return; - } - - /* If Generic OnOff state is changed, and the publish address of Generic OnOff Server - * model is valid, Generic OnOff Status will be published. - */ - if (prev_onoff != led->current && model->pub->publish_addr != ESP_BLE_MESH_ADDR_UNASSIGNED) { - ESP_LOGI(TAG, "Publish previous 0x%02x current 0x%02x", prev_onoff, led->current); - err = esp_ble_mesh_model_publish(model, ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_STATUS, - sizeof(send_data), &send_data, ROLE_NODE); - if (err != ESP_OK) { - ESP_LOGE(TAG, "%s: Publish Generic OnOff Status failed", __func__); - return; - } - } -} - -static char *esp_ble_mesh_prov_event_to_str(esp_ble_mesh_prov_cb_event_t event) -{ - switch (event) { - case ESP_BLE_MESH_PROV_REGISTER_COMP_EVT: - return "ESP_BLE_MESH_PROV_REGISTER_COMP_EVT"; - case ESP_BLE_MESH_NODE_PROV_ENABLE_COMP_EVT: - return "ESP_BLE_MESH_NODE_PROV_ENABLE_COMP_EVT"; - case ESP_BLE_MESH_NODE_PROV_LINK_OPEN_EVT: - return "ESP_BLE_MESH_NODE_PROV_LINK_OPEN_EVT"; - case ESP_BLE_MESH_NODE_PROV_LINK_CLOSE_EVT: - return "ESP_BLE_MESH_NODE_PROV_LINK_CLOSE_EVT"; - case ESP_BLE_MESH_NODE_PROV_OUTPUT_NUMBER_EVT: - return "ESP_BLE_MESH_NODE_PROV_OUTPUT_NUMBER_EVT"; - case ESP_BLE_MESH_NODE_PROV_OUTPUT_STRING_EVT: - return "ESP_BLE_MESH_NODE_PROV_OUTPUT_STRING_EVT"; - case ESP_BLE_MESH_NODE_PROV_INPUT_EVT: - return "ESP_BLE_MESH_NODE_PROV_INPUT_EVT"; - case ESP_BLE_MESH_NODE_PROV_COMPLETE_EVT: - return "ESP_BLE_MESH_NODE_PROV_COMPLETE_EVT"; - case ESP_BLE_MESH_NODE_PROV_RESET_EVT: - return "ESP_BLE_MESH_NODE_PROV_RESET_EVT"; - default: - return "Invalid BLE Mesh provision event"; - } - - return NULL; -} - -static void esp_ble_mesh_prov_cb(esp_ble_mesh_prov_cb_event_t event, - esp_ble_mesh_prov_cb_param_t *param) -{ - ESP_LOGI(TAG, "%s, event = %s", __func__, esp_ble_mesh_prov_event_to_str(event)); - switch (event) { - case ESP_BLE_MESH_PROV_REGISTER_COMP_EVT: - ESP_LOGI(TAG, "ESP_BLE_MESH_PROV_REGISTER_COMP_EVT, err_code %d", param->prov_register_comp.err_code); - break; - case ESP_BLE_MESH_NODE_PROV_ENABLE_COMP_EVT: - ESP_LOGI(TAG, "ESP_BLE_MESH_NODE_PROV_ENABLE_COMP_EVT, err_code %d", param->node_prov_enable_comp.err_code); - break; - case ESP_BLE_MESH_NODE_PROV_LINK_OPEN_EVT: - ESP_LOGI(TAG, "ESP_BLE_MESH_NODE_PROV_LINK_OPEN_EVT, bearer %s", - param->node_prov_link_open.bearer == ESP_BLE_MESH_PROV_ADV ? "PB-ADV" : "PB-GATT"); - break; - case ESP_BLE_MESH_NODE_PROV_LINK_CLOSE_EVT: - ESP_LOGI(TAG, "ESP_BLE_MESH_NODE_PROV_LINK_CLOSE_EVT, bearer %s", - param->node_prov_link_close.bearer == ESP_BLE_MESH_PROV_ADV ? "PB-ADV" : "PB-GATT"); - break; - case ESP_BLE_MESH_NODE_PROV_OUTPUT_NUMBER_EVT: - output_number(param->node_prov_output_num.action, param->node_prov_output_num.number); - break; - case ESP_BLE_MESH_NODE_PROV_OUTPUT_STRING_EVT: - break; - case ESP_BLE_MESH_NODE_PROV_INPUT_EVT: - break; - case ESP_BLE_MESH_NODE_PROV_COMPLETE_EVT: - prov_complete(param->node_prov_complete.net_idx, param->node_prov_complete.addr, - param->node_prov_complete.flags, param->node_prov_complete.iv_index); - break; - case ESP_BLE_MESH_NODE_PROV_RESET_EVT: - break; - case ESP_BLE_MESH_NODE_SET_UNPROV_DEV_NAME_COMP_EVT: - ESP_LOGI(TAG, "ESP_BLE_MESH_NODE_SET_UNPROV_DEV_NAME_COMP_EVT, err_code %d", param->node_set_unprov_dev_name_comp.err_code); - break; - default: - break; - } - return; -} - -static void esp_ble_mesh_model_cb(esp_ble_mesh_model_cb_event_t event, - esp_ble_mesh_model_cb_param_t *param) -{ - switch (event) { - case ESP_BLE_MESH_MODEL_OPERATION_EVT: { - if (!param->model_operation.model || !param->model_operation.model->op || !param->model_operation.ctx) { - ESP_LOGE(TAG, "ESP_BLE_MESH_MODEL_OPERATION_EVT parameter is NULL"); - return; - } - switch (param->model_operation.opcode) { - case ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_GET: - gen_onoff_get_handler(param->model_operation.model, param->model_operation.ctx, - param->model_operation.length, param->model_operation.msg); - break; - case ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_SET: - gen_onoff_set_handler(param->model_operation.model, param->model_operation.ctx, - param->model_operation.length, param->model_operation.msg); - break; - case ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_SET_UNACK: - gen_onoff_set_unack_handler(param->model_operation.model, param->model_operation.ctx, - param->model_operation.length, param->model_operation.msg); - break; - default: - break; - } - break; - } - case ESP_BLE_MESH_MODEL_SEND_COMP_EVT: - break; - case ESP_BLE_MESH_MODEL_PUBLISH_COMP_EVT: - break; - default: - break; - } -} - -static esp_err_t ble_mesh_init(void) -{ - int err = 0; - - esp_ble_mesh_register_prov_callback(esp_ble_mesh_prov_cb); - esp_ble_mesh_register_custom_model_callback(esp_ble_mesh_model_cb); - - err = esp_ble_mesh_init(&provision, &composition); - if (err) { - ESP_LOGE(TAG, "Initializing mesh failed (err %d)", err); - return err; - } - - esp_ble_mesh_node_prov_enable(ESP_BLE_MESH_PROV_ADV | ESP_BLE_MESH_PROV_GATT); - - ESP_LOGI(TAG, "BLE Mesh Node initialized"); - - board_led_operation(LED_G, LED_ON); - - return err; -} - -void app_main(void) -{ - int err; - - ESP_LOGI(TAG, "Initializing..."); - - board_init(); - - err = nvs_flash_init(); - if (err == ESP_ERR_NVS_NO_FREE_PAGES) { - ESP_ERROR_CHECK(nvs_flash_erase()); - err = nvs_flash_init(); - } - ESP_ERROR_CHECK(err); - - err = bluetooth_init(); - if (err) { - ESP_LOGE(TAG, "esp32_bluetooth_init failed (err %d)", err); - return; - } - - ble_mesh_get_dev_uuid(dev_uuid); - - /* Initialize the Bluetooth Mesh Subsystem */ - err = ble_mesh_init(); - if (err) { - ESP_LOGE(TAG, "Bluetooth mesh init failed (err %d)", err); - } -} diff --git a/examples/bluetooth/esp_ble_mesh/ble_mesh_node/main/board.c b/examples/bluetooth/esp_ble_mesh/ble_mesh_node/main/board.c deleted file mode 100644 index 50035a7dd..000000000 --- a/examples/bluetooth/esp_ble_mesh/ble_mesh_node/main/board.c +++ /dev/null @@ -1,130 +0,0 @@ -/* board.c - Board-specific hooks */ - -/* - * Copyright (c) 2017 Intel Corporation - * Additional Copyright (c) 2018 Espressif Systems (Shanghai) PTE LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include - -#include "freertos/FreeRTOS.h" -#include "freertos/task.h" -#include "freertos/event_groups.h" - -#include "driver/gpio.h" -#include "esp_log.h" -#include "board.h" -#include "esp_ble_mesh_provisioning_api.h" - -#define TAG "BOARD" - -#define INTR_FLAG_DEFAULT 0 - -static xQueueHandle s_evt_queue; - -struct _led_state led_state[3] = { - { LED_OFF, LED_OFF, LED_R, "red" }, - { LED_OFF, LED_OFF, LED_G, "green" }, - { LED_OFF, LED_OFF, LED_B, "blue" }, -}; - -void board_output_number(esp_ble_mesh_output_action_t action, uint32_t number) -{ - ESP_LOGI(TAG, "Board output number %d", number); -} - -void board_prov_complete(void) -{ - board_led_operation(LED_G, LED_OFF); -} - -void board_led_operation(uint8_t pin, uint8_t onoff) -{ - for (int i = 0; i < 3; i++) { - if (led_state[i].pin != pin) { - continue; - } - if (onoff == led_state[i].previous) { - ESP_LOGW(TAG, "led %s is already %s", - led_state[i].name, (onoff ? "on" : "off")); - return; - } - gpio_set_level(pin, onoff); - led_state[i].previous = onoff; - return; - } - - ESP_LOGE(TAG, "LED is not found!"); -} - -static void board_led_init(void) -{ - for (int i = 0; i < 3; i++) { - gpio_pad_select_gpio(led_state[i].pin); - gpio_set_direction(led_state[i].pin, GPIO_MODE_OUTPUT); - gpio_set_level(led_state[i].pin, LED_OFF); - led_state[i].previous = LED_OFF; - } -} - -static void IRAM_ATTR switch_isr_handler(void *arg) -{ - uint32_t gpio_num = (uint32_t) arg; - xQueueSendFromISR(s_evt_queue, &gpio_num, NULL); -} - -static void switch_key_init(uint32_t key) -{ - gpio_config_t io_conf; - io_conf.intr_type = GPIO_INTR_NEGEDGE; - io_conf.pin_bit_mask = 1 << key; - io_conf.mode = GPIO_MODE_INPUT; - io_conf.pull_up_en = 1; - io_conf.pull_down_en = 0; - gpio_config(&io_conf); - - gpio_set_intr_type(key, GPIO_INTR_NEGEDGE); - gpio_install_isr_service(INTR_FLAG_DEFAULT); - gpio_isr_handler_add(key, switch_isr_handler, (void *)key); -} - -static void switch_task_entry(void *arg) -{ - while (1) { - uint32_t io_num; - if (xQueueReceive(s_evt_queue, &io_num, portMAX_DELAY) == pdTRUE) { - uint8_t onoff = led_state[0].previous; - ESP_LOGI(TAG, "GPIO[%d] intr, val: %d", io_num, gpio_get_level(io_num)); - board_led_operation(LED_R, !onoff); - led_state[0].previous = !onoff; - //TODO: publish state change message - } - } -} - -static void switch_init(gpio_num_t gpio_num) -{ - s_evt_queue = xQueueCreate(3, sizeof(uint32_t)); - if (!s_evt_queue) { - return; - } - - BaseType_t ret = xTaskCreate(switch_task_entry, "switch", 4096, NULL, 4, NULL); - if (ret == pdFAIL) { - goto fail; - } - - switch_key_init(gpio_num); - return; - -fail: - vQueueDelete(s_evt_queue); -} - -void board_init(void) -{ - board_led_init(); - switch_init(GPIO_NUM_18); -} diff --git a/examples/bluetooth/esp_ble_mesh/ble_mesh_node/CMakeLists.txt b/examples/bluetooth/esp_ble_mesh/ble_mesh_node/onoff_client/CMakeLists.txt similarity index 91% rename from examples/bluetooth/esp_ble_mesh/ble_mesh_node/CMakeLists.txt rename to examples/bluetooth/esp_ble_mesh/ble_mesh_node/onoff_client/CMakeLists.txt index 6dd367153..d42dfe18f 100644 --- a/examples/bluetooth/esp_ble_mesh/ble_mesh_node/CMakeLists.txt +++ b/examples/bluetooth/esp_ble_mesh/ble_mesh_node/onoff_client/CMakeLists.txt @@ -4,4 +4,4 @@ cmake_minimum_required(VERSION 3.5) include($ENV{IDF_PATH}/tools/cmake/project.cmake) set(SUPPORTED_TARGETS esp32) -project(ble_mesh_node) +project(onoff_client) diff --git a/examples/bluetooth/esp_ble_mesh/ble_mesh_node/Makefile b/examples/bluetooth/esp_ble_mesh/ble_mesh_node/onoff_client/Makefile similarity index 87% rename from examples/bluetooth/esp_ble_mesh/ble_mesh_node/Makefile rename to examples/bluetooth/esp_ble_mesh/ble_mesh_node/onoff_client/Makefile index 87313e4ab..a47e6fd08 100644 --- a/examples/bluetooth/esp_ble_mesh/ble_mesh_node/Makefile +++ b/examples/bluetooth/esp_ble_mesh/ble_mesh_node/onoff_client/Makefile @@ -3,7 +3,7 @@ # project subdirectory. # -PROJECT_NAME := ble_mesh_node +PROJECT_NAME := onoff_client COMPONENT_ADD_INCLUDEDIRS := components/include diff --git a/examples/bluetooth/esp_ble_mesh/ble_mesh_client_model/README.md b/examples/bluetooth/esp_ble_mesh/ble_mesh_node/onoff_client/README.md similarity index 100% rename from examples/bluetooth/esp_ble_mesh/ble_mesh_client_model/README.md rename to examples/bluetooth/esp_ble_mesh/ble_mesh_node/onoff_client/README.md diff --git a/examples/bluetooth/esp_ble_mesh/ble_mesh_node/onoff_client/components/button/CMakeLists.txt b/examples/bluetooth/esp_ble_mesh/ble_mesh_node/onoff_client/components/button/CMakeLists.txt new file mode 100644 index 000000000..6c385ee21 --- /dev/null +++ b/examples/bluetooth/esp_ble_mesh/ble_mesh_node/onoff_client/components/button/CMakeLists.txt @@ -0,0 +1,7 @@ + +set(COMPONENT_SRCS "button.c" + "button_obj.cpp") + +set(COMPONENT_ADD_INCLUDEDIRS ". include") + +register_component() diff --git a/examples/bluetooth/esp_ble_mesh/ble_mesh_node/onoff_client/components/button/Kconfig b/examples/bluetooth/esp_ble_mesh/ble_mesh_node/onoff_client/components/button/Kconfig new file mode 100644 index 000000000..308410a69 --- /dev/null +++ b/examples/bluetooth/esp_ble_mesh/ble_mesh_node/onoff_client/components/button/Kconfig @@ -0,0 +1,21 @@ +menu "Button" + + choice BUTTON_TIMER_IMPLEMENT + bool "Button Timer Mode" + default BUTTON_USE_ESP_TIMER + help + Choose a implementation of timer for button instance. + + config BUTTON_USE_RTOS_TIMER + bool "Use FreeRTOS Timer" + + config BUTTON_USE_ESP_TIMER + bool "Use ESP Timer" + endchoice + + config BUTTON_IO_GLITCH_FILTER_TIME_MS + int "IO glitch filter timer ms (10~100)" + range 10 100 + default 50 + +endmenu \ No newline at end of file diff --git a/examples/bluetooth/esp_ble_mesh/ble_mesh_node/onoff_client/components/button/README.md b/examples/bluetooth/esp_ble_mesh/ble_mesh_node/onoff_client/components/button/README.md new file mode 100644 index 000000000..6f61910cf --- /dev/null +++ b/examples/bluetooth/esp_ble_mesh/ble_mesh_node/onoff_client/components/button/README.md @@ -0,0 +1,47 @@ +# Component: Button + +* This component defines a button as a well encapsulated object. +* A button device is defined by: + * GPIO number on which the button is attached. + * Active level which decided by peripheral hardware. + * Trigger mode which decides whether to call serial trigger callback during pressing + * Serial threshold seconds which decides that serial trigger callback will be called after how many seconds' pressing +* A button device can provide: + * One push event callback + * One release event callback + * One short-time tap event callback + * One serial trigger event callback + * Several long-time press event callback + We can set different jitter filters for all the events. + Once any of the long press callback is triggered, the short tap event will not be triggered. + This components are based on GPIO provided by idf and soft timer provided by FreeRTOS. + +* To use the button device, you need to : + * create a button object returned by iot_button_create(). + * Then hook different event callbacks to the button object. + * To free the object, you can call iot_button_delete to delete the button object and free the memory that used. + +* Todo: + * Add hardware timer mode(because sometimes soft-timer callback function is limited) + +### NOTE: +> All the event callback function are realized by FreeRTOS soft timer APIs, the callback must follow the rule: + + + +``` + Button callback functions execute in the context of the timer service task. + It is therefore essential that button callback functions never attempt to block. + For example, a button callback function must not call vTaskDelay(), vTaskDelayUntil(), or specify a non zero block time when accessing a queue or a semaphore. +``` + +> In addition: +> You can adjust the following macros within FreeRTOS to adjust the stack depth/queue length/task priority of the timer service. + + +``` +#define configUSE_TIMERS //enable soft-timer +#define configTIMER_TASK_PRIORITY // priority of the timers service task +#define configQueue_LENGTH // length of timer command queue +#define configTIMER_TASK_STACK_DEPTH // stack depth of the soft-timer +``` \ No newline at end of file diff --git a/examples/bluetooth/esp_ble_mesh/ble_mesh_node/onoff_client/components/button/button.c b/examples/bluetooth/esp_ble_mesh/ble_mesh_node/onoff_client/components/button/button.c new file mode 100644 index 000000000..ac391a5c3 --- /dev/null +++ b/examples/bluetooth/esp_ble_mesh/ble_mesh_node/onoff_client/components/button/button.c @@ -0,0 +1,434 @@ +// Copyright 2015-2016 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 +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "freertos/queue.h" +#include "freertos/timers.h" +#include "esp_log.h" +#include "driver/gpio.h" +#include "iot_button.h" +#include "esp_timer.h" + +#define USE_ESP_TIMER CONFIG_BUTTON_USE_ESP_TIMER +#if USE_ESP_TIMER +#define STOP_TIMER(tmr) esp_timer_stop(tmr) +#define DELETE_TIMER(tmr) esp_timer_delete(tmr) +#else +#define STOP_TIMER(tmr) xTimerStop(tmr, portMAX_DELAY) +#define DELETE_TIMER(tmr) xTimerDelete(tmr, portMAX_DELAY); +#endif + +#define IOT_CHECK(tag, a, ret) if(!(a)) { \ + ESP_LOGE(tag,"%s:%d (%s)", __FILE__, __LINE__, __FUNCTION__); \ + return (ret); \ + } +#define ERR_ASSERT(tag, param) IOT_CHECK(tag, (param) == ESP_OK, ESP_FAIL) +#define POINT_ASSERT(tag, param, ret) IOT_CHECK(tag, (param) != NULL, (ret)) + +typedef enum { + BUTTON_STATE_IDLE = 0, + BUTTON_STATE_PUSH, + BUTTON_STATE_PRESSED, +} button_status_t; + +typedef struct button_dev button_dev_t; +typedef struct btn_cb button_cb_t; + +struct btn_cb{ + TickType_t interval; + button_cb cb; + void* arg; + #if !USE_ESP_TIMER + TimerHandle_t tmr; + #else + esp_timer_handle_t tmr; + #endif + button_dev_t *pbtn; + button_cb_t *next_cb; +}; + +struct button_dev{ + uint8_t io_num; + uint8_t active_level; + uint32_t serial_thres_sec; + button_status_t state; + button_cb_t tap_short_cb; + button_cb_t tap_psh_cb; + button_cb_t tap_rls_cb; + button_cb_t press_serial_cb; + button_cb_t* cb_head; +}; + +#define BUTTON_GLITCH_FILTER_TIME_MS CONFIG_BUTTON_IO_GLITCH_FILTER_TIME_MS +static const char* TAG = "button"; + +// static void button_press_cb(xTimerHandle tmr) +static void button_press_cb(void* tmr) +{ + #if !USE_ESP_TIMER + button_cb_t* btn_cb = (button_cb_t*) pvTimerGetTimerID(tmr); + #else + button_cb_t* btn_cb = (button_cb_t*)(tmr); + #endif + + button_dev_t* btn = btn_cb->pbtn; + // low, then restart + if (btn->active_level == gpio_get_level(btn->io_num)) { + btn->state = BUTTON_STATE_PRESSED; + if (btn_cb->cb) { + btn_cb->cb(btn_cb->arg); + } + } +} + +// static void button_tap_psh_cb(xTimerHandle tmr) +static void button_tap_psh_cb(void* tmr) +{ + #if !USE_ESP_TIMER + button_cb_t* btn_cb = (button_cb_t*) pvTimerGetTimerID(tmr); + #else + button_cb_t* btn_cb = (button_cb_t*)(tmr); + #endif + + button_dev_t* btn = btn_cb->pbtn; + STOP_TIMER(btn->tap_rls_cb.tmr); + + int lv = gpio_get_level(btn->io_num); + + if (btn->active_level == lv) { + // high, then key is up + btn->state = BUTTON_STATE_PUSH; + if (btn->press_serial_cb.tmr) { + #if !USE_ESP_TIMER + xTimerChangePeriod(btn->press_serial_cb.tmr, btn->serial_thres_sec*1000 / portTICK_PERIOD_MS, portMAX_DELAY); + xTimerReset(btn->press_serial_cb.tmr, portMAX_DELAY); + #else + esp_timer_stop(btn->press_serial_cb.tmr); + esp_timer_start_once(btn->press_serial_cb.tmr, btn->serial_thres_sec * 1000 * 1000); + #endif + + } + if (btn->tap_psh_cb.cb) { + btn->tap_psh_cb.cb(btn->tap_psh_cb.arg); + } + } else { + // 50ms, check if this is a real key up + if (btn->tap_rls_cb.tmr) { + STOP_TIMER(btn->tap_rls_cb.tmr); + #if !USE_ESP_TIMER + xTimerReset(btn->tap_rls_cb.tmr, portMAX_DELAY); + #else + esp_timer_start_once(btn->tap_rls_cb.tmr, btn->tap_rls_cb.interval * portTICK_PERIOD_MS * 1000); + #endif + } + } +} + +static void button_tap_rls_cb(void* tmr) +{ + #if !USE_ESP_TIMER + button_cb_t* btn_cb = (button_cb_t*) pvTimerGetTimerID(tmr); + #else + button_cb_t* btn_cb = (button_cb_t*)(tmr); + #endif + button_dev_t* btn = btn_cb->pbtn; + STOP_TIMER(btn->tap_rls_cb.tmr); + + if (btn->active_level == gpio_get_level(btn->io_num)) { + + } else { + // high, then key is up + button_cb_t *pcb = btn->cb_head; + while (pcb != NULL) { + if (pcb->tmr != NULL) { + STOP_TIMER(pcb->tmr); + } + pcb = pcb->next_cb; + } + if (btn->press_serial_cb.tmr && btn->press_serial_cb.tmr != NULL) { + STOP_TIMER(btn->press_serial_cb.tmr); + } + if (btn->tap_short_cb.cb && btn->state == BUTTON_STATE_PUSH) { + btn->tap_short_cb.cb(btn->tap_short_cb.arg); + } + if(btn->tap_rls_cb.cb && btn->state != BUTTON_STATE_IDLE) { + btn->tap_rls_cb.cb(btn->tap_rls_cb.arg); + } + btn->state = BUTTON_STATE_IDLE; + } +} + +static void button_press_serial_cb(void* tmr) +{ + #if !USE_ESP_TIMER + button_dev_t* btn = (button_dev_t*) pvTimerGetTimerID(tmr); + #else + button_dev_t* btn = (button_dev_t*)(tmr); + #endif + + if (btn->press_serial_cb.cb) { + btn->press_serial_cb.cb(btn->press_serial_cb.arg); + } + #if !USE_ESP_TIMER + xTimerChangePeriod(btn->press_serial_cb.tmr, btn->press_serial_cb.interval, portMAX_DELAY); + xTimerReset(btn->press_serial_cb.tmr, portMAX_DELAY); + #else + esp_timer_stop(btn->press_serial_cb.tmr); + esp_timer_start_once(btn->press_serial_cb.tmr, btn->press_serial_cb.interval * portTICK_PERIOD_MS * 1000); + #endif +} + +static void button_gpio_isr_handler(void* arg) +{ + button_dev_t* btn = (button_dev_t*) arg; + portBASE_TYPE HPTaskAwoken = pdFALSE; + int level = gpio_get_level(btn->io_num); + if (level == btn->active_level) { + if (btn->tap_psh_cb.tmr) { + #if !USE_ESP_TIMER + xTimerStopFromISR(btn->tap_psh_cb.tmr, &HPTaskAwoken); + xTimerResetFromISR(btn->tap_psh_cb.tmr, &HPTaskAwoken); + #else + esp_timer_stop(btn->tap_psh_cb.tmr); + esp_timer_start_once(btn->tap_psh_cb.tmr, btn->tap_psh_cb.interval * portTICK_PERIOD_MS * 1000); + #endif + } + + button_cb_t *pcb = btn->cb_head; + while (pcb != NULL) { + if (pcb->tmr != NULL) { + #if !USE_ESP_TIMER + xTimerStopFromISR(pcb->tmr, &HPTaskAwoken); + xTimerResetFromISR(pcb->tmr, &HPTaskAwoken); + #else + esp_timer_stop(pcb->tmr); + esp_timer_start_once(pcb->tmr, pcb->interval * portTICK_PERIOD_MS * 1000); + #endif + } + pcb = pcb->next_cb; + } + } else { + // 50ms, check if this is a real key up + if (btn->tap_rls_cb.tmr) { + #if !USE_ESP_TIMER + xTimerStopFromISR(btn->tap_rls_cb.tmr, &HPTaskAwoken); + xTimerResetFromISR(btn->tap_rls_cb.tmr, &HPTaskAwoken); + #else + esp_timer_stop(btn->tap_rls_cb.tmr); + esp_timer_start_once(btn->tap_rls_cb.tmr, btn->tap_rls_cb.interval * portTICK_PERIOD_MS * 1000); + #endif + } + } + if(HPTaskAwoken == pdTRUE) { + portYIELD_FROM_ISR(); + } +} + +#if !USE_ESP_TIMER +static void button_free_tmr(xTimerHandle* tmr) +#else +static void button_free_tmr(esp_timer_handle_t *tmr) +#endif +{ + if (tmr && *tmr) { + STOP_TIMER(*tmr); + DELETE_TIMER(*tmr); + *tmr = NULL; + } +} + +esp_err_t iot_button_delete(button_handle_t btn_handle) +{ + POINT_ASSERT(TAG, btn_handle, ESP_ERR_INVALID_ARG); + button_dev_t* btn = (button_dev_t*) btn_handle; + gpio_set_intr_type(btn->io_num, GPIO_INTR_DISABLE); + gpio_isr_handler_remove(btn->io_num); + + button_free_tmr(&btn->tap_rls_cb.tmr); + button_free_tmr(&btn->tap_psh_cb.tmr); + button_free_tmr(&btn->tap_short_cb.tmr); + button_free_tmr(&btn->press_serial_cb.tmr); + + button_cb_t *pcb = btn->cb_head; + while (pcb != NULL) { + button_cb_t *cb_next = pcb->next_cb; + button_free_tmr(&pcb->tmr); + free(pcb); + pcb = cb_next; + } + free(btn); + return ESP_OK; +} + +button_handle_t iot_button_create(gpio_num_t gpio_num, button_active_t active_level) +{ + #if USE_ESP_TIMER + ets_printf("use esp timer !!!\n"); + esp_timer_init(); + #endif + + IOT_CHECK(TAG, gpio_num < GPIO_NUM_MAX, NULL); + button_dev_t* btn = (button_dev_t*) calloc(1, sizeof(button_dev_t)); + POINT_ASSERT(TAG, btn, NULL); + btn->active_level = active_level; + btn->io_num = gpio_num; + btn->state = BUTTON_STATE_IDLE; + btn->tap_rls_cb.arg = NULL; + btn->tap_rls_cb.cb = NULL; + btn->tap_rls_cb.interval = BUTTON_GLITCH_FILTER_TIME_MS / portTICK_PERIOD_MS; + btn->tap_rls_cb.pbtn = btn; + #if !USE_ESP_TIMER + btn->tap_rls_cb.tmr = xTimerCreate("btn_rls_tmr", btn->tap_rls_cb.interval, pdFALSE, + &btn->tap_rls_cb, button_tap_rls_cb); + #else + esp_timer_create_args_t tmr_param_rls; + tmr_param_rls.arg = &btn->tap_rls_cb; + tmr_param_rls.callback = button_tap_rls_cb; + tmr_param_rls.dispatch_method = ESP_TIMER_TASK; + tmr_param_rls.name = "btn_rls_tmr"; + esp_timer_create(&tmr_param_rls, &btn->tap_rls_cb.tmr); + #endif + + btn->tap_psh_cb.arg = NULL; + btn->tap_psh_cb.cb = NULL; + btn->tap_psh_cb.interval = BUTTON_GLITCH_FILTER_TIME_MS / portTICK_PERIOD_MS; + btn->tap_psh_cb.pbtn = btn; + #if !USE_ESP_TIMER + btn->tap_psh_cb.tmr = xTimerCreate("btn_psh_tmr", btn->tap_psh_cb.interval, pdFALSE, + &btn->tap_psh_cb, button_tap_psh_cb); + #else + esp_timer_create_args_t tmr_param_psh; + tmr_param_psh.arg = &btn->tap_psh_cb; + tmr_param_psh.callback = button_tap_psh_cb; + tmr_param_psh.dispatch_method = ESP_TIMER_TASK; + tmr_param_psh.name = "btn_psh_tmr"; + esp_timer_create(&tmr_param_psh, &btn->tap_psh_cb.tmr); + #endif + gpio_install_isr_service(0); + gpio_config_t gpio_conf; + gpio_conf.intr_type = GPIO_INTR_ANYEDGE; + gpio_conf.mode = GPIO_MODE_INPUT; + gpio_conf.pin_bit_mask = (1ULL << gpio_num); + gpio_conf.pull_down_en = GPIO_PULLDOWN_DISABLE; + gpio_conf.pull_up_en = GPIO_PULLUP_ENABLE; + gpio_config(&gpio_conf); + gpio_isr_handler_add(gpio_num, button_gpio_isr_handler, btn); + return (button_handle_t) btn; +} + +esp_err_t iot_button_rm_cb(button_handle_t btn_handle, button_cb_type_t type) +{ + button_dev_t* btn = (button_dev_t*) btn_handle; + button_cb_t* btn_cb = NULL; + if (type == BUTTON_CB_PUSH) { + btn_cb = &btn->tap_psh_cb; + } else if (type == BUTTON_CB_RELEASE) { + btn_cb = &btn->tap_rls_cb; + } else if (type == BUTTON_CB_TAP) { + btn_cb = &btn->tap_short_cb; + } else if (type == BUTTON_CB_SERIAL) { + btn_cb = &btn->press_serial_cb; + } + btn_cb->cb = NULL; + btn_cb->arg = NULL; + btn_cb->pbtn = btn; + button_free_tmr(&btn_cb->tmr); + return ESP_OK; +} + +esp_err_t iot_button_set_serial_cb(button_handle_t btn_handle, uint32_t start_after_sec, TickType_t interval_tick, button_cb cb, void* arg) +{ + button_dev_t* btn = (button_dev_t*) btn_handle; + btn->serial_thres_sec = start_after_sec; + + if (btn->press_serial_cb.tmr == NULL) { + #if !USE_ESP_TIMER + btn->press_serial_cb.tmr = xTimerCreate("btn_serial_tmr", btn->serial_thres_sec*1000 / portTICK_PERIOD_MS, + pdFALSE, btn, button_press_serial_cb); + #else + esp_timer_create_args_t tmr_param_ser; + tmr_param_ser.arg = btn; + tmr_param_ser.callback = button_press_serial_cb; + tmr_param_ser.dispatch_method = ESP_TIMER_TASK; + tmr_param_ser.name = "btn_serial_tmr"; + esp_timer_create(&tmr_param_ser, &btn->press_serial_cb.tmr); + #endif + } + btn->press_serial_cb.arg = arg; + btn->press_serial_cb.cb = cb; + btn->press_serial_cb.interval = interval_tick; + btn->press_serial_cb.pbtn = btn; + #if !USE_ESP_TIMER + xTimerChangePeriod(btn->press_serial_cb.tmr, btn->serial_thres_sec*1000 / portTICK_PERIOD_MS, portMAX_DELAY); + #endif + return ESP_OK; +} + +esp_err_t iot_button_set_evt_cb(button_handle_t btn_handle, button_cb_type_t type, button_cb cb, void* arg) +{ + POINT_ASSERT(TAG, btn_handle, ESP_ERR_INVALID_ARG); + button_dev_t* btn = (button_dev_t*) btn_handle; + if (type == BUTTON_CB_PUSH) { + btn->tap_psh_cb.arg = arg; + btn->tap_psh_cb.cb = cb; + btn->tap_psh_cb.interval = BUTTON_GLITCH_FILTER_TIME_MS / portTICK_RATE_MS; + btn->tap_psh_cb.pbtn = btn; + #if !USE_ESP_TIMER + xTimerChangePeriod(btn->tap_psh_cb.tmr, btn->tap_psh_cb.interval, portMAX_DELAY); + #endif + } else if (type == BUTTON_CB_RELEASE) { + btn->tap_rls_cb.arg = arg; + btn->tap_rls_cb.cb = cb; + btn->tap_rls_cb.interval = BUTTON_GLITCH_FILTER_TIME_MS / portTICK_RATE_MS; + btn->tap_rls_cb.pbtn = btn; + #if !USE_ESP_TIMER + xTimerChangePeriod(btn->tap_rls_cb.tmr, btn->tap_psh_cb.interval, portMAX_DELAY); + #endif + } else if (type == BUTTON_CB_TAP) { + btn->tap_short_cb.arg = arg; + btn->tap_short_cb.cb = cb; + btn->tap_short_cb.interval = BUTTON_GLITCH_FILTER_TIME_MS / portTICK_RATE_MS; + btn->tap_short_cb.pbtn = btn; + } else if (type == BUTTON_CB_SERIAL) { + iot_button_set_serial_cb(btn_handle, 1, 1000 / portTICK_RATE_MS, cb, arg); + } + return ESP_OK; +} + +esp_err_t iot_button_add_custom_cb(button_handle_t btn_handle, uint32_t press_sec, button_cb cb, void* arg) +{ + POINT_ASSERT(TAG, btn_handle, ESP_ERR_INVALID_ARG); + IOT_CHECK(TAG, press_sec != 0, ESP_ERR_INVALID_ARG); + button_dev_t* btn = (button_dev_t*) btn_handle; + button_cb_t* cb_new = (button_cb_t*) calloc(1, sizeof(button_cb_t)); + POINT_ASSERT(TAG, cb_new, ESP_FAIL); + cb_new->arg = arg; + cb_new->cb = cb; + cb_new->interval = press_sec * 1000 / portTICK_PERIOD_MS; + cb_new->pbtn = btn; + #if !USE_ESP_TIMER + cb_new->tmr = xTimerCreate("btn_press_tmr", cb_new->interval, pdFALSE, cb_new, button_press_cb); + #else + esp_timer_create_args_t tmr_param_cus; + tmr_param_cus.arg = cb_new; + tmr_param_cus.callback = button_press_cb; + tmr_param_cus.dispatch_method = ESP_TIMER_TASK; + tmr_param_cus.name = "btn_press_custom_tmr"; + esp_timer_create(&tmr_param_cus, &cb_new->tmr); + #endif + cb_new->next_cb = btn->cb_head; + btn->cb_head = cb_new; + return ESP_OK; +} diff --git a/examples/bluetooth/esp_ble_mesh/ble_mesh_node/onoff_client/components/button/button_obj.cpp b/examples/bluetooth/esp_ble_mesh/ble_mesh_node/onoff_client/components/button/button_obj.cpp new file mode 100644 index 000000000..bf49238e5 --- /dev/null +++ b/examples/bluetooth/esp_ble_mesh/ble_mesh_node/onoff_client/components/button/button_obj.cpp @@ -0,0 +1,48 @@ +// Copyright 2015-2016 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 "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "esp_system.h" +#include "iot_button.h" + +CButton::CButton(gpio_num_t gpio_num, button_active_t active_level) +{ + m_btn_handle = iot_button_create(gpio_num, active_level); +} + +CButton::~CButton() +{ + iot_button_delete(m_btn_handle); + m_btn_handle = NULL; +} + +esp_err_t CButton::set_evt_cb(button_cb_type_t type, button_cb cb, void* arg) +{ + return iot_button_set_evt_cb(m_btn_handle, type, cb, arg); +} + +esp_err_t CButton::set_serial_cb(button_cb cb, void* arg, TickType_t interval_tick, uint32_t start_after_sec) +{ + return iot_button_set_serial_cb(m_btn_handle, start_after_sec, interval_tick, cb, arg); +} + +esp_err_t CButton::add_custom_cb(uint32_t press_sec, button_cb cb, void* arg) +{ + return iot_button_add_custom_cb(m_btn_handle, press_sec, cb, arg); +} + +esp_err_t CButton::rm_cb(button_cb_type_t type) +{ + return iot_button_rm_cb(m_btn_handle, type); +} diff --git a/examples/bluetooth/esp_ble_mesh/ble_mesh_client_model/main/component.mk b/examples/bluetooth/esp_ble_mesh/ble_mesh_node/onoff_client/components/button/component.mk similarity index 100% rename from examples/bluetooth/esp_ble_mesh/ble_mesh_client_model/main/component.mk rename to examples/bluetooth/esp_ble_mesh/ble_mesh_node/onoff_client/components/button/component.mk diff --git a/examples/bluetooth/esp_ble_mesh/ble_mesh_node/onoff_client/components/button/include/iot_button.h b/examples/bluetooth/esp_ble_mesh/ble_mesh_node/onoff_client/components/button/include/iot_button.h new file mode 100644 index 000000000..6a2fa23c0 --- /dev/null +++ b/examples/bluetooth/esp_ble_mesh/ble_mesh_node/onoff_client/components/button/include/iot_button.h @@ -0,0 +1,230 @@ +// Copyright 2015-2016 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. +#ifndef _IOT_BUTTON_H_ +#define _IOT_BUTTON_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "driver/gpio.h" +#include "freertos/portmacro.h" +typedef void (* button_cb)(void*); +typedef void* button_handle_t; + +typedef enum { + BUTTON_ACTIVE_HIGH = 1, /*!