Bluetooth: Mesh: Op agg mdl coex
Refactors the implementation of the Opcode Aggregator models to allow them to coexist on the same device. Signed-off-by: Anders Storrø <anders.storro@nordicsemi.no>
This commit is contained in:
parent
31081d8411
commit
0a25a61c7d
5 changed files with 141 additions and 157 deletions
|
@ -1506,8 +1506,10 @@ int bt_mesh_model_send(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx,
|
||||||
struct net_buf_simple *msg,
|
struct net_buf_simple *msg,
|
||||||
const struct bt_mesh_send_cb *cb, void *cb_data)
|
const struct bt_mesh_send_cb *cb, void *cb_data)
|
||||||
{
|
{
|
||||||
if (IS_ENABLED(CONFIG_BT_MESH_OP_AGG) && bt_mesh_op_agg_accept(ctx)) {
|
if (IS_ENABLED(CONFIG_BT_MESH_OP_AGG_SRV) && bt_mesh_op_agg_srv_accept(ctx, msg)) {
|
||||||
return bt_mesh_op_agg_send(model, ctx, msg, cb);
|
return bt_mesh_op_agg_srv_send(model, msg);
|
||||||
|
} else if (IS_ENABLED(CONFIG_BT_MESH_OP_AGG_CLI) && bt_mesh_op_agg_cli_accept(ctx, msg)) {
|
||||||
|
return bt_mesh_op_agg_cli_send(model, msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!bt_mesh_model_has_key(model, ctx->app_idx)) {
|
if (!bt_mesh_model_has_key(model, ctx->app_idx)) {
|
||||||
|
|
|
@ -16,83 +16,22 @@ LOG_MODULE_REGISTER(bt_mesh_op_agg);
|
||||||
#define IS_LENGTH_LONG(buf) ((buf)->data[0] & 1)
|
#define IS_LENGTH_LONG(buf) ((buf)->data[0] & 1)
|
||||||
#define LENGTH_SHORT_MAX BIT_MASK(7)
|
#define LENGTH_SHORT_MAX BIT_MASK(7)
|
||||||
|
|
||||||
NET_BUF_SIMPLE_DEFINE_STATIC(sdu, BT_MESH_TX_SDU_MAX);
|
int bt_mesh_op_agg_encode_msg(struct net_buf_simple *msg, struct net_buf_simple *buf)
|
||||||
NET_BUF_SIMPLE_DEFINE_STATIC(srcs, BT_MESH_TX_SDU_MAX);
|
|
||||||
|
|
||||||
static struct op_agg_ctx agg_ctx = {
|
|
||||||
.sdu = &sdu,
|
|
||||||
#if IS_ENABLED(CONFIG_BT_MESH_OP_AGG_CLI)
|
|
||||||
.srcs = &srcs,
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
struct op_agg_ctx *bt_mesh_op_agg_ctx_get(void)
|
|
||||||
{
|
|
||||||
return &agg_ctx;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool ctx_match(struct bt_mesh_msg_ctx *ctx)
|
|
||||||
{
|
|
||||||
return (ctx->net_idx == agg_ctx.net_idx) && (ctx->addr == agg_ctx.addr) &&
|
|
||||||
(ctx->app_idx == agg_ctx.app_idx);
|
|
||||||
}
|
|
||||||
|
|
||||||
int bt_mesh_op_agg_accept(struct bt_mesh_msg_ctx *msg_ctx)
|
|
||||||
{
|
|
||||||
return agg_ctx.initialized && ctx_match(msg_ctx);
|
|
||||||
}
|
|
||||||
|
|
||||||
void bt_mesh_op_agg_ctx_reinit(void)
|
|
||||||
{
|
|
||||||
agg_ctx.initialized = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
int bt_mesh_op_agg_send(struct bt_mesh_model *model,
|
|
||||||
struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *msg,
|
|
||||||
const struct bt_mesh_send_cb *cb)
|
|
||||||
{
|
|
||||||
int err;
|
|
||||||
|
|
||||||
/* Model responded so mark this message as acknowledged */
|
|
||||||
agg_ctx.ack = true;
|
|
||||||
|
|
||||||
if (IS_ENABLED(CONFIG_BT_MESH_OP_AGG_CLI)) {
|
|
||||||
/* Store source address so that Opcodes Aggregator Client can
|
|
||||||
* match response with source model
|
|
||||||
*/
|
|
||||||
uint16_t src = bt_mesh_model_elem(model)->addr;
|
|
||||||
|
|
||||||
if (net_buf_simple_tailroom(&srcs) < 2) {
|
|
||||||
return -ENOMEM;
|
|
||||||
}
|
|
||||||
|
|
||||||
net_buf_simple_add_le16(&srcs, src);
|
|
||||||
}
|
|
||||||
|
|
||||||
err = bt_mesh_op_agg_encode_msg(msg);
|
|
||||||
if (err) {
|
|
||||||
agg_ctx.rsp_err = ACCESS_STATUS_RESPONSE_OVERFLOW;
|
|
||||||
}
|
|
||||||
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
int bt_mesh_op_agg_encode_msg(struct net_buf_simple *msg)
|
|
||||||
{
|
{
|
||||||
if (msg->len > LENGTH_SHORT_MAX) {
|
if (msg->len > LENGTH_SHORT_MAX) {
|
||||||
if (net_buf_simple_tailroom(agg_ctx.sdu) < (msg->len + 2)) {
|
if (net_buf_simple_tailroom(buf) < (msg->len + 2)) {
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
net_buf_simple_add_le16(agg_ctx.sdu, (msg->len << 1) | 1);
|
net_buf_simple_add_le16(buf, (msg->len << 1) | 1);
|
||||||
} else {
|
} else {
|
||||||
if (net_buf_simple_tailroom(agg_ctx.sdu) < (msg->len + 1)) {
|
if (net_buf_simple_tailroom(buf) < (msg->len + 1)) {
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
net_buf_simple_add_u8(agg_ctx.sdu, msg->len << 1);
|
net_buf_simple_add_u8(buf, msg->len << 1);
|
||||||
}
|
}
|
||||||
net_buf_simple_add_mem(agg_ctx.sdu, msg->data, msg->len);
|
net_buf_simple_add_mem(buf, msg->data, msg->len);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -124,3 +63,21 @@ int bt_mesh_op_agg_decode_msg(struct net_buf_simple *msg,
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool bt_mesh_op_agg_is_op_agg_msg(struct net_buf_simple *buf)
|
||||||
|
{
|
||||||
|
if (buf->len >= 2 && (buf->data[0] >> 6) == 2) {
|
||||||
|
uint16_t opcode;
|
||||||
|
struct net_buf_simple_state state;
|
||||||
|
|
||||||
|
net_buf_simple_save(buf, &state);
|
||||||
|
opcode = net_buf_simple_pull_be16(buf);
|
||||||
|
net_buf_simple_restore(buf, &state);
|
||||||
|
|
||||||
|
if ((opcode == OP_OPCODES_AGGREGATOR_STATUS) ||
|
||||||
|
(opcode == OP_OPCODES_AGGREGATOR_SEQUENCE)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
|
@ -7,45 +7,20 @@
|
||||||
struct op_agg_ctx {
|
struct op_agg_ctx {
|
||||||
/** Context is initialized. */
|
/** Context is initialized. */
|
||||||
bool initialized;
|
bool initialized;
|
||||||
|
|
||||||
/** NetKey Index of the subnet to send the message on. */
|
/** NetKey Index of the subnet to send the message on. */
|
||||||
uint16_t net_idx;
|
uint16_t net_idx;
|
||||||
|
|
||||||
/** AppKey Index to encrypt the message with. */
|
/** AppKey Index to encrypt the message with. */
|
||||||
uint16_t app_idx;
|
uint16_t app_idx;
|
||||||
|
|
||||||
/** Remote element address. */
|
/** Remote element address. */
|
||||||
uint16_t addr;
|
uint16_t addr;
|
||||||
|
|
||||||
/** List of source element addresses.
|
|
||||||
* Used by Client to match aggregated responses
|
|
||||||
* with local source client models.
|
|
||||||
*/
|
|
||||||
struct net_buf_simple *srcs;
|
|
||||||
|
|
||||||
/** Response error code. */
|
|
||||||
int rsp_err;
|
|
||||||
|
|
||||||
/** Aggregated message buffer. */
|
/** Aggregated message buffer. */
|
||||||
struct net_buf_simple *sdu;
|
struct net_buf_simple *sdu;
|
||||||
|
|
||||||
/** Used only by the Opcodes Aggregator Server.
|
|
||||||
*
|
|
||||||
* Indicates that the received aggregated message
|
|
||||||
* was acknowledged by local server model.
|
|
||||||
*/
|
|
||||||
bool ack;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct op_agg_ctx *bt_mesh_op_agg_ctx_get(void);
|
int bt_mesh_op_agg_encode_msg(struct net_buf_simple *msg, struct net_buf_simple *buf);
|
||||||
void bt_mesh_op_agg_ctx_reinit(void);
|
int bt_mesh_op_agg_decode_msg(struct net_buf_simple *msg, struct net_buf_simple *buf);
|
||||||
|
int bt_mesh_op_agg_cli_send(struct bt_mesh_model *model, struct net_buf_simple *msg);
|
||||||
int bt_mesh_op_agg_encode_msg(struct net_buf_simple *msg);
|
int bt_mesh_op_agg_cli_accept(struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf);
|
||||||
int bt_mesh_op_agg_decode_msg(struct net_buf_simple *msg,
|
int bt_mesh_op_agg_srv_send(struct bt_mesh_model *model, struct net_buf_simple *msg);
|
||||||
struct net_buf_simple *buf);
|
int bt_mesh_op_agg_srv_accept(struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf);
|
||||||
|
bool bt_mesh_op_agg_is_op_agg_msg(struct net_buf_simple *buf);
|
||||||
int bt_mesh_op_agg_accept(struct bt_mesh_msg_ctx *ctx);
|
|
||||||
|
|
||||||
int bt_mesh_op_agg_send(struct bt_mesh_model *model,
|
|
||||||
struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *msg,
|
|
||||||
const struct bt_mesh_send_cb *cb);
|
|
||||||
|
|
|
@ -18,14 +18,24 @@
|
||||||
#include <zephyr/logging/log.h>
|
#include <zephyr/logging/log.h>
|
||||||
LOG_MODULE_REGISTER(bt_mesh_op_agg_cli);
|
LOG_MODULE_REGISTER(bt_mesh_op_agg_cli);
|
||||||
|
|
||||||
|
NET_BUF_SIMPLE_DEFINE_STATIC(srcs, BT_MESH_TX_SDU_MAX);
|
||||||
|
NET_BUF_SIMPLE_DEFINE_STATIC(sdu, BT_MESH_TX_SDU_MAX);
|
||||||
|
|
||||||
/** Mesh Opcodes Aggregator Client Model Context */
|
/** Mesh Opcodes Aggregator Client Model Context */
|
||||||
static struct bt_mesh_op_agg_cli {
|
static struct bt_mesh_op_agg_cli {
|
||||||
/** Composition data model entry pointer. */
|
/** Composition data model entry pointer. */
|
||||||
struct bt_mesh_model *model;
|
struct bt_mesh_model *model;
|
||||||
|
/** Acknowledge context. */
|
||||||
/* Internal parameters for tracking message responses. */
|
|
||||||
struct bt_mesh_msg_ack_ctx ack_ctx;
|
struct bt_mesh_msg_ack_ctx ack_ctx;
|
||||||
} cli;
|
/** List of source element addresses.
|
||||||
|
* Used by Client to match aggregated responses
|
||||||
|
* with local source client models.
|
||||||
|
*/
|
||||||
|
struct net_buf_simple *srcs;
|
||||||
|
/** Aggregator context. */
|
||||||
|
struct op_agg_ctx ctx;
|
||||||
|
|
||||||
|
} cli = {.srcs = &srcs, .ctx.sdu = &sdu};
|
||||||
|
|
||||||
static int32_t msg_timeout;
|
static int32_t msg_timeout;
|
||||||
|
|
||||||
|
@ -33,7 +43,6 @@ static int handle_status(struct bt_mesh_model *model,
|
||||||
struct bt_mesh_msg_ctx *ctx,
|
struct bt_mesh_msg_ctx *ctx,
|
||||||
struct net_buf_simple *buf)
|
struct net_buf_simple *buf)
|
||||||
{
|
{
|
||||||
struct op_agg_ctx *agg = bt_mesh_op_agg_ctx_get();
|
|
||||||
struct net_buf_simple msg;
|
struct net_buf_simple msg;
|
||||||
uint8_t status;
|
uint8_t status;
|
||||||
uint16_t elem_addr, addr;
|
uint16_t elem_addr, addr;
|
||||||
|
@ -57,17 +66,17 @@ static int handle_status(struct bt_mesh_model *model,
|
||||||
err = bt_mesh_op_agg_decode_msg(&msg, buf);
|
err = bt_mesh_op_agg_decode_msg(&msg, buf);
|
||||||
if (err) {
|
if (err) {
|
||||||
LOG_ERR("Cannot decode aggregated message %d", err);
|
LOG_ERR("Cannot decode aggregated message %d", err);
|
||||||
bt_mesh_op_agg_ctx_reinit();
|
cli.ctx.initialized = true;
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (agg->srcs->len < 2) {
|
if (cli.srcs->len < 2) {
|
||||||
LOG_ERR("Mismatch in sources address buffer");
|
LOG_ERR("Mismatch in sources address buffer");
|
||||||
bt_mesh_op_agg_ctx_reinit();
|
cli.ctx.initialized = true;
|
||||||
return -ENOENT;
|
return -ENOENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
addr = net_buf_simple_pull_le16(agg->srcs);
|
addr = net_buf_simple_pull_le16(cli.srcs);
|
||||||
|
|
||||||
/* Empty item means unacked msg. */
|
/* Empty item means unacked msg. */
|
||||||
if (!msg.len) {
|
if (!msg.len) {
|
||||||
|
@ -78,7 +87,7 @@ static int handle_status(struct bt_mesh_model *model,
|
||||||
err = bt_mesh_model_recv(ctx, &msg);
|
err = bt_mesh_model_recv(ctx, &msg);
|
||||||
if (err) {
|
if (err) {
|
||||||
LOG_ERR("Opcodes Aggregator receive error %d", err);
|
LOG_ERR("Opcodes Aggregator receive error %d", err);
|
||||||
bt_mesh_op_agg_ctx_reinit();
|
cli.ctx.initialized = true;
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -115,56 +124,51 @@ static int op_agg_cli_init(struct bt_mesh_model *model)
|
||||||
int bt_mesh_op_agg_cli_seq_start(uint16_t net_idx, uint16_t app_idx, uint16_t dst,
|
int bt_mesh_op_agg_cli_seq_start(uint16_t net_idx, uint16_t app_idx, uint16_t dst,
|
||||||
uint16_t elem_addr)
|
uint16_t elem_addr)
|
||||||
{
|
{
|
||||||
struct op_agg_ctx *agg = bt_mesh_op_agg_ctx_get();
|
|
||||||
|
|
||||||
if (!BT_MESH_ADDR_IS_UNICAST(elem_addr)) {
|
if (!BT_MESH_ADDR_IS_UNICAST(elem_addr)) {
|
||||||
LOG_ERR("Element address shall be a unicast address");
|
LOG_ERR("Element address shall be a unicast address");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (agg->initialized) {
|
if (cli.ctx.initialized) {
|
||||||
LOG_ERR("Opcodes Aggregator is already configured");
|
LOG_ERR("Opcodes Aggregator is already configured");
|
||||||
return -EALREADY;
|
return -EALREADY;
|
||||||
}
|
}
|
||||||
|
|
||||||
agg->net_idx = net_idx;
|
cli.ctx.net_idx = net_idx;
|
||||||
agg->app_idx = app_idx;
|
cli.ctx.app_idx = app_idx;
|
||||||
agg->addr = dst;
|
cli.ctx.addr = dst;
|
||||||
agg->ack = false;
|
cli.ctx.initialized = true;
|
||||||
agg->rsp_err = 0;
|
|
||||||
agg->initialized = true;
|
|
||||||
|
|
||||||
net_buf_simple_init(agg->srcs, 0);
|
net_buf_simple_init(cli.srcs, 0);
|
||||||
bt_mesh_model_msg_init(agg->sdu, OP_OPCODES_AGGREGATOR_SEQUENCE);
|
bt_mesh_model_msg_init(cli.ctx.sdu, OP_OPCODES_AGGREGATOR_SEQUENCE);
|
||||||
net_buf_simple_add_le16(agg->sdu, elem_addr);
|
net_buf_simple_add_le16(cli.ctx.sdu, elem_addr);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int bt_mesh_op_agg_cli_seq_send(void)
|
int bt_mesh_op_agg_cli_seq_send(void)
|
||||||
{
|
{
|
||||||
struct op_agg_ctx *agg = bt_mesh_op_agg_ctx_get();
|
|
||||||
struct bt_mesh_msg_ctx ctx = {
|
struct bt_mesh_msg_ctx ctx = {
|
||||||
.net_idx = agg->net_idx,
|
.net_idx = cli.ctx.net_idx,
|
||||||
.app_idx = agg->app_idx,
|
.app_idx = cli.ctx.app_idx,
|
||||||
.addr = agg->addr,
|
.addr = cli.ctx.addr,
|
||||||
};
|
};
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
if (!agg->initialized) {
|
if (!cli.ctx.initialized) {
|
||||||
LOG_ERR("Opcodes Aggregator not initialized");
|
LOG_ERR("Opcodes Aggregator not initialized");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = bt_mesh_msg_ack_ctx_prepare(&cli.ack_ctx, OP_OPCODES_AGGREGATOR_STATUS, agg->addr,
|
err = bt_mesh_msg_ack_ctx_prepare(&cli.ack_ctx, OP_OPCODES_AGGREGATOR_STATUS,
|
||||||
NULL);
|
cli.ctx.addr, NULL);
|
||||||
if (err) {
|
if (err) {
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
agg->initialized = false;
|
cli.ctx.initialized = false;
|
||||||
|
|
||||||
err = bt_mesh_model_send(cli.model, &ctx, agg->sdu, NULL, NULL);
|
err = bt_mesh_model_send(cli.model, &ctx, cli.ctx.sdu, NULL, NULL);
|
||||||
if (err) {
|
if (err) {
|
||||||
LOG_ERR("model_send() failed (err %d)", err);
|
LOG_ERR("model_send() failed (err %d)", err);
|
||||||
bt_mesh_msg_ack_ctx_clear(&cli.ack_ctx);
|
bt_mesh_msg_ack_ctx_clear(&cli.ack_ctx);
|
||||||
|
@ -176,23 +180,17 @@ int bt_mesh_op_agg_cli_seq_send(void)
|
||||||
|
|
||||||
void bt_mesh_op_agg_cli_seq_abort(void)
|
void bt_mesh_op_agg_cli_seq_abort(void)
|
||||||
{
|
{
|
||||||
struct op_agg_ctx *agg = bt_mesh_op_agg_ctx_get();
|
cli.ctx.initialized = false;
|
||||||
|
|
||||||
agg->initialized = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool bt_mesh_op_agg_cli_seq_is_started(void)
|
bool bt_mesh_op_agg_cli_seq_is_started(void)
|
||||||
{
|
{
|
||||||
struct op_agg_ctx *agg = bt_mesh_op_agg_ctx_get();
|
return cli.ctx.initialized;
|
||||||
|
|
||||||
return agg->initialized;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t bt_mesh_op_agg_cli_seq_tailroom(void)
|
size_t bt_mesh_op_agg_cli_seq_tailroom(void)
|
||||||
{
|
{
|
||||||
struct op_agg_ctx *agg = bt_mesh_op_agg_ctx_get();
|
return net_buf_simple_tailroom(cli.ctx.sdu);
|
||||||
|
|
||||||
return net_buf_simple_tailroom(agg->sdu);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t bt_mesh_op_agg_cli_timeout_get(void)
|
int32_t bt_mesh_op_agg_cli_timeout_get(void)
|
||||||
|
@ -205,6 +203,26 @@ void bt_mesh_op_agg_cli_timeout_set(int32_t timeout)
|
||||||
msg_timeout = timeout;
|
msg_timeout = timeout;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int bt_mesh_op_agg_cli_send(struct bt_mesh_model *model, struct net_buf_simple *msg)
|
||||||
|
{
|
||||||
|
uint16_t src = bt_mesh_model_elem(model)->addr;
|
||||||
|
|
||||||
|
if (net_buf_simple_tailroom(&srcs) < 2) {
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
net_buf_simple_add_le16(&srcs, src);
|
||||||
|
return bt_mesh_op_agg_encode_msg(msg, cli.ctx.sdu);
|
||||||
|
}
|
||||||
|
|
||||||
|
int bt_mesh_op_agg_cli_accept(struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf)
|
||||||
|
{
|
||||||
|
|
||||||
|
return cli.ctx.initialized && (ctx->net_idx == cli.ctx.net_idx) &&
|
||||||
|
(ctx->addr == cli.ctx.addr) && (ctx->app_idx == cli.ctx.app_idx) &&
|
||||||
|
!bt_mesh_op_agg_is_op_agg_msg(buf);
|
||||||
|
}
|
||||||
|
|
||||||
const struct bt_mesh_model_cb _bt_mesh_op_agg_cli_cb = {
|
const struct bt_mesh_model_cb _bt_mesh_op_agg_cli_cb = {
|
||||||
.init = op_agg_cli_init,
|
.init = op_agg_cli_init,
|
||||||
};
|
};
|
||||||
|
|
|
@ -17,17 +17,26 @@
|
||||||
#include <zephyr/logging/log.h>
|
#include <zephyr/logging/log.h>
|
||||||
LOG_MODULE_REGISTER(bt_mesh_op_agg_srv);
|
LOG_MODULE_REGISTER(bt_mesh_op_agg_srv);
|
||||||
|
|
||||||
|
NET_BUF_SIMPLE_DEFINE_STATIC(sdu, BT_MESH_TX_SDU_MAX);
|
||||||
|
|
||||||
/** Mesh Opcodes Aggragator Server Model Context */
|
/** Mesh Opcodes Aggragator Server Model Context */
|
||||||
static struct bt_mesh_op_agg_srv {
|
static struct bt_mesh_op_agg_srv {
|
||||||
/** Composition data model entry pointer. */
|
/** Composition data model entry pointer. */
|
||||||
struct bt_mesh_model *model;
|
struct bt_mesh_model *model;
|
||||||
} srv;
|
/** Response error code. */
|
||||||
|
int rsp_err;
|
||||||
|
/** Indicates that the received aggregated message
|
||||||
|
* was acknowledged by local server model.
|
||||||
|
*/
|
||||||
|
bool ack;
|
||||||
|
/** Aggregator context. */
|
||||||
|
struct op_agg_ctx ctx;
|
||||||
|
} srv = {.ctx.sdu = &sdu};
|
||||||
|
|
||||||
static int handle_sequence(struct bt_mesh_model *model,
|
static int handle_sequence(struct bt_mesh_model *model,
|
||||||
struct bt_mesh_msg_ctx *ctx,
|
struct bt_mesh_msg_ctx *ctx,
|
||||||
struct net_buf_simple *buf)
|
struct net_buf_simple *buf)
|
||||||
{
|
{
|
||||||
struct op_agg_ctx *agg = bt_mesh_op_agg_ctx_get();
|
|
||||||
struct net_buf_simple_state state;
|
struct net_buf_simple_state state;
|
||||||
struct net_buf_simple msg;
|
struct net_buf_simple msg;
|
||||||
uint16_t elem;
|
uint16_t elem;
|
||||||
|
@ -37,14 +46,14 @@ static int handle_sequence(struct bt_mesh_model *model,
|
||||||
elem = net_buf_simple_pull_le16(buf);
|
elem = net_buf_simple_pull_le16(buf);
|
||||||
ctx->recv_dst = elem;
|
ctx->recv_dst = elem;
|
||||||
|
|
||||||
bt_mesh_model_msg_init(agg->sdu, OP_OPCODES_AGGREGATOR_STATUS);
|
bt_mesh_model_msg_init(srv.ctx.sdu, OP_OPCODES_AGGREGATOR_STATUS);
|
||||||
status = net_buf_simple_add_u8(agg->sdu, 0);
|
status = net_buf_simple_add_u8(srv.ctx.sdu, 0);
|
||||||
net_buf_simple_add_le16(agg->sdu, elem);
|
net_buf_simple_add_le16(srv.ctx.sdu, elem);
|
||||||
|
|
||||||
agg->net_idx = ctx->net_idx;
|
srv.ctx.net_idx = ctx->net_idx;
|
||||||
agg->app_idx = ctx->app_idx;
|
srv.ctx.app_idx = ctx->app_idx;
|
||||||
agg->addr = ctx->addr;
|
srv.ctx.addr = ctx->addr;
|
||||||
agg->initialized = true;
|
srv.ctx.initialized = true;
|
||||||
|
|
||||||
if (!BT_MESH_ADDR_IS_UNICAST(elem)) {
|
if (!BT_MESH_ADDR_IS_UNICAST(elem)) {
|
||||||
LOG_WRN("Address is not unicast, ignoring.");
|
LOG_WRN("Address is not unicast, ignoring.");
|
||||||
|
@ -70,12 +79,12 @@ static int handle_sequence(struct bt_mesh_model *model,
|
||||||
while (buf->len > 0) {
|
while (buf->len > 0) {
|
||||||
(void) bt_mesh_op_agg_decode_msg(&msg, buf);
|
(void) bt_mesh_op_agg_decode_msg(&msg, buf);
|
||||||
|
|
||||||
agg->ack = false;
|
srv.ack = false;
|
||||||
agg->rsp_err = 0;
|
srv.rsp_err = 0;
|
||||||
err = bt_mesh_model_recv(ctx, &msg);
|
err = bt_mesh_model_recv(ctx, &msg);
|
||||||
|
|
||||||
if (agg->rsp_err) {
|
if (srv.rsp_err) {
|
||||||
*status = agg->rsp_err;
|
*status = srv.rsp_err;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -84,14 +93,14 @@ static int handle_sequence(struct bt_mesh_model *model,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!agg->ack) {
|
if (!srv.ack) {
|
||||||
net_buf_simple_add_u8(agg->sdu, 0);
|
net_buf_simple_add_u8(srv.ctx.sdu, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
send:
|
send:
|
||||||
agg->initialized = false;
|
srv.ctx.initialized = false;
|
||||||
err = bt_mesh_model_send(model, ctx, agg->sdu, NULL, NULL);
|
err = bt_mesh_model_send(model, ctx, srv.ctx.sdu, NULL, NULL);
|
||||||
if (err) {
|
if (err) {
|
||||||
LOG_ERR("Unable to send Opcodes Aggregator Status");
|
LOG_ERR("Unable to send Opcodes Aggregator Status");
|
||||||
return err;
|
return err;
|
||||||
|
@ -122,6 +131,29 @@ static int op_agg_srv_init(struct bt_mesh_model *model)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int bt_mesh_op_agg_srv_send(struct bt_mesh_model *model, struct net_buf_simple *msg)
|
||||||
|
{
|
||||||
|
int err;
|
||||||
|
|
||||||
|
/* Model responded so mark this message as acknowledged */
|
||||||
|
srv.ack = true;
|
||||||
|
|
||||||
|
err = bt_mesh_op_agg_encode_msg(msg, srv.ctx.sdu);
|
||||||
|
if (err) {
|
||||||
|
srv.rsp_err = ACCESS_STATUS_RESPONSE_OVERFLOW;
|
||||||
|
}
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
int bt_mesh_op_agg_srv_accept(struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf)
|
||||||
|
{
|
||||||
|
|
||||||
|
return srv.ctx.initialized && (ctx->net_idx == srv.ctx.net_idx) &&
|
||||||
|
(ctx->addr == srv.ctx.addr) && (ctx->app_idx == srv.ctx.app_idx) &&
|
||||||
|
!bt_mesh_op_agg_is_op_agg_msg(buf);
|
||||||
|
}
|
||||||
|
|
||||||
const struct bt_mesh_model_cb _bt_mesh_op_agg_srv_cb = {
|
const struct bt_mesh_model_cb _bt_mesh_op_agg_srv_cb = {
|
||||||
.init = op_agg_srv_init,
|
.init = op_agg_srv_init,
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue