ble_mesh: update ble mesh examples
This commit is contained in:
@@ -1,7 +0,0 @@
|
||||
# The following lines of boilerplate have to be in your project's CMakeLists
|
||||
# in this exact order for cmake to work correctly
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
|
||||
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||
set(SUPPORTED_TARGETS esp32)
|
||||
project(ble_mesh_client_model)
|
||||
@@ -1,10 +0,0 @@
|
||||
#
|
||||
# This is a project Makefile. It is assumed the directory this Makefile resides in is a
|
||||
# project subdirectory.
|
||||
#
|
||||
|
||||
PROJECT_NAME := ble_mesh_client_model
|
||||
|
||||
COMPONENT_ADD_INCLUDEDIRS := components/include
|
||||
|
||||
include $(IDF_PATH)/make/project.mk
|
||||
@@ -1,14 +0,0 @@
|
||||
ESP BLE Mesh Client Model Demo
|
||||
========================
|
||||
|
||||
This demo shows how to use the Generic OnOff Client Model to get/set the generic on/off state. The basic procedures are as follows:
|
||||
|
||||
1. Download and run this demo.
|
||||
2. Use any app for BLE Mesh to provision this device as well as the device running the Generic OnOff Server demo.
|
||||
3. After both onoff client and server devices are provisioned, use UART1 to input the unicast address of the element within the server device.
|
||||
4. The Generic OnOff Client will start to get and set Generic OnOff states periodically.
|
||||
|
||||
>**Notes:**
|
||||
>
|
||||
>1. The NetKey index and AppKey index are fixed to 0x0000 in this demo.
|
||||
>2. If the client device is re-provisioned, but the server device is not, the first few get/set messages from the client will be treated as replay attacks. To avoid this, both devices should be re-provisioned prior to transmitting messages.
|
||||
@@ -1,7 +0,0 @@
|
||||
set(COMPONENT_SRCS "ble_mesh_demo_main.c"
|
||||
"ble_mesh_demo_init.c"
|
||||
"board.c")
|
||||
|
||||
set(COMPONENT_ADD_INCLUDEDIRS ".")
|
||||
|
||||
register_component()
|
||||
@@ -1,22 +0,0 @@
|
||||
menu "Example Configuration"
|
||||
|
||||
choice BLE_MESH_EXAMPLE_BOARD
|
||||
prompt "Board selection for BLE Mesh"
|
||||
default BLE_MESH_ESP_WROOM_32
|
||||
help
|
||||
Select this option to choose the board for BLE Mesh. The default is ESP32-WROOM-32
|
||||
|
||||
config BLE_MESH_ESP_WROOM_32
|
||||
bool "ESP32-WROOM-32"
|
||||
|
||||
config BLE_MESH_ESP_WROVER
|
||||
bool "ESP32-WROVER"
|
||||
endchoice
|
||||
|
||||
config BLE_MESH_PATCH_FOR_SLAB_APP_1_1_0
|
||||
bool "Fix bug of Silicon Lab Android App v1.1.0 when reconnection will cause sequence number to recount from 0"
|
||||
default y
|
||||
help
|
||||
It is an ad hoc solution and needs further modifications.
|
||||
|
||||
endmenu
|
||||
@@ -1,143 +0,0 @@
|
||||
|
||||
/*
|
||||
* Copyright (c) 2017 Intel Corporation
|
||||
* Additional Copyright (c) 2018 Espressif Systems (Shanghai) PTE LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sdkconfig.h>
|
||||
/* BLE */
|
||||
#ifdef CONFIG_BT_BLUEDROID_ENABLED
|
||||
#include "esp_bt.h"
|
||||
#include "esp_bt_main.h"
|
||||
#include "esp_bt_device.h"
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_BT_NIMBLE_ENABLED
|
||||
#include "esp_nimble_hci.h"
|
||||
#include "nimble/nimble_port.h"
|
||||
#include "nimble/nimble_port_freertos.h"
|
||||
#include "host/ble_hs.h"
|
||||
#include "host/util/util.h"
|
||||
#include "console/console.h"
|
||||
#endif
|
||||
|
||||
#include "esp_ble_mesh_defs.h"
|
||||
#include "ble_mesh_demo_init.h"
|
||||
#include "esp_ble_mesh_common_api.h"
|
||||
|
||||
#ifdef CONFIG_BT_BLUEDROID_ENABLED
|
||||
|
||||
void ble_mesh_get_dev_uuid(uint8_t *dev_uuid)
|
||||
{
|
||||
memcpy(dev_uuid + 2, esp_bt_dev_get_address(), BD_ADDR_LEN);
|
||||
}
|
||||
|
||||
esp_err_t bluetooth_init(void)
|
||||
{
|
||||
esp_err_t ret;
|
||||
|
||||
|
||||
ESP_ERROR_CHECK(esp_bt_controller_mem_release(ESP_BT_MODE_CLASSIC_BT));
|
||||
|
||||
esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT();
|
||||
ret = esp_bt_controller_init(&bt_cfg);
|
||||
if (ret) {
|
||||
ESP_LOGE(TAG, "%s initialize controller failed", __func__);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = esp_bt_controller_enable(ESP_BT_MODE_BLE);
|
||||
if (ret) {
|
||||
ESP_LOGE(TAG, "%s enable controller failed", __func__);
|
||||
return ret;
|
||||
}
|
||||
ret = esp_bluedroid_init();
|
||||
if (ret) {
|
||||
ESP_LOGE(TAG, "%s init bluetooth failed", __func__);
|
||||
return ret;
|
||||
}
|
||||
ret = esp_bluedroid_enable();
|
||||
if (ret) {
|
||||
ESP_LOGE(TAG, "%s enable bluetooth failed", __func__);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_BT_NIMBLE_ENABLED
|
||||
static SemaphoreHandle_t mesh_sem;
|
||||
static uint8_t own_addr_type;
|
||||
void ble_store_config_init(void);
|
||||
static uint8_t addr_val[6] = {0};
|
||||
|
||||
void ble_mesh_get_dev_uuid(uint8_t *dev_uuid)
|
||||
{
|
||||
memcpy(dev_uuid + 2, addr_val, BD_ADDR_LEN);
|
||||
}
|
||||
|
||||
static void mesh_on_reset(int reason)
|
||||
{
|
||||
ESP_LOGI(TAG, "Resetting state; reason=%d", reason);
|
||||
}
|
||||
|
||||
static void mesh_on_sync(void)
|
||||
{
|
||||
int rc;
|
||||
|
||||
rc = ble_hs_util_ensure_addr(0);
|
||||
assert(rc == 0);
|
||||
|
||||
/* Figure out address to use while advertising (no privacy for now) */
|
||||
rc = ble_hs_id_infer_auto(0, &own_addr_type);
|
||||
if (rc != 0) {
|
||||
ESP_LOGI(TAG, "error determining address type; rc=%d", rc);
|
||||
return;
|
||||
}
|
||||
|
||||
rc = ble_hs_id_copy_addr(own_addr_type, addr_val, NULL);
|
||||
|
||||
xSemaphoreGive(mesh_sem);
|
||||
}
|
||||
|
||||
void mesh_host_task(void *param)
|
||||
{
|
||||
ESP_LOGI(TAG, "BLE Host Task Started");
|
||||
/* This function will return only when nimble_port_stop() is executed */
|
||||
nimble_port_run();
|
||||
|
||||
nimble_port_freertos_deinit();
|
||||
}
|
||||
|
||||
esp_err_t bluetooth_init(void)
|
||||
{
|
||||
mesh_sem = xSemaphoreCreateBinary();
|
||||
if (mesh_sem == NULL) {
|
||||
ESP_LOGE(TAG, "Failed to create mesh semaphore");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
ESP_ERROR_CHECK(esp_nimble_hci_and_controller_init());
|
||||
|
||||
nimble_port_init();
|
||||
/* Initialize the NimBLE host configuration. */
|
||||
ble_hs_cfg.reset_cb = mesh_on_reset;
|
||||
ble_hs_cfg.sync_cb = mesh_on_sync;
|
||||
ble_hs_cfg.store_status_cb = ble_store_util_status_rr;
|
||||
|
||||
/* XXX Need to have template for store */
|
||||
ble_store_config_init();
|
||||
|
||||
nimble_port_freertos_init(mesh_host_task);
|
||||
|
||||
xSemaphoreTake(mesh_sem, portMAX_DELAY);
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
#endif
|
||||
@@ -1,18 +0,0 @@
|
||||
/*
|
||||
This example code is in the Public Domain (or CC0 licensed, at your option.)
|
||||
|
||||
Unless required by applicable law or agreed to in writing, this
|
||||
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
CONDITIONS OF ANY KIND, either express or implied.
|
||||
*/
|
||||
|
||||
#ifndef _BLE_MESH_DEMO_INIT_H_
|
||||
#define _BLE_MESH_DEMO_INIT_H_
|
||||
|
||||
#define TAG "ble_mesh_client"
|
||||
|
||||
void ble_mesh_get_dev_uuid(uint8_t *dev_uuid);
|
||||
|
||||
esp_err_t bluetooth_init(void);
|
||||
|
||||
#endif
|
||||
@@ -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 <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#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);
|
||||
}
|
||||
}
|
||||
@@ -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 <stdio.h>
|
||||
|
||||
#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);
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
/* board.h - Board-specific hooks */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2017 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#ifndef _BOARD_H_
|
||||
#define _BOARD_H_
|
||||
|
||||
#include "driver/gpio.h"
|
||||
#include "esp_ble_mesh_defs.h"
|
||||
|
||||
#if defined(CONFIG_BLE_MESH_ESP_WROOM_32)
|
||||
#define LED_R GPIO_NUM_25
|
||||
#define LED_G GPIO_NUM_26
|
||||
#define LED_B GPIO_NUM_27
|
||||
#elif defined(CONFIG_BLE_MESH_ESP_WROVER)
|
||||
#define LED_R GPIO_NUM_0
|
||||
#define LED_G GPIO_NUM_2
|
||||
#define LED_B GPIO_NUM_4
|
||||
#endif
|
||||
|
||||
#define LED_ON 1
|
||||
#define LED_OFF 0
|
||||
|
||||
struct _led_state {
|
||||
uint8_t current;
|
||||
uint8_t previous;
|
||||
uint8_t pin;
|
||||
char *name;
|
||||
};
|
||||
|
||||
void board_output_number(esp_ble_mesh_output_action_t action, uint32_t number);
|
||||
|
||||
void board_prov_complete(void);
|
||||
|
||||
void board_led_operation(uint8_t pin, uint8_t onoff);
|
||||
|
||||
void board_init(void);
|
||||
|
||||
#endif
|
||||
@@ -1,4 +0,0 @@
|
||||
#
|
||||
# "main" pseudo-component makefile.
|
||||
#
|
||||
# (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.)
|
||||
@@ -1,47 +0,0 @@
|
||||
# Override some defaults so BT stack is enabled
|
||||
# by default in this example
|
||||
CONFIG_BT_ENABLED=y
|
||||
CONFIG_BTDM_CTRL_MODE_BLE_ONLY=y
|
||||
CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY=
|
||||
CONFIG_BTDM_CTRL_MODE_BTDM=
|
||||
CONFIG_BTDM_MODEM_SLEEP=n
|
||||
CONFIG_BTDM_BLE_SCAN_DUPL=y
|
||||
CONFIG_BTDM_SCAN_DUPL_TYPE=2
|
||||
CONFIG_BTDM_SCAN_DUPL_TYPE_DATA_DEVICE=y
|
||||
CONFIG_BTDM_SCAN_DUPL_CACHE_SIZE=200
|
||||
CONFIG_BTDM_BLE_MESH_SCAN_DUPL_EN=y
|
||||
CONFIG_BTDM_MESH_DUPL_SCAN_CACHE_SIZE=200
|
||||
CONFIG_BTDM_CTRL_FULL_SCAN_SUPPORTED=y
|
||||
CONFIG_BTDM_BLE_ADV_REPORT_FLOW_CTRL_SUPP=y
|
||||
CONFIG_BT_GATTS_ENABLE=y
|
||||
CONFIG_BT_GATTS_SEND_SERVICE_CHANGE_MANUAL=y
|
||||
CONFIG_BLE_MESH=y
|
||||
CONFIG_BLE_MESH_HCI_5_0=y
|
||||
CONFIG_BLE_MESH_USE_DUPLICATE_SCAN=y
|
||||
CONFIG_BLE_MESH_NODE=y
|
||||
CONFIG_BLE_MESH_PROV=y
|
||||
CONFIG_BLE_MESH_NET_BUF_POOL_USAGE=y
|
||||
CONFIG_BLE_MESH_PROXY=y
|
||||
CONFIG_BLE_MESH_PB_GATT=y
|
||||
CONFIG_BLE_MESH_GATT_PROXY_SERVER=y
|
||||
CONFIG_BLE_MESH_NODE_ID_TIMEOUT=60
|
||||
CONFIG_BLE_MESH_PROXY_FILTER_SIZE=1
|
||||
CONFIG_BLE_MESH_IV_UPDATE_TEST=
|
||||
CONFIG_BLE_MESH_SUBNET_COUNT=1
|
||||
CONFIG_BLE_MESH_APP_KEY_COUNT=1
|
||||
CONFIG_BLE_MESH_MODEL_KEY_COUNT=1
|
||||
CONFIG_BLE_MESH_MODEL_GROUP_COUNT=1
|
||||
CONFIG_BLE_MESH_LABEL_COUNT=1
|
||||
CONFIG_BLE_MESH_CRPL=10
|
||||
CONFIG_BLE_MESH_MSG_CACHE_SIZE=10
|
||||
CONFIG_BLE_MESH_ADV_BUF_COUNT=60
|
||||
CONFIG_BLE_MESH_TX_SEG_MSG_COUNT=6
|
||||
CONFIG_BLE_MESH_RX_SEG_MSG_COUNT=1
|
||||
CONFIG_BLE_MESH_RX_SDU_MAX=384
|
||||
CONFIG_BLE_MESH_TX_SEG_MAX=32
|
||||
CONFIG_BLE_MESH_RELAY=y
|
||||
CONFIG_BLE_MESH_LOW_POWER=
|
||||
CONFIG_BLE_MESH_FRIEND=
|
||||
CONFIG_BLE_MESH_CFG_CLI=
|
||||
CONFIG_BLE_MESH_GENERIC_ONOFF_CLI=y
|
||||
CONFIG_BT_BTU_TASK_STACK_SIZE=4512
|
||||
-252
@@ -1,252 +0,0 @@
|
||||
# 1. Introduction
|
||||
## 1.1 Demo Function
|
||||
|
||||
1. This demo forwards the message sent by the nRF Mesh app.
|
||||
2. The user enters the address of the destination node and use it to forwarded packet.
|
||||
3. The types of the forwarded message include:
|
||||
* `ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_GET`,
|
||||
* `ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_SET`,
|
||||
* `ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_SET_UNACK`.
|
||||
4. The destination node reports its Onoff state with the `ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_STATUS` message.
|
||||
|
||||
Example: The nRF Mesh app sends a `ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_SET` message to the node that runs the `ble_mesh_client_model` project. Then this node sends a `ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_SET` message to the destination node that runs the `ble_mesh_node` project. The address of the destination node is entered by the user via the serial port.
|
||||
|
||||
## 1.1.1 What You Need
|
||||
|
||||
* 1 x Device that runs the `ble_mesh_client_model` project.
|
||||
* 1 x Device that runs the `ble_mesh_node` project.
|
||||
* 1 x Phone that installs the nRF Mesh app for controlling these two devices
|
||||
|
||||
## 1.2 Node Composition
|
||||
|
||||
This demo has only one element, in which the following three Models are implemented:
|
||||
|
||||
- **Configuration Server Model** is mainly to represent a mesh network configuration, such as its AppKey, Relay State, TTL State, Subscription List State, etc.
|
||||
- **Generic OnOff Client Model** controls a Generic OnOff Server via messages defined by the Generic OnOff Model, that is, turning on and off the lights.
|
||||
- **Generic OnOff Server Model** implements the nodes' Onoff state.
|
||||
|
||||
## 1.3 Message Sequence
|
||||
|
||||
You can choose from the 4 message sequences described below:
|
||||
|
||||
1. Acknowledged Get
|
||||
2. Acknowledged Set
|
||||
3. Unacknowledged Set
|
||||
4. Acknowledged Set with Periodic Publishing
|
||||
|
||||

|
||||
|
||||
## 2. Code Analysis
|
||||
|
||||
Code initialization part reference [Initializing the Bluetooth and Initializing the BLE Mesh](../../ble_mesh_wifi_coexist/tutorial%20%20%20%20%20%20/ble_mesh_wifi_coexist.md)
|
||||
|
||||
### 2.1 Model Definition
|
||||
|
||||
#### 2.1.1 Generic OnOff Server Model
|
||||
|
||||
```c
|
||||
//Allocating memory for publishing messages.
|
||||
ESP_BLE_MESH_MODEL_PUB_DEFINE(onoff_srv_pub, 2 + 1, MSG_ROLE);
|
||||
//Registering the minimum length of messages. For example, the minimum length of the ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_SET message is registered as 2 octets.
|
||||
static esp_ble_mesh_model_op_t onoff_op[] = {
|
||||
{ ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_GET, 0, 0},
|
||||
{ ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_SET, 2, 0},
|
||||
{ ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_SET_UNACK, 2, 0},
|
||||
ESP_BLE_MESH_MODEL_OP_END,
|
||||
};
|
||||
//Registering the Generic Onoff Server Model.
|
||||
static esp_ble_mesh_model_t root_models[] = {
|
||||
//onoff server's onoff state init
|
||||
ESP_BLE_MESH_SIG_MODEL(ESP_BLE_MESH_MODEL_ID_GEN_ONOFF_SRV, onoff_op,
|
||||
&onoff_srv_pub, &led_state[0]),
|
||||
};
|
||||
```
|
||||
#### 2.1.2 Generic OnOff Client Model
|
||||
|
||||
```c
|
||||
//Allocating memory for publishing messages.
|
||||
ESP_BLE_MESH_MODEL_PUB_DEFINE(onoff_cli_pub, 2 + 1, MSG_ROLE);
|
||||
//Registering the Generic Onoff Client Model.
|
||||
static esp_ble_mesh_model_t root_models[] = {
|
||||
ESP_BLE_MESH_MODEL_GEN_ONOFF_CLI(&onoff_cli_pub, &onoff_client),
|
||||
};
|
||||
```
|
||||
|
||||
### 2.2 Model Callback Function
|
||||
|
||||
#### 2.2.1 The Callback function for the Generic Onoff Client Model
|
||||
|
||||
```c
|
||||
esp_ble_mesh_register_generic_client_callback(esp_ble_mesh_generic_cb);
|
||||
|
||||
```
|
||||
1. The callback function will be triggered when the Client Model:
|
||||
|
||||
* Receives a message that indicates the Onoff state of the Sever Model; Or
|
||||
* Calls any APIs that the Server Model send messages.
|
||||
|
||||
2. The events that the callback function handle:
|
||||
|
||||
| Event name | Opcode |Description |
|
||||
| ------------- | ------------|------------------------------------------- |
|
||||
| ESP_BLE_MESH_GENERIC_CLIENT_GET_STATE_EVT | ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_GET |The event triggered when the Generic Onoff Client Model receives acknowledgment after sending the `ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_GET` message |
|
||||
| ESP_BLE_MESH_GENERIC_CLIENT_SET_STATE_EVT | ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_SET | The event triggered when the Generic Onoff Client Model receives acknowledgment after sending the `ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_SET` message |
|
||||
| ESP_BLE_MESH_GENERIC_CLIENT_PUBLISH_EVT | NA | The event triggered when the Generic Onoff Client Model receives publishing messages. |
|
||||
| ESP_BLE_MESH_GENERIC_CLIENT_TIMEOUT_EVT | ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_SET | The event triggered when API (that send messages) calling times out |
|
||||
|
||||
|
||||
#### 2.2.2 The Callback function for the Generic Onoff Server Model
|
||||
|
||||
```c
|
||||
esp_ble_mesh_register_custom_model_callback(esp_ble_mesh_model_cb);
|
||||
|
||||
```
|
||||
1. The callback function will be triggered when the Server Model:
|
||||
|
||||
* Receives a message that indicates operating the Onoff state of the Server Model from the Generic Onoff Client Model; Or
|
||||
* Calls any APIs that the Server Model send messages.
|
||||
|
||||
2. The events of the callback function:
|
||||
|
||||
| Event Name | Opcode | Description |
|
||||
|-------------------------------------|-------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| ESP_BLE_MESH_MODEL_OPERATION_EVT | ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_GET | The event triggered when the Generic Onoff Server Model receives the ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_GET message that **gets** the Onoff state of the server from the Client Model |
|
||||
| ESP_BLE_MESH_MODEL_OPERATION_EVT | ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_SET | The event triggered when the Generic Onoff Server Model receives the ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_SET message that **sets** the Onoff state of the server from the Client Model |
|
||||
| ESP_BLE_MESH_MODEL_OPERATION_EVT | ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_SET_UNACK | The event triggered when the Generic Onoff Server Model receives the ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_SET_UNACK message that **sets** the Onoff state of the server from the Client Model |
|
||||
| ESP_BLE_MESH_MODEL_SEND_COMP_EVT | NA | The event triggered when the `esp_ble_mesh_server_model_send_msg` API calling completes |
|
||||
| ESP_BLE_MESH_MODEL_PUBLISH_COMP_EVT | NA | The event triggered when the `esp_ble_mesh_model_publish` API calling completes |
|
||||
|
||||
|
||||
### 2.3 Model that Sends Message
|
||||
#### 2.3.1 Message Control
|
||||
|
||||
The `esp_ble_mesh_set_msg_common` function is used to set the message controlling parameters.
|
||||
|
||||
| Parameter Name |Description |
|
||||
| ----------------------|------------------------- |
|
||||
| `opcode` | The message opcode |
|
||||
| `model` | The pointer to the client Model struct |
|
||||
| `ctx.net_idx` | The NetKey Index of the subnet through which the message is sent |
|
||||
| `ctx.app_idx` | The AppKey Index for message encryption |
|
||||
| `ctx.addr` | The address of the destination nodes |
|
||||
| `ctx.send_ttl`| The TTL State, which determines how many times a message will be relayed |
|
||||
| `ctx.send_rel`| This parameter determines if the Model will wait for an acknowledgement after sending a message |
|
||||
| `msg_timeout` | The maximum time the Model will wait for an acknowledgement |
|
||||
| `msg_role` | The role of message (node/provisioner) |
|
||||
|
||||
> Note:
|
||||
>
|
||||
> Please check the `ESP_BLE_MESH_MODEL_SEND_COMP_EVT` event to see if the message is sent successfully.
|
||||
> This event is just for sending sig Model and vendor Model messages, not for all Models.
|
||||
|
||||
#### 2.3.2 The Generic Onoff Client sends message
|
||||
|
||||
The Generic Onoff Client Model calls the `esp_ble_mesh_generic_client_get_state` API to get the state of the server Model, such as the Onoff state.
|
||||
|
||||
```c
|
||||
esp_ble_mesh_generic_client_get_state_t get_state = {0};
|
||||
esp_ble_mesh_set_msg_common(&common, node, onoff_client.model, ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_GET);
|
||||
err = esp_ble_mesh_generic_client_get_state(&common, &get_state);
|
||||
if (err) {
|
||||
ESP_LOGE(TAG, "%s: Generic OnOff Get failed", __func__);
|
||||
return;
|
||||
}
|
||||
```
|
||||
|
||||
The Generic Onoff Client Model calls the `esp_ble_mesh_generic_client_set_state` API to set the state of the server Model, such as the Onoff state.
|
||||
|
||||
```c
|
||||
esp_ble_mesh_generic_client_set_state_t set_state = {0};
|
||||
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;
|
||||
}
|
||||
```
|
||||
|
||||
#### 2.3.3 The Generic Onoff Server sends message
|
||||
|
||||
The Generic Onoff Server Model has to bind its Appkey before calling the `esp_ble_mesh_server_model_send_msg` API to send a message.
|
||||
|
||||
```c
|
||||
err = esp_ble_mesh_server_model_send_msg(model, ctx, ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_STATUS,
|
||||
sizeof(send_data), &send_data);
|
||||
```
|
||||
The Generic Onoff Server Model calls the `esp_ble_mesh_model_publish` API to publish messages. Only the Models that have subscribed to this destination address receive the published messages.
|
||||
|
||||
```c
|
||||
err = esp_ble_mesh_model_publish(model, ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_STATUS,
|
||||
sizeof(led->current), &led->current, ROLE_NODE);
|
||||
```
|
||||
|
||||
### 2.4 Users Enter the Address of the Destination Node via Serial Port
|
||||
|
||||
Please connect your devices and enters the address of the destination node via the serial port.
|
||||
|
||||
Users can adjust the address of the destination node.
|
||||
|
||||
|
||||
> Note:
|
||||
> Please connect the pin 16 and pin 17 of the device that runs the `ble_mesh_client_model` project to the USB-to-UART tool.
|
||||
|
||||
```c
|
||||
#define UART1_TX_PIN GPIO_NUM_16
|
||||
#define UART1_RX_PIN GPIO_NUM_17
|
||||
```
|
||||
|
||||
The `board_uart_task` task is used to receive commands sent via the serial port, among which, the`remote_addr` represents the address of destination node that the message is forwarded to. Please enters hexadecimal string, such as 5, for this parameter. The address will be converted to 0x05 automatically.
|
||||
|
||||
```c
|
||||
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);
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
# 3. Timing Sequence Diagram
|
||||
|
||||
The steps for this demo:
|
||||
|
||||
1. The nRF Mesh App provisionings the unprovisioned devices into nodes;
|
||||
2. The nRF Mesh App adds a Appkey to these nodes, and bind the Models of these nodes to this Appkey.
|
||||
3. The nRF Mesh App sends a controlling message to the Generic Onoff Client Model. Then the Client Model forwards this message to the server Model of the other node.
|
||||
|
||||
The timing sequence diagram of this demo is shown below:
|
||||
|
||||
 <div align=center></div>
|
||||
|
||||
>Note:
|
||||
>
|
||||
>The node **only forwards the message after it receives the controlling message sent by the app**. That is said, the node will **not** forwards messages to the other nodes every time the user enters the address of the destination node through the serial port.
|
||||
|
||||
|
||||
# 4. The nRF Mesh App
|
||||
|
||||

|
||||
|
||||
1. Scan the unprovisioned devices.
|
||||
2. Identity the the capability of the unprovisioned devices.
|
||||
3. Provisioning the unprovisioned devices.
|
||||
4. Check if the Mesh node has been configured successful.
|
||||
5. Configure the Models of the nodes.
|
||||
6. Click on the Generic On Off Client option.
|
||||
7. Bind the Generic On Off Client Model to the Appkey.
|
||||
8. Check if the binding is successfully.
|
||||
9. Bind the Generic On Off Server Model to the Appkey.
|
||||
10. Send controlling messages.
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 433 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 66 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 26 KiB |
Reference in New Issue
Block a user