xref: /btstack/src/mesh/mesh_network.h (revision 77ba3d3f9fd2c90e975cda31e3c706784e95d43a)
1*77ba3d3fSMatthias Ringwald /*
2*77ba3d3fSMatthias Ringwald  * Copyright (C) 2018 BlueKitchen GmbH
3*77ba3d3fSMatthias Ringwald  *
4*77ba3d3fSMatthias Ringwald  * Redistribution and use in source and binary forms, with or without
5*77ba3d3fSMatthias Ringwald  * modification, are permitted provided that the following conditions
6*77ba3d3fSMatthias Ringwald  * are met:
7*77ba3d3fSMatthias Ringwald  *
8*77ba3d3fSMatthias Ringwald  * 1. Redistributions of source code must retain the above copyright
9*77ba3d3fSMatthias Ringwald  *    notice, this list of conditions and the following disclaimer.
10*77ba3d3fSMatthias Ringwald  * 2. Redistributions in binary form must reproduce the above copyright
11*77ba3d3fSMatthias Ringwald  *    notice, this list of conditions and the following disclaimer in the
12*77ba3d3fSMatthias Ringwald  *    documentation and/or other materials provided with the distribution.
13*77ba3d3fSMatthias Ringwald  * 3. Neither the name of the copyright holders nor the names of
14*77ba3d3fSMatthias Ringwald  *    contributors may be used to endorse or promote products derived
15*77ba3d3fSMatthias Ringwald  *    from this software without specific prior written permission.
16*77ba3d3fSMatthias Ringwald  * 4. Any redistribution, use, or modification is done solely for
17*77ba3d3fSMatthias Ringwald  *    personal benefit and not for any commercial purpose or for
18*77ba3d3fSMatthias Ringwald  *    monetary gain.
19*77ba3d3fSMatthias Ringwald  *
20*77ba3d3fSMatthias Ringwald  * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS
21*77ba3d3fSMatthias Ringwald  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22*77ba3d3fSMatthias Ringwald  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23*77ba3d3fSMatthias Ringwald  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MATTHIAS
24*77ba3d3fSMatthias Ringwald  * RINGWALD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25*77ba3d3fSMatthias Ringwald  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
26*77ba3d3fSMatthias Ringwald  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
27*77ba3d3fSMatthias Ringwald  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
28*77ba3d3fSMatthias Ringwald  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
29*77ba3d3fSMatthias Ringwald  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
30*77ba3d3fSMatthias Ringwald  * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31*77ba3d3fSMatthias Ringwald  * SUCH DAMAGE.
32*77ba3d3fSMatthias Ringwald  *
33*77ba3d3fSMatthias Ringwald  * Please inquire about commercial licensing options at
34*77ba3d3fSMatthias Ringwald  * [email protected]
35*77ba3d3fSMatthias Ringwald  *
36*77ba3d3fSMatthias Ringwald  */
37*77ba3d3fSMatthias Ringwald 
38*77ba3d3fSMatthias Ringwald #ifndef __MESH_NETWORK
39*77ba3d3fSMatthias Ringwald #define __MESH_NETWORK
40*77ba3d3fSMatthias Ringwald 
41*77ba3d3fSMatthias Ringwald #include "btstack_linked_list.h"
42*77ba3d3fSMatthias Ringwald #include "provisioning.h"
43*77ba3d3fSMatthias Ringwald #include "btstack_run_loop.h"
44*77ba3d3fSMatthias Ringwald 
45*77ba3d3fSMatthias Ringwald #if defined __cplusplus
46*77ba3d3fSMatthias Ringwald extern "C" {
47*77ba3d3fSMatthias Ringwald #endif
48*77ba3d3fSMatthias Ringwald 
49*77ba3d3fSMatthias Ringwald #define MESH_DEVICE_KEY_INDEX     0xffff
50*77ba3d3fSMatthias Ringwald 
51*77ba3d3fSMatthias Ringwald #define MESH_NETWORK_PAYLOAD_MAX      29
52*77ba3d3fSMatthias Ringwald #define MESH_ACCESS_PAYLOAD_MAX      384
53*77ba3d3fSMatthias Ringwald 
54*77ba3d3fSMatthias Ringwald #define MESH_ADDRESS_UNSASSIGNED     0x0000u
55*77ba3d3fSMatthias Ringwald #define MESH_ADDRESS_ALL_PROXIES     0xFFFCu
56*77ba3d3fSMatthias Ringwald #define MESH_ADDRESS_ALL_FRIENDS     0xFFFDu
57*77ba3d3fSMatthias Ringwald #define MESH_ADDRESS_ALL_RELAYS      0xFFFEu
58*77ba3d3fSMatthias Ringwald #define MESH_ADDRESS_ALL_NODES       0xFFFFu
59*77ba3d3fSMatthias Ringwald 
60*77ba3d3fSMatthias Ringwald typedef enum {
61*77ba3d3fSMatthias Ringwald     MESH_NETWORK_PDU_RECEIVED,
62*77ba3d3fSMatthias Ringwald     MESH_NETWORK_PDU_SENT,
63*77ba3d3fSMatthias Ringwald } mesh_network_callback_type_t;
64*77ba3d3fSMatthias Ringwald 
65*77ba3d3fSMatthias Ringwald typedef enum {
66*77ba3d3fSMatthias Ringwald     MESH_PDU_TYPE_NETWORK = 0,
67*77ba3d3fSMatthias Ringwald     MESH_PDU_TYPE_TRANSPORT,
68*77ba3d3fSMatthias Ringwald } mesh_pdu_type_t;
69*77ba3d3fSMatthias Ringwald 
70*77ba3d3fSMatthias Ringwald typedef struct mesh_pdu {
71*77ba3d3fSMatthias Ringwald     // allow for linked lists
72*77ba3d3fSMatthias Ringwald     btstack_linked_item_t item;
73*77ba3d3fSMatthias Ringwald     // type
74*77ba3d3fSMatthias Ringwald     mesh_pdu_type_t pdu_type;
75*77ba3d3fSMatthias Ringwald } mesh_pdu_t;
76*77ba3d3fSMatthias Ringwald 
77*77ba3d3fSMatthias Ringwald typedef struct mesh_network_pdu {
78*77ba3d3fSMatthias Ringwald     mesh_pdu_t pdu_header;
79*77ba3d3fSMatthias Ringwald 
80*77ba3d3fSMatthias Ringwald     // callback
81*77ba3d3fSMatthias Ringwald     void (*callback)(struct mesh_network_pdu * network_pdu);
82*77ba3d3fSMatthias Ringwald 
83*77ba3d3fSMatthias Ringwald     // meta data network layer
84*77ba3d3fSMatthias Ringwald     uint16_t              netkey_index;
85*77ba3d3fSMatthias Ringwald     // meta data transport layer
86*77ba3d3fSMatthias Ringwald     uint16_t              appkey_index;
87*77ba3d3fSMatthias Ringwald     // flags: bit 0 indicates Proxy PDU
88*77ba3d3fSMatthias Ringwald     uint16_t              flags;
89*77ba3d3fSMatthias Ringwald 
90*77ba3d3fSMatthias Ringwald     // pdu
91*77ba3d3fSMatthias Ringwald     uint16_t              len;
92*77ba3d3fSMatthias Ringwald     uint8_t               data[MESH_NETWORK_PAYLOAD_MAX];
93*77ba3d3fSMatthias Ringwald } mesh_network_pdu_t;
94*77ba3d3fSMatthias Ringwald 
95*77ba3d3fSMatthias Ringwald typedef struct {
96*77ba3d3fSMatthias Ringwald     mesh_pdu_t pdu_header;
97*77ba3d3fSMatthias Ringwald 
98*77ba3d3fSMatthias Ringwald     // rx/tx: acknowledgement timer / segment transmission timer
99*77ba3d3fSMatthias Ringwald     btstack_timer_source_t acknowledgement_timer;
100*77ba3d3fSMatthias Ringwald     // rx: incomplete timer / tx: resend timer
101*77ba3d3fSMatthias Ringwald     btstack_timer_source_t incomplete_timer;
102*77ba3d3fSMatthias Ringwald     // block access
103*77ba3d3fSMatthias Ringwald     uint32_t              block_ack;
104*77ba3d3fSMatthias Ringwald     // meta data network layer
105*77ba3d3fSMatthias Ringwald     uint16_t              netkey_index;
106*77ba3d3fSMatthias Ringwald     // meta data transport layer
107*77ba3d3fSMatthias Ringwald     uint16_t              appkey_index;
108*77ba3d3fSMatthias Ringwald     // transmic size
109*77ba3d3fSMatthias Ringwald     uint8_t               transmic_len;
110*77ba3d3fSMatthias Ringwald     // akf - aid
111*77ba3d3fSMatthias Ringwald     uint8_t               akf_aid;
112*77ba3d3fSMatthias Ringwald     // network pdu header
113*77ba3d3fSMatthias Ringwald     uint8_t               network_header[9];
114*77ba3d3fSMatthias Ringwald     // acknowledgement timer active
115*77ba3d3fSMatthias Ringwald     uint8_t               acknowledgement_timer_active;
116*77ba3d3fSMatthias Ringwald     // incomplete timer active
117*77ba3d3fSMatthias Ringwald     uint8_t               incomplete_timer_active;
118*77ba3d3fSMatthias Ringwald     // message complete
119*77ba3d3fSMatthias Ringwald     uint8_t               message_complete;
120*77ba3d3fSMatthias Ringwald     // seq_zero for segmented messages
121*77ba3d3fSMatthias Ringwald     uint16_t              seq_zero;
122*77ba3d3fSMatthias Ringwald     // pdu
123*77ba3d3fSMatthias Ringwald     uint16_t              len;
124*77ba3d3fSMatthias Ringwald     uint8_t               data[MESH_ACCESS_PAYLOAD_MAX];
125*77ba3d3fSMatthias Ringwald } mesh_transport_pdu_t;
126*77ba3d3fSMatthias Ringwald 
127*77ba3d3fSMatthias Ringwald 
128*77ba3d3fSMatthias Ringwald /**
129*77ba3d3fSMatthias Ringwald  * @brief Init Mesh Network Layer
130*77ba3d3fSMatthias Ringwald  */
131*77ba3d3fSMatthias Ringwald void mesh_network_init(void);
132*77ba3d3fSMatthias Ringwald 
133*77ba3d3fSMatthias Ringwald /**
134*77ba3d3fSMatthias Ringwald  * @brief Set higher layer Network PDU handler
135*77ba3d3fSMatthias Ringwald  * @param packet_handler
136*77ba3d3fSMatthias Ringwald  */
137*77ba3d3fSMatthias Ringwald void mesh_network_set_higher_layer_handler(void (*packet_handler)(mesh_network_callback_type_t callback_type, mesh_network_pdu_t * network_pdu));
138*77ba3d3fSMatthias Ringwald 
139*77ba3d3fSMatthias Ringwald /**
140*77ba3d3fSMatthias Ringwald  * @brief Set higher layer Proxy PDU handler
141*77ba3d3fSMatthias Ringwald  * @param packet_handler
142*77ba3d3fSMatthias Ringwald  */
143*77ba3d3fSMatthias Ringwald void mesh_network_set_proxy_message_handler(void (*packet_handler)(mesh_network_callback_type_t callback_type, mesh_network_pdu_t * network_pdu));
144*77ba3d3fSMatthias Ringwald 
145*77ba3d3fSMatthias Ringwald /**
146*77ba3d3fSMatthias Ringwald  * @brief Mark packet as processed
147*77ba3d3fSMatthias Ringwald  * @param newtork_pdu received via call packet_handler
148*77ba3d3fSMatthias Ringwald  */
149*77ba3d3fSMatthias Ringwald void mesh_network_message_processed_by_higher_layer(mesh_network_pdu_t * network_pdu);
150*77ba3d3fSMatthias Ringwald 
151*77ba3d3fSMatthias Ringwald /**
152*77ba3d3fSMatthias Ringwald  * @brief Configure address filter
153*77ba3d3fSMatthias Ringwald  */
154*77ba3d3fSMatthias Ringwald void mesh_network_set_primary_element_address(uint16_t addr);
155*77ba3d3fSMatthias Ringwald 
156*77ba3d3fSMatthias Ringwald /**
157*77ba3d3fSMatthias Ringwald  * @brief Send network_pdu after encryption
158*77ba3d3fSMatthias Ringwald  * @param network_pdu
159*77ba3d3fSMatthias Ringwald  */
160*77ba3d3fSMatthias Ringwald void mesh_network_send_pdu(mesh_network_pdu_t * network_pdu);
161*77ba3d3fSMatthias Ringwald 
162*77ba3d3fSMatthias Ringwald /*
163*77ba3d3fSMatthias Ringwald  * @brief Setup network pdu header
164*77ba3d3fSMatthias Ringwald  * @param netkey_index
165*77ba3d3fSMatthias Ringwald  * @param nid
166*77ba3d3fSMatthias Ringwald  * @param ctl
167*77ba3d3fSMatthias Ringwald  * @param ttl
168*77ba3d3fSMatthias Ringwald  * @param seq
169*77ba3d3fSMatthias Ringwald  * @param dst
170*77ba3d3fSMatthias Ringwald  * @param transport_pdu_data
171*77ba3d3fSMatthias Ringwald  * @param transport_pdu_len
172*77ba3d3fSMatthias Ringwald  */
173*77ba3d3fSMatthias Ringwald 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);
174*77ba3d3fSMatthias Ringwald 
175*77ba3d3fSMatthias Ringwald /**
176*77ba3d3fSMatthias Ringwald  * Setup network pdu header without modifying len or payload
177*77ba3d3fSMatthias Ringwald  * @param network_pdu
178*77ba3d3fSMatthias Ringwald  * @param netkey_index
179*77ba3d3fSMatthias Ringwald  * @param nid
180*77ba3d3fSMatthias Ringwald  * @param ctl
181*77ba3d3fSMatthias Ringwald  * @param ttl
182*77ba3d3fSMatthias Ringwald  * @param seq
183*77ba3d3fSMatthias Ringwald  * @param src
184*77ba3d3fSMatthias Ringwald  * @param dest
185*77ba3d3fSMatthias Ringwald  */
186*77ba3d3fSMatthias Ringwald 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);
187*77ba3d3fSMatthias Ringwald 
188*77ba3d3fSMatthias Ringwald /**
189*77ba3d3fSMatthias Ringwald  * @brief Validate network addresses
190*77ba3d3fSMatthias Ringwald  * @param ctl
191*77ba3d3fSMatthias Ringwald  * @param src
192*77ba3d3fSMatthias Ringwald  * @param dst
193*77ba3d3fSMatthias Ringwald  * @returns 1 if valid,
194*77ba3d3fSMatthias Ringwald  */
195*77ba3d3fSMatthias Ringwald int mesh_network_addresses_valid(uint8_t ctl, uint16_t src, uint16_t dst);
196*77ba3d3fSMatthias Ringwald 
197*77ba3d3fSMatthias Ringwald /**
198*77ba3d3fSMatthias Ringwald  * @brief Check if Unicast address
199*77ba3d3fSMatthias Ringwald  * @param addr
200*77ba3d3fSMatthias Ringwald  * @returns 1 if unicast
201*77ba3d3fSMatthias Ringwald  */
202*77ba3d3fSMatthias Ringwald int mesh_network_address_unicast(uint16_t addr);
203*77ba3d3fSMatthias Ringwald 
204*77ba3d3fSMatthias Ringwald /**
205*77ba3d3fSMatthias Ringwald  * @brief Check if Unicast address
206*77ba3d3fSMatthias Ringwald  * @param addr
207*77ba3d3fSMatthias Ringwald  * @returns 1 if unicast
208*77ba3d3fSMatthias Ringwald  */
209*77ba3d3fSMatthias Ringwald int mesh_network_address_group(uint16_t addr);
210*77ba3d3fSMatthias Ringwald 
211*77ba3d3fSMatthias Ringwald /**
212*77ba3d3fSMatthias Ringwald  * @brief Check if All Proxies address
213*77ba3d3fSMatthias Ringwald  * @param addr
214*77ba3d3fSMatthias Ringwald  * @returns 1 if all proxies
215*77ba3d3fSMatthias Ringwald  */
216*77ba3d3fSMatthias Ringwald int mesh_network_address_all_proxies(uint16_t addr);
217*77ba3d3fSMatthias Ringwald 
218*77ba3d3fSMatthias Ringwald /**
219*77ba3d3fSMatthias Ringwald  * @brief Check if All Nodes address
220*77ba3d3fSMatthias Ringwald  * @param addr
221*77ba3d3fSMatthias Ringwald  * @returns 1 if all nodes
222*77ba3d3fSMatthias Ringwald  */
223*77ba3d3fSMatthias Ringwald int mesh_network_address_all_nodes(uint16_t addr);
224*77ba3d3fSMatthias Ringwald 
225*77ba3d3fSMatthias Ringwald /**
226*77ba3d3fSMatthias Ringwald  * @brief Check if All Friends address
227*77ba3d3fSMatthias Ringwald  * @param addr
228*77ba3d3fSMatthias Ringwald  * @returns 1 if all friends
229*77ba3d3fSMatthias Ringwald  */
230*77ba3d3fSMatthias Ringwald int mesh_network_address_all_friends(uint16_t addr);
231*77ba3d3fSMatthias Ringwald 
232*77ba3d3fSMatthias Ringwald /**
233*77ba3d3fSMatthias Ringwald  * @brief Check if All Relays address
234*77ba3d3fSMatthias Ringwald  * @param addr
235*77ba3d3fSMatthias Ringwald  * @returns 1 if all relays
236*77ba3d3fSMatthias Ringwald  */
237*77ba3d3fSMatthias Ringwald int mesh_network_address_all_relays(uint16_t addr);
238*77ba3d3fSMatthias Ringwald 
239*77ba3d3fSMatthias Ringwald 
240*77ba3d3fSMatthias Ringwald /**
241*77ba3d3fSMatthias Ringwald  * @brief Check if Virtual address
242*77ba3d3fSMatthias Ringwald  * @param addr
243*77ba3d3fSMatthias Ringwald  * @returns 1 if virtual
244*77ba3d3fSMatthias Ringwald  */
245*77ba3d3fSMatthias Ringwald int mesh_network_address_virtual(uint16_t addr);
246*77ba3d3fSMatthias Ringwald 
247*77ba3d3fSMatthias Ringwald // buffer pool
248*77ba3d3fSMatthias Ringwald mesh_network_pdu_t * mesh_network_pdu_get(void);
249*77ba3d3fSMatthias Ringwald void mesh_network_pdu_free(mesh_network_pdu_t * network_pdu);
250*77ba3d3fSMatthias Ringwald 
251*77ba3d3fSMatthias Ringwald // Mesh Network PDU Getter
252*77ba3d3fSMatthias Ringwald uint16_t  mesh_network_control(mesh_network_pdu_t * network_pdu);
253*77ba3d3fSMatthias Ringwald uint8_t   mesh_network_nid(mesh_network_pdu_t * network_pdu);
254*77ba3d3fSMatthias Ringwald uint8_t   mesh_network_ttl(mesh_network_pdu_t * network_pdu);
255*77ba3d3fSMatthias Ringwald uint32_t  mesh_network_seq(mesh_network_pdu_t * network_pdu);
256*77ba3d3fSMatthias Ringwald uint16_t  mesh_network_src(mesh_network_pdu_t * network_pdu);
257*77ba3d3fSMatthias Ringwald uint16_t  mesh_network_dst(mesh_network_pdu_t * network_pdu);
258*77ba3d3fSMatthias Ringwald int       mesh_network_segmented(mesh_network_pdu_t * network_pdu);
259*77ba3d3fSMatthias Ringwald uint8_t * mesh_network_pdu_data(mesh_network_pdu_t * network_pdu);
260*77ba3d3fSMatthias Ringwald uint8_t   mesh_network_pdu_len(mesh_network_pdu_t * network_pdu);
261*77ba3d3fSMatthias Ringwald 
262*77ba3d3fSMatthias Ringwald void     mesh_set_iv_index(uint32_t iv_index);
263*77ba3d3fSMatthias Ringwald uint32_t mesh_get_iv_index(void);
264*77ba3d3fSMatthias Ringwald 
265*77ba3d3fSMatthias Ringwald // Testing only
266*77ba3d3fSMatthias Ringwald void mesh_network_received_message(const uint8_t * pdu_data, uint8_t pdu_len);
267*77ba3d3fSMatthias Ringwald void mesh_network_process_proxy_message(const uint8_t * pdu_data, uint8_t pdu_len);
268*77ba3d3fSMatthias Ringwald void mesh_network_encrypt_proxy_message(mesh_network_pdu_t * network_pdu, void (* callback)(mesh_network_pdu_t * callback));
269*77ba3d3fSMatthias Ringwald void mesh_network_dump(void);
270*77ba3d3fSMatthias Ringwald void mesh_network_reset(void);
271*77ba3d3fSMatthias Ringwald 
272*77ba3d3fSMatthias Ringwald void mesh_gatt_handle_event(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size);
273*77ba3d3fSMatthias Ringwald 
274*77ba3d3fSMatthias Ringwald #if defined __cplusplus
275*77ba3d3fSMatthias Ringwald }
276*77ba3d3fSMatthias Ringwald #endif
277*77ba3d3fSMatthias Ringwald 
278*77ba3d3fSMatthias Ringwald #endif
279