• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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