WXK
2024-12-16 9201a33e45484b3247271759c91c158063baccac
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
/** @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_ */