From 898b2e8cba94bb08771366aae8ba3ec83ff62409 Mon Sep 17 00:00:00 2001 From: Peter McGoron Date: Mon, 1 Aug 2022 14:44:09 -0400 Subject: [PATCH] ethernet communication --- software/CMakeLists.txt | 3 +- software/prj.conf | 18 ++++++ software/src/test_ethernet.c | 120 +++++++++++++++++++++++++++++++++++ 3 files changed, 140 insertions(+), 1 deletion(-) create mode 100644 software/src/test_ethernet.c diff --git a/software/CMakeLists.txt b/software/CMakeLists.txt index a767307..1de1814 100644 --- a/software/CMakeLists.txt +++ b/software/CMakeLists.txt @@ -4,4 +4,5 @@ find_package(Zephyr) project(cryosnom1) include_directories("../firmware") -target_sources(app PRIVATE src/io.c src/test_dac_adc_main.c) +# target_sources(app PRIVATE src/io.c src/test_dac_adc_main.c) +target_sources(app PRIVATE src/test_ethernet.c) diff --git a/software/prj.conf b/software/prj.conf index 1186b44..b4c474e 100644 --- a/software/prj.conf +++ b/software/prj.conf @@ -1,3 +1,21 @@ CONFIG_LOG=y +CONFIG_NET_LOG=y CONFIG_LOG_BUFFER_SIZE=1024 CONFIG_LOG_PRINTK=y + +CONFIG_NETWORKING=y +CONFIG_NET_IPV4=y +CONFIG_NET_IPV6=n +CONFIG_NET_TCP=y +CONFIG_NET_SOCKETS=y +CONFIG_NET_ARP=y +CONFIG_NET_UDP=y +CONFIG_NET_DHCPV4=y + +CONFIG_INIT_STACKS=y + +CONFIG_NET_CONFIG_SETTINGS=y +CONFIG_NET_CONFIG_NEED_IPV4=y +CONFIG_NET_MGMT=y +CONFIG_NET_MGMT_EVENT=y +CONFIG_TEST_RANDOM_GENERATOR=y diff --git a/software/src/test_ethernet.c b/software/src/test_ethernet.c new file mode 100644 index 0000000..c9f0d06 --- /dev/null +++ b/software/src/test_ethernet.c @@ -0,0 +1,120 @@ +#include +#include +#include +#include + +LOG_MODULE_REGISTER(test_ethernet); + +#define PORT 6626 + +static int +ip_init(void) +{ + int sock; + + sock = zsock_socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + + if (sock < 0) { + LOG_ERR("error: socket: %d", sock); + k_fatal_halt(K_ERR_KERNEL_PANIC); + } + + struct sockaddr_in addr = { + .sin_family = AF_INET, + .sin_addr = {.s_addr = htonl(INADDR_ANY)}, + .sin_port = htons(PORT) + }; + + if (zsock_bind(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) { + LOG_ERR("error: bind: %d", errno); + k_fatal_halt(K_ERR_KERNEL_PANIC); + } + + if (zsock_listen(sock, 2) < 0) { + LOG_ERR("error: listen: %d", errno); + k_fatal_halt(K_ERR_KERNEL_PANIC); + } + + return sock; +} + +static int +get_client(int server) +{ + int client; + struct sockaddr_in addr; + socklen_t len = sizeof(addr); + + do { + client = zsock_accept(server, (struct sockaddr *)&addr, &len); + if (client < 0) + LOG_WRN("error in accept: %d", errno); + } while (client < 0); + + char ipaddr[32]; + zsock_inet_ntop(addr.sin_family, &addr.sin_addr, ipaddr, sizeof(ipaddr)); + LOG_PRINTK("Connection: %s\n", ipaddr); + return client; +} + +static int +send_all(int sock, char *buf, int len) +{ + do { + int sent = zsock_send(sock, buf, len, 0); + if (sent < 0) { + LOG_WRN("error in send: %d", errno); + return 0; + } + buf += sent; + len -= sent; + } while (len > 0); + return 1; +} + +static void +print_buf_escaped(const char *buf, size_t len) +{ + for (size_t i = 0; i < len; i++) { + if (*buf < 0x20 || *buf >= 0x7F) + LOG_PRINTK("[%02x]", *buf); + else + LOG_PRINTK("%c", *buf); + } +} + +static void +client_comm(int sock) +{ + for (;;) { + char buf[256]; + ssize_t len = zsock_recv(sock, buf, sizeof(buf), 0); + + if (len < 0) { + LOG_WRN("Error in client socket: %d", errno); + return; + } else if (len == 0) { + LOG_INF("Client disconnected"); + return; + } + print_buf_escaped(buf, len); + if (!send_all(sock, buf, len)) + return; + } +} + +/* DHCP is done before main(), so no manual DHCP setup required. */ + +void +main(void) +{ + LOG_PRINTK("Init test server...\n"); + int server_sock = ip_init(); + LOG_PRINTK("Test server waiting on %d\n", PORT); + + for (;;) { + int client_sock = get_client(server_sock); + client_comm(client_sock); + zsock_close(client_sock); + } +}