1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00
RIOT/tests/net/gnrc_sock_tcp/main.c

224 lines
5.8 KiB
C

/*
* Copyright (C) 2021 Simon Brummer <simon.brummer@posteo.de>
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/
#include <stdio.h>
#include <string.h>
#include "shell.h"
#include "msg.h"
#include "net/sock/tcp.h"
#include "net/gnrc/tcp.h"
#define MAIN_QUEUE_SIZE (8)
#define SOCK_TCP_QUEUE_SIZE (1)
#define BUFFER_SIZE (1024)
static msg_t main_msg_queue[MAIN_QUEUE_SIZE];
static sock_tcp_t socks[SOCK_TCP_QUEUE_SIZE];
static sock_tcp_t *sock = socks;
static sock_tcp_queue_t sock_queue;
static char buffer[BUFFER_SIZE];
void dump_args(int argc, char **argv)
{
printf("%s: ", argv[0]);
printf("argc=%d", argc);
for (int i = 0; i < argc; ++i) {
printf(", argv[%d] = %s", i, argv[i]);
}
printf("\n");
}
void print_result(const char *name, int err)
{
if (err) {
printf("%s: returns %s\n", name, strerror(-err));
} else {
printf("%s: returns %d\n", name, err);
}
}
int sock_tcp_connect_cmd(int argc, char **argv)
{
dump_args(argc, argv);
sock_tcp_ep_t ep = SOCK_IPV6_EP_ANY;
gnrc_tcp_ep_from_str((gnrc_tcp_ep_t *) &ep, argv[1]);
uint16_t local_port = atol(argv[2]);
uint16_t flags = 0;
int err = sock_tcp_connect(sock, &ep, local_port, flags);
print_result(argv[0], err);
return 0;
}
int sock_tcp_disconnect_cmd(int argc, char **argv)
{
dump_args(argc, argv);
sock_tcp_disconnect(sock);
printf("%s: returns\n", argv[0]);
return 0;
}
int sock_tcp_listen_cmd(int argc, char **argv)
{
dump_args(argc, argv);
sock_tcp_ep_t ep = SOCK_IPV6_EP_ANY;
gnrc_tcp_ep_from_str((gnrc_tcp_ep_t *) &ep, argv[1]);
uint16_t flags = 0;
int err = sock_tcp_listen(&sock_queue, &ep, socks, SOCK_TCP_QUEUE_SIZE, flags);
print_result(argv[0], err);
return 0;
}
int sock_tcp_stop_listen_cmd(int argc, char **argv)
{
dump_args(argc, argv);
sock_tcp_stop_listen(&sock_queue);
printf("%s: returns\n", argv[0]);
return 0;
}
int sock_tcp_accept_cmd(int argc, char **argv)
{
dump_args(argc, argv);
sock_tcp_t *tmp = NULL;
uint16_t timeout = atol(argv[1]);
int err = sock_tcp_accept(&sock_queue, &tmp, timeout);
print_result(argv[0], err);
if (tmp) {
sock = tmp;
}
return 0;
}
int sock_tcp_read_cmd(int argc, char **argv)
{
dump_args(argc, argv);
unsigned to_receive = atol(argv[1]);
int timeout = (argc > 2) ? atol(argv[1]) : 0;
unsigned rcvd = 0;
while (rcvd < to_receive) {
int ret = sock_tcp_read(sock, buffer + rcvd, to_receive - rcvd, timeout);
if (ret > 0) {
rcvd += ret;
} else {
print_result(argv[0], ret);
if (ret == -EAGAIN) {
continue;
} else {
return ret;
}
}
}
buffer[to_receive] = '\0';
printf("%s: received %u %s\n", argv[0], rcvd, buffer);
return 0;
}
int sock_tcp_write_cmd(int argc, char **argv)
{
dump_args(argc, argv);
unsigned payload_size = strlen(argv[1]);
char *payload = argv[1];
unsigned sent = 0;
while (sent < payload_size)
{
int ret = sock_tcp_write(sock, payload + sent, payload_size - sent);
if (ret >= 0) {
sent += ret;
} else {
print_result(argv[0], ret);
return ret;
}
}
printf("%s: sent %u\n", argv[0], sent);
return 0;
}
int sock_tcp_get_local_cmd(int argc, char **argv)
{
dump_args(argc, argv);
sock_tcp_ep_t ep = SOCK_IPV6_EP_ANY;
int err = sock_tcp_get_local(sock, &ep);
print_result(argv[0], err);
if (err == 0) {
printf("Endpoint: addr.ipv6=");
ipv6_addr_print((ipv6_addr_t *) ep.addr.ipv6);
printf(" netif=%u port=%u\n", ep.netif, ep.port);
}
return 0;
}
int sock_tcp_queue_get_local_cmd(int argc, char **argv)
{
dump_args(argc, argv);
sock_tcp_ep_t ep = SOCK_IPV6_EP_ANY;
int err = sock_tcp_queue_get_local(&sock_queue, &ep);
print_result(argv[0], err);
if (err == 0) {
printf("Endpoint: addr.ipv6=");
ipv6_addr_print((ipv6_addr_t *) ep.addr.ipv6);
printf(" netif=%u port=%u\n", ep.netif, ep.port);
}
return 0;
}
int sock_tcp_get_remote_cmd(int argc, char **argv)
{
dump_args(argc, argv);
sock_tcp_ep_t ep = SOCK_IPV6_EP_ANY;
int err = sock_tcp_get_remote(sock, &ep);
print_result(argv[0], err);
if (err == 0) {
printf("Endpoint: addr.ipv6=");
ipv6_addr_print((ipv6_addr_t *) ep.addr.ipv6);
printf(" netif=%u port=%u\n", ep.netif, ep.port);
}
return 0;
}
/* Exporting GNRC SOCK TCP Api to for shell usage */
static const shell_command_t shell_commands[] = {
{ "sock_tcp_connect", "connect", sock_tcp_connect_cmd },
{ "sock_tcp_disconnect", "disconnect", sock_tcp_disconnect_cmd },
{ "sock_tcp_listen", "listen", sock_tcp_listen_cmd },
{ "sock_tcp_stop_listen", "stop_listen", sock_tcp_stop_listen_cmd },
{ "sock_tcp_accept", "accept", sock_tcp_accept_cmd },
{ "sock_tcp_read", "read", sock_tcp_read_cmd },
{ "sock_tcp_write", "write", sock_tcp_write_cmd },
{ "sock_tcp_get_local", "get_local", sock_tcp_get_local_cmd },
{ "sock_tcp_queue_get_local", "queue_get_local", sock_tcp_queue_get_local_cmd },
{ "sock_tcp_get_remote", "get_remote", sock_tcp_get_remote_cmd },
{ NULL, NULL, NULL }
};
int main(void)
{
/* we need a message queue for the thread running the shell in order to
* receive potentially fast incoming networking packets */
msg_init_queue(main_msg_queue, MAIN_QUEUE_SIZE);
printf("RIOT GNRC_TCP test application\n");
/* start shell */
char line_buf[SHELL_DEFAULT_BUFSIZE];
shell_run(shell_commands, line_buf, SHELL_DEFAULT_BUFSIZE);
/* should be never reached */
return 0;
}