NimBLE-Arduino 2.1.2
Loading...
Searching...
No Matches
net.h
1/* Bluetooth Mesh */
2
3/*
4 * Copyright (c) 2017 Intel Corporation
5 *
6 * SPDX-License-Identifier: Apache-2.0
7 */
8
9#ifndef __NET_H__
10#define __NET_H__
11
12#include "subnet.h"
13
14#define BT_MESH_IV_UPDATE(flags) ((flags >> 1) & 0x01)
15#define BT_MESH_KEY_REFRESH(flags) (flags & 0x01)
16
17#include <stdbool.h>
18#include "atomic.h"
19#include "../include/mesh/mesh.h"
20#include "../include/mesh/glue.h"
21
22/* How many hours in between updating IVU duration */
23#define BT_MESH_IVU_MIN_HOURS 96
24#define BT_MESH_IVU_HOURS (BT_MESH_IVU_MIN_HOURS / \
25 CONFIG_BT_MESH_IVU_DIVIDER)
26#define BT_MESH_IVU_TIMEOUT K_HOURS(BT_MESH_IVU_HOURS)
27
28/* Minimum valid Mesh Network PDU length. The Network headers
29 * themselves take up 9 bytes. After that there is a minimum of 1 byte
30 * payload for both CTL=1 and CTL=0 PDUs (smallest OpCode is 1 byte). CTL=1
31 * PDUs must use a 64-bit (8 byte) NetMIC, whereas CTL=0 PDUs have at least
32 * a 32-bit (4 byte) NetMIC and AppMIC giving again a total of 8 bytes.
33 */
34#define BT_MESH_NET_MIN_PDU_LEN (BT_MESH_NET_HDR_LEN + 1 + 8)
35/* Maximum valid Mesh Network PDU length. The longest packet can either be a
36 * transport control message (CTL=1) of 12 bytes + 8 bytes of NetMIC, or an
37 * access message (CTL=0) of 16 bytes + 4 bytes of NetMIC.
38 */
39#define BT_MESH_NET_MAX_PDU_LEN (BT_MESH_NET_HDR_LEN + 16 + 4)
40
41struct bt_mesh_net_cred;
42
43struct bt_mesh_node {
44 uint16_t addr;
45 uint16_t net_idx;
46 uint8_t dev_key[16];
47 uint8_t num_elem;
48};
49
50#if MYNEWT_VAL(BLE_MESH_FRIEND)
51#define FRIEND_SEG_RX MYNEWT_VAL(BLE_MESH_FRIEND_SEG_RX)
52#define FRIEND_SUB_LIST_SIZE MYNEWT_VAL(BLE_MESH_FRIEND_SUB_LIST_SIZE)
53#else
54#define FRIEND_SEG_RX 0
55#define FRIEND_SUB_LIST_SIZE 0
56#endif
57
58struct bt_mesh_friend {
59 uint16_t lpn;
60 uint8_t recv_delay;
61 uint8_t fsn:1,
62 send_last:1,
63 pending_req:1,
64 pending_buf:1,
65 established:1;
66 int32_t poll_to;
67 uint8_t num_elem;
68 uint16_t lpn_counter;
69 uint16_t counter;
70
71 struct bt_mesh_subnet *subnet;
72
73 struct bt_mesh_net_cred cred[2];
74
75 uint16_t sub_list[FRIEND_SUB_LIST_SIZE];
76
77 struct k_work_delayable timer;
78
79 struct bt_mesh_friend_seg {
80 struct net_buf_slist_t queue;
81
82 /* The target number of segments, i.e. not necessarily
83 * the current number of segments, in the queue. This is
84 * used for Friend Queue free space calculations.
85 */
86 uint8_t seg_count;
87 } seg[FRIEND_SEG_RX];
88
89 struct os_mbuf *last;
90
91 struct net_buf_slist_t queue;
92 uint32_t queue_size;
93
94 /* Friend Clear Procedure */
95 struct {
96 uint32_t start; /* Clear Procedure start */
97 uint16_t frnd; /* Previous Friend's address */
98 uint16_t repeat_sec; /* Repeat timeout in seconds */
99 struct k_work_delayable timer; /* Repeat timer */
100 } clear;
101};
102
103#if (MYNEWT_VAL(BLE_MESH_LOW_POWER))
104#define LPN_GROUPS CONFIG_BT_MESH_LPN_GROUPS
105#else
106#define LPN_GROUPS 0
107#endif
108
109/* Low Power Node state */
110struct bt_mesh_lpn {
111 enum __packed {
112 BT_MESH_LPN_DISABLED, /* LPN feature is disabled */
113 BT_MESH_LPN_CLEAR, /* Clear in progress */
114 BT_MESH_LPN_TIMER, /* Waiting for auto timer expiry */
115 BT_MESH_LPN_ENABLED, /* LPN enabled, but no Friend */
116 BT_MESH_LPN_REQ_WAIT, /* Wait before scanning for offers */
117 BT_MESH_LPN_WAIT_OFFER, /* Friend Req sent */
118 BT_MESH_LPN_ESTABLISHED, /* Friendship established */
119 BT_MESH_LPN_RECV_DELAY, /* Poll sent, waiting ReceiveDelay */
120 BT_MESH_LPN_WAIT_UPDATE, /* Waiting for Update or message */
121 } state;
122
123 /* Transaction Number (used for subscription list) */
124 uint8_t xact_next;
125 uint8_t xact_pending;
126 uint8_t sent_req;
127
128 /* Address of our Friend when we're a LPN. Unassigned if we don't
129 * have a friend yet.
130 */
131 uint16_t frnd;
132
133 /* Value from the friend offer */
134 uint8_t recv_win;
135
136 uint8_t req_attempts; /* Number of Request attempts */
137
138 int32_t poll_timeout;
139
140 uint8_t groups_changed:1, /* Friend Subscription List needs updating */
141 pending_poll:1, /* Poll to be sent after subscription */
142 disable:1, /* Disable LPN after clearing */
143 fsn:1, /* Friend Sequence Number */
144 established:1, /* Friendship established */
145 clear_success:1; /* Friend Clear Confirm received */
146
147 /* Friend Queue Size */
148 uint8_t queue_size;
149
150 /* FriendCounter */
151 uint16_t frnd_counter;
152
153 /* LPNCounter */
154 uint16_t lpn_counter;
155
156 /* Previous Friend of this LPN */
157 uint16_t old_friend;
158
159 /* Duration reported for last advertising packet */
160 uint16_t adv_duration;
161
162 /* Next LPN related action timer */
163 struct k_work_delayable timer;
164
165 /* Subscribed groups */
166 uint16_t groups[LPN_GROUPS];
167
168 struct bt_mesh_subnet *sub;
169
170 struct bt_mesh_net_cred cred[2];
171
172 /* Bit fields for tracking which groups the Friend knows about */
173 ATOMIC_DEFINE(added, LPN_GROUPS);
174 ATOMIC_DEFINE(pending, LPN_GROUPS);
175 ATOMIC_DEFINE(to_remove, LPN_GROUPS);
176};
177
178/* bt_mesh_net.flags */
179enum {
180 BT_MESH_VALID, /* We have been provisioned */
181 BT_MESH_SUSPENDED, /* Network is temporarily suspended */
182 BT_MESH_IVU_IN_PROGRESS, /* IV Update in Progress */
183 BT_MESH_IVU_INITIATOR, /* IV Update initiated by us */
184 BT_MESH_IVU_TEST, /* IV Update test mode */
185 BT_MESH_IVU_PENDING, /* Update blocked by SDU in progress */
186
187 /* Feature flags */
188 BT_MESH_RELAY,
189 BT_MESH_BEACON,
190 BT_MESH_GATT_PROXY,
191 BT_MESH_FRIEND,
192
193 /* Don't touch - intentionally last */
194 BT_MESH_FLAG_COUNT,
195};
196
197struct bt_mesh_net {
198 uint32_t iv_index; /* Current IV Index */
199 uint32_t seq; /* Next outgoing sequence number (24 bits) */
200
201 ATOMIC_DEFINE(flags, BT_MESH_FLAG_COUNT);
202
203 /* Local network interface */
204 struct ble_npl_callout local_work;
205 struct net_buf_slist_t local_queue;
206
207#if MYNEWT_VAL(BLE_MESH_FRIEND)
208 /* Friend state, unique for each LPN that we're Friends for */
209 struct bt_mesh_friend frnd[MYNEWT_VAL(BLE_MESH_FRIEND_LPN_COUNT)];
210#endif
211
212#if (MYNEWT_VAL(BLE_MESH_LOW_POWER))
213 struct bt_mesh_lpn lpn; /* Low Power Node state */
214#endif
215
216 /* Number of hours in current IV Update state */
217 uint8_t ivu_duration;
218
219 uint8_t net_xmit;
220 uint8_t relay_xmit;
221 uint8_t default_ttl;
222
223 /* Timer to track duration in current IV Update state */
224 struct k_work_delayable ivu_timer;
225
226 uint8_t dev_key[16];
227};
228
229/* Network interface */
230enum bt_mesh_net_if {
231 BT_MESH_NET_IF_ADV,
232 BT_MESH_NET_IF_LOCAL,
233 BT_MESH_NET_IF_PROXY,
234 BT_MESH_NET_IF_PROXY_CFG,
235};
236
237/* Decoding context for Network/Transport data */
238struct bt_mesh_net_rx {
239 struct bt_mesh_subnet *sub;
240 struct bt_mesh_msg_ctx ctx;
241 uint32_t seq; /* Sequence Number */
242 uint8_t old_iv:1, /* iv_index - 1 was used */
243 new_key:1, /* Data was encrypted with updated key */
244 friend_cred:1, /* Data was encrypted with friend cred */
245 ctl:1, /* Network Control */
246 net_if:2, /* Network interface */
247 local_match:1, /* Matched a local element */
248 friend_match:1; /* Matched an LPN we're friends for */
249 uint16_t msg_cache_idx; /* Index of entry in message cache */
250};
251
252/* Encoding context for Network/Transport data */
253struct bt_mesh_net_tx {
254 struct bt_mesh_subnet *sub;
255 struct bt_mesh_msg_ctx *ctx;
256 uint16_t src;
257 uint8_t xmit;
258 uint8_t friend_cred:1,
259 aszmic:1,
260 aid:6;
261};
262
263extern struct bt_mesh_net bt_mesh;
264
265#define BT_MESH_NET_IVI_TX (bt_mesh.iv_index - \
266 atomic_test_bit(bt_mesh.flags, \
267 BT_MESH_IVU_IN_PROGRESS))
268#define BT_MESH_NET_IVI_RX(rx) (bt_mesh.iv_index - (rx)->old_iv)
269
270#define BT_MESH_NET_HDR_LEN 9
271
272static inline void *net_buf_user_data(const struct os_mbuf *buf)
273{
274 /* In Zephyr at the end of net_buf (which is ported as os_mbuf) is place
275 * for user_data, which is array of octets, just like os_mbuf's om_data. Let's just
276 * use last octets (starting at start of om_data + total size of data mbuf can hold -
277 * intended user_data size) of om_data as Zephyr's user_data.
278 */
279 return (void *)(buf->om_data + buf->om_omp->omp_databuf_len - MYNEWT_VAL(BLE_MESH_NET_BUF_USER_DATA_SIZE));
280}
281
282int bt_mesh_net_create(uint16_t idx, uint8_t flags, const uint8_t key[16],
283 uint32_t iv_index);
284
285bool bt_mesh_net_iv_update(uint32_t iv_index, bool iv_update);
286
287int bt_mesh_net_encode(struct bt_mesh_net_tx *tx, struct os_mbuf *buf,
288 bool proxy);
289
290int bt_mesh_net_decode(struct os_mbuf *in, enum bt_mesh_net_if net_if,
291 struct bt_mesh_net_rx *rx, struct os_mbuf *out);
292
293int bt_mesh_net_send(struct bt_mesh_net_tx *tx, struct os_mbuf *buf,
294 const struct bt_mesh_send_cb *cb, void *cb_data);
295
296void bt_mesh_net_recv(struct os_mbuf *data, int8_t rssi,
297 enum bt_mesh_net_if net_if);
298
299void bt_mesh_net_loopback_clear(uint16_t net_idx);
300
301uint32_t bt_mesh_next_seq(void);
302
303void bt_mesh_net_init(void);
304void bt_mesh_net_header_parse(struct os_mbuf *buf,
305 struct bt_mesh_net_rx *rx);
306void bt_mesh_net_pending_net_store(void);
307void bt_mesh_net_pending_iv_store(void);
308void bt_mesh_net_pending_seq_store(void);
309void bt_mesh_net_clear(void);
310void bt_mesh_net_settings_commit(void);
311
312static inline void send_cb_finalize(const struct bt_mesh_send_cb *cb,
313 void *cb_data)
314{
315 if (!cb) {
316 return;
317 }
318
319 if (cb->start) {
320 cb->start(0, 0, cb_data);
321 }
322
323 if (cb->end) {
324 cb->end(0, cb_data);
325 }
326}
327
328#endif
#define ATOMIC_DEFINE(name, num_bits)
Define an array of atomic variables.
Definition atomic.h:274
Definition msg.h:80
Definition subnet.h:28
Definition subnet.h:35
uint16_t omp_databuf_len
Definition os_mbuf.h:57
Definition os_mbuf.h:86
struct os_mbuf_pool * om_omp
Definition os_mbuf.h:107
uint8_t * om_data
Definition os_mbuf.h:90