xref: /btstack/src/mesh/mesh_network.h (revision fd7ffe00475e98871ea322e0dfe1740e4d593c75)
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 "provisioning.h"
43 #include "btstack_run_loop.h"
44 
45 #if defined __cplusplus
46 extern "C" {
47 #endif
48 
49 #define MESH_DEVICE_KEY_INDEX     0xffff
50 
51 #define MESH_NETWORK_PAYLOAD_MAX      29
52 #define MESH_ACCESS_PAYLOAD_MAX      384
53 
54 #define MESH_ADDRESS_UNSASSIGNED     0x0000u
55 #define MESH_ADDRESS_ALL_PROXIES     0xFFFCu
56 #define MESH_ADDRESS_ALL_FRIENDS     0xFFFDu
57 #define MESH_ADDRESS_ALL_RELAYS      0xFFFEu
58 #define MESH_ADDRESS_ALL_NODES       0xFFFFu
59 
60 typedef enum {
61     MESH_NETWORK_PDU_RECEIVED,
62     MESH_NETWORK_PDU_SENT,
63 } mesh_network_callback_type_t;
64 
65 typedef enum {
66     MESH_PDU_TYPE_NETWORK = 0,
67     MESH_PDU_TYPE_TRANSPORT,
68 } mesh_pdu_type_t;
69 
70 typedef struct mesh_pdu {
71     // allow for linked lists
72     btstack_linked_item_t item;
73     // type
74     mesh_pdu_type_t pdu_type;
75 } mesh_pdu_t;
76 
77 //
78 #define MESH_NETWORK_PDU_FLAGS_PROXY_CONFIGURATION 1
79 #define MESH_NETWORK_PDU_FLAGS_GATT_BEARER   2
80 
81 typedef struct mesh_network_pdu {
82     mesh_pdu_t pdu_header;
83 
84     // callback
85     void (*callback)(struct mesh_network_pdu * network_pdu);
86 
87     // meta data network layer
88     uint16_t              netkey_index;
89     // meta data transport layer
90     uint16_t              appkey_index;
91     // flags: bit 0 indicates Proxy PDU
92     uint16_t              flags;
93 
94     // pdu
95     uint16_t              len;
96     uint8_t               data[MESH_NETWORK_PAYLOAD_MAX];
97 } mesh_network_pdu_t;
98 
99 typedef struct {
100     mesh_pdu_t pdu_header;
101 
102     // rx/tx: acknowledgement timer / segment transmission timer
103     btstack_timer_source_t acknowledgement_timer;
104     // rx: incomplete timer / tx: resend timer
105     btstack_timer_source_t incomplete_timer;
106     // block access
107     uint32_t              block_ack;
108     // meta data network layer
109     uint16_t              netkey_index;
110     // meta data transport layer
111     uint16_t              appkey_index;
112     // transmic size
113     uint8_t               transmic_len;
114     // akf - aid
115     uint8_t               akf_aid;
116     // network pdu header
117     uint8_t               network_header[9];
118     // acknowledgement timer active
119     uint8_t               acknowledgement_timer_active;
120     // incomplete timer active
121     uint8_t               incomplete_timer_active;
122     // message complete
123     uint8_t               message_complete;
124     // seq_zero for segmented messages
125     uint16_t              seq_zero;
126     // pdu
127     uint16_t              len;
128     uint8_t               data[MESH_ACCESS_PAYLOAD_MAX];
129 } mesh_transport_pdu_t;
130 
131 
132 /**
133  * @brief Init Mesh Network Layer
134  */
135 void mesh_network_init(void);
136 
137 /**
138  * @brief Set higher layer Network PDU handler
139  * @param packet_handler
140  */
141 void mesh_network_set_higher_layer_handler(void (*packet_handler)(mesh_network_callback_type_t callback_type, mesh_network_pdu_t * network_pdu));
142 
143 /**
144  * @brief Set higher layer Proxy PDU handler
145  * @param packet_handler
146  */
147 void mesh_network_set_proxy_message_handler(void (*packet_handler)(mesh_network_callback_type_t callback_type, mesh_network_pdu_t * network_pdu));
148 
149 /**
150  * @brief Mark packet as processed
151  * @param newtork_pdu received via call packet_handler
152  */
153 void mesh_network_message_processed_by_higher_layer(mesh_network_pdu_t * network_pdu);
154 
155 /**
156  * @brief Configure address filter
157  */
158 void mesh_network_set_primary_element_address(uint16_t addr);
159 
160 /**
161  * @brief Send network_pdu after encryption
162  * @param network_pdu
163  */
164 void mesh_network_send_pdu(mesh_network_pdu_t * network_pdu);
165 
166 /*
167  * @brief Setup network pdu header
168  * @param netkey_index
169  * @param nid
170  * @param ctl
171  * @param ttl
172  * @param seq
173  * @param dst
174  * @param transport_pdu_data
175  * @param transport_pdu_len
176  */
177 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);
178 
179 /**
180  * Setup network pdu header without modifying len or payload
181  * @param network_pdu
182  * @param netkey_index
183  * @param nid
184  * @param ctl
185  * @param ttl
186  * @param seq
187  * @param src
188  * @param dest
189  */
190 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);
191 
192 /**
193  * @brief Validate network addresses
194  * @param ctl
195  * @param src
196  * @param dst
197  * @returns 1 if valid,
198  */
199 int mesh_network_addresses_valid(uint8_t ctl, uint16_t src, uint16_t dst);
200 
201 /**
202  * @brief Check if Unicast address
203  * @param addr
204  * @returns 1 if unicast
205  */
206 int mesh_network_address_unicast(uint16_t addr);
207 
208 /**
209  * @brief Check if Unicast address
210  * @param addr
211  * @returns 1 if unicast
212  */
213 int mesh_network_address_group(uint16_t addr);
214 
215 /**
216  * @brief Check if All Proxies address
217  * @param addr
218  * @returns 1 if all proxies
219  */
220 int mesh_network_address_all_proxies(uint16_t addr);
221 
222 /**
223  * @brief Check if All Nodes address
224  * @param addr
225  * @returns 1 if all nodes
226  */
227 int mesh_network_address_all_nodes(uint16_t addr);
228 
229 /**
230  * @brief Check if All Friends address
231  * @param addr
232  * @returns 1 if all friends
233  */
234 int mesh_network_address_all_friends(uint16_t addr);
235 
236 /**
237  * @brief Check if All Relays address
238  * @param addr
239  * @returns 1 if all relays
240  */
241 int mesh_network_address_all_relays(uint16_t addr);
242 
243 
244 /**
245  * @brief Check if Virtual address
246  * @param addr
247  * @returns 1 if virtual
248  */
249 int mesh_network_address_virtual(uint16_t addr);
250 
251 // buffer pool
252 mesh_network_pdu_t * mesh_network_pdu_get(void);
253 void mesh_network_pdu_free(mesh_network_pdu_t * network_pdu);
254 
255 // Mesh Network PDU Getter
256 uint16_t  mesh_network_control(mesh_network_pdu_t * network_pdu);
257 uint8_t   mesh_network_nid(mesh_network_pdu_t * network_pdu);
258 uint8_t   mesh_network_ttl(mesh_network_pdu_t * network_pdu);
259 uint32_t  mesh_network_seq(mesh_network_pdu_t * network_pdu);
260 uint16_t  mesh_network_src(mesh_network_pdu_t * network_pdu);
261 uint16_t  mesh_network_dst(mesh_network_pdu_t * network_pdu);
262 int       mesh_network_segmented(mesh_network_pdu_t * network_pdu);
263 uint8_t * mesh_network_pdu_data(mesh_network_pdu_t * network_pdu);
264 uint8_t   mesh_network_pdu_len(mesh_network_pdu_t * network_pdu);
265 
266 void     mesh_set_iv_index(uint32_t iv_index);
267 uint32_t mesh_get_iv_index(void);
268 
269 // Testing only
270 void mesh_network_received_message(const uint8_t * pdu_data, uint8_t pdu_len);
271 void mesh_network_process_proxy_configuration_message(const uint8_t * pdu_data, uint8_t pdu_len);
272 void mesh_network_encrypt_proxy_configuration_message(mesh_network_pdu_t * network_pdu, void (* callback)(mesh_network_pdu_t * callback));
273 void mesh_network_dump(void);
274 void mesh_network_reset(void);
275 
276 #if defined __cplusplus
277 }
278 #endif
279 
280 #endif
281