summaryrefslogtreecommitdiff
path: root/mesh/net.h
blob: bfc8064f3466d88e807215febba43588c79a42d4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
/*
 *
 *  BlueZ - Bluetooth protocol stack for Linux
 *
 *  Copyright (C) 2018-2019  Intel Corporation. All rights reserved.
 *
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License as published by the Free Software Foundation; either
 *  version 2.1 of the License, or (at your option) any later version.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 */

#ifndef __packed
#define __packed __attribute__((packed))
#endif

struct mesh_io;
struct mesh_node;

#define DEV_ID	0

#define UNUSED_KEY_IDX	0xffff

#define APP_AID_DEV	0x00

#define CTL		0x80

#define CREDFLAG_MASK	0x1000

#define KEY_CACHE_SIZE	64
#define FRND_CACHE_MAX	32

#define MAX_UNSEG_LEN	15 /* msg_len == 11 + sizeof(MIC) */
#define MAX_SEG_LEN	12 /* UnSeg length - 3 octets overhead */
#define SEG_MAX(seg, len) ((!seg && len <= MAX_UNSEG_LEN) ? 0 : \
						(((len) - 1) / MAX_SEG_LEN))

#define SEG_OFF(seg)	((seg) * MAX_SEG_LEN)
#define MAX_SEG_TO_LEN(seg)	((seg) ? SEG_OFF((seg) + 1) : MAX_UNSEG_LEN)

#define SEGMENTED	0x80
#define UNSEGMENTED	0x00
#define SEG_HDR_SHIFT	31
#define IS_SEGMENTED(hdr)	(!!((hdr) & (true << SEG_HDR_SHIFT)))

#define KEY_ID_MASK	0x7f
#define KEY_AID_MASK	0x3f
#define KEY_ID_AKF	0x40
#define KEY_AID_SHIFT	0
#define AKF_HDR_SHIFT	30
#define KEY_HDR_SHIFT	24
#define HAS_APP_KEY(hdr)	(!!((hdr) & (true << AKF_HDR_SHIFT)))

#define OPCODE_MASK	0x7f
#define OPCODE_HDR_SHIFT	24
#define RELAY		0x80
#define RELAY_HDR_SHIFT	23
#define SZMIC		0x80
#define SZMIC_HDR_SHIFT	23
#define SEQ_ZERO_MASK	0x1fff
#define SEQ_ZERO_HDR_SHIFT	10
#define IS_RELAYED(hdr)	(!!((hdr) & (true << RELAY_HDR_SHIFT)))
#define HAS_MIC64(hdr)	(!!((hdr) & (true << SZMIC_HDR_SHIFT)))

#define SEG_MASK	0x1f
#define SEGO_HDR_SHIFT	5
#define SEGN_HDR_SHIFT	0
#define SEG_TOTAL(hdr)	(((hdr) >> SEGN_HDR_SHIFT) & SEG_MASK)

/* Mask of Hdr bits which must be constant over entire incoming SAR message */
/* (SEG || AKF || AID || SZMIC || SeqZero || SegN) */
#define HDR_KEY_MASK		((true << SEG_HDR_SHIFT) |		\
				(KEY_ID_MASK << KEY_HDR_SHIFT) |	\
				(true << SZMIC_HDR_SHIFT) |		\
				(SEQ_ZERO_MASK << SEQ_ZERO_HDR_SHIFT) |	\
				(SEG_MASK << SEGN_HDR_SHIFT))

#define HDR_ACK_MASK		((OPCODE_MASK << OPCODE_HDR_SHIFT) |	\
				(SEQ_ZERO_MASK << SEQ_ZERO_HDR_SHIFT))



#define MSG_CACHE_SIZE		70
#define REPLAY_CACHE_SIZE	10

/* Proxy Configuration Opcodes */
#define PROXY_OP_SET_FILTER_TYPE	0x00
#define PROXY_OP_FILTER_ADD		0x01
#define PROXY_OP_FILTER_DEL		0x02
#define PROXY_OP_FILTER_STATUS		0x03

/* Proxy Filter Defines */
#define PROXY_FILTER_WHITELIST		0x00
#define PROXY_FILTER_BLACKLIST		0x01

