1 /* 2 * Copyright (c) 2021 Chipsea Technologies (Shenzhen) Corp., Ltd. All rights reserved. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 #ifndef _WIFI_HOST_IPERF_H 16 #define _WIFI_HOST_IPERF_H 17 18 #include "wb_co_int.h" 19 #include "wb_co_bool.h" 20 #include "lwip/sockets.h" 21 22 #if PLF_IPERF 23 /// Maximum number of iperf streams 24 #define FHOST_IPERF_MAX_STREAMS 1 25 26 /// UDP Rate 27 #define FHOST_IPERF_DEFAULT_UDPRATE 1024 * 1024 // 1 Mbit/sec (-u) 28 /// UDP buffer length 29 #define FHOST_IPERF_DEFAULT_UDPBUFLEN 1470 // read/write 1470 bytes (-u) 30 /// Invalid socket id 31 #define FHOST_IPERF_INVALID_SOCKET -1 32 /// Time to travel 33 #define FHOST_IPERF_TTL 1 34 /// Number of IPERF send buffers (credits) 35 #define FHOST_IPERF_SEND_BUF_CNT 8 36 37 /// Type of traffic generation 38 enum test_mode 39 { 40 /// Unidirectional test 41 FHOST_IPERF_TEST_NORMAL = 0, 42 /// Bidirectional test simultaneously 43 FHOST_IPERF_TEST_DUALTEST, 44 /// Unkwnow test mode 45 FHOST_IPERF_TEST_UNKNOWN 46 }; 47 48 /* 49 * TYPE DEFINITIONS 50 **************************************************************************************** 51 */ 52 53 /// Datagram for UDP packets 54 struct iperf_UDP_datagram 55 { 56 /// Datagram ID 57 int32_t id; 58 /// Sending time (seconds) 59 uint32_t sec; 60 /// Sending time (microseconds) 61 uint32_t usec; 62 }; 63 64 /// Iperf timer 65 struct iperf_time 66 { 67 /// Second 68 uint32_t sec; 69 /// Microsecond 70 uint32_t usec; 71 }; 72 73 /// Iperf configuration flags 74 struct fhost_iperf_flags 75 { 76 /// Command option: buffer len option set (-l) 77 bool is_buf_len_set :1; 78 /// Command option: udp mode enable (-u) 79 bool is_udp :1; 80 /// Command option: time mode option set (-t) 81 bool is_time_mode :1; 82 /// Command option: bandwidth option set (-b) 83 bool is_bw_set :1; 84 /// Command option: server mode enable (-s) 85 bool is_server :1; 86 /// Command option: peer version detect option set(-X) 87 bool is_peer_ver :1; 88 }; 89 90 /// Iperf configuration 91 struct fhost_iperf_settings 92 { 93 /// Iperf server IP (-c) 94 uint32_t host_ip; 95 /// Iperf UDP buffer length (-l) 96 uint32_t buf_len; 97 /// Iperf test mode 98 enum test_mode test_mode; 99 /// Iperf printing format (-f): Possible values are: 'a', 'A', 'b', 'B', 'k', 'K', 'g', 'G' 100 char format; 101 /// Iperf TCP client listen port (-L) 102 uint16_t listen_port; 103 /// Iperf server port (-p) 104 uint16_t port; 105 /// IP type-of-service (-S) 106 uint16_t tos; 107 /// Time to live (-T) 108 uint16_t ttl; 109 /// Iperf udp rate (-b) 110 uint64_t udprate; 111 /// Iperf amount of data to send 112 uint64_t amount; 113 /// Iperf interval 114 struct iperf_time interval; 115 /// Setting flags 116 struct fhost_iperf_flags flags; 117 }; 118 119 /// Iperf statistics 120 struct iperf_stats 121 { 122 /// Transferred bytes 123 uint64_t bytes; 124 /// Number of transferred datagrams 125 uint32_t nb_datagrams; 126 /// Number of errors 127 uint32_t nb_error; 128 /// Number of out of order datagrams 129 uint32_t nb_out_of_orded; 130 /// Jitter in microseconds 131 uint32_t jitter_us; 132 }; 133 134 /// Report for TCP and UDP client/server 135 struct iperf_report 136 { 137 /// Packet ID 138 int32_t packet_id; 139 /// Current statistics 140 struct iperf_stats stats; 141 /// Statistics at the last interval 142 struct iperf_stats last_stats; 143 /// Timestamp of the last sent/received packet 144 struct iperf_time packet_time; 145 /// Timestamp of the first packet 146 struct iperf_time start_time; 147 /// End of reception/transmission time 148 struct iperf_time end_time; 149 /// Sending time included in the received UDP datagram 150 struct iperf_time sent_time; 151 /// Transit time (RX time - TX time) of last received UDP datagram 152 struct iperf_time last_transit; 153 /// Last interval time 154 struct iperf_time last_interval; 155 /// Target interval timestamp 156 struct iperf_time interval_target; 157 /// UDP client IP address 158 ip_addr_t addr; 159 /// UDP client port 160 u16_t port; 161 }; 162 163 /// Iperf stream related info 164 struct fhost_iperf_stream 165 { 166 /// Ping thread ID 167 uint32_t id; 168 /// State of ping thread (true for active, false for inactive) 169 bool active; 170 /// Iperf settings 171 struct fhost_iperf_settings iperf_settings; 172 /// Handle of iperf send task 173 rtos_task_handle iperf_handle; 174 /// Iperf semaphore used to wake up the iperf thread to close the task 175 rtos_semaphore iperf_task_semaphore; 176 /// Semaphore used to protect Iperf buffer pool 177 rtos_semaphore send_buf_semaphore; 178 /// Iperf timeout semaphore 179 rtos_semaphore to_semaphore; 180 /// Iperf mutex used when we modify the credits for sending process 181 rtos_mutex iperf_mutex; 182 /// Param pointer for NET IPERF AL 183 void *arg; 184 /// TCP/UDP report 185 struct iperf_report report; 186 }; 187 188 /* Macros for timers */ 189 190 /// Timer addition 191 #define iperf_timeradd(a, b, result) \ 192 (result)->sec = (a)->sec + (b)->sec; \ 193 (result)->usec = (a)->usec + (b)->usec; \ 194 while ((result)->usec > 1000000) \ 195 { \ 196 (result)->usec -= 1000000; \ 197 (result)->sec++; \ 198 } 199 200 /// Timer subtraction 201 #define iperf_timersub(a, b, result) \ 202 do { \ 203 int32_t usec; \ 204 (result)->sec = (a)->sec - (b)->sec; \ 205 usec = (a)->usec - (b)->usec; \ 206 (result)->usec = usec; \ 207 if (usec < 0) { \ 208 --(result)->sec; \ 209 (result)->usec = usec + 1000000; \ 210 } \ 211 } while (0) 212 213 /// Check if timer a is before timer b 214 #define iperf_timerbefore(a, b) \ 215 (((a)->sec < (b)->sec) || \ 216 ((a)->sec == (b)->sec && \ 217 (a)->usec < (b)->usec)) 218 219 /// Check if timer a is after timer b 220 #define iperf_after(a, b) iperf_timerbefore(b, a) 221 222 /// Extract timer seconds 223 #define iperf_timersec(a) ((a)->sec + ((a)->usec / 1000000)) 224 225 /// Extract timer microseconds 226 #define iperf_timerusec(a) (((a)->sec * 1000000) + (a)->usec) 227 228 /// Extract timer microseconds 229 #define iperf_timermsec(a) (((a)->sec * 1000) + (a)->usec / 1000) 230 231 /* 232 * GLOBAL VARIABLES 233 **************************************************************************************** 234 */ 235 extern const char iperf_short_help[], iperf_long_help[]; 236 extern struct fhost_iperf_stream i_streams[FHOST_IPERF_MAX_STREAMS]; 237 238 /* 239 * FUNCTIONS 240 **************************************************************************************** 241 */ 242 243 /** 244 **************************************************************************************** 245 * @brief Initialize iperf settings 246 * 247 * @param[in] iperf_settings Pointer to iperf settings to initialize 248 **************************************************************************************** 249 **/ 250 void fhost_iperf_settings_init(struct fhost_iperf_settings *iperf_settings); 251 252 /** 253 **************************************************************************************** 254 * @brief Start iperf command with certain configuration options 255 * This function creates the RTOS task dedicated to the iperf command. 256 * 257 * @param[in] args Iperf configuration pointer 258 * @param[out] args task handle of the created task 259 * 260 * @return 261 **************************************************************************************** 262 */ 263 int fhost_iperf_start(void *args, rtos_task_handle *handle); 264 265 /** 266 **************************************************************************************** 267 * @brief Print interval statistics for UDP client 268 * 269 * @param[in] stream Pointer to iperf stream 270 **************************************************************************************** 271 **/ 272 void fhost_iperf_udp_print_interv_stats(struct fhost_iperf_stream *stream); 273 274 /** 275 **************************************************************************************** 276 * @brief Print iperf statistics with a different format for TCP/UDP Server and Client. 277 * Statistics are printed in the task buffer. 278 * 279 * @param[in] stream Pointer to iperf stream 280 * @param[in] start_time Pointer to beginning time 281 * @param[in] end_time Pointer to ending time 282 * @param[in] stats Pointer to statistics 283 **************************************************************************************** 284 **/ 285 void fhost_iperf_print_stats(const struct fhost_iperf_stream *stream, 286 struct iperf_time *start_time, 287 struct iperf_time *end_time, 288 const struct iperf_stats *stats); 289 290 /** 291 **************************************************************************************** 292 * @brief Iperf sigkill handler. Closes TCP/UDP Server and Client connection. 293 * 294 * @param[in] iperf_handle Iperf task handle 295 * 296 * @return FHOST_IPC_SUCCESS if successful, FHOST_IPC_ERROR otherwise 297 **************************************************************************************** 298 **/ 299 int fhost_iperf_sigkill_handler(rtos_task_handle iperf_handle); 300 301 #endif /* PLF_PING */ 302 303 #endif // _WIFI_HOST_IPERF_H 304