/** * Copyright (c) 2022 Raspberry Pi (Trading) Ltd. * * SPDX-License-Identifier: BSD-3-Clause */ #include #include "pico/stdlib.h" #include "pico/cyw43_arch.h" #include "lwip/pbuf.h" #include "lwip/tcp.h" #include "dhcpserver.h" #ifndef USE_LED #define USE_LED 1 #endif #define TCP_PORT 80 #define DEBUG_printf printf typedef struct TCP_ASERVER_T_ { struct tcp_pcb *server_pcb; struct tcp_pcb *client_pcb; bool complete; } TCP_SERVER_T; static err_t tcp_server_close(void *arg) { TCP_SERVER_T *state = (TCP_SERVER_T*)arg; err_t err = ERR_OK; if (state->client_pcb != NULL) { tcp_arg(state->client_pcb, NULL); tcp_poll(state->client_pcb, NULL, 0); tcp_sent(state->client_pcb, NULL); tcp_recv(state->client_pcb, NULL); tcp_err(state->client_pcb, NULL); err = tcp_close(state->client_pcb); if (err != ERR_OK) { DEBUG_printf("close failed %d, calling abort\n", err); tcp_abort(state->client_pcb); err = ERR_ABRT; } state->client_pcb = NULL; } if (state->server_pcb) { tcp_arg(state->server_pcb, NULL); tcp_close(state->server_pcb); state->server_pcb = NULL; } return err; } static err_t tcp_ap_result(void *arg, int status) { TCP_SERVER_T *state = (TCP_SERVER_T*)arg; if (status == 0) { DEBUG_printf("test success\n"); } else { DEBUG_printf("test failed %d\n", status); } state->complete = true; return tcp_server_close(arg); } static err_t tcp_server_accept(void *arg, struct tcp_pcb *client_pcb, err_t err) { // TCP_SERVER_T *state = (TCP_SERVER_T*)arg; if (err != ERR_OK || client_pcb == NULL) { DEBUG_printf("Failure in accept\n"); tcp_ap_result(arg, err); return ERR_VAL; } DEBUG_printf("Client connected\n"); /*state->client_pcb = client_pcb; tcp_arg(client_pcb, state); tcp_sent(client_pcb, tcp_server_sent); tcp_recv(client_pcb, tcp_server_recv); tcp_poll(client_pcb, tcp_server_poll, POLL_TIME_S * 2); tcp_err(client_pcb, tcp_server_err); return tcp_server_send_data(arg, state->client_pcb);*/ return ERR_OK; } static bool tcp_server_open(void *arg) { TCP_SERVER_T *state = (TCP_SERVER_T*)arg; DEBUG_printf("Starting server on port %u\n", TCP_PORT); struct tcp_pcb *pcb = tcp_new_ip_type(IPADDR_TYPE_ANY); if (!pcb) { DEBUG_printf("failed to create pcb\n"); return false; } err_t err = tcp_bind(pcb, NULL, TCP_PORT); if (err) { DEBUG_printf("failed to bind to port %d\n"); return false; } state->server_pcb = tcp_listen_with_backlog(pcb, 1); if (!state->server_pcb) { DEBUG_printf("failed to listen\n"); if (pcb) { tcp_close(pcb); } return false; } tcp_arg(state->server_pcb, state); tcp_accept(state->server_pcb, tcp_server_accept); return true; } int main() { stdio_init_all(); TCP_SERVER_T *state = calloc(1, sizeof(TCP_SERVER_T)); if (!state) { DEBUG_printf("failed to allocate state\n"); return 1; } if (cyw43_arch_init()) { printf("failed to initialise\n"); return 1; } const char *ap_name = "picow_test"; #if 1 const char *password = "password"; #else const char *password = NULL; #endif cyw43_arch_enable_ap_mode(ap_name, password, CYW43_AUTH_WPA2_AES_PSK); ip4_addr_t gw, mask; IP4_ADDR(&gw, 192, 168, 4, 1); IP4_ADDR(&mask, 255, 255, 255, 0); // Start the dhcp server dhcp_server_t dhcp_server; dhcp_server_init(&dhcp_server, &gw, &mask); if (!tcp_server_open(state)) { tcp_ap_result(state, -1); } while(!state->complete) { #if USE_LED static absolute_time_t led_time; static int led_on = true; // Invert the led if (absolute_time_diff_us(get_absolute_time(), led_time) < 0) { led_on = !led_on; cyw43_arch_gpio_put(CYW43_WL_GPIO_LED_PIN, led_on); led_time = make_timeout_time_ms(1000); } #endif // the following #ifdef is only here so this same example can be used in multiple modes; // you do not need it in your code #if PICO_CYW43_ARCH_POLL // if you are using pico_cyw43_arch_poll, then you must poll periodically from your // main loop (not from a timer) to check for WiFi driver or lwIP work that needs to be done. cyw43_arch_poll(); sleep_ms(1); #else // if you are not using pico_cyw43_arch_poll, then WiFI driver and lwIP work // is done via interrupt in the background. This sleep is just an example of some (blocking) // work you might be doing. sleep_ms(1000); #endif } dhcp_server_deinit(&dhcp_server); cyw43_arch_deinit(); return 0; }