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/mesh/msg.h>
16
17 /* Internal macros used to initialize array members */
18 #define BT_MESH_KEY_UNUSED_ELT_(IDX, _) BT_MESH_KEY_UNUSED
19 #define BT_MESH_ADDR_UNASSIGNED_ELT_(IDX, _) BT_MESH_ADDR_UNASSIGNED
20 #define BT_MESH_MODEL_KEYS_UNUSED(_keys) \
21 { LISTIFY(_keys, BT_MESH_KEY_UNUSED_ELT_, (,)) }
22 #define BT_MESH_MODEL_GROUPS_UNASSIGNED(_grps) \
23 { LISTIFY(_grps, BT_MESH_ADDR_UNASSIGNED_ELT_, (,)) }
24
25 /**
26 * @brief Access layer
27 * @defgroup bt_mesh_access Access layer
28 * @ingroup bt_mesh
29 * @{
30 */
31
32 #ifdef __cplusplus
33 extern "C" {
34 #endif
35
36 #define BT_MESH_ADDR_UNASSIGNED 0x0000
37 #define BT_MESH_ADDR_ALL_NODES 0xffff
38 #define BT_MESH_ADDR_RELAYS 0xfffe
39 #define BT_MESH_ADDR_FRIENDS 0xfffd
40 #define BT_MESH_ADDR_PROXIES 0xfffc
41 #define BT_MESH_ADDR_DFW_NODES 0xfffb
42 #define BT_MESH_ADDR_IP_NODES 0xfffa
43 #define BT_MESH_ADDR_IP_BR_ROUTERS 0xfff9
44
45 #define BT_MESH_KEY_UNUSED 0xffff
46 #define BT_MESH_KEY_ANY 0xffff
47 #define BT_MESH_KEY_DEV 0xfffe
48 #define BT_MESH_KEY_DEV_LOCAL BT_MESH_KEY_DEV
49 #define BT_MESH_KEY_DEV_REMOTE 0xfffd
50 #define BT_MESH_KEY_DEV_ANY 0xfffc
51
52 #define BT_MESH_ADDR_IS_UNICAST(addr) ((addr) && (addr) < 0x8000)
53 #define BT_MESH_ADDR_IS_GROUP(addr) ((addr) >= 0xc000 && (addr) < 0xff00)
54 #define BT_MESH_ADDR_IS_FIXED_GROUP(addr) ((addr) >= 0xff00 && (addr) < 0xffff)
55 #define BT_MESH_ADDR_IS_VIRTUAL(addr) ((addr) >= 0x8000 && (addr) < 0xc000)
56 #define BT_MESH_ADDR_IS_RFU(addr) ((addr) >= 0xff00 && (addr) <= 0xfff8)
57
58 #define BT_MESH_IS_DEV_KEY(key) (key == BT_MESH_KEY_DEV_LOCAL || \
59 key == BT_MESH_KEY_DEV_REMOTE)
60
61 /** Maximum size of an access message segment (in octets). */
62 #define BT_MESH_APP_SEG_SDU_MAX 12
63
64 /** Maximum payload size of an unsegmented access message (in octets). */
65 #define BT_MESH_APP_UNSEG_SDU_MAX 15
66
67 /** Maximum number of segments supported for incoming messages. */
68 #if defined(CONFIG_BT_MESH_RX_SEG_MAX)
69 #define BT_MESH_RX_SEG_MAX CONFIG_BT_MESH_RX_SEG_MAX
70 #else
71 #define BT_MESH_RX_SEG_MAX 0
72 #endif
73
74 /** Maximum number of segments supported for outgoing messages. */
75 #if defined(CONFIG_BT_MESH_TX_SEG_MAX)
76 #define BT_MESH_TX_SEG_MAX CONFIG_BT_MESH_TX_SEG_MAX
77 #else
78 #define BT_MESH_TX_SEG_MAX 0
79 #endif
80
81 /** Maximum possible payload size of an outgoing access message (in octets). */
82 #define BT_MESH_TX_SDU_MAX MAX((BT_MESH_TX_SEG_MAX * \
83 BT_MESH_APP_SEG_SDU_MAX), \
84 BT_MESH_APP_UNSEG_SDU_MAX)
85
86 /** Maximum possible payload size of an incoming access message (in octets). */
87 #define BT_MESH_RX_SDU_MAX MAX((BT_MESH_RX_SEG_MAX * \
88 BT_MESH_APP_SEG_SDU_MAX), \
89 BT_MESH_APP_UNSEG_SDU_MAX)
90
91 /** Helper to define a mesh element within an array.
92 *
93 * In case the element has no SIG or Vendor models the helper
94 * macro BT_MESH_MODEL_NONE can be given instead.
95 *
96 * @param _loc Location Descriptor.
97 * @param _mods Array of models.
98 * @param _vnd_mods Array of vendor models.
99 */
100 #define BT_MESH_ELEM(_loc, _mods, _vnd_mods) \
101 { \
102 .loc = (_loc), \
103 .model_count = ARRAY_SIZE(_mods), \
104 .vnd_model_count = ARRAY_SIZE(_vnd_mods), \
105 .models = (_mods), \
106 .vnd_models = (_vnd_mods), \
107 }
108
109 /** Abstraction that describes a Mesh Element */
110 struct bt_mesh_elem {
111 /** Unicast Address. Set at runtime during provisioning. */
112 uint16_t addr;
113
114 /** Location Descriptor (GATT Bluetooth Namespace Descriptors) */
115 const uint16_t loc;
116 /** The number of SIG models in this element */
117 const uint8_t model_count;
118 /** The number of vendor models in this element */
119 const uint8_t vnd_model_count;
120
121 /** The list of SIG models in this element */
122 struct bt_mesh_model * const models;
123 /** The list of vendor models in this element */
124 struct bt_mesh_model * const vnd_models;
125 };
126
127 /* Foundation Models */
128 #define BT_MESH_MODEL_ID_CFG_SRV 0x0000
129 #define BT_MESH_MODEL_ID_CFG_CLI 0x0001
130 #define BT_MESH_MODEL_ID_HEALTH_SRV 0x0002
131 #define BT_MESH_MODEL_ID_HEALTH_CLI 0x0003
132 #define BT_MESH_MODEL_ID_REMOTE_PROV_SRV 0x0004
133 #define BT_MESH_MODEL_ID_REMOTE_PROV_CLI 0x0005
134 #define BT_MESH_MODEL_ID_PRIV_BEACON_SRV 0x000a
135 #define BT_MESH_MODEL_ID_PRIV_BEACON_CLI 0x000b
136 #define BT_MESH_MODEL_ID_SAR_CFG_SRV 0x000e
137 #define BT_MESH_MODEL_ID_SAR_CFG_CLI 0x000f
138 #define BT_MESH_MODEL_ID_OP_AGG_SRV 0x0010
139 #define BT_MESH_MODEL_ID_OP_AGG_CLI 0x0011
140 #define BT_MESH_MODEL_ID_LARGE_COMP_DATA_SRV 0x0012
141 #define BT_MESH_MODEL_ID_LARGE_COMP_DATA_CLI 0x0013
142 #define BT_MESH_MODEL_ID_SOL_PDU_RPL_SRV 0x0014
143 #define BT_MESH_MODEL_ID_SOL_PDU_RPL_CLI 0x0015
144 #define BT_MESH_MODEL_ID_ON_DEMAND_PROXY_SRV 0x000c
145 #define BT_MESH_MODEL_ID_ON_DEMAND_PROXY_CLI 0x000d
146
147 /* Models from the Mesh Model Specification */
148 #define BT_MESH_MODEL_ID_GEN_ONOFF_SRV 0x1000
149 #define BT_MESH_MODEL_ID_GEN_ONOFF_CLI 0x1001
150 #define BT_MESH_MODEL_ID_GEN_LEVEL_SRV 0x1002
151 #define BT_MESH_MODEL_ID_GEN_LEVEL_CLI 0x1003
152 #define BT_MESH_MODEL_ID_GEN_DEF_TRANS_TIME_SRV 0x1004
153 #define BT_MESH_MODEL_ID_GEN_DEF_TRANS_TIME_CLI 0x1005
154 #define BT_MESH_MODEL_ID_GEN_POWER_ONOFF_SRV 0x1006
155 #define BT_MESH_MODEL_ID_GEN_POWER_ONOFF_SETUP_SRV 0x1007
156 #define BT_MESH_MODEL_ID_GEN_POWER_ONOFF_CLI 0x1008
157 #define BT_MESH_MODEL_ID_GEN_POWER_LEVEL_SRV 0x1009
158 #define BT_MESH_MODEL_ID_GEN_POWER_LEVEL_SETUP_SRV 0x100a
159 #define BT_MESH_MODEL_ID_GEN_POWER_LEVEL_CLI 0x100b
160 #define BT_MESH_MODEL_ID_GEN_BATTERY_SRV 0x100c
161 #define BT_MESH_MODEL_ID_GEN_BATTERY_CLI 0x100d
162 #define BT_MESH_MODEL_ID_GEN_LOCATION_SRV 0x100e
163 #define BT_MESH_MODEL_ID_GEN_LOCATION_SETUPSRV 0x100f
164 #define BT_MESH_MODEL_ID_GEN_LOCATION_CLI 0x1010
165 #define BT_MESH_MODEL_ID_GEN_ADMIN_PROP_SRV 0x1011
166 #define BT_MESH_MODEL_ID_GEN_MANUFACTURER_PROP_SRV 0x1012
167 #define BT_MESH_MODEL_ID_GEN_USER_PROP_SRV 0x1013
168 #define BT_MESH_MODEL_ID_GEN_CLIENT_PROP_SRV 0x1014
169 #define BT_MESH_MODEL_ID_GEN_PROP_CLI 0x1015
170 #define BT_MESH_MODEL_ID_SENSOR_SRV 0x1100
171 #define BT_MESH_MODEL_ID_SENSOR_SETUP_SRV 0x1101
172 #define BT_MESH_MODEL_ID_SENSOR_CLI 0x1102
173 #define BT_MESH_MODEL_ID_TIME_SRV 0x1200
174 #define BT_MESH_MODEL_ID_TIME_SETUP_SRV 0x1201
175 #define BT_MESH_MODEL_ID_TIME_CLI 0x1202
176 #define BT_MESH_MODEL_ID_SCENE_SRV 0x1203
177 #define BT_MESH_MODEL_ID_SCENE_SETUP_SRV 0x1204
178 #define BT_MESH_MODEL_ID_SCENE_CLI 0x1205
179 #define BT_MESH_MODEL_ID_SCHEDULER_SRV 0x1206
180 #define BT_MESH_MODEL_ID_SCHEDULER_SETUP_SRV 0x1207
181 #define BT_MESH_MODEL_ID_SCHEDULER_CLI 0x1208
182 #define BT_MESH_MODEL_ID_LIGHT_LIGHTNESS_SRV 0x1300
183 #define BT_MESH_MODEL_ID_LIGHT_LIGHTNESS_SETUP_SRV 0x1301
184 #define BT_MESH_MODEL_ID_LIGHT_LIGHTNESS_CLI 0x1302
185 #define BT_MESH_MODEL_ID_LIGHT_CTL_SRV 0x1303
186 #define BT_MESH_MODEL_ID_LIGHT_CTL_SETUP_SRV 0x1304
187 #define BT_MESH_MODEL_ID_LIGHT_CTL_CLI 0x1305
188 #define BT_MESH_MODEL_ID_LIGHT_CTL_TEMP_SRV 0x1306
189 #define BT_MESH_MODEL_ID_LIGHT_HSL_SRV 0x1307
190 #define BT_MESH_MODEL_ID_LIGHT_HSL_SETUP_SRV 0x1308
191 #define BT_MESH_MODEL_ID_LIGHT_HSL_CLI 0x1309
192 #define BT_MESH_MODEL_ID_LIGHT_HSL_HUE_SRV 0x130a
193 #define BT_MESH_MODEL_ID_LIGHT_HSL_SAT_SRV 0x130b
194 #define BT_MESH_MODEL_ID_LIGHT_XYL_SRV 0x130c
195 #define BT_MESH_MODEL_ID_LIGHT_XYL_SETUP_SRV 0x130d
196 #define BT_MESH_MODEL_ID_LIGHT_XYL_CLI 0x130e
197 #define BT_MESH_MODEL_ID_LIGHT_LC_SRV 0x130f
198 #define BT_MESH_MODEL_ID_LIGHT_LC_SETUPSRV 0x1310
199 #define BT_MESH_MODEL_ID_LIGHT_LC_CLI 0x1311
200 #define BT_MESH_MODEL_ID_BLOB_SRV 0x1400
201 #define BT_MESH_MODEL_ID_BLOB_CLI 0x1401
202 #define BT_MESH_MODEL_ID_DFU_SRV 0x1402
203 #define BT_MESH_MODEL_ID_DFU_CLI 0x1403
204 #define BT_MESH_MODEL_ID_DFD_SRV 0x1404
205 #define BT_MESH_MODEL_ID_DFD_CLI 0x1405
206
207 /** Model opcode handler. */
208 struct bt_mesh_model_op {
209 /** OpCode encoded using the BT_MESH_MODEL_OP_* macros */
210 const uint32_t opcode;
211
212 /** Message length. If the message has variable length then this value
213 * indicates minimum message length and should be positive. Handler
214 * function should verify precise length based on the contents of the
215 * message. If the message has fixed length then this value should
216 * be negative. Use BT_MESH_LEN_* macros when defining this value.
217 */
218 const ssize_t len;
219
220 /** @brief Handler function for this opcode.
221 *
222 * @param model Model instance receiving the message.
223 * @param ctx Message context for the message.
224 * @param buf Message buffer containing the message payload, not
225 * including the opcode.
226 *
227 * @return Zero on success or (negative) error code otherwise.
228 */
229 int (*const func)(struct bt_mesh_model *model,
230 struct bt_mesh_msg_ctx *ctx,
231 struct net_buf_simple *buf);
232 };
233
234 #define BT_MESH_MODEL_OP_1(b0) (b0)
235 #define BT_MESH_MODEL_OP_2(b0, b1) (((b0) << 8) | (b1))
236 #define BT_MESH_MODEL_OP_3(b0, cid) ((((b0) << 16) | 0xc00000) | (cid))
237
238 /** Macro for encoding exact message length for fixed-length messages. */
239 #define BT_MESH_LEN_EXACT(len) (-len)
240 /** Macro for encoding minimum message length for variable-length messages. */
241 #define BT_MESH_LEN_MIN(len) (len)
242
243 /** End of the opcode list. Must always be present. */
244 #define BT_MESH_MODEL_OP_END { 0, 0, NULL }
245
246 #if !defined(__cplusplus) || defined(__DOXYGEN__)
247 /**
248 * @brief Helper to define an empty opcode list.
249 *
250 * This macro uses compound literal feature of C99 standard and thus is available only from C,
251 * not C++.
252 */
253 #define BT_MESH_MODEL_NO_OPS ((struct bt_mesh_model_op []) \
254 { BT_MESH_MODEL_OP_END })
255
256 /**
257 * @brief Helper to define an empty model array
258 *
259 * This macro uses compound literal feature of C99 standard and thus is available only from C,
260 * not C++.
261 */
262 #define BT_MESH_MODEL_NONE ((struct bt_mesh_model []){})
263
264 /**
265 * @brief Composition data SIG model entry with callback functions
266 * with specific number of keys & groups.
267 *
268 * This macro uses compound literal feature of C99 standard and thus is available only from C,
269 * not C++.
270 *
271 * @param _id Model ID.
272 * @param _op Array of model opcode handlers.
273 * @param _pub Model publish parameters.
274 * @param _user_data User data for the model.
275 * @param _keys Number of keys that can be bound to the model.
276 * Shall not exceed @kconfig{CONFIG_BT_MESH_MODEL_KEY_COUNT}.
277 * @param _grps Number of addresses that the model can be subscribed to.
278 * Shall not exceed @kconfig{CONFIG_BT_MESH_MODEL_GROUP_COUNT}.
279 * @param _cb Callback structure, or NULL to keep no callbacks.
280 */
281 #define BT_MESH_MODEL_CNT_CB(_id, _op, _pub, _user_data, _keys, _grps, _cb) \
282 { \
283 .id = (_id), \
284 .pub = _pub, \
285 .keys = (uint16_t []) BT_MESH_MODEL_KEYS_UNUSED(_keys), \
286 .keys_cnt = _keys, \
287 .groups = (uint16_t []) BT_MESH_MODEL_GROUPS_UNASSIGNED(_grps), \
288 .groups_cnt = _grps, \
289 .op = _op, \
290 .cb = _cb, \
291 .user_data = _user_data, \
292 }
293
294 /**
295 * @brief Composition data vendor model entry with callback functions
296 * with specific number of keys & groups.
297 *
298 * This macro uses compound literal feature of C99 standard and thus is available only from C,
299 * not C++.
300 *
301 * @param _company Company ID.
302 * @param _id Model ID.
303 * @param _op Array of model opcode handlers.
304 * @param _pub Model publish parameters.
305 * @param _user_data User data for the model.
306 * @param _keys Number of keys that can be bound to the model.
307 * Shall not exceed @kconfig{CONFIG_BT_MESH_MODEL_KEY_COUNT}.
308 * @param _grps Number of addresses that the model can be subscribed to.
309 * Shall not exceed @kconfig{CONFIG_BT_MESH_MODEL_GROUP_COUNT}.
310 * @param _cb Callback structure, or NULL to keep no callbacks.
311 */
312 #define BT_MESH_MODEL_CNT_VND_CB(_company, _id, _op, _pub, _user_data, _keys, _grps, _cb) \
313 { \
314 .vnd.company = (_company), \
315 .vnd.id = (_id), \
316 .op = _op, \
317 .pub = _pub, \
318 .keys = (uint16_t []) BT_MESH_MODEL_KEYS_UNUSED(_keys), \
319 .keys_cnt = _keys, \
320 .groups = (uint16_t []) BT_MESH_MODEL_GROUPS_UNASSIGNED(_grps), \
321 .groups_cnt = _grps, \
322 .user_data = _user_data, \
323 .cb = _cb, \
324 }
325
326 /**
327 * @brief Composition data SIG model entry with callback functions.
328 *
329 * This macro uses compound literal feature of C99 standard and thus is available only from C,
330 * not C++.
331 *
332 * @param _id Model ID.
333 * @param _op Array of model opcode handlers.
334 * @param _pub Model publish parameters.
335 * @param _user_data User data for the model.
336 * @param _cb Callback structure, or NULL to keep no callbacks.
337 */
338 #define BT_MESH_MODEL_CB(_id, _op, _pub, _user_data, _cb) \
339 BT_MESH_MODEL_CNT_CB(_id, _op, _pub, _user_data, \
340 CONFIG_BT_MESH_MODEL_KEY_COUNT, \
341 CONFIG_BT_MESH_MODEL_GROUP_COUNT, _cb)
342
343
344 /**
345 *
346 * @brief Composition data SIG model entry with callback functions and metadata.
347 *
348 * This macro uses compound literal feature of C99 standard and thus is available only from C,
349 * not C++.
350 *
351 * @param _id Model ID.
352 * @param _op Array of model opcode handlers.
353 * @param _pub Model publish parameters.
354 * @param _user_data User data for the model.
355 * @param _cb Callback structure, or NULL to keep no callbacks.
356 * @param _metadata Metadata structure.
357 */
358 #if defined(CONFIG_BT_MESH_LARGE_COMP_DATA_SRV)
359 #define BT_MESH_MODEL_METADATA_CB(_id, _op, _pub, _user_data, _cb, _metadata) \
360 { \
361 .id = (_id), \
362 .pub = _pub, \
363 .keys = (uint16_t []) BT_MESH_MODEL_KEYS_UNUSED(CONFIG_BT_MESH_MODEL_KEY_COUNT), \
364 .keys_cnt = CONFIG_BT_MESH_MODEL_KEY_COUNT, \
365 .groups = (uint16_t []) BT_MESH_MODEL_GROUPS_UNASSIGNED(CONFIG_BT_MESH_MODEL_GROUP_COUNT), \
366 .groups_cnt = CONFIG_BT_MESH_MODEL_GROUP_COUNT, \
367 .op = _op, \
368 .cb = _cb, \
369 .user_data = _user_data, \
370 .metadata = _metadata, \
371 }
372 #else
373 #define BT_MESH_MODEL_METADATA_CB(_id, _op, _pub, _user_data, _cb, _metadata) \
374 BT_MESH_MODEL_CB(_id, _op, _pub, _user_data, _cb)
375 #endif
376
377 /**
378 *
379 * @brief Composition data vendor model entry with callback functions.
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 */
391 #define BT_MESH_MODEL_VND_CB(_company, _id, _op, _pub, _user_data, _cb) \
392 BT_MESH_MODEL_CNT_VND_CB(_company, _id, _op, _pub, _user_data, \
393 CONFIG_BT_MESH_MODEL_KEY_COUNT, \
394 CONFIG_BT_MESH_MODEL_GROUP_COUNT, _cb)
395
396 /**
397 *
398 * @brief Composition data vendor model entry with callback functions and metadata.
399 *
400 * This macro uses compound literal feature of C99 standard and thus is available only from C,
401 * not C++.
402 *
403 * @param _company Company ID.
404 * @param _id Model ID.
405 * @param _op Array of model opcode handlers.
406 * @param _pub Model publish parameters.
407 * @param _user_data User data for the model.
408 * @param _cb Callback structure, or NULL to keep no callbacks.
409 * @param _metadata Metadata structure.
410 */
411 #define BT_MESH_MODEL_VND_METADATA_CB(_company, _id, _op, _pub, _user_data, _cb, _metadata) \
412 { \
413 .vnd.company = (_company), \
414 .vnd.id = (_id), \
415 .op = _op, \
416 .pub = _pub, \
417 .keys = (uint16_t []) BT_MESH_MODEL_KEYS_UNUSED(CONFIG_BT_MESH_MODEL_KEY_COUNT), \
418 .keys_cnt = CONFIG_BT_MESH_MODEL_KEY_COUNT, \
419 .groups = (uint16_t []) BT_MESH_MODEL_GROUPS_UNASSIGNED(CONFIG_BT_MESH_MODEL_GROUP_COUNT), \
420 .groups_cnt = CONFIG_BT_MESH_MODEL_GROUP_COUNT, \
421 .user_data = _user_data, \
422 .cb = _cb, \
423 .metadata = _metadata, \
424 }
425
426 /**
427 * @brief Composition data SIG model entry.
428 *
429 * This macro uses compound literal feature of C99 standard and thus is available only from C,
430 * not C++.
431 *
432 * @param _id Model ID.
433 * @param _op Array of model opcode handlers.
434 * @param _pub Model publish parameters.
435 * @param _user_data User data for the model.
436 */
437 #define BT_MESH_MODEL(_id, _op, _pub, _user_data) \
438 BT_MESH_MODEL_CB(_id, _op, _pub, _user_data, NULL)
439
440 /**
441 * @brief Composition data vendor model entry.
442 *
443 * This macro uses compound literal feature of C99 standard and thus is available only from C,
444 * not C++.
445 *
446 * @param _company Company ID.
447 * @param _id Model ID.
448 * @param _op Array of model opcode handlers.
449 * @param _pub Model publish parameters.
450 * @param _user_data User data for the model.
451 */
452 #define BT_MESH_MODEL_VND(_company, _id, _op, _pub, _user_data) \
453 BT_MESH_MODEL_VND_CB(_company, _id, _op, _pub, _user_data, NULL)
454 #endif /* !defined(__cplusplus) || defined(__DOXYGEN__) */
455
456 /**
457 * @brief Encode transmission count & interval steps.
458 *
459 * @param count Number of retransmissions (first transmission is excluded).
460 * @param int_ms Interval steps in milliseconds. Must be greater than 0,
461 * less than or equal to 320, and a multiple of 10.
462 *
463 * @return Mesh transmit value that can be used e.g. for the default
464 * values of the configuration model data.
465 */
466 #define BT_MESH_TRANSMIT(count, int_ms) ((count) | (((int_ms / 10) - 1) << 3))
467
468 /**
469 * @brief Decode transmit count from a transmit value.
470 *
471 * @param transmit Encoded transmit count & interval value.
472 *
473 * @return Transmission count (actual transmissions is N + 1).
474 */
475 #define BT_MESH_TRANSMIT_COUNT(transmit) (((transmit) & (uint8_t)BIT_MASK(3)))
476
477 /**
478 * @brief Decode transmit interval from a transmit value.
479 *
480 * @param transmit Encoded transmit count & interval value.
481 *
482 * @return Transmission interval in milliseconds.
483 */
484 #define BT_MESH_TRANSMIT_INT(transmit) ((((transmit) >> 3) + 1) * 10)
485
486 /**
487 * @brief Encode Publish Retransmit count & interval steps.
488 *
489 * @param count Number of retransmissions (first transmission is excluded).
490 * @param int_ms Interval steps in milliseconds. Must be greater than 0 and a
491 * multiple of 50.
492 *
493 * @return Mesh transmit value that can be used e.g. for the default
494 * values of the configuration model data.
495 */
496 #define BT_MESH_PUB_TRANSMIT(count, int_ms) BT_MESH_TRANSMIT(count, \
497 (int_ms) / 5)
498
499 /**
500 * @brief Decode Publish Retransmit count from a given value.
501 *
502 * @param transmit Encoded Publish Retransmit count & interval value.
503 *
504 * @return Retransmission count (actual transmissions is N + 1).
505 */
506 #define BT_MESH_PUB_TRANSMIT_COUNT(transmit) BT_MESH_TRANSMIT_COUNT(transmit)
507
508 /**
509 * @brief Decode Publish Retransmit interval from a given value.
510 *
511 * @param transmit Encoded Publish Retransmit count & interval value.
512 *
513 * @return Transmission interval in milliseconds.
514 */
515 #define BT_MESH_PUB_TRANSMIT_INT(transmit) ((((transmit) >> 3) + 1) * 50)
516
517 /**
518 * @brief Get total number of messages within one publication interval including initial
519 * publication.
520 *
521 * @param pub Model publication context.
522 *
523 * @return total number of messages.
524 */
525 #define BT_MESH_PUB_MSG_TOTAL(pub) (BT_MESH_PUB_TRANSMIT_COUNT((pub)->retransmit) + 1)
526
527 /**
528 * @brief Get message number within one publication interval.
529 *
530 * Meant to be used inside @ref bt_mesh_model_pub.update.
531 *
532 * @param pub Model publication context.
533 *
534 * @return message number starting from 1.
535 */
536 #define BT_MESH_PUB_MSG_NUM(pub) (BT_MESH_PUB_TRANSMIT_COUNT((pub)->retransmit) + 1 - (pub)->count)
537
538 /** Model publication context.
539 *
540 * The context should primarily be created using the
541 * BT_MESH_MODEL_PUB_DEFINE macro.
542 */
543 struct bt_mesh_model_pub {
544 /** The model the context belongs to. Initialized by the stack. */
545 struct bt_mesh_model *mod;
546
547 uint16_t addr; /**< Publish Address. */
548 uint16_t key:12, /**< Publish AppKey Index. */
549 cred:1, /**< Friendship Credentials Flag. */
550 send_rel:1, /**< Force reliable sending (segment acks) */
551 fast_period:1, /**< Use FastPeriodDivisor */
552 retr_update:1; /**< Call update callback on every retransmission. */
553
554 uint8_t ttl; /**< Publish Time to Live. */
555 uint8_t retransmit; /**< Retransmit Count & Interval Steps. */
556 uint8_t period; /**< Publish Period. */
557 uint8_t period_div:4, /**< Divisor for the Period. */
558 count:4; /**< Transmissions left. */
559
560 uint32_t period_start; /**< Start of the current period. */
561
562 /** @brief Publication buffer, containing the publication message.
563 *
564 * This will get correctly created when the publication context
565 * has been defined using the BT_MESH_MODEL_PUB_DEFINE macro.
566 *
567 * BT_MESH_MODEL_PUB_DEFINE(name, update, size);
568 */
569 struct net_buf_simple *msg;
570
571 /** @brief Callback for updating the publication buffer.
572 *
573 * When set to NULL, the model is assumed not to support
574 * periodic publishing. When set to non-NULL the callback
575 * will be called periodically and is expected to update
576 * @ref bt_mesh_model_pub.msg with a valid publication
577 * message.
578 *
579 * If the callback returns non-zero, the publication is skipped
580 * and will resume on the next periodic publishing interval.
581 *
582 * When @ref bt_mesh_model_pub.retr_update is set to 1,
583 * the callback will be called on every retransmission.
584 *
585 * @param mod The Model the Publication Context belongs to.
586 *
587 * @return Zero on success or (negative) error code otherwise.
588 */
589 int (*update)(struct bt_mesh_model *mod);
590
591 /** Publish Period Timer. Only for stack-internal use. */
592 struct k_work_delayable timer;
593 };
594
595 /**
596 * Define a model publication context.
597 *
598 * @param _name Variable name given to the context.
599 * @param _update Optional message update callback (may be NULL).
600 * @param _msg_len Length of the publication message.
601 */
602 #define BT_MESH_MODEL_PUB_DEFINE(_name, _update, _msg_len) \
603 NET_BUF_SIMPLE_DEFINE_STATIC(bt_mesh_pub_msg_##_name, _msg_len); \
604 static struct bt_mesh_model_pub _name = { \
605 .msg = &bt_mesh_pub_msg_##_name, \
606 .update = _update, \
607 }
608
609 /** Models Metadata Entry struct
610 *
611 * The struct should primarily be created using the
612 * BT_MESH_MODELS_METADATA_ENTRY macro.
613 */
614 struct bt_mesh_models_metadata_entry {
615 /* Length of the metadata */
616 const uint16_t len;
617
618 /* ID of the metadata */
619 const uint16_t id;
620
621 /* Pointer to raw data */
622 void *data;
623 };
624
625 /**
626 *
627 * Initialize a Models Metadata entry structure in a list.
628 *
629 * @param _len Length of the metadata entry.
630 * @param _id ID of the Models Metadata entry.
631 * @param _data Pointer to a contiguous memory that contains the metadata.
632 */
633 #define BT_MESH_MODELS_METADATA_ENTRY(_len, _id, _data) \
634 { \
635 .len = (_len), .id = _id, .data = _data, \
636 }
637
638 /** Helper to define an empty Models metadata array */
639 #define BT_MESH_MODELS_METADATA_NONE NULL
640
641 /** End of the Models Metadata list. Must always be present. */
642 #define BT_MESH_MODELS_METADATA_END { 0, 0, NULL }
643
644 /** Model callback functions. */
645 struct bt_mesh_model_cb {
646 /** @brief Set value handler of user data tied to the model.
647 *
648 * @sa settings_handler::h_set
649 *
650 * @param model Model to set the persistent data of.
651 * @param name Name/key of the settings item.
652 * @param len_rd The size of the data found in the backend.
653 * @param read_cb Function provided to read the data from the backend.
654 * @param cb_arg Arguments for the read function provided by the
655 * backend.
656 *
657 * @return 0 on success, error otherwise.
658 */
659 int (*const settings_set)(struct bt_mesh_model *model,
660 const char *name, size_t len_rd,
661 settings_read_cb read_cb, void *cb_arg);
662
663 /** @brief Callback called when the mesh is started.
664 *
665 * This handler gets called after the node has been provisioned, or
666 * after all mesh data has been loaded from persistent storage.
667 *
668 * When this callback fires, the mesh model may start its behavior,
669 * and all Access APIs are ready for use.
670 *
671 * @param model Model this callback belongs to.
672 *
673 * @return 0 on success, error otherwise.
674 */
675 int (*const start)(struct bt_mesh_model *model);
676
677 /** @brief Model init callback.
678 *
679 * Called on every model instance during mesh initialization.
680 *
681 * If any of the model init callbacks return an error, the Mesh
682 * subsystem initialization will be aborted, and the error will be
683 * returned to the caller of @ref bt_mesh_init.
684 *
685 * @param model Model to be initialized.
686 *
687 * @return 0 on success, error otherwise.
688 */
689 int (*const init)(struct bt_mesh_model *model);
690
691 /** @brief Model reset callback.
692 *
693 * Called when the mesh node is reset. All model data is deleted on
694 * reset, and the model should clear its state.
695 *
696 * @note If the model stores any persistent data, this needs to be
697 * erased manually.
698 *
699 * @param model Model this callback belongs to.
700 */
701 void (*const reset)(struct bt_mesh_model *model);
702
703 /** @brief Callback used to store pending model's user data.
704 *
705 * Triggered by @ref bt_mesh_model_data_store_schedule.
706 *
707 * To store the user data, call @ref bt_mesh_model_data_store.
708 *
709 * @param model Model this callback belongs to.
710 */
711 void (*const pending_store)(struct bt_mesh_model *model);
712 };
713
714 /** Vendor model ID */
715 struct bt_mesh_mod_id_vnd {
716 /** Vendor's company ID */
717 uint16_t company;
718 /** Model ID */
719 uint16_t id;
720 };
721
722 /** Abstraction that describes a Mesh Model instance */
723 struct bt_mesh_model {
724 union {
725 /** SIG model ID */
726 const uint16_t id;
727 /** Vendor model ID */
728 const struct bt_mesh_mod_id_vnd vnd;
729 };
730
731 /* Internal information, mainly for persistent storage */
732 uint8_t elem_idx; /* Belongs to Nth element */
733 uint8_t mod_idx; /* Is the Nth model in the element */
734 uint16_t flags; /* Model flags for internal bookkeeping */
735
736 /** Model Publication */
737 struct bt_mesh_model_pub * const pub;
738
739 /** AppKey List */
740 uint16_t * const keys;
741 const uint16_t keys_cnt;
742
743 /** Subscription List (group or virtual addresses) */
744 uint16_t * const groups;
745 const uint16_t groups_cnt;
746
747 /** Opcode handler list */
748 const struct bt_mesh_model_op * const op;
749
750 /** Model callback structure. */
751 const struct bt_mesh_model_cb * const cb;
752
753 #ifdef CONFIG_BT_MESH_MODEL_EXTENSIONS
754 /* Pointer to the next model in a model extension list. */
755 struct bt_mesh_model *next;
756 #endif
757
758 #ifdef CONFIG_BT_MESH_LARGE_COMP_DATA_SRV
759 /* Pointer to the array of model metadata entries. */
760 struct bt_mesh_models_metadata_entry **metadata;
761 #endif
762
763 /** Model-specific user data */
764 void *user_data;
765 };
766
767 /** Callback structure for monitoring model message sending */
768 struct bt_mesh_send_cb {
769 /** @brief Handler called at the start of the transmission.
770 *
771 * @param duration The duration of the full transmission.
772 * @param err Error occurring during sending.
773 * @param cb_data Callback data, as passed to the send API.
774 */
775 void (*start)(uint16_t duration, int err, void *cb_data);
776 /** @brief Handler called at the end of the transmission.
777 *
778 * @param err Error occurring during sending.
779 * @param cb_data Callback data, as passed to the send API.
780 */
781 void (*end)(int err, void *cb_data);
782 };
783
784
785 /** Special TTL value to request using configured default TTL */
786 #define BT_MESH_TTL_DEFAULT 0xff
787
788 /** Maximum allowed TTL value */
789 #define BT_MESH_TTL_MAX 0x7f
790
791 /** @brief Send an Access Layer message.
792 *
793 * @param model Mesh (client) Model that the message belongs to.
794 * @param ctx Message context, includes keys, TTL, etc.
795 * @param msg Access Layer payload (the actual message to be sent).
796 * @param cb Optional "message sent" callback.
797 * @param cb_data User data to be passed to the callback.
798 *
799 * @return 0 on success, or (negative) error code on failure.
800 */
801 int bt_mesh_model_send(struct bt_mesh_model *model,
802 struct bt_mesh_msg_ctx *ctx,
803 struct net_buf_simple *msg,
804 const struct bt_mesh_send_cb *cb,
805 void *cb_data);
806
807 /** @brief Send a model publication message.
808 *
809 * Before calling this function, the user needs to ensure that the model
810 * publication message (@ref bt_mesh_model_pub.msg) contains a valid
811 * message to be sent. Note that this API is only to be used for
812 * non-period publishing. For periodic publishing the app only needs
813 * to make sure that @ref bt_mesh_model_pub.msg contains a valid message
814 * whenever the @ref bt_mesh_model_pub.update callback is called.
815 *
816 * @param model Mesh (client) Model that's publishing the message.
817 *
818 * @return 0 on success, or (negative) error code on failure.
819 */
820 int bt_mesh_model_publish(struct bt_mesh_model *model);
821
822 /** @brief Check if a message is being retransmitted.
823 *
824 * Meant to be used inside the @ref bt_mesh_model_pub.update callback.
825 *
826 * @param model Mesh Model that supports publication.
827 *
828 * @return true if this is a retransmission, false if this is a first publication.
829 */
bt_mesh_model_pub_is_retransmission(const struct bt_mesh_model * model)830 static inline bool bt_mesh_model_pub_is_retransmission(const struct bt_mesh_model *model)
831 {
832 return model->pub->count != BT_MESH_PUB_TRANSMIT_COUNT(model->pub->retransmit);
833 }
834
835 /** @brief Get the element that a model belongs to.
836 *
837 * @param mod Mesh model.
838 *
839 * @return Pointer to the element that the given model belongs to.
840 */
841 struct bt_mesh_elem *bt_mesh_model_elem(struct bt_mesh_model *mod);
842
843 /** @brief Find a SIG model.
844 *
845 * @param elem Element to search for the model in.
846 * @param id Model ID of the model.
847 *
848 * @return A pointer to the Mesh model matching the given parameters, or NULL
849 * if no SIG model with the given ID exists in the given element.
850 */
851 struct bt_mesh_model *bt_mesh_model_find(const struct bt_mesh_elem *elem,
852 uint16_t id);
853
854 /** @brief Find a vendor model.
855 *
856 * @param elem Element to search for the model in.
857 * @param company Company ID of the model.
858 * @param id Model ID of the model.
859 *
860 * @return A pointer to the Mesh model matching the given parameters, or NULL
861 * if no vendor model with the given ID exists in the given element.
862 */
863 struct bt_mesh_model *bt_mesh_model_find_vnd(const struct bt_mesh_elem *elem,
864 uint16_t company, uint16_t id);
865
866 /** @brief Get whether the model is in the primary element of the device.
867 *
868 * @param mod Mesh model.
869 *
870 * @return true if the model is on the primary element, false otherwise.
871 */
bt_mesh_model_in_primary(const struct bt_mesh_model * mod)872 static inline bool bt_mesh_model_in_primary(const struct bt_mesh_model *mod)
873 {
874 return (mod->elem_idx == 0);
875 }
876
877 /** @brief Immediately store the model's user data in persistent storage.
878 *
879 * @param mod Mesh model.
880 * @param vnd This is a vendor model.
881 * @param name Name/key of the settings item. Only
882 * @ref SETTINGS_MAX_DIR_DEPTH bytes will be used at most.
883 * @param data Model data to store, or NULL to delete any model data.
884 * @param data_len Length of the model data.
885 *
886 * @return 0 on success, or (negative) error code on failure.
887 */
888 int bt_mesh_model_data_store(struct bt_mesh_model *mod, bool vnd,
889 const char *name, const void *data,
890 size_t data_len);
891
892 /** @brief Schedule the model's user data store in persistent storage.
893 *
894 * This function triggers the @ref bt_mesh_model_cb.pending_store callback
895 * for the corresponding model after delay defined by
896 * @kconfig{CONFIG_BT_MESH_STORE_TIMEOUT}.
897 *
898 * The delay is global for all models. Once scheduled, the callback can
899 * not be re-scheduled until previous schedule completes.
900 *
901 * @param mod Mesh model.
902 */
903 void bt_mesh_model_data_store_schedule(struct bt_mesh_model *mod);
904
905 /** @brief Let a model extend another.
906 *
907 * Mesh models may be extended to reuse their functionality, forming a more
908 * complex model. A Mesh model may extend any number of models, in any element.
909 * The extensions may also be nested, ie a model that extends another may
910 * itself be extended.
911 *
912 * A set of models that extend each other form a model extension list.
913 *
914 * All models in an extension list share one subscription list per element. The
915 * access layer will utilize the combined subscription list of all models in an
916 * extension list and element, giving the models extended subscription list
917 * capacity.
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 int bt_mesh_model_extend(struct bt_mesh_model *extending_mod,
925 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 int bt_mesh_model_correspond(struct bt_mesh_model *corresponding_mod,
948 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 bool bt_mesh_model_is_extended(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 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 int bt_mesh_models_metadata_change_prepare(void);
975
976 /** Node Composition */
977 struct bt_mesh_comp {
978 uint16_t cid; /**< Company ID */
979 uint16_t pid; /**< Product ID */
980 uint16_t vid; /**< Version ID */
981
982 size_t elem_count; /**< The number of elements in this device. */
983 struct bt_mesh_elem *elem; /**< List of elements. */
984 };
985
986 #ifdef __cplusplus
987 }
988 #endif
989
990 /**
991 * @}
992 */
993
994 #endif /* ZEPHYR_INCLUDE_BLUETOOTH_MESH_ACCESS_H_ */
995