/** @file
|
* @brief Bluetooth Mesh Message APIs.
|
*/
|
|
/*
|
* Copyright (c) 2021 Nordic Semiconductor ASA
|
*
|
* SPDX-License-Identifier: Apache-2.0
|
*/
|
|
#ifndef ZEPHYR_INCLUDE_BLUETOOTH_MESH_MSG_H_
|
#define ZEPHYR_INCLUDE_BLUETOOTH_MESH_MSG_H_
|
|
/**
|
* @brief Bluetooth Mesh Message API
|
* @defgroup bt_mesh_msg Bluetooth Mesh Message API
|
* @ingroup bt_mesh
|
* @{
|
*/
|
|
#ifdef __cplusplus
|
extern "C" {
|
#endif
|
|
/** Length of a short Mesh MIC. */
|
#define BT_MESH_MIC_SHORT 4
|
/** Length of a long Mesh MIC. */
|
#define BT_MESH_MIC_LONG 8
|
|
/** @def BT_MESH_MODEL_OP_LEN
|
*
|
* @brief Helper to determine the length of an opcode.
|
*
|
* @param _op Opcode.
|
*/
|
#define BT_MESH_MODEL_OP_LEN(_op) ((_op) <= 0xff ? 1 : (_op) <= 0xffff ? 2 : 3)
|
|
|
/** @def BT_MESH_MODEL_BUF_LEN
|
*
|
* @brief Helper for model message buffer length.
|
*
|
* Returns the length of a Mesh model message buffer, including the opcode
|
* length and a short MIC.
|
*
|
* @param _op Opcode of the message.
|
* @param _payload_len Length of the model payload.
|
*/
|
#define BT_MESH_MODEL_BUF_LEN(_op, _payload_len) \
|
(BT_MESH_MODEL_OP_LEN(_op) + (_payload_len) + BT_MESH_MIC_SHORT)
|
|
|
/** @def BT_MESH_MODEL_BUF_LEN_LONG_MIC
|
*
|
* @brief Helper for model message buffer length.
|
*
|
* Returns the length of a Mesh model message buffer, including the opcode
|
* length and a long MIC.
|
*
|
* @param _op Opcode of the message.
|
* @param _payload_len Length of the model payload.
|
*/
|
#define BT_MESH_MODEL_BUF_LEN_LONG_MIC(_op, _payload_len) \
|
(BT_MESH_MODEL_OP_LEN(_op) + (_payload_len) + BT_MESH_MIC_LONG)
|
|
|
/** @def BT_MESH_MODEL_BUF_DEFINE
|
*
|
* @brief Define a Mesh model message buffer using @ref NET_BUF_SIMPLE_DEFINE.
|
*
|
* @param _buf Buffer name.
|
* @param _op Opcode of the message.
|
* @param _payload_len Length of the model message payload.
|
*/
|
#define BT_MESH_MODEL_BUF(_op, _payload_len) \
|
NET_BUF_SIMPLE(BT_MESH_MODEL_BUF_LEN(_op, (_payload_len)))
|
|
|
/** Message sending context. */
|
struct bt_mesh_msg_ctx {
|
/** NetKey Index of the subnet to send the message on. */
|
uint16_t net_idx;
|
|
/** AppKey Index to encrypt the message with. */
|
uint16_t app_idx;
|
|
/** Remote address. */
|
uint16_t addr;
|
|
/** Destination address of a received message. Not used for sending. */
|
uint16_t recv_dst;
|
|
/** RSSI of received packet. Not used for sending. */
|
int8_t recv_rssi;
|
|
/** Received TTL value. Not used for sending. */
|
uint8_t recv_ttl;
|
|
/** Force sending reliably by using segment acknowledgment */
|
bool send_rel;
|
|
/** TTL, or BT_MESH_TTL_DEFAULT for default TTL. */
|
uint8_t send_ttl;
|
};
|
|
/** @brief Initialize a model message.
|
*
|
* Clears the message buffer contents, and encodes the given opcode.
|
* The message buffer will be ready for filling in payload data.
|
*
|
* @param msg Message buffer.
|
* @param opcode Opcode to encode.
|
*/
|
void bt_mesh_model_msg_init(struct os_mbuf *msg, uint32_t opcode);
|
|
/**
|
* Acknowledged message context for tracking the status of model messages pending a response.
|
*/
|
struct bt_mesh_msg_ack_ctx {
|
struct k_sem sem; /**< Sync semaphore. */
|
uint32_t op; /**< Opcode we're waiting for. */
|
uint16_t dst; /**< Address of the node that should respond. */
|
void *user_data; /**< User specific parameter. */
|
};
|
|
/** @brief Initialize an acknowledged message context.
|
*
|
* Initializes semaphore used for synchronization between @ref bt_mesh_msg_ack_ctx_wait and
|
* @ref bt_mesh_msg_ack_ctx_rx calls. Call this function before using @ref bt_mesh_msg_ack_ctx.
|
*
|
* @param ack Acknowledged message context to initialize.
|
*/
|
static inline void bt_mesh_msg_ack_ctx_init(struct bt_mesh_msg_ack_ctx *ack)
|
{
|
k_sem_init(&ack->sem, 0, 1);
|
}
|
|
/** @brief Reset the synchronization semaphore in an acknowledged message context.
|
*
|
* This function aborts call to @ref bt_mesh_msg_ack_ctx_wait.
|
*
|
* @param ack Acknowledged message context to be reset.
|
*/
|
static inline void bt_mesh_msg_ack_ctx_reset(struct bt_mesh_msg_ack_ctx *ack)
|
{
|
k_sem_reset(&ack->sem);
|
}
|
|
/** @brief Clear parameters of an acknowledged message context.
|
*
|
* This function clears the opcode, remote address and user data set
|
* by @ref bt_mesh_msg_ack_ctx_prepare.
|
*
|
* @param ack Acknowledged message context to be cleared.
|
*/
|
void bt_mesh_msg_ack_ctx_clear(struct bt_mesh_msg_ack_ctx *ack);
|
|
/** @brief Prepare an acknowledged message context for the incoming message to wait.
|
*
|
* This function sets the opcode, remote address of the incoming message and stores the user data.
|
* Use this function before calling @ref bt_mesh_msg_ack_ctx_wait.
|
*
|
* @param ack Acknowledged message context to prepare.
|
* @param op The message OpCode.
|
* @param dst Destination address of the message.
|
* @param user_data User data for the acknowledged message context.
|
*
|
* @return 0 on success, or (negative) error code on failure.
|
*/
|
int bt_mesh_msg_ack_ctx_prepare(struct bt_mesh_msg_ack_ctx *ack,
|
uint32_t op, uint16_t dst, void *user_data);
|
/** @brief Check if the acknowledged message context is initialized with an opcode.
|
*
|
* @param ack Acknowledged message context.
|
*
|
* @return true if the acknowledged message context is initialized with an opcode,
|
* false otherwise.
|
*/
|
static inline bool bt_mesh_msg_ack_ctx_busy(struct bt_mesh_msg_ack_ctx *ack)
|
{
|
return (ack->op != 0);
|
}
|
|
/** @brief Wait for a message acknowledge.
|
*
|
* This function blocks execution until @ref bt_mesh_msg_ack_ctx_rx is called or by timeout.
|
*
|
* @param ack Acknowledged message context of the message to wait for.
|
* @param timeout Wait timeout.
|
*
|
* @return 0 on success, or (negative) error code on failure.
|
*/
|
int bt_mesh_msg_ack_ctx_wait(struct bt_mesh_msg_ack_ctx *ack, int32_t timeout);
|
|
/** @brief Mark a message as acknowledged.
|
*
|
* This function unblocks call to @ref bt_mesh_msg_ack_ctx_wait.
|
*
|
* @param ack Context of a message to be acknowledged.
|
*/
|
static inline void bt_mesh_msg_ack_ctx_rx(struct bt_mesh_msg_ack_ctx *ack)
|
{
|
k_sem_give(&ack->sem);
|
}
|
|
/** @brief Check if an opcode and address of a message matches the expected one.
|
*
|
* @param ack Acknowledged message context to be checked.
|
* @param op OpCode of the incoming message.
|
* @param addr Source address of the incoming message.
|
* @param user_data If not NULL, returns a user data stored in the acknowledged message context
|
* by @ref bt_mesh_msg_ack_ctx_prepare.
|
*
|
* @return true if the incoming message matches the expected one, false otherwise.
|
*/
|
bool bt_mesh_msg_ack_ctx_match(const struct bt_mesh_msg_ack_ctx *ack,
|
uint32_t op, uint16_t addr, void **user_data);
|
|
#ifdef __cplusplus
|
}
|
#endif
|
/**
|
* @}
|
*/
|
#endif /* ZEPHYR_INCLUDE_BLUETOOTH_MESH_MSG_H_ */
|