diff --git a/include/zephyr/net/zperf.h b/include/zephyr/net/zperf.h index e26a6076f7a..3b4e9bbb684 100644 --- a/include/zephyr/net/zperf.h +++ b/include/zephyr/net/zperf.h @@ -90,6 +90,7 @@ struct zperf_results { uint64_t client_time_in_us; /**< Client connection time in microseconds */ uint32_t packet_size; /**< Packet size */ uint32_t nb_packets_errors; /**< Number of packet errors */ + bool is_multicast; /**< True if this session used IP multicast */ }; /** diff --git a/subsys/net/lib/zperf/zperf_shell.c b/subsys/net/lib/zperf/zperf_shell.c index dca889b49a9..5ebaada1b50 100644 --- a/subsys/net/lib/zperf/zperf_shell.c +++ b/subsys/net/lib/zperf/zperf_shell.c @@ -516,41 +516,56 @@ static void shell_udp_upload_print_stats(const struct shell *sh, client_rate_in_kbps = 0U; } - if (!rate_in_kbps) { + /* Print warning if no server stats in unicast case; for multicast, + * server stats are not expected. + */ + if (!rate_in_kbps && !results->is_multicast) { shell_fprintf(sh, SHELL_ERROR, "LAST PACKET NOT RECEIVED!!!\n"); } - shell_fprintf(sh, SHELL_NORMAL, - "Statistics:\t\tserver\t(client)\n"); - shell_fprintf(sh, SHELL_NORMAL, "Duration:\t\t"); - print_number_64(sh, results->time_in_us, TIME_US, - TIME_US_UNIT); - shell_fprintf(sh, SHELL_NORMAL, "\t("); - print_number_64(sh, results->client_time_in_us, TIME_US, - TIME_US_UNIT); - shell_fprintf(sh, SHELL_NORMAL, ")\n"); - - shell_fprintf(sh, SHELL_NORMAL, "Num packets:\t\t%u\t(%u)\n", - results->nb_packets_rcvd, - results->nb_packets_sent); - - shell_fprintf(sh, SHELL_NORMAL, - "Num packets out order:\t%u\n", - results->nb_packets_outorder); - shell_fprintf(sh, SHELL_NORMAL, "Num packets lost:\t%u\n", - results->nb_packets_lost); - - shell_fprintf(sh, SHELL_NORMAL, "Jitter:\t\t\t"); - print_number(sh, results->jitter_in_us, TIME_US, - TIME_US_UNIT); - shell_fprintf(sh, SHELL_NORMAL, "\n"); + if (results->is_multicast) { + shell_fprintf(sh, SHELL_NORMAL, "Statistics (client only)\n"); + shell_fprintf(sh, SHELL_NORMAL, "Duration:\t\t"); + print_number_64(sh, results->client_time_in_us, TIME_US, TIME_US_UNIT); + shell_fprintf(sh, SHELL_NORMAL, "\n"); + shell_fprintf(sh, SHELL_NORMAL, "Num packets:\t\t%u\n", + results->nb_packets_sent); + shell_fprintf(sh, SHELL_NORMAL, "Rate:\t\t\t"); + print_number(sh, client_rate_in_kbps, KBPS, KBPS_UNIT); + shell_fprintf(sh, SHELL_NORMAL, "\n"); + } else { + shell_fprintf(sh, SHELL_NORMAL, + "Statistics:\t\tserver\t(client)\n"); + shell_fprintf(sh, SHELL_NORMAL, "Duration:\t\t"); + print_number_64(sh, results->time_in_us, TIME_US, + TIME_US_UNIT); + shell_fprintf(sh, SHELL_NORMAL, "\t("); + print_number_64(sh, results->client_time_in_us, TIME_US, + TIME_US_UNIT); + shell_fprintf(sh, SHELL_NORMAL, ")\n"); + + shell_fprintf(sh, SHELL_NORMAL, "Num packets:\t\t%u\t(%u)\n", + results->nb_packets_rcvd, + results->nb_packets_sent); - shell_fprintf(sh, SHELL_NORMAL, "Rate:\t\t\t"); - print_number(sh, rate_in_kbps, KBPS, KBPS_UNIT); - shell_fprintf(sh, SHELL_NORMAL, "\t("); - print_number(sh, client_rate_in_kbps, KBPS, KBPS_UNIT); - shell_fprintf(sh, SHELL_NORMAL, ")\n"); + shell_fprintf(sh, SHELL_NORMAL, + "Num packets out order:\t%u\n", + results->nb_packets_outorder); + shell_fprintf(sh, SHELL_NORMAL, "Num packets lost:\t%u\n", + results->nb_packets_lost); + + shell_fprintf(sh, SHELL_NORMAL, "Jitter:\t\t\t"); + print_number(sh, results->jitter_in_us, TIME_US, + TIME_US_UNIT); + shell_fprintf(sh, SHELL_NORMAL, "\n"); + + shell_fprintf(sh, SHELL_NORMAL, "Rate:\t\t\t"); + print_number(sh, rate_in_kbps, KBPS, KBPS_UNIT); + shell_fprintf(sh, SHELL_NORMAL, "\t("); + print_number(sh, client_rate_in_kbps, KBPS, KBPS_UNIT); + shell_fprintf(sh, SHELL_NORMAL, ")\n"); + } #ifdef CONFIG_ZPERF_SESSION_PER_THREAD if (is_async) { diff --git a/subsys/net/lib/zperf/zperf_udp_uploader.c b/subsys/net/lib/zperf/zperf_udp_uploader.c index 344ea39560b..f4944d5777f 100644 --- a/subsys/net/lib/zperf/zperf_udp_uploader.c +++ b/subsys/net/lib/zperf/zperf_udp_uploader.c @@ -105,10 +105,14 @@ static inline int zperf_upload_fin(int sock, continue; } - /* Multicast only send the negative sequence number packet - * and doesn't wait for a server ack + /* For multicast, do not wait for a server ack. Keep resending FIN + * for the configured number of attempts by forcing another loop + * iteration. */ - if (!is_mcast_pkt) { + if (is_mcast_pkt) { + ret = 0; + continue; + } else { /* Receive statistics */ ret = zsock_setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, &rcvtimeo, sizeof(rcvtimeo)); @@ -126,6 +130,11 @@ static inline int zperf_upload_fin(int sock, } } + /* In multicast, we never expect a stats reply. Stop here. */ + if (is_mcast_pkt) { + return 0; + } + /* Decode statistics */ if (ret > 0) { zperf_upload_decode_stat(stats, ret, results); @@ -299,6 +308,7 @@ static int udp_upload(int sock, int port, results->client_time_in_us = k_ticks_to_us_ceil64(end_time - start_time); results->packet_size = packet_size; + results->is_multicast = is_mcast_pkt; return 0; }