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 <[email protected]> 7 * Javier Cardona <[email protected]> 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 <pthread.h> 137 #include <stdint.h> 138 #include <stdbool.h> 139 #include <syslog.h> 140 #include <usfstl/sched.h> 141 142 #include "list.h" 143 #include "ieee80211.h" 144 145 typedef uint8_t u8; 146 typedef uint32_t u32; 147 typedef uint64_t u64; 148 149 #define TIME_FMT "%lld.%06lld" 150 #define TIME_ARGS(a) ((unsigned long long)(a)->tv_sec), ((unsigned long long)(a)->tv_nsec/1000) 151 152 #define MAC_FMT "%02x:%02x:%02x:%02x:%02x:%02x" 153 #define MAC_ARGS(a) a[0]&0xff,a[1]&0xff,a[2]&0xff,a[3]&0xff,a[4]&0xff,a[5]&0xff 154 155 #ifndef min 156 #define min(x,y) ((x) < (y) ? (x) : (y)) 157 #endif 158 159 #define NOISE_LEVEL (-91) 160 #define CCA_THRESHOLD (-90) 161 162 extern struct usfstl_scheduler scheduler; 163 164 struct wqueue { 165 struct list_head frames; 166 int cw_min; 167 int cw_max; 168 }; 169 170 struct addr { 171 u8 addr[ETH_ALEN]; 172 uint16_t count; 173 }; 174 175 struct station { 176 int index; 177 u8 addr[ETH_ALEN]; /* virtual interface mac address */ 178 u8 hwaddr[ETH_ALEN]; /* hardware address of hwsim radio */ 179 double x, y; /* position of the station [m] */ 180 char *lci; /* LCI */ 181 char *civicloc; /* CIVIC */ 182 double dir_x, dir_y; /* direction of the station [meter per MOVE_INTERVAL] */ 183 int tx_power; /* transmission power [dBm] */ 184 struct wqueue queues[IEEE80211_NUM_ACS]; 185 struct list_head list; 186 struct client *client; 187 unsigned int n_addrs; 188 struct addr *addrs; 189 }; 190 191 enum client_type { 192 CLIENT_NETLINK, 193 CLIENT_VHOST_USER, 194 CLIENT_API_SOCK, 195 }; 196 197 struct client { 198 struct list_head list; 199 enum client_type type; 200 201 /* 202 * There's no additional data for the netlink client, we 203 * just have it as such for the link from struct station. 204 */ 205 206 /* for vhost-user */ 207 struct usfstl_vhost_user_dev *dev; 208 209 /* for API socket */ 210 struct usfstl_loop_entry loop; 211 bool wait_for_ack; 212 213 u32 flags; 214 }; 215 216 struct wmediumd { 217 int timerfd; 218 int msq_id; 219 220 struct nl_sock *sock; 221 struct usfstl_loop_entry nl_loop, grpc_loop; 222 223 struct usfstl_sched_ctrl *ctrl; 224 225 struct list_head clients, clients_to_free; 226 struct client nl_client; 227 228 int num_stas; 229 struct list_head stations; 230 struct station **sta_array; 231 int *snr_matrix; 232 double *error_prob_matrix; 233 struct intf_info *intf; 234 struct usfstl_job intf_job, move_job; 235 #define MOVE_INTERVAL (3) /* station movement interval [sec] */ 236 void *path_loss_param; 237 float *per_matrix; 238 int per_matrix_row_num; 239 int per_matrix_signal_min; 240 int fading_coefficient; 241 242 struct nl_cb *cb; 243 int family_id; 244 245 int (*get_link_snr)(struct wmediumd *, struct station *, 246 struct station *); 247 double (*get_error_prob)(struct wmediumd *, double, unsigned int, u32, 248 int, struct station *, struct station *); 249 int (*calc_path_loss)(void *, struct station *, 250 struct station *); 251 int (*get_fading_signal)(struct wmediumd *); 252 253 u8 log_lvl; 254 255 u32 need_start_notify; 256 257 FILE *pcap_file; 258 259 char *config_path; 260 261 // data_transfer_thread and data_transfer_direction are undefined when 262 // data_transfer_fd is invalid (-1). 263 int data_transfer_fd; 264 uint32_t data_transfer_direction; 265 pthread_t data_transfer_thread; 266 }; 267 268 struct hwsim_tx_rate { 269 signed char idx; 270 unsigned char count; 271 }; 272 273 struct frame { 274 struct list_head list; /* frame queue list */ 275 struct usfstl_job job; 276 struct usfstl_job start_job; 277 struct client *src; 278 bool acked; 279 u64 cookie; 280 u32 freq; 281 int flags; 282 int signal; 283 int duration; 284 int tx_rates_count; 285 struct station *sender; 286 struct hwsim_tx_rate tx_rates[IEEE80211_TX_MAX_RATES]; 287 size_t data_len; 288 u8 data[0]; /* frame contents */ 289 }; 290 291 struct log_distance_model_param { 292 double path_loss_exponent; 293 double Xg; 294 }; 295 296 struct itu_model_param { 297 int nFLOORS; 298 int LF; 299 }; 300 301 struct intf_info { 302 int signal; 303 int duration; 304 double prob_col; 305 }; 306 307 void station_init_queues(struct station *station); 308 double get_error_prob_from_snr(double snr, unsigned int rate_idx, u32 freq, 309 int frame_len); 310 int set_default_per(struct wmediumd *ctx); 311 int read_per_file(struct wmediumd *ctx, const char *file_name); 312 int w_logf(struct wmediumd *ctx, u8 level, const char *format, ...); 313 int w_flogf(struct wmediumd *ctx, u8 level, FILE *stream, const char *format, ...); 314 int index_to_rate(size_t index, u32 freq); 315 int get_max_index(void); 316 317 #ifdef __cplusplus 318 extern "C" { 319 #endif 320 321 int wmediumd_main(int argc, char *argv[], int event_fd, int msq_id); 322 323 #ifdef __cplusplus 324 } 325 #endif 326 327 #endif /* WMEDIUMD_H_ */ 328