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_MAX, 43 }; 44 #define HWSIM_CMD_MAX (_HWSIM_CMD_MAX - 1) 45 46 /** 47 * enum hwsim_attrs - hwsim netlink attributes 48 * 49 * @HWSIM_ATTR_UNSPEC: unspecified attribute to catch errors 50 * 51 * @HWSIM_ATTR_ADDR_RECEIVER: MAC address of the radio device that 52 * the frame is broadcasted to 53 * @HWSIM_ATTR_ADDR_TRANSMITTER: MAC address of the radio device that 54 * the frame was broadcasted from 55 * @HWSIM_ATTR_FRAME: Data array 56 * @HWSIM_ATTR_FLAGS: mac80211 transmission flags, used to process 57 properly the frame at user space 58 * @HWSIM_ATTR_RX_RATE: estimated rx rate index for this frame at user 59 space 60 * @HWSIM_ATTR_SIGNAL: estimated RX signal for this frame at user 61 space 62 * @HWSIM_ATTR_TX_INFO: ieee80211_tx_rate array 63 * @HWSIM_ATTR_COOKIE: sk_buff cookie to identify the frame 64 * @HWSIM_ATTR_CHANNELS: u32 attribute used with the %HWSIM_CMD_CREATE_RADIO 65 * command giving the number of channels supported by the new radio 66 * @HWSIM_ATTR_RADIO_ID: u32 attribute used with %HWSIM_CMD_DESTROY_RADIO 67 * only to destroy a radio 68 * @HWSIM_ATTR_REG_HINT_ALPHA2: alpha2 for regulatoro driver hint 69 * (nla string, length 2) 70 * @HWSIM_ATTR_REG_CUSTOM_REG: custom regulatory domain index (u32 attribute) 71 * @HWSIM_ATTR_REG_STRICT_REG: request REGULATORY_STRICT_REG (flag attribute) 72 * @HWSIM_ATTR_SUPPORT_P2P_DEVICE: support P2P Device virtual interface (flag) 73 * @HWSIM_ATTR_USE_CHANCTX: used with the %HWSIM_CMD_CREATE_RADIO 74 * command to force use of channel contexts even when only a 75 * single channel is supported 76 * @HWSIM_ATTR_DESTROY_RADIO_ON_CLOSE: used with the %HWSIM_CMD_CREATE_RADIO 77 * command to force radio removal when process that created the radio dies 78 * @HWSIM_ATTR_RADIO_NAME: Name of radio, e.g. phy666 79 * @HWSIM_ATTR_NO_VIF: Do not create vif (wlanX) when creating radio. 80 * @HWSIM_ATTR_FREQ: Frequency at which packet is transmitted or received. 81 * @__HWSIM_ATTR_MAX: enum limit 82 */ 83 84 85 enum { 86 HWSIM_ATTR_UNSPEC, 87 HWSIM_ATTR_ADDR_RECEIVER, 88 HWSIM_ATTR_ADDR_TRANSMITTER, 89 HWSIM_ATTR_FRAME, 90 HWSIM_ATTR_FLAGS, 91 HWSIM_ATTR_RX_RATE, 92 HWSIM_ATTR_SIGNAL, 93 HWSIM_ATTR_TX_INFO, 94 HWSIM_ATTR_COOKIE, 95 HWSIM_ATTR_CHANNELS, 96 HWSIM_ATTR_RADIO_ID, 97 HWSIM_ATTR_REG_HINT_ALPHA2, 98 HWSIM_ATTR_REG_CUSTOM_REG, 99 HWSIM_ATTR_REG_STRICT_REG, 100 HWSIM_ATTR_SUPPORT_P2P_DEVICE, 101 HWSIM_ATTR_USE_CHANCTX, 102 HWSIM_ATTR_DESTROY_RADIO_ON_CLOSE, 103 HWSIM_ATTR_RADIO_NAME, 104 HWSIM_ATTR_NO_VIF, 105 HWSIM_ATTR_FREQ, 106 HWSIM_ATTR_PAD, 107 __HWSIM_ATTR_MAX, 108 }; 109 #define HWSIM_ATTR_MAX (__HWSIM_ATTR_MAX - 1) 110 111 #define VERSION_NR 1 112 113 #define SNR_DEFAULT 30 114 115 #include <stdint.h> 116 #include <stdbool.h> 117 #include <syslog.h> 118 #include <usfstl/sched.h> 119 120 #include "list.h" 121 #include "ieee80211.h" 122 123 typedef uint8_t u8; 124 typedef uint32_t u32; 125 typedef uint64_t u64; 126 127 #define TIME_FMT "%lld.%06lld" 128 #define TIME_ARGS(a) ((unsigned long long)(a)->tv_sec), ((unsigned long long)(a)->tv_nsec/1000) 129 130 #define MAC_FMT "%02x:%02x:%02x:%02x:%02x:%02x" 131 #define MAC_ARGS(a) a[0],a[1],a[2],a[3],a[4],a[5] 132 133 #ifndef min 134 #define min(x,y) ((x) < (y) ? (x) : (y)) 135 #endif 136 137 #define NOISE_LEVEL (-91) 138 #define CCA_THRESHOLD (-90) 139 140 extern struct usfstl_scheduler scheduler; 141 142 struct wqueue { 143 struct list_head frames; 144 int cw_min; 145 int cw_max; 146 }; 147 148 struct addr { 149 u8 addr[ETH_ALEN]; 150 }; 151 152 struct station { 153 int index; 154 u8 addr[ETH_ALEN]; /* virtual interface mac address */ 155 u8 hwaddr[ETH_ALEN]; /* hardware address of hwsim radio */ 156 double x, y; /* position of the station [m] */ 157 double dir_x, dir_y; /* direction of the station [meter per MOVE_INTERVAL] */ 158 int tx_power; /* transmission power [dBm] */ 159 struct wqueue queues[IEEE80211_NUM_ACS]; 160 struct list_head list; 161 struct client *client; 162 unsigned int n_addrs; 163 struct addr *addrs; 164 }; 165 166 enum client_type { 167 CLIENT_NETLINK, 168 CLIENT_VHOST_USER, 169 CLIENT_API_SOCK, 170 }; 171 172 struct client { 173 struct list_head list; 174 enum client_type type; 175 176 /* 177 * There's no additional data for the netlink client, we 178 * just have it as such for the link from struct station. 179 */ 180 181 /* for vhost-user */ 182 struct usfstl_vhost_user_dev *dev; 183 184 /* for API socket */ 185 struct usfstl_loop_entry loop; 186 bool wait_for_ack; 187 188 u32 flags; 189 }; 190 191 struct wmediumd { 192 int timerfd; 193 194 struct nl_sock *sock; 195 struct usfstl_loop_entry nl_loop; 196 197 struct usfstl_sched_ctrl *ctrl; 198 199 struct list_head clients, clients_to_free; 200 struct client nl_client; 201 202 int num_stas; 203 struct list_head stations; 204 struct station **sta_array; 205 int *snr_matrix; 206 double *error_prob_matrix; 207 struct intf_info *intf; 208 struct usfstl_job intf_job, move_job; 209 #define MOVE_INTERVAL (3) /* station movement interval [sec] */ 210 void *path_loss_param; 211 float *per_matrix; 212 int per_matrix_row_num; 213 int per_matrix_signal_min; 214 int fading_coefficient; 215 216 struct nl_cb *cb; 217 int family_id; 218 219 int (*get_link_snr)(struct wmediumd *, struct station *, 220 struct station *); 221 double (*get_error_prob)(struct wmediumd *, double, unsigned int, u32, 222 int, struct station *, struct station *); 223 int (*calc_path_loss)(void *, struct station *, 224 struct station *); 225 int (*get_fading_signal)(struct wmediumd *); 226 227 u8 log_lvl; 228 229 u32 need_start_notify; 230 231 FILE *pcap_file; 232 233 char *config_path; 234 }; 235 236 struct hwsim_tx_rate { 237 signed char idx; 238 unsigned char count; 239 }; 240 241 struct frame { 242 struct list_head list; /* frame queue list */ 243 struct usfstl_job job; 244 struct usfstl_job start_job; 245 struct client *src; 246 bool acked; 247 u64 cookie; 248 u32 freq; 249 int flags; 250 int signal; 251 int duration; 252 int tx_rates_count; 253 struct station *sender; 254 struct hwsim_tx_rate tx_rates[IEEE80211_TX_MAX_RATES]; 255 size_t data_len; 256 u8 data[0]; /* frame contents */ 257 }; 258 259 struct log_distance_model_param { 260 double path_loss_exponent; 261 double Xg; 262 }; 263 264 struct itu_model_param { 265 int nFLOORS; 266 int LF; 267 }; 268 269 struct intf_info { 270 int signal; 271 int duration; 272 double prob_col; 273 }; 274 275 void station_init_queues(struct station *station); 276 double get_error_prob_from_snr(double snr, unsigned int rate_idx, u32 freq, 277 int frame_len); 278 int set_default_per(struct wmediumd *ctx); 279 int read_per_file(struct wmediumd *ctx, const char *file_name); 280 int w_logf(struct wmediumd *ctx, u8 level, const char *format, ...); 281 int w_flogf(struct wmediumd *ctx, u8 level, FILE *stream, const char *format, ...); 282 int index_to_rate(size_t index, u32 freq); 283 int get_max_index(void); 284 285 #endif /* WMEDIUMD_H_ */ 286