xref: /nrf52832-nimble/packages/NimBLE-latest/nimble/host/mesh/include/mesh/access.h (revision 042d53a763ad75cb1465103098bb88c245d95138)
1 /** @file
2  *  @brief Bluetooth Mesh Access Layer APIs.
3  */
4 
5 /*
6  * Copyright (c) 2017 Intel Corporation
7  *
8  * SPDX-License-Identifier: Apache-2.0
9  */
10 #ifndef __BT_MESH_ACCESS_H
11 #define __BT_MESH_ACCESS_H
12 
13 /**
14  * @brief Bluetooth Mesh Access Layer
15  * @defgroup bt_mesh_access Bluetooth Mesh Access Layer
16  * @ingroup bt_mesh
17  * @{
18  */
19 
20 #define BT_MESH_ADDR_UNASSIGNED   0x0000
21 #define BT_MESH_ADDR_ALL_NODES    0xffff
22 #define BT_MESH_ADDR_PROXIES      0xfffc
23 #define BT_MESH_ADDR_FRIENDS      0xfffd
24 #define BT_MESH_ADDR_RELAYS       0xfffe
25 
26 #define BT_MESH_KEY_UNUSED        0xffff
27 #define BT_MESH_KEY_DEV           0xfffe
28 
29 /** Helper to define a mesh element within an array.
30  *
31  *  In case the element has no SIG or Vendor models the helper
32  *  macro BT_MESH_MODEL_NONE can be given instead.
33  *
34  *  @param _loc       Location Descriptor.
35  *  @param _mods      Array of models.
36  *  @param _vnd_mods  Array of vendor models.
37  */
38 #define BT_MESH_ELEM(_loc, _mods, _vnd_mods)        \
39 {                                                   \
40 	.loc              = (_loc),                 \
41 	.model_count      = ARRAY_SIZE(_mods),      \
42 	.models           = (_mods),                \
43 	.vnd_model_count  = ARRAY_SIZE(_vnd_mods),  \
44 	.vnd_models       = (_vnd_mods),            \
45 }
46 
47 /** Abstraction that describes a Mesh Element */
48 struct bt_mesh_elem {
49 	/* Unicast Address. Set at runtime during provisioning. */
50 	u16_t addr;
51 
52 	/* Location Descriptor (GATT Bluetooth Namespace Descriptors) */
53 	const u16_t loc;
54 
55 	const u8_t model_count;
56 	const u8_t vnd_model_count;
57 
58 	struct bt_mesh_model * const models;
59 	struct bt_mesh_model * const vnd_models;
60 };
61 
62 /* Foundation Models */
63 #define BT_MESH_MODEL_ID_CFG_SRV                   0x0000
64 #define BT_MESH_MODEL_ID_CFG_CLI                   0x0001
65 #define BT_MESH_MODEL_ID_HEALTH_SRV                0x0002
66 #define BT_MESH_MODEL_ID_HEALTH_CLI                0x0003
67 
68 /* Models from the Mesh Model Specification */
69 #define BT_MESH_MODEL_ID_GEN_ONOFF_SRV             0x1000
70 #define BT_MESH_MODEL_ID_GEN_ONOFF_CLI             0x1001
71 #define BT_MESH_MODEL_ID_GEN_LEVEL_SRV             0x1002
72 #define BT_MESH_MODEL_ID_GEN_LEVEL_CLI             0x1003
73 #define BT_MESH_MODEL_ID_GEN_DEF_TRANS_TIME_SRV    0x1004
74 #define BT_MESH_MODEL_ID_GEN_DEF_TRANS_TIME_CLI    0x1005
75 #define BT_MESH_MODEL_ID_GEN_POWER_ONOFF_SRV       0x1006
76 #define BT_MESH_MODEL_ID_GEN_POWER_ONOFF_SETUP_SRV 0x1007
77 #define BT_MESH_MODEL_ID_GEN_POWER_ONOFF_CLI       0x1008
78 #define BT_MESH_MODEL_ID_GEN_POWER_LEVEL_SRV       0x1009
79 #define BT_MESH_MODEL_ID_GEN_POWER_LEVEL_SETUP_SRV 0x100a
80 #define BT_MESH_MODEL_ID_GEN_POWER_LEVEL_CLI       0x100b
81 #define BT_MESH_MODEL_ID_GEN_BATTERY_SRV           0x100c
82 #define BT_MESH_MODEL_ID_GEN_BATTERY_CLI           0x100d
83 #define BT_MESH_MODEL_ID_GEN_LOCATION_SRV          0x100e
84 #define BT_MESH_MODEL_ID_GEN_LOCATION_SETUPSRV     0x100f
85 #define BT_MESH_MODEL_ID_GEN_LOCATION_CLI          0x1010
86 #define BT_MESH_MODEL_ID_GEN_ADMIN_PROP_SRV        0x1011
87 #define BT_MESH_MODEL_ID_GEN_MANUFACTURER_PROP_SRV 0x1012
88 #define BT_MESH_MODEL_ID_GEN_USER_PROP_SRV         0x1013
89 #define BT_MESH_MODEL_ID_GEN_CLIENT_PROP_SRV       0x1014
90 #define BT_MESH_MODEL_ID_GEN_PROP_CLI              0x1015
91 #define BT_MESH_MODEL_ID_SENSOR_SRV                0x1100
92 #define BT_MESH_MODEL_ID_SENSOR_SETUP_SRV          0x1101
93 #define BT_MESH_MODEL_ID_SENSOR_CLI                0x1102
94 #define BT_MESH_MODEL_ID_TIME_SRV                  0x1200
95 #define BT_MESH_MODEL_ID_TIME_SETUP_SRV            0x1201
96 #define BT_MESH_MODEL_ID_TIME_CLI                  0x1202
97 #define BT_MESH_MODEL_ID_SCENE_SRV                 0x1203
98 #define BT_MESH_MODEL_ID_SCENE_SETUP_SRV           0x1204
99 #define BT_MESH_MODEL_ID_SCENE_CLI                 0x1205
100 #define BT_MESH_MODEL_ID_SCHEDULER_SRV             0x1206
101 #define BT_MESH_MODEL_ID_SCHEDULER_SETUP_SRV       0x1207
102 #define BT_MESH_MODEL_ID_SCHEDULER_CLI             0x1208
103 #define BT_MESH_MODEL_ID_LIGHT_LIGHTNESS_SRV       0x1300
104 #define BT_MESH_MODEL_ID_LIGHT_LIGHTNESS_SETUP_SRV 0x1301
105 #define BT_MESH_MODEL_ID_LIGHT_LIGHTNESS_CLI       0x1302
106 #define BT_MESH_MODEL_ID_LIGHT_CTL_SRV             0x1303
107 #define BT_MESH_MODEL_ID_LIGHT_CTL_SETUP_SRV       0x1304
108 #define BT_MESH_MODEL_ID_LIGHT_CTL_CLI             0x1305
109 #define BT_MESH_MODEL_ID_LIGHT_CTL_TEMP_SRV        0x1306
110 #define BT_MESH_MODEL_ID_LIGHT_HSL_SRV             0x1307
111 #define BT_MESH_MODEL_ID_LIGHT_HSL_SETUP_SRV       0x1308
112 #define BT_MESH_MODEL_ID_LIGHT_HSL_CLI             0x1309
113 #define BT_MESH_MODEL_ID_LIGHT_HSL_HUE_SRV         0x130a
114 #define BT_MESH_MODEL_ID_LIGHT_HSL_SAT_SRV         0x130b
115 #define BT_MESH_MODEL_ID_LIGHT_XYL_SRV             0x130c
116 #define BT_MESH_MODEL_ID_LIGHT_XYL_SETUP_SRV       0x130d
117 #define BT_MESH_MODEL_ID_LIGHT_XYL_CLI             0x130e
118 #define BT_MESH_MODEL_ID_LIGHT_LC_SRV              0x130f
119 #define BT_MESH_MODEL_ID_LIGHT_LC_SETUPSRV         0x1310
120 #define BT_MESH_MODEL_ID_LIGHT_LC_CLI              0x1311
121 
122 /** Message sending context. */
123 struct bt_mesh_msg_ctx {
124 	/** NetKey Index of the subnet to send the message on. */
125 	u16_t net_idx;
126 
127 	/** AppKey Index to encrypt the message with. */
128 	u16_t app_idx;
129 
130 	/** Remote address. */
131 	u16_t addr;
132 
133 	/** Destination address of a received message. Not used for sending. */
134 	u16_t recv_dst;
135 
136 	/** Received TTL value. Not used for sending. */
137 	u8_t  recv_ttl:7;
138 
139 	/** Force sending reliably by using segment acknowledgement */
140 	u8_t  send_rel:1;
141 
142 	/** TTL, or BT_MESH_TTL_DEFAULT for default TTL. */
143 	u8_t  send_ttl;
144 };
145 
146 struct bt_mesh_model_op {
147 	/* OpCode encoded using the BT_MESH_MODEL_OP_* macros */
148 	const u32_t  opcode;
149 
150 	/* Minimum required message length */
151 	const size_t min_len;
152 
153 	/* Message handler for the opcode */
154 	void (*const func)(struct bt_mesh_model *model,
155 			   struct bt_mesh_msg_ctx *ctx,
156 			   struct os_mbuf *buf);
157 };
158 
159 #define BT_MESH_MODEL_OP_1(b0) (b0)
160 #define BT_MESH_MODEL_OP_2(b0, b1) (((b0) << 8) | (b1))
161 #define BT_MESH_MODEL_OP_3(b0, cid) ((((b0) << 16) | 0xc00000) | (cid))
162 
163 #define BT_MESH_MODEL_OP_END { 0, 0, NULL }
164 #define BT_MESH_MODEL_NO_OPS ((struct bt_mesh_model_op []) \
165 			      { BT_MESH_MODEL_OP_END })
166 
167 /** Helper to define an empty model array */
168 #define BT_MESH_MODEL_NONE ((struct bt_mesh_model []){})
169 
170 #define BT_MESH_MODEL(_id, _op, _pub, _user_data)                            \
171 {                                                                            \
172 	.id = (_id),                                                         \
173 	.op = _op,                                                           \
174 	.keys = { [0 ... (CONFIG_BT_MESH_MODEL_KEY_COUNT - 1)] =             \
175 			BT_MESH_KEY_UNUSED },                                \
176 	.pub = _pub,                                                         \
177 	.groups = { [0 ... (CONFIG_BT_MESH_MODEL_GROUP_COUNT - 1)] =         \
178 			BT_MESH_ADDR_UNASSIGNED },                           \
179 	.user_data = _user_data,                                             \
180 }
181 
182 #define BT_MESH_MODEL_VND(_company, _id, _op, _pub, _user_data)              \
183 {                                                                            \
184 	.vnd.company = (_company),                                           \
185 	.vnd.id = (_id),                                                     \
186 	.op = _op,                                                           \
187 	.pub = _pub,                                                         \
188 	.keys = { [0 ... (CONFIG_BT_MESH_MODEL_KEY_COUNT - 1)] =             \
189 			BT_MESH_KEY_UNUSED },                                \
190 	.groups = { [0 ... (CONFIG_BT_MESH_MODEL_GROUP_COUNT - 1)] =         \
191 			BT_MESH_ADDR_UNASSIGNED },                           \
192 	.user_data = _user_data,                                             \
193 }
194 
195 /** @def BT_MESH_TRANSMIT
196  *
197  *  @brief Encode transmission count & interval steps.
198  *
199  *  @param count   Number of retransmissions (first transmission is excluded).
200  *  @param int_ms  Interval steps in milliseconds. Must be greater than 0,
201  *                 less than or equal to 320, and a multiple of 10.
202  *
203  *  @return Mesh transmit value that can be used e.g. for the default
204  *          values of the configuration model data.
205  */
206 #define BT_MESH_TRANSMIT(count, int_ms) ((count) | (((int_ms / 10) - 1) << 3))
207 
208 /** @def BT_MESH_TRANSMIT_COUNT
209  *
210  *  @brief Decode transmit count from a transmit value.
211  *
212  *  @param transmit Encoded transmit count & interval value.
213  *
214  *  @return Transmission count (actual transmissions is N + 1).
215  */
216 #define BT_MESH_TRANSMIT_COUNT(transmit) (((transmit) & (u8_t)BIT_MASK(3)))
217 
218 /** @def BT_MESH_TRANSMIT_INT
219  *
220  *  @brief Decode transmit interval from a transmit value.
221  *
222  *  @param transmit Encoded transmit count & interval value.
223  *
224  *  @return Transmission interval in milliseconds.
225  */
226 #define BT_MESH_TRANSMIT_INT(transmit) ((((transmit) >> 3) + 1) * 10)
227 
228 /** @def BT_MESH_PUB_TRANSMIT
229  *
230  *  @brief Encode Publish Retransmit count & interval steps.
231  *
232  *  @param count   Number of retransmissions (first transmission is excluded).
233  *  @param int_ms  Interval steps in milliseconds. Must be greater than 0
234  *                 and a multiple of 50.
235  *
236  *  @return Mesh transmit value that can be used e.g. for the default
237  *          values of the configuration model data.
238  */
239 #define BT_MESH_PUB_TRANSMIT(count, int_ms) BT_MESH_TRANSMIT(count,           \
240 							     (int_ms) / 5)
241 
242 /** @def BT_MESH_PUB_TRANSMIT_COUNT
243  *
244  *  @brief Decode Pubhlish Retransmit count from a given value.
245  *
246  *  @param transmit Encoded Publish Retransmit count & interval value.
247  *
248  *  @return Retransmission count (actual transmissions is N + 1).
249  */
250 #define BT_MESH_PUB_TRANSMIT_COUNT(transmit) BT_MESH_TRANSMIT_COUNT(transmit)
251 
252 /** @def BT_MESH_PUB_TRANSMIT_INT
253  *
254  *  @brief Decode Publish Retransmit interval from a given value.
255  *
256  *  @param transmit Encoded Publish Retransmit count & interval value.
257  *
258  *  @return Transmission interval in milliseconds.
259  */
260 #define BT_MESH_PUB_TRANSMIT_INT(transmit) ((((transmit) >> 3) + 1) * 50)
261 
262 /** Model publication context. */
263 struct bt_mesh_model_pub {
264 	/** The model the context belongs to. Initialized by the stack. */
265 	struct bt_mesh_model *mod;
266 
267 	u16_t addr;         /**< Publish Address. */
268 	u16_t key;          /**< Publish AppKey Index. */
269 
270 	u8_t  ttl;          /**< Publish Time to Live. */
271 	u8_t  retransmit;   /**< Retransmit Count & Interval Steps. */
272 	u8_t  period;       /**< Publish Period. */
273 	u8_t  period_div:4, /**< Divisor for the Period. */
274 	      cred:1,       /**< Friendship Credentials Flag. */
275 	      count:3;      /**< Retransmissions left. */
276 
277 	u32_t period_start; /**< Start of the current period. */
278 
279 	/** @brief Publication buffer, containing the publication message.
280 	 *
281 	 *  The application is expected to initialize this with
282 	 *  a valid net_buf_simple pointer, with the help of e.g.
283 	 *  the NET_BUF_SIMPLE() macro. The publication buffer must
284 	 *  contain a valid publication message before calling the
285 	 *  bt_mesh_model_publish() API or after the publication's
286 	 *  @ref bt_mesh_model_pub.update callback has been called
287 	 *  and returned success. The buffer must be created outside
288 	 *  of function context, i.e. it must not be on the stack.
289 	 *  This is most conveniently acheived by creating it inline
290 	 *  when declaring the publication context:
291 	 *
292 	 *      static struct bt_mesh_model_pub my_pub = {
293 	 *              .msg = NET_BUF_SIMPLE(size),
294 	 *      };
295 	 */
296 	struct os_mbuf *msg;
297 
298 	/** @brief Callback for updating the publication buffer.
299 	 *
300 	 *  When set to NULL, the model is assumed not to support
301 	 *  periodic publishing. When set to non-NULL the callback
302 	 *  will be called periodically and is expected to update
303 	 *  @ref bt_mesh_model_pub.msg with a valid publication
304 	 *  message.
305 	 *
306 	 *  @param mod The Model the Publication Context belogs to.
307 	 *
308 	 *  @return Zero on success or (negative) error code otherwise.
309 	 */
310 	int (*update)(struct bt_mesh_model *mod);
311 
312 	/** Publish Period Timer. Only for stack-internal use. */
313 	struct k_delayed_work timer;
314 };
315 
316 /** Abstraction that describes a Mesh Model instance */
317 struct bt_mesh_model {
318 	union {
319 		const u16_t id;
320 		struct {
321 			u16_t company;
322 			u16_t id;
323 		} vnd;
324 	};
325 
326 	/* Internal information, mainly for persistent storage */
327 	u8_t  elem_idx;   /* Belongs to Nth element */
328 	u8_t  mod_idx;    /* Is the Nth model in the element */
329 	u16_t flags;      /* Information about what has changed */
330 
331 	/* Model Publication */
332 	struct bt_mesh_model_pub * const pub;
333 
334 	/* AppKey List */
335 	u16_t keys[CONFIG_BT_MESH_MODEL_KEY_COUNT];
336 
337 	/* Subscription List (group or virtual addresses) */
338 	u16_t groups[CONFIG_BT_MESH_MODEL_GROUP_COUNT];
339 
340 	const struct bt_mesh_model_op * const op;
341 
342 	/* Model-specific user data */
343 	void *user_data;
344 };
345 
346 struct bt_mesh_send_cb {
347 	void (*start)(u16_t duration, int err, void *cb_data);
348 	void (*end)(int err, void *cb_data);
349 };
350 
351 void bt_mesh_model_msg_init(struct os_mbuf *msg, u32_t opcode);
352 
353 /** Special TTL value to request using configured default TTL */
354 #define BT_MESH_TTL_DEFAULT 0xff
355 
356 /** Maximum allowed TTL value */
357 #define BT_MESH_TTL_MAX     0x7f
358 
359 /**
360  * @brief Send an Access Layer message.
361  *
362  * @param model     Mesh (client) Model that the message belongs to.
363  * @param ctx       Message context, includes keys, TTL, etc.
364  * @param msg       Access Layer payload (the actual message to be sent).
365  * @param cb        Optional "message sent" callback.
366  * @param cb_data   User data to be passed to the callback.
367  *
368  * @return 0 on success, or (negative) error code on failure.
369  */
370 int bt_mesh_model_send(struct bt_mesh_model *model,
371 		       struct bt_mesh_msg_ctx *ctx,
372 		       struct os_mbuf *msg,
373 		       const struct bt_mesh_send_cb *cb,
374 		       void *cb_data);
375 
376 /**
377  * @brief Send a model publication message.
378  *
379  * Before calling this function, the user needs to ensure that the model
380  * publication message (@ref bt_mesh_model_pub.msg) contains a valid
381  * message to be sent. Note that this API is only to be used for
382  * non-period publishing. For periodic publishing the app only needs
383  * to make sure that @ref bt_mesh_model_pub.msg contains a valid message
384  * whenever the @ref bt_mesh_model_pub.update callback is called.
385  *
386  * @param model  Mesh (client) Model that's publishing the message.
387  *
388  * @return 0 on success, or (negative) error code on failure.
389  */
390 int bt_mesh_model_publish(struct bt_mesh_model *model);
391 
392 /**
393  * @brief Get the element that a model belongs to.
394  *
395  * @param mod  Mesh model.
396  *
397  * @return Pointer to the element that the given model belongs to.
398  */
399 struct bt_mesh_elem *bt_mesh_model_elem(struct bt_mesh_model *mod);
400 
401 /** Node Composition */
402 struct bt_mesh_comp {
403 	u16_t cid;
404 	u16_t pid;
405 	u16_t vid;
406 
407 	size_t elem_count;
408 	struct bt_mesh_elem *elem;
409 };
410 
411 /**
412  * @}
413  */
414 
415 #endif /* __BT_MESH_ACCESS_H */
416