Bluetooth: Mesh: access tx msg randomizer
Commit adds implementation of the specification recommendations regarding randomization of responses on the access layer. 3.7.3.1 Transmitting an Access messages Signed-off-by: Aleksandr Khromykh <aleksandr.khromykh@nordicsemi.no>
This commit is contained in:
parent
3533178713
commit
d175ac0572
12 changed files with 460 additions and 0 deletions
|
@ -222,6 +222,39 @@ They are used to represent the new content of the mirrored pages when the Compos
|
|||
change after a firmware update. See :ref:`bluetooth_mesh_dfu_srv_comp_data_and_models_metadata`
|
||||
for details.
|
||||
|
||||
Delayable messages
|
||||
==================
|
||||
|
||||
The delayable message functionality is enabled with Kconfig option
|
||||
:kconfig:option:`CONFIG_BT_MESH_ACCESS_DELAYABLE_MSG`.
|
||||
This is an optional functionality that implements specification recommendations for
|
||||
messages that are transmitted by a model in a response to a received message, also called
|
||||
response messages.
|
||||
|
||||
Response messages should be sent with the following random delays:
|
||||
|
||||
* Between 20 and 50 milliseconds if the received message was sent
|
||||
to a unicast address
|
||||
* Between 20 and 500 milliseconds if the received message was sent
|
||||
to a group or virtual address
|
||||
|
||||
The delayable message functionality is triggered if the :c:member:`bt_mesh_msg_ctx.rnd_delay`
|
||||
flag is set.
|
||||
The delayable message functionality stores messages in the local memory while they are
|
||||
waiting for the random delay expiration.
|
||||
|
||||
If the transport layer doesn't have sufficient memory to send a message at the moment
|
||||
the random delay expires, the message is postponed for another 10 milliseconds.
|
||||
If the transport layer cannot send a message for any other reason, the delayable message
|
||||
functionality raises the :c:member:`bt_mesh_send_cb.start` callback with a transport layer
|
||||
error code.
|
||||
|
||||
If the delayable message functionality cannot find enough free memory to store an incoming
|
||||
message, it will send messages with delay close to expiration to free memory.
|
||||
|
||||
When the mesh stack is suspended or reset, messages not yet sent are removed and
|
||||
the :c:member:`bt_mesh_send_cb.start` callback is raised with an error code.
|
||||
|
||||
API reference
|
||||
*************
|
||||
|
||||
|
|
|
@ -52,6 +52,11 @@ Bluetooth
|
|||
|
||||
* Mesh
|
||||
|
||||
* Added the delayable messages functionality to apply random delays for
|
||||
the transmitted responses on the Access layer.
|
||||
The functionality is enabled by the :kconfig:option:`CONFIG_BT_MESH_ACCESS_DELAYABLE_MSG`
|
||||
Kconfig option.
|
||||
|
||||
* Controller
|
||||
|
||||
Boards & SoC Support
|
||||
|
|
|
@ -98,6 +98,9 @@ struct bt_mesh_msg_ctx {
|
|||
/** Force sending reliably by using segment acknowledgment */
|
||||
bool send_rel;
|
||||
|
||||
/** Send message with a random delay according to the Access layer transmitting rules. */
|
||||
bool rnd_delay;
|
||||
|
||||
/** TTL, or BT_MESH_TTL_DEFAULT for default TTL. */
|
||||
uint8_t send_ttl;
|
||||
};
|
||||
|
|
|
@ -32,3 +32,4 @@ CONFIG_BT_MESH_SUBNET_COUNT=1
|
|||
CONFIG_BT_MESH_APP_KEY_COUNT=1
|
||||
CONFIG_BT_MESH_MODEL_GROUP_COUNT=1
|
||||
CONFIG_BT_MESH_LABEL_COUNT=0
|
||||
CONFIG_BT_MESH_ACCESS_DELAYABLE_MSG=n
|
||||
|
|
|
@ -22,3 +22,4 @@ CONFIG_BT_MESH_BEACON_ENABLED=n
|
|||
CONFIG_BT_MESH_LABEL_COUNT=1
|
||||
|
||||
CONFIG_BT_MESH_SETTINGS_WORKQ=n
|
||||
CONFIG_BT_MESH_ACCESS_DELAYABLE_MSG=n
|
||||
|
|
|
@ -122,6 +122,8 @@ zephyr_library_sources_ifdef(CONFIG_BT_MESH_SOLICITATION solicitation.c)
|
|||
|
||||
zephyr_library_sources_ifdef(CONFIG_BT_MESH_STATISTIC statistic.c)
|
||||
|
||||
zephyr_library_sources_ifdef(CONFIG_BT_MESH_ACCESS_DELAYABLE_MSG delayable_msg.c)
|
||||
|
||||
if (CONFIG_BT_MESH_USES_TINYCRYPT)
|
||||
zephyr_library_sources(crypto_tc.c)
|
||||
else()
|
||||
|
|
|
@ -628,6 +628,41 @@ config BT_MESH_LABEL_NO_RECOVER
|
|||
unprovisioned before upgrading to the version with this option). The option is marked as
|
||||
deprecated to remove the recovery code eventually.
|
||||
|
||||
menuconfig BT_MESH_ACCESS_DELAYABLE_MSG
|
||||
bool "Access layer tx delayable message"
|
||||
help
|
||||
Enable following of the message transmitting recommendations, the Access layer
|
||||
specification. The recommendations are optional.
|
||||
However, they are strictly recommended if the device participates in the network with
|
||||
intensive communication where the device receives a lot of requests that require responses.
|
||||
|
||||
if BT_MESH_ACCESS_DELAYABLE_MSG
|
||||
|
||||
config BT_MESH_ACCESS_DELAYABLE_MSG_COUNT
|
||||
int "Number of simultaneously delayed messages"
|
||||
default 4
|
||||
help
|
||||
The maximum number of messages the Access layer can manage to delay
|
||||
at the same time. The number of messages can be handled only if the Access layer
|
||||
has a sufficient amount of memory to store the model payload for them.
|
||||
|
||||
config BT_MESH_ACCESS_DELAYABLE_MSG_CHUNK_SIZE
|
||||
int "Maximum delayable message storage chunk"
|
||||
default 20
|
||||
help
|
||||
Size of memory that Access layer uses to split model message to. It allocates
|
||||
a sufficient number of these chunks from the pool to store the full model payload.
|
||||
|
||||
config BT_MESH_ACCESS_DELAYABLE_MSG_CHUNK_COUNT
|
||||
int "Maximum number of available chunks"
|
||||
default 20
|
||||
help
|
||||
The maximum number of available chunks the Access layer allocates to store model payload.
|
||||
It is recommended to keep chunk size equal to the reasonable small value to prevent
|
||||
unnecessary memory wasting.
|
||||
|
||||
endif # BT_MESH_ACCESS_DELAYABLE_MSG
|
||||
|
||||
endmenu # Access layer
|
||||
|
||||
menu "Models"
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include "op_agg.h"
|
||||
#include "settings.h"
|
||||
#include "va.h"
|
||||
#include "delayable_msg.h"
|
||||
|
||||
#define LOG_LEVEL CONFIG_BT_MESH_ACCESS_LOG_LEVEL
|
||||
#include <zephyr/logging/log.h>
|
||||
|
@ -1518,6 +1519,13 @@ int bt_mesh_model_send(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
#if defined CONFIG_BT_MESH_ACCESS_DELAYABLE_MSG
|
||||
if (ctx->rnd_delay) {
|
||||
return bt_mesh_delayable_msg_manage(ctx, msg, bt_mesh_model_elem(model)->rt->addr,
|
||||
cb, cb_data);
|
||||
}
|
||||
#endif
|
||||
|
||||
return bt_mesh_access_send(ctx, msg, bt_mesh_model_elem(model)->rt->addr, cb, cb_data);
|
||||
}
|
||||
|
||||
|
@ -2613,3 +2621,24 @@ uint8_t bt_mesh_comp_parse_page(struct net_buf_simple *buf)
|
|||
|
||||
return page;
|
||||
}
|
||||
|
||||
void bt_mesh_access_init(void)
|
||||
{
|
||||
#if defined CONFIG_BT_MESH_ACCESS_DELAYABLE_MSG
|
||||
bt_mesh_delayable_msg_init();
|
||||
#endif
|
||||
}
|
||||
|
||||
void bt_mesh_access_suspend(void)
|
||||
{
|
||||
#if defined CONFIG_BT_MESH_ACCESS_DELAYABLE_MSG
|
||||
bt_mesh_delayable_msg_stop();
|
||||
#endif
|
||||
}
|
||||
|
||||
void bt_mesh_access_reset(void)
|
||||
{
|
||||
#if defined CONFIG_BT_MESH_ACCESS_DELAYABLE_MSG
|
||||
bt_mesh_delayable_msg_stop();
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -96,8 +96,25 @@ void bt_mesh_msg_cb_set(void (*cb)(uint32_t opcode, struct bt_mesh_msg_ctx *ctx,
|
|||
*
|
||||
* @param ctx The Bluetooth Mesh message context.
|
||||
* @param buf The message payload.
|
||||
* @param src_addr The source address of model
|
||||
* @param cb Callback function.
|
||||
* @param cb_data Callback data.
|
||||
*
|
||||
* @return 0 on success or negative error code on failure.
|
||||
*/
|
||||
int bt_mesh_access_send(struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf, uint16_t src_addr,
|
||||
const struct bt_mesh_send_cb *cb, void *cb_data);
|
||||
|
||||
/** @brief Initialize the Access layer.
|
||||
*
|
||||
* Initialize the delayable message mechanism if it has been enabled.
|
||||
*/
|
||||
void bt_mesh_access_init(void);
|
||||
|
||||
/** @brief Suspend the Access layer.
|
||||
*/
|
||||
void bt_mesh_access_suspend(void);
|
||||
|
||||
/** @brief Reset the Access layer.
|
||||
*/
|
||||
void bt_mesh_access_reset(void);
|
||||
|
|
314
subsys/bluetooth/mesh/delayable_msg.c
Normal file
314
subsys/bluetooth/mesh/delayable_msg.c
Normal file
|
@ -0,0 +1,314 @@
|
|||
/*
|
||||
* Copyright (c) 2023 Nordic Semiconductor ASA
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <zephyr/kernel.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <zephyr/sys/slist.h>
|
||||
|
||||
#include <zephyr/net/buf.h>
|
||||
#include <zephyr/bluetooth/mesh.h>
|
||||
|
||||
#include "msg.h"
|
||||
#include "access.h"
|
||||
#include "net.h"
|
||||
|
||||
#define LOG_LEVEL CONFIG_BT_MESH_ACCESS_LOG_LEVEL
|
||||
#include <zephyr/logging/log.h>
|
||||
LOG_MODULE_REGISTER(bt_mesh_delayable_msg);
|
||||
|
||||
static void delayable_msg_handler(struct k_work *w);
|
||||
static bool push_msg_from_delayable_msgs(void);
|
||||
|
||||
static struct delayable_msg_chunk {
|
||||
sys_snode_t node;
|
||||
uint8_t data[CONFIG_BT_MESH_ACCESS_DELAYABLE_MSG_CHUNK_SIZE];
|
||||
} delayable_msg_chunks[CONFIG_BT_MESH_ACCESS_DELAYABLE_MSG_CHUNK_COUNT];
|
||||
|
||||
static struct delayable_msg_ctx {
|
||||
sys_snode_t node;
|
||||
sys_slist_t chunks;
|
||||
struct bt_mesh_msg_ctx ctx;
|
||||
uint16_t src_addr;
|
||||
const struct bt_mesh_send_cb *cb;
|
||||
void *cb_data;
|
||||
uint32_t fired_time;
|
||||
uint16_t len;
|
||||
} delayable_msgs_ctx[CONFIG_BT_MESH_ACCESS_DELAYABLE_MSG_COUNT];
|
||||
|
||||
static struct {
|
||||
sys_slist_t busy_ctx;
|
||||
sys_slist_t free_ctx;
|
||||
sys_slist_t free_chunks;
|
||||
struct k_work_delayable random_delay;
|
||||
} access_delayable_msg = {.random_delay = Z_WORK_DELAYABLE_INITIALIZER(delayable_msg_handler)};
|
||||
|
||||
static void put_ctx_to_busy_list(struct delayable_msg_ctx *ctx)
|
||||
{
|
||||
struct delayable_msg_ctx *curr_ctx;
|
||||
sys_slist_t *list = &access_delayable_msg.busy_ctx;
|
||||
sys_snode_t *head = sys_slist_peek_head(list);
|
||||
sys_snode_t *curr = head;
|
||||
sys_snode_t *prev = curr;
|
||||
|
||||
if (!head) {
|
||||
sys_slist_append(list, &ctx->node);
|
||||
return;
|
||||
}
|
||||
|
||||
do {
|
||||
curr_ctx = CONTAINER_OF(curr, struct delayable_msg_ctx, node);
|
||||
if (ctx->fired_time < curr_ctx->fired_time) {
|
||||
if (curr == head) {
|
||||
sys_slist_prepend(list, &ctx->node);
|
||||
} else {
|
||||
sys_slist_insert(list, prev, &ctx->node);
|
||||
}
|
||||
return;
|
||||
}
|
||||
prev = curr;
|
||||
} while ((curr = sys_slist_peek_next(curr)));
|
||||
|
||||
sys_slist_append(list, &ctx->node);
|
||||
}
|
||||
|
||||
static struct delayable_msg_ctx *peek_pending_msg(void)
|
||||
{
|
||||
struct delayable_msg_ctx *pending_msg = NULL;
|
||||
sys_snode_t *node = sys_slist_peek_head(&access_delayable_msg.busy_ctx);
|
||||
|
||||
if (node) {
|
||||
pending_msg = CONTAINER_OF(node, struct delayable_msg_ctx, node);
|
||||
}
|
||||
|
||||
return pending_msg;
|
||||
}
|
||||
|
||||
static void reschedule_delayable_msg(struct delayable_msg_ctx *msg)
|
||||
{
|
||||
uint32_t curr_time;
|
||||
k_timeout_t delay = K_NO_WAIT;
|
||||
struct delayable_msg_ctx *pending_msg;
|
||||
|
||||
if (msg) {
|
||||
put_ctx_to_busy_list(msg);
|
||||
}
|
||||
|
||||
pending_msg = peek_pending_msg();
|
||||
|
||||
if (!pending_msg) {
|
||||
return;
|
||||
}
|
||||
|
||||
curr_time = k_uptime_get_32();
|
||||
if (curr_time < pending_msg->fired_time) {
|
||||
delay = K_MSEC(pending_msg->fired_time - curr_time);
|
||||
}
|
||||
|
||||
k_work_reschedule(&access_delayable_msg.random_delay, delay);
|
||||
}
|
||||
|
||||
static int allocate_delayable_msg_chunks(struct delayable_msg_ctx *msg, int number)
|
||||
{
|
||||
sys_snode_t *node;
|
||||
|
||||
for (int i = 0; i < number; i++) {
|
||||
node = sys_slist_get(&access_delayable_msg.free_chunks);
|
||||
if (!node) {
|
||||
LOG_WRN("Unable allocate %u chunks, allocated %u", number, i);
|
||||
return i;
|
||||
}
|
||||
sys_slist_append(&msg->chunks, node);
|
||||
}
|
||||
|
||||
return number;
|
||||
}
|
||||
|
||||
static void release_delayable_msg_chunks(struct delayable_msg_ctx *msg)
|
||||
{
|
||||
sys_snode_t *node;
|
||||
|
||||
while ((node = sys_slist_get(&msg->chunks))) {
|
||||
sys_slist_append(&access_delayable_msg.free_chunks, node);
|
||||
}
|
||||
}
|
||||
|
||||
static struct delayable_msg_ctx *allocate_delayable_msg_ctx(void)
|
||||
{
|
||||
struct delayable_msg_ctx *msg;
|
||||
sys_snode_t *node;
|
||||
|
||||
if (sys_slist_is_empty(&access_delayable_msg.free_ctx)) {
|
||||
LOG_WRN("Purge pending delayable message.");
|
||||
if (!push_msg_from_delayable_msgs()) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
node = sys_slist_get(&access_delayable_msg.free_ctx);
|
||||
msg = CONTAINER_OF(node, struct delayable_msg_ctx, node);
|
||||
sys_slist_init(&msg->chunks);
|
||||
|
||||
return msg;
|
||||
}
|
||||
|
||||
static void release_delayable_msg_ctx(struct delayable_msg_ctx *ctx)
|
||||
{
|
||||
if (sys_slist_find_and_remove(&access_delayable_msg.busy_ctx, &ctx->node)) {
|
||||
sys_slist_append(&access_delayable_msg.free_ctx, &ctx->node);
|
||||
}
|
||||
}
|
||||
|
||||
static bool push_msg_from_delayable_msgs(void)
|
||||
{
|
||||
sys_snode_t *node;
|
||||
struct delayable_msg_chunk *chunk;
|
||||
struct delayable_msg_ctx *msg = peek_pending_msg();
|
||||
uint16_t len = msg->len;
|
||||
int err;
|
||||
|
||||
if (!msg) {
|
||||
return false;
|
||||
}
|
||||
|
||||
NET_BUF_SIMPLE_DEFINE(buf, BT_MESH_TX_SDU_MAX);
|
||||
|
||||
SYS_SLIST_FOR_EACH_NODE(&msg->chunks, node) {
|
||||
uint16_t tmp = MIN(CONFIG_BT_MESH_ACCESS_DELAYABLE_MSG_CHUNK_SIZE, len);
|
||||
|
||||
chunk = CONTAINER_OF(node, struct delayable_msg_chunk, node);
|
||||
memcpy(net_buf_simple_add(&buf, tmp), chunk->data, tmp);
|
||||
len -= tmp;
|
||||
}
|
||||
|
||||
msg->ctx.rnd_delay = false;
|
||||
err = bt_mesh_access_send(&msg->ctx, &buf, msg->src_addr, msg->cb, msg->cb_data);
|
||||
msg->ctx.rnd_delay = true;
|
||||
|
||||
if (err == -EBUSY || err == -ENOBUFS) {
|
||||
return false;
|
||||
}
|
||||
|
||||
release_delayable_msg_chunks(msg);
|
||||
release_delayable_msg_ctx(msg);
|
||||
|
||||
if (err && msg->cb && msg->cb->start) {
|
||||
msg->cb->start(0, err, msg->cb_data);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void delayable_msg_handler(struct k_work *w)
|
||||
{
|
||||
if (!push_msg_from_delayable_msgs()) {
|
||||
sys_snode_t *node = sys_slist_get(&access_delayable_msg.busy_ctx);
|
||||
struct delayable_msg_ctx *pending_msg =
|
||||
CONTAINER_OF(node, struct delayable_msg_ctx, node);
|
||||
|
||||
pending_msg->fired_time += 10;
|
||||
reschedule_delayable_msg(pending_msg);
|
||||
} else {
|
||||
reschedule_delayable_msg(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
int bt_mesh_delayable_msg_manage(struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf,
|
||||
uint16_t src_addr, const struct bt_mesh_send_cb *cb, void *cb_data)
|
||||
{
|
||||
sys_snode_t *node;
|
||||
struct delayable_msg_ctx *msg;
|
||||
uint16_t random_delay;
|
||||
int total_number = DIV_ROUND_UP(buf->size, CONFIG_BT_MESH_ACCESS_DELAYABLE_MSG_CHUNK_SIZE);
|
||||
int allocated_number = 0;
|
||||
uint16_t len = buf->len;
|
||||
|
||||
if (atomic_test_bit(bt_mesh.flags, BT_MESH_SUSPENDED)) {
|
||||
LOG_WRN("Refusing to allocate message context while suspended");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
if (total_number > CONFIG_BT_MESH_ACCESS_DELAYABLE_MSG_CHUNK_COUNT) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
msg = allocate_delayable_msg_ctx();
|
||||
if (!msg) {
|
||||
LOG_WRN("No available free delayable message context.");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
do {
|
||||
allocated_number +=
|
||||
allocate_delayable_msg_chunks(msg, total_number - allocated_number);
|
||||
|
||||
if (total_number > allocated_number) {
|
||||
LOG_DBG("Unable allocate %u chunks, allocated %u", total_number,
|
||||
allocated_number);
|
||||
if (!push_msg_from_delayable_msgs()) {
|
||||
LOG_WRN("No available chunk memory.");
|
||||
release_delayable_msg_chunks(msg);
|
||||
release_delayable_msg_ctx(msg);
|
||||
return -ENOMEM;
|
||||
}
|
||||
}
|
||||
} while (total_number > allocated_number);
|
||||
|
||||
SYS_SLIST_FOR_EACH_NODE(&msg->chunks, node) {
|
||||
uint16_t tmp = MIN(CONFIG_BT_MESH_ACCESS_DELAYABLE_MSG_CHUNK_SIZE, buf->len);
|
||||
|
||||
struct delayable_msg_chunk *chunk =
|
||||
CONTAINER_OF(node, struct delayable_msg_chunk, node);
|
||||
|
||||
memcpy(chunk->data, net_buf_simple_pull_mem(buf, tmp), tmp);
|
||||
}
|
||||
|
||||
bt_rand(&random_delay, sizeof(uint16_t));
|
||||
random_delay = 20 + random_delay % (BT_MESH_ADDR_IS_UNICAST(ctx->recv_dst) ? 30 : 480);
|
||||
msg->fired_time = k_uptime_get_32() + random_delay;
|
||||
msg->ctx = *ctx;
|
||||
msg->src_addr = src_addr;
|
||||
msg->cb = cb;
|
||||
msg->cb_data = cb_data;
|
||||
msg->len = len;
|
||||
|
||||
reschedule_delayable_msg(msg);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void bt_mesh_delayable_msg_init(void)
|
||||
{
|
||||
sys_slist_init(&access_delayable_msg.busy_ctx);
|
||||
sys_slist_init(&access_delayable_msg.free_ctx);
|
||||
sys_slist_init(&access_delayable_msg.free_chunks);
|
||||
|
||||
for (int i = 0; i < CONFIG_BT_MESH_ACCESS_DELAYABLE_MSG_COUNT; i++) {
|
||||
sys_slist_append(&access_delayable_msg.free_ctx, &delayable_msgs_ctx[i].node);
|
||||
}
|
||||
|
||||
for (int i = 0; i < CONFIG_BT_MESH_ACCESS_DELAYABLE_MSG_CHUNK_COUNT; i++) {
|
||||
sys_slist_append(&access_delayable_msg.free_chunks, &delayable_msg_chunks[i].node);
|
||||
}
|
||||
}
|
||||
|
||||
void bt_mesh_delayable_msg_stop(void)
|
||||
{
|
||||
sys_snode_t *node;
|
||||
struct delayable_msg_ctx *ctx;
|
||||
|
||||
k_work_cancel_delayable(&access_delayable_msg.random_delay);
|
||||
|
||||
while ((node = sys_slist_peek_head(&access_delayable_msg.busy_ctx))) {
|
||||
ctx = CONTAINER_OF(node, struct delayable_msg_ctx, node);
|
||||
release_delayable_msg_chunks(ctx);
|
||||
release_delayable_msg_ctx(ctx);
|
||||
|
||||
if (ctx->cb && ctx->cb->start) {
|
||||
ctx->cb->start(0, -ENODEV, ctx->cb_data);
|
||||
}
|
||||
}
|
||||
}
|
16
subsys/bluetooth/mesh/delayable_msg.h
Normal file
16
subsys/bluetooth/mesh/delayable_msg.h
Normal file
|
@ -0,0 +1,16 @@
|
|||
/*
|
||||
* Copyright (c) 2023 Nordic Semiconductor ASA
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef ZEPHYR_INCLUDE_BLUETOOTH_MESH_DELAYABLE_MSG_H__
|
||||
#define ZEPHYR_INCLUDE_BLUETOOTH_MESH_DELAYABLE_MSG_H__
|
||||
|
||||
int bt_mesh_delayable_msg_manage(struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf,
|
||||
uint16_t src_addr, const struct bt_mesh_send_cb *cb,
|
||||
void *cb_data);
|
||||
void bt_mesh_delayable_msg_init(void);
|
||||
void bt_mesh_delayable_msg_stop(void);
|
||||
|
||||
#endif /* ZEPHYR_INCLUDE_BLUETOOTH_MESH_DELAYABLE_MSG_H__ */
|
|
@ -359,6 +359,7 @@ void bt_mesh_reset(void)
|
|||
*/
|
||||
(void)k_work_cancel_delayable(&bt_mesh.ivu_timer);
|
||||
|
||||
bt_mesh_access_reset();
|
||||
bt_mesh_model_reset();
|
||||
bt_mesh_cfg_default_set();
|
||||
bt_mesh_trans_reset();
|
||||
|
@ -459,6 +460,8 @@ int bt_mesh_suspend(void)
|
|||
|
||||
bt_mesh_model_foreach(model_suspend, NULL);
|
||||
|
||||
bt_mesh_access_suspend();
|
||||
|
||||
err = bt_mesh_adv_disable();
|
||||
if (err) {
|
||||
atomic_clear_bit(bt_mesh.flags, BT_MESH_SUSPENDED);
|
||||
|
@ -558,6 +561,7 @@ int bt_mesh_init(const struct bt_mesh_prov *prov,
|
|||
bt_mesh_cfg_default_set();
|
||||
bt_mesh_net_init();
|
||||
bt_mesh_trans_init();
|
||||
bt_mesh_access_init();
|
||||
bt_mesh_hb_init();
|
||||
bt_mesh_beacon_init();
|
||||
bt_mesh_adv_init();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue