blob: e05489ee0cfd7353c6a6ce66edf2bc985fc3e6e5 [file] [log] [blame]
/*
* Copyright (c) 2021 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr/kernel.h>
#include <string.h>
#include <errno.h>
#include <stdbool.h>
#include <zephyr/types.h>
#include <zephyr/sys/util.h>
#include <zephyr/sys/byteorder.h>
#include <zephyr/bluetooth/bluetooth.h>
#include <zephyr/bluetooth/conn.h>
#include <zephyr/bluetooth/mesh.h>
#include "net.h"
#include "access.h"
#include "foundation.h"
#include "mesh.h"
#include "sar_cfg_internal.h"
#include "settings.h"
#define LOG_LEVEL CONFIG_BT_MESH_MODEL_LOG_LEVEL
#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(bt_mesh_sar_cfg_srv);
static int sar_rx_store(struct bt_mesh_model *model, bool delete)
{
const void *data = delete ? NULL : &bt_mesh.sar_rx;
size_t len = delete ? 0 : sizeof(struct bt_mesh_sar_rx);
return bt_mesh_model_data_store(model, false, "sar_rx", data, len);
}
static int sar_tx_store(struct bt_mesh_model *model, bool delete)
{
const void *data = delete ? NULL : &bt_mesh.sar_tx;
size_t len = delete ? 0 : sizeof(struct bt_mesh_sar_tx);
return bt_mesh_model_data_store(model, false, "sar_tx", data, len);
}
static void transmitter_status(struct bt_mesh_model *model,
struct bt_mesh_msg_ctx *ctx)
{
BT_MESH_MODEL_BUF_DEFINE(msg, OP_SAR_CFG_TX_STATUS, BT_MESH_SAR_TX_LEN);
const struct bt_mesh_sar_tx *tx = &bt_mesh.sar_tx;
LOG_DBG("SAR TX {0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x}",
tx->seg_int_step, tx->unicast_retrans_count,
tx->unicast_retrans_without_prog_count,
tx->unicast_retrans_int_step, tx->unicast_retrans_int_inc,
tx->multicast_retrans_count, tx->multicast_retrans_int);
bt_mesh_model_msg_init(&msg, OP_SAR_CFG_TX_STATUS);
bt_mesh_sar_tx_encode(&msg, tx);
if (bt_mesh_model_send(model, ctx, &msg, NULL, NULL)) {
LOG_ERR("Unable to send Transmitter Status");
}
}
static void receiver_status(struct bt_mesh_model *model,
struct bt_mesh_msg_ctx *ctx)
{
BT_MESH_MODEL_BUF_DEFINE(msg, OP_SAR_CFG_RX_STATUS, BT_MESH_SAR_RX_LEN);
const struct bt_mesh_sar_rx *rx = &bt_mesh.sar_rx;
LOG_DBG("SAR RX {0x%02x 0x%02x 0x%02x 0x%02x 0x%02x}", rx->seg_thresh,
rx->ack_delay_inc, rx->discard_timeout, rx->rx_seg_int_step,
rx->ack_retrans_count);
bt_mesh_model_msg_init(&msg, OP_SAR_CFG_RX_STATUS);
bt_mesh_sar_rx_encode(&msg, rx);
if (bt_mesh_model_send(model, ctx, &msg, NULL, NULL)) {
LOG_ERR("Unable to send Receiver Status");
}
}
static int transmitter_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx,
struct net_buf_simple *buf)
{
LOG_DBG("src 0x%04x", ctx->addr);
transmitter_status(model, ctx);
return 0;
}
static int transmitter_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx,
struct net_buf_simple *buf)
{
struct bt_mesh_sar_tx *tx = &bt_mesh.sar_tx;
LOG_DBG("src 0x%04x", ctx->addr);
bt_mesh_sar_tx_decode(buf, tx);
transmitter_status(model, ctx);
if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
sar_tx_store(model, false);
}
return 0;
}
static int receiver_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx,
struct net_buf_simple *buf)
{
LOG_DBG("src 0x%04x", ctx->addr);
receiver_status(model, ctx);
return 0;
}
static int receiver_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx,
struct net_buf_simple *buf)
{
struct bt_mesh_sar_rx *rx = &bt_mesh.sar_rx;
LOG_DBG("src 0x%04x", ctx->addr);
bt_mesh_sar_rx_decode(buf, rx);
receiver_status(model, ctx);
if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
sar_rx_store(model, false);
}
return 0;
}
const struct bt_mesh_model_op bt_mesh_sar_cfg_srv_op[] = {
{ OP_SAR_CFG_TX_GET, BT_MESH_LEN_EXACT(0), transmitter_get },
{ OP_SAR_CFG_TX_SET, BT_MESH_LEN_EXACT(BT_MESH_SAR_TX_LEN), transmitter_set },
{ OP_SAR_CFG_RX_GET, BT_MESH_LEN_EXACT(0), receiver_get },
{ OP_SAR_CFG_RX_SET, BT_MESH_LEN_EXACT(BT_MESH_SAR_RX_LEN), receiver_set },
BT_MESH_MODEL_OP_END,
};
static int sar_cfg_srv_init(struct bt_mesh_model *model)
{
if (!bt_mesh_model_in_primary(model)) {
LOG_ERR("Configuration Server only allowed in primary element");
return -EINVAL;
}
/*
* SAR Configuration Model security is device-key based and only the local
* device-key is allowed to access this model.
*/
model->keys[0] = BT_MESH_KEY_DEV_LOCAL;
model->flags |= BT_MESH_MOD_DEVKEY_ONLY;
return 0;
}
static void sar_cfg_srv_reset(struct bt_mesh_model *model)
{
struct bt_mesh_sar_tx sar_tx = BT_MESH_SAR_TX_INIT;
struct bt_mesh_sar_rx sar_rx = BT_MESH_SAR_RX_INIT;
bt_mesh.sar_tx = sar_tx;
bt_mesh.sar_rx = sar_rx;
if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
sar_rx_store(model, true);
sar_tx_store(model, true);
}
}
#ifdef CONFIG_BT_SETTINGS
static int sar_cfg_srv_settings_set(struct bt_mesh_model *model, const char *name, size_t len_rd,
settings_read_cb read_cb, void *cb_data)
{
if (!strncmp(name, "sar_rx", 5)) {
return bt_mesh_settings_set(read_cb, cb_data, &bt_mesh.sar_rx,
sizeof(bt_mesh.sar_rx));
}
if (!strncmp(name, "sar_tx", 5)) {
return bt_mesh_settings_set(read_cb, cb_data, &bt_mesh.sar_tx,
sizeof(bt_mesh.sar_tx));
}
return 0;
}
#endif
const struct bt_mesh_model_cb bt_mesh_sar_cfg_srv_cb = {
.init = sar_cfg_srv_init,
.reset = sar_cfg_srv_reset,
#ifdef CONFIG_BT_SETTINGS
.settings_set = sar_cfg_srv_settings_set
#endif
};