From 85f11d50ca1012c6a43515793b67783fde21c205 Mon Sep 17 00:00:00 2001 From: Krzysztof Mazur Date: Sun, 13 Nov 2022 17:52:04 +0100 Subject: [PATCH] Add mDNS functionality Closes #9 --- src/CMakeLists.txt | 10 ++++- src/access_point.cpp | 39 ------------------- src/access_point.h | 7 ---- src/lwipopts.h | 4 ++ src/main.cpp | 30 ++------------- src/network_utils.cpp | 88 +++++++++++++++++++++++++++++++++++++++++++ src/network_utils.h | 11 ++++++ 7 files changed, 115 insertions(+), 74 deletions(-) delete mode 100644 src/access_point.cpp delete mode 100644 src/access_point.h create mode 100644 src/network_utils.cpp create mode 100644 src/network_utils.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 3469a77..c3c53aa 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -18,10 +18,17 @@ execute_process(COMMAND ) file(RENAME fsdata.c my_fsdata.c) + +# TODO fix after https://github.com/georgerobotics/cyw43-driver/pull/39 gets into the SDK +set(BROKEN_FILE ${PICO_CYW43_DRIVER_PATH}/src/cyw43_lwip.c) +file(READ ${BROKEN_FILE} FILE_CONTENTS) +string(REPLACE "LWIP_MDNS_RESPONDER" "LWIP_1_MDNS_RESPONDER" FILE_CONTENTS "${FILE_CONTENTS}") +file(WRITE ${BROKEN_FILE} "${FILE_CONTENTS}") + add_executable(${PROGRAM_NAME} main.cpp double_reset_detector.cpp - access_point.cpp + network_utils.cpp http_server.cpp ) target_compile_definitions(${PROGRAM_NAME} PRIVATE @@ -35,6 +42,7 @@ target_link_libraries(${PROGRAM_NAME} cyw43_driver_base pico_cyw43_arch_lwip_threadsafe_background pico_lwip_http + pico_lwip_mdns pico_stdlib hardware_adc ) diff --git a/src/access_point.cpp b/src/access_point.cpp deleted file mode 100644 index 3484193..0000000 --- a/src/access_point.cpp +++ /dev/null @@ -1,39 +0,0 @@ -#include "access_point.h" - -#include -#include -#include - -namespace access_point { - -int stop_access_point(){ - autoip_stop(&cyw43_state.netif[CYW43_ITF_AP]); - return 0; -} - -int setup_access_point() { - if (!cyw43_is_initialized(&cyw43_state)){ - if (cyw43_arch_init()) { - printf("failed to initialise\n"); - return 1; - } - } - - const char *ap_name = "picow_webserver"; - const char *password = NULL; - - cyw43_arch_enable_ap_mode(ap_name, password, CYW43_AUTH_WPA2_AES_PSK); - // sleep mostly to let serial monitor catch the ip log. probably to be removed once mDNS is set up - sleep_ms(2000); - - autoip_start(&cyw43_state.netif[CYW43_ITF_AP]); - auto link_local_ip_addr = netif_autoip_data(&cyw43_state.netif[CYW43_ITF_AP])->llipaddr.addr; - printf("IP Address: %lu.%lu.%lu.%lu\n", - link_local_ip_addr & 0xFF, - (link_local_ip_addr >> 8) & 0xFF, - (link_local_ip_addr >> 16) & 0xFF, - link_local_ip_addr >> 24); - return 0; -} - -} // namespace access_point \ No newline at end of file diff --git a/src/access_point.h b/src/access_point.h deleted file mode 100644 index 045f2f7..0000000 --- a/src/access_point.h +++ /dev/null @@ -1,7 +0,0 @@ -#pragma once - -namespace access_point { - int stop_access_point(); - - int setup_access_point(); -} // namespace access_point \ No newline at end of file diff --git a/src/lwipopts.h b/src/lwipopts.h index 4f01973..f2c403a 100644 --- a/src/lwipopts.h +++ b/src/lwipopts.h @@ -57,6 +57,10 @@ #define LWIP_AUTOIP 1 +#define LWIP_IGMP 1 +#define LWIP_MDNS_RESPONDER 1 +#define LWIP_NUM_NETIF_CLIENT_DATA (LWIP_MDNS_RESPONDER) + #define LWIP_HTTPD 1 #define LWIP_HTTPD_SSI 1 // don't include the tag comment - less work for the CPU, but may be harder to debug diff --git a/src/main.cpp b/src/main.cpp index ebd65dc..7469b3c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -7,38 +7,14 @@ #include "double_reset_detector.h" #include "http_server.h" -#include "access_point.h" +#include "network_utils.h" #include "lwipopts.h" -namespace double_reset_detector { - extern bool double_reset_detected; -} - -int connect_to_wifi() { - cyw43_arch_enable_sta_mode(); - // this seems to be the best be can do using the predefined `cyw43_pm_value` macro: - // cyw43_wifi_pm(&cyw43_state, CYW43_PERFORMANCE_PM); - // however it doesn't use the `CYW43_NO_POWERSAVE_MODE` value, so we do this instead: - cyw43_wifi_pm(&cyw43_state, cyw43_pm_value(CYW43_NO_POWERSAVE_MODE, 20, 1, 1, 1)); - - printf("Connecting to WiFi...\n"); - if (cyw43_arch_wifi_connect_timeout_ms(WIFI_SSID, WIFI_PASSWORD, CYW43_AUTH_WPA2_AES_PSK, 30000)) { - printf("failed to connect.\n"); - return ERR_CONN; - } else { - printf("Connected.\n"); - - auto ip_addr = cyw43_state.netif[CYW43_ITF_STA].ip_addr.addr; - printf("IP Address: %lu.%lu.%lu.%lu\n", ip_addr & 0xFF, (ip_addr >> 8) & 0xFF, (ip_addr >> 16) & 0xFF, ip_addr >> 24); - } - return ERR_OK; -} - void setup() { if (double_reset_detector::double_reset_detected) { printf("Double reset detected!\n"); - access_point::setup_access_point(); + network_utils::setup_access_point(); http_server::start_http_server(); while (true) { cyw43_arch_gpio_put(CYW43_WL_GPIO_LED_PIN, 1); @@ -59,7 +35,7 @@ int main() { // turn on LED to distinguish from BOOTSEL mode cyw43_arch_gpio_put(CYW43_WL_GPIO_LED_PIN, 1); setup(); - if (connect_to_wifi() != ERR_OK) { + if (network_utils::connect_to_wifi() != ERR_OK) { return 1; } http_server::start_http_server(); diff --git a/src/network_utils.cpp b/src/network_utils.cpp new file mode 100644 index 0000000..c68c351 --- /dev/null +++ b/src/network_utils.cpp @@ -0,0 +1,88 @@ +#include "network_utils.h" + +extern "C" { +#include +} +#include +#include +#include +#include + +namespace network_utils { + +err_t setup_mdns(struct netif *netif){ + const auto hostname = "pico-w-webserver"; + mdns_resp_init(); + return mdns_resp_add_netif(netif, hostname); +} + +err_t connect_to_wifi() { + cyw43_arch_enable_sta_mode(); + // this seems to be the best be can do using the predefined `cyw43_pm_value` macro: + // cyw43_wifi_pm(&cyw43_state, CYW43_PERFORMANCE_PM); + // however it doesn't use the `CYW43_NO_POWERSAVE_MODE` value, so we do this instead: + cyw43_wifi_pm(&cyw43_state, cyw43_pm_value(CYW43_NO_POWERSAVE_MODE, 20, 1, 1, 1)); + auto& netif = cyw43_state.netif[CYW43_ITF_STA]; + const auto err = setup_mdns(&netif); + if (err != ERR_OK) { + return err; + } + + printf("Connecting to WiFi...\n"); + if (cyw43_arch_wifi_connect_timeout_ms(WIFI_SSID, WIFI_PASSWORD, CYW43_AUTH_WPA2_AES_PSK, 30000)) { + printf("failed to connect.\n"); + return ERR_CONN; + } else { + printf("Connected.\n"); + + auto ip_addr = netif.ip_addr.addr; + printf("IP Address: %lu.%lu.%lu.%lu\n", ip_addr & 0xFF, (ip_addr >> 8) & 0xFF, (ip_addr >> 16) & 0xFF, ip_addr >> 24); + } + return ERR_OK; +} + +err_t stop_access_point(){ + auto& netif = cyw43_state.netif[CYW43_ITF_AP]; + auto err = autoip_stop(&netif); + if (err != ERR_OK){ + return err; + } + err = mdns_resp_remove_netif(&netif); + if (err != ERR_OK){ + return err; + } + return ERR_OK; +} + +err_t setup_access_point() { + if (!cyw43_is_initialized(&cyw43_state)){ + if (cyw43_arch_init()) { + printf("failed to initialise\n"); + return ERR_ABRT; + } + } + + const char *ap_name = "picow_webserver"; + const char *password = NULL; + + cyw43_arch_enable_ap_mode(ap_name, password, CYW43_AUTH_WPA2_AES_PSK); + // sleep mostly to let serial monitor catch the ip log. probably to be removed once mDNS is set up + sleep_ms(2000); + + auto& netif = cyw43_state.netif[CYW43_ITF_AP]; + const auto err = setup_mdns(&netif); + if (err != ERR_OK) { + return err; + } + + autoip_start(&netif); + auto link_local_ip_addr = netif_autoip_data(&netif)->llipaddr.addr; + printf("IP Address: %lu.%lu.%lu.%lu\n", + link_local_ip_addr & 0xFF, + (link_local_ip_addr >> 8) & 0xFF, + (link_local_ip_addr >> 16) & 0xFF, + link_local_ip_addr >> 24); + return ERR_OK; +} + +} // namespace network_utils \ No newline at end of file diff --git a/src/network_utils.h b/src/network_utils.h new file mode 100644 index 0000000..6e88eb1 --- /dev/null +++ b/src/network_utils.h @@ -0,0 +1,11 @@ +#pragma once + +#include + +namespace network_utils { + err_t connect_to_wifi(); + + err_t stop_access_point(); + + err_t setup_access_point(); +} // namespace network_utils \ No newline at end of file