xref: /btstack/src/mesh/mesh_network.h (revision efe57ffd8824c61843a47a6495b1d16a482ac85a)
1 /*
2  * Copyright (C) 2018 BlueKitchen GmbH
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  *
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  * 3. Neither the name of the copyright holders nor the names of
14  *    contributors may be used to endorse or promote products derived
15  *    from this software without specific prior written permission.
16  * 4. Any redistribution, use, or modification is done solely for
17  *    personal benefit and not for any commercial purpose or for
18  *    monetary gain.
19  *
20  * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS
21  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MATTHIAS
24  * RINGWALD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
26  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
27  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
28  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
29  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
30  * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31  * SUCH DAMAGE.
32  *
33  * Please inquire about commercial licensing options at
34  * [email protected]
35  *
36  */
37 
38 #ifndef __MESH_NETWORK
39 #define __MESH_NETWORK
40 
41 #include "btstack_linked_list.h"
42 #include "btstack_run_loop.h"
43 
44 #include "mesh/provisioning.h"
45 #include "mesh/mesh_keys.h"
46 
47 #if defined __cplusplus
48 extern "C" {
49 #endif
50 
51 #define MESH_DEVICE_KEY_INDEX     0xffff
52 
53 #define MESH_NETWORK_PAYLOAD_MAX      29
54 #define MESH_ACCESS_PAYLOAD_MAX      384
55 #define MESH_CONTROL_PAYLOAD_MAX     256
56 
57 #define MESH_ADDRESS_UNSASSIGNED     0x0000u
58 #define MESH_ADDRESS_ALL_PROXIES     0xFFFCu
59 #define MESH_ADDRESS_ALL_FRIENDS     0xFFFDu
60 #define MESH_ADDRESS_ALL_RELAYS      0xFFFEu
61 #define MESH_ADDRESS_ALL_NODES       0xFFFFu
62 
63 typedef enum {
64     MESH_NETWORK_PDU_RECEIVED,
65     MESH_NETWORK_PDU_SENT,
66     MESH_NETWORK_PDU_ENCRYPTED,
67     MESH_NETWORK_CAN_SEND_NOW,
68 } mesh_network_callback_type_t;
69 
70 typedef enum {
71     MESH_PDU_TYPE_NETWORK = 0,
72     MESH_PDU_TYPE_TRANSPORT,
73     MESH_PDU_TYPE_SEGMENTED,
74     MESH_PDU_TYPE_UNSEGMENTED,
75     MESH_PDU_TYPE_ACCESS,
76     MESH_PDU_TYPE_CONTROL,
77     MESH_PDU_TYPE_UPPER_SEGMENTED_ACCESS,
78     MESH_PDU_TYPE_UPPER_UNSEGMENTED_ACCESS,
79     MESH_PDU_TYPE_UPPER_SEGMENTED_CONTROL,
80     MESH_PDU_TYPE_UPPER_UNSEGMENTED_CONTROL,
81 } mesh_pdu_type_t;
82 
83 typedef struct mesh_pdu {
84     // allow for linked lists
85     btstack_linked_item_t item;
86     // type
87     mesh_pdu_type_t pdu_type;
88 
89 } mesh_pdu_t;
90 
91 //
92 #define MESH_NETWORK_PDU_FLAGS_PROXY_CONFIGURATION 1
93 #define MESH_NETWORK_PDU_FLAGS_GATT_BEARER         2
94 #define MESH_NETWORK_PDU_FLAGS_RELAY               4
95 
96 typedef struct mesh_network_pdu {
97     mesh_pdu_t pdu_header;
98 
99     // meta data network layer
100     uint16_t              netkey_index;
101     // MESH_NETWORK_PDU_FLAGS
102     uint16_t              flags;
103 
104     // pdu
105     uint16_t              len;
106     uint8_t               data[MESH_NETWORK_PAYLOAD_MAX];
107 } mesh_network_pdu_t;
108 
109 #define MESH_TRANSPORT_FLAG_SEQ_RESERVED    1
110 #define MESH_TRANSPORT_FLAG_CONTROL         2
111 
112 
113 typedef struct {
114     // generic pdu header
115     mesh_pdu_t            pdu_header;
116     // meta data transport layer
117     uint16_t              appkey_index;
118     // MESH_TRANSPORT_FLAG
119     uint16_t              flags;
120     // pdu segment
121     mesh_network_pdu_t  * segment;
122 } mesh_unsegmented_pdu_t;
123 
124 typedef struct {
125     mesh_pdu_t pdu_header;
126 
127     // rx/tx: acknowledgement timer / segment transmission timer
128     btstack_timer_source_t acknowledgement_timer;
129     // rx: incomplete timer / tx: resend timer
130     btstack_timer_source_t incomplete_timer;
131     // block access
132     uint32_t              block_ack;
133     // meta data network layer
134     uint16_t              netkey_index;
135     // meta data transport layer
136     uint16_t              appkey_index;
137     // transmic size
138     uint8_t               transmic_len;
139     // akf - aid for access, opcode for control
140     uint8_t               akf_aid_control;
141     // network pdu header
142     uint8_t               network_header[9];
143     // MESH_TRANSPORT_FLAG
144     uint16_t              flags;
145     // acknowledgement timer active
146     uint8_t               acknowledgement_timer_active;
147     // incomplete timer active
148     uint8_t               incomplete_timer_active;
149     // message complete
150     uint8_t               message_complete;
151     // seq_zero for segmented messages
152     uint16_t              seq_zero;
153     // pdu segments
154     uint16_t              len;
155     btstack_linked_list_t segments;
156 } mesh_segmented_pdu_t;
157 
158 typedef struct {
159     mesh_pdu_t pdu_header;
160 
161     // meta data network layer
162     uint16_t              netkey_index;
163     // meta data transport layer
164     uint16_t              appkey_index;
165     // transmic size
166     uint8_t               transmic_len;
167     // akf - aid for access, opcode for control
168     uint8_t               akf_aid_control;
169     // network pdu header
170     uint8_t               network_header[9];
171     // MESH_TRANSPORT_FLAG
172     uint16_t              flags;
173     // pdu
174     uint16_t              len;
175     uint8_t               data[MESH_ACCESS_PAYLOAD_MAX];
176 } mesh_transport_pdu_t;
177 
178 typedef struct {
179     // generic pdu header
180     mesh_pdu_t            pdu_header;
181     // meta data network layer
182     uint16_t              netkey_index;
183     // meta data transport layer
184     uint16_t              appkey_index;
185     // transmic size
186     uint8_t               transmic_len;
187     // akf - aid for access, opcode for control
188     uint8_t               akf_aid_control;
189     // network pdu header
190     uint8_t               network_header[9];
191     // MESH_TRANSPORT_FLAG
192     uint16_t              flags;
193     // payload
194     uint16_t              len;
195     uint8_t               data[MESH_ACCESS_PAYLOAD_MAX];
196 
197 } mesh_access_pdu_t;
198 
199 // for unsegmented + segmented access + segmented control pdus
200 typedef struct {
201     // generic pdu header
202     mesh_pdu_t            pdu_header;
203     // src
204     uint16_t              src;
205     // dst
206     uint16_t              dst;
207     // meta data network layer
208     uint16_t              netkey_index;
209     // meta data transport layer
210     uint16_t              appkey_index;
211     uint8_t               transmic_len;
212     // akf - aid for access, opcode for control
213     uint8_t               akf_aid_control;
214     // MESH_TRANSPORT_FLAG
215     uint16_t              flags;
216     // payload, single segmented or list of them
217     uint16_t              len;
218     union {
219         btstack_linked_list_t     segments;
220         struct mesh_network_pdu * segment;
221     } payload;
222 
223     // access acknowledged message
224     uint16_t retransmit_count;
225     uint32_t retransmit_timeout_ms;
226     uint32_t ack_opcode;
227 
228     // associated lower transport pdu
229     mesh_pdu_t *          lower_pdu;
230 } mesh_upper_transport_pdu_t;
231 
232 typedef struct {
233     // generic pdu header
234     mesh_pdu_t            pdu_header;
235     // meta data network layer
236     uint16_t              netkey_index;
237     // akf - aid for access, opcode for control
238     uint8_t               akf_aid_control;
239     // network pdu header
240     uint8_t               network_header[9];
241     // MESH_TRANSPORT_FLAG
242     uint16_t              flags;
243     // payload
244     uint16_t              len;
245     uint8_t               data[MESH_CONTROL_PAYLOAD_MAX];
246 } mesh_control_pdu_t;
247 
248 typedef enum {
249     MESH_KEY_REFRESH_NOT_ACTIVE = 0,
250     MESH_KEY_REFRESH_FIRST_PHASE,
251     MESH_KEY_REFRESH_SECOND_PHASE
252 } mesh_key_refresh_state_t;
253 
254 typedef enum {
255     MESH_SECURE_NETWORK_BEACON_W2_AUTH_VALUE,
256     MESH_SECURE_NETWORK_BEACON_W4_AUTH_VALUE,
257     MESH_SECURE_NETWORK_BEACON_AUTH_VALUE,
258     MESH_SECURE_NETWORK_BEACON_W2_SEND_ADV,
259     MESH_SECURE_NETWORK_BEACON_ADV_SENT,
260     MESH_SECURE_NETWORK_BEACON_W2_SEND_GATT,
261     MESH_SECURE_NETWORK_BEACON_GATT_SENT,
262     MESH_SECURE_NETWORK_BEACON_W4_INTERVAL
263 } mesh_secure_network_beacon_state_t;
264 
265 typedef struct {
266     btstack_linked_item_t item;
267 
268     // netkey index
269     uint16_t              netkey_index;
270 
271     // current / old key
272     mesh_network_key_t * old_key;
273 
274     // new key (only set during key refresh)
275     mesh_network_key_t * new_key;
276 
277     // key refresh state
278     mesh_key_refresh_state_t key_refresh;
279 
280     // advertisement using node id active
281     uint8_t node_id_advertisement_running;
282 
283 
284     // advertisement using network id (used by proxy)
285     adv_bearer_connectable_advertisement_data_item_t advertisement_with_network_id;
286 
287     // advertising using node id (used by proxy)
288     adv_bearer_connectable_advertisement_data_item_t advertisement_with_node_id;
289 
290     // secure network beacons
291     mesh_secure_network_beacon_state_t beacon_state;
292     uint32_t                           beacon_interval_ms;
293     uint32_t                           beacon_observation_start_ms;
294     uint16_t                           beacon_observation_counter;
295 
296 } mesh_subnet_t;
297 
298 typedef struct {
299     btstack_linked_list_iterator_t it;
300 } mesh_subnet_iterator_t;
301 
302 /**
303  * @brief Init Mesh Network Layer
304  */
305 void mesh_network_init(void);
306 
307 /**
308  * @brief Set higher layer Network PDU handler
309  * @param packet_handler
310  */
311 void mesh_network_set_higher_layer_handler(void (*packet_handler)(mesh_network_callback_type_t callback_type, mesh_network_pdu_t * network_pdu));
312 
313 /**
314  * @brief Set higher layer Proxy PDU handler
315  * @param packet_handler
316  */
317 void mesh_network_set_proxy_message_handler(void (*packet_handler)(mesh_network_callback_type_t callback_type, mesh_network_pdu_t * network_pdu));
318 
319 /**
320  * @brief Mark packet as processed
321  * @param newtork_pdu received via call packet_handler
322  */
323 void mesh_network_message_processed_by_higher_layer(mesh_network_pdu_t * network_pdu);
324 
325 /**
326  * @brief Send network_pdu after encryption
327  * @param network_pdu
328  */
329 void mesh_network_send_pdu(mesh_network_pdu_t * network_pdu);
330 
331 /*
332  * @brief Setup network pdu header
333  * @param netkey_index
334  * @param nid
335  * @param ctl
336  * @param ttl
337  * @param seq
338  * @param dst
339  * @param transport_pdu_data
340  * @param transport_pdu_len
341  */
342 void mesh_network_setup_pdu(mesh_network_pdu_t * network_pdu, uint16_t netkey_index, uint8_t nid, uint8_t ctl, uint8_t ttl, uint32_t seq, uint16_t src, uint16_t dst, const uint8_t * transport_pdu_data, uint8_t transport_pdu_len);
343 
344 /**
345  * Setup network pdu header without modifying len or payload
346  * @param network_pdu
347  * @param netkey_index
348  * @param nid
349  * @param ctl
350  * @param ttl
351  * @param seq
352  * @param src
353  * @param dest
354  */
355 void mesh_network_setup_pdu_header(mesh_network_pdu_t * network_pdu, uint16_t netkey_index, uint8_t nid, uint8_t ctl, uint8_t ttl, uint32_t seq, uint16_t src, uint16_t dest);
356 
357 /**
358  * @brief Validate network addresses
359  * @param ctl
360  * @param src
361  * @param dst
362  * @returns 1 if valid,
363  */
364 int mesh_network_addresses_valid(uint8_t ctl, uint16_t src, uint16_t dst);
365 
366 /**
367  * @brief Check if Unicast address
368  * @param addr
369  * @returns 1 if unicast
370  */
371 int mesh_network_address_unicast(uint16_t addr);
372 
373 /**
374  * @brief Check if Unicast address
375  * @param addr
376  * @returns 1 if unicast
377  */
378 int mesh_network_address_group(uint16_t addr);
379 
380 /**
381  * @brief Check if All Proxies address
382  * @param addr
383  * @returns 1 if all proxies
384  */
385 int mesh_network_address_all_proxies(uint16_t addr);
386 
387 /**
388  * @brief Check if All Nodes address
389  * @param addr
390  * @returns 1 if all nodes
391  */
392 int mesh_network_address_all_nodes(uint16_t addr);
393 
394 /**
395  * @brief Check if All Friends address
396  * @param addr
397  * @returns 1 if all friends
398  */
399 int mesh_network_address_all_friends(uint16_t addr);
400 
401 /**
402  * @brief Check if All Relays address
403  * @param addr
404  * @returns 1 if all relays
405  */
406 int mesh_network_address_all_relays(uint16_t addr);
407 
408 
409 /**
410  * @brief Check if Virtual address
411  * @param addr
412  * @returns 1 if virtual
413  */
414 int mesh_network_address_virtual(uint16_t addr);
415 
416 
417 /**
418  * @brief Add subnet to list
419  * @param subnet
420  */
421 void mesh_subnet_add(mesh_subnet_t * subnet);
422 
423 /**
424  * @brief Remove subnet from list
425  * @param subnet
426  */
427 void mesh_subnet_remove(mesh_subnet_t * subnet);
428 
429 /**
430  * @brief Get subnet for netkey_index
431  * @param netkey_index
432  * @returns mesh_subnet_t or NULL
433  */
434 mesh_subnet_t * mesh_subnet_get_by_netkey_index(uint16_t netkey_index);
435 
436 /**
437  * @brief Get number of stored subnets
438  * @returns count
439  */
440 int mesh_subnet_list_count(void);
441 
442 /**
443  * @brief Iterate over all subnets
444  * @param it
445  */
446 void mesh_subnet_iterator_init(mesh_subnet_iterator_t *it);
447 
448 /**
449  * @brief Check if another subnet is available
450  * @param it
451  * @return
452  */
453 int mesh_subnet_iterator_has_more(mesh_subnet_iterator_t *it);
454 
455 /**
456  * @brief Get next subnet
457  * @param it
458  * @return
459  */
460 mesh_subnet_t * mesh_subnet_iterator_get_next(mesh_subnet_iterator_t *it);
461 
462 /**
463  * @brief Setup subnet for given netkey index
464  */
465 void mesh_subnet_setup_for_netkey_index(uint16_t netkey_index);
466 
467 
468 /**
469  * @brief Get outgoing network key for subnet based on key refresh phase
470  */
471 mesh_network_key_t * mesh_subnet_get_outgoing_network_key(mesh_subnet_t * subnet);
472 
473 // buffer pool
474 mesh_network_pdu_t * mesh_network_pdu_get(void);
475 void mesh_network_pdu_free(mesh_network_pdu_t * network_pdu);
476 
477 // Mesh Network PDU Getter
478 uint16_t  mesh_network_control(mesh_network_pdu_t * network_pdu);
479 uint8_t   mesh_network_nid(mesh_network_pdu_t * network_pdu);
480 uint8_t   mesh_network_ttl(mesh_network_pdu_t * network_pdu);
481 uint32_t  mesh_network_seq(mesh_network_pdu_t * network_pdu);
482 uint16_t  mesh_network_src(mesh_network_pdu_t * network_pdu);
483 uint16_t  mesh_network_dst(mesh_network_pdu_t * network_pdu);
484 int       mesh_network_segmented(mesh_network_pdu_t * network_pdu);
485 uint8_t   mesh_network_control_opcode(mesh_network_pdu_t * network_pdu);
486 uint8_t * mesh_network_pdu_data(mesh_network_pdu_t * network_pdu);
487 uint8_t   mesh_network_pdu_len(mesh_network_pdu_t * network_pdu);
488 
489 // Mesh Network PDU Setter
490 void mesh_network_pdu_set_seq(mesh_network_pdu_t * network_pdu, uint32_t seq);
491 
492 // Testing only
493 void mesh_network_received_message(const uint8_t * pdu_data, uint8_t pdu_len, uint8_t flags);
494 void mesh_network_process_proxy_configuration_message(const uint8_t * pdu_data, uint8_t pdu_len);
495 void mesh_network_encrypt_proxy_configuration_message(mesh_network_pdu_t * network_pdu);
496 void mesh_network_dump(void);
497 void mesh_network_reset(void);
498 
499 #if defined __cplusplus
500 }
501 #endif
502 
503 #endif
504