diff --git a/CMakeLists.txt b/CMakeLists.txt index 4030255..f6d6c01 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -46,6 +46,7 @@ add_executable(${TARGET_NAME}) # lwip set (LWIP_INCLUDE_DIRS "${LWIP_DIR}/src/include" + "${LWIP_DIR}/src/include/compat/posix" "bsp_z7/lwip/include" #${LWIP_DIR}/contrib/ports/freertos/include ) diff --git a/bsp_z7/hardware/uart.c b/bsp_z7/hardware/uart.c index bfec1f1..ddfe8a6 100644 --- a/bsp_z7/hardware/uart.c +++ b/bsp_z7/hardware/uart.c @@ -77,6 +77,7 @@ void uart0_enable_receiver() { } int uart0_read(char *ptr, int len) { + // TODO for blocking, if first call was successfull, further calls need to be delay=0 int received = 0; while (len > 0) { BaseType_t result = xQueueReceive(uart0_receive_queue, ptr, 0); diff --git a/bsp_z7/lwip/include/lwipopts.h b/bsp_z7/lwip/include/lwipopts.h index 4c6d126..a3b8132 100644 --- a/bsp_z7/lwip/include/lwipopts.h +++ b/bsp_z7/lwip/include/lwipopts.h @@ -36,9 +36,9 @@ #define LWIP_IPV6 0 #define NO_SYS 0 -#define LWIP_SOCKET (NO_SYS==0) -#define LWIP_NETCONN (NO_SYS==0) -#define LWIP_NETIF_API (NO_SYS==0) +#define LWIP_SOCKET 1 +#define LWIP_NETCONN 1 +#define LWIP_NETIF_API 0 #define LWIP_IGMP 0 #define LWIP_ICMP LWIP_IPV4 @@ -60,9 +60,17 @@ #define TCP_LISTEN_BACKLOG 0 -#define LWIP_COMPAT_SOCKETS 0 -#define LWIP_SO_RCVTIMEO 0 -#define LWIP_SO_RCVBUF 0 +#define LWIP_COMPAT_SOCKETS 2 +//TODO put this into the OS +#define LWIP_POSIX_SOCKETS_IO_NAMES 0 +#define LWIP_SO_RCVTIMEO 0 +#define LWIP_SO_RCVBUF 0 +//TODO use this with LWIP_POSIX_SOCKETS_IO_NAMES +// TODO why is 100 not working... +#define LWIP_SOCKET_OFFSET 10 + +#define LWIP_SOCKET_SELECT 1 +#define LWIP_SOCKET_POLL 1 #define LWIP_TCPIP_CORE_LOCKING 0 diff --git a/bsp_z7/testEth.c b/bsp_z7/testEth.c index 62fc939..cdb8c0e 100644 --- a/bsp_z7/testEth.c +++ b/bsp_z7/testEth.c @@ -1,12 +1,134 @@ +#include "lwip/api.h" +#include "lwip/priv/sockets_priv.h" #include "lwip/tcpip.h" + +#include "sys/socket.h" + #include "FreeRTOS.h" #include "task.h" - #include "xethernet.h" -int testEth(){ +#include "hardware/interfaces.h" +#include + +struct lwip_sock *get_socket(int fd); + +extern QueueHandle_t uart0_receive_queue; + +void udp_echo_thread(void *_) { + vTaskDelay(5000 * portTICK_RATE_MS); + + int sock = socket(AF_INET, SOCK_DGRAM, 0); + if (sock == -1) { + xil_printf("no sock\n"); + } + + struct sockaddr_in our_addr; + memset(&our_addr, 0, sizeof(our_addr)); + + our_addr.sin_family = AF_INET; + our_addr.sin_port = htons(8100); + + int ret = inet_aton("192.168.1.10", &our_addr.sin_addr); + if (ret == 0) { + xil_printf("no addr"); + } + + ret = bind(sock, (struct sockaddr *)&our_addr, sizeof(our_addr)); + if (ret == -1) { + xil_printf("no bind"); + } + + struct sockaddr_in peer_addr; + memset(&peer_addr, 0, sizeof(peer_addr)); + + peer_addr.sin_family = AF_INET; + peer_addr.sin_port = htons(8100); + + ret = inet_aton("192.168.1.5", &peer_addr.sin_addr); + if (ret == 0) { + xil_printf("no addr"); + } + + int uart_sock = hw_device_open("uart0", 5); + write(uart_sock, "1234", 4); + + // char buffer[] = {'1','2','3','4'}; + // ret = sendto(sock, buffer, sizeof(buffer), 0, (struct sockaddr *) + // &peer_addr, sizeof(peer_addr)); if (ret <= 0) { + // xil_printf("no send"); + // } + + uint8_t rec_buffer[1024]; + + QueueSetHandle_t listening_set = xQueueCreateSet(100); + if (listening_set == NULL) { + xil_printf("no set"); + } + + struct lwip_sock *raw_socket = get_socket(sock); + + sys_mbox_t queue_id = raw_socket->conn->recvmbox; + + xQueueAddToSet(queue_id, listening_set); + xQueueAddToSet(uart0_receive_queue, listening_set); + + while (1) { + QueueSetMemberHandle_t readable = + xQueueSelectFromSet(listening_set, portMAX_DELAY); + + if (readable == queue_id) { + socklen_t peer_len = sizeof(peer_addr); + ret = lwip_recvfrom(sock, rec_buffer, sizeof(rec_buffer), 0, (struct sockaddr *) &peer_addr, + &peer_len); + if (peer_len > sizeof(peer_addr)) { + xil_printf("invalid peer"); + continue; + } + if (ret < 0) { + continue; + } + uint16_t port = ntohs(peer_addr.sin_port); + switch (port) { + case 8100: + xil_printf("udp rec 8100 len: %i\n", ret); + write(uart_sock, rec_buffer, ret); + break; + default: + xil_printf("invalid port %i\n", port); + break; + } + } else if (readable == uart0_receive_queue) { + ret = read(uart_sock, rec_buffer, sizeof(rec_buffer)); + xil_printf("uart got %i\n", ret); + + // Do not send empty packets + if (ret <= 0) { + continue; + } + peer_addr.sin_port = htons(8100); + + //TODO sending 1 byte gives invalid UDP checksum + lwip_sendto(sock, rec_buffer, ret, 0, (struct sockaddr *)&peer_addr, + sizeof(peer_addr)); + } else { + xil_printf("invalid handle"); + } + } + + xQueueRemoveFromSet(queue_id, listening_set); + + while (1) { + ret = recv(sock, rec_buffer, sizeof(rec_buffer), 0); + xil_printf("received %i\n", ret); + vTaskDelay(100 * portTICK_RATE_MS); + } +} + +int testEth() { tcpip_init(NULL, NULL); xethernet_init(); - vTaskStartScheduler(); + sys_thread_new("echo", udp_echo_thread, 0, 1024, DEFAULT_THREAD_PRIO); + vTaskStartScheduler(); } \ No newline at end of file