| /* |
| * Copyright (c) 2022 Nordic Semiconductor ASA |
| * |
| * SPDX-License-Identifier: Apache-2.0 |
| */ |
| |
| #include <zephyr/bluetooth/mesh.h> |
| |
| #include "foundation.h" |
| #include "op_agg.h" |
| |
| #define LOG_LEVEL CONFIG_BT_MESH_MODEL_LOG_LEVEL |
| #include <zephyr/logging/log.h> |
| LOG_MODULE_REGISTER(bt_mesh_op_agg); |
| |
| #define IS_LENGTH_LONG(buf) ((buf)->data[0] & 1) |
| #define LENGTH_SHORT_MAX BIT_MASK(7) |
| |
| int bt_mesh_op_agg_encode_msg(struct net_buf_simple *msg, struct net_buf_simple *buf) |
| { |
| if (msg->len > LENGTH_SHORT_MAX) { |
| if (net_buf_simple_tailroom(buf) < (msg->len + 2)) { |
| return -ENOMEM; |
| } |
| |
| net_buf_simple_add_le16(buf, (msg->len << 1) | 1); |
| } else { |
| if (net_buf_simple_tailroom(buf) < (msg->len + 1)) { |
| return -ENOMEM; |
| } |
| |
| net_buf_simple_add_u8(buf, msg->len << 1); |
| } |
| net_buf_simple_add_mem(buf, msg->data, msg->len); |
| |
| return 0; |
| } |
| |
| int bt_mesh_op_agg_decode_msg(struct net_buf_simple *msg, |
| struct net_buf_simple *buf) |
| { |
| uint16_t len; |
| |
| if (IS_LENGTH_LONG(buf)) { |
| if (buf->len < 2) { |
| return -EINVAL; |
| } |
| |
| len = net_buf_simple_pull_le16(buf) >> 1; |
| } else { |
| if (buf->len < 1) { |
| return -EINVAL; |
| } |
| |
| len = net_buf_simple_pull_u8(buf) >> 1; |
| } |
| |
| if (buf->len < len) { |
| return -EINVAL; |
| } |
| |
| net_buf_simple_init_with_data(msg, net_buf_simple_pull_mem(buf, len), len); |
| |
| 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; |
| } |