Line data Source code
1 1 : /** @file
2 : * @brief Access layer APIs.
3 : */
4 :
5 : /*
6 : * Copyright (c) 2017 Intel Corporation
7 : *
8 : * SPDX-License-Identifier: Apache-2.0
9 : */
10 : #ifndef ZEPHYR_INCLUDE_BLUETOOTH_MESH_ACCESS_H_
11 : #define ZEPHYR_INCLUDE_BLUETOOTH_MESH_ACCESS_H_
12 :
13 : #include <zephyr/sys/util.h>
14 : #include <zephyr/settings/settings.h>
15 : #include <zephyr/bluetooth/assigned_numbers.h>
16 : #include <zephyr/bluetooth/mesh/msg.h>
17 :
18 : /**
19 : * @cond INTERNAL_HIDDEN
20 : */
21 :
22 : /* Internal macros used to initialize array members */
23 : #define BT_MESH_KEY_UNUSED_ELT_(IDX, _) BT_MESH_KEY_UNUSED
24 : #define BT_MESH_ADDR_UNASSIGNED_ELT_(IDX, _) BT_MESH_ADDR_UNASSIGNED
25 : #define BT_MESH_UUID_UNASSIGNED_ELT_(IDX, _) NULL
26 : #define BT_MESH_MODEL_KEYS_UNUSED(_keys) \
27 : { LISTIFY(_keys, BT_MESH_KEY_UNUSED_ELT_, (,)) }
28 : #define BT_MESH_MODEL_GROUPS_UNASSIGNED(_grps) \
29 : { LISTIFY(_grps, BT_MESH_ADDR_UNASSIGNED_ELT_, (,)) }
30 : #if CONFIG_BT_MESH_LABEL_COUNT > 0
31 : #define BT_MESH_MODEL_UUIDS_UNASSIGNED() \
32 : .uuids = (const uint8_t *[]){ LISTIFY(CONFIG_BT_MESH_LABEL_COUNT, \
33 : BT_MESH_UUID_UNASSIGNED_ELT_, (,)) },
34 : #else
35 : #define BT_MESH_MODEL_UUIDS_UNASSIGNED()
36 : #endif
37 :
38 : /** @endcond */
39 :
40 0 : #define BT_MESH_MODEL_RUNTIME_INIT(_user_data) \
41 : .rt = &(struct bt_mesh_model_rt_ctx){ .user_data = (_user_data) },
42 :
43 : /**
44 : * @brief Access layer
45 : * @defgroup bt_mesh_access Access layer
46 : * @ingroup bt_mesh
47 : * @{
48 : */
49 :
50 : #ifdef __cplusplus
51 : extern "C" {
52 : #endif
53 :
54 : /**
55 : * @name Group addresses
56 : * @{
57 : */
58 1 : #define BT_MESH_ADDR_UNASSIGNED 0x0000 /**< unassigned */
59 1 : #define BT_MESH_ADDR_ALL_NODES 0xffff /**< all-nodes */
60 1 : #define BT_MESH_ADDR_RELAYS 0xfffe /**< all-relays */
61 1 : #define BT_MESH_ADDR_FRIENDS 0xfffd /**< all-friends */
62 1 : #define BT_MESH_ADDR_PROXIES 0xfffc /**< all-proxies */
63 1 : #define BT_MESH_ADDR_DFW_NODES 0xfffb /**< all-directed-forwarding-nodes */
64 1 : #define BT_MESH_ADDR_IP_NODES 0xfffa /**< all-ipt-nodes */
65 1 : #define BT_MESH_ADDR_IP_BR_ROUTERS 0xfff9 /**< all-ipt-border-routers */
66 : /**
67 : * @}
68 : */
69 :
70 : /**
71 : * @name Predefined key indexes
72 : * @{
73 : */
74 1 : #define BT_MESH_KEY_UNUSED 0xffff /**< Key unused */
75 1 : #define BT_MESH_KEY_ANY 0xffff /**< Any key index */
76 1 : #define BT_MESH_KEY_DEV 0xfffe /**< Device key */
77 1 : #define BT_MESH_KEY_DEV_LOCAL BT_MESH_KEY_DEV /**< Local device key */
78 1 : #define BT_MESH_KEY_DEV_REMOTE 0xfffd /**< Remote device key */
79 1 : #define BT_MESH_KEY_DEV_ANY 0xfffc /**< Any device key */
80 : /**
81 : * @}
82 : */
83 :
84 : /**
85 : * Check if a Bluetooth Mesh address is a unicast address.
86 : */
87 1 : #define BT_MESH_ADDR_IS_UNICAST(addr) ((addr) && (addr) < 0x8000)
88 : /**
89 : * Check if a Bluetooth Mesh address is a group address.
90 : */
91 1 : #define BT_MESH_ADDR_IS_GROUP(addr) ((addr) >= 0xc000 && (addr) < 0xff00)
92 : /**
93 : * Check if a Bluetooth Mesh address is a fixed group address.
94 : */
95 1 : #define BT_MESH_ADDR_IS_FIXED_GROUP(addr) ((addr) >= 0xff00 && (addr) < 0xffff)
96 : /**
97 : * Check if a Bluetooth Mesh address is a virtual address.
98 : */
99 1 : #define BT_MESH_ADDR_IS_VIRTUAL(addr) ((addr) >= 0x8000 && (addr) < 0xc000)
100 : /**
101 : * Check if a Bluetooth Mesh address is an RFU address.
102 : */
103 1 : #define BT_MESH_ADDR_IS_RFU(addr) ((addr) >= 0xff00 && (addr) <= 0xfff8)
104 :
105 : /**
106 : * Check if a Bluetooth Mesh key is a device key.
107 : */
108 1 : #define BT_MESH_IS_DEV_KEY(key) (key == BT_MESH_KEY_DEV_LOCAL || \
109 : key == BT_MESH_KEY_DEV_REMOTE)
110 :
111 : /** Maximum size of an access message segment (in octets). */
112 1 : #define BT_MESH_APP_SEG_SDU_MAX 12
113 :
114 : /** Maximum payload size of an unsegmented access message (in octets). */
115 1 : #define BT_MESH_APP_UNSEG_SDU_MAX 15
116 :
117 : /** Maximum number of segments supported for incoming messages. */
118 : #if defined(CONFIG_BT_MESH_RX_SEG_MAX)
119 : #define BT_MESH_RX_SEG_MAX CONFIG_BT_MESH_RX_SEG_MAX
120 : #else
121 1 : #define BT_MESH_RX_SEG_MAX 0
122 : #endif
123 :
124 : /** Maximum number of segments supported for outgoing messages. */
125 : #if defined(CONFIG_BT_MESH_TX_SEG_MAX)
126 : #define BT_MESH_TX_SEG_MAX CONFIG_BT_MESH_TX_SEG_MAX
127 : #else
128 1 : #define BT_MESH_TX_SEG_MAX 0
129 : #endif
130 :
131 : /** Maximum possible payload size of an outgoing access message (in octets). */
132 1 : #define BT_MESH_TX_SDU_MAX MAX((BT_MESH_TX_SEG_MAX * \
133 : BT_MESH_APP_SEG_SDU_MAX), \
134 : BT_MESH_APP_UNSEG_SDU_MAX)
135 :
136 : /** Maximum possible payload size of an incoming access message (in octets). */
137 1 : #define BT_MESH_RX_SDU_MAX MAX((BT_MESH_RX_SEG_MAX * \
138 : BT_MESH_APP_SEG_SDU_MAX), \
139 : BT_MESH_APP_UNSEG_SDU_MAX)
140 :
141 : /** Helper to define a mesh element within an array.
142 : *
143 : * In case the element has no SIG or Vendor models the helper
144 : * macro BT_MESH_MODEL_NONE can be given instead.
145 : *
146 : * @param _loc Location Descriptor.
147 : * @param _mods Array of models.
148 : * @param _vnd_mods Array of vendor models.
149 : */
150 1 : #define BT_MESH_ELEM(_loc, _mods, _vnd_mods) \
151 : { \
152 : .rt = &(struct bt_mesh_elem_rt_ctx) { 0 }, \
153 : .loc = (_loc), \
154 : .model_count = ARRAY_SIZE(_mods), \
155 : .vnd_model_count = ARRAY_SIZE(_vnd_mods), \
156 : .models = (_mods), \
157 : .vnd_models = (_vnd_mods), \
158 : }
159 :
160 : /** Abstraction that describes a Mesh Element */
161 1 : struct bt_mesh_elem {
162 : /** Mesh Element runtime information */
163 1 : struct bt_mesh_elem_rt_ctx {
164 : /** Unicast Address. Set at runtime during provisioning. */
165 1 : uint16_t addr;
166 0 : } * const rt;
167 :
168 : /** Location Descriptor (GATT Bluetooth Namespace Descriptors) */
169 1 : const uint16_t loc;
170 : /** The number of SIG models in this element */
171 1 : const uint8_t model_count;
172 : /** The number of vendor models in this element */
173 1 : const uint8_t vnd_model_count;
174 :
175 : /** The list of SIG models in this element */
176 1 : const struct bt_mesh_model * const models;
177 : /** The list of vendor models in this element */
178 1 : const struct bt_mesh_model * const vnd_models;
179 : };
180 :
181 : /** Model opcode handler. */
182 1 : struct bt_mesh_model_op {
183 : /** OpCode encoded using the BT_MESH_MODEL_OP_* macros */
184 1 : const uint32_t opcode;
185 :
186 : /** Message length. If the message has variable length then this value
187 : * indicates minimum message length and should be positive. Handler
188 : * function should verify precise length based on the contents of the
189 : * message. If the message has fixed length then this value should
190 : * be negative. Use BT_MESH_LEN_* macros when defining this value.
191 : */
192 1 : const ssize_t len;
193 :
194 : /** @brief Handler function for this opcode.
195 : *
196 : * @param model Model instance receiving the message.
197 : * @param ctx Message context for the message.
198 : * @param buf Message buffer containing the message payload, not
199 : * including the opcode.
200 : *
201 : * @return Zero on success or (negative) error code otherwise.
202 : */
203 1 : int (*const func)(const struct bt_mesh_model *model,
204 : struct bt_mesh_msg_ctx *ctx,
205 : struct net_buf_simple *buf);
206 : };
207 :
208 : /** Macro for encoding a 1-byte opcode (used by Bluetooth SIG defined models). */
209 1 : #define BT_MESH_MODEL_OP_1(b0) (b0)
210 : /** Macro for encoding a 2-byte opcode (used by Bluetooth SIG defined models). */
211 1 : #define BT_MESH_MODEL_OP_2(b0, b1) (((b0) << 8) | (b1))
212 : /** Macro for encoding a 3-byte opcode (vendor-specific message). */
213 1 : #define BT_MESH_MODEL_OP_3(b0, cid) ((((b0) << 16) | 0xc00000) | (cid))
214 :
215 : /** Macro for encoding exact message length for fixed-length messages. */
216 1 : #define BT_MESH_LEN_EXACT(len) (-len)
217 : /** Macro for encoding minimum message length for variable-length messages. */
218 1 : #define BT_MESH_LEN_MIN(len) (len)
219 :
220 : /** End of the opcode list. Must always be present. */
221 1 : #define BT_MESH_MODEL_OP_END { 0, 0, NULL }
222 :
223 : #if !defined(__cplusplus) || defined(__DOXYGEN__)
224 : /**
225 : * @brief Helper to define an empty opcode list.
226 : *
227 : * This macro uses compound literal feature of C99 standard and thus is available only from C,
228 : * not C++.
229 : */
230 1 : #define BT_MESH_MODEL_NO_OPS ((struct bt_mesh_model_op []) \
231 : { BT_MESH_MODEL_OP_END })
232 :
233 : /**
234 : * @brief Helper to define an empty model array
235 : *
236 : * This macro uses compound literal feature of C99 standard and thus is available only from C,
237 : * not C++.
238 : */
239 1 : #define BT_MESH_MODEL_NONE ((const struct bt_mesh_model []){})
240 :
241 : /**
242 : * @brief Composition data SIG model entry with callback functions
243 : * with specific number of keys & groups.
244 : *
245 : * This macro uses compound literal feature of C99 standard and thus is available only from C,
246 : * not C++.
247 : *
248 : * @param _id Model ID.
249 : * @param _op Array of model opcode handlers.
250 : * @param _pub Model publish parameters.
251 : * @param _user_data User data for the model.
252 : * @param _keys Number of keys that can be bound to the model.
253 : * Shall not exceed @kconfig{CONFIG_BT_MESH_MODEL_KEY_COUNT}.
254 : * @param _grps Number of addresses that the model can be subscribed to.
255 : * Shall not exceed @kconfig{CONFIG_BT_MESH_MODEL_GROUP_COUNT}.
256 : * @param _cb Callback structure, or NULL to keep no callbacks.
257 : */
258 1 : #define BT_MESH_MODEL_CNT_CB(_id, _op, _pub, _user_data, _keys, _grps, _cb) \
259 : { \
260 : .id = (_id), \
261 : BT_MESH_MODEL_RUNTIME_INIT(_user_data) \
262 : .pub = _pub, \
263 : .keys = (uint16_t []) BT_MESH_MODEL_KEYS_UNUSED(_keys), \
264 : .keys_cnt = _keys, \
265 : .groups = (uint16_t []) BT_MESH_MODEL_GROUPS_UNASSIGNED(_grps), \
266 : .groups_cnt = _grps, \
267 : BT_MESH_MODEL_UUIDS_UNASSIGNED() \
268 : .op = _op, \
269 : .cb = _cb, \
270 : }
271 :
272 : /**
273 : * @brief Composition data vendor model entry with callback functions
274 : * with specific number of keys & groups.
275 : *
276 : * This macro uses compound literal feature of C99 standard and thus is available only from C,
277 : * not C++.
278 : *
279 : * @param _company Company ID.
280 : * @param _id Model ID.
281 : * @param _op Array of model opcode handlers.
282 : * @param _pub Model publish parameters.
283 : * @param _user_data User data for the model.
284 : * @param _keys Number of keys that can be bound to the model.
285 : * Shall not exceed @kconfig{CONFIG_BT_MESH_MODEL_KEY_COUNT}.
286 : * @param _grps Number of addresses that the model can be subscribed to.
287 : * Shall not exceed @kconfig{CONFIG_BT_MESH_MODEL_GROUP_COUNT}.
288 : * @param _cb Callback structure, or NULL to keep no callbacks.
289 : */
290 1 : #define BT_MESH_MODEL_CNT_VND_CB(_company, _id, _op, _pub, _user_data, _keys, _grps, _cb) \
291 : { \
292 : .vnd.company = (_company), \
293 : .vnd.id = (_id), \
294 : BT_MESH_MODEL_RUNTIME_INIT(_user_data) \
295 : .op = _op, \
296 : .pub = _pub, \
297 : .keys = (uint16_t []) BT_MESH_MODEL_KEYS_UNUSED(_keys), \
298 : .keys_cnt = _keys, \
299 : .groups = (uint16_t []) BT_MESH_MODEL_GROUPS_UNASSIGNED(_grps), \
300 : .groups_cnt = _grps, \
301 : BT_MESH_MODEL_UUIDS_UNASSIGNED() \
302 : .cb = _cb, \
303 : }
304 :
305 : /**
306 : * @brief Composition data SIG model entry with callback functions.
307 : *
308 : * This macro uses compound literal feature of C99 standard and thus is available only from C,
309 : * not C++.
310 : *
311 : * @param _id Model ID.
312 : * @param _op Array of model opcode handlers.
313 : * @param _pub Model publish parameters.
314 : * @param _user_data User data for the model.
315 : * @param _cb Callback structure, or NULL to keep no callbacks.
316 : */
317 1 : #define BT_MESH_MODEL_CB(_id, _op, _pub, _user_data, _cb) \
318 : BT_MESH_MODEL_CNT_CB(_id, _op, _pub, _user_data, \
319 : CONFIG_BT_MESH_MODEL_KEY_COUNT, \
320 : CONFIG_BT_MESH_MODEL_GROUP_COUNT, _cb)
321 :
322 :
323 : /**
324 : *
325 : * @brief Composition data SIG model entry with callback functions and metadata.
326 : *
327 : * This macro uses compound literal feature of C99 standard and thus is available only from C,
328 : * not C++.
329 : *
330 : * @param _id Model ID.
331 : * @param _op Array of model opcode handlers.
332 : * @param _pub Model publish parameters.
333 : * @param _user_data User data for the model.
334 : * @param _cb Callback structure, or NULL to keep no callbacks.
335 : * @param _metadata Metadata structure. Used if @kconfig{CONFIG_BT_MESH_LARGE_COMP_DATA_SRV}
336 : * is enabled.
337 : */
338 : #if defined(CONFIG_BT_MESH_LARGE_COMP_DATA_SRV)
339 : #define BT_MESH_MODEL_METADATA_CB(_id, _op, _pub, _user_data, _cb, _metadata) \
340 : { \
341 : .id = (_id), \
342 : BT_MESH_MODEL_RUNTIME_INIT(_user_data) \
343 : .pub = _pub, \
344 : .keys = (uint16_t []) BT_MESH_MODEL_KEYS_UNUSED(CONFIG_BT_MESH_MODEL_KEY_COUNT), \
345 : .keys_cnt = CONFIG_BT_MESH_MODEL_KEY_COUNT, \
346 : .groups = (uint16_t []) BT_MESH_MODEL_GROUPS_UNASSIGNED(CONFIG_BT_MESH_MODEL_GROUP_COUNT), \
347 : .groups_cnt = CONFIG_BT_MESH_MODEL_GROUP_COUNT, \
348 : BT_MESH_MODEL_UUIDS_UNASSIGNED() \
349 : .op = _op, \
350 : .cb = _cb, \
351 : .metadata = _metadata, \
352 : }
353 : #else
354 1 : #define BT_MESH_MODEL_METADATA_CB(_id, _op, _pub, _user_data, _cb, _metadata) \
355 : BT_MESH_MODEL_CB(_id, _op, _pub, _user_data, _cb)
356 : #endif
357 :
358 : /**
359 : *
360 : * @brief Composition data vendor model entry with callback functions.
361 : *
362 : * This macro uses compound literal feature of C99 standard and thus is available only from C,
363 : * not C++.
364 : *
365 : * @param _company Company ID.
366 : * @param _id Model ID.
367 : * @param _op Array of model opcode handlers.
368 : * @param _pub Model publish parameters.
369 : * @param _user_data User data for the model.
370 : * @param _cb Callback structure, or NULL to keep no callbacks.
371 : */
372 1 : #define BT_MESH_MODEL_VND_CB(_company, _id, _op, _pub, _user_data, _cb) \
373 : BT_MESH_MODEL_CNT_VND_CB(_company, _id, _op, _pub, _user_data, \
374 : CONFIG_BT_MESH_MODEL_KEY_COUNT, \
375 : CONFIG_BT_MESH_MODEL_GROUP_COUNT, _cb)
376 :
377 : /**
378 : *
379 : * @brief Composition data vendor model entry with callback functions and metadata.
380 : *
381 : * This macro uses compound literal feature of C99 standard and thus is available only from C,
382 : * not C++.
383 : *
384 : * @param _company Company ID.
385 : * @param _id Model ID.
386 : * @param _op Array of model opcode handlers.
387 : * @param _pub Model publish parameters.
388 : * @param _user_data User data for the model.
389 : * @param _cb Callback structure, or NULL to keep no callbacks.
390 : * @param _metadata Metadata structure. Used if @kconfig{CONFIG_BT_MESH_LARGE_COMP_DATA_SRV}
391 : * is enabled.
392 : */
393 : #if defined(CONFIG_BT_MESH_LARGE_COMP_DATA_SRV)
394 : #define BT_MESH_MODEL_VND_METADATA_CB(_company, _id, _op, _pub, _user_data, _cb, _metadata) \
395 : { \
396 : .vnd.company = (_company), \
397 : .vnd.id = (_id), \
398 : BT_MESH_MODEL_RUNTIME_INIT(_user_data) \
399 : .op = _op, \
400 : .pub = _pub, \
401 : .keys = (uint16_t []) BT_MESH_MODEL_KEYS_UNUSED(CONFIG_BT_MESH_MODEL_KEY_COUNT), \
402 : .keys_cnt = CONFIG_BT_MESH_MODEL_KEY_COUNT, \
403 : .groups = (uint16_t []) BT_MESH_MODEL_GROUPS_UNASSIGNED(CONFIG_BT_MESH_MODEL_GROUP_COUNT), \
404 : .groups_cnt = CONFIG_BT_MESH_MODEL_GROUP_COUNT, \
405 : BT_MESH_MODEL_UUIDS_UNASSIGNED() \
406 : .cb = _cb, \
407 : .metadata = _metadata, \
408 : }
409 : #else
410 1 : #define BT_MESH_MODEL_VND_METADATA_CB(_company, _id, _op, _pub, _user_data, _cb, _metadata) \
411 : BT_MESH_MODEL_VND_CB(_company, _id, _op, _pub, _user_data, _cb)
412 : #endif
413 : /**
414 : * @brief Composition data SIG model entry.
415 : *
416 : * This macro uses compound literal feature of C99 standard and thus is available only from C,
417 : * not C++.
418 : *
419 : * @param _id Model ID.
420 : * @param _op Array of model opcode handlers.
421 : * @param _pub Model publish parameters.
422 : * @param _user_data User data for the model.
423 : */
424 1 : #define BT_MESH_MODEL(_id, _op, _pub, _user_data) \
425 : BT_MESH_MODEL_CB(_id, _op, _pub, _user_data, NULL)
426 :
427 : /**
428 : * @brief Composition data vendor model entry.
429 : *
430 : * This macro uses compound literal feature of C99 standard and thus is available only from C,
431 : * not C++.
432 : *
433 : * @param _company Company ID.
434 : * @param _id Model ID.
435 : * @param _op Array of model opcode handlers.
436 : * @param _pub Model publish parameters.
437 : * @param _user_data User data for the model.
438 : */
439 1 : #define BT_MESH_MODEL_VND(_company, _id, _op, _pub, _user_data) \
440 : BT_MESH_MODEL_VND_CB(_company, _id, _op, _pub, _user_data, NULL)
441 : #endif /* !defined(__cplusplus) || defined(__DOXYGEN__) */
442 :
443 : /**
444 : * @brief Encode transmission count & interval steps.
445 : *
446 : * @param count Number of retransmissions (first transmission is excluded).
447 : * @param int_ms Interval steps in milliseconds. Must be greater than 0,
448 : * less than or equal to 320, and a multiple of 10.
449 : *
450 : * @return Mesh transmit value that can be used e.g. for the default
451 : * values of the configuration model data.
452 : */
453 1 : #define BT_MESH_TRANSMIT(count, int_ms) ((uint8_t)((count) | (((int_ms / 10) - 1) << 3)))
454 :
455 : /**
456 : * @brief Decode transmit count from a transmit value.
457 : *
458 : * @param transmit Encoded transmit count & interval value.
459 : *
460 : * @return Transmission count (actual transmissions is N + 1).
461 : */
462 1 : #define BT_MESH_TRANSMIT_COUNT(transmit) (((transmit) & (uint8_t)BIT_MASK(3)))
463 :
464 : /**
465 : * @brief Decode transmit interval from a transmit value.
466 : *
467 : * @param transmit Encoded transmit count & interval value.
468 : *
469 : * @return Transmission interval in milliseconds.
470 : */
471 1 : #define BT_MESH_TRANSMIT_INT(transmit) ((((transmit) >> 3) + 1) * 10)
472 :
473 : /**
474 : * @brief Encode Publish Retransmit count & interval steps.
475 : *
476 : * @param count Number of retransmissions (first transmission is excluded).
477 : * @param int_ms Interval steps in milliseconds. Must be greater than 0 and a
478 : * multiple of 50.
479 : *
480 : * @return Mesh transmit value that can be used e.g. for the default
481 : * values of the configuration model data.
482 : */
483 1 : #define BT_MESH_PUB_TRANSMIT(count, int_ms) BT_MESH_TRANSMIT(count, \
484 : (int_ms) / 5)
485 :
486 : /**
487 : * @brief Decode Publish Retransmit count from a given value.
488 : *
489 : * @param transmit Encoded Publish Retransmit count & interval value.
490 : *
491 : * @return Retransmission count (actual transmissions is N + 1).
492 : */
493 1 : #define BT_MESH_PUB_TRANSMIT_COUNT(transmit) BT_MESH_TRANSMIT_COUNT(transmit)
494 :
495 : /**
496 : * @brief Decode Publish Retransmit interval from a given value.
497 : *
498 : * @param transmit Encoded Publish Retransmit count & interval value.
499 : *
500 : * @return Transmission interval in milliseconds.
501 : */
502 1 : #define BT_MESH_PUB_TRANSMIT_INT(transmit) ((((transmit) >> 3) + 1) * 50)
503 :
504 : /**
505 : * @brief Get total number of messages within one publication interval including initial
506 : * publication.
507 : *
508 : * @param pub Model publication context.
509 : *
510 : * @return total number of messages.
511 : */
512 1 : #define BT_MESH_PUB_MSG_TOTAL(pub) (BT_MESH_PUB_TRANSMIT_COUNT((pub)->retransmit) + 1)
513 :
514 : /**
515 : * @brief Get message number within one publication interval.
516 : *
517 : * Meant to be used inside @ref bt_mesh_model_pub.update.
518 : *
519 : * @param pub Model publication context.
520 : *
521 : * @return message number starting from 1.
522 : */
523 1 : #define BT_MESH_PUB_MSG_NUM(pub) (BT_MESH_PUB_TRANSMIT_COUNT((pub)->retransmit) + 1 - (pub)->count)
524 :
525 : /** Model publication context.
526 : *
527 : * The context should primarily be created using the
528 : * BT_MESH_MODEL_PUB_DEFINE macro.
529 : */
530 1 : struct bt_mesh_model_pub {
531 : /** The model the context belongs to. Initialized by the stack. */
532 1 : const struct bt_mesh_model *mod;
533 :
534 1 : uint16_t addr; /**< Publish Address. */
535 1 : const uint8_t *uuid; /**< Label UUID if Publish Address is Virtual Address. */
536 1 : uint16_t key:12, /**< Publish AppKey Index. */
537 1 : cred:1, /**< Friendship Credentials Flag. */
538 1 : send_rel:1, /**< Force reliable sending (segment acks) */
539 1 : fast_period:1, /**< Use FastPeriodDivisor */
540 1 : retr_update:1; /**< Call update callback on every retransmission. */
541 :
542 1 : uint8_t ttl; /**< Publish Time to Live. */
543 1 : uint8_t retransmit; /**< Retransmit Count & Interval Steps. */
544 1 : uint8_t period; /**< Publish Period. */
545 1 : uint8_t period_div:4, /**< Divisor for the Period. */
546 1 : count:4; /**< Transmissions left. */
547 :
548 1 : uint8_t delayable:1; /**< Use random delay for publishing. */
549 :
550 1 : uint32_t period_start; /**< Start of the current period. */
551 :
552 : /** @brief Publication buffer, containing the publication message.
553 : *
554 : * This will get correctly created when the publication context
555 : * has been defined using the BT_MESH_MODEL_PUB_DEFINE macro.
556 : *
557 : * BT_MESH_MODEL_PUB_DEFINE(name, update, size);
558 : */
559 1 : struct net_buf_simple *msg;
560 :
561 : /** @brief Callback for updating the publication buffer.
562 : *
563 : * When set to NULL, the model is assumed not to support
564 : * periodic publishing. When set to non-NULL the callback
565 : * will be called periodically and is expected to update
566 : * @ref bt_mesh_model_pub.msg with a valid publication
567 : * message.
568 : *
569 : * If the callback returns non-zero, the publication is skipped
570 : * and will resume on the next periodic publishing interval.
571 : *
572 : * When @ref bt_mesh_model_pub.retr_update is set to 1,
573 : * the callback will be called on every retransmission.
574 : *
575 : * @param mod The Model the Publication Context belongs to.
576 : *
577 : * @return Zero on success or (negative) error code otherwise.
578 : */
579 1 : int (*update)(const struct bt_mesh_model *mod);
580 :
581 : /** Publish Period Timer. Only for stack-internal use. */
582 1 : struct k_work_delayable timer;
583 : };
584 :
585 : /**
586 : * Define a model publication context.
587 : *
588 : * @param _name Variable name given to the context.
589 : * @param _update Optional message update callback (may be NULL).
590 : * @param _msg_len Length of the publication message.
591 : */
592 1 : #define BT_MESH_MODEL_PUB_DEFINE(_name, _update, _msg_len) \
593 : NET_BUF_SIMPLE_DEFINE_STATIC(bt_mesh_pub_msg_##_name, _msg_len); \
594 : static struct bt_mesh_model_pub _name = { \
595 : .msg = &bt_mesh_pub_msg_##_name, \
596 : .update = _update, \
597 : }
598 :
599 : /** Models Metadata Entry struct
600 : *
601 : * The struct should primarily be created using the
602 : * BT_MESH_MODELS_METADATA_ENTRY macro.
603 : */
604 1 : struct bt_mesh_models_metadata_entry {
605 : /** Length of the metadata */
606 1 : const uint16_t len;
607 :
608 : /** ID of the metadata */
609 1 : const uint16_t id;
610 :
611 : /** Pointer to raw data */
612 1 : const void * const data;
613 : };
614 :
615 : /**
616 : *
617 : * Initialize a Models Metadata entry structure in a list.
618 : *
619 : * @param _len Length of the metadata entry.
620 : * @param _id ID of the Models Metadata entry.
621 : * @param _data Pointer to a contiguous memory that contains the metadata.
622 : */
623 1 : #define BT_MESH_MODELS_METADATA_ENTRY(_len, _id, _data) \
624 : { \
625 : .len = (_len), .id = _id, .data = _data, \
626 : }
627 :
628 : /** Helper to define an empty Models metadata array */
629 1 : #define BT_MESH_MODELS_METADATA_NONE NULL
630 :
631 : /** End of the Models Metadata list. Must always be present. */
632 1 : #define BT_MESH_MODELS_METADATA_END { 0, 0, NULL }
633 :
634 : /** Model callback functions. */
635 1 : struct bt_mesh_model_cb {
636 : /** @brief Set value handler of user data tied to the model.
637 : *
638 : * @sa settings_handler::h_set
639 : *
640 : * @param model Model to set the persistent data of.
641 : * @param name Name/key of the settings item.
642 : * @param len_rd The size of the data found in the backend.
643 : * @param read_cb Function provided to read the data from the backend.
644 : * @param cb_arg Arguments for the read function provided by the
645 : * backend.
646 : *
647 : * @return 0 on success, error otherwise.
648 : */
649 1 : int (*const settings_set)(const struct bt_mesh_model *model,
650 : const char *name, size_t len_rd,
651 : settings_read_cb read_cb, void *cb_arg);
652 :
653 : /** @brief Callback called when the mesh is started.
654 : *
655 : * This handler gets called after the node has been provisioned, or
656 : * after all mesh data has been loaded from persistent storage.
657 : *
658 : * When this callback fires, the mesh model may start its behavior,
659 : * and all Access APIs are ready for use.
660 : *
661 : * @param model Model this callback belongs to.
662 : *
663 : * @return 0 on success, error otherwise.
664 : */
665 1 : int (*const start)(const struct bt_mesh_model *model);
666 :
667 : /** @brief Model init callback.
668 : *
669 : * Called on every model instance during mesh initialization.
670 : *
671 : * If any of the model init callbacks return an error, the Mesh
672 : * subsystem initialization will be aborted, and the error will be
673 : * returned to the caller of @ref bt_mesh_init.
674 : *
675 : * @param model Model to be initialized.
676 : *
677 : * @return 0 on success, error otherwise.
678 : */
679 1 : int (*const init)(const struct bt_mesh_model *model);
680 :
681 : /** @brief Model reset callback.
682 : *
683 : * Called when the mesh node is reset. All model data is deleted on
684 : * reset, and the model should clear its state.
685 : *
686 : * @note If the model stores any persistent data, this needs to be
687 : * erased manually.
688 : *
689 : * @param model Model this callback belongs to.
690 : */
691 1 : void (*const reset)(const struct bt_mesh_model *model);
692 :
693 : /** @brief Callback used to store pending model's user data.
694 : *
695 : * Triggered by @ref bt_mesh_model_data_store_schedule.
696 : *
697 : * To store the user data, call @ref bt_mesh_model_data_store.
698 : *
699 : * @param model Model this callback belongs to.
700 : */
701 1 : void (*const pending_store)(const struct bt_mesh_model *model);
702 : };
703 :
704 : /** Vendor model ID */
705 1 : struct bt_mesh_mod_id_vnd {
706 : /** Vendor's company ID */
707 1 : uint16_t company;
708 : /** Model ID */
709 1 : uint16_t id;
710 : };
711 :
712 : /** Abstraction that describes a Mesh Model instance */
713 1 : struct bt_mesh_model {
714 : union {
715 : /** SIG model ID */
716 1 : const uint16_t id;
717 : /** Vendor model ID */
718 1 : const struct bt_mesh_mod_id_vnd vnd;
719 0 : };
720 :
721 : /* Model runtime information */
722 0 : struct bt_mesh_model_rt_ctx {
723 0 : uint8_t elem_idx; /* Belongs to Nth element */
724 0 : uint8_t mod_idx; /* Is the Nth model in the element */
725 0 : uint16_t flags; /* Model flags for internal bookkeeping */
726 :
727 : #ifdef CONFIG_BT_MESH_MODEL_EXTENSIONS
728 : /* Pointer to the next model in a model extension list. */
729 0 : const struct bt_mesh_model *next;
730 : #endif
731 : /** Model-specific user data */
732 1 : void *user_data;
733 0 : } * const rt;
734 :
735 : /** Model Publication */
736 1 : struct bt_mesh_model_pub * const pub;
737 :
738 : /** AppKey List */
739 1 : uint16_t * const keys;
740 0 : const uint16_t keys_cnt;
741 :
742 : /** Subscription List (group or virtual addresses) */
743 1 : uint16_t * const groups;
744 0 : const uint16_t groups_cnt;
745 :
746 : #if (CONFIG_BT_MESH_LABEL_COUNT > 0) || defined(__DOXYGEN__)
747 : /** List of Label UUIDs the model is subscribed to. */
748 1 : const uint8_t ** const uuids;
749 : #endif
750 :
751 : /** Opcode handler list */
752 1 : const struct bt_mesh_model_op * const op;
753 :
754 : /** Model callback structure. */
755 1 : const struct bt_mesh_model_cb * const cb;
756 :
757 : #if defined(CONFIG_BT_MESH_LARGE_COMP_DATA_SRV) || defined(__DOXYGEN__)
758 : /* Pointer to the array of model metadata entries. */
759 0 : const struct bt_mesh_models_metadata_entry * const metadata;
760 : #endif
761 : };
762 :
763 : /** Callback structure for monitoring model message sending */
764 1 : struct bt_mesh_send_cb {
765 : /** @brief Handler called at the start of the transmission.
766 : *
767 : * @param duration The duration of the full transmission.
768 : * @param err Error occurring during sending.
769 : * @param cb_data Callback data, as passed to the send API.
770 : */
771 1 : void (*start)(uint16_t duration, int err, void *cb_data);
772 : /** @brief Handler called at the end of the transmission.
773 : *
774 : * @param err Error occurring during sending.
775 : * @param cb_data Callback data, as passed to the send API.
776 : */
777 1 : void (*end)(int err, void *cb_data);
778 : };
779 :
780 :
781 : /** Special TTL value to request using configured default TTL */
782 1 : #define BT_MESH_TTL_DEFAULT 0xff
783 :
784 : /** Maximum allowed TTL value */
785 1 : #define BT_MESH_TTL_MAX 0x7f
786 :
787 : /** @brief Send an Access Layer message.
788 : *
789 : * @param model Mesh (client) Model that the message belongs to.
790 : * @param ctx Message context, includes keys, TTL, etc.
791 : * @param msg Access Layer payload (the actual message to be sent).
792 : * @param cb Optional "message sent" callback.
793 : * @param cb_data User data to be passed to the callback.
794 : *
795 : * @return 0 on success, or (negative) error code on failure.
796 : */
797 1 : int bt_mesh_model_send(const struct bt_mesh_model *model,
798 : struct bt_mesh_msg_ctx *ctx,
799 : struct net_buf_simple *msg,
800 : const struct bt_mesh_send_cb *cb,
801 : void *cb_data);
802 :
803 : /** @brief Send a model publication message.
804 : *
805 : * Before calling this function, the user needs to ensure that the model
806 : * publication message (@ref bt_mesh_model_pub.msg) contains a valid
807 : * message to be sent. Note that this API is only to be used for
808 : * non-period publishing. For periodic publishing the app only needs
809 : * to make sure that @ref bt_mesh_model_pub.msg contains a valid message
810 : * whenever the @ref bt_mesh_model_pub.update callback is called.
811 : *
812 : * @param model Mesh (client) Model that's publishing the message.
813 : *
814 : * @return 0 on success, or (negative) error code on failure.
815 : */
816 1 : int bt_mesh_model_publish(const struct bt_mesh_model *model);
817 :
818 : /** @brief Check if a message is being retransmitted.
819 : *
820 : * Meant to be used inside the @ref bt_mesh_model_pub.update callback.
821 : *
822 : * @param model Mesh Model that supports publication.
823 : *
824 : * @return true if this is a retransmission, false if this is a first publication.
825 : */
826 1 : static inline bool bt_mesh_model_pub_is_retransmission(const struct bt_mesh_model *model)
827 : {
828 : return model->pub->count != BT_MESH_PUB_TRANSMIT_COUNT(model->pub->retransmit);
829 : }
830 :
831 : /** @brief Get the element that a model belongs to.
832 : *
833 : * @param mod Mesh model.
834 : *
835 : * @return Pointer to the element that the given model belongs to.
836 : */
837 1 : const struct bt_mesh_elem *bt_mesh_model_elem(const struct bt_mesh_model *mod);
838 :
839 : /** @brief Find a SIG model.
840 : *
841 : * @param elem Element to search for the model in.
842 : * @param id Model ID of the model.
843 : *
844 : * @return A pointer to the Mesh model matching the given parameters, or NULL
845 : * if no SIG model with the given ID exists in the given element.
846 : */
847 1 : const struct bt_mesh_model *bt_mesh_model_find(const struct bt_mesh_elem *elem,
848 : uint16_t id);
849 :
850 : /** @brief Find a vendor model.
851 : *
852 : * @param elem Element to search for the model in.
853 : * @param company Company ID of the model.
854 : * @param id Model ID of the model.
855 : *
856 : * @return A pointer to the Mesh model matching the given parameters, or NULL
857 : * if no vendor model with the given ID exists in the given element.
858 : */
859 1 : const struct bt_mesh_model *bt_mesh_model_find_vnd(const struct bt_mesh_elem *elem,
860 : uint16_t company, uint16_t id);
861 :
862 : /** @brief Get whether the model is in the primary element of the device.
863 : *
864 : * @param mod Mesh model.
865 : *
866 : * @return true if the model is on the primary element, false otherwise.
867 : */
868 1 : static inline bool bt_mesh_model_in_primary(const struct bt_mesh_model *mod)
869 : {
870 : return (mod->rt->elem_idx == 0);
871 : }
872 :
873 : /** @brief Immediately store the model's user data in persistent storage.
874 : *
875 : * @param mod Mesh model.
876 : * @param vnd This is a vendor model.
877 : * @param name Name/key of the settings item. Only
878 : * @ref SETTINGS_MAX_DIR_DEPTH bytes will be used at most.
879 : * @param data Model data to store, or NULL to delete any model data.
880 : * @param data_len Length of the model data.
881 : *
882 : * @return 0 on success, or (negative) error code on failure.
883 : */
884 1 : int bt_mesh_model_data_store(const struct bt_mesh_model *mod, bool vnd,
885 : const char *name, const void *data,
886 : size_t data_len);
887 :
888 : /** @brief Schedule the model's user data store in persistent storage.
889 : *
890 : * This function triggers the @ref bt_mesh_model_cb.pending_store callback
891 : * for the corresponding model after delay defined by
892 : * @kconfig{CONFIG_BT_MESH_STORE_TIMEOUT}.
893 : *
894 : * The delay is global for all models. Once scheduled, the callback can
895 : * not be re-scheduled until previous schedule completes.
896 : *
897 : * @param mod Mesh model.
898 : */
899 1 : void bt_mesh_model_data_store_schedule(const struct bt_mesh_model *mod);
900 :
901 : /** @brief Let a model extend another.
902 : *
903 : * Mesh models may be extended to reuse their functionality, forming a more
904 : * complex model. A Mesh model may extend any number of models, in any element.
905 : * The extensions may also be nested, ie a model that extends another may
906 : * itself be extended.
907 : *
908 : * A set of models that extend each other form a model extension list.
909 : *
910 : * All models in an extension list share one subscription list per element. The
911 : * access layer will utilize the combined subscription list of all models in an
912 : * extension list and element, giving the models extended subscription list
913 : * capacity.
914 : *
915 : * If @kconfig{CONFIG_BT_MESH_COMP_PAGE_1} is enabled, it is not allowed to call
916 : * this function before the @ref bt_mesh_model_cb.init callback is called
917 : * for both models, except if it is called as part of the final callback.
918 : *
919 : * @param extending_mod Mesh model that is extending the base model.
920 : * @param base_mod The model being extended.
921 : *
922 : * @retval 0 Successfully extended the base_mod model.
923 : */
924 1 : int bt_mesh_model_extend(const struct bt_mesh_model *extending_mod,
925 : const struct bt_mesh_model *base_mod);
926 :
927 : /** @brief Let a model correspond to another.
928 : *
929 : * Mesh models may correspond to each other, which means that if one is present,
930 : * other must be present too. A Mesh model may correspond to any number of models,
931 : * in any element. All models connected together via correspondence form single
932 : * Correspondence Group, which has it's unique Correspondence ID. Information about
933 : * Correspondence is used to construct Composition Data Page 1.
934 : *
935 : * This function must be called on already initialized base_mod. Because this function
936 : * is designed to be called in corresponding_mod initializer, this means that base_mod
937 : * shall be initialized before corresponding_mod is.
938 : *
939 : * @param corresponding_mod Mesh model that is corresponding to the base model.
940 : * @param base_mod The model being corresponded to.
941 : *
942 : * @retval 0 Successfully saved correspondence to the base_mod model.
943 : * @retval -ENOMEM There is no more space to save this relation.
944 : * @retval -ENOTSUP Composition Data Page 1 is not supported.
945 : */
946 :
947 1 : int bt_mesh_model_correspond(const struct bt_mesh_model *corresponding_mod,
948 : const struct bt_mesh_model *base_mod);
949 :
950 : /** @brief Check if model is extended by another model.
951 : *
952 : * @param model The model to check.
953 : *
954 : * @retval true If model is extended by another model, otherwise false
955 : */
956 1 : bool bt_mesh_model_is_extended(const struct bt_mesh_model *model);
957 :
958 : /** @brief Indicate that the composition data will change on next bootup.
959 : *
960 : * Tell the config server that the composition data is expected to change on
961 : * the next bootup, and the current composition data should be backed up.
962 : *
963 : * @return Zero on success or (negative) error code otherwise.
964 : */
965 1 : int bt_mesh_comp_change_prepare(void);
966 :
967 : /** @brief Indicate that the metadata will change on next bootup.
968 : *
969 : * Tell the config server that the models metadata is expected to change on
970 : * the next bootup, and the current models metadata should be backed up.
971 : *
972 : * @return Zero on success or (negative) error code otherwise.
973 : */
974 1 : int bt_mesh_models_metadata_change_prepare(void);
975 :
976 : /** Node Composition */
977 1 : struct bt_mesh_comp {
978 1 : uint16_t cid; /**< Company ID */
979 1 : uint16_t pid; /**< Product ID */
980 1 : uint16_t vid; /**< Version ID */
981 :
982 1 : size_t elem_count; /**< The number of elements in this device. */
983 1 : const struct bt_mesh_elem *elem; /**< List of elements. */
984 : };
985 :
986 : /** Composition data page 2 record. */
987 1 : struct bt_mesh_comp2_record {
988 : /** Mesh profile ID. */
989 1 : uint16_t id;
990 : /** Mesh Profile Version. */
991 : struct {
992 : /** Major version. */
993 1 : uint8_t x;
994 : /** Minor version. */
995 1 : uint8_t y;
996 : /** Z version. */
997 1 : uint8_t z;
998 1 : } version;
999 : /** Element offset count. */
1000 1 : uint8_t elem_offset_cnt;
1001 : /** Element offset list. */
1002 1 : const uint8_t *elem_offset;
1003 : /** Length of additional data. */
1004 1 : uint16_t data_len;
1005 : /** Additional data. */
1006 1 : const void *data;
1007 : };
1008 :
1009 : /** Node Composition data page 2 */
1010 1 : struct bt_mesh_comp2 {
1011 : /** The number of Mesh Profile records on a device. */
1012 1 : size_t record_cnt;
1013 : /** List of records. */
1014 1 : const struct bt_mesh_comp2_record *record;
1015 : };
1016 :
1017 : /** @brief Register composition data page 2 of the device.
1018 : *
1019 : * Register Mesh Profiles information (Ref section 3.12 in
1020 : * Bluetooth SIG Assigned Numbers) for composition data
1021 : * page 2 of the device.
1022 : *
1023 : * @note There must be at least one record present in @c comp2
1024 : *
1025 : * @param comp2 Pointer to composition data page 2.
1026 : *
1027 : * @return Zero on success or (negative) error code otherwise.
1028 : */
1029 1 : int bt_mesh_comp2_register(const struct bt_mesh_comp2 *comp2);
1030 :
1031 : #ifdef __cplusplus
1032 : }
1033 : #endif
1034 :
1035 : /**
1036 : * @}
1037 : */
1038 :
1039 : #endif /* ZEPHYR_INCLUDE_BLUETOOTH_MESH_ACCESS_H_ */
|