zephyr/subsys/bluetooth/mesh/od_priv_proxy_cli.c
Krzysztof Kopyściński d0995541fb Bluetooth: Mesh: add implementation for Proxy Solicitation
This is initial implementation of Proxy solicitation procedure.
This includes:
- support for sending and receiving Solicitation PDUs
- On-Demand Private Proxy functionality (Server and Client) controlling
  behaviour of node after receiving Solicitation PDU
- Solicitation PDU RPL Configuration (Server and Client), which manages
  Replay Protection List for Solicitation PDUs.

Proxy Solicitation allows to enable advertising of Proxy service on node
by sending Solicitation PDUs. These PDUs are not part of Mesh messages;
instead, these are non-connectable, undirected advertising PDUs with
their own format, containing Proxy Solicitation UUID.

Signed-off-by: Krzysztof Kopyściński <krzysztof.kopyscinski@codecoup.pl>
2023-03-06 13:52:15 +01:00

114 lines
2.7 KiB
C

/*
* Copyright (c) 2022 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr/bluetooth/mesh.h>
#include "cfg.h"
#include "access.h"
#include "foundation.h"
#include "msg.h"
#define LOG_LEVEL CONFIG_BT_MESH_MODEL_LOG_LEVEL
#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(bt_mesh_od_priv_proxy_cli);
/** On-Demand Private Proxy Client Model Context */
static struct bt_mesh_od_priv_proxy_cli *cli;
static int32_t msg_timeout;
static int handle_proxy_status(struct bt_mesh_model *mod,
struct bt_mesh_msg_ctx *ctx,
struct net_buf_simple *buf)
{
uint8_t *state;
uint8_t state_rsp;
state_rsp = net_buf_simple_pull_u8(buf);
LOG_DBG("On-Demand Private Proxy status received: state: %u", state_rsp);
if (bt_mesh_msg_ack_ctx_match(&cli->ack_ctx, OP_OD_PRIV_PROXY_STATUS,
ctx->addr, (void **)&state)) {
if (state) {
*state = state_rsp;
}
bt_mesh_msg_ack_ctx_rx(&cli->ack_ctx);
}
if (cli->od_status) {
cli->od_status(cli, ctx->addr, state_rsp);
}
return 0;
}
const struct bt_mesh_model_op _bt_mesh_od_priv_proxy_cli_op[] = {
{ OP_OD_PRIV_PROXY_STATUS, BT_MESH_LEN_EXACT(1), handle_proxy_status },
BT_MESH_MODEL_OP_END
};
int bt_mesh_od_priv_proxy_cli_get(struct bt_mesh_msg_ctx *ctx, uint8_t *val)
{
const struct bt_mesh_msg_rsp_ctx rsp = {
.ack = &cli->ack_ctx,
.op = OP_OD_PRIV_PROXY_STATUS,
.user_data = val,
.timeout = msg_timeout,
};
BT_MESH_MODEL_BUF_DEFINE(msg, OP_OD_PRIV_PROXY_GET, 0);
bt_mesh_model_msg_init(&msg, OP_OD_PRIV_PROXY_GET);
return bt_mesh_msg_ackd_send(cli->model, ctx, &msg, val ? &rsp : NULL);
}
int bt_mesh_od_priv_proxy_cli_set(struct bt_mesh_msg_ctx *ctx, uint8_t val, uint8_t *val_rsp)
{
const struct bt_mesh_msg_rsp_ctx rsp = {
.ack = &cli->ack_ctx,
.op = OP_OD_PRIV_PROXY_STATUS,
.user_data = val_rsp,
.timeout = msg_timeout,
};
BT_MESH_MODEL_BUF_DEFINE(msg, OP_OD_PRIV_PROXY_SET, 1);
bt_mesh_model_msg_init(&msg, OP_OD_PRIV_PROXY_SET);
net_buf_simple_add_u8(&msg, val);
return bt_mesh_msg_ackd_send(cli->model, ctx, &msg, val_rsp ? &rsp : NULL);
}
void bt_mesh_od_priv_proxy_cli_timeout_set(int32_t timeout)
{
msg_timeout = timeout;
}
static int on_demand_proxy_cli_init(struct bt_mesh_model *mod)
{
if (!bt_mesh_model_in_primary(mod)) {
LOG_ERR("On-Demand Private Proxy client not in primary element");
return -EINVAL;
}
cli = mod->user_data;
cli->model = mod;
mod->keys[0] = BT_MESH_KEY_DEV_ANY;
mod->flags |= BT_MESH_MOD_DEVKEY_ONLY;
msg_timeout = CONFIG_BT_MESH_OD_PRIV_PROXY_CLI_TIMEOUT;
bt_mesh_msg_ack_ctx_init(&cli->ack_ctx);
return 0;
}
const struct bt_mesh_model_cb _bt_mesh_od_priv_proxy_cli_cb = {
.init = on_demand_proxy_cli_init,
};