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