samples: net: zperf: Fix TCP download command

The TCP download command was not handling TCP session and
connection closing properly.

Signed-off-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>
This commit is contained in:
Jukka Rissanen 2019-03-12 15:14:43 +02:00 committed by Anas Nashif
parent 0cd9b3e267
commit b9f6bdfe08
6 changed files with 91 additions and 15 deletions

View file

@ -14,7 +14,7 @@ CONFIG_NET_BUF_TX_COUNT=28
CONFIG_NET_IF_UNICAST_IPV6_ADDR_COUNT=4
CONFIG_NET_IF_MCAST_IPV6_ADDR_COUNT=5
CONFIG_NET_IF_UNICAST_IPV4_ADDR_COUNT=1
CONFIG_NET_MAX_CONTEXTS=3
CONFIG_NET_MAX_CONTEXTS=5
CONFIG_NET_CONTEXT_SYNC_RECV=y
CONFIG_INIT_STACKS=y

View file

@ -117,4 +117,7 @@ extern void connect_ap(char *ssid);
const struct in_addr *zperf_get_default_if_in4_addr(void);
const struct in6_addr *zperf_get_default_if_in6_addr(void);
void zperf_tcp_stopped(void);
void zperf_tcp_started(void);
#endif /* __ZPERF_INTERNAL_H */

View file

@ -107,6 +107,41 @@ struct session *get_session(struct net_pkt *pkt, enum session_proto proto)
return active;
}
struct session *get_tcp_session(struct net_context *ctx)
{
struct session *free = NULL;
int i = 0;
if (!ctx) {
printk("Error! null context detected.\n");
return NULL;
}
/* Check whether we already have an active session */
while (i < SESSION_MAX) {
struct session *ptr = &sessions[SESSION_TCP][i];
if (ptr->ctx == ctx) {
return ptr;
}
if (ptr->state == STATE_NULL ||
ptr->state == STATE_COMPLETED) {
/* We found a free slot - just in case */
free = ptr;
break;
}
i++;
}
if (free) {
free->ctx = ctx;
}
return free;
}
void zperf_reset_session_stats(struct session *session)
{
if (!session) {

View file

@ -34,11 +34,13 @@ enum session_proto {
};
struct session {
/* Tuple */
/* Tuple for UDP */
u16_t port;
struct net_addr ip;
/* TCP session */
struct net_context *ctx;
enum state state;
/* Stat data */
@ -57,6 +59,7 @@ struct session {
};
struct session *get_session(struct net_pkt *pkt, enum session_proto proto);
struct session *get_tcp_session(struct net_context *ctx);
void zperf_session_init(void);
void zperf_reset_session_stats(struct session *session);

View file

@ -989,11 +989,22 @@ static int cmd_connectap(const struct shell *shell, size_t argc, char *argv[])
return 0;
}
static bool tcp_running;
void zperf_tcp_stopped(void)
{
tcp_running = false;
}
void zperf_tcp_started(void)
{
tcp_running = true;
}
static int cmd_tcp_download(const struct shell *shell, size_t argc,
char *argv[])
{
if (IS_ENABLED(CONFIG_NET_TCP)) {
static bool tcp_stopped = true;
int port;
do_init(shell);
@ -1004,7 +1015,7 @@ static int cmd_tcp_download(const struct shell *shell, size_t argc,
port = DEF_PORT;
}
if (!tcp_stopped) {
if (tcp_running) {
shell_fprintf(shell, SHELL_WARNING,
"TCP server already started!\n");
return -ENOEXEC;
@ -1012,8 +1023,6 @@ static int cmd_tcp_download(const struct shell *shell, size_t argc,
zperf_tcp_receiver_init(shell, port);
tcp_stopped = false;
shell_fprintf(shell, SHELL_NORMAL,
"TCP server started on port %u\n", port);

View file

@ -30,6 +30,8 @@ LOG_MODULE_DECLARE(net_zperf_sample, LOG_LEVEL_DBG);
static struct sockaddr_in6 *in6_addr_my;
static struct sockaddr_in *in4_addr_my;
const struct shell *tcp_shell;
static void tcp_received(struct net_context *context,
struct net_pkt *pkt,
union net_ip_header *ip_hdr,
@ -37,35 +39,41 @@ static void tcp_received(struct net_context *context,
int status,
void *user_data)
{
const struct shell *shell = user_data;
const struct shell *shell = tcp_shell;
struct session *session;
u32_t time;
if (!pkt) {
if (!shell) {
printk("Shell is not set!\n");
return;
}
time = k_cycle_get_32();
session = get_session(pkt, SESSION_TCP);
session = get_tcp_session(context);
if (!session) {
shell_fprintf(shell, SHELL_WARNING, "Cannot get a session!\n");
return;
}
switch (session->state) {
case STATE_NULL:
case STATE_COMPLETED:
shell_fprintf(shell, SHELL_NORMAL, "New session started\n");
break;
case STATE_NULL:
shell_fprintf(shell, SHELL_NORMAL,
"New TCP session started\n");
zperf_reset_session_stats(session);
session->start_time = k_cycle_get_32();
session->state = STATE_ONGOING;
/* fall through */
case STATE_ONGOING:
session->counter++;
session->length += net_pkt_appdatalen(pkt);
if (status == 0) { /* EOF */
if (pkt) {
session->length += net_pkt_appdatalen(pkt);
}
if (pkt == NULL && status == 0) { /* EOF */
u32_t rate_in_kbps;
u32_t duration = HW_CYCLES_TO_USEC(
time_delta(session->start_time, time));
@ -94,6 +102,11 @@ static void tcp_received(struct net_context *context,
shell_fprintf(shell, SHELL_NORMAL, " rate:\t\t\t");
print_number(shell, rate_in_kbps, KBPS, KBPS_UNIT);
shell_fprintf(shell, SHELL_NORMAL, "\n");
zperf_tcp_stopped();
net_context_unref(context);
session->state = STATE_NULL;
}
break;
case STATE_LAST_PACKET_RECEIVED:
@ -102,7 +115,9 @@ static void tcp_received(struct net_context *context,
shell_fprintf(shell, SHELL_WARNING, "Unsupported case\n");
}
net_pkt_unref(pkt);
if (pkt) {
net_pkt_unref(pkt);
}
}
static void tcp_accepted(struct net_context *context,
@ -124,12 +139,20 @@ static void tcp_accepted(struct net_context *context,
void zperf_tcp_receiver_init(const struct shell *shell, int port)
{
static bool init_done;
struct net_context *context4 = NULL;
struct net_context *context6 = NULL;
const struct in_addr *in4_addr = NULL;
const struct in6_addr *in6_addr = NULL;
int ret;
if (init_done) {
zperf_tcp_started();
return;
}
tcp_shell = shell;
if (IS_ENABLED(CONFIG_NET_IPV6)) {
in6_addr_my = zperf_get_sin6();
}
@ -269,4 +292,7 @@ void zperf_tcp_receiver_init(const struct shell *shell, int port)
shell_fprintf(shell, SHELL_NORMAL,
"Listening on port %d\n", port);
zperf_tcp_started();
init_done = true;
}