Bluetooth: Mesh: Wait for proxy on node reset
Adds idle wait callback to proxy by counting the number of pending notifications. Ensures that all connected nodes have received messages before resetting the mesh stack. Signed-off-by: Trond Einar Snekvik <Trond.Einar.Snekvik@nordicsemi.no>
This commit is contained in:
parent
559cf02107
commit
cb7835d18f
3 changed files with 66 additions and 6 deletions
|
@ -2622,6 +2622,8 @@ static void node_reset(struct bt_mesh_model *model,
|
|||
struct bt_mesh_msg_ctx *ctx,
|
||||
struct net_buf_simple *buf)
|
||||
{
|
||||
static struct bt_mesh_proxy_idle_cb proxy_idle = {.cb = bt_mesh_reset};
|
||||
|
||||
BT_MESH_MODEL_BUF_DEFINE(msg, OP_NODE_RESET_STATUS, 0);
|
||||
|
||||
BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s",
|
||||
|
@ -2638,7 +2640,15 @@ static void node_reset(struct bt_mesh_model *model,
|
|||
BT_ERR("Unable to send Node Reset Status");
|
||||
}
|
||||
|
||||
bt_mesh_reset();
|
||||
if (!IS_ENABLED(CONFIG_BT_MESH_GATT_PROXY)) {
|
||||
bt_mesh_reset();
|
||||
return;
|
||||
}
|
||||
|
||||
/* If the response goes to a proxy node, we'll wait for the sending to
|
||||
* complete before moving on.
|
||||
*/
|
||||
bt_mesh_proxy_on_idle(&proxy_idle);
|
||||
}
|
||||
|
||||
static void send_friend_status(struct bt_mesh_model *model,
|
||||
|
|
|
@ -103,6 +103,8 @@ static struct bt_mesh_proxy_client {
|
|||
},
|
||||
};
|
||||
|
||||
static sys_slist_t idle_waiters;
|
||||
static atomic_t pending_notifications;
|
||||
static uint8_t __noinit client_buf_data[CLIENT_BUF_SIZE * CONFIG_BT_MAX_CONN];
|
||||
|
||||
/* Track which service is enabled */
|
||||
|
@ -921,23 +923,54 @@ bool bt_mesh_proxy_relay(struct net_buf_simple *buf, uint16_t dst)
|
|||
|
||||
#endif /* CONFIG_BT_MESH_GATT_PROXY */
|
||||
|
||||
static int proxy_send(struct bt_conn *conn, const void *data, uint16_t len)
|
||||
static void notify_complete(struct bt_conn *conn, void *user_data)
|
||||
{
|
||||
sys_snode_t *n;
|
||||
|
||||
if (atomic_dec(&pending_notifications) > 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
BT_DBG("");
|
||||
|
||||
while ((n = sys_slist_get(&idle_waiters))) {
|
||||
CONTAINER_OF(n, struct bt_mesh_proxy_idle_cb, n)->cb();
|
||||
}
|
||||
}
|
||||
|
||||
static int proxy_send(struct bt_conn *conn, const void *data,
|
||||
uint16_t len)
|
||||
{
|
||||
struct bt_gatt_notify_params params = {
|
||||
.data = data,
|
||||
.len = len,
|
||||
.func = notify_complete,
|
||||
};
|
||||
int err;
|
||||
|
||||
BT_DBG("%u bytes: %s", len, bt_hex(data, len));
|
||||
|
||||
#if defined(CONFIG_BT_MESH_GATT_PROXY)
|
||||
if (gatt_svc == MESH_GATT_PROXY) {
|
||||
return bt_gatt_notify(conn, &proxy_attrs[3], data, len);
|
||||
params.attr = &proxy_attrs[3];
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_BT_MESH_PB_GATT)
|
||||
if (gatt_svc == MESH_GATT_PROV) {
|
||||
return bt_gatt_notify(conn, &prov_attrs[3], data, len);
|
||||
params.attr = &prov_attrs[3];
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
if (!params.attr) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
err = bt_gatt_notify_cb(conn, ¶ms);
|
||||
if (!err) {
|
||||
atomic_inc(&pending_notifications);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int proxy_segment_and_send(struct bt_conn *conn, uint8_t type,
|
||||
|
@ -1320,3 +1353,13 @@ int bt_mesh_proxy_init(void)
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void bt_mesh_proxy_on_idle(struct bt_mesh_proxy_idle_cb *cb)
|
||||
{
|
||||
if (!atomic_get(&pending_notifications)) {
|
||||
cb->cb();
|
||||
return;
|
||||
}
|
||||
|
||||
sys_slist_append(&idle_waiters, &cb->n);
|
||||
}
|
||||
|
|
|
@ -11,6 +11,12 @@
|
|||
#define BT_MESH_PROXY_CONFIG 0x02
|
||||
#define BT_MESH_PROXY_PROV 0x03
|
||||
|
||||
|
||||
struct bt_mesh_proxy_idle_cb {
|
||||
sys_snode_t n;
|
||||
void (*cb)(void);
|
||||
};
|
||||
|
||||
int bt_mesh_proxy_send(struct bt_conn *conn, uint8_t type,
|
||||
struct net_buf_simple *msg);
|
||||
|
||||
|
@ -35,3 +41,4 @@ bool bt_mesh_proxy_relay(struct net_buf_simple *buf, uint16_t dst);
|
|||
void bt_mesh_proxy_addr_add(struct net_buf_simple *buf, uint16_t addr);
|
||||
|
||||
int bt_mesh_proxy_init(void);
|
||||
void bt_mesh_proxy_on_idle(struct bt_mesh_proxy_idle_cb *cb);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue