From 32fd775a186625ff41f3bf97578fb195c1ec315a Mon Sep 17 00:00:00 2001 From: Ulysse Cura Date: Sat, 31 Jan 2026 19:51:23 +0100 Subject: [PATCH] Working udp client and station mode --- .vscode/tasks.json | 37 ++++++++ python_test_codes/test_udp_receiver.py | 18 ---- python_test_codes/test_udp_send.py | 34 +++---- src/lwipopts.h | 15 +-- src/main.c | 122 +++++++++++++++++++++++++ src/test_connection.c | 120 ------------------------ src/udp/udp_client.c | 62 ------------- src/udp/udp_client.h | 26 ------ src/udp/udp_server.c | 87 ------------------ src/udp/udp_server.h | 17 ---- src/wifi_operator/wifi_operator.c | 69 -------------- src/wifi_operator/wifi_operator.h | 8 -- 12 files changed, 179 insertions(+), 436 deletions(-) create mode 100644 .vscode/tasks.json delete mode 100755 python_test_codes/test_udp_receiver.py create mode 100644 src/main.c delete mode 100644 src/test_connection.c delete mode 100644 src/udp/udp_client.c delete mode 100644 src/udp/udp_client.h delete mode 100644 src/udp/udp_server.c delete mode 100644 src/udp/udp_server.h delete mode 100644 src/wifi_operator/wifi_operator.c delete mode 100644 src/wifi_operator/wifi_operator.h diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 0000000..e70a949 --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,37 @@ +{ + "tasks": [ + { + "label": "CMake & Make", + "type": "shell", + "group": "build", + + "command": "mkdir -p build && cd build && cmake ../ && make", + + "presentation": { + "echo": true, + "reveal": "always", + "focus": true, + "panel": "shared", + "showReuseMessage": true, + "clear": true + } + }, + { + "label": "CMake & Make & Flash", + "type": "shell", + "group": "build", + + "command": "mkdir -p build && cd build && cmake ../ && make Flash", + + "presentation": { + "echo": true, + "reveal": "always", + "focus": true, + "panel": "shared", + "showReuseMessage": true, + "clear": true + } + } + ], + "version": "2.0.0" +} \ No newline at end of file diff --git a/python_test_codes/test_udp_receiver.py b/python_test_codes/test_udp_receiver.py deleted file mode 100755 index e167f99..0000000 --- a/python_test_codes/test_udp_receiver.py +++ /dev/null @@ -1,18 +0,0 @@ -#!/usr/bin/env python3 - -import socket -import struct - -def start_udp_server(): - sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) - sock.bind(('0.0.0.0', 10101)) - print("Serveur UDP démarré sur le port 10101") - - while True: - data, addr = sock.recvfrom(1024) - if len(data) == 2: - packet_num, instruction = struct.unpack('BB', data) - print(f"Reçu: packet_number={packet_num}, instruction={instruction}") - -if __name__ == '__main__': - start_udp_server() \ No newline at end of file diff --git a/python_test_codes/test_udp_send.py b/python_test_codes/test_udp_send.py index ab9e3fc..fe2f02c 100755 --- a/python_test_codes/test_udp_send.py +++ b/python_test_codes/test_udp_send.py @@ -4,22 +4,18 @@ import socket import time import struct -def send_test_packets(): - sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) - pico_address = ('192.168.128.1', 4243) # Adresse IP du Pico W - - packet_number = 0 - instruction = 0 - - while True: - # Créer le message binaire - message = struct.pack('BB', packet_number, instruction) - sock.sendto(message, pico_address) - - packet_number = (packet_number + 1) % 256 - instruction = (instruction + 1) % 256 - - time.sleep(3.5) - -if __name__ == '__main__': - send_test_packets() \ No newline at end of file +sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) +pico_address = ('255.255.255.255', 4243) + +packet_number = 0 +instruction = 0 + +while True: + # Créer le message binaire + message = struct.pack('BB', packet_number, instruction) + sock.sendto(message, pico_address) + + packet_number = (packet_number + 1) % 256 + instruction = (instruction + 1) % 256 + print("Sended") + time.sleep(3.5) diff --git a/src/lwipopts.h b/src/lwipopts.h index b5d3861..3cc083c 100644 --- a/src/lwipopts.h +++ b/src/lwipopts.h @@ -21,18 +21,18 @@ #endif #define MEM_ALIGNMENT 4 #ifndef MEM_SIZE -#define MEM_SIZE 32768 // Augmenté pour plus de mémoire disponible +#define MEM_SIZE 4000 #endif #define MEMP_NUM_TCP_SEG 32 #define MEMP_NUM_ARP_QUEUE 10 -#define PBUF_POOL_SIZE 32 // Augmenté pour réduire les allocations +#define PBUF_POOL_SIZE 24 #define LWIP_ARP 1 #define LWIP_ETHERNET 1 #define LWIP_ICMP 1 #define LWIP_RAW 1 -#define TCP_WND (16 * TCP_MSS) // Augmenté pour de meilleures performances +#define TCP_WND (8 * TCP_MSS) #define TCP_MSS 1460 -#define TCP_SND_BUF (8 * TCP_MSS) // Augmenté pour de meilleures performances +#define TCP_SND_BUF (8 * TCP_MSS) #define TCP_SND_QUEUELEN ((4 * (TCP_SND_BUF) + (TCP_MSS - 1)) / (TCP_MSS)) #define LWIP_NETIF_STATUS_CALLBACK 1 #define LWIP_NETIF_LINK_CALLBACK 1 @@ -45,7 +45,6 @@ // #define ETH_PAD_SIZE 2 #define LWIP_CHKSUM_ALGORITHM 3 #define LWIP_DHCP 1 -#define LWIP_DHCP_SERVER 1 #define LWIP_IPV4 1 #define LWIP_TCP 1 #define LWIP_UDP 1 @@ -90,8 +89,4 @@ #define SLIP_DEBUG LWIP_DBG_OFF #define DHCP_DEBUG LWIP_DBG_OFF -#define SYS_LIGHTWEIGHT_PROT 1 // Protection pour le multicore -#define MEMP_NUM_PBUF 32 // Augmenté pour les buffers -#define ICMP_TTL 255 // Augmenté pour la fiabilité - -#endif /* __LWIPOPTS_H__ */ \ No newline at end of file +#endif /* __LWIPOPTS_H__ */ diff --git a/src/main.c b/src/main.c new file mode 100644 index 0000000..f2dee3e --- /dev/null +++ b/src/main.c @@ -0,0 +1,122 @@ +// Necessary includes from the Pico SDK +#include +#include +#include +#include +#include + +#define SSID "thinkpad-T440p" +#define PASSWORD "CDuKaka2000!" + +#define PORT 4243 + +static void udp_recv_callback(void *arg, struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *addr, u16_t port) +{ + puts("Callback"); + + if(p->len == 1) + { + printf("a:%d\n", ((uint8_t *)p->payload)[0]); + } + pbuf_free(p); +} + +int main() +{ + stdio_init_all(); + + sleep_ms(2000); + + puts("Pi Starting..."); + + if(cyw43_arch_init_with_country(CYW43_COUNTRY_FRANCE)) + { + puts("CYW43 arch init failed"); + return -1; + } + + cyw43_arch_enable_sta_mode(); + cyw43_wifi_pm(&cyw43_state, CYW43_NO_POWERSAVE_MODE); + + puts("CYW43 arch initialized"); + + for(int error_code = 1; error_code; ) + { + puts("WiFi connection attempt"); + + error_code = cyw43_arch_wifi_connect_timeout_ms(SSID, PASSWORD, CYW43_AUTH_WPA2_AES_PSK, 10000); + + if(error_code) + { + const char *error_message; + + switch(error_code) + { + case PICO_ERROR_TIMEOUT: + error_message = "Timeout reached"; + break; + + case PICO_ERROR_BADAUTH: + error_message = "Bad password"; + break; + + case PICO_ERROR_CONNECT_FAILED: + error_message = "Some reason"; + break; + } + + printf("Connection failed : %s\n", error_message); + } + } + + puts("WiFi connected"); + + struct udp_pcb *pcb = udp_new(); + + if(!pcb) + { + puts("UDP pcb init failed"); + return -1; + } + + udp_recv(pcb, udp_recv_callback, NULL); + + udp_bind(pcb, IP4_ADDR_ANY, PORT); + + // ========================== Main loop ========================== + while(true) + { + cyw43_arch_poll(); + + int ret = cyw43_wifi_link_status(&cyw43_state, CYW43_ITF_STA); + if(ret != CYW43_LINK_JOIN) + { + const char *status_message; + switch(ret) + { + case CYW43_LINK_DOWN: + status_message = "WiFi down"; + break; + + case CYW43_LINK_JOIN: + status_message = "WiFi up"; + break; + + case CYW43_LINK_FAIL: + status_message = "WiFi connection failed"; + break; + + case CYW43_LINK_NONET: + status_message = "Network not found"; + break; + + case CYW43_LINK_BADAUTH: + status_message = "Bad auth"; + break; + } + puts(status_message); + } + + tight_loop_contents(); + } +} diff --git a/src/test_connection.c b/src/test_connection.c deleted file mode 100644 index 276dbe9..0000000 --- a/src/test_connection.c +++ /dev/null @@ -1,120 +0,0 @@ -// Necessary includes from the Pico SDK -#include -#include -#include "pico/cyw43_arch.h" - -// Custom libraries includes -#include "wifi_operator/wifi_operator.h" -#include "udp/udp_client.h" -#include "udp/udp_server.h" - -// Multicore includes to limit latency on packet reception on core 0 -#include "pico/multicore.h" -#include "hardware/irq.h" -#include "hardware/sync.h" -#include "pico/mutex.h" - -#define UART_ID uart0 -#define BAUD_RATE 115200 -#define UART_TX_PIN 0 // GP0 -#define UART_RX_PIN 1 // GP1 -#define UDP_SERVER_PORT 4242 -#define UDP_CLIENT_PORT 4243 - -// Ajouter ces defines en haut du fichier -#define TARGET_IP "192.168.128.2" // IP de votre PC -#define TARGET_PORT 10101 // Port sur lequel votre PC écoute - -// Access Point configuration -#define AP_SSID "PicoW_AP" -#define AP_PASSWORD "password123" -#define AP_CHANNEL 13 - -// Déclarer le mutex comme variable globale -auto_init_mutex(wifi_mutex); - -// En haut du fichier, après les includes existants -#define BUFFER_SIZE 1024 - -void custom_message_callback(uint8_t packet_number, uint8_t instruction, const ip_addr_t *addr, u16_t port) -{ - printf("Core0: Received: packet=%d, instruction=%d, from %s:%d\n", packet_number, instruction, ipaddr_ntoa(addr), port); - - //making the led blink twice in 0.1s - for (int i = 0; i < 2; i++) - { - cyw43_arch_gpio_put(CYW43_WL_GPIO_LED_PIN, true); - sleep_ms(25); - cyw43_arch_gpio_put(CYW43_WL_GPIO_LED_PIN, false); - sleep_ms(25); - } -} - -void core1_entry() -{ - int diodeState = 0; - udp_server_init(UDP_SERVER_PORT); // Uniquement le serveur sur core 1 - - uint8_t buffer[2]; - uint8_t *packet_number = &buffer[0]; - uint8_t *instruction = &buffer[1]; - - printf("Core1: Starting UDP server on port %d\n", UDP_SERVER_PORT); - - while(true) - { - mutex_enter_blocking(&wifi_mutex); - cyw43_arch_gpio_put(CYW43_WL_GPIO_LED_PIN, diodeState); // Update LED - udp_server_send(buffer, sizeof(buffer), TARGET_IP, TARGET_PORT); // Send message - mutex_exit(&wifi_mutex); - - // Increment counters - *packet_number = (*packet_number + 1) % 256; - *instruction = (*instruction + 1) % 256; - - diodeState = !diodeState; - - sleep_ms(2000); - } -} - -int main() -{ - stdio_init_all(); - - sleep_ms(2000); - - puts("Pi Starting..."); - - if(cyw43_arch_init()) - { - puts("WiFi init failed !"); - return -1; - } - - multicore_launch_core1(core1_entry); - - puts("WiFi is configuring..."); - - mutex_enter_blocking(&wifi_mutex); - wifi_operator_init_ap_mode(AP_SSID, AP_PASSWORD, AP_CHANNEL); - mutex_exit(&wifi_mutex); - - puts("WiFi configured !"); - - // Starts UDP client on core 0 - udp_client_init(UDP_CLIENT_PORT, custom_message_callback); - // UDP client receive data on port 4243 automatically and execute the message callback on each receptions - puts("UDP client started on core 0 !"); - - while(true) - { - mutex_enter_blocking(&wifi_mutex); - cyw43_arch_poll(); - mutex_exit(&wifi_mutex); - - tight_loop_contents(); - } - - udp_client_exit(); // Hehehe, I know you could forgot this one -} diff --git a/src/udp/udp_client.c b/src/udp/udp_client.c deleted file mode 100644 index 465f859..0000000 --- a/src/udp/udp_client.c +++ /dev/null @@ -1,62 +0,0 @@ -#include "udp_client.h" - -#include - -udp_client_t udp_client; - -static inline void handle_receive(struct pbuf *p, const ip_addr_t *addr, u16_t port) -{ - if(p->len >= 2) - { - uint8_t packet_number = ((uint8_t*)p->payload)[0]; - uint8_t instruction = ((uint8_t*)p->payload)[1]; - - udp_client.message_callback(packet_number, instruction, addr, port); - } - - pbuf_free(p); -} - -static void udp_receive_callback(void *arg, struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *addr, u16_t port) -{ - udp_client_t *udp_client_received_data = (udp_client_t *)arg; - handle_receive(p, addr, port); -} - -// Default callback func -static void default_message_callback(uint8_t packet_number, uint8_t instruction, const ip_addr_t *addr, u16_t port) -{ - printf("Reçu: packet=%d, instruction=%d depuis %s:%d\n", packet_number, instruction, ipaddr_ntoa(addr), port); -} - -void udp_client_init(int port, message_callback_t callback) -{ - udp_client.message_callback = callback ? callback : default_message_callback; - - udp_client.pcb = udp_new(); - if(udp_client.pcb == NULL) - { - puts("Error creating UDP client"); - return; - } - - udp_recv(udp_client.pcb, udp_receive_callback, &udp_client); - - err_t err = udp_bind(udp_client.pcb, IP_ADDR_ANY, port); - if(err != ERR_OK) - { - printf("Erreur bind UDP client: %d\n", err); - return; - } - - printf("UDP client started on port %d\n", port); -} - -void udp_client_exit(void) -{ - if(udp_client.pcb) - { - udp_remove(udp_client.pcb); - udp_client.pcb = NULL; - } -} diff --git a/src/udp/udp_client.h b/src/udp/udp_client.h deleted file mode 100644 index bb36890..0000000 --- a/src/udp/udp_client.h +++ /dev/null @@ -1,26 +0,0 @@ -#ifndef UDP_CLIENT_H -#define UDP_CLIENT_H - -#include -#include "lwip/udp.h" - -#define BUFFER_SIZE 1024 - -// Message callback deffinition -typedef void (*message_callback_t)(uint8_t packet_number, uint8_t instruction, const ip_addr_t *addr, uint16_t port); - -// Data in here is used by the hardware -typedef struct udp_client_t { - struct udp_pcb *pcb; // Like this - ip_addr_t local_addr; // Or this - uint16_t local_port; // So don't remove them, even if they are not used explicitely in the program - uint8_t recv_buffer[BUFFER_SIZE]; // Please (Not even change their position) - message_callback_t message_callback; -} udp_client_t; - -// Init udp client, set callback to NULL for the default callback -void udp_client_init(int port, message_callback_t callback); -// Exit udp client -void udp_client_exit(void); - -#endif // UDP_CLIENT_H \ No newline at end of file diff --git a/src/udp/udp_server.c b/src/udp/udp_server.c deleted file mode 100644 index 4dec0c7..0000000 --- a/src/udp/udp_server.c +++ /dev/null @@ -1,87 +0,0 @@ -#include "udp_server.h" - -#include -#include "pico/cyw43_arch.h" -#include "lwip/def.h" - -udp_server_t udp_server; - -void udp_server_init(int port) -{ - udp_server.pcb = udp_new(); - if(!udp_server.pcb) - { - puts("Error creating UDP server"); - return; - } - - err_t err = udp_bind(udp_server.pcb, IP_ADDR_ANY, port); - if(err != ERR_OK) - { - printf("Error binding UDP server: %d\n", err); - return; - } -} - -void udp_server_exit(void) -{ - if(udp_server.pcb) - { - udp_remove(udp_server.pcb); - udp_server.pcb = NULL; - } -} - -void udp_server_send(const uint8_t *data, size_t length, const char *ip, uint16_t port) -{ - ip4addr_aton(ip, &udp_server.remote_addr); - udp_server.remote_port = port; - - // Nombre maximum de tentatives - const int MAX_RETRIES = 3; - uint tries = 0; - - while(tries < MAX_RETRIES) - { - struct pbuf *p = pbuf_alloc(PBUF_TRANSPORT, length, PBUF_RAM); - if(p == NULL) - { - printf("Try %d - Error allocating pbuf\n", ++tries); - sleep_ms(100); // Wait before retry - continue; - } - - memcpy(p->payload, (char *)data, length); - err_t err = udp_sendto(udp_server.pcb, p, &udp_server.remote_addr, udp_server.remote_port); - pbuf_free(p); - - if (err == ERR_OK) - { - return; // Succès - } - else - { - const char* error_msg; - - switch(err) - { - case ERR_MEM: - error_msg = "Insuficient memory"; - break; - - case ERR_BUF: - error_msg = "Buffer full"; - break; - - default: - error_msg = "Unknown error"; - } - - printf("Try %d - Error send UDP: %d (%s)\n", ++tries, err, error_msg); - - sleep_ms(100); // Wait before retry - } - } - - printf("Error sending data after %d tries...\n", tries); -} diff --git a/src/udp/udp_server.h b/src/udp/udp_server.h deleted file mode 100644 index 6e8ff2b..0000000 --- a/src/udp/udp_server.h +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef UDP_SERVER_H -#define UDP_SERVER_H - -#include -#include "lwip/udp.h" - -typedef struct udp_server_t { - struct udp_pcb *pcb; - ip_addr_t remote_addr; - uint16_t remote_port; -} udp_server_t; - -void udp_server_init(int port); -void udp_server_exit(void); -void udp_server_send(const uint8_t *data, size_t length, const char *ip, uint16_t port); - -#endif // UDP_SERVER_H \ No newline at end of file diff --git a/src/wifi_operator/wifi_operator.c b/src/wifi_operator/wifi_operator.c deleted file mode 100644 index 53a6290..0000000 --- a/src/wifi_operator/wifi_operator.c +++ /dev/null @@ -1,69 +0,0 @@ -#include "wifi_operator.h" - -#include -#include "pico/cyw43_arch.h" -#include "lwip/netif.h" -#include "lwip/ip4_addr.h" - -void wifi_operator_init_ap_mode(const char *ssid, const char *password, int channel) -{ - cyw43_arch_gpio_put(CYW43_WL_GPIO_LED_PIN, 1); - - // Configuration IP pour le mode AP - ip4_addr_t ip, netmask, gateway; - IP4_ADDR(&ip, 192, 168, 128, 1); - IP4_ADDR(&netmask, 255, 255, 255, 0); - IP4_ADDR(&gateway, 192, 168, 128, 1); - - puts("WiFi is configuring..."); - - // Désactiver le mode d'économie d'énergie - cyw43_wifi_pm(&cyw43_state, CYW43_NO_POWERSAVE_MODE); - - // Activer le mode AP - cyw43_arch_enable_ap_mode(ssid, password, CYW43_AUTH_WPA2_AES_PSK); - - // Attendre que l'interface soit prête - int retry = 0; - while (netif_default == NULL && retry < 10) - { - sleep_ms(500); - retry++; - } - - if (netif_default == NULL) - { - puts("Error: wireless interface not initialised"); - return; - } - - // Configuration du canal WiFi - cyw43_wifi_ap_set_channel(&cyw43_state, channel); - - // Configuration de l'interface réseau - netif_set_up(netif_default); - netif_set_link_up(netif_default); - netif_set_addr(netif_default, &ip, &netmask, &gateway); - - puts("IP configuration ended !"); - puts("Access point activated !"); - printf("SSID : %s\n", ssid); - printf("Password : %s\n", password); - printf("Channel : %d\n", channel); -} - -void wifi_operator_init(const char *ssid, const char *password) -{ - // Mode client - cyw43_arch_enable_sta_mode(); - cyw43_arch_wifi_connect_timeout_ms(ssid, password, CYW43_AUTH_WPA2_AES_PSK, 30000); - puts("Connexion au réseau Wi-Fi..."); - int status = cyw43_wifi_link_status(&cyw43_state, CYW43_ITF_STA); - while (status != CYW43_LINK_UP) - { - sleep_ms(500); - puts("Connexion en cours..."); - status = cyw43_wifi_link_status(&cyw43_state, CYW43_ITF_STA); - } - puts("Connexion établie!"); -} diff --git a/src/wifi_operator/wifi_operator.h b/src/wifi_operator/wifi_operator.h deleted file mode 100644 index b68cf4d..0000000 --- a/src/wifi_operator/wifi_operator.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef WIFI_OPERATOR_H -#define WIFI_OPERATOR_H - -void wifi_operator_init_ap_mode(const char *ssid, const char *password, int channel); - -void wifi_operator_init(const char *ssid, const char *password); - -#endif // WIFI_OPERATOR_H \ No newline at end of file