28#include "lwip/sockets.h"
30#include "lwip/netdb.h"
41#define IPERF_HUNDRED 100
55static void socket_recv(
int recv_socket,
struct sockaddr *listen_addr, uint8_t type);
56static void socket_send(
int send_socket,
struct sockaddr *dest_addr, uint8_t type,
int bw_lim);
69static const char *
TAG =
"iperf";
73#define XF_ASSERT_RET_GOTO(condition, err_code, label, tag, format, ...) \
76 XF_ASSERT_GOTO(condition, label, tag, format, ##__VA_ARGS__); \
100 XF_LOGE(
TAG,
"create buffer: not enough memory");
133 XF_LOGI(
TAG,
"wait current iperf to stop ...");
180 XF_LOGW(
TAG,
"%s error, error code: %d, reason: %s",
181 str, err, strerror(err));
194 uint32_t delay_interval_ms = interval * 1000;
197 float actual_bandwidth = 0;
212 actual_bandwidth = ((float)(
s_ctx.
actual_len * 8) / 1e6f) / (
float)interval;
216 average = ((average * (k - 1) / k) + (actual_bandwidth / k));
227 (
int)cur, (
int)(cur + interval),
274static void socket_recv(
int recv_socket,
struct sockaddr *listen_addr, uint8_t type)
276 bool iperf_recv_start =
true;
281 ?
sizeof(
struct sockaddr_in6)
282 :
sizeof(
struct sockaddr_in);
292 actual_recv = recvfrom(recv_socket, buffer, want_recv, 0, listen_addr, &socklen);
293 if (actual_recv >= 0) {
294 if (iperf_recv_start) {
296 iperf_recv_start =
false;
308static void socket_send(
int send_socket,
struct sockaddr *dest_addr, uint8_t type,
int bw_lim)
312 uint32_t pkt_cnt = 0;
321 ?
sizeof(
struct sockaddr_in6)
322 :
sizeof(
struct sockaddr_in);
333 period_us = want_send * 8 / bw_lim;
339 if (actual_send > 0) {
342 delay_us += period_us + (int32_t)(prev_time - send_time);
350 prev_time = send_time;
352 *pkt_id_p = htonl(pkt_cnt++);
353 actual_send = sendto(send_socket, buffer, want_send, 0, dest_addr, socklen);
354 if (actual_send != want_send) {
377 int listen_socket = -1;
378 int client_socket = -1;
382 struct sockaddr_in remote_addr;
383 struct timeval timeout = { 0 };
384 socklen_t addr_len =
sizeof(
struct sockaddr);
385 struct sockaddr *listen_addr = NULL;
386 struct sockaddr_in6 listen_addr6 = { 0 };
387 struct sockaddr_in listen_addr4 = { 0 };
394 inet6_aton(
"::", &listen_addr6.sin6_addr);
395 listen_addr6.sin6_family = AF_INET6;
398 listen_socket = socket(AF_INET6, SOCK_STREAM, IPPROTO_IPV6);
401 setsockopt(listen_socket, SOL_SOCKET, SO_REUSEADDR, &opt,
sizeof(opt));
402 setsockopt(listen_socket, IPPROTO_IPV6, IPV6_V6ONLY, &opt,
sizeof(opt));
406 err = bind(listen_socket, (
struct sockaddr *)&listen_addr6,
sizeof(listen_addr6));
408 err = listen(listen_socket, 1);
413 setsockopt(listen_socket, SOL_SOCKET, SO_RCVTIMEO, &timeout,
sizeof(timeout));
415 listen_addr = (
struct sockaddr *)&listen_addr6;
417 listen_addr4.sin_family = AF_INET;
421 listen_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
424 setsockopt(listen_socket, SOL_SOCKET, SO_REUSEADDR, &opt,
sizeof(opt));
428 err = bind(listen_socket, (
struct sockaddr *)&listen_addr4,
sizeof(listen_addr4));
431 err = listen(listen_socket, 5);
434 listen_addr = (
struct sockaddr *)&listen_addr4;
437 client_socket = accept(listen_socket, (
struct sockaddr *)&remote_addr, &addr_len);
439 XF_LOGI(
TAG,
"accept: %s,%d\n", inet_ntoa(remote_addr.sin_addr), htons(remote_addr.sin_port));
443 setsockopt(client_socket, SOL_SOCKET, SO_RCVTIMEO, &timeout,
sizeof(timeout));
447 if (client_socket != -1) {
448 shutdown(client_socket, SHUT_RDWR);
449 closesocket(client_socket);
452 if (listen_socket != -1) {
453 shutdown(listen_socket, SHUT_RDWR);
454 closesocket(listen_socket);
463 int client_socket = -1;
466 struct sockaddr *dest_addr = NULL;
467 struct sockaddr_in6 dest_addr6 = { 0 };
468 struct sockaddr_in dest_addr4 = { 0 };
474 client_socket = socket(AF_INET6, SOCK_STREAM, IPPROTO_IPV6);
478 dest_addr6.sin6_family = AF_INET6;
481 err = connect(client_socket, (
struct sockaddr *)&dest_addr6,
sizeof(
struct sockaddr_in6));
485 dest_addr = (
struct sockaddr *)&dest_addr6;
487 client_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
490 dest_addr4.sin_family = AF_INET;
494 err = connect(client_socket, (
struct sockaddr *)&dest_addr4,
sizeof(
struct sockaddr_in));
498 dest_addr = (
struct sockaddr *)&dest_addr4;
503 if (client_socket != -1) {
504 shutdown(client_socket, SHUT_RDWR);
505 closesocket(client_socket);
514 int listen_socket = -1;
518 struct timeval timeout = { 0 };
519 struct sockaddr *listen_addr = NULL;
520 struct sockaddr_in6 listen_addr6 = { 0 };
521 struct sockaddr_in listen_addr4 = { 0 };
528 inet6_aton(
"::", &listen_addr6.sin6_addr);
529 listen_addr6.sin6_family = AF_INET6;
532 listen_socket = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
536 setsockopt(listen_socket, SOL_SOCKET, SO_REUSEADDR, &opt,
sizeof(opt));
538 err = bind(listen_socket, (
struct sockaddr *)&listen_addr6,
sizeof(
struct sockaddr_in6));
540 XF_LOGI(
TAG,
"Socket bound, port %d", listen_addr6.sin6_port);
542 listen_addr = (
struct sockaddr *)&listen_addr6;
544 listen_addr4.sin_family = AF_INET;
548 listen_socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
552 setsockopt(listen_socket, SOL_SOCKET, SO_REUSEADDR, &opt,
sizeof(opt));
554 err = bind(listen_socket, (
struct sockaddr *)&listen_addr4,
sizeof(
struct sockaddr_in));
556 XF_LOGI(
TAG,
"Socket bound, port %d", listen_addr4.sin_port);
558 listen_addr = (
struct sockaddr *)&listen_addr4;
563 timeout.tv_usec = 1000;
564 setsockopt(listen_socket, SOL_SOCKET, SO_RCVTIMEO, &timeout,
sizeof(timeout));
568 if (listen_socket != -1) {
569 shutdown(listen_socket, SHUT_RDWR);
570 closesocket(listen_socket);
579 int client_socket = -1;
582 struct sockaddr *dest_addr = NULL;
583 struct sockaddr_in6 dest_addr6 = { 0 };
584 struct sockaddr_in dest_addr4 = { 0 };
591 dest_addr6.sin6_family = AF_INET6;
594 client_socket = socket(AF_INET6, SOCK_DGRAM, IPPROTO_IPV6);
599 setsockopt(client_socket, SOL_SOCKET, SO_REUSEADDR, &opt,
sizeof(opt));
601 dest_addr = (
struct sockaddr *)&dest_addr6;
603 dest_addr4.sin_family = AF_INET;
607 client_socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
612 setsockopt(client_socket, SOL_SOCKET, SO_REUSEADDR, &opt,
sizeof(opt));
614 dest_addr = (
struct sockaddr *)&dest_addr4;
619 if (client_socket != -1) {
620 shutdown(client_socket, SHUT_RDWR);
621 closesocket(client_socket);
652#ifdef CONFIG_XF_NET_APPS_ENABLE_IPV6
#define XF_IPV62STR(ipaddr)
#define XF_IP2STR(ipaddr)
xf_err_t xf_iperf_start(const xf_iperf_cfg_t *p_cfg, xf_iperf_cb_t cb_func, void *user_args)
启动 iperf.
#define IPERF_DEFAULT_IPV6_UDP_TX_LEN
#define IPERF_TRAFFIC_TASK_NAME
void(* xf_iperf_cb_t)(xf_iperf_event_id_t event_id, xf_iperf_t hdl, void *user_args)
iperf 回调函数原型。
#define IPERF_DEFAULT_UDP_RX_LEN
#define IPERF_TRANS_TYPE_TCP
#define IPERF_DEFAULT_TCP_RX_LEN
#define IPERF_DEFAULT_IPV4_UDP_TX_LEN
#define IPERF_FLAG_SERVER
#define IPERF_SOCKET_RX_TIMEOUT_MS
#define IPERF_FLAG_CLIENT
#define IPERF_DEFAULT_TCP_TX_LEN
#define IPERF_IP_TYPE_IPV6
#define IPERF_IP_TYPE_IPV4
bool xf_iperf_is_running(void)
检查 iperf 是否正在运行。
xf_err_t xf_iperf_stop(void)
停止 iperf.
#define IPERF_REPORT_TASK_NAME
#define IPERF_TRANS_TYPE_UDP
xf_err_t xf_osal_thread_delete(xf_osal_thread_t thread)
终止线程的执行。
xf_osal_thread_t xf_osal_thread_create(xf_osal_thread_func_t func, void *argument, const xf_osal_thread_attr_t *attr)
创建一个线程并将其添加到活动线程中。
xf_err_t xf_osal_delay_ms(uint32_t ms)
(睡眠)等待超时,以 ms 为单位。
xf_us_t xf_sys_time_get_us(void)
获取系统时间的时间戳,单位微秒(us)
xf_err_t xf_delay_us(xf_us_t n_us)
微秒级延时
int32_t xf_err_t
整形错误类型。 错误码具体值见 xf_err_code_t.
#define xf_memset(ptr, value, size)
#define xf_memcpy(dest, src, n)
union _xf_ip_addr::@10 u_addr
uint32_t traffic_task_prio
uint32_t report_task_stack_size
uint32_t report_task_prio
uint32_t traffic_task_stack_size
xf_osal_thread_t report_task_hdl
xf_osal_thread_t traffic_task_hdl
uint32_t actual_len_internal
static void iperf_report_task(void *arg)
static uint32_t iperf_get_buffer_len(void)
static int iperf_get_socket_error_code(int sockfd)
static uint32_t iperf_get_float_dec(float in)
static int iperf_show_socket_error_reason(const char *str, int sockfd)
#define XF_ASSERT_RET_GOTO(condition, err_code, label, tag, format,...)
static bool iperf_is_udp_server(void)
static uint32_t iperf_get_float_int(float in)
static xf_err_t iperf_run_udp_client(void)
static void socket_send(int send_socket, struct sockaddr *dest_addr, uint8_t type, int bw_lim)
static void iperf_task_traffic(void *arg)
static xf_err_t iperf_run_tcp_server(void)
static bool iperf_is_udp_client(void)
static xf_err_t iperf_run_tcp_client(void)
static bool iperf_is_tcp_client(void)
static xf_err_t iperf_start_report(void)
static xf_err_t iperf_run_udp_server(void)
static xf_iperf_ctx_t s_ctx
static bool iperf_is_tcp_server(void)
static void socket_recv(int recv_socket, struct sockaddr *listen_addr, uint8_t type)
#define XF_LOGI(tag, format,...)
#define XF_LOGE(tag, format,...)
#define XF_LOGW(tag, format,...)
#define xf_log_printf(format,...)