From b74366a546257f738cfe454065c4b33783fbc8bf Mon Sep 17 00:00:00 2001 From: DcruBro Date: Fri, 10 Apr 2026 13:11:27 +0200 Subject: [PATCH] tcp test --- CMakeLists.txt | 2 +- include/lwipopts.h | 51 ++++++++++++++++++++ include/net/net.h | 29 +++++++++++ src/main.c | 34 ++++++------- src/net/net.c | 117 +++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 216 insertions(+), 17 deletions(-) create mode 100644 include/lwipopts.h create mode 100644 include/net/net.h create mode 100644 src/net/net.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 042fac0..75b3196 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -70,7 +70,7 @@ target_include_directories(l3iot-fin PRIVATE # Add any user requested libraries target_link_libraries(l3iot-fin - pico_cyw43_arch_none + pico_cyw43_arch_lwip_threadsafe_background ) pico_add_extra_outputs(l3iot-fin) diff --git a/include/lwipopts.h b/include/lwipopts.h new file mode 100644 index 0000000..7cfc9e3 --- /dev/null +++ b/include/lwipopts.h @@ -0,0 +1,51 @@ +#ifndef LWIPOPTS_H +#define LWIPOPTS_H + +// lwIP configuration for Raspberry Pi Pico W (CYW43 + lwIP). +// This is a sane baseline for pico_cyw43_arch_lwip_threadsafe_background. +// example + +#define NO_SYS 1 +#define LWIP_SOCKET 0 +#define LWIP_NETCONN 0 + +#define MEM_ALIGNMENT 4 +#define MEM_SIZE 4000 + +#define MEMP_NUM_TCP_SEG 32 +#define MEMP_NUM_ARP_QUEUE 10 +#define PBUF_POOL_SIZE 24 + +#define LWIP_ARP 1 +#define LWIP_ETHERNET 1 +#define LWIP_ICMP 1 +#define LWIP_RAW 1 +#define LWIP_DHCP 1 +#define LWIP_IPV4 1 +#define LWIP_TCP 1 +#define LWIP_UDP 1 +#define LWIP_DNS 1 + +#define TCP_MSS 1460 +#define TCP_WND (8 * TCP_MSS) +#define TCP_SND_BUF (8 * TCP_MSS) +#define TCP_SND_QUEUELEN ((4 * TCP_SND_BUF + TCP_MSS - 1) / TCP_MSS) + +#define MEMP_NUM_TCP_PCB 5 +#define MEMP_NUM_TCP_PCB_LISTEN 8 +#define MEMP_NUM_SYS_TIMEOUT 10 + +#define LWIP_NETIF_STATUS_CALLBACK 1 +#define LWIP_NETIF_LINK_CALLBACK 1 +#define LWIP_NETIF_HOSTNAME 1 + +#define LWIP_TCP_KEEPALIVE 1 +#define LWIP_SO_RCVTIMEO 1 +#define LWIP_SO_SNDTIMEO 1 + +// Use system-provided timeval definition. +#define LWIP_TIMEVAL_PRIVATE 0 + +#define LWIP_CHKSUM_ALGORITHM 3 + +#endif // LWIPOPTS_H diff --git a/include/net/net.h b/include/net/net.h new file mode 100644 index 0000000..4815606 --- /dev/null +++ b/include/net/net.h @@ -0,0 +1,29 @@ +#ifndef NET_H +#define NET_H + +// net.h +// Includes +#include +#include "pico/stdlib.h" +#include "pico/cyw43_arch.h" +#include +#include + +typedef struct { + char ssid[32]; + char password[64]; +} net_creds_t; + +typedef struct { + uint16_t port; + uint16_t maxClients; + void (*onConnect)(int clientId); + void (*onDisconnect)(int clientId); + void (*onData)(int clientId, const uint8_t* data, size_t len); +} net_server_t; + +net_server_t* Net_Init(net_creds_t* creds); +bool Net_Listen(net_server_t* server); +void Net_Destroy(net_server_t* server); + +#endif diff --git a/src/main.c b/src/main.c index 8def55d..3f13bf8 100644 --- a/src/main.c +++ b/src/main.c @@ -1,24 +1,26 @@ -#include -#include "pico/stdlib.h" -#include "pico/cyw43_arch.h" -#include +#include int main(void) { stdio_init_all(); - // Initialise the Wi-Fi chip - if (cyw43_arch_init()) { - printf("Wi-Fi init failed\n"); - return -1; + net_creds_t creds = { + .ssid = "5", + .password = "nevem123" + }; + + net_server_t* server = Net_Init(&creds); + if (!server) { + printf("Failed to initialize network\n"); + return 1; } - // Example to turn on the Pico W LED - bool led_on = true; + if (!Net_Listen(server)) { + printf("Failed to start server\n"); + Net_Destroy(server); + return 1; + } + + Net_Destroy(server); - - while (true) { - cyw43_arch_gpio_put(CYW43_WL_GPIO_LED_PIN, led_on); - led_on = !led_on; // Toggle LED state - sleep_ms(1000); - } + return 0; } diff --git a/src/net/net.c b/src/net/net.c new file mode 100644 index 0000000..4b5bc97 --- /dev/null +++ b/src/net/net.c @@ -0,0 +1,117 @@ +#include +#include +#include +#include + +static const char* link_status_to_string(int status) { + switch (status) { + case CYW43_LINK_DOWN: + return "LINK_DOWN"; + case CYW43_LINK_JOIN: + return "LINK_JOIN"; + case CYW43_LINK_NOIP: + return "LINK_NOIP"; + case CYW43_LINK_UP: + return "LINK_UP"; + case CYW43_LINK_FAIL: + return "LINK_FAIL"; + case CYW43_LINK_NONET: + return "LINK_NONET"; + case CYW43_LINK_BADAUTH: + return "LINK_BADAUTH"; + default: + return "LINK_UNKNOWN"; + } +} + +net_server_t* Net_Init(net_creds_t* creds) { + if (!creds) { + printf("Invalid credentials\n"); + return NULL; + } + + if (creds->ssid[0] == '\0') { + printf("SSID is empty\n"); + return NULL; + } + + // Init Wi-Fi + if (cyw43_arch_init()) { + printf("Wi-Fi init failed\n"); + return NULL; + } + + cyw43_arch_enable_sta_mode(); + + printf("Connecting to SSID: %s\n", creds->ssid); + + int rc = cyw43_arch_wifi_connect_timeout_ms( + creds->ssid, + creds->password, + CYW43_AUTH_WPA2_AES_PSK, + 15000 + ); + + if (rc) { + int link = cyw43_tcpip_link_status(&cyw43_state, CYW43_ITF_STA); + printf("Wi-Fi connection failed rc=%d status=%s(%d)\n", rc, link_status_to_string(link), link); + return NULL; + } + + int link = cyw43_tcpip_link_status(&cyw43_state, CYW43_ITF_STA); + printf("Wi-Fi connected status=%s(%d)\n", link_status_to_string(link), link); + + net_server_t* svr = (net_server_t*)malloc(sizeof(net_server_t)); + if (!svr) { + printf("Failed to allocate server memory\n"); + return NULL; + } + + memset(svr, 0, sizeof(net_server_t)); // Zero out + + return svr; +} + +bool Net_Listen(net_server_t* server) { + if (!server) { + printf("Server not initialized\n"); + return false; + } + + struct tcp_pcb* pcb = tcp_new(); + if (!pcb) { + printf("Failed to create TCP PCB\n"); + return false; + } + + err_t err = tcp_bind(pcb, IP_ADDR_ANY, server->port); + if (err != ERR_OK) { + printf("Failed to bind TCP PCB: %d\n", err); + tcp_close(pcb); + return false; + } + + struct tcp_pcb* listen_pcb = tcp_listen_with_backlog(pcb, server->maxClients); + if (!listen_pcb) { + printf("Failed to listen on TCP PCB\n"); + tcp_close(pcb); + return false; + } + + // Turn on LED + cyw43_arch_gpio_put(CYW43_WL_GPIO_LED_PIN, true); + + while (true) { + // TODO: Accept clients and handle data + sleep_ms(10); + } + + return true; +} + +void Net_Destroy(net_server_t* server) { + if (server) { + // TODO: Disconnect gracefully + free(server); + } +}