/* Network Tranport Opcodes */
#define NET_OP_SEG_ACKNOWLEDGE		0x00
#define NET_OP_FRND_POLL		0x01
#define NET_OP_FRND_UPDATE		0x02
#define NET_OP_FRND_REQUEST		0x03
#define NET_OP_FRND_OFFER		0x04
#define NET_OP_FRND_CLEAR		0x05
#define NET_OP_FRND_CLEAR_CONFIRM	0x06

#define NET_OP_PROXY_SUB_ADD		0x07
#define NET_OP_PROXY_SUB_REMOVE		0x08
#define NET_OP_PROXY_SUB_CONFIRM	0x09
#define NET_OP_HEARTBEAT		0x0a

#define FRND_OPCODE(x) \
		((x) >= NET_OP_FRND_POLL && (x) <= NET_OP_FRND_CLEAR_CONFIRM)

#define DEFAULT_MIN_DELAY		0
#define DEFAULT_MAX_DELAY		25

struct mesh_net_addr_range {
	uint16_t low;
	uint16_t high;
	uint16_t next;
};

struct mesh_net_prov_caps {
	uint8_t num_ele;
	uint16_t algorithms;
	uint8_t pub_type;
	uint8_t static_type;
	uint8_t output_size;
	uint16_t output_action;
	uint8_t input_size;
	uint16_t input_action;
} __packed;

struct mesh_net_heartbeat {
	struct l_timeout *pub_timer;
	struct l_timeout *sub_timer;
	struct timeval sub_time;
	bool sub_enabled;
	uint32_t pub_period;
	uint32_t sub_period;
	uint32_t sub_start;
	uint16_t pub_dst;
	uint16_t pub_count;
	uint16_t pub_features;
	uint16_t features;
	uint16_t pub_net_idx;
	uint16_t sub_src;
	uint16_t sub_dst;
	uint16_t sub_count;
	uint8_t pub_ttl;
	uint8_t sub_min_hops;
	uint8_t sub_max_hops;
};

struct mesh_key_set {
	bool frnd;
	uint8_t nid;
	uint8_t enc_key[16];
	uint8_t privacy_key[16];
};

struct friend_neg {
	int8_t rssi;
	bool clearing;
};

struct friend_act {
	uint16_t *grp_list;
	uint32_t last_hdr;
	int16_t grp_cnt;
	bool seq;
	bool last;
};

struct mesh_friend {
	struct mesh_net *net;
	struct l_timeout *timeout;
	struct l_queue *pkt_cache;
	void *pkt;
	uint32_t poll_timeout;
	uint32_t net_key_cur;
	uint32_t net_key_upd;
	uint16_t old_friend;
	uint16_t net_idx;
	uint16_t lp_addr;/* dst; * Primary Element unicast addr */
	uint16_t fn_cnt;
	uint16_t lp_cnt;
	uint8_t	receive_delay;
	uint8_t ele_cnt;
	uint8_t frd;
	uint8_t frw;
	union {
		struct friend_neg negotiate;
		struct friend_act active;
	} u;
};

struct mesh_frnd_pkt {
	uint32_t iv_index;
	uint32_t seq;
	uint16_t src;
	uint16_t dst;
	uint16_t size;
	uint8_t segN;
	uint8_t segO;
	uint8_t ttl;
	uint8_t tc;
	bool szmict;
	union {
		struct {
			uint8_t key_id;
		} m;
		struct {
			uint16_t seq0;
		} a;
		struct {
			uint8_t opcode;
		} c;
	} u;
	uint8_t data[];
};

struct mesh_friend_seg_one {
	uint32_t hdr;
	uint32_t seq;
	bool sent;
	bool md;
	uint8_t data[15];
};

struct mesh_friend_seg_12 {
	uint32_t hdr;
	uint32_t seq;
	bool sent;
	bool md;
	uint8_t data[12];
};

struct mesh_friend_msg {
	uint32_t iv_index;
	uint32_t flags;
	uint16_t src;
	uint16_t dst;
	uint8_t ttl;
	uint8_t cnt_in;
	uint8_t cnt_out;
	uint8_t last_len;
	bool done;
	bool ctl;
	union {
		struct mesh_friend_seg_one one[1]; /* Single segment */
		struct mesh_friend_seg_12 s12[0]; /* Array of segments */
	} u;
};

