diff --git a/Config.h b/Config.h new file mode 100644 index 0000000..72a7cbc --- /dev/null +++ b/Config.h @@ -0,0 +1,9 @@ +#ifndef _CONFIG_H +#define _CONFIG_H + +#define UDP_SERVER_PORT 4242 +#define UDP_CLIENT_PORT 4243 + +#define UDP_CLIENT_DATA_LEN 16 + +#endif // _CONFIG_H \ No newline at end of file diff --git a/PicoW_UDP.c b/PicoW_UDP.c index dee34ed..2df206e 100644 --- a/PicoW_UDP.c +++ b/PicoW_UDP.c @@ -1,172 +1,100 @@ -// Necessary includes from the Pico SDK -#include +#include "PicoW_UDP.h" + #include #include #include -#include +#include "Config.h" -#define CLIENT -//#define SERVER -#define STA_MODE -//#define AP_MODE - -#ifdef STA_MODE - -#define SSID "thinkpad-T440p" -#define PASSWORD "CDuKaka2000!" - -#endif // STA_MODE - -#ifdef AP_MODE - -#define AP_SSID "PicoAP" -#define AP_PASSWORD "PicoPassword!" -#define AP_CHANNEL 3 - -#endif // AP_MODE - -#ifdef CLIENT - -#define CLIENT_PORT 4243 - -static void udp_recv_callback(void *arg, struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *addr, u16_t port) +inline int udp_server_init(struct udp_server_t *udp_server) { - puts("Callback"); - - if(p->len == 1) + udp_server->pcb = udp_new(); + if(udp_server->pcb == NULL) { - printf("a:%d\n", ((uint8_t *)p->payload)[0]); + puts("Error creating UDP server pcb."); + return PICO_ERROR_GENERIC; } + + err_t err = udp_bind(udp_server->pcb, IP_ADDR_ANY, UDP_SERVER_PORT); + if(err) + { + printf("Error binding UDP server: %d\n", err); + return err; + } + + return PICO_OK; +} + +inline void udp_server_exit(struct udp_server_t *udp_server) +{ + if(udp_server->pcb) + { + udp_remove(udp_server->pcb); + udp_server->pcb = NULL; + } +} + +int udp_server_send(struct udp_server_t *udp_server, void *data, uint16_t len) +{ + struct pbuf *p = pbuf_alloc(PBUF_TRANSPORT, len, PBUF_RAM); + if(p == NULL) + { + puts("Pbuf memory allocation error"); + return PICO_ERROR_INSUFFICIENT_RESOURCES; + } + + memcpy((uint8_t *)p->payload, data, len); + + err_t err = udp_sendto(udp_server->pcb, p, IP_ADDR_ANY, UDP_CLIENT_PORT); + + pbuf_free(p); + + if(err) + { + printf("UDP send error : %d\n", err); + return err; + } + + return PICO_OK; +} + +static inline void builtin_udp_client_callback(void *arg, struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *addr, u16_t port) +{ + struct udp_client_t *udp_client = arg; + + if(p->len != UDP_CLIENT_DATA_LEN) + return; + + memcpy(udp_client->data, p->payload, UDP_CLIENT_DATA_LEN); + pbuf_free(p); } -#endif // CLIENT - -int main() +inline int udp_client_init(struct udp_client_t *udp_client, udp_recv_fn callback) { - stdio_init_all(); - - sleep_ms(2000); - - puts("Pi Starting..."); - - if(cyw43_arch_init_with_country(CYW43_COUNTRY_FRANCE)) + udp_client->pcb = udp_new(); + if(udp_client->pcb == NULL) { - puts("CYW43 arch init failed"); - return -1; + puts("Error creating UDP server pcb."); + return PICO_ERROR_GENERIC; } - if(cyw43_wifi_pm(&cyw43_state, CYW43_NO_POWERSAVE_MODE)) + err_t err = udp_bind(udp_client->pcb, IP_ADDR_ANY, UDP_CLIENT_PORT); + if(err) { - puts("CYW43 no powersave mode failed"); - return -1; + printf("Error binding UDP server: %d\n", err); + return err; } - puts("CYW43 arch initialized"); + udp_recv(udp_client->pcb, callback ? callback : builtin_udp_client_callback, &udp_client); -#ifdef STA_MODE + return PICO_OK; +} - cyw43_arch_enable_sta_mode(); - - for(int error_code = 1; error_code; ) +inline void udp_client_exit(struct udp_client_t *udp_client) +{ + if(udp_client->pcb) { - printf("WiFi connection attempt to \"%s\"\n", SSID); - - 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"); - -#endif // STA_MODE - -#ifdef AP_MODE - - cyw43_arch_enable_ap_mode(AP_SSID, AP_PASSWORD, CYW43_AUTH_WPA2_AES_PSK); - - cyw43_wifi_ap_set_channel(&cyw43_state, AP_CHANNEL); - - puts("AP mode enabled"); - -#endif //AP_MODE - -#ifdef CLIENT - - struct udp_pcb *pcb = udp_new(); - - if(!pcb) - { - puts("UDP pcb init failed"); - return -1; - } - - udp_recv(pcb, udp_recv_callback, NULL); - - if(udp_bind(pcb, IP4_ADDR_ANY, CLIENT_PORT)) - { - puts("UDP pcb bind failed"); - return -1; - } - -#endif // CLIENT - - // ========================== Main loop ========================== - while(true) - { - cyw43_arch_poll(); - -#ifdef STA_MODE - 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); - } -#endif // STA_MODE - - tight_loop_contents(); + udp_remove(udp_client->pcb); + udp_client->pcb = NULL; } } diff --git a/PicoW_UDP.h b/PicoW_UDP.h index e69de29..1266a8e 100644 --- a/PicoW_UDP.h +++ b/PicoW_UDP.h @@ -0,0 +1,46 @@ +#ifndef _PICOW_UDP_H +#define _PICOW_UDP_H + +#include +#include "Config.h" + +struct udp_server_t { + struct udp_pcb *pcb; +}; + +struct udp_client_t { + struct udp_pcb *pcb; + uint8_t data[UDP_CLIENT_DATA_LEN]; +}; + +/** + * @brief Init an udp server with Config.h parameters. + * + * @param udp_server Pointer to the pre allocated udp_server_t to init + */ +int udp_server_init(struct udp_server_t *udp_server); + +/** + * @brief Exit an udp server. + * + * @param udp_server Pointer to the udp_server_t to exit + */ +void udp_server_exit(struct udp_server_t *udp_server); + +/** + * @brief Send message on an udp server. + * + * @param udp_server Pointer to the udp server to send with + * @param data Pointer to the data to send + * @param len Length of the message to send in bytes + */ +int udp_server_send(struct udp_server_t *udp_server, void *data, uint16_t len); + +/** + * @brief + */ +int udp_client_init(struct udp_client_t *udp_client, udp_recv_fn callback); + +void udp_client_exit(struct udp_client_t *udp_client); + +#endif // _PICOW_UDP_H \ No newline at end of file diff --git a/README.md b/README.md index e3b754b..81a8c6d 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,3 @@ # PicoW_UDP_Lib -Library for rapsberry pi pico to communicate over WIFI \ No newline at end of file +Library for rapsberry pi pico to communicate with UDP over WiFi \ No newline at end of file