doubao_chat/apps/common/ble/mesh/examples/onoff_tobe_provision.c

346 lines
8.7 KiB
C

/* Bluetooth Mesh */
/*
* Copyright (c) 2017 Intel Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "btstack/bluetooth.h"
#include "bt_common.h"
#include "api/sig_mesh_api.h"
#include "../model_api.h"
#include "provisioner_config.h"
#include "device/gpio.h"
#include "event/key_event.h"
#define LOG_TAG "[Mesh-OnOff_cli]"
#define LOG_ERROR_ENABLE
#define LOG_DEBUG_ENABLE
#define LOG_INFO_ENABLE
/* #define LOG_DUMP_ENABLE */
#define LOG_CLI_ENABLE
#include "debug.h"
#if CONFIG_BLE_MESH_ENABLE && (CONFIG_MESH_MODEL == SIG_MESH_ONOFF_TOBE_PROV)
extern u16_t primary_addr;
extern void mesh_setup(void (*init_cb)(void));
extern void bt_mac_addr_set(u8 *bt_addr);
extern void prov_complete(u16_t net_idx, u16_t addr);
extern void prov_reset(void);
/**
* @brief Config current node features(Relay/Proxy/Friend/Low Power)
*/
/*-----------------------------------------------------------*/
#define BT_MESH_FEAT_SUPPORTED_TEMP ( \
0 \
)
#include "../feature_correct.h"
const int config_bt_mesh_features = BT_MESH_FEAT_SUPPORTED;
/**
* @brief Config proxy connectable adv hardware param
*/
/*-----------------------------------------------------------*/
#if BT_MESH_FEATURES_GET(BT_MESH_FEAT_LOW_POWER)
const u16 config_bt_mesh_proxy_node_adv_interval = ADV_SCAN_UNIT(3000); // unit: ms
#else
const u16 config_bt_mesh_proxy_node_adv_interval = ADV_SCAN_UNIT(300); // unit: ms
#endif /* BT_MESH_FEATURES_GET(BT_MESH_FEAT_LOW_POWER) */
/**
* @brief Conifg complete local name
*/
/*-----------------------------------------------------------*/
#define BLE_DEV_NAME 'O', 'n', 'O', 'f', 'f', '_', 'c', 'l', 'i'
const uint8_t mesh_name[] = {
// Name
BYTE_LEN(BLE_DEV_NAME) + 1, BLUETOOTH_DATA_TYPE_COMPLETE_LOCAL_NAME, BLE_DEV_NAME,
};
void get_mesh_adv_name(u8 *len, u8 **data)
{
*len = sizeof(mesh_name);
*data = mesh_name;
}
/**
* @brief Conifg MAC of current demo
*/
/*-----------------------------------------------------------*/
#define CUR_DEVICE_MAC_ADDR 0x112233445566
/*
* Publication Declarations
*
* The publication messages are initialized to the
* the size of the opcode + content
*
* For publication, the message must be in static or global as
* it is re-transmitted several times. This occurs
* after the function that called bt_mesh_model_publish() has
* exited and the stack is no longer valid.
*
* Note that the additional 4 bytes for the AppMIC is not needed
* because it is added to a stack variable at the time a
* transmission occurs.
*
*/
BT_MESH_MODEL_PUB_DEFINE(gen_onoff_pub_cli, NULL, 2 + 2);
/* Model Operation Codes */
#define BT_MESH_MODEL_OP_GEN_ONOFF_SET BT_MESH_MODEL_OP_2(0x82, 0x02)
#define BT_MESH_MODEL_OP_GEN_ONOFF_SET_UNACK BT_MESH_MODEL_OP_2(0x82, 0x03)
#define BT_MESH_MODEL_OP_GEN_ONOFF_STATUS BT_MESH_MODEL_OP_2(0x82, 0x04)
/* Company Identifiers (see Bluetooth Assigned Numbers) */
#define BT_COMP_ID_LF 0x05D6 // Zhuhai Jieli technology Co.,Ltd
/* LED NUMBER */
#define LED0_GPIO_PIN 0
/*
* Server Configuration Declaration
*/
static struct bt_mesh_cfg_srv cfg_srv = {
.relay = BT_MESH_FEATURES_GET(BT_MESH_FEAT_RELAY),
.frnd = BT_MESH_FEATURES_GET(BT_MESH_FEAT_FRIEND),
.gatt_proxy = BT_MESH_FEATURES_GET(BT_MESH_FEAT_PROXY),
.beacon = BT_MESH_BEACON_ENABLED,
.default_ttl = 7,
};
static struct bt_mesh_cfg_cli cfg_cli;
struct onoff_state {
u8_t current;
u8_t previous;
u8_t led_gpio_pin;
};
struct _switch {
u8_t sw_num;
u8_t onoff_state;
};
static u8_t trans_id;
static struct onoff_state onoff_state[] = {
{ .led_gpio_pin = LED0_GPIO_PIN },
};
const u8 led_use_port[1] = {
IO_PORTA_03,
};
/*
* Models in an element must have unique op codes.
*
* The mesh stack dispatches a message to the first model in an element
* that is also bound to an app key and supports the op code in the
* received message.
*
*/
static void gen_onoff_status(struct bt_mesh_model *model,
struct bt_mesh_msg_ctx *ctx,
struct net_buf_simple *buf)
{
u8_t state;
state = buffer_pull_u8_from_head(buf);
log_info("Node 0x%04x OnOff status from 0x%04x with state 0x%02x\n",
bt_mesh_model_elem(model)->addr, ctx->addr, state);
}
/*
* OnOff Model Client Op Dispatch Table
*/
static const struct bt_mesh_model_op gen_onoff_cli_op[] = {
{ BT_MESH_MODEL_OP_GEN_ONOFF_STATUS, 1, gen_onoff_status },
BT_MESH_MODEL_OP_END,
};
/*
* Generic OnOff Model Server Message Handlers
*
* Mesh Model Specification 3.1.1
*/
static void gen_onoff_set_unack(struct bt_mesh_model *model,
struct bt_mesh_msg_ctx *ctx,
struct net_buf_simple *buf)
{
struct net_buf_simple *msg = model->pub->msg;
struct onoff_state *onoff_state = model->user_data;
int err;
onoff_state->current = buffer_pull_u8_from_head(buf);
log_info("addr 0x%02x state 0x%02x\n",
bt_mesh_model_elem(model)->addr, onoff_state->current);
/* log_info_hexdump((u8 *)onoff_state, sizeof(*onoff_state)); */
gpio_direction_output(onoff_state->led_gpio_pin,
onoff_state->current);
}
/*
*
* Element Model Declarations
*
* Element 0 Root Models
*/
static struct bt_mesh_model root_models[] = {
BT_MESH_MODEL_CFG_SRV(&cfg_srv),
BT_MESH_MODEL(BT_MESH_MODEL_ID_GEN_ONOFF_CLI, gen_onoff_cli_op, &gen_onoff_pub_cli, &onoff_state[0]),
};
/*
* Button to Client Model Assignments
*/
static struct bt_mesh_model *mod_cli_sw[] = {
&root_models[1],
};
/*
* LED to Server Model Assigmnents
*/
static struct bt_mesh_model *mod_srv_sw[] = {
&root_models[1],
};
/*
* Root and Secondary Element Declarations
*/
static struct bt_mesh_elem elements[] = {
BT_MESH_ELEM(0, root_models, BT_MESH_MODEL_NONE),
};
static const struct bt_mesh_comp composition = {
.cid = BT_COMP_ID_LF,
.elem = elements,
.elem_count = ARRAY_SIZE(elements),
};
static const u8_t dev_uuid[16] = {MAC_TO_LITTLE_ENDIAN(CUR_DEVICE_MAC_ADDR)};
static const struct bt_mesh_prov prov = {
.uuid = dev_uuid,
#if 0
.output_size = 6,
.output_actions = (BT_MESH_DISPLAY_NUMBER | BT_MESH_DISPLAY_STRING),
.output_number = output_number,
.output_string = output_string,
#else
.output_size = 0,
.output_actions = 0,
.output_number = 0,
#endif
.complete = prov_complete,
.reset = prov_reset,
};
static void client_publish(struct _switch *sw)
{
int err;
struct bt_mesh_model *mod_cli;
struct bt_mesh_model_pub *pub_cli;
mod_cli = mod_cli_sw[sw->sw_num];
pub_cli = mod_cli->pub;
if (pub_cli->addr == BT_MESH_ADDR_UNASSIGNED) {
return;
}
log_info("publish to 0x%04x onoff 0x%04x sw->sw_num 0x%04x\n",
pub_cli->addr, sw->onoff_state, sw->sw_num);
bt_mesh_model_msg_init(pub_cli->msg,
BT_MESH_MODEL_OP_GEN_ONOFF_SET);
buffer_add_u8_at_tail(pub_cli->msg, sw->onoff_state);
buffer_add_u8_at_tail(pub_cli->msg, trans_id++);
err = bt_mesh_model_publish(mod_cli);
if (err) {
log_error("bt_mesh_model_publish err %d\n", err);
}
}
/*
* Button Pressed Worker Task
*/
static void button_pressed_worker(struct _switch *sw)
{
if (sw->sw_num >= composition.elem_count) {
log_error("sw_num over elem_count");
return;
}
client_publish(sw);
}
static void mesh_init(void)
{
int err = bt_mesh_init(&prov, &composition);
if (err) {
log_error("Initializing mesh failed (err %d)\n", err);
return;
}
settings_load();
bt_mesh_prov_enable(BT_MESH_PROV_GATT | BT_MESH_PROV_ADV);
}
void input_key_handler(u8 key_status, u8 key_number)
{
struct _switch press_switch;
log_info("key_number=0x%x", key_number);
if ((key_number == 2) && (key_status == KEY_EVENT_LONG)) {
log_info("\n <bt_mesh_reset> \n");
bt_mesh_reset();
return;
}
switch (key_status) {
case KEY_EVENT_CLICK:
log_info(" [KEY_EVENT_CLICK] ");
press_switch.sw_num = key_number;
press_switch.onoff_state = 1;
button_pressed_worker(&press_switch);
break;
case KEY_EVENT_LONG:
log_info(" [KEY_EVENT_LONG] ");
press_switch.sw_num = key_number;
press_switch.onoff_state = 0;
button_pressed_worker(&press_switch);
break;
case KEY_EVENT_HOLD:
log_info(" [KEY_EVENT_HOLD] ");
break;
default :
return;
}
}
void bt_ble_mesh_init(void)
{
u8 bt_addr[6] = {MAC_TO_LITTLE_ENDIAN(CUR_DEVICE_MAC_ADDR)};
bt_mac_addr_set(bt_addr);
mesh_setup(mesh_init);
}
#endif /* (CONFIG_MESH_MODEL == SIG_MESH_ONOFF_TOBE_PROV) */