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:
parent
0cd9b3e267
commit
b9f6bdfe08
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue