• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *	wmediumd, wireless medium simulator for mac80211_hwsim kernel module
3  *	Copyright (c) 2011 cozybit Inc.
4  *	Copyright (C) 2020 Intel Corporation
5  *
6  *	Author:	Javier Lopez	<jlopex@cozybit.com>
7  *		Javier Cardona	<javier@cozybit.com>
8  *
9  *	This program is free software; you can redistribute it and/or
10  *	modify it under the terms of the GNU General Public License
11  *	as published by the Free Software Foundation; either version 2
12  *	of the License, or (at your option) any later version.
13  *
14  *	This program is distributed in the hope that it will be useful,
15  *	but WITHOUT ANY WARRANTY; without even the implied warranty of
16  *	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  *	GNU General Public License for more details.
18  *
19  *	You should have received a copy of the GNU General Public License
20  *	along with this program; if not, write to the Free Software
21  *	Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
22  *	02110-1301, USA.
23  */
24 
25 #ifndef WMEDIUMD_H_
26 #define WMEDIUMD_H_
27 
28 #define HWSIM_TX_CTL_REQ_TX_STATUS	1
29 #define HWSIM_TX_CTL_NO_ACK		(1 << 1)
30 #define HWSIM_TX_STAT_ACK		(1 << 2)
31 
32 enum {
33 	HWSIM_CMD_UNSPEC,
34 	HWSIM_CMD_REGISTER,
35 	HWSIM_CMD_FRAME,
36 	HWSIM_CMD_TX_INFO_FRAME,
37 	HWSIM_CMD_NEW_RADIO,
38 	HWSIM_CMD_DEL_RADIO,
39 	HWSIM_CMD_GET_RADIO,
40 	HWSIM_CMD_ADD_MAC_ADDR,
41 	HWSIM_CMD_DEL_MAC_ADDR,
42 	HWSIM_CMD_START_PMSR,
43 	HWSIM_CMD_ABORT_PMSR,
44 	HWSIM_CMD_REPORT_PMSR,
45 	__HWSIM_CMD_MAX,
46 };
47 #define HWSIM_CMD_MAX (_HWSIM_CMD_MAX - 1)
48 
49 /**
50  * enum hwsim_attrs - hwsim netlink attributes
51  *
52  * @HWSIM_ATTR_UNSPEC: unspecified attribute to catch errors
53  *
54  * @HWSIM_ATTR_ADDR_RECEIVER: MAC address of the radio device that
55  *	the frame is broadcasted to
56  * @HWSIM_ATTR_ADDR_TRANSMITTER: MAC address of the radio device that
57  *	the frame was broadcasted from
58  * @HWSIM_ATTR_FRAME: Data array
59  * @HWSIM_ATTR_FLAGS: mac80211 transmission flags, used to process
60 	properly the frame at user space
61  * @HWSIM_ATTR_RX_RATE: estimated rx rate index for this frame at user
62 	space
63  * @HWSIM_ATTR_SIGNAL: estimated RX signal for this frame at user
64 	space
65  * @HWSIM_ATTR_TX_INFO: ieee80211_tx_rate array
66  * @HWSIM_ATTR_COOKIE: sk_buff cookie to identify the frame
67  * @HWSIM_ATTR_CHANNELS: u32 attribute used with the %HWSIM_CMD_CREATE_RADIO
68  *	command giving the number of channels supported by the new radio
69  * @HWSIM_ATTR_RADIO_ID: u32 attribute used with %HWSIM_CMD_DESTROY_RADIO
70  *	only to destroy a radio
71  * @HWSIM_ATTR_REG_HINT_ALPHA2: alpha2 for regulatoro driver hint
72  *	(nla string, length 2)
73  * @HWSIM_ATTR_REG_CUSTOM_REG: custom regulatory domain index (u32 attribute)
74  * @HWSIM_ATTR_REG_STRICT_REG: request REGULATORY_STRICT_REG (flag attribute)
75  * @HWSIM_ATTR_SUPPORT_P2P_DEVICE: support P2P Device virtual interface (flag)
76  * @HWSIM_ATTR_USE_CHANCTX: used with the %HWSIM_CMD_CREATE_RADIO
77  *	command to force use of channel contexts even when only a
78  *	single channel is supported
79  * @HWSIM_ATTR_DESTROY_RADIO_ON_CLOSE: used with the %HWSIM_CMD_CREATE_RADIO
80  *	command to force radio removal when process that created the radio dies
81  * @HWSIM_ATTR_RADIO_NAME: Name of radio, e.g. phy666
82  * @HWSIM_ATTR_NO_VIF:  Do not create vif (wlanX) when creating radio.
83  * @HWSIM_ATTR_FREQ: Frequency at which packet is transmitted or received.
84  * @HWSIM_ATTR_TX_INFO_FLAGS: additional flags for corresponding
85  *	rates of %HWSIM_ATTR_TX_INFO
86  * @HWSIM_ATTR_PERM_ADDR: permanent mac address of new radio
87  * @HWSIM_ATTR_IFTYPE_SUPPORT: u32 attribute of supported interface types bits
88  * @HWSIM_ATTR_CIPHER_SUPPORT: u32 array of supported cipher types
89  * @HWSIM_ATTR_MLO_SUPPORT: claim MLO support (exact parameters TBD) for
90  *	the new radio
91  * @HWSIM_ATTR_PMSR_SUPPORT: claim peer measurement support
92  * @HWSIM_ATTR_PMSR_REQUEST: peer measurement request
93  * @HWSIM_ATTR_PMSR_RESULT: peer measurement result
94  * @__HWSIM_ATTR_MAX: enum limit
95  */
96 
97 
98 enum {
99 	HWSIM_ATTR_UNSPEC,
100 	HWSIM_ATTR_ADDR_RECEIVER,
101 	HWSIM_ATTR_ADDR_TRANSMITTER,
102 	HWSIM_ATTR_FRAME,
103 	HWSIM_ATTR_FLAGS,
104 	HWSIM_ATTR_RX_RATE,
105 	HWSIM_ATTR_SIGNAL,
106 	HWSIM_ATTR_TX_INFO,
107 	HWSIM_ATTR_COOKIE,
108 	HWSIM_ATTR_CHANNELS,
109 	HWSIM_ATTR_RADIO_ID,
110 	HWSIM_ATTR_REG_HINT_ALPHA2,
111 	HWSIM_ATTR_REG_CUSTOM_REG,
112 	HWSIM_ATTR_REG_STRICT_REG,
113 	HWSIM_ATTR_SUPPORT_P2P_DEVICE,
114 	HWSIM_ATTR_USE_CHANCTX,
115 	HWSIM_ATTR_DESTROY_RADIO_ON_CLOSE,
116 	HWSIM_ATTR_RADIO_NAME,
117 	HWSIM_ATTR_NO_VIF,
118 	HWSIM_ATTR_FREQ,
119 	HWSIM_ATTR_PAD,
120 	HWSIM_ATTR_TX_INFO_FLAGS,
121 	HWSIM_ATTR_PERM_ADDR,
122 	HWSIM_ATTR_IFTYPE_SUPPORT,
123 	HWSIM_ATTR_CIPHER_SUPPORT,
124 	HWSIM_ATTR_MLO_SUPPORT,
125 	HWSIM_ATTR_PMSR_SUPPORT,
126 	HWSIM_ATTR_PMSR_REQUEST,
127 	HWSIM_ATTR_PMSR_RESULT,
128 	__HWSIM_ATTR_MAX,
129 };
130 #define HWSIM_ATTR_MAX (__HWSIM_ATTR_MAX - 1)
131 
132 #define VERSION_NR 1
133 
134 #define SNR_DEFAULT 30
135 
136 #include <stdint.h>
137 #include <stdbool.h>
138 #include <syslog.h>
139 #include <usfstl/sched.h>
140 
141 #include "list.h"
142 #include "ieee80211.h"
143 
144 typedef uint8_t u8;
145 typedef uint32_t u32;
146 typedef uint64_t u64;
147 
148 #define TIME_FMT "%lld.%06lld"
149 #define TIME_ARGS(a) ((unsigned long long)(a)->tv_sec), ((unsigned long long)(a)->tv_nsec/1000)
150 
151 #define MAC_FMT "%02x:%02x:%02x:%02x:%02x:%02x"
152 #define MAC_ARGS(a) a[0],a[1],a[2],a[3],a[4],a[5]
153 
154 #ifndef min
155 #define min(x,y) ((x) < (y) ? (x) : (y))
156 #endif
157 
158 #define NOISE_LEVEL	(-91)
159 #define CCA_THRESHOLD	(-90)
160 
161 extern struct usfstl_scheduler scheduler;
162 
163 struct wqueue {
164 	struct list_head frames;
165 	int cw_min;
166 	int cw_max;
167 };
168 
169 struct addr {
170 	u8 addr[ETH_ALEN];
171 	uint16_t count;
172 };
173 
174 struct station {
175 	int index;
176 	u8 addr[ETH_ALEN];		/* virtual interface mac address */
177 	u8 hwaddr[ETH_ALEN];		/* hardware address of hwsim radio */
178 	double x, y;			/* position of the station [m] */
179 	char *lci;			/* LCI */
180 	char *civicloc;			/* CIVIC */
181 	double dir_x, dir_y;		/* direction of the station [meter per MOVE_INTERVAL] */
182 	int tx_power;			/* transmission power [dBm] */
183 	struct wqueue queues[IEEE80211_NUM_ACS];
184 	struct list_head list;
185 	struct client *client;
186 	unsigned int n_addrs;
187 	struct addr *addrs;
188 };
189 
190 enum client_type {
191 	CLIENT_NETLINK,
192 	CLIENT_VHOST_USER,
193 	CLIENT_API_SOCK,
194 };
195 
196 struct client {
197 	struct list_head list;
198 	enum client_type type;
199 
200 	/*
201 	 * There's no additional data for the netlink client, we
202 	 * just have it as such for the link from struct station.
203 	 */
204 
205 	/* for vhost-user */
206 	struct usfstl_vhost_user_dev *dev;
207 
208 	/* for API socket */
209 	struct usfstl_loop_entry loop;
210 	bool wait_for_ack;
211 
212 	u32 flags;
213 };
214 
215 struct wmediumd {
216 	int timerfd;
217 	int msq_id;
218 
219 	struct nl_sock *sock;
220 	struct usfstl_loop_entry nl_loop, grpc_loop;
221 
222 	struct usfstl_sched_ctrl *ctrl;
223 
224 	struct list_head clients, clients_to_free;
225 	struct client nl_client;
226 
227 	int num_stas;
228 	struct list_head stations;
229 	struct station **sta_array;
230 	int *snr_matrix;
231 	double *error_prob_matrix;
232 	struct intf_info *intf;
233 	struct usfstl_job intf_job, move_job;
234 #define MOVE_INTERVAL	(3) /* station movement interval [sec] */
235 	void *path_loss_param;
236 	float *per_matrix;
237 	int per_matrix_row_num;
238 	int per_matrix_signal_min;
239 	int fading_coefficient;
240 
241 	struct nl_cb *cb;
242 	int family_id;
243 
244 	int (*get_link_snr)(struct wmediumd *, struct station *,
245 			    struct station *);
246 	double (*get_error_prob)(struct wmediumd *, double, unsigned int, u32,
247 				 int, struct station *, struct station *);
248 	int (*calc_path_loss)(void *, struct station *,
249 			      struct station *);
250 	int (*get_fading_signal)(struct wmediumd *);
251 
252 	u8 log_lvl;
253 
254 	u32 need_start_notify;
255 
256 	FILE *pcap_file;
257 
258 	char *config_path;
259 };
260 
261 struct hwsim_tx_rate {
262 	signed char idx;
263 	unsigned char count;
264 };
265 
266 struct frame {
267 	struct list_head list;		/* frame queue list */
268 	struct usfstl_job job;
269 	struct usfstl_job start_job;
270 	struct client *src;
271 	bool acked;
272 	u64 cookie;
273 	u32 freq;
274 	int flags;
275 	int signal;
276 	int duration;
277 	int tx_rates_count;
278 	struct station *sender;
279 	struct hwsim_tx_rate tx_rates[IEEE80211_TX_MAX_RATES];
280 	size_t data_len;
281 	u8 data[0];			/* frame contents */
282 };
283 
284 struct log_distance_model_param {
285 	double path_loss_exponent;
286 	double Xg;
287 };
288 
289 struct itu_model_param {
290 	int nFLOORS;
291 	int LF;
292 };
293 
294 struct intf_info {
295 	int signal;
296 	int duration;
297 	double prob_col;
298 };
299 
300 void station_init_queues(struct station *station);
301 double get_error_prob_from_snr(double snr, unsigned int rate_idx, u32 freq,
302 			       int frame_len);
303 int set_default_per(struct wmediumd *ctx);
304 int read_per_file(struct wmediumd *ctx, const char *file_name);
305 int w_logf(struct wmediumd *ctx, u8 level, const char *format, ...);
306 int w_flogf(struct wmediumd *ctx, u8 level, FILE *stream, const char *format, ...);
307 int index_to_rate(size_t index, u32 freq);
308 int get_max_index(void);
309 
310 #ifdef __cplusplus
311 extern "C" {
312 #endif
313 
314 int wmediumd_main(int argc, char *argv[], int event_fd, int msq_id);
315 
316 #ifdef __cplusplus
317 }
318 #endif
319 
320 #endif /* WMEDIUMD_H_ */
321