typedef void (*mesh_status_func_t)(void *user_data, bool result);
typedef void (*mesh_net_status_func_t)(uint16_t remote, uint8_t status,
					void *data, uint16_t size,
					void *user_data);

struct mesh_net *mesh_net_new(struct mesh_node *node);
void mesh_net_free(struct mesh_net *net);
void mesh_net_flush_msg_queues(struct mesh_net *net);
void mesh_net_set_iv_index(struct mesh_net *net, uint32_t index, bool update);
bool mesh_net_iv_index_update(struct mesh_net *net);
bool mesh_net_set_seq_num(struct mesh_net *net, uint32_t number);
uint32_t mesh_net_get_seq_num(struct mesh_net *net);
uint32_t mesh_net_next_seq_num(struct mesh_net *net);
bool mesh_net_set_default_ttl(struct mesh_net *net, uint8_t ttl);
uint8_t mesh_net_get_default_ttl(struct mesh_net *net);
bool mesh_net_get_frnd_seq(struct mesh_net *net);
void mesh_net_set_frnd_seq(struct mesh_net *net, bool seq);
uint16_t mesh_net_get_address(struct mesh_net *net);
bool mesh_net_register_unicast(struct mesh_net *net,
					uint16_t unicast, uint8_t num_ele);
uint8_t mesh_net_get_num_ele(struct mesh_net *net);
void net_local_beacon(uint32_t key_id, uint8_t *beacon);
bool mesh_net_set_beacon_mode(struct mesh_net *net, bool enable);
bool mesh_net_set_proxy_mode(struct mesh_net *net, bool enable);
bool mesh_net_set_relay_mode(struct mesh_net *net, bool enable, uint8_t cnt,
							uint8_t interval);
bool mesh_net_set_friend_mode(struct mesh_net *net, bool enable);
int mesh_net_del_key(struct mesh_net *net, uint16_t net_idx);
int mesh_net_add_key(struct mesh_net *net, uint16_t net_idx,
							const uint8_t *key);
int mesh_net_update_key(struct mesh_net *net, uint16_t net_idx,
							const uint8_t *key);
bool mesh_net_set_key(struct mesh_net *net, uint16_t idx, const uint8_t *key,
					const uint8_t *new_key, uint8_t phase);
uint32_t mesh_net_get_iv_index(struct mesh_net *net);
void mesh_net_get_snb_state(struct mesh_net *net,
					uint8_t *flags, uint32_t *iv_index);
bool mesh_net_get_key(struct mesh_net *net, bool new_key, uint16_t idx,
							uint32_t *key_id);
bool mesh_net_attach(struct mesh_net *net, struct mesh_io *io);
struct mesh_io *mesh_net_detach(struct mesh_net *net);
struct l_queue *mesh_net_get_app_keys(struct mesh_net *net);

bool mesh_net_flush(struct mesh_net *net);
void mesh_net_transport_send(struct mesh_net *net, uint32_t key_id,
				uint16_t net_idx, uint32_t iv_index,
				uint8_t ttl, uint32_t seq, uint16_t src,
				uint16_t dst, const uint8_t *msg,
				uint16_t msg_len);

bool mesh_net_app_send(struct mesh_net *net, bool frnd_cred, uint16_t src,
				uint16_t dst, uint8_t key_id, uint16_t net_idx,
				uint8_t ttl, uint32_t seq, uint32_t iv_index,
				bool segmented, bool szmic,
				const void *msg, uint16_t msg_len,
				mesh_net_status_func_t status_func,
				void *user_data);
void mesh_net_ack_send(struct mesh_net *net, uint32_t key_id,
				uint32_t iv_index, uint8_t ttl, uint32_t seq,
				uint16_t src, uint16_t dst, bool rly,
				uint16_t seqZero, uint32_t ack_flags);
