xref: /btstack/src/mesh/mesh_network.h (revision 2ebe2350f1cf16e9569f52dbc33a168e81096d9c)
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 
56 #define MESH_ADDRESS_UNSASSIGNED     0x0000u
57 #define MESH_ADDRESS_ALL_PROXIES     0xFFFCu
58 #define MESH_ADDRESS_ALL_FRIENDS     0xFFFDu
59 #define MESH_ADDRESS_ALL_RELAYS      0xFFFEu
60 #define MESH_ADDRESS_ALL_NODES       0xFFFFu
61 
62 typedef enum {
63     MESH_NETWORK_PDU_RECEIVED,
64     MESH_NETWORK_PDU_SENT,
65     MESH_NETWORK_PDU_ENCRYPTED,
66     MESH_NETWORK_CAN_SEND_NOW,
67 } mesh_network_callback_type_t;
68 
69 typedef enum {
70     MESH_PDU_TYPE_NETWORK = 0,
71     MESH_PDU_TYPE_TRANSPORT,
72     MESH_PDU_TYPE_MESSAGE,
73     MESH_PDU_TYPE_UNSEGMENTED_INCOMING,
74     MESH_PDU_TYPE_ACCESS,
75 } mesh_pdu_type_t;
76 
77 typedef struct mesh_pdu {
78     // allow for linked lists
79     btstack_linked_item_t item;
80     // type
81     mesh_pdu_type_t pdu_type;
82 
83 } mesh_pdu_t;
84 
85 //
86 #define MESH_NETWORK_PDU_FLAGS_PROXY_CONFIGURATION 1
87 #define MESH_NETWORK_PDU_FLAGS_GATT_BEARER         2
88 #define MESH_NETWORK_PDU_FLAGS_RELAY               4
89 
90 typedef struct mesh_network_pdu {
91     mesh_pdu_t pdu_header;
92 
93     // meta data network layer
94     uint16_t              netkey_index;
95     // MESH_NETWORK_PDU_FLAGS
96     uint16_t              flags;
97 
98     // pdu
99     uint16_t              len;
100     uint8_t               data[MESH_NETWORK_PAYLOAD_MAX];
101 } mesh_network_pdu_t;
102 
103 #define MESH_TRANSPORT_FLAG_SEQ_RESERVED    1
104 #define MESH_TRANSPORT_FLAG_SEGMENTED       2
105 
106 typedef struct {
107     mesh_pdu_t pdu_header;
108 
109     // access acknowledged message
110     uint16_t retransmit_count;
111     uint32_t retransmit_timeout_ms;
112     uint32_t ack_opcode;
113 
114     // meta data network layer
115     uint16_t              netkey_index;
116     // meta data transport layer
117     uint16_t              appkey_index;
118     // transmic size
119     uint8_t               transmic_len;
120     // akf - aid for access, opcode for control
121     uint8_t               akf_aid_control;
122     // network pdu header
123     uint8_t               network_header[9];
124     // MESH_TRANSPORT_FLAG
125     uint16_t              flags;
126     // pdu
127     uint16_t              len;
128     uint8_t               data[MESH_ACCESS_PAYLOAD_MAX];
129 } mesh_transport_pdu_t;
130 
131 typedef struct {
132     mesh_pdu_t pdu_header;
133 
134     // access acknowledged message
135     uint16_t retransmit_count;
136     uint32_t retransmit_timeout_ms;
137     uint32_t ack_opcode;
138 
139     bool     segmented;
140 
141     // rx/tx: acknowledgement timer / segment transmission timer
142     btstack_timer_source_t acknowledgement_timer;
143     // rx: incomplete timer / tx: resend timer
144     btstack_timer_source_t incomplete_timer;
145     // block access
146     uint32_t              block_ack;
147     // meta data network layer
148     uint16_t              netkey_index;
149     // meta data transport layer
150     uint16_t              appkey_index;
151     // transmic size
152     uint8_t               transmic_len;
153     // akf - aid for access, opcode for control
154     uint8_t               akf_aid_control;
155     // network pdu header
156     uint8_t               network_header[9];
157     // MESH_TRANSPORT_FLAG
158     uint16_t              flags;
159     // acknowledgement timer active
160     uint8_t               acknowledgement_timer_active;
161     // incomplete timer active
162     uint8_t               incomplete_timer_active;
163     // message complete
164     uint8_t               message_complete;
165     // seq_zero for segmented messages
166     uint16_t              seq_zero;
167     // pdu segments
168     uint16_t              len;
169     btstack_linked_list_t segments;
170 } mesh_message_pdu_t;
171 
172 typedef struct {
173     // generic pdu header
174     mesh_pdu_t            pdu_header;
175     // meta data transport layer
176     uint16_t              appkey_index;
177     // MESH_TRANSPORT_FLAG
178     uint16_t              flags;
179     // pdu segment
180     mesh_network_pdu_t  * segment;
181 } mesh_unsegmented_incoming_pdu_t;
182 
183 typedef struct {
184     // generic pdu header
185     mesh_pdu_t            pdu_header;
186     // meta data network layer
187     uint16_t              netkey_index;
188     // meta data transport layer
189     uint16_t              appkey_index;
190     // transmic size
191     uint8_t               transmic_len;
192     // akf - aid for access, opcode for control
193     uint8_t               akf_aid_control;
194     // network pdu header
195     uint8_t               network_header[9];
196     // MESH_TRANSPORT_FLAG
197     uint16_t              flags;
198     // payload
199     uint16_t              len;
200     uint8_t               data[MESH_ACCESS_PAYLOAD_MAX];
201 } mesh_access_pdu_t;
202 
203 typedef enum {
204     MESH_KEY_REFRESH_NOT_ACTIVE = 0,
205     MESH_KEY_REFRESH_FIRST_PHASE,
206     MESH_KEY_REFRESH_SECOND_PHASE
207 } mesh_key_refresh_state_t;
208 
209 typedef enum {
210     MESH_SECURE_NETWORK_BEACON_W2_AUTH_VALUE,
211     MESH_SECURE_NETWORK_BEACON_W4_AUTH_VALUE,
212     MESH_SECURE_NETWORK_BEACON_AUTH_VALUE,
213     MESH_SECURE_NETWORK_BEACON_W2_SEND_ADV,
214     MESH_SECURE_NETWORK_BEACON_ADV_SENT,
215     MESH_SECURE_NETWORK_BEACON_W2_SEND_GATT,
216     MESH_SECURE_NETWORK_BEACON_GATT_SENT,
217     MESH_SECURE_NETWORK_BEACON_W4_INTERVAL
218 } mesh_secure_network_beacon_state_t;
219 
220 typedef struct {
221     btstack_linked_item_t item;
222 
223     // netkey index
224     uint16_t              netkey_index;
225 
226     // current / old key
227     mesh_network_key_t * old_key;
228 
229     // new key (only set during key refresh)
230     mesh_network_key_t * new_key;
231 
232     // key refresh state
233     mesh_key_refresh_state_t key_refresh;
234 
235     // advertisement using node id active
236     uint8_t node_id_advertisement_running;
237 
238 
239     // advertisement using network id (used by proxy)
240     adv_bearer_connectable_advertisement_data_item_t advertisement_with_network_id;
241 
242     // advertising using node id (used by proxy)
243     adv_bearer_connectable_advertisement_data_item_t advertisement_with_node_id;
244 
245     // secure network beacons
246     mesh_secure_network_beacon_state_t beacon_state;
247     uint32_t                           beacon_interval_ms;
248     uint32_t                           beacon_observation_start_ms;
249     uint16_t                           beacon_observation_counter;
250 
251 } mesh_subnet_t;
252 
253 typedef struct {
254     btstack_linked_list_iterator_t it;
255 } mesh_subnet_iterator_t;
256 
257 /**
258  * @brief Init Mesh Network Layer
259  */
260 void mesh_network_init(void);
261 
262 /**
263  * @brief Set higher layer Network PDU handler
264  * @param packet_handler
265  */
266 void mesh_network_set_higher_layer_handler(void (*packet_handler)(mesh_network_callback_type_t callback_type, mesh_network_pdu_t * network_pdu));
267 
268 /**
269  * @brief Set higher layer Proxy PDU handler
270  * @param packet_handler
271  */
272 void mesh_network_set_proxy_message_handler(void (*packet_handler)(mesh_network_callback_type_t callback_type, mesh_network_pdu_t * network_pdu));
273 
274 /**
275  * @brief Mark packet as processed
276  * @param newtork_pdu received via call packet_handler
277  */
278 void mesh_network_message_processed_by_higher_layer(mesh_network_pdu_t * network_pdu);
279 
280 /**
281  * @brief Send network_pdu after encryption
282  * @param network_pdu
283  */
284 void mesh_network_send_pdu(mesh_network_pdu_t * network_pdu);
285 
286 /*
287  * @brief Setup network pdu header
288  * @param netkey_index
289  * @param nid
290  * @param ctl
291  * @param ttl
292  * @param seq
293  * @param dst
294  * @param transport_pdu_data
295  * @param transport_pdu_len
296  */
297 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);
298 
299 /**
300  * Setup network pdu header without modifying len or payload
301  * @param network_pdu
302  * @param netkey_index
303  * @param nid
304  * @param ctl
305  * @param ttl
306  * @param seq
307  * @param src
308  * @param dest
309  */
310 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);
311 
312 /**
313  * @brief Validate network addresses
314  * @param ctl
315  * @param src
316  * @param dst
317  * @returns 1 if valid,
318  */
319 int mesh_network_addresses_valid(uint8_t ctl, uint16_t src, uint16_t dst);
320 
321 /**
322  * @brief Check if Unicast address
323  * @param addr
324  * @returns 1 if unicast
325  */
326 int mesh_network_address_unicast(uint16_t addr);
327 
328 /**
329  * @brief Check if Unicast address
330  * @param addr
331  * @returns 1 if unicast
332  */
333 int mesh_network_address_group(uint16_t addr);
334 
335 /**
336  * @brief Check if All Proxies address
337  * @param addr
338  * @returns 1 if all proxies
339  */
340 int mesh_network_address_all_proxies(uint16_t addr);
341 
342 /**
343  * @brief Check if All Nodes address
344  * @param addr
345  * @returns 1 if all nodes
346  */
347 int mesh_network_address_all_nodes(uint16_t addr);
348 
349 /**
350  * @brief Check if All Friends address
351  * @param addr
352  * @returns 1 if all friends
353  */
354 int mesh_network_address_all_friends(uint16_t addr);
355 
356 /**
357  * @brief Check if All Relays address
358  * @param addr
359  * @returns 1 if all relays
360  */
361 int mesh_network_address_all_relays(uint16_t addr);
362 
363 
364 /**
365  * @brief Check if Virtual address
366  * @param addr
367  * @returns 1 if virtual
368  */
369 int mesh_network_address_virtual(uint16_t addr);
370 
371 
372 /**
373  * @brief Add subnet to list
374  * @param subnet
375  */
376 void mesh_subnet_add(mesh_subnet_t * subnet);
377 
378 /**
379  * @brief Remove subnet from list
380  * @param subnet
381  */
382 void mesh_subnet_remove(mesh_subnet_t * subnet);
383 
384 /**
385  * @brief Get subnet for netkey_index
386  * @param netkey_index
387  * @returns mesh_subnet_t or NULL
388  */
389 mesh_subnet_t * mesh_subnet_get_by_netkey_index(uint16_t netkey_index);
390 
391 /**
392  * @brief Get number of stored subnets
393  * @returns count
394  */
395 int mesh_subnet_list_count(void);
396 
397 /**
398  * @brief Iterate over all subnets
399  * @param it
400  */
401 void mesh_subnet_iterator_init(mesh_subnet_iterator_t *it);
402 
403 /**
404  * @brief Check if another subnet is available
405  * @param it
406  * @return
407  */
408 int mesh_subnet_iterator_has_more(mesh_subnet_iterator_t *it);
409 
410 /**
411  * @brief Get next subnet
412  * @param it
413  * @return
414  */
415 mesh_subnet_t * mesh_subnet_iterator_get_next(mesh_subnet_iterator_t *it);
416 
417 /**
418  * @brief Setup subnet for given netkey index
419  */
420 void mesh_subnet_setup_for_netkey_index(uint16_t netkey_index);
421 
422 
423 /**
424  * @brief Get outgoing network key for subnet based on key refresh phase
425  */
426 mesh_network_key_t * mesh_subnet_get_outgoing_network_key(mesh_subnet_t * subnet);
427 
428 // buffer pool
429 mesh_network_pdu_t * mesh_network_pdu_get(void);
430 void mesh_network_pdu_free(mesh_network_pdu_t * network_pdu);
431 
432 // Mesh Network PDU Getter
433 uint16_t  mesh_network_control(mesh_network_pdu_t * network_pdu);
434 uint8_t   mesh_network_nid(mesh_network_pdu_t * network_pdu);
435 uint8_t   mesh_network_ttl(mesh_network_pdu_t * network_pdu);
436 uint32_t  mesh_network_seq(mesh_network_pdu_t * network_pdu);
437 uint16_t  mesh_network_src(mesh_network_pdu_t * network_pdu);
438 uint16_t  mesh_network_dst(mesh_network_pdu_t * network_pdu);
439 int       mesh_network_segmented(mesh_network_pdu_t * network_pdu);
440 uint8_t   mesh_network_control_opcode(mesh_network_pdu_t * network_pdu);
441 uint8_t * mesh_network_pdu_data(mesh_network_pdu_t * network_pdu);
442 uint8_t   mesh_network_pdu_len(mesh_network_pdu_t * network_pdu);
443 
444 // Mesh Network PDU Setter
445 void mesh_network_pdu_set_seq(mesh_network_pdu_t * network_pdu, uint32_t seq);
446 
447 // Testing only
448 void mesh_network_received_message(const uint8_t * pdu_data, uint8_t pdu_len, uint8_t flags);
449 void mesh_network_process_proxy_configuration_message(const uint8_t * pdu_data, uint8_t pdu_len);
450 void mesh_network_encrypt_proxy_configuration_message(mesh_network_pdu_t * network_pdu);
451 void mesh_network_dump(void);
452 void mesh_network_reset(void);
453 
454 #if defined __cplusplus
455 }
456 #endif
457 
458 #endif
459