115 lines
2.5 KiB
C
115 lines
2.5 KiB
C
/*
|
|
* Copyright (c) 2022 Nordic Semiconductor ASA
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
#include <zephyr/bluetooth/mesh.h>
|
|
|
|
#include "foundation.h"
|
|
#include "subnet.h"
|
|
#include "solicitation.h"
|
|
|
|
#define LOG_LEVEL CONFIG_BT_MESH_MODEL_LOG_LEVEL
|
|
#include <zephyr/logging/log.h>
|
|
LOG_MODULE_REGISTER(bt_mesh_sol_pdu_rpl_srv);
|
|
|
|
static void sol_rpl_status_rsp(const struct bt_mesh_model *mod,
|
|
struct bt_mesh_msg_ctx *ctx,
|
|
uint16_t range,
|
|
uint8_t len)
|
|
{
|
|
BT_MESH_MODEL_BUF_DEFINE(buf, OP_SOL_PDU_RPL_ITEM_STATUS, 2 + (len < 2 ? 0 : 1));
|
|
|
|
bt_mesh_model_msg_init(&buf, OP_SOL_PDU_RPL_ITEM_STATUS);
|
|
|
|
net_buf_simple_add_le16(&buf, range);
|
|
|
|
if (len >= 2) {
|
|
net_buf_simple_add_u8(&buf, len);
|
|
}
|
|
|
|
bt_mesh_model_send(mod, ctx, &buf, NULL, NULL);
|
|
}
|
|
|
|
static int item_clear(const struct bt_mesh_model *mod,
|
|
struct bt_mesh_msg_ctx *ctx,
|
|
struct net_buf_simple *buf,
|
|
bool acked)
|
|
{
|
|
uint16_t primary, range;
|
|
uint8_t len = 0;
|
|
|
|
LOG_DBG("");
|
|
|
|
if (buf->len > 3) {
|
|
return -EMSGSIZE;
|
|
}
|
|
|
|
range = net_buf_simple_pull_le16(buf);
|
|
primary = range >> 1;
|
|
|
|
LOG_DBG("Start address: 0x%02x, %d", primary, buf->len);
|
|
if (range & BIT(0)) {
|
|
if (buf->len == 0) {
|
|
return -EMSGSIZE;
|
|
}
|
|
|
|
len = net_buf_simple_pull_u8(buf);
|
|
|
|
if (len < 2) {
|
|
return -EINVAL;
|
|
}
|
|
}
|
|
|
|
if ((primary + len) > 0x8000 || primary == 0) {
|
|
LOG_WRN("Range outside unicast address range or equal to 0");
|
|
return -EINVAL;
|
|
}
|
|
|
|
for (int i = 0; i < len || i == 0; i++) {
|
|
bt_mesh_srpl_entry_clear(primary + i);
|
|
}
|
|
|
|
if (acked) {
|
|
sol_rpl_status_rsp(mod, ctx, range, len);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int handle_item_clear(const struct bt_mesh_model *mod,
|
|
struct bt_mesh_msg_ctx *ctx,
|
|
struct net_buf_simple *buf)
|
|
{
|
|
return item_clear(mod, ctx, buf, true);
|
|
}
|
|
|
|
static int handle_item_clear_unacked(const struct bt_mesh_model *mod,
|
|
struct bt_mesh_msg_ctx *ctx,
|
|
struct net_buf_simple *buf)
|
|
{
|
|
return item_clear(mod, ctx, buf, false);
|
|
}
|
|
|
|
const struct bt_mesh_model_op _bt_mesh_sol_pdu_rpl_srv_op[] = {
|
|
{ OP_SOL_PDU_RPL_ITEM_CLEAR, BT_MESH_LEN_MIN(2), handle_item_clear },
|
|
{ OP_SOL_PDU_RPL_ITEM_CLEAR_UNACKED, BT_MESH_LEN_MIN(2), handle_item_clear_unacked },
|
|
|
|
BT_MESH_MODEL_OP_END
|
|
};
|
|
|
|
static int sol_pdu_rpl_srv_init(const struct bt_mesh_model *mod)
|
|
{
|
|
if (!bt_mesh_model_in_primary(mod)) {
|
|
LOG_ERR("Solicitation PDU RPL Configuration server not in primary element");
|
|
return -EINVAL;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
const struct bt_mesh_model_cb _bt_mesh_sol_pdu_rpl_srv_cb = {
|
|
.init = sol_pdu_rpl_srv_init,
|
|
};
|