struct mesh_net_prov_caps *mesh_net_prov_caps_get(struct mesh_net *net);
uint8_t *mesh_net_priv_key_get(struct mesh_net *net);
bool mesh_net_priv_key_set(struct mesh_net *net, uint8_t key[32]);
uint8_t *mesh_net_prov_rand(struct mesh_net *net);
uint16_t mesh_net_prov_uni(struct mesh_net *net, uint8_t ele_cnt);
bool mesh_net_id_uuid_set(struct mesh_net *net, uint8_t uuid[16]);
uint8_t *mesh_net_test_addr(struct mesh_net *net);
int mesh_net_get_identity_mode(struct mesh_net *net, uint16_t idx,
								uint8_t *mode);
char *mesh_net_id_name(struct mesh_net *net);
bool mesh_net_test_mode(struct mesh_net *net);
bool mesh_net_dst_reg(struct mesh_net *net, uint16_t dst);
bool mesh_net_dst_unreg(struct mesh_net *net, uint16_t dst);
struct mesh_friend *mesh_friend_new(struct mesh_net *net, uint16_t dst,
					uint8_t ele_cnt, uint8_t frd,
					uint8_t frw, uint32_t fpt,
					uint16_t fn_cnt, uint16_t lp_cnt);
void mesh_friend_free(void *frnd);
bool mesh_friend_clear(struct mesh_net *net, struct mesh_friend *frnd);
void mesh_friend_sub_add(struct mesh_net *net, uint16_t lpn, uint8_t ele_cnt,
							uint8_t grp_cnt,
							const uint8_t *list);
void mesh_friend_sub_del(struct mesh_net *net, uint16_t lpn, uint8_t cnt,
						const uint8_t *del_list);
uint8_t mesh_net_key_refresh_phase_set(struct mesh_net *net, uint16_t net_idx,
							uint8_t transition);
uint8_t mesh_net_key_refresh_phase_get(struct mesh_net *net, uint16_t net_idx,
							uint8_t *phase);
void mesh_net_send_seg(struct mesh_net *net, uint32_t key_id,
				uint32_t iv_index, uint8_t ttl, uint32_t seq,
				uint16_t src, uint16_t dst, uint32_t hdr,
				const void *seg, uint16_t seg_len);
uint16_t mesh_net_get_features(struct mesh_net *net);
struct mesh_net_heartbeat *mesh_net_heartbeat_get(struct mesh_net *net);
void mesh_net_heartbeat_init(struct mesh_net *net);
void mesh_net_heartbeat_send(struct mesh_net *net);
void mesh_net_uni_range_set(struct mesh_net *net,
				struct mesh_net_addr_range *range);
struct mesh_net_addr_range mesh_net_uni_range_get(struct mesh_net *net);
void mesh_net_provisioner_mode_set(struct mesh_net *net, bool mode);
bool mesh_net_provisioner_mode_get(struct mesh_net *net);
bool mesh_net_key_list_get(struct mesh_net *net, uint8_t *buf, uint16_t *count);
uint16_t mesh_net_get_primary_idx(struct mesh_net *net);
uint32_t mesh_net_friend_timeout(struct mesh_net *net, uint16_t addr);
struct mesh_io *mesh_net_get_io(struct mesh_net *net);
struct mesh_node *mesh_net_node_get(struct mesh_net *net);
bool mesh_net_have_key(struct mesh_net *net, uint16_t net_idx);
bool mesh_net_is_local_address(struct mesh_net *net, uint16_t src,
							uint16_t count);
void mesh_net_set_window_accuracy(struct mesh_net *net, uint8_t accuracy);
void mesh_net_transmit_params_set(struct mesh_net *net, uint8_t count,
							uint16_t interval);
void mesh_net_transmit_params_get(struct mesh_net *net, uint8_t *count,
							uint16_t *interval);
struct mesh_prov *mesh_net_get_prov(struct mesh_net *net);
void mesh_net_set_prov(struct mesh_net *net, struct mesh_prov *prov);
uint32_t mesh_net_get_instant(struct mesh_net *net);
struct l_queue *mesh_net_get_friends(struct mesh_net *net);
struct l_queue *mesh_net_get_negotiations(struct mesh_net *net);
bool net_msg_check_replay_cache(struct mesh_net *net, uint16_t src,
				uint16_t crpl, uint32_t seq, uint32_t iv_index);
void net_msg_add_replay_cache(struct mesh_net *net, uint16_t src, uint32_t seq,
							uint32_t iv_index);