diff --git a/examples/common_components/protocol_examples_common/CMakeLists.txt b/examples/common_components/protocol_examples_common/CMakeLists.txt new file mode 100644 index 0000000000..784909da03 --- /dev/null +++ b/examples/common_components/protocol_examples_common/CMakeLists.txt @@ -0,0 +1,5 @@ +set(COMPONENT_SRCS "connect.c" + "stdin_out.c") +set(COMPONENT_ADD_INCLUDEDIRS "include") + +register_component() diff --git a/examples/common_components/protocol_examples_common/Kconfig.projbuild b/examples/common_components/protocol_examples_common/Kconfig.projbuild new file mode 100644 index 0000000000..fe095582b9 --- /dev/null +++ b/examples/common_components/protocol_examples_common/Kconfig.projbuild @@ -0,0 +1,153 @@ +menu "Example Connection Configuration" + + choice EXAMPLE_CONNECT_INTERFACE + prompt "Connect using" + default EXAMPLE_CONNECT_WIFI + help + Protocol examples can use Wi-Fi or Ethernet to connect to the network. + Choose which interface to use. + + config EXAMPLE_CONNECT_WIFI + bool "Wi-Fi" + + config EXAMPLE_CONNECT_ETHERNET + bool "Ethernet" + + endchoice + + config EXAMPLE_WIFI_SSID + depends on EXAMPLE_CONNECT_WIFI + string "WiFi SSID" + default "myssid" + help + SSID (network name) for the example to connect to. + + config EXAMPLE_WIFI_PASSWORD + depends on EXAMPLE_CONNECT_WIFI + string "WiFi Password" + default "mypassword" + help + WiFi password (WPA or WPA2) for the example to use. + Can be left blank if the network has no security set. + + + choice PHY_MODEL + prompt "Ethernet PHY" + depends on EXAMPLE_CONNECT_ETHERNET + default CONFIG_PHY_TLK110 + help + Select the PHY driver to use for the example. + + config PHY_IP101 + bool "IP101" + help + IP101 is a single port 10/100 MII/RMII/TP/Fiber Fast Ethernet Transceiver. + Goto http://www.icplus.com.tw/pp-IP101G.html for more information about it. + + config PHY_TLK110 + bool "TI TLK110 PHY" + help + Select this to use the TI TLK110 PHY + + config PHY_LAN8720 + bool "Microchip LAN8720 PHY" + help + Select this to use the Microchip LAN8720 PHY + + endchoice + + + config PHY_ADDRESS + int "PHY Address (0-31)" + depends on EXAMPLE_CONNECT_ETHERNET + default 31 + range 0 31 + help + Select the PHY Address (0-31) for the hardware configuration and PHY model. + TLK110 default 31 + LAN8720 default 1 or 0 + + + choice PHY_CLOCK_MODE + prompt "EMAC clock mode" + depends on EXAMPLE_CONNECT_ETHERNET + default PHY_CLOCK_GPIO0_IN + help + Select external (input on GPIO0) or internal (output on GPIO16 or GPIO17) clock + + + config PHY_CLOCK_GPIO0_IN + bool "GPIO0 input" + depends on EXAMPLE_CONNECT_ETHERNET + help + Input of 50MHz PHY clock on GPIO0. + + config PHY_CLOCK_GPIO0_OUT + bool "GPIO0 Output" + help + Output the internal 50MHz RMII clock on GPIO0. + + config PHY_CLOCK_GPIO16_OUT + bool "GPIO16 output" + depends on EXAMPLE_CONNECT_ETHERNET + help + Output the internal 50MHz APLL clock on GPIO16. + + config PHY_CLOCK_GPIO17_OUT + bool "GPIO17 output (inverted)" + depends on EXAMPLE_CONNECT_ETHERNET + help + Output the internal 50MHz APLL clock on GPIO17 (inverted signal). + + endchoice + + config PHY_CLOCK_MODE + int + depends on EXAMPLE_CONNECT_ETHERNET + default 0 if PHY_CLOCK_GPIO0_IN + default 1 if PHY_CLOCK_GPIO0_OUT + default 2 if PHY_CLOCK_GPIO16_OUT + default 3 if PHY_CLOCK_GPIO17_OUT + + + config PHY_USE_POWER_PIN + bool "Use PHY Power (enable/disable) pin" + depends on EXAMPLE_CONNECT_ETHERNET + default y + help + Use a GPIO "power pin" to power the PHY on/off during operation. + Consult the example README for more details + + config PHY_POWER_PIN + int "PHY Power GPIO" + depends on EXAMPLE_CONNECT_ETHERNET + default 17 + range 0 33 + depends on PHY_USE_POWER_PIN + help + GPIO number to use for powering on/off the PHY. + + config PHY_SMI_MDC_PIN + int "SMI MDC Pin" + depends on EXAMPLE_CONNECT_ETHERNET + default 23 + range 0 33 + help + GPIO number to use for SMI clock output MDC to PHY. + + config PHY_SMI_MDIO_PIN + int "SMI MDIO Pin" + depends on EXAMPLE_CONNECT_ETHERNET + default 18 + range 0 33 + help + GPIO number to use for SMI data pin MDIO to/from PHY. + + config EXAMPLE_CONNECT_IPV6 + bool "Obtain IPv6 link-local address" + default y + help + By default, examples will wait until IPv4 and IPv6 addresses are obtained. + Disable this option if the network does not support IPv6. + +endmenu diff --git a/examples/common_components/protocol_examples_common/component.mk b/examples/common_components/protocol_examples_common/component.mk new file mode 100644 index 0000000000..e69de29bb2 diff --git a/examples/common_components/protocol_examples_common/connect.c b/examples/common_components/protocol_examples_common/connect.c new file mode 100644 index 0000000000..37d9df6dbe --- /dev/null +++ b/examples/common_components/protocol_examples_common/connect.c @@ -0,0 +1,291 @@ +/* Common functions for protocol examples, to establish Wi-Fi or Ethernet connection. + + This example code is in the Public Domain (or CC0 licensed, at your option.) + + Unless required by applicable law or agreed to in writing, this + software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + CONDITIONS OF ANY KIND, either express or implied. + */ + +#include +#include "protocol_examples_common.h" +#include "sdkconfig.h" +#include "esp_event.h" +#include "esp_wifi.h" +#include "esp_eth.h" +#include "esp_log.h" +#include "tcpip_adapter.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "freertos/event_groups.h" +#include "lwip/err.h" +#include "lwip/sys.h" + +#define GOT_IPV4_BIT BIT(0) +#define GOT_IPV6_BIT BIT(1) + +#ifdef CONFIG_EXAMPLE_CONNECT_IPV6 +#define CONNECTED_BITS (GOT_IPV4_BIT | GOT_IPV6_BIT) +#else +#define CONNECTED_BITS (GOT_IPV4_BIT) +#endif + +static EventGroupHandle_t s_connect_event_group; +static ip4_addr_t s_ip_addr; +static const char* s_connection_name; + +#ifdef CONFIG_EXAMPLE_CONNECT_IPV6 +static ip6_addr_t s_ipv6_addr; +#endif + + +static const char *TAG = "example_connect"; + +/* set up connection, Wi-Fi or Ethernet */ +static void start(); + +/* tear down connection, release resources */ +static void stop(); + +static void on_got_ip(void* arg, esp_event_base_t event_base, + int32_t event_id, void* event_data) +{ + ip_event_got_ip_t* event = (ip_event_got_ip_t*) event_data; + memcpy(&s_ip_addr, &event->ip_info.ip, sizeof(s_ip_addr)); + xEventGroupSetBits(s_connect_event_group, GOT_IPV4_BIT); +} + +#ifdef CONFIG_EXAMPLE_CONNECT_IPV6 + +static void on_got_ipv6(void* arg, esp_event_base_t event_base, + int32_t event_id, void* event_data) +{ + ip_event_got_ip6_t* event = (ip_event_got_ip6_t*) event_data; + memcpy(&s_ipv6_addr, &event->ip6_info.ip, sizeof(s_ipv6_addr)); + xEventGroupSetBits(s_connect_event_group, GOT_IPV6_BIT); +} + +#endif // CONFIG_EXAMPLE_CONNECT_IPV6 + +esp_err_t example_connect() +{ + if (s_connect_event_group != NULL) { + return ESP_ERR_INVALID_STATE; + } + s_connect_event_group = xEventGroupCreate(); + start(); + xEventGroupWaitBits(s_connect_event_group, CONNECTED_BITS, true, true, portMAX_DELAY); + ESP_LOGI(TAG, "Connected to %s", s_connection_name); + ESP_LOGI(TAG, "IPv4 address: " IPSTR, IP2STR(&s_ip_addr)); +#ifdef CONFIG_EXAMPLE_CONNECT_IPV6 + ESP_LOGI(TAG, "IPv6 address: " IPV6STR, IPV62STR(s_ipv6_addr)); +#endif + return ESP_OK; +} + +esp_err_t example_disconnect() +{ + if (s_connect_event_group == NULL) { + return ESP_ERR_INVALID_STATE; + } + vEventGroupDelete(s_connect_event_group); + s_connect_event_group = NULL; + stop(); + ESP_LOGI(TAG, "Disconnected from %s", s_connection_name); + s_connection_name = NULL; + return ESP_OK; +} + +#ifdef CONFIG_EXAMPLE_CONNECT_WIFI + +static void on_wifi_disconnect(void* arg, esp_event_base_t event_base, + int32_t event_id, void* event_data) +{ + ESP_LOGI(TAG, "Wi-Fi disconnected, trying to reconnect..."); + ESP_ERROR_CHECK( esp_wifi_connect() ); +} + +#ifdef CONFIG_EXAMPLE_CONNECT_IPV6 + +static void on_wifi_connect(void* arg, esp_event_base_t event_base, + int32_t event_id, void* event_data) +{ + tcpip_adapter_create_ip6_linklocal(TCPIP_ADAPTER_IF_STA); +} + +#endif // CONFIG_EXAMPLE_CONNECT_IPV6 + +static void start() +{ + wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); + ESP_ERROR_CHECK(esp_wifi_init(&cfg)); + + ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_STA_DISCONNECTED, &on_wifi_disconnect, NULL)); + ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &on_got_ip, NULL)); +#ifdef CONFIG_EXAMPLE_CONNECT_IPV6 + ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_STA_CONNECTED, &on_wifi_connect, NULL)); + ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_GOT_IP6, &on_got_ipv6, NULL)); +#endif + + ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_RAM)); + wifi_config_t wifi_config = { + .sta = { + .ssid = CONFIG_EXAMPLE_WIFI_SSID, + .password = CONFIG_EXAMPLE_WIFI_PASSWORD, + }, + }; + ESP_LOGI(TAG, "Connecting to %s...", wifi_config.sta.ssid); + ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA)); + ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config)); + ESP_ERROR_CHECK(esp_wifi_start()); + ESP_ERROR_CHECK(esp_wifi_connect()); + s_connection_name = CONFIG_EXAMPLE_WIFI_SSID; +} + +static void stop() +{ + ESP_ERROR_CHECK(esp_event_handler_unregister(WIFI_EVENT, WIFI_EVENT_STA_DISCONNECTED, &on_wifi_disconnect)); + ESP_ERROR_CHECK(esp_event_handler_unregister(IP_EVENT, IP_EVENT_STA_GOT_IP, &on_got_ip)); +#ifdef CONFIG_EXAMPLE_CONNECT_IPV6 + ESP_ERROR_CHECK(esp_event_handler_unregister(IP_EVENT, IP_EVENT_GOT_IP6, &on_got_ipv6)); + ESP_ERROR_CHECK(esp_event_handler_unregister(WIFI_EVENT, WIFI_EVENT_STA_CONNECTED, &on_wifi_connect)); +#endif + ESP_ERROR_CHECK(esp_wifi_stop()); + ESP_ERROR_CHECK(esp_wifi_deinit()); +} +#endif // CONFIG_EXAMPLE_CONNECT_WIFI + + +#ifdef CONFIG_EXAMPLE_CONNECT_ETHERNET + +#include "driver/gpio.h" + +#ifdef CONFIG_PHY_LAN8720 +#include "eth_phy/phy_lan8720.h" +#define DEFAULT_ETHERNET_PHY_CONFIG phy_lan8720_default_ethernet_config +#endif +#ifdef CONFIG_PHY_TLK110 +#include "eth_phy/phy_tlk110.h" +#define DEFAULT_ETHERNET_PHY_CONFIG phy_tlk110_default_ethernet_config +#elif CONFIG_PHY_IP101 +#include "eth_phy/phy_ip101.h" +#define DEFAULT_ETHERNET_PHY_CONFIG phy_ip101_default_ethernet_config +#endif + +#define PIN_PHY_POWER CONFIG_PHY_POWER_PIN +#define PIN_SMI_MDC CONFIG_PHY_SMI_MDC_PIN +#define PIN_SMI_MDIO CONFIG_PHY_SMI_MDIO_PIN + +#ifdef CONFIG_PHY_USE_POWER_PIN +/** + * @brief re-define power enable func for phy + * + * @param enable true to enable, false to disable + * + * @note This function replaces the default PHY power on/off function. + * If this GPIO is not connected on your device (and PHY is always powered), + * you can use the default PHY-specific power on/off function. + */ +static void phy_device_power_enable_via_gpio(bool enable) +{ + assert(DEFAULT_ETHERNET_PHY_CONFIG.phy_power_enable); + + if (!enable) { + DEFAULT_ETHERNET_PHY_CONFIG.phy_power_enable(false); + } + + gpio_pad_select_gpio(PIN_PHY_POWER); + gpio_set_direction(PIN_PHY_POWER, GPIO_MODE_OUTPUT); + if (enable == true) { + gpio_set_level(PIN_PHY_POWER, 1); + ESP_LOGI(TAG, "Power On Ethernet PHY"); + } else { + gpio_set_level(PIN_PHY_POWER, 0); + ESP_LOGI(TAG, "Power Off Ethernet PHY"); + } + + vTaskDelay(1); // Allow the power up/down to take effect, min 300us + + if (enable) { + /* call the default PHY-specific power on function */ + DEFAULT_ETHERNET_PHY_CONFIG.phy_power_enable(true); + } +} +#endif + +/** + * @brief gpio specific init + * + * @note RMII data pins are fixed in esp32: + * TXD0 <=> GPIO19 + * TXD1 <=> GPIO22 + * TX_EN <=> GPIO21 + * RXD0 <=> GPIO25 + * RXD1 <=> GPIO26 + * CLK <=> GPIO0 + * + */ +static void eth_gpio_config_rmii(void) +{ + phy_rmii_configure_data_interface_pins(); + phy_rmii_smi_configure_pins(PIN_SMI_MDC, PIN_SMI_MDIO); +} + +#ifdef CONFIG_EXAMPLE_CONNECT_IPV6 + +/** Event handler for Ethernet events */ +static void on_eth_event(void* arg, esp_event_base_t event_base, + int32_t event_id, void* event_data) +{ + switch (event_id) { + case ETHERNET_EVENT_CONNECTED: + ESP_LOGI(TAG, "Ethernet Link Up"); + tcpip_adapter_create_ip6_linklocal(TCPIP_ADAPTER_IF_ETH); + break; + default: + break; + } +} + +#endif // CONFIG_EXAMPLE_CONNECT_IPV6 + +static void start() +{ + eth_config_t config = DEFAULT_ETHERNET_PHY_CONFIG; + config.phy_addr = CONFIG_PHY_ADDRESS; + config.gpio_config = eth_gpio_config_rmii; + config.tcpip_input = tcpip_adapter_eth_input; + config.clock_mode = CONFIG_PHY_CLOCK_MODE; + +#ifdef CONFIG_PHY_USE_POWER_PIN + /* Replace the default 'power enable' function with an example-specific one + that toggles a power GPIO. */ + config.phy_power_enable = phy_device_power_enable_via_gpio; +#endif + + ESP_ERROR_CHECK(esp_eth_init(&config)); + + ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_ETH_GOT_IP, &on_got_ip, NULL)); +#ifdef CONFIG_EXAMPLE_CONNECT_IPV6 + ESP_ERROR_CHECK(esp_event_handler_register(ETH_EVENT, ETHERNET_EVENT_CONNECTED, &on_eth_event, NULL)); + ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_GOT_IP6, &on_got_ipv6, NULL)); +#endif + + ESP_ERROR_CHECK(esp_eth_enable()); + + s_connection_name = "Ethernet"; +} + +static void stop() +{ + ESP_ERROR_CHECK(esp_event_handler_unregister(IP_EVENT, IP_EVENT_ETH_GOT_IP, &on_got_ip)); +#ifdef CONFIG_EXAMPLE_CONNECT_IPV6 + ESP_ERROR_CHECK(esp_event_handler_unregister(IP_EVENT, IP_EVENT_GOT_IP6, &on_got_ipv6)); + ESP_ERROR_CHECK(esp_event_handler_unregister(ETH_EVENT, ETHERNET_EVENT_CONNECTED, &on_eth_event)); +#endif + + ESP_ERROR_CHECK(esp_eth_disable()); + ESP_ERROR_CHECK(esp_eth_deinit()); +} + +#endif // CONFIG_EXAMPLE_CONNECT_ETHERNET diff --git a/examples/common_components/protocol_examples_common/include/protocol_examples_common.h b/examples/common_components/protocol_examples_common/include/protocol_examples_common.h new file mode 100644 index 0000000000..e250db14d5 --- /dev/null +++ b/examples/common_components/protocol_examples_common/include/protocol_examples_common.h @@ -0,0 +1,59 @@ +/* Common functions for protocol examples, to establish Wi-Fi or Ethernet connection. + + This example code is in the Public Domain (or CC0 licensed, at your option.) + + Unless required by applicable law or agreed to in writing, this + software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + CONDITIONS OF ANY KIND, either express or implied. + */ + +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +#include "esp_err.h" +#include "tcpip_adapter.h" + +#ifdef CONFIG_EXAMPLE_CONNECT_ETHERNET +#define EXAMPLE_INTERFACE TCPIP_ADAPTER_IF_ETH +#endif + +#ifdef CONFIG_EXAMPLE_CONNECT_WIFI +#define EXAMPLE_INTERFACE TCPIP_ADAPTER_IF_STA +#endif + +/** + * @brief Configure Wi-Fi or Ethernet, connect, wait for IP + * + * This all-in-one helper function is used in protocols examples to + * reduce the amount of boilerplate in the example. + * + * It is not intended to be used in real world applications. + * See examples under examples/wifi/getting_started/ and examples/ethernet/ + * for more complete Wi-Fi or Ethernet initialization code. + * + * Read "Establishing Wi-Fi or Ethernet Connection" section in + * examples/protocols/README.md for more information about this function. + * + * @return ESP_OK on successful connection + */ +esp_err_t example_connect(); + +/** + * Counterpart to example_connect, de-initializes Wi-Fi or Ethernet + */ +esp_err_t example_disconnect(); + +/** + * @brief Configure stdin and stdout to use blocking I/O + * + * This helper function is used in ASIO examples. It wraps installing the + * UART driver and configuring VFS layer to use UART driver for console I/O. + */ +esp_err_t example_configure_stdin_stdout(); + +#ifdef __cplusplus +} +#endif diff --git a/examples/common_components/protocol_examples_common/stdin_out.c b/examples/common_components/protocol_examples_common/stdin_out.c new file mode 100644 index 0000000000..a4bc2cca49 --- /dev/null +++ b/examples/common_components/protocol_examples_common/stdin_out.c @@ -0,0 +1,30 @@ +/* Common functions for protocol examples, to configure stdin and stdout. + + This example code is in the Public Domain (or CC0 licensed, at your option.) + + Unless required by applicable law or agreed to in writing, this + software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + CONDITIONS OF ANY KIND, either express or implied. + */ + +#include "protocol_examples_common.h" +#include "esp_err.h" +#include "esp_vfs_dev.h" +#include "driver/uart.h" +#include "sdkconfig.h" + +esp_err_t example_configure_stdin_stdout() +{ + // Initialize VFS & UART so we can use std::cout/cin + setvbuf(stdin, NULL, _IONBF, 0); + setvbuf(stdout, NULL, _IONBF, 0); + /* Install UART driver for interrupt-driven reads and writes */ + ESP_ERROR_CHECK( uart_driver_install( (uart_port_t)CONFIG_CONSOLE_UART_NUM, + 256, 0, 0, NULL, 0) ); + /* Tell VFS to use UART driver */ + esp_vfs_dev_uart_use_driver(CONFIG_CONSOLE_UART_NUM); + esp_vfs_dev_uart_set_rx_line_endings(ESP_LINE_ENDINGS_CR); + /* Move the caret to the beginning of the next line on '\n' */ + esp_vfs_dev_uart_set_tx_line_endings(ESP_LINE_ENDINGS_CRLF); + return ESP_OK; +} diff --git a/examples/protocols/README.md b/examples/protocols/README.md index 0fef293839..0e31668a70 100644 --- a/examples/protocols/README.md +++ b/examples/protocols/README.md @@ -3,3 +3,23 @@ Implementation of internet communication protocols and services. See the [README.md](../README.md) file in the upper level [examples](../) directory for more information about examples. + +## Establishing Wi-Fi or Ethernet Connection + +### About the `example_connect()` Function + +Protocols examples use a simple helper function, `example_connect()`, to establish Wi-Fi or Ethernet connection. This function is implemented in [examples/common_components/protocol_examples/common/connect.c](../common_components/protocol_examples/common/connect.c), and has a very simple behavior: block until connection is established and IP address is obtained, then return. This function is used to reduce the amount of boilerplate and to keep the example code focused on the protocol or library being demonstrated. + +The simple `example_connect()` function does not handle timeouts, does not gracefully handle various error conditions, and is only suited for use in examples. When developing real applications, this helper function needs to be replaced with full Wi-Fi / Ethernet connection handling code. Such code can be found in [examples/wifi/getting_started/](../examples/wifi/getting_started) and [examples/ethernet/ethernet/](../examples/ethernet/ethernet) examples. + +### Configuring the Example + +To configure the example to use Wi-Fi or Ethernet connection, run `make menuconfig` (or `idf.py menuconfig` if using CMake build system) and navigate to "Example Connection Configuration" menu. Select either "Wi-Fi" or "Ethernet" in the "Connect using" choice. + +When connecting using Wi-Fi, enter SSID and password of your Wi-Fi access point into the corresponding fields. If connecting to an open Wi-Fi network, keep the password field empty. + +When connecting using Ethernet, set up PHY type and configuration in the provided fields. If using Ethernet for the first time, it is recommended to start with the [Ethernet example readme](../examples/ethernet/ethernet/README.md), which contains instructions for connecting and configuring the PHY. Once Ethernet example obtains IP address successfully, proceed to the protocols example and set the same configuration options. + +### Disabling IPv6 + +By default, `example_connect()` function waits until Wi-Fi or Ethernet connection is established, and IPv4 address and IPv6 link-local address are obtained. In network environments where IPv6 link-local address cannot be obtained, disable "Obtain IPv6 link-local address" option found in "Example Connection Configuration" menu. diff --git a/examples/protocols/asio/chat_client/CMakeLists.txt b/examples/protocols/asio/chat_client/CMakeLists.txt index e0480c277a..ddcc068ba8 100644 --- a/examples/protocols/asio/chat_client/CMakeLists.txt +++ b/examples/protocols/asio/chat_client/CMakeLists.txt @@ -2,5 +2,9 @@ # in this exact order for cmake to work correctly cmake_minimum_required(VERSION 3.5) +# (Not part of the boilerplate) +# This example uses an extra component for common functions such as Wi-Fi and Ethernet connection. +set(EXTRA_COMPONENT_DIRS $ENV{IDF_PATH}/examples/common_components/protocol_examples_common) + include($ENV{IDF_PATH}/tools/cmake/project.cmake) project(asio_chat_client) diff --git a/examples/protocols/asio/chat_client/Makefile b/examples/protocols/asio/chat_client/Makefile index 924891a67c..90197676aa 100644 --- a/examples/protocols/asio/chat_client/Makefile +++ b/examples/protocols/asio/chat_client/Makefile @@ -4,4 +4,6 @@ # PROJECT_NAME := asio_chat_client +EXTRA_COMPONENT_DIRS = $(IDF_PATH)/examples/common_components/protocol_examples_common + include $(IDF_PATH)/make/project.mk diff --git a/examples/protocols/asio/chat_client/README.md b/examples/protocols/asio/chat_client/README.md index 0ab16f578f..951afad53b 100644 --- a/examples/protocols/asio/chat_client/README.md +++ b/examples/protocols/asio/chat_client/README.md @@ -1,19 +1,20 @@ -# ASIO chat server example +# Asio chat client example -Simple asio chat client using WiFi STA +Simple Asio chat client using WiFi STA or Ethernet. ## Example workflow -- WiFi STA is started and trying to connect to the access point defined through `make menuconfig` -- Once connected and acquired IP address ASIO chat client connects to a corresponding server whose port number and ip are defined through `make menuconfig` -- Chat client receives all messages from other chat clients, also it sends message received from stdin using `make monitor` +- Wi-Fi or Ethernet connection is established, and IP address is obtained. +- Asio chat client connects to the corresponding server whose port number and IP are defined through `make menuconfig`. +- Chat client receives all messages from other chat clients, also it sends message received from stdin using `make monitor`. ## Running the example -- Run `make menuconfig` to configure the access point's SSID and Password and server ip address and port number -- Start chat server either on host machine or as another ESP device running chat_server example -- Run `make flash monitor` to build and upload the example to your board and connect to it's serial terminal -- Wait for WiFi to connect to your access point +- Run `make menuconfig` to configure Wi-Fi or Ethernet. See "Establishing Wi-Fi or Ethernet Connection" section in [examples/protocols/README.md](../../README.md) for more details. +- Set server IP address and port number in menuconfig, "Example configuration". +- Start chat server either on host machine or as another ESP device running chat_server example. +- Run `make flash monitor` to build and upload the example to your board and connect to it's serial terminal. +- Wait for the board to connect to WiFi or Ethernet. - Receive and send messages to/from other clients on stdin/stdout via serial terminal. See the README.md file in the upper level 'examples' directory for more information about examples. diff --git a/examples/protocols/asio/chat_client/components/CMakeLists.txt b/examples/protocols/asio/chat_client/components/CMakeLists.txt deleted file mode 100644 index e517667247..0000000000 --- a/examples/protocols/asio/chat_client/components/CMakeLists.txt +++ /dev/null @@ -1,5 +0,0 @@ -set(COMPONENT_SRCS "wifi_asio.cpp") - -set(COMPONENT_PRIV_REQUIRES asio nvs_flash console) - -register_component() diff --git a/examples/protocols/asio/chat_client/components/component.mk b/examples/protocols/asio/chat_client/components/component.mk deleted file mode 100644 index b23b0cb719..0000000000 --- a/examples/protocols/asio/chat_client/components/component.mk +++ /dev/null @@ -1,10 +0,0 @@ -# -# Component Makefile -# -# This Makefile should, at the very least, just include $(SDK_PATH)/Makefile. By default, -# this will take the sources in the src/ directory, compile them and link them into -# lib(subdirectory_name).a in the build directory. This behaviour is entirely configurable, -# please read the SDK documents if you need to do this. -# - -COMPONENT_SRCDIRS = . diff --git a/examples/protocols/asio/chat_client/components/wifi_asio.cpp b/examples/protocols/asio/chat_client/components/wifi_asio.cpp deleted file mode 100644 index b90ce26ae0..0000000000 --- a/examples/protocols/asio/chat_client/components/wifi_asio.cpp +++ /dev/null @@ -1,136 +0,0 @@ -/* Common WiFi Init as STA for ASIO examples - - This example code is in the Public Domain (or CC0 licensed, at your option.) - - Unless required by applicable law or agreed to in writing, this - software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - CONDITIONS OF ANY KIND, either express or implied. -*/ -#include "freertos/FreeRTOS.h" -#include "freertos/task.h" -#include "freertos/event_groups.h" -#include "esp_system.h" -#include "esp_wifi.h" -#include "esp_event_loop.h" -#include "esp_log.h" -#include "nvs_flash.h" -#include "driver/uart.h" -#include "esp_console.h" -#include "esp_vfs_dev.h" - -#include "lwip/err.h" -#include "lwip/sys.h" - -#include - -/* The examples use simple WiFi configuration that you can set via - 'make menuconfig'. - - If you'd rather not, just change the below entries to strings with - the config you want - ie #define EXAMPLE_WIFI_SSID "mywifissid" -*/ -#define EXAMPLE_ESP_WIFI_SSID CONFIG_ESP_WIFI_SSID -#define EXAMPLE_ESP_WIFI_PASS CONFIG_ESP_WIFI_PASSWORD - -/* FreeRTOS event group to signal when we are connected*/ -static EventGroupHandle_t wifi_event_group; - -/* The event group allows multiple bits for each event, - but we only care about one event - are we connected - to the AP with an IP? */ -const int WIFI_CONNECTED_BIT = BIT0; - -static const char *TAG = "asio example wifi init"; - -/** - * Definition of ASIO main method, which is called after network initialized - */ -void asio_main(); - -static esp_err_t event_handler(void *ctx, system_event_t *event) -{ - switch(event->event_id) { - case SYSTEM_EVENT_STA_START: - esp_wifi_connect(); - break; - case SYSTEM_EVENT_STA_GOT_IP: - ESP_LOGI(TAG, "got ip:%s", - ip4addr_ntoa(&event->event_info.got_ip.ip_info.ip)); - xEventGroupSetBits(wifi_event_group, WIFI_CONNECTED_BIT); - break; - case SYSTEM_EVENT_AP_STACONNECTED: - ESP_LOGI(TAG, "station:" MACSTR " join, AID=%d", - MAC2STR(event->event_info.sta_connected.mac), - event->event_info.sta_connected.aid); - break; - case SYSTEM_EVENT_AP_STADISCONNECTED: - ESP_LOGI(TAG, "station:" MACSTR "leave, AID=%d", - MAC2STR(event->event_info.sta_disconnected.mac), - event->event_info.sta_disconnected.aid); - break; - case SYSTEM_EVENT_STA_DISCONNECTED: - esp_wifi_connect(); - xEventGroupClearBits(wifi_event_group, WIFI_CONNECTED_BIT); - break; - default: - break; - } - return ESP_OK; -} - -void wifi_init_sta() -{ - wifi_event_group = xEventGroupCreate(); - - tcpip_adapter_init(); - ESP_ERROR_CHECK(esp_event_loop_init(event_handler, NULL) ); - - wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); - ESP_ERROR_CHECK(esp_wifi_init(&cfg)); - wifi_config_t wifi_config; - // zero out the config struct to ensure defaults are setup - memset(&wifi_config, 0, sizeof(wifi_sta_config_t)); - // only copy ssid&password from example config - strcpy((char*)(wifi_config.sta.ssid), EXAMPLE_ESP_WIFI_SSID); - strcpy((char*)(wifi_config.sta.password), EXAMPLE_ESP_WIFI_PASS); - - ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA) ); - ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config) ); - ESP_ERROR_CHECK(esp_wifi_start() ); - - ESP_LOGI(TAG, "wifi_init_sta finished."); - ESP_LOGI(TAG, "connect to ap SSID:%s password:%s", - EXAMPLE_ESP_WIFI_SSID, EXAMPLE_ESP_WIFI_PASS); -} - -extern "C" void app_main() -{ - //Initialize NVS - esp_err_t ret = nvs_flash_init(); - if (ret == ESP_ERR_NVS_NO_FREE_PAGES) { - ESP_ERROR_CHECK(nvs_flash_erase()); - ret = nvs_flash_init(); - } - ESP_ERROR_CHECK(ret); - - ESP_LOGI(TAG, "ESP_WIFI_MODE_AP"); - wifi_init_sta(); - - // Initialize VFS & UART so we can use std::cout/cin - setvbuf(stdin, NULL, _IONBF, 0); - setvbuf(stdout, NULL, _IONBF, 0); - /* Install UART driver for interrupt-driven reads and writes */ - ESP_ERROR_CHECK( uart_driver_install( (uart_port_t)CONFIG_CONSOLE_UART_NUM, - 256, 0, 0, NULL, 0) ); - /* Tell VFS to use UART driver */ - esp_vfs_dev_uart_use_driver(CONFIG_CONSOLE_UART_NUM); - esp_vfs_dev_uart_set_rx_line_endings(ESP_LINE_ENDINGS_CR); - /* Move the caret to the beginning of the next line on '\n' */ - esp_vfs_dev_uart_set_tx_line_endings(ESP_LINE_ENDINGS_CRLF); - - // wait till we receive IP, so asio realated code can be started - xEventGroupWaitBits(wifi_event_group, WIFI_CONNECTED_BIT, 1, 1, portMAX_DELAY); - - // network is ready, let's proceed with ASIO example - asio_main(); -} diff --git a/examples/protocols/asio/chat_client/main/Kconfig.projbuild b/examples/protocols/asio/chat_client/main/Kconfig.projbuild index 4185e24246..34d9e93cfa 100644 --- a/examples/protocols/asio/chat_client/main/Kconfig.projbuild +++ b/examples/protocols/asio/chat_client/main/Kconfig.projbuild @@ -1,28 +1,16 @@ menu "Example Configuration" - config ESP_WIFI_SSID - string "WiFi SSID" - default "myssid" - help - SSID (network name) for the example to connect to. - - config ESP_WIFI_PASSWORD - string "WiFi Password" - default "mypassword" - help - WiFi password (WPA or WPA2) for the example to use. - config EXAMPLE_PORT - string "asio example port number" + string "Asio example server port number" default "2222" help - Port number used by ASIO example + Port number used by Asio example. config EXAMPLE_SERVER_IP - string "asio example server ip" + string "Asio example server ip" default "FROM_STDIN" help - asio example server ip for this client to connect to (leave default=FROM_STDIN to enter the server address - via serial terminal). + Asio example server ip for this client to connect to. + Leave default "FROM_STDIN" to enter the server address via serial terminal. endmenu diff --git a/examples/protocols/asio/chat_client/main/chat_client.cpp b/examples/protocols/asio/chat_client/main/chat_client.cpp index e18d8d4e3c..d4a1110573 100644 --- a/examples/protocols/asio/chat_client/main/chat_client.cpp +++ b/examples/protocols/asio/chat_client/main/chat_client.cpp @@ -14,6 +14,10 @@ #include #include "asio.hpp" #include "chat_message.hpp" +#include "protocol_examples_common.h" +#include "esp_event.h" +#include "tcpip_adapter.h" +#include "nvs_flash.h" using asio::ip::tcp; @@ -130,8 +134,21 @@ private: void read_line(char * line, int max_chars); -void asio_main() +extern "C" void app_main() { + ESP_ERROR_CHECK(nvs_flash_init()); + tcpip_adapter_init(); + ESP_ERROR_CHECK(esp_event_loop_create_default()); + + /* This helper function configures Wi-Fi or Ethernet, as selected in menuconfig. + * Read "Establishing Wi-Fi or Ethernet Connection" section in + * examples/protocols/README.md for more information about this function. + */ + ESP_ERROR_CHECK(example_connect()); + + /* This helper function configures blocking UART I/O */ + ESP_ERROR_CHECK(example_configure_stdin_stdout()); + std::string name(CONFIG_EXAMPLE_SERVER_IP); std::string port(CONFIG_EXAMPLE_PORT); char line[chat_message::max_body_length + 1] = { 0 }; @@ -152,7 +169,7 @@ void asio_main() std::thread t([&io_context](){ io_context.run(); }); - while (std::cin.getline(line, chat_message::max_body_length + 1) && std::string(line) != "exit\n") { + while (std::cin.getline(line, chat_message::max_body_length + 1) && std::string(line) != "exit") { chat_message msg; msg.body_length(std::strlen(line)); std::memcpy(msg.body(), line, msg.body_length()); @@ -162,4 +179,6 @@ void asio_main() c.close(); t.join(); + + ESP_ERROR_CHECK(example_disconnect()); } diff --git a/examples/protocols/asio/chat_server/CMakeLists.txt b/examples/protocols/asio/chat_server/CMakeLists.txt index c8c629856d..182f8d4024 100644 --- a/examples/protocols/asio/chat_server/CMakeLists.txt +++ b/examples/protocols/asio/chat_server/CMakeLists.txt @@ -2,5 +2,9 @@ # in this exact order for cmake to work correctly cmake_minimum_required(VERSION 3.5) +# (Not part of the boilerplate) +# This example uses an extra component for common functions such as Wi-Fi and Ethernet connection. +set(EXTRA_COMPONENT_DIRS $ENV{IDF_PATH}/examples/common_components/protocol_examples_common) + include($ENV{IDF_PATH}/tools/cmake/project.cmake) project(asio_chat_server) diff --git a/examples/protocols/asio/chat_server/Makefile b/examples/protocols/asio/chat_server/Makefile index 0b0ed1fc57..a7656889fd 100644 --- a/examples/protocols/asio/chat_server/Makefile +++ b/examples/protocols/asio/chat_server/Makefile @@ -4,4 +4,6 @@ # PROJECT_NAME := asio_chat_server +EXTRA_COMPONENT_DIRS = $(IDF_PATH)/examples/common_components/protocol_examples_common + include $(IDF_PATH)/make/project.mk diff --git a/examples/protocols/asio/chat_server/README.md b/examples/protocols/asio/chat_server/README.md index 591efd9776..e043cba32c 100644 --- a/examples/protocols/asio/chat_server/README.md +++ b/examples/protocols/asio/chat_server/README.md @@ -1,19 +1,20 @@ -# ASIO chat server example +# Asio chat server example -Simple asio chat server using WiFi STA +Simple Asio chat server using WiFi STA or Ethernet. ## Example workflow -- WiFi STA is started and trying to connect to the access point defined through `make menuconfig` -- Once connected and acquired IP address, ASIO chat server is started on port number defined through `make menuconfig` -- Chat server echoes a message (received from any client) to all connected clients +- Wi-Fi or Ethernet connection is established, and IP address is obtained. +- Asio chat server is started on port number defined through `make menuconfig`. +- Chat server echoes a message (received from any client) to all connected clients. ## Running the example -- Run `make menuconfig` to configure the access point's SSID and Password and port number -- Run `make flash monitor` to build and upload the example to your board and connect to it's serial terminal -- Wait for WiFi to connect to your access point (note the IP address) -- Connect to the server using multiple clients, for example using any option below +- Run `make menuconfig` to configure Wi-Fi or Ethernet. See "Establishing Wi-Fi or Ethernet Connection" section in [examples/protocols/README.md](../../README.md) for more details. +- Set server port number in menuconfig, "Example configuration". +- Run `make flash monitor` to build and upload the example to your board and connect to it's serial terminal. +- Wait for the board to connect to WiFi or Ethernet (note the IP address). +- Connect to the server using multiple clients, for example using any option below. - build and run asi chat client on your host machine - run chat_client asio example on ESP platform - since chat message consist of ascii size and message, it is possible to diff --git a/examples/protocols/asio/chat_server/asio_chat_server_test.py b/examples/protocols/asio/chat_server/asio_chat_server_test.py index 4f28116aaf..ea4702c4e8 100644 --- a/examples/protocols/asio/chat_server/asio_chat_server_test.py +++ b/examples/protocols/asio/chat_server/asio_chat_server_test.py @@ -40,7 +40,7 @@ def test_examples_protocol_asio_chat_server(env, extra_data): # 3. create tcp client and connect to server cli = socket.socket(socket.AF_INET, socket.SOCK_STREAM) cli.settimeout(30) - cli.connect((data[0],80)) + cli.connect((data[0], 2222)) cli.send(test_msg) data = cli.recv(1024) # 4. check the message received back from the server diff --git a/examples/protocols/asio/chat_server/components/CMakeLists.txt b/examples/protocols/asio/chat_server/components/CMakeLists.txt deleted file mode 100644 index e517667247..0000000000 --- a/examples/protocols/asio/chat_server/components/CMakeLists.txt +++ /dev/null @@ -1,5 +0,0 @@ -set(COMPONENT_SRCS "wifi_asio.cpp") - -set(COMPONENT_PRIV_REQUIRES asio nvs_flash console) - -register_component() diff --git a/examples/protocols/asio/chat_server/components/component.mk b/examples/protocols/asio/chat_server/components/component.mk deleted file mode 100644 index b23b0cb719..0000000000 --- a/examples/protocols/asio/chat_server/components/component.mk +++ /dev/null @@ -1,10 +0,0 @@ -# -# Component Makefile -# -# This Makefile should, at the very least, just include $(SDK_PATH)/Makefile. By default, -# this will take the sources in the src/ directory, compile them and link them into -# lib(subdirectory_name).a in the build directory. This behaviour is entirely configurable, -# please read the SDK documents if you need to do this. -# - -COMPONENT_SRCDIRS = . diff --git a/examples/protocols/asio/chat_server/components/wifi_asio.cpp b/examples/protocols/asio/chat_server/components/wifi_asio.cpp deleted file mode 100644 index b90ce26ae0..0000000000 --- a/examples/protocols/asio/chat_server/components/wifi_asio.cpp +++ /dev/null @@ -1,136 +0,0 @@ -/* Common WiFi Init as STA for ASIO examples - - This example code is in the Public Domain (or CC0 licensed, at your option.) - - Unless required by applicable law or agreed to in writing, this - software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - CONDITIONS OF ANY KIND, either express or implied. -*/ -#include "freertos/FreeRTOS.h" -#include "freertos/task.h" -#include "freertos/event_groups.h" -#include "esp_system.h" -#include "esp_wifi.h" -#include "esp_event_loop.h" -#include "esp_log.h" -#include "nvs_flash.h" -#include "driver/uart.h" -#include "esp_console.h" -#include "esp_vfs_dev.h" - -#include "lwip/err.h" -#include "lwip/sys.h" - -#include - -/* The examples use simple WiFi configuration that you can set via - 'make menuconfig'. - - If you'd rather not, just change the below entries to strings with - the config you want - ie #define EXAMPLE_WIFI_SSID "mywifissid" -*/ -#define EXAMPLE_ESP_WIFI_SSID CONFIG_ESP_WIFI_SSID -#define EXAMPLE_ESP_WIFI_PASS CONFIG_ESP_WIFI_PASSWORD - -/* FreeRTOS event group to signal when we are connected*/ -static EventGroupHandle_t wifi_event_group; - -/* The event group allows multiple bits for each event, - but we only care about one event - are we connected - to the AP with an IP? */ -const int WIFI_CONNECTED_BIT = BIT0; - -static const char *TAG = "asio example wifi init"; - -/** - * Definition of ASIO main method, which is called after network initialized - */ -void asio_main(); - -static esp_err_t event_handler(void *ctx, system_event_t *event) -{ - switch(event->event_id) { - case SYSTEM_EVENT_STA_START: - esp_wifi_connect(); - break; - case SYSTEM_EVENT_STA_GOT_IP: - ESP_LOGI(TAG, "got ip:%s", - ip4addr_ntoa(&event->event_info.got_ip.ip_info.ip)); - xEventGroupSetBits(wifi_event_group, WIFI_CONNECTED_BIT); - break; - case SYSTEM_EVENT_AP_STACONNECTED: - ESP_LOGI(TAG, "station:" MACSTR " join, AID=%d", - MAC2STR(event->event_info.sta_connected.mac), - event->event_info.sta_connected.aid); - break; - case SYSTEM_EVENT_AP_STADISCONNECTED: - ESP_LOGI(TAG, "station:" MACSTR "leave, AID=%d", - MAC2STR(event->event_info.sta_disconnected.mac), - event->event_info.sta_disconnected.aid); - break; - case SYSTEM_EVENT_STA_DISCONNECTED: - esp_wifi_connect(); - xEventGroupClearBits(wifi_event_group, WIFI_CONNECTED_BIT); - break; - default: - break; - } - return ESP_OK; -} - -void wifi_init_sta() -{ - wifi_event_group = xEventGroupCreate(); - - tcpip_adapter_init(); - ESP_ERROR_CHECK(esp_event_loop_init(event_handler, NULL) ); - - wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); - ESP_ERROR_CHECK(esp_wifi_init(&cfg)); - wifi_config_t wifi_config; - // zero out the config struct to ensure defaults are setup - memset(&wifi_config, 0, sizeof(wifi_sta_config_t)); - // only copy ssid&password from example config - strcpy((char*)(wifi_config.sta.ssid), EXAMPLE_ESP_WIFI_SSID); - strcpy((char*)(wifi_config.sta.password), EXAMPLE_ESP_WIFI_PASS); - - ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA) ); - ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config) ); - ESP_ERROR_CHECK(esp_wifi_start() ); - - ESP_LOGI(TAG, "wifi_init_sta finished."); - ESP_LOGI(TAG, "connect to ap SSID:%s password:%s", - EXAMPLE_ESP_WIFI_SSID, EXAMPLE_ESP_WIFI_PASS); -} - -extern "C" void app_main() -{ - //Initialize NVS - esp_err_t ret = nvs_flash_init(); - if (ret == ESP_ERR_NVS_NO_FREE_PAGES) { - ESP_ERROR_CHECK(nvs_flash_erase()); - ret = nvs_flash_init(); - } - ESP_ERROR_CHECK(ret); - - ESP_LOGI(TAG, "ESP_WIFI_MODE_AP"); - wifi_init_sta(); - - // Initialize VFS & UART so we can use std::cout/cin - setvbuf(stdin, NULL, _IONBF, 0); - setvbuf(stdout, NULL, _IONBF, 0); - /* Install UART driver for interrupt-driven reads and writes */ - ESP_ERROR_CHECK( uart_driver_install( (uart_port_t)CONFIG_CONSOLE_UART_NUM, - 256, 0, 0, NULL, 0) ); - /* Tell VFS to use UART driver */ - esp_vfs_dev_uart_use_driver(CONFIG_CONSOLE_UART_NUM); - esp_vfs_dev_uart_set_rx_line_endings(ESP_LINE_ENDINGS_CR); - /* Move the caret to the beginning of the next line on '\n' */ - esp_vfs_dev_uart_set_tx_line_endings(ESP_LINE_ENDINGS_CRLF); - - // wait till we receive IP, so asio realated code can be started - xEventGroupWaitBits(wifi_event_group, WIFI_CONNECTED_BIT, 1, 1, portMAX_DELAY); - - // network is ready, let's proceed with ASIO example - asio_main(); -} diff --git a/examples/protocols/asio/chat_server/main/Kconfig.projbuild b/examples/protocols/asio/chat_server/main/Kconfig.projbuild index ecbbf8ae91..c1f397b9cd 100644 --- a/examples/protocols/asio/chat_server/main/Kconfig.projbuild +++ b/examples/protocols/asio/chat_server/main/Kconfig.projbuild @@ -1,21 +1,9 @@ menu "Example Configuration" - config ESP_WIFI_SSID - string "WiFi SSID" - default "myssid" - help - SSID (network name) for the example to connect to. - - config ESP_WIFI_PASSWORD - string "WiFi Password" - default "mypassword" - help - WiFi password (WPA or WPA2) for the example to use. - config EXAMPLE_PORT - string "asio example port number" - default "80" + string "Asio example server port number" + default "2222" help - Port number used by ASIO example + Port number used by Asio example endmenu diff --git a/examples/protocols/asio/chat_server/main/chat_server.cpp b/examples/protocols/asio/chat_server/main/chat_server.cpp index 05740f4798..56a447e05f 100644 --- a/examples/protocols/asio/chat_server/main/chat_server.cpp +++ b/examples/protocols/asio/chat_server/main/chat_server.cpp @@ -17,6 +17,11 @@ #include #include "asio.hpp" #include "chat_message.hpp" +#include "protocol_examples_common.h" +#include "esp_event.h" +#include "tcpip_adapter.h" +#include "nvs_flash.h" + using asio::ip::tcp; @@ -197,8 +202,21 @@ private: //---------------------------------------------------------------------- -int asio_main() +extern "C" void app_main() { + ESP_ERROR_CHECK(nvs_flash_init()); + tcpip_adapter_init(); + ESP_ERROR_CHECK(esp_event_loop_create_default()); + + /* This helper function configures Wi-Fi or Ethernet, as selected in menuconfig. + * Read "Establishing Wi-Fi or Ethernet Connection" section in + * examples/protocols/README.md for more information about this function. + */ + ESP_ERROR_CHECK(example_connect()); + + /* This helper function configures blocking UART I/O */ + ESP_ERROR_CHECK(example_configure_stdin_stdout()); + asio::io_context io_context; std::list servers; @@ -209,6 +227,4 @@ int asio_main() } io_context.run(); - - return 0; } diff --git a/examples/protocols/asio/tcp_echo_server/CMakeLists.txt b/examples/protocols/asio/tcp_echo_server/CMakeLists.txt index b8d5638f7a..6bf8f46825 100644 --- a/examples/protocols/asio/tcp_echo_server/CMakeLists.txt +++ b/examples/protocols/asio/tcp_echo_server/CMakeLists.txt @@ -2,5 +2,9 @@ # in this exact order for cmake to work correctly cmake_minimum_required(VERSION 3.5) +# (Not part of the boilerplate) +# This example uses an extra component for common functions such as Wi-Fi and Ethernet connection. +set(EXTRA_COMPONENT_DIRS $ENV{IDF_PATH}/examples/common_components/protocol_examples_common) + include($ENV{IDF_PATH}/tools/cmake/project.cmake) project(asio_tcp_echo_server) diff --git a/examples/protocols/asio/tcp_echo_server/Makefile b/examples/protocols/asio/tcp_echo_server/Makefile index ef5b796704..ed9cfb8d8f 100644 --- a/examples/protocols/asio/tcp_echo_server/Makefile +++ b/examples/protocols/asio/tcp_echo_server/Makefile @@ -4,4 +4,6 @@ # PROJECT_NAME := asio_tcp_echo_server +EXTRA_COMPONENT_DIRS = $(IDF_PATH)/examples/common_components/protocol_examples_common + include $(IDF_PATH)/make/project.mk diff --git a/examples/protocols/asio/tcp_echo_server/README.md b/examples/protocols/asio/tcp_echo_server/README.md index a32fd93ea9..f672027ef4 100644 --- a/examples/protocols/asio/tcp_echo_server/README.md +++ b/examples/protocols/asio/tcp_echo_server/README.md @@ -1,18 +1,19 @@ -# ASIO tcp echo server example +# Asio TCP echo server example -Simple asio echo server using WiFi STA +Simple Asio TCP echo server using WiFi STA or Ethernet. ## Example workflow -- WiFi STA is started and trying to connect to the access point defined through `make menuconfig` -- Once connected and acquired IP address, ASIO tcp server is started on port number defined through `make menuconfig` -- Server receives and echoes back messages transmitted from client +- Wi-Fi or Ethernet connection is established, and IP address is obtained. +- Asio TCP server is started on port number defined through `make menuconfig`. +- Server receives and echoes back messages transmitted from client. ## Running the example -- Run `make menuconfig` to configure the access point's SSID and Password and port number -- Run `make flash monitor` to build and upload the example to your board and connect to it's serial terminal -- Wait for WiFi to connect to your access point (note the IP address) -- You can now send a tcp message and check it is repeated, for example using netcat `nc IP PORT` +- Run `make menuconfig` to configure Wi-Fi or Ethernet. See "Establishing Wi-Fi or Ethernet Connection" section in [examples/protocols/README.md](../../README.md) for more details. +- Set server port number in menuconfig, "Example configuration". +- Run `make flash monitor` to build and upload the example to your board and connect to it's serial terminal. +- Wait for the board to connect to WiFi or Ethernet (note the IP address). +- You can now send a TCP message and check it is repeated, for example using netcat `nc IP PORT`. See the README.md file in the upper level 'examples' directory for more information about examples. diff --git a/examples/protocols/asio/tcp_echo_server/asio_tcp_server_test.py b/examples/protocols/asio/tcp_echo_server/asio_tcp_server_test.py index c29b8ce7b8..2cdfd45aee 100644 --- a/examples/protocols/asio/tcp_echo_server/asio_tcp_server_test.py +++ b/examples/protocols/asio/tcp_echo_server/asio_tcp_server_test.py @@ -42,7 +42,7 @@ def test_examples_protocol_asio_tcp_server(env, extra_data): # 3. create tcp client and connect to server cli = socket.socket(socket.AF_INET, socket.SOCK_STREAM) cli.settimeout(30) - cli.connect((data[0],80)) + cli.connect((data[0], 2222)) cli.send(test_msg) data = cli.recv(1024) # 4. check the message received back from the server @@ -51,7 +51,7 @@ def test_examples_protocol_asio_tcp_server(env, extra_data): pass else: print("Failure!") - raise ValueError('Wrong data received from asi tcp server: {} (expoected:{})'.format(data, test_msg)) + raise ValueError('Wrong data received from asi tcp server: {} (expected:{})'.format(data, test_msg)) # 5. check the client message appears also on server terminal dut1.expect(test_msg.decode()) diff --git a/examples/protocols/asio/tcp_echo_server/components/CMakeLists.txt b/examples/protocols/asio/tcp_echo_server/components/CMakeLists.txt deleted file mode 100644 index e517667247..0000000000 --- a/examples/protocols/asio/tcp_echo_server/components/CMakeLists.txt +++ /dev/null @@ -1,5 +0,0 @@ -set(COMPONENT_SRCS "wifi_asio.cpp") - -set(COMPONENT_PRIV_REQUIRES asio nvs_flash console) - -register_component() diff --git a/examples/protocols/asio/tcp_echo_server/components/component.mk b/examples/protocols/asio/tcp_echo_server/components/component.mk deleted file mode 100644 index b23b0cb719..0000000000 --- a/examples/protocols/asio/tcp_echo_server/components/component.mk +++ /dev/null @@ -1,10 +0,0 @@ -# -# Component Makefile -# -# This Makefile should, at the very least, just include $(SDK_PATH)/Makefile. By default, -# this will take the sources in the src/ directory, compile them and link them into -# lib(subdirectory_name).a in the build directory. This behaviour is entirely configurable, -# please read the SDK documents if you need to do this. -# - -COMPONENT_SRCDIRS = . diff --git a/examples/protocols/asio/tcp_echo_server/components/wifi_asio.cpp b/examples/protocols/asio/tcp_echo_server/components/wifi_asio.cpp deleted file mode 100644 index b90ce26ae0..0000000000 --- a/examples/protocols/asio/tcp_echo_server/components/wifi_asio.cpp +++ /dev/null @@ -1,136 +0,0 @@ -/* Common WiFi Init as STA for ASIO examples - - This example code is in the Public Domain (or CC0 licensed, at your option.) - - Unless required by applicable law or agreed to in writing, this - software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - CONDITIONS OF ANY KIND, either express or implied. -*/ -#include "freertos/FreeRTOS.h" -#include "freertos/task.h" -#include "freertos/event_groups.h" -#include "esp_system.h" -#include "esp_wifi.h" -#include "esp_event_loop.h" -#include "esp_log.h" -#include "nvs_flash.h" -#include "driver/uart.h" -#include "esp_console.h" -#include "esp_vfs_dev.h" - -#include "lwip/err.h" -#include "lwip/sys.h" - -#include - -/* The examples use simple WiFi configuration that you can set via - 'make menuconfig'. - - If you'd rather not, just change the below entries to strings with - the config you want - ie #define EXAMPLE_WIFI_SSID "mywifissid" -*/ -#define EXAMPLE_ESP_WIFI_SSID CONFIG_ESP_WIFI_SSID -#define EXAMPLE_ESP_WIFI_PASS CONFIG_ESP_WIFI_PASSWORD - -/* FreeRTOS event group to signal when we are connected*/ -static EventGroupHandle_t wifi_event_group; - -/* The event group allows multiple bits for each event, - but we only care about one event - are we connected - to the AP with an IP? */ -const int WIFI_CONNECTED_BIT = BIT0; - -static const char *TAG = "asio example wifi init"; - -/** - * Definition of ASIO main method, which is called after network initialized - */ -void asio_main(); - -static esp_err_t event_handler(void *ctx, system_event_t *event) -{ - switch(event->event_id) { - case SYSTEM_EVENT_STA_START: - esp_wifi_connect(); - break; - case SYSTEM_EVENT_STA_GOT_IP: - ESP_LOGI(TAG, "got ip:%s", - ip4addr_ntoa(&event->event_info.got_ip.ip_info.ip)); - xEventGroupSetBits(wifi_event_group, WIFI_CONNECTED_BIT); - break; - case SYSTEM_EVENT_AP_STACONNECTED: - ESP_LOGI(TAG, "station:" MACSTR " join, AID=%d", - MAC2STR(event->event_info.sta_connected.mac), - event->event_info.sta_connected.aid); - break; - case SYSTEM_EVENT_AP_STADISCONNECTED: - ESP_LOGI(TAG, "station:" MACSTR "leave, AID=%d", - MAC2STR(event->event_info.sta_disconnected.mac), - event->event_info.sta_disconnected.aid); - break; - case SYSTEM_EVENT_STA_DISCONNECTED: - esp_wifi_connect(); - xEventGroupClearBits(wifi_event_group, WIFI_CONNECTED_BIT); - break; - default: - break; - } - return ESP_OK; -} - -void wifi_init_sta() -{ - wifi_event_group = xEventGroupCreate(); - - tcpip_adapter_init(); - ESP_ERROR_CHECK(esp_event_loop_init(event_handler, NULL) ); - - wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); - ESP_ERROR_CHECK(esp_wifi_init(&cfg)); - wifi_config_t wifi_config; - // zero out the config struct to ensure defaults are setup - memset(&wifi_config, 0, sizeof(wifi_sta_config_t)); - // only copy ssid&password from example config - strcpy((char*)(wifi_config.sta.ssid), EXAMPLE_ESP_WIFI_SSID); - strcpy((char*)(wifi_config.sta.password), EXAMPLE_ESP_WIFI_PASS); - - ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA) ); - ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config) ); - ESP_ERROR_CHECK(esp_wifi_start() ); - - ESP_LOGI(TAG, "wifi_init_sta finished."); - ESP_LOGI(TAG, "connect to ap SSID:%s password:%s", - EXAMPLE_ESP_WIFI_SSID, EXAMPLE_ESP_WIFI_PASS); -} - -extern "C" void app_main() -{ - //Initialize NVS - esp_err_t ret = nvs_flash_init(); - if (ret == ESP_ERR_NVS_NO_FREE_PAGES) { - ESP_ERROR_CHECK(nvs_flash_erase()); - ret = nvs_flash_init(); - } - ESP_ERROR_CHECK(ret); - - ESP_LOGI(TAG, "ESP_WIFI_MODE_AP"); - wifi_init_sta(); - - // Initialize VFS & UART so we can use std::cout/cin - setvbuf(stdin, NULL, _IONBF, 0); - setvbuf(stdout, NULL, _IONBF, 0); - /* Install UART driver for interrupt-driven reads and writes */ - ESP_ERROR_CHECK( uart_driver_install( (uart_port_t)CONFIG_CONSOLE_UART_NUM, - 256, 0, 0, NULL, 0) ); - /* Tell VFS to use UART driver */ - esp_vfs_dev_uart_use_driver(CONFIG_CONSOLE_UART_NUM); - esp_vfs_dev_uart_set_rx_line_endings(ESP_LINE_ENDINGS_CR); - /* Move the caret to the beginning of the next line on '\n' */ - esp_vfs_dev_uart_set_tx_line_endings(ESP_LINE_ENDINGS_CRLF); - - // wait till we receive IP, so asio realated code can be started - xEventGroupWaitBits(wifi_event_group, WIFI_CONNECTED_BIT, 1, 1, portMAX_DELAY); - - // network is ready, let's proceed with ASIO example - asio_main(); -} diff --git a/examples/protocols/asio/tcp_echo_server/main/Kconfig.projbuild b/examples/protocols/asio/tcp_echo_server/main/Kconfig.projbuild index ecbbf8ae91..795326db91 100644 --- a/examples/protocols/asio/tcp_echo_server/main/Kconfig.projbuild +++ b/examples/protocols/asio/tcp_echo_server/main/Kconfig.projbuild @@ -1,21 +1,9 @@ menu "Example Configuration" - config ESP_WIFI_SSID - string "WiFi SSID" - default "myssid" - help - SSID (network name) for the example to connect to. - - config ESP_WIFI_PASSWORD - string "WiFi Password" - default "mypassword" - help - WiFi password (WPA or WPA2) for the example to use. - config EXAMPLE_PORT - string "asio example port number" - default "80" + string "Asio example port number" + default "2222" help - Port number used by ASIO example + Port number used by Asio example. endmenu diff --git a/examples/protocols/asio/tcp_echo_server/main/echo_server.cpp b/examples/protocols/asio/tcp_echo_server/main/echo_server.cpp index 22f171f530..008ec6ed79 100644 --- a/examples/protocols/asio/tcp_echo_server/main/echo_server.cpp +++ b/examples/protocols/asio/tcp_echo_server/main/echo_server.cpp @@ -1,6 +1,10 @@ #include "asio.hpp" #include #include +#include "protocol_examples_common.h" +#include "esp_event.h" +#include "tcpip_adapter.h" +#include "nvs_flash.h" using asio::ip::tcp; @@ -27,6 +31,7 @@ private: { if (!ec) { + data_[length] = 0; std::cout << data_ << std::endl; do_write(length); } @@ -79,13 +84,24 @@ private: }; -void asio_main() +extern "C" void app_main() { + ESP_ERROR_CHECK(nvs_flash_init()); + tcpip_adapter_init(); + ESP_ERROR_CHECK(esp_event_loop_create_default()); + + /* This helper function configures Wi-Fi or Ethernet, as selected in menuconfig. + * Read "Establishing Wi-Fi or Ethernet Connection" section in + * examples/protocols/README.md for more information about this function. + */ + ESP_ERROR_CHECK(example_connect()); + + /* This helper function configures blocking UART I/O */ + ESP_ERROR_CHECK(example_configure_stdin_stdout()); asio::io_context io_context; server s(io_context, std::atoi(CONFIG_EXAMPLE_PORT)); io_context.run(); - } \ No newline at end of file diff --git a/examples/protocols/asio/udp_echo_server/CMakeLists.txt b/examples/protocols/asio/udp_echo_server/CMakeLists.txt index 8d5c3a6927..59493277c4 100644 --- a/examples/protocols/asio/udp_echo_server/CMakeLists.txt +++ b/examples/protocols/asio/udp_echo_server/CMakeLists.txt @@ -2,5 +2,9 @@ # in this exact order for cmake to work correctly cmake_minimum_required(VERSION 3.5) +# (Not part of the boilerplate) +# This example uses an extra component for common functions such as Wi-Fi and Ethernet connection. +set(EXTRA_COMPONENT_DIRS $ENV{IDF_PATH}/examples/common_components/protocol_examples_common) + include($ENV{IDF_PATH}/tools/cmake/project.cmake) project(asio_udp_echo_server) diff --git a/examples/protocols/asio/udp_echo_server/Makefile b/examples/protocols/asio/udp_echo_server/Makefile index a23a5c9acc..f28a9d96ad 100644 --- a/examples/protocols/asio/udp_echo_server/Makefile +++ b/examples/protocols/asio/udp_echo_server/Makefile @@ -4,4 +4,6 @@ # PROJECT_NAME := asio_udp_echo_server +EXTRA_COMPONENT_DIRS = $(IDF_PATH)/examples/common_components/protocol_examples_common + include $(IDF_PATH)/make/project.mk diff --git a/examples/protocols/asio/udp_echo_server/README.md b/examples/protocols/asio/udp_echo_server/README.md index 6cf2c2ba38..cc69fee08d 100644 --- a/examples/protocols/asio/udp_echo_server/README.md +++ b/examples/protocols/asio/udp_echo_server/README.md @@ -1,18 +1,19 @@ -# ASIO udp echo server example +# Asio UDP echo server example -Simple asio echo server using WiFi STA +Simple Asio UDP echo server using WiFi STA or Ethernet. ## Example workflow -- WiFi STA is started and trying to connect to the access point defined through `make menuconfig` -- Once connected and acquired IP address, ASIO udp server is started on port number defined through `make menuconfig` +- Wi-Fi or Ethernet connection is established, and IP address is obtained. +- Asio UDP server is started on port number defined through `make menuconfig` - Server receives and echoes back messages transmitted from client ## Running the example -- Run `make menuconfig` to configure the access point's SSID and Password and port number -- Run `make flash monitor` to build and upload the example to your board and connect to it's serial terminal -- Wait for WiFi to connect to your access point (note the IP address) -- You can now send a udp message and check it is repeated, for example using netcat `nc -u IP PORT` +- Run `make menuconfig` to configure Wi-Fi or Ethernet. See "Establishing Wi-Fi or Ethernet Connection" section in [examples/protocols/README.md](../../README.md) for more details. +- Set server port number in menuconfig, "Example configuration". +- Run `make flash monitor` to build and upload the example to your board and connect to it's serial terminal. +- Wait for the board to connect to WiFi or Ethernet (note the IP address). +- You can now send a UDP message and check it is repeated, for example using netcat `nc -u IP PORT`. See the README.md file in the upper level 'examples' directory for more information about examples. diff --git a/examples/protocols/asio/udp_echo_server/asio_udp_server_test.py b/examples/protocols/asio/udp_echo_server/asio_udp_server_test.py index d3a01563c1..dc2cc78a80 100644 --- a/examples/protocols/asio/udp_echo_server/asio_udp_server_test.py +++ b/examples/protocols/asio/udp_echo_server/asio_udp_server_test.py @@ -42,7 +42,7 @@ def test_examples_protocol_asio_udp_server(env, extra_data): # 3. create tcp client and connect to server cli = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) cli.settimeout(30) - cli.connect((data[0], 80)) + cli.connect((data[0], 2222)) cli.send(test_msg) data = cli.recv(1024) # 4. check the message received back from the server @@ -51,7 +51,7 @@ def test_examples_protocol_asio_udp_server(env, extra_data): pass else: print("Failure!") - raise ValueError('Wrong data received from asi udp server: {} (expoected:{})'.format(data, test_msg)) + raise ValueError('Wrong data received from asio udp server: {} (expected:{})'.format(data, test_msg)) # 5. check the client message appears also on server terminal dut1.expect(test_msg.decode()) diff --git a/examples/protocols/asio/udp_echo_server/components/CMakeLists.txt b/examples/protocols/asio/udp_echo_server/components/CMakeLists.txt deleted file mode 100644 index e517667247..0000000000 --- a/examples/protocols/asio/udp_echo_server/components/CMakeLists.txt +++ /dev/null @@ -1,5 +0,0 @@ -set(COMPONENT_SRCS "wifi_asio.cpp") - -set(COMPONENT_PRIV_REQUIRES asio nvs_flash console) - -register_component() diff --git a/examples/protocols/asio/udp_echo_server/components/component.mk b/examples/protocols/asio/udp_echo_server/components/component.mk deleted file mode 100644 index b23b0cb719..0000000000 --- a/examples/protocols/asio/udp_echo_server/components/component.mk +++ /dev/null @@ -1,10 +0,0 @@ -# -# Component Makefile -# -# This Makefile should, at the very least, just include $(SDK_PATH)/Makefile. By default, -# this will take the sources in the src/ directory, compile them and link them into -# lib(subdirectory_name).a in the build directory. This behaviour is entirely configurable, -# please read the SDK documents if you need to do this. -# - -COMPONENT_SRCDIRS = . diff --git a/examples/protocols/asio/udp_echo_server/components/wifi_asio.cpp b/examples/protocols/asio/udp_echo_server/components/wifi_asio.cpp deleted file mode 100644 index b90ce26ae0..0000000000 --- a/examples/protocols/asio/udp_echo_server/components/wifi_asio.cpp +++ /dev/null @@ -1,136 +0,0 @@ -/* Common WiFi Init as STA for ASIO examples - - This example code is in the Public Domain (or CC0 licensed, at your option.) - - Unless required by applicable law or agreed to in writing, this - software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - CONDITIONS OF ANY KIND, either express or implied. -*/ -#include "freertos/FreeRTOS.h" -#include "freertos/task.h" -#include "freertos/event_groups.h" -#include "esp_system.h" -#include "esp_wifi.h" -#include "esp_event_loop.h" -#include "esp_log.h" -#include "nvs_flash.h" -#include "driver/uart.h" -#include "esp_console.h" -#include "esp_vfs_dev.h" - -#include "lwip/err.h" -#include "lwip/sys.h" - -#include - -/* The examples use simple WiFi configuration that you can set via - 'make menuconfig'. - - If you'd rather not, just change the below entries to strings with - the config you want - ie #define EXAMPLE_WIFI_SSID "mywifissid" -*/ -#define EXAMPLE_ESP_WIFI_SSID CONFIG_ESP_WIFI_SSID -#define EXAMPLE_ESP_WIFI_PASS CONFIG_ESP_WIFI_PASSWORD - -/* FreeRTOS event group to signal when we are connected*/ -static EventGroupHandle_t wifi_event_group; - -/* The event group allows multiple bits for each event, - but we only care about one event - are we connected - to the AP with an IP? */ -const int WIFI_CONNECTED_BIT = BIT0; - -static const char *TAG = "asio example wifi init"; - -/** - * Definition of ASIO main method, which is called after network initialized - */ -void asio_main(); - -static esp_err_t event_handler(void *ctx, system_event_t *event) -{ - switch(event->event_id) { - case SYSTEM_EVENT_STA_START: - esp_wifi_connect(); - break; - case SYSTEM_EVENT_STA_GOT_IP: - ESP_LOGI(TAG, "got ip:%s", - ip4addr_ntoa(&event->event_info.got_ip.ip_info.ip)); - xEventGroupSetBits(wifi_event_group, WIFI_CONNECTED_BIT); - break; - case SYSTEM_EVENT_AP_STACONNECTED: - ESP_LOGI(TAG, "station:" MACSTR " join, AID=%d", - MAC2STR(event->event_info.sta_connected.mac), - event->event_info.sta_connected.aid); - break; - case SYSTEM_EVENT_AP_STADISCONNECTED: - ESP_LOGI(TAG, "station:" MACSTR "leave, AID=%d", - MAC2STR(event->event_info.sta_disconnected.mac), - event->event_info.sta_disconnected.aid); - break; - case SYSTEM_EVENT_STA_DISCONNECTED: - esp_wifi_connect(); - xEventGroupClearBits(wifi_event_group, WIFI_CONNECTED_BIT); - break; - default: - break; - } - return ESP_OK; -} - -void wifi_init_sta() -{ - wifi_event_group = xEventGroupCreate(); - - tcpip_adapter_init(); - ESP_ERROR_CHECK(esp_event_loop_init(event_handler, NULL) ); - - wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); - ESP_ERROR_CHECK(esp_wifi_init(&cfg)); - wifi_config_t wifi_config; - // zero out the config struct to ensure defaults are setup - memset(&wifi_config, 0, sizeof(wifi_sta_config_t)); - // only copy ssid&password from example config - strcpy((char*)(wifi_config.sta.ssid), EXAMPLE_ESP_WIFI_SSID); - strcpy((char*)(wifi_config.sta.password), EXAMPLE_ESP_WIFI_PASS); - - ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA) ); - ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config) ); - ESP_ERROR_CHECK(esp_wifi_start() ); - - ESP_LOGI(TAG, "wifi_init_sta finished."); - ESP_LOGI(TAG, "connect to ap SSID:%s password:%s", - EXAMPLE_ESP_WIFI_SSID, EXAMPLE_ESP_WIFI_PASS); -} - -extern "C" void app_main() -{ - //Initialize NVS - esp_err_t ret = nvs_flash_init(); - if (ret == ESP_ERR_NVS_NO_FREE_PAGES) { - ESP_ERROR_CHECK(nvs_flash_erase()); - ret = nvs_flash_init(); - } - ESP_ERROR_CHECK(ret); - - ESP_LOGI(TAG, "ESP_WIFI_MODE_AP"); - wifi_init_sta(); - - // Initialize VFS & UART so we can use std::cout/cin - setvbuf(stdin, NULL, _IONBF, 0); - setvbuf(stdout, NULL, _IONBF, 0); - /* Install UART driver for interrupt-driven reads and writes */ - ESP_ERROR_CHECK( uart_driver_install( (uart_port_t)CONFIG_CONSOLE_UART_NUM, - 256, 0, 0, NULL, 0) ); - /* Tell VFS to use UART driver */ - esp_vfs_dev_uart_use_driver(CONFIG_CONSOLE_UART_NUM); - esp_vfs_dev_uart_set_rx_line_endings(ESP_LINE_ENDINGS_CR); - /* Move the caret to the beginning of the next line on '\n' */ - esp_vfs_dev_uart_set_tx_line_endings(ESP_LINE_ENDINGS_CRLF); - - // wait till we receive IP, so asio realated code can be started - xEventGroupWaitBits(wifi_event_group, WIFI_CONNECTED_BIT, 1, 1, portMAX_DELAY); - - // network is ready, let's proceed with ASIO example - asio_main(); -} diff --git a/examples/protocols/asio/udp_echo_server/main/Kconfig.projbuild b/examples/protocols/asio/udp_echo_server/main/Kconfig.projbuild index ecbbf8ae91..795326db91 100644 --- a/examples/protocols/asio/udp_echo_server/main/Kconfig.projbuild +++ b/examples/protocols/asio/udp_echo_server/main/Kconfig.projbuild @@ -1,21 +1,9 @@ menu "Example Configuration" - config ESP_WIFI_SSID - string "WiFi SSID" - default "myssid" - help - SSID (network name) for the example to connect to. - - config ESP_WIFI_PASSWORD - string "WiFi Password" - default "mypassword" - help - WiFi password (WPA or WPA2) for the example to use. - config EXAMPLE_PORT - string "asio example port number" - default "80" + string "Asio example port number" + default "2222" help - Port number used by ASIO example + Port number used by Asio example. endmenu diff --git a/examples/protocols/asio/udp_echo_server/main/udp_echo_server.cpp b/examples/protocols/asio/udp_echo_server/main/udp_echo_server.cpp index 5b6607d736..06ac3fec92 100644 --- a/examples/protocols/asio/udp_echo_server/main/udp_echo_server.cpp +++ b/examples/protocols/asio/udp_echo_server/main/udp_echo_server.cpp @@ -13,6 +13,12 @@ #include "asio.hpp" +#include "protocol_examples_common.h" +#include "esp_event.h" +#include "tcpip_adapter.h" +#include "nvs_flash.h" + + using asio::ip::udp; class server @@ -32,6 +38,7 @@ public: { if (!ec && bytes_recvd > 0) { + data_[bytes_recvd] = 0; std::cout << data_ << std::endl; do_send(bytes_recvd); } @@ -59,8 +66,21 @@ private: char data_[max_length]; }; -void asio_main() +extern "C" void app_main() { + ESP_ERROR_CHECK(nvs_flash_init()); + tcpip_adapter_init(); + ESP_ERROR_CHECK(esp_event_loop_create_default()); + + /* This helper function configures Wi-Fi or Ethernet, as selected in menuconfig. + * Read "Establishing Wi-Fi or Ethernet Connection" section in + * examples/protocols/README.md for more information about this function. + */ + ESP_ERROR_CHECK(example_connect()); + + /* This helper function configures blocking UART I/O */ + ESP_ERROR_CHECK(example_configure_stdin_stdout()); + asio::io_context io_context; server s(io_context, std::atoi(CONFIG_EXAMPLE_PORT)); diff --git a/examples/protocols/asio/wifi_init/wifi_asio.cpp b/examples/protocols/asio/wifi_init/wifi_asio.cpp deleted file mode 100644 index b90ce26ae0..0000000000 --- a/examples/protocols/asio/wifi_init/wifi_asio.cpp +++ /dev/null @@ -1,136 +0,0 @@ -/* Common WiFi Init as STA for ASIO examples - - This example code is in the Public Domain (or CC0 licensed, at your option.) - - Unless required by applicable law or agreed to in writing, this - software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - CONDITIONS OF ANY KIND, either express or implied. -*/ -#include "freertos/FreeRTOS.h" -#include "freertos/task.h" -#include "freertos/event_groups.h" -#include "esp_system.h" -#include "esp_wifi.h" -#include "esp_event_loop.h" -#include "esp_log.h" -#include "nvs_flash.h" -#include "driver/uart.h" -#include "esp_console.h" -#include "esp_vfs_dev.h" - -#include "lwip/err.h" -#include "lwip/sys.h" - -#include - -/* The examples use simple WiFi configuration that you can set via - 'make menuconfig'. - - If you'd rather not, just change the below entries to strings with - the config you want - ie #define EXAMPLE_WIFI_SSID "mywifissid" -*/ -#define EXAMPLE_ESP_WIFI_SSID CONFIG_ESP_WIFI_SSID -#define EXAMPLE_ESP_WIFI_PASS CONFIG_ESP_WIFI_PASSWORD - -/* FreeRTOS event group to signal when we are connected*/ -static EventGroupHandle_t wifi_event_group; - -/* The event group allows multiple bits for each event, - but we only care about one event - are we connected - to the AP with an IP? */ -const int WIFI_CONNECTED_BIT = BIT0; - -static const char *TAG = "asio example wifi init"; - -/** - * Definition of ASIO main method, which is called after network initialized - */ -void asio_main(); - -static esp_err_t event_handler(void *ctx, system_event_t *event) -{ - switch(event->event_id) { - case SYSTEM_EVENT_STA_START: - esp_wifi_connect(); - break; - case SYSTEM_EVENT_STA_GOT_IP: - ESP_LOGI(TAG, "got ip:%s", - ip4addr_ntoa(&event->event_info.got_ip.ip_info.ip)); - xEventGroupSetBits(wifi_event_group, WIFI_CONNECTED_BIT); - break; - case SYSTEM_EVENT_AP_STACONNECTED: - ESP_LOGI(TAG, "station:" MACSTR " join, AID=%d", - MAC2STR(event->event_info.sta_connected.mac), - event->event_info.sta_connected.aid); - break; - case SYSTEM_EVENT_AP_STADISCONNECTED: - ESP_LOGI(TAG, "station:" MACSTR "leave, AID=%d", - MAC2STR(event->event_info.sta_disconnected.mac), - event->event_info.sta_disconnected.aid); - break; - case SYSTEM_EVENT_STA_DISCONNECTED: - esp_wifi_connect(); - xEventGroupClearBits(wifi_event_group, WIFI_CONNECTED_BIT); - break; - default: - break; - } - return ESP_OK; -} - -void wifi_init_sta() -{ - wifi_event_group = xEventGroupCreate(); - - tcpip_adapter_init(); - ESP_ERROR_CHECK(esp_event_loop_init(event_handler, NULL) ); - - wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); - ESP_ERROR_CHECK(esp_wifi_init(&cfg)); - wifi_config_t wifi_config; - // zero out the config struct to ensure defaults are setup - memset(&wifi_config, 0, sizeof(wifi_sta_config_t)); - // only copy ssid&password from example config - strcpy((char*)(wifi_config.sta.ssid), EXAMPLE_ESP_WIFI_SSID); - strcpy((char*)(wifi_config.sta.password), EXAMPLE_ESP_WIFI_PASS); - - ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA) ); - ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config) ); - ESP_ERROR_CHECK(esp_wifi_start() ); - - ESP_LOGI(TAG, "wifi_init_sta finished."); - ESP_LOGI(TAG, "connect to ap SSID:%s password:%s", - EXAMPLE_ESP_WIFI_SSID, EXAMPLE_ESP_WIFI_PASS); -} - -extern "C" void app_main() -{ - //Initialize NVS - esp_err_t ret = nvs_flash_init(); - if (ret == ESP_ERR_NVS_NO_FREE_PAGES) { - ESP_ERROR_CHECK(nvs_flash_erase()); - ret = nvs_flash_init(); - } - ESP_ERROR_CHECK(ret); - - ESP_LOGI(TAG, "ESP_WIFI_MODE_AP"); - wifi_init_sta(); - - // Initialize VFS & UART so we can use std::cout/cin - setvbuf(stdin, NULL, _IONBF, 0); - setvbuf(stdout, NULL, _IONBF, 0); - /* Install UART driver for interrupt-driven reads and writes */ - ESP_ERROR_CHECK( uart_driver_install( (uart_port_t)CONFIG_CONSOLE_UART_NUM, - 256, 0, 0, NULL, 0) ); - /* Tell VFS to use UART driver */ - esp_vfs_dev_uart_use_driver(CONFIG_CONSOLE_UART_NUM); - esp_vfs_dev_uart_set_rx_line_endings(ESP_LINE_ENDINGS_CR); - /* Move the caret to the beginning of the next line on '\n' */ - esp_vfs_dev_uart_set_tx_line_endings(ESP_LINE_ENDINGS_CRLF); - - // wait till we receive IP, so asio realated code can be started - xEventGroupWaitBits(wifi_event_group, WIFI_CONNECTED_BIT, 1, 1, portMAX_DELAY); - - // network is ready, let's proceed with ASIO example - asio_main(); -} diff --git a/examples/protocols/coap_client/CMakeLists.txt b/examples/protocols/coap_client/CMakeLists.txt index 495538d3df..4cad43b5ea 100644 --- a/examples/protocols/coap_client/CMakeLists.txt +++ b/examples/protocols/coap_client/CMakeLists.txt @@ -2,5 +2,9 @@ # in this exact order for cmake to work correctly cmake_minimum_required(VERSION 3.5) +# (Not part of the boilerplate) +# This example uses an extra component for common functions such as Wi-Fi and Ethernet connection. +set(EXTRA_COMPONENT_DIRS $ENV{IDF_PATH}/examples/common_components/protocol_examples_common) + include($ENV{IDF_PATH}/tools/cmake/project.cmake) project(coap_client) diff --git a/examples/protocols/coap_client/Makefile b/examples/protocols/coap_client/Makefile index c9a25d117f..84a2905fb9 100644 --- a/examples/protocols/coap_client/Makefile +++ b/examples/protocols/coap_client/Makefile @@ -5,5 +5,7 @@ PROJECT_NAME := coap_client +EXTRA_COMPONENT_DIRS = $(IDF_PATH)/examples/common_components/protocol_examples_common + include $(IDF_PATH)/make/project.mk diff --git a/examples/protocols/coap_client/main/Kconfig.projbuild b/examples/protocols/coap_client/main/Kconfig.projbuild index 05a0d714f5..929b8cf4fa 100644 --- a/examples/protocols/coap_client/main/Kconfig.projbuild +++ b/examples/protocols/coap_client/main/Kconfig.projbuild @@ -6,16 +6,4 @@ menu "Example Configuration" help Target uri for the example to use. - config WIFI_SSID - string "WiFi SSID" - default "myssid" - help - SSID (network name) for the example to connect to. - - config WIFI_PASSWORD - string "WiFi Password" - default "mypassword" - help - WiFi password (WPA or WPA2) for the example to use. - -endmenu \ No newline at end of file +endmenu diff --git a/examples/protocols/coap_client/main/coap_client_example_main.c b/examples/protocols/coap_client/main/coap_client_example_main.c index 2c1b1294a9..38761267f6 100644 --- a/examples/protocols/coap_client/main/coap_client_example_main.c +++ b/examples/protocols/coap_client/main/coap_client_example_main.c @@ -17,21 +17,14 @@ #include "esp_log.h" #include "esp_wifi.h" -#include "esp_event_loop.h" +#include "esp_event.h" #include "nvs_flash.h" +#include "protocol_examples_common.h" + #include "coap.h" -/* The examples use simple WiFi configuration that you can set via - 'make menuconfig'. - - If you'd rather not, just change the below entries to strings with - the config you want - ie #define EXAMPLE_WIFI_SSID "mywifissid" -*/ -#define EXAMPLE_WIFI_SSID CONFIG_WIFI_SSID -#define EXAMPLE_WIFI_PASS CONFIG_WIFI_PASSWORD - #define COAP_DEFAULT_TIME_SEC 5 /* Set this to 9 to get verbose logging from within libcoap */ @@ -45,13 +38,6 @@ */ #define COAP_DEFAULT_DEMO_URI CONFIG_TARGET_DOMAIN_URI -static EventGroupHandle_t wifi_event_group; - -/* The event group allows multiple bits for each event, - but we only care about one event - are we connected - to the AP with an IP? */ -const static int CONNECTED_BIT = BIT0; - const static char *TAG = "CoAP_client"; static int resp_wait = 1; @@ -159,13 +145,6 @@ static void coap_example_task(void *p) coap_session_t *session = NULL; coap_pdu_t *request = NULL; - /* Wait for the callback to set the CONNECTED_BIT in the - event group. - */ - xEventGroupWaitBits(wifi_event_group, CONNECTED_BIT, - false, true, portMAX_DELAY); - ESP_LOGI(TAG, "Connected to AP"); - optlist = NULL; if (coap_split_uri((const uint8_t *)server_uri, strlen(server_uri), &uri) == -1) { ESP_LOGE(TAG, "CoAP server uri error"); @@ -300,49 +279,17 @@ clean_up: vTaskDelete(NULL); } -static esp_err_t wifi_event_handler(void *ctx, system_event_t *event) -{ - switch(event->event_id) { - case SYSTEM_EVENT_STA_START: - esp_wifi_connect(); - break; - case SYSTEM_EVENT_STA_GOT_IP: - xEventGroupSetBits(wifi_event_group, CONNECTED_BIT); - break; - case SYSTEM_EVENT_STA_DISCONNECTED: - /* This is a workaround as ESP32 WiFi libs don't currently - auto-reassociate. */ - esp_wifi_connect(); - xEventGroupClearBits(wifi_event_group, CONNECTED_BIT); - break; - default: - break; - } - return ESP_OK; -} - -static void wifi_conn_init(void) -{ - tcpip_adapter_init(); - wifi_event_group = xEventGroupCreate(); - ESP_ERROR_CHECK( esp_event_loop_init(wifi_event_handler, NULL) ); - wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); - ESP_ERROR_CHECK( esp_wifi_init(&cfg) ); - ESP_ERROR_CHECK( esp_wifi_set_storage(WIFI_STORAGE_RAM) ); - wifi_config_t wifi_config = { - .sta = { - .ssid = EXAMPLE_WIFI_SSID, - .password = EXAMPLE_WIFI_PASS, - }, - }; - ESP_ERROR_CHECK( esp_wifi_set_mode(WIFI_MODE_STA) ); - ESP_ERROR_CHECK( esp_wifi_set_config(WIFI_IF_STA, &wifi_config) ); - ESP_ERROR_CHECK( esp_wifi_start() ); -} - void app_main(void) { ESP_ERROR_CHECK( nvs_flash_init() ); - wifi_conn_init(); - xTaskCreate(coap_example_task, "coap", 1024 * 5, NULL, 5, NULL); + tcpip_adapter_init(); + ESP_ERROR_CHECK(esp_event_loop_create_default()); + + /* This helper function configures Wi-Fi or Ethernet, as selected in menuconfig. + * Read "Establishing Wi-Fi or Ethernet Connection" section in + * examples/protocols/README.md for more information about this function. + */ + ESP_ERROR_CHECK(example_connect()); + + xTaskCreate(coap_example_task, "coap", 5 * 1024, NULL, 5, NULL); } diff --git a/examples/protocols/coap_server/CMakeLists.txt b/examples/protocols/coap_server/CMakeLists.txt index 16689d2e3b..a162ee1897 100644 --- a/examples/protocols/coap_server/CMakeLists.txt +++ b/examples/protocols/coap_server/CMakeLists.txt @@ -2,5 +2,9 @@ # in this exact order for cmake to work correctly cmake_minimum_required(VERSION 3.5) +# (Not part of the boilerplate) +# This example uses an extra component for common functions such as Wi-Fi and Ethernet connection. +set(EXTRA_COMPONENT_DIRS $ENV{IDF_PATH}/examples/common_components/protocol_examples_common) + include($ENV{IDF_PATH}/tools/cmake/project.cmake) project(coap_server) diff --git a/examples/protocols/coap_server/Makefile b/examples/protocols/coap_server/Makefile index f82e5fc278..63af79f7c5 100644 --- a/examples/protocols/coap_server/Makefile +++ b/examples/protocols/coap_server/Makefile @@ -5,5 +5,7 @@ PROJECT_NAME := coap_server +EXTRA_COMPONENT_DIRS = $(IDF_PATH)/examples/common_components/protocol_examples_common + include $(IDF_PATH)/make/project.mk diff --git a/examples/protocols/coap_server/main/Kconfig.projbuild b/examples/protocols/coap_server/main/Kconfig.projbuild deleted file mode 100644 index 2772f30da8..0000000000 --- a/examples/protocols/coap_server/main/Kconfig.projbuild +++ /dev/null @@ -1,15 +0,0 @@ -menu "Example Configuration" - - config WIFI_SSID - string "WiFi SSID" - default "myssid" - help - SSID (network name) for the example to connect to. - - config WIFI_PASSWORD - string "WiFi Password" - default "mypassword" - help - WiFi password (WPA or WPA2) for the example to use. - -endmenu \ No newline at end of file diff --git a/examples/protocols/coap_server/main/coap_server_example_main.c b/examples/protocols/coap_server/main/coap_server_example_main.c index f41ca9dfdd..eb5e131baa 100644 --- a/examples/protocols/coap_server/main/coap_server_example_main.c +++ b/examples/protocols/coap_server/main/coap_server_example_main.c @@ -16,32 +16,17 @@ #include "esp_log.h" #include "esp_wifi.h" -#include "esp_event_loop.h" +#include "esp_event.h" #include "nvs_flash.h" +#include "protocol_examples_common.h" + #include "coap.h" -/* The examples use simple WiFi configuration that you can set via - 'make menuconfig'. - - If you'd rather not, just change the below entries to strings with - the config you want - ie #define EXAMPLE_WIFI_SSID "mywifissid" -*/ -#define EXAMPLE_WIFI_SSID CONFIG_WIFI_SSID -#define EXAMPLE_WIFI_PASS CONFIG_WIFI_PASSWORD - /* Set this to 9 to get verbose logging from within libcoap */ #define COAP_LOGGING_LEVEL 0 -static EventGroupHandle_t wifi_event_group; - -/* The event group allows multiple bits for each event, - but we only care about one event - are we connected - to the AP with an IP? */ -const static int CONNECTED_BIT = BIT0; - -const static char *TAG = "CoAP_server"; static char espressif_data[100]; static int espressif_data_len = 0; @@ -122,13 +107,6 @@ static void coap_example_thread(void *p) coap_endpoint_t *ep_tcp = NULL; unsigned wait_ms; - /* Wait for the callback to set the CONNECTED_BIT in the - event group. - */ - xEventGroupWaitBits(wifi_event_group, CONNECTED_BIT, - false, true, portMAX_DELAY); - ESP_LOGI(TAG, "Connected to AP"); - /* Prepare the CoAP server socket */ coap_address_init(&serv_addr); serv_addr.addr.sin.sin_family = AF_INET; @@ -181,50 +159,17 @@ clean_up: vTaskDelete(NULL); } -static esp_err_t wifi_event_handler(void *ctx, system_event_t *event) -{ - switch(event->event_id) { - case SYSTEM_EVENT_STA_START: - esp_wifi_connect(); - break; - case SYSTEM_EVENT_STA_GOT_IP: - xEventGroupSetBits(wifi_event_group, CONNECTED_BIT); - break; - case SYSTEM_EVENT_STA_DISCONNECTED: - /* This is a workaround as ESP32 WiFi libs don't currently - auto-reassociate. */ - esp_wifi_connect(); - xEventGroupClearBits(wifi_event_group, CONNECTED_BIT); - break; - default: - break; - } - return ESP_OK; -} - -static void wifi_conn_init(void) -{ - tcpip_adapter_init(); - wifi_event_group = xEventGroupCreate(); - ESP_ERROR_CHECK( esp_event_loop_init(wifi_event_handler, NULL) ); - wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); - ESP_ERROR_CHECK( esp_wifi_init(&cfg) ); - ESP_ERROR_CHECK( esp_wifi_set_storage(WIFI_STORAGE_RAM) ); - wifi_config_t wifi_config = { - .sta = { - .ssid = EXAMPLE_WIFI_SSID, - .password = EXAMPLE_WIFI_PASS, - }, - }; - ESP_ERROR_CHECK( esp_wifi_set_mode(WIFI_MODE_STA) ); - ESP_ERROR_CHECK( esp_wifi_set_config(WIFI_IF_STA, &wifi_config) ); - ESP_ERROR_CHECK( esp_wifi_start() ); -} - void app_main(void) { ESP_ERROR_CHECK( nvs_flash_init() ); - wifi_conn_init(); + tcpip_adapter_init(); + ESP_ERROR_CHECK(esp_event_loop_create_default()); + + /* This helper function configures Wi-Fi or Ethernet, as selected in menuconfig. + * Read "Establishing Wi-Fi or Ethernet Connection" section in + * examples/protocols/README.md for more information about this function. + */ + ESP_ERROR_CHECK(example_connect()); xTaskCreate(coap_example_thread, "coap", 1024 * 5, NULL, 5, NULL); } diff --git a/examples/protocols/esp_http_client/CMakeLists.txt b/examples/protocols/esp_http_client/CMakeLists.txt index 6896d5acd9..cce8eb1e25 100644 --- a/examples/protocols/esp_http_client/CMakeLists.txt +++ b/examples/protocols/esp_http_client/CMakeLists.txt @@ -2,5 +2,9 @@ # CMakeLists in this exact order for cmake to work correctly cmake_minimum_required(VERSION 3.5) +# (Not part of the boilerplate) +# This example uses an extra component for common functions such as Wi-Fi and Ethernet connection. +set(EXTRA_COMPONENT_DIRS $ENV{IDF_PATH}/examples/common_components/protocol_examples_common) + include($ENV{IDF_PATH}/tools/cmake/project.cmake) project(esp-http-client-example) diff --git a/examples/protocols/esp_http_client/Makefile b/examples/protocols/esp_http_client/Makefile index 851c3475df..50d3b5f354 100644 --- a/examples/protocols/esp_http_client/Makefile +++ b/examples/protocols/esp_http_client/Makefile @@ -5,5 +5,7 @@ PROJECT_NAME := esp-http-client-example +EXTRA_COMPONENT_DIRS = $(IDF_PATH)/examples/common_components/protocol_examples_common + include $(IDF_PATH)/make/project.mk diff --git a/examples/protocols/esp_http_client/main/CMakeLists.txt b/examples/protocols/esp_http_client/main/CMakeLists.txt index 093811e664..77a52e233a 100644 --- a/examples/protocols/esp_http_client/main/CMakeLists.txt +++ b/examples/protocols/esp_http_client/main/CMakeLists.txt @@ -1,5 +1,4 @@ -set(COMPONENT_SRCS "app_wifi.c" - "esp_http_client_example.c") +set(COMPONENT_SRCS "esp_http_client_example.c") set(COMPONENT_ADD_INCLUDEDIRS ".") diff --git a/examples/protocols/esp_http_client/main/Kconfig.projbuild b/examples/protocols/esp_http_client/main/Kconfig.projbuild deleted file mode 100644 index 803ab080a8..0000000000 --- a/examples/protocols/esp_http_client/main/Kconfig.projbuild +++ /dev/null @@ -1,17 +0,0 @@ -menu "Example Configuration" - - config WIFI_SSID - string "WiFi SSID" - default "myssid" - help - SSID (network name) for the example to connect to. - - config WIFI_PASSWORD - string "WiFi Password" - default "mypassword" - help - WiFi password (WPA or WPA2) for the example to use. - - Can be left blank if the network has no security set. - -endmenu diff --git a/examples/protocols/esp_http_client/main/app_wifi.c b/examples/protocols/esp_http_client/main/app_wifi.c deleted file mode 100644 index da5ac44d50..0000000000 --- a/examples/protocols/esp_http_client/main/app_wifi.c +++ /dev/null @@ -1,75 +0,0 @@ -/* ESP HTTP Client Example - - This example code is in the Public Domain (or CC0 licensed, at your option.) - - Unless required by applicable law or agreed to in writing, this - software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - CONDITIONS OF ANY KIND, either express or implied. -*/ - -#include "esp_wifi.h" -#include "esp_event_loop.h" -#include "esp_log.h" -#include "esp_system.h" -#include "freertos/event_groups.h" -#include "esp_wifi.h" -#include "esp_event_loop.h" -#include "esp_log.h" -#include "app_wifi.h" - -static const char *TAG = "WIFI"; - -/* FreeRTOS event group to signal when we are connected & ready to make a request */ -static EventGroupHandle_t wifi_event_group; - -/* The event group allows multiple bits for each event, - but we only care about one event - are we connected - to the AP with an IP? */ -const int CONNECTED_BIT = BIT0; - -static esp_err_t event_handler(void *ctx, system_event_t *event) -{ - switch (event->event_id) { - case SYSTEM_EVENT_STA_START: - esp_wifi_connect(); - break; - case SYSTEM_EVENT_STA_GOT_IP: - xEventGroupSetBits(wifi_event_group, CONNECTED_BIT); - break; - case SYSTEM_EVENT_STA_DISCONNECTED: - /* This is a workaround as ESP32 WiFi libs don't currently - auto-reassociate. */ - esp_wifi_connect(); - xEventGroupClearBits(wifi_event_group, CONNECTED_BIT); - break; - default: - break; - } - return ESP_OK; -} - -void app_wifi_initialise(void) -{ - tcpip_adapter_init(); - wifi_event_group = xEventGroupCreate(); - ESP_ERROR_CHECK(esp_event_loop_init(event_handler, NULL)); - wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); - ESP_ERROR_CHECK(esp_wifi_init(&cfg)); - ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_RAM)); - wifi_config_t wifi_config = { - .sta = { - .ssid = CONFIG_WIFI_SSID, - .password = CONFIG_WIFI_PASSWORD, - }, - }; - ESP_LOGI(TAG, "Setting WiFi configuration SSID %s...", wifi_config.sta.ssid); - ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA)); - ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config)); - ESP_ERROR_CHECK(esp_wifi_start()); - -} - -void app_wifi_wait_connected() -{ - xEventGroupWaitBits(wifi_event_group, CONNECTED_BIT, false, true, portMAX_DELAY); -} diff --git a/examples/protocols/esp_http_client/main/app_wifi.h b/examples/protocols/esp_http_client/main/app_wifi.h deleted file mode 100644 index 91c886d5b8..0000000000 --- a/examples/protocols/esp_http_client/main/app_wifi.h +++ /dev/null @@ -1,17 +0,0 @@ -/* ESP HTTP Client Example - - This example code is in the Public Domain (or CC0 licensed, at your option.) - - Unless required by applicable law or agreed to in writing, this - software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - CONDITIONS OF ANY KIND, either express or implied. -*/ - -#ifndef _APP_WIFI_H_ -#define _APP_WIFI_H_ - -void app_wifi_initialise(void); -void app_wifi_wait_connected(); - - -#endif diff --git a/examples/protocols/esp_http_client/main/esp_http_client_example.c b/examples/protocols/esp_http_client/main/esp_http_client_example.c index 3978671b4c..c1aa73ea98 100644 --- a/examples/protocols/esp_http_client/main/esp_http_client_example.c +++ b/examples/protocols/esp_http_client/main/esp_http_client_example.c @@ -14,7 +14,9 @@ #include "esp_log.h" #include "esp_system.h" #include "nvs_flash.h" -#include "app_wifi.h" +#include "esp_event.h" +#include "tcpip_adapter.h" +#include "protocol_examples_common.h" #include "esp_http_client.h" @@ -486,8 +488,6 @@ static void https_async() static void http_test_task(void *pvParameters) { - app_wifi_wait_connected(); - ESP_LOGI(TAG, "Connected to AP, begin http example"); http_rest_with_url(); http_rest_with_hostname_path(); http_auth_basic(); @@ -514,7 +514,14 @@ void app_main() ret = nvs_flash_init(); } ESP_ERROR_CHECK(ret); - app_wifi_initialise(); + tcpip_adapter_init(); + ESP_ERROR_CHECK(esp_event_loop_create_default()); + + /* This helper function configures Wi-Fi or Ethernet, as selected in menuconfig. + * Read "Establishing Wi-Fi or Ethernet Connection" section in + * examples/protocols/README.md for more information about this function. + */ + ESP_ERROR_CHECK(example_connect()); xTaskCreate(&http_test_task, "http_test_task", 8192, NULL, 5, NULL); } diff --git a/examples/protocols/http2_request/CMakeLists.txt b/examples/protocols/http2_request/CMakeLists.txt index edda2c42f6..0a720bf544 100644 --- a/examples/protocols/http2_request/CMakeLists.txt +++ b/examples/protocols/http2_request/CMakeLists.txt @@ -2,5 +2,9 @@ # in this exact order for cmake to work correctly cmake_minimum_required(VERSION 3.5) +# (Not part of the boilerplate) +# This example uses an extra component for common functions such as Wi-Fi and Ethernet connection. +set(EXTRA_COMPONENT_DIRS $ENV{IDF_PATH}/examples/common_components/protocol_examples_common) + include($ENV{IDF_PATH}/tools/cmake/project.cmake) project(http2-request) diff --git a/examples/protocols/http2_request/Makefile b/examples/protocols/http2_request/Makefile index 52a6fe6e08..f7831273cf 100644 --- a/examples/protocols/http2_request/Makefile +++ b/examples/protocols/http2_request/Makefile @@ -5,5 +5,7 @@ PROJECT_NAME := http2-request +EXTRA_COMPONENT_DIRS = $(IDF_PATH)/examples/common_components/protocol_examples_common + include $(IDF_PATH)/make/project.mk diff --git a/examples/protocols/http2_request/main/Kconfig.projbuild b/examples/protocols/http2_request/main/Kconfig.projbuild deleted file mode 100644 index 803ab080a8..0000000000 --- a/examples/protocols/http2_request/main/Kconfig.projbuild +++ /dev/null @@ -1,17 +0,0 @@ -menu "Example Configuration" - - config WIFI_SSID - string "WiFi SSID" - default "myssid" - help - SSID (network name) for the example to connect to. - - config WIFI_PASSWORD - string "WiFi Password" - default "mypassword" - help - WiFi password (WPA or WPA2) for the example to use. - - Can be left blank if the network has no security set. - -endmenu diff --git a/examples/protocols/http2_request/main/http2_request_example_main.c b/examples/protocols/http2_request/main/http2_request_example_main.c index 8083fcf720..180b8b9348 100644 --- a/examples/protocols/http2_request/main/http2_request_example_main.c +++ b/examples/protocols/http2_request/main/http2_request_example_main.c @@ -15,34 +15,16 @@ #include #include "freertos/FreeRTOS.h" #include "freertos/task.h" -#include "freertos/event_groups.h" #include "esp_wifi.h" -#include "esp_event_loop.h" +#include "esp_event.h" #include "lwip/apps/sntp.h" -#include "esp_log.h" #include "esp_system.h" #include "nvs_flash.h" +#include "protocol_examples_common.h" +#include "tcpip_adapter.h" #include "sh2lib.h" -/* The examples use simple WiFi configuration that you can set via - 'make menuconfig'. - - If you'd rather not, just change the below entries to strings with - the config you want - ie #define EXAMPLE_WIFI_SSID "mywifissid" -*/ -#define EXAMPLE_WIFI_SSID CONFIG_WIFI_SSID -#define EXAMPLE_WIFI_PASS CONFIG_WIFI_PASSWORD - -/* FreeRTOS event group to signal when we are connected & ready to make a request */ -static EventGroupHandle_t wifi_event_group; - -/* The event group allows multiple bits for each event, - but we only care about one event - are we connected - to the AP with an IP? */ -const int CONNECTED_BIT = BIT0; - -static const char *TAG = "http2-req"; /* The HTTP/2 server to connect to */ #define HTTP2_SERVER_URI "https://http2.golang.org" @@ -51,6 +33,7 @@ static const char *TAG = "http2-req"; /* A PUT request that echoes whatever we had sent to it */ #define HTTP2_PUT_PATH "/ECHO" + int handle_get_response(struct sh2lib_handle *handle, const char *data, size_t len, int flags) { if (len) { @@ -111,10 +94,6 @@ static void set_time(void) static void http2_task(void *args) { - /* Waiting for connection */ - xEventGroupWaitBits(wifi_event_group, CONNECTED_BIT, - false, true, portMAX_DELAY); - /* Set current time: proper system time is required for TLS based * certificate verification. */ @@ -125,6 +104,7 @@ static void http2_task(void *args) struct sh2lib_handle hd; if (sh2lib_connect(&hd, HTTP2_SERVER_URI) != 0) { printf("Failed to connect\n"); + vTaskDelete(NULL); return; } printf("Connection done\n"); @@ -148,53 +128,17 @@ static void http2_task(void *args) vTaskDelete(NULL); } -static esp_err_t event_handler(void *ctx, system_event_t *event) -{ - switch (event->event_id) { - case SYSTEM_EVENT_STA_START: - ESP_LOGI(TAG, "SYSTEM_EVENT_STA_START"); - ESP_ERROR_CHECK(esp_wifi_connect()); - break; - case SYSTEM_EVENT_STA_GOT_IP: - ESP_LOGI(TAG, "SYSTEM_EVENT_STA_GOT_IP"); - ESP_LOGI(TAG, "got ip:%s\n", ip4addr_ntoa(&event->event_info.got_ip.ip_info.ip)); - xEventGroupSetBits(wifi_event_group, CONNECTED_BIT); - break; - case SYSTEM_EVENT_STA_DISCONNECTED: - ESP_LOGI(TAG, "SYSTEM_EVENT_STA_DISCONNECTED"); - ESP_ERROR_CHECK(esp_wifi_connect()); - xEventGroupClearBits(wifi_event_group, CONNECTED_BIT); - break; - default: - break; - } - return ESP_OK; -} - -static void initialise_wifi(void) -{ - tcpip_adapter_init(); - wifi_event_group = xEventGroupCreate(); - ESP_ERROR_CHECK( esp_event_loop_init(event_handler, NULL) ); - wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); - ESP_ERROR_CHECK( esp_wifi_init(&cfg) ); - ESP_ERROR_CHECK( esp_wifi_set_storage(WIFI_STORAGE_RAM) ); - wifi_config_t wifi_config = { - .sta = { - .ssid = EXAMPLE_WIFI_SSID, - .password = EXAMPLE_WIFI_PASS, - }, - }; - ESP_LOGI(TAG, "Setting WiFi configuration SSID %s...", wifi_config.sta.ssid); - ESP_ERROR_CHECK( esp_wifi_set_mode(WIFI_MODE_STA) ); - ESP_ERROR_CHECK( esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config) ); - ESP_ERROR_CHECK( esp_wifi_start() ); -} - void app_main() { ESP_ERROR_CHECK( nvs_flash_init() ); - initialise_wifi(); + tcpip_adapter_init(); + ESP_ERROR_CHECK(esp_event_loop_create_default()); + + /* This helper function configures Wi-Fi or Ethernet, as selected in menuconfig. + * Read "Establishing Wi-Fi or Ethernet Connection" section in + * examples/protocols/README.md for more information about this function. + */ + ESP_ERROR_CHECK(example_connect()); xTaskCreate(&http2_task, "http2_task", (1024 * 32), NULL, 5, NULL); } diff --git a/examples/protocols/http_request/CMakeLists.txt b/examples/protocols/http_request/CMakeLists.txt index 1c818eb23e..e0024407f3 100644 --- a/examples/protocols/http_request/CMakeLists.txt +++ b/examples/protocols/http_request/CMakeLists.txt @@ -2,5 +2,9 @@ # in this exact order for cmake to work correctly cmake_minimum_required(VERSION 3.5) +# (Not part of the boilerplate) +# This example uses an extra component for common functions such as Wi-Fi and Ethernet connection. +set(EXTRA_COMPONENT_DIRS $ENV{IDF_PATH}/examples/common_components/protocol_examples_common) + include($ENV{IDF_PATH}/tools/cmake/project.cmake) project(http-request) diff --git a/examples/protocols/http_request/Makefile b/examples/protocols/http_request/Makefile index 2625075074..3d31a53068 100644 --- a/examples/protocols/http_request/Makefile +++ b/examples/protocols/http_request/Makefile @@ -5,5 +5,7 @@ PROJECT_NAME := http-request +EXTRA_COMPONENT_DIRS = $(IDF_PATH)/examples/common_components/protocol_examples_common + include $(IDF_PATH)/make/project.mk diff --git a/examples/protocols/http_request/main/Kconfig.projbuild b/examples/protocols/http_request/main/Kconfig.projbuild deleted file mode 100644 index 803ab080a8..0000000000 --- a/examples/protocols/http_request/main/Kconfig.projbuild +++ /dev/null @@ -1,17 +0,0 @@ -menu "Example Configuration" - - config WIFI_SSID - string "WiFi SSID" - default "myssid" - help - SSID (network name) for the example to connect to. - - config WIFI_PASSWORD - string "WiFi Password" - default "mypassword" - help - WiFi password (WPA or WPA2) for the example to use. - - Can be left blank if the network has no security set. - -endmenu diff --git a/examples/protocols/http_request/main/http_request_example_main.c b/examples/protocols/http_request/main/http_request_example_main.c index c51205e821..20f1b667f6 100644 --- a/examples/protocols/http_request/main/http_request_example_main.c +++ b/examples/protocols/http_request/main/http_request_example_main.c @@ -9,12 +9,12 @@ #include #include "freertos/FreeRTOS.h" #include "freertos/task.h" -#include "freertos/event_groups.h" #include "esp_system.h" #include "esp_wifi.h" -#include "esp_event_loop.h" +#include "esp_event.h" #include "esp_log.h" #include "nvs_flash.h" +#include "protocol_examples_common.h" #include "lwip/err.h" #include "lwip/sockets.h" @@ -22,23 +22,6 @@ #include "lwip/netdb.h" #include "lwip/dns.h" -/* The examples use simple WiFi configuration that you can set via - 'make menuconfig'. - - If you'd rather not, just change the below entries to strings with - the config you want - ie #define EXAMPLE_WIFI_SSID "mywifissid" -*/ -#define EXAMPLE_WIFI_SSID CONFIG_WIFI_SSID -#define EXAMPLE_WIFI_PASS CONFIG_WIFI_PASSWORD - -/* FreeRTOS event group to signal when we are connected & ready to make a request */ -static EventGroupHandle_t wifi_event_group; - -/* The event group allows multiple bits for each event, - but we only care about one event - are we connected - to the AP with an IP? */ -const int CONNECTED_BIT = BIT0; - /* Constants that aren't configurable in menuconfig */ #define WEB_SERVER "example.com" #define WEB_PORT 80 @@ -51,47 +34,6 @@ static const char *REQUEST = "GET " WEB_URL " HTTP/1.0\r\n" "User-Agent: esp-idf/1.0 esp32\r\n" "\r\n"; -static esp_err_t event_handler(void *ctx, system_event_t *event) -{ - switch(event->event_id) { - case SYSTEM_EVENT_STA_START: - esp_wifi_connect(); - break; - case SYSTEM_EVENT_STA_GOT_IP: - xEventGroupSetBits(wifi_event_group, CONNECTED_BIT); - break; - case SYSTEM_EVENT_STA_DISCONNECTED: - /* This is a workaround as ESP32 WiFi libs don't currently - auto-reassociate. */ - esp_wifi_connect(); - xEventGroupClearBits(wifi_event_group, CONNECTED_BIT); - break; - default: - break; - } - return ESP_OK; -} - -static void initialise_wifi(void) -{ - tcpip_adapter_init(); - wifi_event_group = xEventGroupCreate(); - ESP_ERROR_CHECK( esp_event_loop_init(event_handler, NULL) ); - wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); - ESP_ERROR_CHECK( esp_wifi_init(&cfg) ); - ESP_ERROR_CHECK( esp_wifi_set_storage(WIFI_STORAGE_RAM) ); - wifi_config_t wifi_config = { - .sta = { - .ssid = EXAMPLE_WIFI_SSID, - .password = EXAMPLE_WIFI_PASS, - }, - }; - ESP_LOGI(TAG, "Setting WiFi configuration SSID %s...", wifi_config.sta.ssid); - ESP_ERROR_CHECK( esp_wifi_set_mode(WIFI_MODE_STA) ); - ESP_ERROR_CHECK( esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config) ); - ESP_ERROR_CHECK( esp_wifi_start() ); -} - static void http_get_task(void *pvParameters) { const struct addrinfo hints = { @@ -104,13 +46,6 @@ static void http_get_task(void *pvParameters) char recv_buf[64]; while(1) { - /* Wait for the callback to set the CONNECTED_BIT in the - event group. - */ - xEventGroupWaitBits(wifi_event_group, CONNECTED_BIT, - false, true, portMAX_DELAY); - ESP_LOGI(TAG, "Connected to AP"); - int err = getaddrinfo(WEB_SERVER, "80", &hints, &res); if(err != 0 || res == NULL) { @@ -174,7 +109,7 @@ static void http_get_task(void *pvParameters) } } while(r > 0); - ESP_LOGI(TAG, "... done reading from socket. Last read return=%d errno=%d\r\n", r, errno); + ESP_LOGI(TAG, "... done reading from socket. Last read return=%d errno=%d.", r, errno); close(s); for(int countdown = 10; countdown >= 0; countdown--) { ESP_LOGI(TAG, "%d... ", countdown); @@ -187,6 +122,14 @@ static void http_get_task(void *pvParameters) void app_main() { ESP_ERROR_CHECK( nvs_flash_init() ); - initialise_wifi(); + tcpip_adapter_init(); + ESP_ERROR_CHECK(esp_event_loop_create_default()); + + /* This helper function configures Wi-Fi or Ethernet, as selected in menuconfig. + * Read "Establishing Wi-Fi or Ethernet Connection" section in + * examples/protocols/README.md for more information about this function. + */ + ESP_ERROR_CHECK(example_connect()); + xTaskCreate(&http_get_task, "http_get_task", 4096, NULL, 5, NULL); } diff --git a/examples/protocols/http_server/advanced_tests/CMakeLists.txt b/examples/protocols/http_server/advanced_tests/CMakeLists.txt index b6f65f8f0f..c3972d7d3c 100644 --- a/examples/protocols/http_server/advanced_tests/CMakeLists.txt +++ b/examples/protocols/http_server/advanced_tests/CMakeLists.txt @@ -2,7 +2,9 @@ # in this exact order for cmake to work correctly cmake_minimum_required(VERSION 3.5) +# (Not part of the boilerplate) +# This example uses an extra component for common functions such as Wi-Fi and Ethernet connection. +set(EXTRA_COMPONENT_DIRS $ENV{IDF_PATH}/examples/common_components/protocol_examples_common) + include($ENV{IDF_PATH}/tools/cmake/project.cmake) project(tests) - -target_include_directories(tests.elf PRIVATE main/include) diff --git a/examples/protocols/http_server/advanced_tests/Makefile b/examples/protocols/http_server/advanced_tests/Makefile index 178ddf6968..07699abcd2 100644 --- a/examples/protocols/http_server/advanced_tests/Makefile +++ b/examples/protocols/http_server/advanced_tests/Makefile @@ -5,5 +5,7 @@ PROJECT_NAME := tests +EXTRA_COMPONENT_DIRS = $(IDF_PATH)/examples/common_components/protocol_examples_common + include $(IDF_PATH)/make/project.mk diff --git a/examples/protocols/http_server/advanced_tests/http_server_advanced_test.py b/examples/protocols/http_server/advanced_tests/http_server_advanced_test.py index 1509fa5410..a27ad5ee02 100644 --- a/examples/protocols/http_server/advanced_tests/http_server_advanced_test.py +++ b/examples/protocols/http_server/advanced_tests/http_server_advanced_test.py @@ -66,7 +66,7 @@ def test_examples_protocol_http_server_advanced(env, extra_data): # Parse IP address of STA Utility.console_log("Waiting to connect with AP") - got_ip = dut1.expect(re.compile(r"(?:[\s\S]*)Got IP: '(\d+.\d+.\d+.\d+)'"), timeout=30)[0] + got_ip = dut1.expect(re.compile(r"(?:[\s\S]*)IPv4 address: (\d+.\d+.\d+.\d+)"), timeout=30)[0] got_port = dut1.expect(re.compile(r"(?:[\s\S]*)Started HTTP server on port: '(\d+)'"), timeout=15)[0] result = dut1.expect(re.compile(r"(?:[\s\S]*)Max URI handlers: '(\d+)'(?:[\s\S]*)Max Open Sessions: " # noqa: W605 diff --git a/examples/protocols/http_server/advanced_tests/main/Kconfig.projbuild b/examples/protocols/http_server/advanced_tests/main/Kconfig.projbuild deleted file mode 100644 index c27669664d..0000000000 --- a/examples/protocols/http_server/advanced_tests/main/Kconfig.projbuild +++ /dev/null @@ -1,16 +0,0 @@ -menu "Example Configuration" - - config WIFI_SSID - string "WiFi SSID" - default "myssid" - help - SSID (network name) for the example to connect to. - - config WIFI_PASSWORD - string "WiFi Password" - default "mypassword" - help - WiFi password (WPA or WPA2) for the example to use. - Can be left blank if the network has no security set. - -endmenu diff --git a/examples/protocols/http_server/advanced_tests/main/main.c b/examples/protocols/http_server/advanced_tests/main/main.c index de32966c8f..d203c48820 100644 --- a/examples/protocols/http_server/advanced_tests/main/main.c +++ b/examples/protocols/http_server/advanced_tests/main/main.c @@ -1,81 +1,72 @@ +/* HTTP Server Tests + + This example code is in the Public Domain (or CC0 licensed, at your option.) + + Unless required by applicable law or agreed to in writing, this + software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + CONDITIONS OF ANY KIND, either express or implied. +*/ + #include "esp_wifi.h" #include "esp_event_loop.h" #include "esp_log.h" #include "esp_system.h" #include "nvs_flash.h" +#include "tcpip_adapter.h" +#include "esp_eth.h" +#include "protocol_examples_common.h" #include "tests.h" -/* The examples use simple WiFi configuration that you can set via - 'make menuconfig'. +static const char *TAG = "example"; - If you'd rather not, just change the below entries to strings with - the config you want - ie #define EXAMPLE_WIFI_SSID "mywifissid" -*/ -#define EXAMPLE_WIFI_SSID CONFIG_WIFI_SSID -#define EXAMPLE_WIFI_PASS CONFIG_WIFI_PASSWORD - -static const char *TAG="TEST_WIFI"; - -static esp_err_t event_handler(void *ctx, system_event_t *event) +static void disconnect_handler(void* arg, esp_event_base_t event_base, + int32_t event_id, void* event_data) { - httpd_handle_t *hd = (httpd_handle_t *) ctx; - - switch(event->event_id) { - case SYSTEM_EVENT_STA_START: - ESP_LOGI(TAG, "SYSTEM_EVENT_STA_START"); - ESP_ERROR_CHECK(esp_wifi_connect()); - break; - case SYSTEM_EVENT_STA_GOT_IP: - ESP_LOGI(TAG, "SYSTEM_EVENT_STA_GOT_IP"); - ESP_LOGI(TAG, "Got IP: '%s'", - ip4addr_ntoa(&event->event_info.got_ip.ip_info.ip)); - - // Start webserver tests - if (*hd == NULL) { - *hd = start_tests(); - } - - break; - case SYSTEM_EVENT_STA_DISCONNECTED: - ESP_LOGI(TAG, "SYSTEM_EVENT_STA_DISCONNECTED"); - ESP_ERROR_CHECK(esp_wifi_connect()); - - // Stop webserver tests - if (*hd) { - stop_tests(*hd); - *hd = NULL; - } - - break; - default: - break; + httpd_handle_t* server = (httpd_handle_t*) arg; + if (*server) { + ESP_LOGI(TAG, "Stopping webserver"); + stop_tests(*server); + *server = NULL; } - return ESP_OK; } -static void initialise_wifi(void) +static void connect_handler(void* arg, esp_event_base_t event_base, + int32_t event_id, void* event_data) { - tcpip_adapter_init(); - static httpd_handle_t hd = NULL; - ESP_ERROR_CHECK(esp_event_loop_init(event_handler, &hd)); - wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); - ESP_ERROR_CHECK(esp_wifi_init(&cfg)); - ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_RAM)); - wifi_config_t wifi_config = { - .sta = { - .ssid = EXAMPLE_WIFI_SSID, - .password = EXAMPLE_WIFI_PASS, - }, - }; - ESP_LOGI(TAG, "Setting WiFi configuration SSID %s...", wifi_config.sta.ssid); - ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA)); - ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config)); - ESP_ERROR_CHECK(esp_wifi_start()); + httpd_handle_t* server = (httpd_handle_t*) arg; + if (*server == NULL) { + ESP_LOGI(TAG, "Starting webserver"); + *server = start_tests(); + } } void app_main() { + static httpd_handle_t server = NULL; + ESP_ERROR_CHECK(nvs_flash_init()); - initialise_wifi(); + tcpip_adapter_init(); + ESP_ERROR_CHECK(esp_event_loop_create_default()); + + /* This helper function configures Wi-Fi or Ethernet, as selected in menuconfig. + * Read "Establishing Wi-Fi or Ethernet Connection" section in + * examples/protocols/README.md for more information about this function. + */ + ESP_ERROR_CHECK(example_connect()); + + /* Register event handlers to stop the server when Wi-Fi or Ethernet is disconnected, + * and re-start it upon connection. + */ +#ifdef CONFIG_EXAMPLE_CONNECT_WIFI + ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &connect_handler, &server)); + ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_STA_DISCONNECTED, &disconnect_handler, &server)); +#endif // CONFIG_EXAMPLE_CONNECT_WIFI +#ifdef CONFIG_EXAMPLE_CONNECT_ETHERNET + ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_ETH_GOT_IP, &connect_handler, &server)); + ESP_ERROR_CHECK(esp_event_handler_register(ETH_EVENT, ETHERNET_EVENT_DISCONNECTED, &disconnect_handler, &server)); +#endif // CONFIG_EXAMPLE_CONNECT_ETHERNET + + /* Start the server for the first time */ + server = start_tests(); } diff --git a/examples/protocols/http_server/advanced_tests/main/tests.c b/examples/protocols/http_server/advanced_tests/main/tests.c index 589bf96469..c41810e612 100644 --- a/examples/protocols/http_server/advanced_tests/main/tests.c +++ b/examples/protocols/http_server/advanced_tests/main/tests.c @@ -7,10 +7,9 @@ #include "tests.h" -static const char *TAG="TESTS"; +static const char *TAG = "TESTS"; -int pre_start_mem, post_stop_mem, post_stop_min_mem; -bool basic_sanity = true; +static int pre_start_mem, post_stop_mem; struct async_resp_arg { httpd_handle_t hd; @@ -19,7 +18,7 @@ struct async_resp_arg { /********************* Basic Handlers Start *******************/ -esp_err_t hello_get_handler(httpd_req_t *req) +static esp_err_t hello_get_handler(httpd_req_t *req) { #define STR "Hello World!" ESP_LOGI(TAG, "Free Stack for server task: '%d'", uxTaskGetStackHighWaterMark(NULL)); @@ -28,7 +27,7 @@ esp_err_t hello_get_handler(httpd_req_t *req) #undef STR } -esp_err_t hello_type_get_handler(httpd_req_t *req) +static esp_err_t hello_type_get_handler(httpd_req_t *req) { #define STR "Hello World!" httpd_resp_set_type(req, HTTPD_TYPE_TEXT); @@ -37,7 +36,7 @@ esp_err_t hello_type_get_handler(httpd_req_t *req) #undef STR } -esp_err_t hello_status_get_handler(httpd_req_t *req) +static esp_err_t hello_status_get_handler(httpd_req_t *req) { #define STR "Hello World!" httpd_resp_set_status(req, HTTPD_500); @@ -46,7 +45,7 @@ esp_err_t hello_status_get_handler(httpd_req_t *req) #undef STR } -esp_err_t echo_post_handler(httpd_req_t *req) +static esp_err_t echo_post_handler(httpd_req_t *req) { ESP_LOGI(TAG, "/echo handler read content length %d", req->content_len); @@ -101,7 +100,7 @@ esp_err_t echo_post_handler(httpd_req_t *req) return ESP_OK; } -void adder_free_func(void *ctx) +static void adder_free_func(void *ctx) { ESP_LOGI(TAG, "Custom Free Context function called"); free(ctx); @@ -110,7 +109,7 @@ void adder_free_func(void *ctx) /* Create a context, keep incrementing value in the context, by whatever was * received. Return the result */ -esp_err_t adder_post_handler(httpd_req_t *req) +static esp_err_t adder_post_handler(httpd_req_t *req) { char buf[10]; char outbuf[50]; @@ -143,7 +142,7 @@ esp_err_t adder_post_handler(httpd_req_t *req) return ESP_OK; } -esp_err_t leftover_data_post_handler(httpd_req_t *req) +static esp_err_t leftover_data_post_handler(httpd_req_t *req) { /* Only echo the first 10 bytes of the request, leaving the rest of the * request data as is. @@ -166,8 +165,9 @@ esp_err_t leftover_data_post_handler(httpd_req_t *req) return ESP_OK; } -int httpd_default_send(httpd_handle_t hd, int sockfd, const char *buf, unsigned buf_len, int flags); -void generate_async_resp(void *arg) +extern int httpd_default_send(httpd_handle_t hd, int sockfd, const char *buf, unsigned buf_len, int flags); + +static void generate_async_resp(void *arg) { char buf[250]; struct async_resp_arg *resp_arg = (struct async_resp_arg *)arg; @@ -190,7 +190,7 @@ void generate_async_resp(void *arg) free(arg); } -esp_err_t async_get_handler(httpd_req_t *req) +static esp_err_t async_get_handler(httpd_req_t *req) { #define STR "Hello World!" httpd_resp_send(req, STR, strlen(STR)); @@ -211,7 +211,7 @@ esp_err_t async_get_handler(httpd_req_t *req) } -httpd_uri_t basic_handlers[] = { +static const httpd_uri_t basic_handlers[] = { { .uri = "/hello/type_html", .method = HTTP_GET, .handler = hello_type_get_handler, @@ -254,8 +254,9 @@ httpd_uri_t basic_handlers[] = { } }; -int basic_handlers_no = sizeof(basic_handlers)/sizeof(httpd_uri_t); -void register_basic_handlers(httpd_handle_t hd) +static const int basic_handlers_no = sizeof(basic_handlers)/sizeof(httpd_uri_t); + +static void register_basic_handlers(httpd_handle_t hd) { int i; ESP_LOGI(TAG, "Registering basic handlers"); @@ -269,7 +270,7 @@ void register_basic_handlers(httpd_handle_t hd) ESP_LOGI(TAG, "Success"); } -httpd_handle_t test_httpd_start() +static httpd_handle_t test_httpd_start() { pre_start_mem = esp_get_free_heap_size(); httpd_handle_t hd; @@ -291,7 +292,7 @@ httpd_handle_t test_httpd_start() return NULL; } -void test_httpd_stop(httpd_handle_t hd) +static void test_httpd_stop(httpd_handle_t hd) { httpd_stop(hd); post_stop_mem = esp_get_free_heap_size(); diff --git a/examples/protocols/http_server/file_serving/CMakeLists.txt b/examples/protocols/http_server/file_serving/CMakeLists.txt index 17591d30d7..be30203200 100644 --- a/examples/protocols/http_server/file_serving/CMakeLists.txt +++ b/examples/protocols/http_server/file_serving/CMakeLists.txt @@ -2,5 +2,9 @@ # in this exact order for cmake to work correctly cmake_minimum_required(VERSION 3.5) +# (Not part of the boilerplate) +# This example uses an extra component for common functions such as Wi-Fi and Ethernet connection. +set(EXTRA_COMPONENT_DIRS $ENV{IDF_PATH}/examples/common_components/protocol_examples_common) + include($ENV{IDF_PATH}/tools/cmake/project.cmake) project(file_server) diff --git a/examples/protocols/http_server/file_serving/Makefile b/examples/protocols/http_server/file_serving/Makefile index 7b1def8bc8..f53a50600b 100644 --- a/examples/protocols/http_server/file_serving/Makefile +++ b/examples/protocols/http_server/file_serving/Makefile @@ -5,5 +5,7 @@ PROJECT_NAME := file_server +EXTRA_COMPONENT_DIRS = $(IDF_PATH)/examples/common_components/protocol_examples_common + include $(IDF_PATH)/make/project.mk diff --git a/examples/protocols/http_server/file_serving/main/Kconfig.projbuild b/examples/protocols/http_server/file_serving/main/Kconfig.projbuild deleted file mode 100644 index c27669664d..0000000000 --- a/examples/protocols/http_server/file_serving/main/Kconfig.projbuild +++ /dev/null @@ -1,16 +0,0 @@ -menu "Example Configuration" - - config WIFI_SSID - string "WiFi SSID" - default "myssid" - help - SSID (network name) for the example to connect to. - - config WIFI_PASSWORD - string "WiFi Password" - default "mypassword" - help - WiFi password (WPA or WPA2) for the example to use. - Can be left blank if the network has no security set. - -endmenu diff --git a/examples/protocols/http_server/file_serving/main/main.c b/examples/protocols/http_server/file_serving/main/main.c index ee1aaeef60..8515f61334 100644 --- a/examples/protocols/http_server/file_serving/main/main.c +++ b/examples/protocols/http_server/file_serving/main/main.c @@ -15,66 +15,15 @@ #include "esp_system.h" #include "esp_spiffs.h" #include "nvs_flash.h" +#include "tcpip_adapter.h" +#include "protocol_examples_common.h" /* This example demonstrates how to create file server * using esp_http_server. This file has only startup code. * Look in file_server.c for the implementation */ -/* The example uses simple WiFi configuration that you can set via - * 'make menuconfig'. - * If you'd rather not, just change the below entries to strings - * with the config you want - - * ie. #define EXAMPLE_WIFI_SSID "mywifissid" -*/ -#define EXAMPLE_WIFI_SSID CONFIG_WIFI_SSID -#define EXAMPLE_WIFI_PASS CONFIG_WIFI_PASSWORD - static const char *TAG="example"; -/* Wi-Fi event handler */ -static esp_err_t event_handler(void *ctx, system_event_t *event) -{ - switch(event->event_id) { - case SYSTEM_EVENT_STA_START: - ESP_LOGI(TAG, "SYSTEM_EVENT_STA_START"); - ESP_ERROR_CHECK(esp_wifi_connect()); - break; - case SYSTEM_EVENT_STA_GOT_IP: - ESP_LOGI(TAG, "SYSTEM_EVENT_STA_GOT_IP"); - ESP_LOGI(TAG, "Got IP: '%s'", - ip4addr_ntoa(&event->event_info.got_ip.ip_info.ip)); - break; - case SYSTEM_EVENT_STA_DISCONNECTED: - ESP_LOGI(TAG, "SYSTEM_EVENT_STA_DISCONNECTED"); - ESP_ERROR_CHECK(esp_wifi_connect()); - break; - default: - break; - } - return ESP_OK; -} - -/* Function to initialize Wi-Fi at station */ -static void initialise_wifi(void) -{ - ESP_ERROR_CHECK(nvs_flash_init()); - tcpip_adapter_init(); - ESP_ERROR_CHECK(esp_event_loop_init(event_handler, NULL)); - wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); - ESP_ERROR_CHECK(esp_wifi_init(&cfg)); - ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_RAM)); - wifi_config_t wifi_config = { - .sta = { - .ssid = EXAMPLE_WIFI_SSID, - .password = EXAMPLE_WIFI_PASS, - }, - }; - ESP_LOGI(TAG, "Setting WiFi configuration SSID %s...", wifi_config.sta.ssid); - ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA)); - ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config)); - ESP_ERROR_CHECK(esp_wifi_start()); -} - /* Function to initialize SPIFFS */ static esp_err_t init_spiffs(void) { @@ -117,7 +66,15 @@ esp_err_t start_file_server(const char *base_path); void app_main() { - initialise_wifi(); + ESP_ERROR_CHECK(nvs_flash_init()); + tcpip_adapter_init(); + ESP_ERROR_CHECK(esp_event_loop_create_default()); + + /* This helper function configures Wi-Fi or Ethernet, as selected in menuconfig. + * Read "Establishing Wi-Fi or Ethernet Connection" section in + * examples/protocols/README.md for more information about this function. + */ + ESP_ERROR_CHECK(example_connect()); /* Initialize file storage */ ESP_ERROR_CHECK(init_spiffs()); diff --git a/examples/protocols/http_server/persistent_sockets/CMakeLists.txt b/examples/protocols/http_server/persistent_sockets/CMakeLists.txt index 2d453b679a..b6d34fb24b 100644 --- a/examples/protocols/http_server/persistent_sockets/CMakeLists.txt +++ b/examples/protocols/http_server/persistent_sockets/CMakeLists.txt @@ -2,6 +2,10 @@ # in this exact order for cmake to work correctly cmake_minimum_required(VERSION 3.5) +# (Not part of the boilerplate) +# This example uses an extra component for common functions such as Wi-Fi and Ethernet connection. +set(EXTRA_COMPONENT_DIRS $ENV{IDF_PATH}/examples/common_components/protocol_examples_common) + include($ENV{IDF_PATH}/tools/cmake/project.cmake) project(persistent_sockets) diff --git a/examples/protocols/http_server/persistent_sockets/Makefile b/examples/protocols/http_server/persistent_sockets/Makefile index 9c17802296..f20d51a636 100644 --- a/examples/protocols/http_server/persistent_sockets/Makefile +++ b/examples/protocols/http_server/persistent_sockets/Makefile @@ -5,5 +5,7 @@ PROJECT_NAME := persistent_sockets +EXTRA_COMPONENT_DIRS = $(IDF_PATH)/examples/common_components/protocol_examples_common + include $(IDF_PATH)/make/project.mk diff --git a/examples/protocols/http_server/persistent_sockets/README.md b/examples/protocols/http_server/persistent_sockets/README.md index b7517d8fd1..ded2cfd6cf 100644 --- a/examples/protocols/http_server/persistent_sockets/README.md +++ b/examples/protocols/http_server/persistent_sockets/README.md @@ -1,12 +1,9 @@ -# HTTPD Server Persistant Sockets Example +# HTTPD Server Persistent Sockets Example The Example consists of HTTPD server persistent sockets demo. -This sort of persistancy enables the server to have independent sessions/contexts per client. +This sort of persistency enables the server to have independent sessions/contexts per client. -* Configure the project using "make menuconfig" and goto : - * Example Configuration -> - 1. WIFI SSID: WIFI network to which your PC is also connected to. - 2. WIFI Password: WIFI password +* Run `make menuconfig` (or `idf.py menuconfig` if using CMake build system) to configure Wi-Fi or Ethernet. See "Establishing Wi-Fi or Ethernet Connection" section in [examples/protocols/README.md](../../README.md) for more details. * In order to test the HTTPD server persistent sockets demo : 1. compile and burn the firmware "make flash" diff --git a/examples/protocols/http_server/persistent_sockets/http_server_persistence_test.py b/examples/protocols/http_server/persistent_sockets/http_server_persistence_test.py index dae81814e2..43174bc52c 100644 --- a/examples/protocols/http_server/persistent_sockets/http_server_persistence_test.py +++ b/examples/protocols/http_server/persistent_sockets/http_server_persistence_test.py @@ -62,7 +62,7 @@ def test_examples_protocol_http_server_persistence(env, extra_data): # Parse IP address of STA Utility.console_log("Waiting to connect with AP") - got_ip = dut1.expect(re.compile(r"(?:[\s\S]*)Got IP: '(\d+.\d+.\d+.\d+)'"), timeout=120)[0] + got_ip = dut1.expect(re.compile(r"(?:[\s\S]*)IPv4 address: (\d+.\d+.\d+.\d+)"), timeout=30)[0] got_port = dut1.expect(re.compile(r"(?:[\s\S]*)Starting server on port: '(\d+)'"), timeout=30)[0] Utility.console_log("Got IP : " + got_ip) diff --git a/examples/protocols/http_server/persistent_sockets/main/Kconfig.projbuild b/examples/protocols/http_server/persistent_sockets/main/Kconfig.projbuild deleted file mode 100644 index c27669664d..0000000000 --- a/examples/protocols/http_server/persistent_sockets/main/Kconfig.projbuild +++ /dev/null @@ -1,16 +0,0 @@ -menu "Example Configuration" - - config WIFI_SSID - string "WiFi SSID" - default "myssid" - help - SSID (network name) for the example to connect to. - - config WIFI_PASSWORD - string "WiFi Password" - default "mypassword" - help - WiFi password (WPA or WPA2) for the example to use. - Can be left blank if the network has no security set. - -endmenu diff --git a/examples/protocols/http_server/persistent_sockets/main/main.c b/examples/protocols/http_server/persistent_sockets/main/main.c index b353559292..3d551fe268 100644 --- a/examples/protocols/http_server/persistent_sockets/main/main.c +++ b/examples/protocols/http_server/persistent_sockets/main/main.c @@ -12,22 +12,20 @@ #include #include #include +#include "tcpip_adapter.h" +#include "esp_eth.h" +#include "protocol_examples_common.h" #include /* An example to demonstrate persistent sockets, with context maintained across * multiple requests on that socket. - * The examples use simple WiFi configuration that you can set via 'make menuconfig'. - * If you'd rather not, just change the below entries to strings with - * the config you want - ie #define EXAMPLE_WIFI_SSID "mywifissid" */ -#define EXAMPLE_WIFI_SSID CONFIG_WIFI_SSID -#define EXAMPLE_WIFI_PASS CONFIG_WIFI_PASSWORD - -static const char *TAG="APP"; +static const char *TAG = "example"; + /* Function to free context */ -void adder_free_func(void *ctx) +static void adder_free_func(void *ctx) { ESP_LOGI(TAG, "/adder Free Context function called"); free(ctx); @@ -36,7 +34,7 @@ void adder_free_func(void *ctx) /* This handler keeps accumulating data that is posted to it into a per * socket/session context. And returns the result. */ -esp_err_t adder_post_handler(httpd_req_t *req) +static esp_err_t adder_post_handler(httpd_req_t *req) { /* Log total visitors */ unsigned *visitors = (unsigned *)req->user_ctx; @@ -78,7 +76,7 @@ esp_err_t adder_post_handler(httpd_req_t *req) } /* This handler gets the present value of the accumulator */ -esp_err_t adder_get_handler(httpd_req_t *req) +static esp_err_t adder_get_handler(httpd_req_t *req) { /* Log total visitors */ unsigned *visitors = (unsigned *)req->user_ctx; @@ -102,7 +100,7 @@ esp_err_t adder_get_handler(httpd_req_t *req) } /* This handler resets the value of the accumulator */ -esp_err_t adder_put_handler(httpd_req_t *req) +static esp_err_t adder_put_handler(httpd_req_t *req) { /* Log total visitors */ unsigned *visitors = (unsigned *)req->user_ctx; @@ -143,28 +141,28 @@ esp_err_t adder_put_handler(httpd_req_t *req) * the "/adder" URI has been visited */ static unsigned visitors = 0; -httpd_uri_t adder_post = { +static const httpd_uri_t adder_post = { .uri = "/adder", .method = HTTP_POST, .handler = adder_post_handler, .user_ctx = &visitors }; -httpd_uri_t adder_get = { +static const httpd_uri_t adder_get = { .uri = "/adder", .method = HTTP_GET, .handler = adder_get_handler, .user_ctx = &visitors }; -httpd_uri_t adder_put = { +static const httpd_uri_t adder_put = { .uri = "/adder", .method = HTTP_PUT, .handler = adder_put_handler, .user_ctx = &visitors }; -httpd_handle_t start_webserver(void) +static httpd_handle_t start_webserver(void) { httpd_config_t config = HTTPD_DEFAULT_CONFIG(); // Start the httpd server @@ -184,69 +182,61 @@ httpd_handle_t start_webserver(void) return NULL; } -void stop_webserver(httpd_handle_t server) +static void stop_webserver(httpd_handle_t server) { // Stop the httpd server httpd_stop(server); } -static esp_err_t event_handler(void *ctx, system_event_t *event) + +static void disconnect_handler(void* arg, esp_event_base_t event_base, + int32_t event_id, void* event_data) { - httpd_handle_t *server = (httpd_handle_t *) ctx; - - switch(event->event_id) { - case SYSTEM_EVENT_STA_START: - ESP_LOGI(TAG, "SYSTEM_EVENT_STA_START"); - ESP_ERROR_CHECK(esp_wifi_connect()); - break; - case SYSTEM_EVENT_STA_GOT_IP: - ESP_LOGI(TAG, "SYSTEM_EVENT_STA_GOT_IP"); - ESP_LOGI(TAG, "Got IP: '%s'", - ip4addr_ntoa(&event->event_info.got_ip.ip_info.ip)); - - /* Start the web server */ - if (*server == NULL) { - *server = start_webserver(); - } - break; - case SYSTEM_EVENT_STA_DISCONNECTED: - ESP_LOGI(TAG, "SYSTEM_EVENT_STA_DISCONNECTED"); - ESP_ERROR_CHECK(esp_wifi_connect()); - - /* Stop the webserver */ - if (*server) { - stop_webserver(*server); - *server = NULL; - } - break; - default: - break; + httpd_handle_t* server = (httpd_handle_t*) arg; + if (*server) { + ESP_LOGI(TAG, "Stopping webserver"); + stop_webserver(*server); + *server = NULL; } - return ESP_OK; } -static void initialise_wifi(void *arg) +static void connect_handler(void* arg, esp_event_base_t event_base, + int32_t event_id, void* event_data) { - tcpip_adapter_init(); - ESP_ERROR_CHECK(esp_event_loop_init(event_handler, arg)); - wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); - ESP_ERROR_CHECK(esp_wifi_init(&cfg)); - ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_RAM)); - wifi_config_t wifi_config = { - .sta = { - .ssid = EXAMPLE_WIFI_SSID, - .password = EXAMPLE_WIFI_PASS, - }, - }; - ESP_LOGI(TAG, "Setting WiFi configuration SSID %s...", wifi_config.sta.ssid); - ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA)); - ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config)); - ESP_ERROR_CHECK(esp_wifi_start()); + httpd_handle_t* server = (httpd_handle_t*) arg; + if (*server == NULL) { + ESP_LOGI(TAG, "Starting webserver"); + *server = start_webserver(); + } } + void app_main() { static httpd_handle_t server = NULL; + ESP_ERROR_CHECK(nvs_flash_init()); - initialise_wifi(&server); + tcpip_adapter_init(); + ESP_ERROR_CHECK(esp_event_loop_create_default()); + + /* This helper function configures Wi-Fi or Ethernet, as selected in menuconfig. + * Read "Establishing Wi-Fi or Ethernet Connection" section in + * examples/protocols/README.md for more information about this function. + */ + ESP_ERROR_CHECK(example_connect()); + + /* Register event handlers to stop the server when Wi-Fi or Ethernet is disconnected, + * and re-start it upon connection. + */ +#ifdef CONFIG_EXAMPLE_CONNECT_WIFI + ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &connect_handler, &server)); + ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_STA_DISCONNECTED, &disconnect_handler, &server)); +#endif // CONFIG_EXAMPLE_CONNECT_WIFI +#ifdef CONFIG_EXAMPLE_CONNECT_ETHERNET + ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_ETH_GOT_IP, &connect_handler, &server)); + ESP_ERROR_CHECK(esp_event_handler_register(ETH_EVENT, ETHERNET_EVENT_DISCONNECTED, &disconnect_handler, &server)); +#endif // CONFIG_EXAMPLE_CONNECT_ETHERNET + + /* Start the server for the first time */ + server = start_webserver(); } diff --git a/examples/protocols/http_server/simple/CMakeLists.txt b/examples/protocols/http_server/simple/CMakeLists.txt index cc9d4fd833..db2ef2fa67 100644 --- a/examples/protocols/http_server/simple/CMakeLists.txt +++ b/examples/protocols/http_server/simple/CMakeLists.txt @@ -2,5 +2,9 @@ # in this exact order for cmake to work correctly cmake_minimum_required(VERSION 3.5) +# (Not part of the boilerplate) +# This example uses an extra component for common functions such as Wi-Fi and Ethernet connection. +set(EXTRA_COMPONENT_DIRS $ENV{IDF_PATH}/examples/common_components/protocol_examples_common) + include($ENV{IDF_PATH}/tools/cmake/project.cmake) project(simple) diff --git a/examples/protocols/http_server/simple/Makefile b/examples/protocols/http_server/simple/Makefile index 48f628a6b1..85660a2078 100644 --- a/examples/protocols/http_server/simple/Makefile +++ b/examples/protocols/http_server/simple/Makefile @@ -5,5 +5,7 @@ PROJECT_NAME := simple +EXTRA_COMPONENT_DIRS = $(IDF_PATH)/examples/common_components/protocol_examples_common + include $(IDF_PATH)/make/project.mk diff --git a/examples/protocols/http_server/simple/README.md b/examples/protocols/http_server/simple/README.md index b9af67ec09..969c038363 100644 --- a/examples/protocols/http_server/simple/README.md +++ b/examples/protocols/http_server/simple/README.md @@ -4,10 +4,7 @@ The Example consists of HTTPD server demo with demostration of URI handling : 1. URI \hello for GET command returns "Hello World!" message 2. URI \echo for POST command echoes back the POSTed message -* Configure the project using "make menuconfig" and goto : - * Example Configuration -> - 1. WIFI SSID: WIFI network to which your PC is also connected to. - 2. WIFI Password: WIFI password +* Run `make menuconfig` (or `idf.py menuconfig` if using CMake build system) to configure Wi-Fi or Ethernet. See "Establishing Wi-Fi or Ethernet Connection" section in [examples/protocols/README.md](../../README.md) for more details. * In order to test the HTTPD server persistent sockets demo : 1. compile and burn the firmware "make flash" diff --git a/examples/protocols/http_server/simple/http_server_simple_test.py b/examples/protocols/http_server/simple/http_server_simple_test.py index 38d8c319e0..4cd344db83 100644 --- a/examples/protocols/http_server/simple/http_server_simple_test.py +++ b/examples/protocols/http_server/simple/http_server_simple_test.py @@ -63,7 +63,7 @@ def test_examples_protocol_http_server_simple(env, extra_data): # Parse IP address of STA Utility.console_log("Waiting to connect with AP") - got_ip = dut1.expect(re.compile(r"(?:[\s\S]*)Got IP: '(\d+.\d+.\d+.\d+)'"), timeout=120)[0] + got_ip = dut1.expect(re.compile(r"(?:[\s\S]*)IPv4 address: (\d+.\d+.\d+.\d+)"), timeout=30)[0] got_port = dut1.expect(re.compile(r"(?:[\s\S]*)Starting server on port: '(\d+)'"), timeout=30)[0] Utility.console_log("Got IP : " + got_ip) diff --git a/examples/protocols/http_server/simple/main/Kconfig.projbuild b/examples/protocols/http_server/simple/main/Kconfig.projbuild deleted file mode 100644 index c27669664d..0000000000 --- a/examples/protocols/http_server/simple/main/Kconfig.projbuild +++ /dev/null @@ -1,16 +0,0 @@ -menu "Example Configuration" - - config WIFI_SSID - string "WiFi SSID" - default "myssid" - help - SSID (network name) for the example to connect to. - - config WIFI_PASSWORD - string "WiFi Password" - default "mypassword" - help - WiFi password (WPA or WPA2) for the example to use. - Can be left blank if the network has no security set. - -endmenu diff --git a/examples/protocols/http_server/simple/main/main.c b/examples/protocols/http_server/simple/main/main.c index 9ada49cabc..270c939410 100644 --- a/examples/protocols/http_server/simple/main/main.c +++ b/examples/protocols/http_server/simple/main/main.c @@ -8,29 +8,26 @@ */ #include -#include +#include #include #include #include #include +#include "nvs_flash.h" +#include "tcpip_adapter.h" +#include "esp_eth.h" +#include "protocol_examples_common.h" #include /* A simple example that demonstrates how to create GET and POST * handlers for the web server. - * The examples use simple WiFi configuration that you can set via - * 'make menuconfig'. - * If you'd rather not, just change the below entries to strings - * with the config you want - - * ie. #define EXAMPLE_WIFI_SSID "mywifissid" -*/ -#define EXAMPLE_WIFI_SSID CONFIG_WIFI_SSID -#define EXAMPLE_WIFI_PASS CONFIG_WIFI_PASSWORD + */ -static const char *TAG="APP"; +static const char *TAG = "example"; /* An HTTP GET handler */ -esp_err_t hello_get_handler(httpd_req_t *req) +static esp_err_t hello_get_handler(httpd_req_t *req) { char* buf; size_t buf_len; @@ -104,7 +101,7 @@ esp_err_t hello_get_handler(httpd_req_t *req) return ESP_OK; } -httpd_uri_t hello = { +static const httpd_uri_t hello = { .uri = "/hello", .method = HTTP_GET, .handler = hello_get_handler, @@ -114,7 +111,7 @@ httpd_uri_t hello = { }; /* An HTTP POST handler */ -esp_err_t echo_post_handler(httpd_req_t *req) +static esp_err_t echo_post_handler(httpd_req_t *req) { char buf[100]; int ret, remaining = req->content_len; @@ -145,7 +142,7 @@ esp_err_t echo_post_handler(httpd_req_t *req) return ESP_OK; } -httpd_uri_t echo = { +static const httpd_uri_t echo = { .uri = "/echo", .method = HTTP_POST, .handler = echo_post_handler, @@ -182,7 +179,7 @@ esp_err_t http_404_error_handler(httpd_req_t *req, httpd_err_code_t err) /* An HTTP PUT handler. This demonstrates realtime * registration and deregistration of URI handlers */ -esp_err_t ctrl_put_handler(httpd_req_t *req) +static esp_err_t ctrl_put_handler(httpd_req_t *req) { char buf; int ret; @@ -215,14 +212,14 @@ esp_err_t ctrl_put_handler(httpd_req_t *req) return ESP_OK; } -httpd_uri_t ctrl = { +static const httpd_uri_t ctrl = { .uri = "/ctrl", .method = HTTP_PUT, .handler = ctrl_put_handler, .user_ctx = NULL }; -httpd_handle_t start_webserver(void) +static httpd_handle_t start_webserver(void) { httpd_handle_t server = NULL; httpd_config_t config = HTTPD_DEFAULT_CONFIG(); @@ -242,69 +239,60 @@ httpd_handle_t start_webserver(void) return NULL; } -void stop_webserver(httpd_handle_t server) +static void stop_webserver(httpd_handle_t server) { // Stop the httpd server httpd_stop(server); } -static esp_err_t event_handler(void *ctx, system_event_t *event) +static void disconnect_handler(void* arg, esp_event_base_t event_base, + int32_t event_id, void* event_data) { - httpd_handle_t *server = (httpd_handle_t *) ctx; - - switch(event->event_id) { - case SYSTEM_EVENT_STA_START: - ESP_LOGI(TAG, "SYSTEM_EVENT_STA_START"); - ESP_ERROR_CHECK(esp_wifi_connect()); - break; - case SYSTEM_EVENT_STA_GOT_IP: - ESP_LOGI(TAG, "SYSTEM_EVENT_STA_GOT_IP"); - ESP_LOGI(TAG, "Got IP: '%s'", - ip4addr_ntoa(&event->event_info.got_ip.ip_info.ip)); - - /* Start the web server */ - if (*server == NULL) { - *server = start_webserver(); - } - break; - case SYSTEM_EVENT_STA_DISCONNECTED: - ESP_LOGI(TAG, "SYSTEM_EVENT_STA_DISCONNECTED"); - ESP_ERROR_CHECK(esp_wifi_connect()); - - /* Stop the web server */ - if (*server) { - stop_webserver(*server); - *server = NULL; - } - break; - default: - break; + httpd_handle_t* server = (httpd_handle_t*) arg; + if (*server) { + ESP_LOGI(TAG, "Stopping webserver"); + stop_webserver(*server); + *server = NULL; } - return ESP_OK; } -static void initialise_wifi(void *arg) +static void connect_handler(void* arg, esp_event_base_t event_base, + int32_t event_id, void* event_data) { - tcpip_adapter_init(); - ESP_ERROR_CHECK(esp_event_loop_init(event_handler, arg)); - wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); - ESP_ERROR_CHECK(esp_wifi_init(&cfg)); - ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_RAM)); - wifi_config_t wifi_config = { - .sta = { - .ssid = EXAMPLE_WIFI_SSID, - .password = EXAMPLE_WIFI_PASS, - }, - }; - ESP_LOGI(TAG, "Setting WiFi configuration SSID %s...", wifi_config.sta.ssid); - ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA)); - ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config)); - ESP_ERROR_CHECK(esp_wifi_start()); + httpd_handle_t* server = (httpd_handle_t*) arg; + if (*server == NULL) { + ESP_LOGI(TAG, "Starting webserver"); + *server = start_webserver(); + } } + void app_main() { static httpd_handle_t server = NULL; + ESP_ERROR_CHECK(nvs_flash_init()); - initialise_wifi(&server); + tcpip_adapter_init(); + ESP_ERROR_CHECK(esp_event_loop_create_default()); + + /* This helper function configures Wi-Fi or Ethernet, as selected in menuconfig. + * Read "Establishing Wi-Fi or Ethernet Connection" section in + * examples/protocols/README.md for more information about this function. + */ + ESP_ERROR_CHECK(example_connect()); + + /* Register event handlers to stop the server when Wi-Fi or Ethernet is disconnected, + * and re-start it upon connection. + */ +#ifdef CONFIG_EXAMPLE_CONNECT_WIFI + ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &connect_handler, &server)); + ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_STA_DISCONNECTED, &disconnect_handler, &server)); +#endif // CONFIG_EXAMPLE_CONNECT_WIFI +#ifdef CONFIG_EXAMPLE_CONNECT_ETHERNET + ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_ETH_GOT_IP, &connect_handler, &server)); + ESP_ERROR_CHECK(esp_event_handler_register(ETH_EVENT, ETHERNET_EVENT_DISCONNECTED, &disconnect_handler, &server)); +#endif // CONFIG_EXAMPLE_CONNECT_ETHERNET + + /* Start the server for the first time */ + server = start_webserver(); } diff --git a/examples/protocols/https_mbedtls/CMakeLists.txt b/examples/protocols/https_mbedtls/CMakeLists.txt index a1f41ff875..a053cbaf04 100644 --- a/examples/protocols/https_mbedtls/CMakeLists.txt +++ b/examples/protocols/https_mbedtls/CMakeLists.txt @@ -2,5 +2,9 @@ # CMakeLists in this exact order for cmake to work correctly cmake_minimum_required(VERSION 3.5) +# (Not part of the boilerplate) +# This example uses an extra component for common functions such as Wi-Fi and Ethernet connection. +set(EXTRA_COMPONENT_DIRS $ENV{IDF_PATH}/examples/common_components/protocol_examples_common) + include($ENV{IDF_PATH}/tools/cmake/project.cmake) -project(https-mbedtls) \ No newline at end of file +project(https-mbedtls) diff --git a/examples/protocols/https_mbedtls/Makefile b/examples/protocols/https_mbedtls/Makefile index 070f89048b..bb1cf2f18e 100644 --- a/examples/protocols/https_mbedtls/Makefile +++ b/examples/protocols/https_mbedtls/Makefile @@ -5,5 +5,7 @@ PROJECT_NAME := https-mbedtls +EXTRA_COMPONENT_DIRS = $(IDF_PATH)/examples/common_components/protocol_examples_common + include $(IDF_PATH)/make/project.mk diff --git a/examples/protocols/https_mbedtls/main/Kconfig.projbuild b/examples/protocols/https_mbedtls/main/Kconfig.projbuild deleted file mode 100644 index 803ab080a8..0000000000 --- a/examples/protocols/https_mbedtls/main/Kconfig.projbuild +++ /dev/null @@ -1,17 +0,0 @@ -menu "Example Configuration" - - config WIFI_SSID - string "WiFi SSID" - default "myssid" - help - SSID (network name) for the example to connect to. - - config WIFI_PASSWORD - string "WiFi Password" - default "mypassword" - help - WiFi password (WPA or WPA2) for the example to use. - - Can be left blank if the network has no security set. - -endmenu diff --git a/examples/protocols/https_mbedtls/main/https_mbedtls_example_main.c b/examples/protocols/https_mbedtls/main/https_mbedtls_example_main.c index 93aaba74fa..fe2c0bf8b3 100644 --- a/examples/protocols/https_mbedtls/main/https_mbedtls_example_main.c +++ b/examples/protocols/https_mbedtls/main/https_mbedtls_example_main.c @@ -25,12 +25,13 @@ #include #include "freertos/FreeRTOS.h" #include "freertos/task.h" -#include "freertos/event_groups.h" #include "esp_wifi.h" -#include "esp_event_loop.h" +#include "esp_event.h" #include "esp_log.h" #include "esp_system.h" #include "nvs_flash.h" +#include "protocol_examples_common.h" +#include "tcpip_adapter.h" #include "lwip/err.h" #include "lwip/sockets.h" @@ -47,22 +48,6 @@ #include "mbedtls/error.h" #include "mbedtls/certs.h" -/* The examples use simple WiFi configuration that you can set via - 'make menuconfig'. - - If you'd rather not, just change the below entries to strings with - the config you want - ie #define EXAMPLE_WIFI_SSID "mywifissid" -*/ -#define EXAMPLE_WIFI_SSID CONFIG_WIFI_SSID -#define EXAMPLE_WIFI_PASS CONFIG_WIFI_PASSWORD - -/* FreeRTOS event group to signal when we are connected & ready to make a request */ -static EventGroupHandle_t wifi_event_group; - -/* The event group allows multiple bits for each event, - but we only care about one event - are we connected - to the AP with an IP? */ -const int CONNECTED_BIT = BIT0; /* Constants that aren't configurable in menuconfig */ #define WEB_SERVER "www.howsmyssl.com" @@ -89,46 +74,6 @@ static const char *REQUEST = "GET " WEB_URL " HTTP/1.0\r\n" extern const uint8_t server_root_cert_pem_start[] asm("_binary_server_root_cert_pem_start"); extern const uint8_t server_root_cert_pem_end[] asm("_binary_server_root_cert_pem_end"); -static esp_err_t event_handler(void *ctx, system_event_t *event) -{ - switch(event->event_id) { - case SYSTEM_EVENT_STA_START: - esp_wifi_connect(); - break; - case SYSTEM_EVENT_STA_GOT_IP: - xEventGroupSetBits(wifi_event_group, CONNECTED_BIT); - break; - case SYSTEM_EVENT_STA_DISCONNECTED: - /* This is a workaround as ESP32 WiFi libs don't currently - auto-reassociate. */ - esp_wifi_connect(); - xEventGroupClearBits(wifi_event_group, CONNECTED_BIT); - break; - default: - break; - } - return ESP_OK; -} - -static void initialise_wifi(void) -{ - tcpip_adapter_init(); - wifi_event_group = xEventGroupCreate(); - ESP_ERROR_CHECK( esp_event_loop_init(event_handler, NULL) ); - wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); - ESP_ERROR_CHECK( esp_wifi_init(&cfg) ); - ESP_ERROR_CHECK( esp_wifi_set_storage(WIFI_STORAGE_RAM) ); - wifi_config_t wifi_config = { - .sta = { - .ssid = EXAMPLE_WIFI_SSID, - .password = EXAMPLE_WIFI_PASS, - }, - }; - ESP_LOGI(TAG, "Setting WiFi configuration SSID %s...", wifi_config.sta.ssid); - ESP_ERROR_CHECK( esp_wifi_set_mode(WIFI_MODE_STA) ); - ESP_ERROR_CHECK( esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config) ); - ESP_ERROR_CHECK( esp_wifi_start() ); -} static void https_get_task(void *pvParameters) { @@ -207,13 +152,6 @@ static void https_get_task(void *pvParameters) } while(1) { - /* Wait for the callback to set the CONNECTED_BIT in the - event group. - */ - xEventGroupWaitBits(wifi_event_group, CONNECTED_BIT, - false, true, portMAX_DELAY); - ESP_LOGI(TAG, "Connected to AP"); - mbedtls_net_init(&server_fd); ESP_LOGI(TAG, "Connecting to %s:%s...", WEB_SERVER, WEB_PORT); @@ -336,6 +274,14 @@ static void https_get_task(void *pvParameters) void app_main() { ESP_ERROR_CHECK( nvs_flash_init() ); - initialise_wifi(); + tcpip_adapter_init(); + ESP_ERROR_CHECK(esp_event_loop_create_default()); + + /* This helper function configures Wi-Fi or Ethernet, as selected in menuconfig. + * Read "Establishing Wi-Fi or Ethernet Connection" section in + * examples/protocols/README.md for more information about this function. + */ + ESP_ERROR_CHECK(example_connect()); + xTaskCreate(&https_get_task, "https_get_task", 8192, NULL, 5, NULL); } diff --git a/examples/protocols/https_request/CMakeLists.txt b/examples/protocols/https_request/CMakeLists.txt index f77bc66101..6e3f1265b9 100644 --- a/examples/protocols/https_request/CMakeLists.txt +++ b/examples/protocols/https_request/CMakeLists.txt @@ -2,5 +2,9 @@ # CMakeLists in this exact order for cmake to work correctly cmake_minimum_required(VERSION 3.5) +# (Not part of the boilerplate) +# This example uses an extra component for common functions such as Wi-Fi and Ethernet connection. +set(EXTRA_COMPONENT_DIRS $ENV{IDF_PATH}/examples/common_components/protocol_examples_common) + include($ENV{IDF_PATH}/tools/cmake/project.cmake) project(https_request) diff --git a/examples/protocols/https_request/Makefile b/examples/protocols/https_request/Makefile index 55c5f943f1..f81163b00d 100644 --- a/examples/protocols/https_request/Makefile +++ b/examples/protocols/https_request/Makefile @@ -5,5 +5,7 @@ PROJECT_NAME := https_request +EXTRA_COMPONENT_DIRS = $(IDF_PATH)/examples/common_components/protocol_examples_common + include $(IDF_PATH)/make/project.mk diff --git a/examples/protocols/https_request/main/Kconfig.projbuild b/examples/protocols/https_request/main/Kconfig.projbuild deleted file mode 100644 index 803ab080a8..0000000000 --- a/examples/protocols/https_request/main/Kconfig.projbuild +++ /dev/null @@ -1,17 +0,0 @@ -menu "Example Configuration" - - config WIFI_SSID - string "WiFi SSID" - default "myssid" - help - SSID (network name) for the example to connect to. - - config WIFI_PASSWORD - string "WiFi Password" - default "mypassword" - help - WiFi password (WPA or WPA2) for the example to use. - - Can be left blank if the network has no security set. - -endmenu diff --git a/examples/protocols/https_request/main/https_request_example_main.c b/examples/protocols/https_request/main/https_request_example_main.c index 3964b4ea52..742a4657e1 100644 --- a/examples/protocols/https_request/main/https_request_example_main.c +++ b/examples/protocols/https_request/main/https_request_example_main.c @@ -27,10 +27,12 @@ #include "freertos/task.h" #include "freertos/event_groups.h" #include "esp_wifi.h" -#include "esp_event_loop.h" +#include "esp_event.h" #include "esp_log.h" #include "esp_system.h" #include "nvs_flash.h" +#include "protocol_examples_common.h" +#include "tcpip_adapter.h" #include "lwip/err.h" #include "lwip/sockets.h" @@ -40,23 +42,6 @@ #include "esp_tls.h" -/* The examples use simple WiFi configuration that you can set via - 'make menuconfig'. - - If you'd rather not, just change the below entries to strings with - the config you want - ie #define EXAMPLE_WIFI_SSID "mywifissid" -*/ -#define EXAMPLE_WIFI_SSID CONFIG_WIFI_SSID -#define EXAMPLE_WIFI_PASS CONFIG_WIFI_PASSWORD - -/* FreeRTOS event group to signal when we are connected & ready to make a request */ -static EventGroupHandle_t wifi_event_group; - -/* The event group allows multiple bits for each event, - but we only care about one event - are we connected - to the AP with an IP? */ -const int CONNECTED_BIT = BIT0; - /* Constants that aren't configurable in menuconfig */ #define WEB_SERVER "www.howsmyssl.com" #define WEB_PORT "443" @@ -81,47 +66,7 @@ static const char *REQUEST = "GET " WEB_URL " HTTP/1.0\r\n" */ extern const uint8_t server_root_cert_pem_start[] asm("_binary_server_root_cert_pem_start"); extern const uint8_t server_root_cert_pem_end[] asm("_binary_server_root_cert_pem_end"); - -static esp_err_t event_handler(void *ctx, system_event_t *event) -{ - switch(event->event_id) { - case SYSTEM_EVENT_STA_START: - esp_wifi_connect(); - break; - case SYSTEM_EVENT_STA_GOT_IP: - xEventGroupSetBits(wifi_event_group, CONNECTED_BIT); - break; - case SYSTEM_EVENT_STA_DISCONNECTED: - /* This is a workaround as ESP32 WiFi libs don't currently - auto-reassociate. */ - esp_wifi_connect(); - xEventGroupClearBits(wifi_event_group, CONNECTED_BIT); - break; - default: - break; - } - return ESP_OK; -} -static void initialise_wifi(void) -{ - tcpip_adapter_init(); - wifi_event_group = xEventGroupCreate(); - ESP_ERROR_CHECK( esp_event_loop_init(event_handler, NULL) ); - wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); - ESP_ERROR_CHECK( esp_wifi_init(&cfg) ); - ESP_ERROR_CHECK( esp_wifi_set_storage(WIFI_STORAGE_RAM) ); - wifi_config_t wifi_config = { - .sta = { - .ssid = EXAMPLE_WIFI_SSID, - .password = EXAMPLE_WIFI_PASS, - }, - }; - ESP_LOGI(TAG, "Setting WiFi configuration SSID %s...", wifi_config.sta.ssid); - ESP_ERROR_CHECK( esp_wifi_set_mode(WIFI_MODE_STA) ); - ESP_ERROR_CHECK( esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config) ); - ESP_ERROR_CHECK( esp_wifi_start() ); -} static void https_get_task(void *pvParameters) { @@ -129,12 +74,6 @@ static void https_get_task(void *pvParameters) int ret, len; while(1) { - /* Wait for the callback to set the CONNECTED_BIT in the - event group. - */ - xEventGroupWaitBits(wifi_event_group, CONNECTED_BIT, - false, true, portMAX_DELAY); - ESP_LOGI(TAG, "Connected to AP"); esp_tls_cfg_t cfg = { .cacert_pem_buf = server_root_cert_pem_start, .cacert_pem_bytes = server_root_cert_pem_end - server_root_cert_pem_start, @@ -212,6 +151,14 @@ static void https_get_task(void *pvParameters) void app_main() { ESP_ERROR_CHECK( nvs_flash_init() ); - initialise_wifi(); + tcpip_adapter_init(); + ESP_ERROR_CHECK(esp_event_loop_create_default()); + + /* This helper function configures Wi-Fi or Ethernet, as selected in menuconfig. + * Read "Establishing Wi-Fi or Ethernet Connection" section in + * examples/protocols/README.md for more information about this function. + */ + ESP_ERROR_CHECK(example_connect()); + xTaskCreate(&https_get_task, "https_get_task", 8192, NULL, 5, NULL); } diff --git a/examples/protocols/https_server/CMakeLists.txt b/examples/protocols/https_server/CMakeLists.txt index 7f58e025f3..35fe8ca898 100644 --- a/examples/protocols/https_server/CMakeLists.txt +++ b/examples/protocols/https_server/CMakeLists.txt @@ -2,5 +2,9 @@ # in this exact order for cmake to work correctly cmake_minimum_required(VERSION 3.5) +# (Not part of the boilerplate) +# This example uses an extra component for common functions such as Wi-Fi and Ethernet connection. +set(EXTRA_COMPONENT_DIRS $ENV{IDF_PATH}/examples/common_components/protocol_examples_common) + include($ENV{IDF_PATH}/tools/cmake/project.cmake) project(https_server) diff --git a/examples/protocols/https_server/Makefile b/examples/protocols/https_server/Makefile index 5a20b6f57e..6747d5ff3d 100644 --- a/examples/protocols/https_server/Makefile +++ b/examples/protocols/https_server/Makefile @@ -5,5 +5,7 @@ PROJECT_NAME := https_server +EXTRA_COMPONENT_DIRS = $(IDF_PATH)/examples/common_components/protocol_examples_common + include $(IDF_PATH)/make/project.mk diff --git a/examples/protocols/https_server/README.md b/examples/protocols/https_server/README.md index 08aa770c08..be0ed0d587 100644 --- a/examples/protocols/https_server/README.md +++ b/examples/protocols/https_server/README.md @@ -4,6 +4,8 @@ This example creates a SSL server that returns a simple HTML page when you visit See the `esp_https_server` component documentation for details. +Before using the example, run `make menuconfig` (or `idf.py menuconfig` if using CMake build system) to configure Wi-Fi or Ethernet. See "Establishing Wi-Fi or Ethernet Connection" section in [examples/protocols/README.md](../README.md) for more details. + ## Certificates You will need to approve a security exception in your browser. This is because of a self signed diff --git a/examples/protocols/https_server/main/Kconfig.projbuild b/examples/protocols/https_server/main/Kconfig.projbuild deleted file mode 100644 index c27669664d..0000000000 --- a/examples/protocols/https_server/main/Kconfig.projbuild +++ /dev/null @@ -1,16 +0,0 @@ -menu "Example Configuration" - - config WIFI_SSID - string "WiFi SSID" - default "myssid" - help - SSID (network name) for the example to connect to. - - config WIFI_PASSWORD - string "WiFi Password" - default "mypassword" - help - WiFi password (WPA or WPA2) for the example to use. - Can be left blank if the network has no security set. - -endmenu diff --git a/examples/protocols/https_server/main/main.c b/examples/protocols/https_server/main/main.c index d46897f1bd..7cebabfb96 100644 --- a/examples/protocols/https_server/main/main.c +++ b/examples/protocols/https_server/main/main.c @@ -13,25 +13,21 @@ #include #include #include +#include "tcpip_adapter.h" +#include "esp_eth.h" +#include "protocol_examples_common.h" #include /* A simple example that demonstrates how to create GET and POST - * handlers for the web server. - * The examples use simple WiFi configuration that you can set via - * 'make menuconfig'. - * If you'd rather not, just change the below entries to strings - * with the config you want - - * ie. #define EXAMPLE_WIFI_SSID "mywifissid" + * handlers and start an HTTPS server. */ -#define EXAMPLE_WIFI_SSID CONFIG_WIFI_SSID -#define EXAMPLE_WIFI_PASS CONFIG_WIFI_PASSWORD -static const char *TAG="APP"; +static const char *TAG = "example"; /* An HTTP GET handler */ -esp_err_t root_get_handler(httpd_req_t *req) +static esp_err_t root_get_handler(httpd_req_t *req) { httpd_resp_set_type(req, "text/html"); httpd_resp_send(req, "

Hello Secure World!

", -1); // -1 = use strlen() @@ -39,14 +35,14 @@ esp_err_t root_get_handler(httpd_req_t *req) return ESP_OK; } -const httpd_uri_t root = { +static const httpd_uri_t root = { .uri = "/", .method = HTTP_GET, .handler = root_get_handler }; -httpd_handle_t start_webserver(void) +static httpd_handle_t start_webserver(void) { httpd_handle_t server = NULL; @@ -77,74 +73,55 @@ httpd_handle_t start_webserver(void) return server; } -void stop_webserver(httpd_handle_t server) +static void stop_webserver(httpd_handle_t server) { // Stop the httpd server httpd_ssl_stop(server); } - - - -// ------------------------- application boilerplate ------------------------ - -static esp_err_t event_handler(void *ctx, system_event_t *event) +static void disconnect_handler(void* arg, esp_event_base_t event_base, + int32_t event_id, void* event_data) { - httpd_handle_t *server = (httpd_handle_t *) ctx; - - switch(event->event_id) { - case SYSTEM_EVENT_STA_START: - ESP_LOGI(TAG, "SYSTEM_EVENT_STA_START"); - ESP_ERROR_CHECK(esp_wifi_connect()); - break; - case SYSTEM_EVENT_STA_GOT_IP: - ESP_LOGI(TAG, "SYSTEM_EVENT_STA_GOT_IP"); - ESP_LOGI(TAG, "Got IP: '%s'", - ip4addr_ntoa(&event->event_info.got_ip.ip_info.ip)); - - /* Start the web server */ - if (*server == NULL) { - *server = start_webserver(); - } - break; - case SYSTEM_EVENT_STA_DISCONNECTED: - ESP_LOGI(TAG, "SYSTEM_EVENT_STA_DISCONNECTED"); - ESP_ERROR_CHECK(esp_wifi_connect()); - - /* Stop the web server */ - if (*server) { - stop_webserver(*server); - *server = NULL; - } - break; - default: - break; + httpd_handle_t* server = (httpd_handle_t*) arg; + if (*server) { + stop_webserver(*server); + *server = NULL; } - return ESP_OK; } -static void initialise_wifi(void *arg) +static void connect_handler(void* arg, esp_event_base_t event_base, + int32_t event_id, void* event_data) { - tcpip_adapter_init(); - ESP_ERROR_CHECK(esp_event_loop_init(event_handler, arg)); - wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); - ESP_ERROR_CHECK(esp_wifi_init(&cfg)); - ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_RAM)); - wifi_config_t wifi_config = { - .sta = { - .ssid = EXAMPLE_WIFI_SSID, - .password = EXAMPLE_WIFI_PASS, - }, - }; - ESP_LOGI(TAG, "Setting WiFi configuration SSID %s...", wifi_config.sta.ssid); - ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA)); - ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config)); - ESP_ERROR_CHECK(esp_wifi_start()); + httpd_handle_t* server = (httpd_handle_t*) arg; + if (*server == NULL) { + *server = start_webserver(); + } } void app_main() { static httpd_handle_t server = NULL; + ESP_ERROR_CHECK(nvs_flash_init()); - initialise_wifi(&server); + tcpip_adapter_init(); + ESP_ERROR_CHECK(esp_event_loop_create_default()); + + /* Register event handlers to start server when Wi-Fi or Ethernet is connected, + * and stop server when disconnection happens. + */ + +#ifdef CONFIG_EXAMPLE_CONNECT_WIFI + ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &connect_handler, &server)); + ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_STA_DISCONNECTED, &disconnect_handler, &server)); +#endif // CONFIG_EXAMPLE_CONNECT_WIFI +#ifdef CONFIG_EXAMPLE_CONNECT_ETHERNET + ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_ETH_GOT_IP, &connect_handler, &server)); + ESP_ERROR_CHECK(esp_event_handler_register(ETH_EVENT, ETHERNET_EVENT_DISCONNECTED, &disconnect_handler, &server)); +#endif // CONFIG_EXAMPLE_CONNECT_ETHERNET + + /* This helper function configures Wi-Fi or Ethernet, as selected in menuconfig. + * Read "Establishing Wi-Fi or Ethernet Connection" section in + * examples/protocols/README.md for more information about this function. + */ + ESP_ERROR_CHECK(example_connect()); } diff --git a/examples/protocols/mdns/CMakeLists.txt b/examples/protocols/mdns/CMakeLists.txt index 88b7c1e3f1..ddd7263c5c 100644 --- a/examples/protocols/mdns/CMakeLists.txt +++ b/examples/protocols/mdns/CMakeLists.txt @@ -2,5 +2,9 @@ # in this exact order for cmake to work correctly cmake_minimum_required(VERSION 3.5) +# (Not part of the boilerplate) +# This example uses an extra component for common functions such as Wi-Fi and Ethernet connection. +set(EXTRA_COMPONENT_DIRS $ENV{IDF_PATH}/examples/common_components/protocol_examples_common) + include($ENV{IDF_PATH}/tools/cmake/project.cmake) project(mdns-test) diff --git a/examples/protocols/mdns/Makefile b/examples/protocols/mdns/Makefile index 0353c51c0e..91a417c7cc 100644 --- a/examples/protocols/mdns/Makefile +++ b/examples/protocols/mdns/Makefile @@ -5,5 +5,7 @@ PROJECT_NAME := mdns-test +EXTRA_COMPONENT_DIRS = $(IDF_PATH)/examples/common_components/protocol_examples_common + include $(IDF_PATH)/make/project.mk diff --git a/examples/protocols/mdns/README.md b/examples/protocols/mdns/README.md index d787099afd..182434e58c 100644 --- a/examples/protocols/mdns/README.md +++ b/examples/protocols/mdns/README.md @@ -12,12 +12,10 @@ Shows how to use mDNS to advertise lookup services and hosts ### Configure the project -``` -make menuconfig -``` +* Run `make menuconfig` (or `idf.py menuconfig` if using CMake build system) -* Set `Default serial port` under `Serial flasher config`. -* Set `WiFi SSID` and `WiFi Password` for the board to connect to AP. +* Configure Wi-Fi or Ethernet under "Example Connection Configuration" menu. See "Establishing Wi-Fi or Ethernet Connection" section in [examples/protocols/README.md](../README.md) for more details. +* When using Make build system, set `Default serial port` under `Serial flasher config`. * Set `mDNS Hostname` as host name prefix for the device and its instance name in `mDNS Instance Name` * Disable `Resolve test services` to prevent the example from querying defined names/services on startup (cause warnings in example logs, as illustrated below) @@ -28,6 +26,7 @@ Build the project and flash it to the board, then run monitor tool to view seria ``` make -j4 flash monitor ``` + - Wait for WiFi to connect to your access point - You can now ping the device at `[board-hostname].local`, where `[board-hostname]` is preconfigured hostname, `esp32-mdns` by default. - You can also browse for `_http._tcp` on the same network to find the advertised service diff --git a/examples/protocols/mdns/main/Kconfig.projbuild b/examples/protocols/mdns/main/Kconfig.projbuild index 7316960601..7e7b22640c 100644 --- a/examples/protocols/mdns/main/Kconfig.projbuild +++ b/examples/protocols/mdns/main/Kconfig.projbuild @@ -1,19 +1,5 @@ menu "Example Configuration" - config WIFI_SSID - string "WiFi SSID" - default "myssid" - help - SSID (network name) for the example to connect to. - - config WIFI_PASSWORD - string "WiFi Password" - default "mypassword" - help - WiFi password (WPA or WPA2) for the example to use. - - Can be left blank if the network has no security set. - config MDNS_HOSTNAME string "mDNS Hostname" default "esp32-mdns" diff --git a/examples/protocols/mdns/main/mdns_example_main.c b/examples/protocols/mdns/main/mdns_example_main.c index 20cdbc3b01..1158405844 100644 --- a/examples/protocols/mdns/main/mdns_example_main.c +++ b/examples/protocols/mdns/main/mdns_example_main.c @@ -12,90 +12,24 @@ #include "freertos/event_groups.h" #include "esp_system.h" #include "esp_wifi.h" -#include "esp_event_loop.h" +#include "esp_event.h" #include "esp_log.h" #include "nvs_flash.h" +#include "tcpip_adapter.h" +#include "protocol_examples_common.h" #include "mdns.h" #include "driver/gpio.h" #include #include -/* The examples use simple WiFi configuration that you can set via - 'make menuconfig'. - - If you'd rather not, just change the below entries to strings with - the config you want - ie #define EXAMPLE_WIFI_SSID "mywifissid" -*/ -#define EXAMPLE_WIFI_SSID CONFIG_WIFI_SSID -#define EXAMPLE_WIFI_PASS CONFIG_WIFI_PASSWORD #define EXAMPLE_MDNS_INSTANCE CONFIG_MDNS_INSTANCE - - -/* FreeRTOS event group to signal when we are connected & ready to make a request */ -static EventGroupHandle_t wifi_event_group; - -/* The event group allows multiple bits for each event, - but we only care about one event - are we connected - to the AP with an IP? */ -const int IP4_CONNECTED_BIT = BIT0; -const int IP6_CONNECTED_BIT = BIT1; +static const char c_config_hostname[] = CONFIG_MDNS_HOSTNAME; +#define EXAMPLE_BUTTON_GPIO 0 static const char *TAG = "mdns-test"; -static bool auto_reconnect = true; static char* generate_hostname(); -static esp_err_t event_handler(void *ctx, system_event_t *event) -{ - switch(event->event_id) { - case SYSTEM_EVENT_STA_START: - esp_wifi_connect(); - break; - case SYSTEM_EVENT_STA_CONNECTED: - /* enable ipv6 */ - tcpip_adapter_create_ip6_linklocal(TCPIP_ADAPTER_IF_STA); - break; - case SYSTEM_EVENT_STA_GOT_IP: - xEventGroupSetBits(wifi_event_group, IP4_CONNECTED_BIT); - break; - case SYSTEM_EVENT_AP_STA_GOT_IP6: - xEventGroupSetBits(wifi_event_group, IP6_CONNECTED_BIT); - break; - case SYSTEM_EVENT_STA_DISCONNECTED: - /* This is a workaround as ESP32 WiFi libs don't currently - auto-reassociate. */ - if (auto_reconnect) { - esp_wifi_connect(); - } - xEventGroupClearBits(wifi_event_group, IP4_CONNECTED_BIT | IP6_CONNECTED_BIT); - break; - default: - break; - } - mdns_handle_system_event(ctx, event); - return ESP_OK; -} - -static void initialise_wifi(void) -{ - tcpip_adapter_init(); - wifi_event_group = xEventGroupCreate(); - ESP_ERROR_CHECK( esp_event_loop_init(event_handler, NULL) ); - wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); - ESP_ERROR_CHECK( esp_wifi_init(&cfg) ); - ESP_ERROR_CHECK( esp_wifi_set_storage(WIFI_STORAGE_RAM) ); - wifi_config_t wifi_config = { - .sta = { - .ssid = EXAMPLE_WIFI_SSID, - .password = EXAMPLE_WIFI_PASS, - }, - }; - ESP_LOGI(TAG, "Setting WiFi configuration SSID %s...", wifi_config.sta.ssid); - ESP_ERROR_CHECK( esp_wifi_set_mode(WIFI_MODE_STA) ); - ESP_ERROR_CHECK( esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config) ); - ESP_ERROR_CHECK( esp_wifi_start() ); -} - static void initialise_mdns(void) { char* hostname = generate_hostname(); @@ -123,7 +57,10 @@ static void initialise_mdns(void) free(hostname); } +/* these strings match tcpip_adapter_if_t enumeration */ static const char * if_str[] = {"STA", "AP", "ETH", "MAX"}; + +/* these strings match mdns_ip_protocol_t enumeration */ static const char * ip_protocol_str[] = {"V4", "V6", "MAX"}; static void mdns_print_results(mdns_result_t * results){ @@ -200,9 +137,9 @@ static void query_mdns_host(const char * host_name) static void initialise_button(void) { - gpio_config_t io_conf; + gpio_config_t io_conf = {0}; io_conf.intr_type = GPIO_PIN_INTR_DISABLE; - io_conf.pin_bit_mask = 1; + io_conf.pin_bit_mask = BIT64(EXAMPLE_BUTTON_GPIO); io_conf.mode = GPIO_MODE_INPUT; io_conf.pull_up_en = 1; io_conf.pull_down_en = 0; @@ -212,7 +149,7 @@ static void initialise_button(void) static void check_button(void) { static bool old_level = true; - bool new_level = gpio_get_level(GPIO_NUM_0); + bool new_level = gpio_get_level(EXAMPLE_BUTTON_GPIO); if (!new_level && old_level) { query_mdns_host("esp32"); query_mdns_service("_arduino", "_tcp"); @@ -229,10 +166,6 @@ static void check_button(void) static void mdns_example_task(void *pvParameters) { - /* Wait for the callback to set the CONNECTED_BIT in the event group. */ - xEventGroupWaitBits(wifi_event_group, IP4_CONNECTED_BIT | IP6_CONNECTED_BIT, - false, true, portMAX_DELAY); - #if CONFIG_RESOLVE_TEST_SERVICES == 1 /* Send initial queries that are started by CI tester */ query_mdns_host("tinytester"); @@ -246,9 +179,18 @@ static void mdns_example_task(void *pvParameters) void app_main() { - ESP_ERROR_CHECK( nvs_flash_init() ); - initialise_wifi(); + ESP_ERROR_CHECK(nvs_flash_init()); + tcpip_adapter_init(); + ESP_ERROR_CHECK(esp_event_loop_create_default()); + initialise_mdns(); + + /* This helper function configures Wi-Fi or Ethernet, as selected in menuconfig. + * Read "Establishing Wi-Fi or Ethernet Connection" section in + * examples/protocols/README.md for more information about this function. + */ + ESP_ERROR_CHECK(example_connect()); + initialise_button(); xTaskCreate(&mdns_example_task, "mdns_example_task", 2048, NULL, 5, NULL); } diff --git a/examples/protocols/mqtt/publish_test/CMakeLists.txt b/examples/protocols/mqtt/publish_test/CMakeLists.txt index 75f161908b..2203d063f7 100644 --- a/examples/protocols/mqtt/publish_test/CMakeLists.txt +++ b/examples/protocols/mqtt/publish_test/CMakeLists.txt @@ -2,6 +2,10 @@ # in this exact order for cmake to work correctly cmake_minimum_required(VERSION 3.5) +# (Not part of the boilerplate) +# This example uses an extra component for common functions such as Wi-Fi and Ethernet connection. +set(EXTRA_COMPONENT_DIRS $ENV{IDF_PATH}/examples/common_components/protocol_examples_common) + include($ENV{IDF_PATH}/tools/cmake/project.cmake) project(mqtt_publish) diff --git a/examples/protocols/mqtt/publish_test/Makefile b/examples/protocols/mqtt/publish_test/Makefile index d1341ae904..7d552c3be2 100644 --- a/examples/protocols/mqtt/publish_test/Makefile +++ b/examples/protocols/mqtt/publish_test/Makefile @@ -4,4 +4,6 @@ # PROJECT_NAME := mqtt_publish +EXTRA_COMPONENT_DIRS = $(IDF_PATH)/examples/common_components/protocol_examples_common + include $(IDF_PATH)/make/project.mk diff --git a/examples/protocols/mqtt/publish_test/README.md b/examples/protocols/mqtt/publish_test/README.md index bc4e02cca5..bdc2bc879d 100644 --- a/examples/protocols/mqtt/publish_test/README.md +++ b/examples/protocols/mqtt/publish_test/README.md @@ -22,16 +22,10 @@ This example can be executed on any ESP32 board, the only required interface is ### Configure the project -``` -make menuconfig -``` - -* Set serial port under Serial Flasher Options. - -* Set ssid and password for the board to connect to AP. - +* Run `make menuconfig` (or `idf.py menuconfig` if using CMake build system) +* Configure Wi-Fi or Ethernet under "Example Connection Configuration" menu. See "Establishing Wi-Fi or Ethernet Connection" section in [examples/protocols/README.md](../../README.md) for more details. +* When using Make build system, set `Default serial port` under `Serial flasher config`. * Set brokers for all 4 transports (TCP, SSL, WS, WSS), also set certificate if needed - * Set topics for publishing from and to ESP32 ### Build and Flash diff --git a/examples/protocols/mqtt/publish_test/main/Kconfig.projbuild b/examples/protocols/mqtt/publish_test/main/Kconfig.projbuild index 3d534a4778..66d3cb09e3 100644 --- a/examples/protocols/mqtt/publish_test/main/Kconfig.projbuild +++ b/examples/protocols/mqtt/publish_test/main/Kconfig.projbuild @@ -1,17 +1,5 @@ menu "Example Configuration" - config WIFI_SSID - string "WiFi SSID" - default "myssid" - help - SSID (network name) for the example to connect to. - - config WIFI_PASSWORD - string "WiFi Password" - default "mypassword" - help - WiFi password (WPA or WPA2) for the example to use. - config BROKER_SSL_URI string "Broker SSL URL" default "mqtts://iot.eclipse.org:8883" diff --git a/examples/protocols/mqtt/publish_test/main/publish_test.c b/examples/protocols/mqtt/publish_test/main/publish_test.c index 65073187ff..99ef19d747 100644 --- a/examples/protocols/mqtt/publish_test/main/publish_test.c +++ b/examples/protocols/mqtt/publish_test/main/publish_test.c @@ -13,7 +13,9 @@ #include "esp_wifi.h" #include "esp_system.h" #include "nvs_flash.h" -#include "esp_event_loop.h" +#include "esp_event.h" +#include "tcpip_adapter.h" +#include "protocol_examples_common.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" @@ -30,7 +32,6 @@ static const char *TAG = "PUBLISH_TEST"; -static EventGroupHandle_t wifi_event_group; static EventGroupHandle_t mqtt_event_group; const static int CONNECTED_BIT = BIT0; @@ -43,47 +44,6 @@ static size_t expected_published = 0; static size_t actual_published = 0; static int qos_test = 0; -static esp_err_t wifi_event_handler(void *ctx, system_event_t *event) -{ - switch (event->event_id) { - case SYSTEM_EVENT_STA_START: - esp_wifi_connect(); - break; - case SYSTEM_EVENT_STA_GOT_IP: - xEventGroupSetBits(wifi_event_group, CONNECTED_BIT); - - break; - case SYSTEM_EVENT_STA_DISCONNECTED: - esp_wifi_connect(); - xEventGroupClearBits(wifi_event_group, CONNECTED_BIT); - break; - default: - break; - } - return ESP_OK; -} - -static void wifi_init(void) -{ - tcpip_adapter_init(); - wifi_event_group = xEventGroupCreate(); - ESP_ERROR_CHECK(esp_event_loop_init(wifi_event_handler, NULL)); - wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); - ESP_ERROR_CHECK(esp_wifi_init(&cfg)); - ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_RAM)); - wifi_config_t wifi_config = { - .sta = { - .ssid = CONFIG_WIFI_SSID, - .password = CONFIG_WIFI_PASSWORD, - }, - }; - ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA)); - ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config)); - ESP_LOGI(TAG, "start the WIFI SSID:[%s]", CONFIG_WIFI_SSID); - ESP_ERROR_CHECK(esp_wifi_start()); - ESP_LOGI(TAG, "Waiting for wifi"); - xEventGroupWaitBits(wifi_event_group, CONNECTED_BIT, false, true, portMAX_DELAY); -} #if CONFIG_BROKER_CERTIFICATE_OVERRIDDEN == 1 static const uint8_t iot_eclipse_org_pem_start[] = "-----BEGIN CERTIFICATE-----\n" CONFIG_BROKER_CERTIFICATE_OVERRIDE "\n-----END CERTIFICATE-----"; @@ -208,8 +168,16 @@ void app_main() esp_log_level_set("TRANSPORT", ESP_LOG_VERBOSE); esp_log_level_set("OUTBOX", ESP_LOG_VERBOSE); - nvs_flash_init(); - wifi_init(); + ESP_ERROR_CHECK(nvs_flash_init()); + tcpip_adapter_init(); + ESP_ERROR_CHECK(esp_event_loop_create_default()); + + /* This helper function configures Wi-Fi or Ethernet, as selected in menuconfig. + * Read "Establishing Wi-Fi or Ethernet Connection" section in + * examples/protocols/README.md for more information about this function. + */ + ESP_ERROR_CHECK(example_connect()); + mqtt_app_start(); while (1) { diff --git a/examples/protocols/mqtt/ssl/CMakeLists.txt b/examples/protocols/mqtt/ssl/CMakeLists.txt index 13bdd8c213..a7b2c44204 100644 --- a/examples/protocols/mqtt/ssl/CMakeLists.txt +++ b/examples/protocols/mqtt/ssl/CMakeLists.txt @@ -2,8 +2,11 @@ # in this exact order for cmake to work correctly cmake_minimum_required(VERSION 3.5) -include($ENV{IDF_PATH}/tools/cmake/project.cmake) +# (Not part of the boilerplate) +# This example uses an extra component for common functions such as Wi-Fi and Ethernet connection. +set(EXTRA_COMPONENT_DIRS $ENV{IDF_PATH}/examples/common_components/protocol_examples_common) +include($ENV{IDF_PATH}/tools/cmake/project.cmake) project(mqtt_ssl) target_add_binary_data(mqtt_ssl.elf "main/iot_eclipse_org.pem" TEXT) diff --git a/examples/protocols/mqtt/ssl/Makefile b/examples/protocols/mqtt/ssl/Makefile index bae0d73baf..efe7f7d572 100644 --- a/examples/protocols/mqtt/ssl/Makefile +++ b/examples/protocols/mqtt/ssl/Makefile @@ -4,4 +4,6 @@ # PROJECT_NAME := mqtt_ssl +EXTRA_COMPONENT_DIRS = $(IDF_PATH)/examples/common_components/protocol_examples_common + include $(IDF_PATH)/make/project.mk diff --git a/examples/protocols/mqtt/ssl/README.md b/examples/protocols/mqtt/ssl/README.md index 3d369bdf99..929257d404 100644 --- a/examples/protocols/mqtt/ssl/README.md +++ b/examples/protocols/mqtt/ssl/README.md @@ -14,13 +14,9 @@ This example can be executed on any ESP32 board, the only required interface is ### Configure the project -``` -make menuconfig -``` - -* Set serial port under Serial Flasher Options. - -* Set ssid and password for the board to connect to AP. +* Run `make menuconfig` (or `idf.py menuconfig` if using CMake build system) +* Configure Wi-Fi or Ethernet under "Example Connection Configuration" menu. See "Establishing Wi-Fi or Ethernet Connection" section in [examples/protocols/README.md](../../README.md) for more details. +* When using Make build system, set `Default serial port` under `Serial flasher config`. Note how to create a PEM certificate for iot.eclipse.org: ``` diff --git a/examples/protocols/mqtt/ssl/main/Kconfig.projbuild b/examples/protocols/mqtt/ssl/main/Kconfig.projbuild index 7bd1fcb987..e318733662 100644 --- a/examples/protocols/mqtt/ssl/main/Kconfig.projbuild +++ b/examples/protocols/mqtt/ssl/main/Kconfig.projbuild @@ -1,17 +1,5 @@ menu "Example Configuration" - config WIFI_SSID - string "WiFi SSID" - default "myssid" - help - SSID (network name) for the example to connect to. - - config WIFI_PASSWORD - string "WiFi Password" - default "mypassword" - help - WiFi password (WPA or WPA2) for the example to use. - config BROKER_URI string "Broker URL" default "mqtts://iot.eclipse.org:8883" diff --git a/examples/protocols/mqtt/ssl/main/app_main.c b/examples/protocols/mqtt/ssl/main/app_main.c index 86697a03cc..88e1a0c381 100644 --- a/examples/protocols/mqtt/ssl/main/app_main.c +++ b/examples/protocols/mqtt/ssl/main/app_main.c @@ -1,3 +1,12 @@ +/* MQTT over SSL Example + + This example code is in the Public Domain (or CC0 licensed, at your option.) + + Unless required by applicable law or agreed to in writing, this + software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + CONDITIONS OF ANY KIND, either express or implied. +*/ + #include #include #include @@ -5,13 +14,14 @@ #include "esp_wifi.h" #include "esp_system.h" #include "nvs_flash.h" -#include "esp_event_loop.h" +#include "esp_event.h" +#include "tcpip_adapter.h" +#include "protocol_examples_common.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "freertos/semphr.h" #include "freertos/queue.h" -#include "freertos/event_groups.h" #include "lwip/sockets.h" #include "lwip/dns.h" @@ -22,52 +32,6 @@ static const char *TAG = "MQTTS_EXAMPLE"; -static EventGroupHandle_t wifi_event_group; -const static int CONNECTED_BIT = BIT0; - - - -static esp_err_t wifi_event_handler(void *ctx, system_event_t *event) -{ - switch (event->event_id) { - case SYSTEM_EVENT_STA_START: - esp_wifi_connect(); - break; - case SYSTEM_EVENT_STA_GOT_IP: - xEventGroupSetBits(wifi_event_group, CONNECTED_BIT); - - break; - case SYSTEM_EVENT_STA_DISCONNECTED: - esp_wifi_connect(); - xEventGroupClearBits(wifi_event_group, CONNECTED_BIT); - break; - default: - break; - } - return ESP_OK; -} - -static void wifi_init(void) -{ - tcpip_adapter_init(); - wifi_event_group = xEventGroupCreate(); - ESP_ERROR_CHECK(esp_event_loop_init(wifi_event_handler, NULL)); - wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); - ESP_ERROR_CHECK(esp_wifi_init(&cfg)); - ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_RAM)); - wifi_config_t wifi_config = { - .sta = { - .ssid = CONFIG_WIFI_SSID, - .password = CONFIG_WIFI_PASSWORD, - }, - }; - ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA)); - ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config)); - ESP_LOGI(TAG, "start the WIFI SSID:[%s]", CONFIG_WIFI_SSID); - ESP_ERROR_CHECK(esp_wifi_start()); - ESP_LOGI(TAG, "Waiting for wifi"); - xEventGroupWaitBits(wifi_event_group, CONNECTED_BIT, false, true, portMAX_DELAY); -} #if CONFIG_BROKER_CERTIFICATE_OVERRIDDEN == 1 static const uint8_t iot_eclipse_org_pem_start[] = "-----BEGIN CERTIFICATE-----\n" CONFIG_BROKER_CERTIFICATE_OVERRIDE "\n-----END CERTIFICATE-----"; @@ -150,8 +114,15 @@ void app_main() esp_log_level_set("TRANSPORT", ESP_LOG_VERBOSE); esp_log_level_set("OUTBOX", ESP_LOG_VERBOSE); - nvs_flash_init(); - wifi_init(); - mqtt_app_start(); + ESP_ERROR_CHECK(nvs_flash_init()); + tcpip_adapter_init(); + ESP_ERROR_CHECK(esp_event_loop_create_default()); + /* This helper function configures Wi-Fi or Ethernet, as selected in menuconfig. + * Read "Establishing Wi-Fi or Ethernet Connection" section in + * examples/protocols/README.md for more information about this function. + */ + ESP_ERROR_CHECK(example_connect()); + + mqtt_app_start(); } diff --git a/examples/protocols/mqtt/ssl_mutual_auth/CMakeLists.txt b/examples/protocols/mqtt/ssl_mutual_auth/CMakeLists.txt index 84bf37525e..472a3ca3ec 100644 --- a/examples/protocols/mqtt/ssl_mutual_auth/CMakeLists.txt +++ b/examples/protocols/mqtt/ssl_mutual_auth/CMakeLists.txt @@ -2,8 +2,11 @@ # in this exact order for cmake to work correctly cmake_minimum_required(VERSION 3.5) -include($ENV{IDF_PATH}/tools/cmake/project.cmake) +# (Not part of the boilerplate) +# This example uses an extra component for common functions such as Wi-Fi and Ethernet connection. +set(EXTRA_COMPONENT_DIRS $ENV{IDF_PATH}/examples/common_components/protocol_examples_common) +include($ENV{IDF_PATH}/tools/cmake/project.cmake) project(mqtt_ssl_mutual_auth) target_add_binary_data(${CMAKE_PROJECT_NAME}.elf "main/client.crt" TEXT) diff --git a/examples/protocols/mqtt/ssl_mutual_auth/Makefile b/examples/protocols/mqtt/ssl_mutual_auth/Makefile index cfc04f81b1..1394f99a6c 100644 --- a/examples/protocols/mqtt/ssl_mutual_auth/Makefile +++ b/examples/protocols/mqtt/ssl_mutual_auth/Makefile @@ -4,4 +4,6 @@ # PROJECT_NAME := mqtt_ssl_mutual_auth +EXTRA_COMPONENT_DIRS = $(IDF_PATH)/examples/common_components/protocol_examples_common + include $(IDF_PATH)/make/project.mk diff --git a/examples/protocols/mqtt/ssl_mutual_auth/README.md b/examples/protocols/mqtt/ssl_mutual_auth/README.md index 7ffe537041..763e2671ac 100644 --- a/examples/protocols/mqtt/ssl_mutual_auth/README.md +++ b/examples/protocols/mqtt/ssl_mutual_auth/README.md @@ -14,13 +14,9 @@ This example can be executed on any ESP32 board, the only required interface is ### Configure the project -``` -make menuconfig -``` - -* Set serial port under Serial Flasher Options. - -* Set ssid and password for the board to connect to AP. +* Run `make menuconfig` (or `idf.py menuconfig` if using CMake build system) +* Configure Wi-Fi or Ethernet under "Example Connection Configuration" menu. See "Establishing Wi-Fi or Ethernet Connection" section in [examples/protocols/README.md](../../README.md) for more details. +* When using Make build system, set `Default serial port` under `Serial flasher config`. * Generate your client keys and certificate diff --git a/examples/protocols/mqtt/ssl_mutual_auth/main/Kconfig.projbuild b/examples/protocols/mqtt/ssl_mutual_auth/main/Kconfig.projbuild deleted file mode 100644 index ed4e691688..0000000000 --- a/examples/protocols/mqtt/ssl_mutual_auth/main/Kconfig.projbuild +++ /dev/null @@ -1,15 +0,0 @@ -menu "Example Configuration" - - config WIFI_SSID - string "WiFi SSID" - default "myssid" - help - SSID (network name) for the example to connect to. - - config WIFI_PASSWORD - string "WiFi Password" - default "mypassword" - help - WiFi password (WPA or WPA2) for the example to use. - -endmenu diff --git a/examples/protocols/mqtt/ssl_mutual_auth/main/app_main.c b/examples/protocols/mqtt/ssl_mutual_auth/main/app_main.c index 62b970056a..21c76ff44d 100644 --- a/examples/protocols/mqtt/ssl_mutual_auth/main/app_main.c +++ b/examples/protocols/mqtt/ssl_mutual_auth/main/app_main.c @@ -1,3 +1,11 @@ +/* MQTT Mutual Authentication Example + + This example code is in the Public Domain (or CC0 licensed, at your option.) + + Unless required by applicable law or agreed to in writing, this + software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + CONDITIONS OF ANY KIND, either express or implied. +*/ #include #include #include @@ -5,13 +13,14 @@ #include "esp_wifi.h" #include "esp_system.h" #include "nvs_flash.h" -#include "esp_event_loop.h" +#include "esp_event.h" +#include "tcpip_adapter.h" +#include "protocol_examples_common.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "freertos/semphr.h" #include "freertos/queue.h" -#include "freertos/event_groups.h" #include "lwip/sockets.h" #include "lwip/dns.h" @@ -22,53 +31,6 @@ static const char *TAG = "MQTTS_EXAMPLE"; -static EventGroupHandle_t wifi_event_group; -const static int CONNECTED_BIT = BIT0; - - - -static esp_err_t wifi_event_handler(void *ctx, system_event_t *event) -{ - switch (event->event_id) { - case SYSTEM_EVENT_STA_START: - esp_wifi_connect(); - break; - case SYSTEM_EVENT_STA_GOT_IP: - xEventGroupSetBits(wifi_event_group, CONNECTED_BIT); - - break; - case SYSTEM_EVENT_STA_DISCONNECTED: - esp_wifi_connect(); - xEventGroupClearBits(wifi_event_group, CONNECTED_BIT); - break; - default: - break; - } - return ESP_OK; -} - -static void wifi_init(void) -{ - tcpip_adapter_init(); - wifi_event_group = xEventGroupCreate(); - ESP_ERROR_CHECK(esp_event_loop_init(wifi_event_handler, NULL)); - wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); - ESP_ERROR_CHECK(esp_wifi_init(&cfg)); - ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_RAM)); - wifi_config_t wifi_config = { - .sta = { - .ssid = CONFIG_WIFI_SSID, - .password = CONFIG_WIFI_PASSWORD, - }, - }; - ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA)); - ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config)); - ESP_LOGI(TAG, "start the WIFI SSID:[%s]", CONFIG_WIFI_SSID); - ESP_ERROR_CHECK(esp_wifi_start()); - ESP_LOGI(TAG, "Waiting for wifi"); - xEventGroupWaitBits(wifi_event_group, CONNECTED_BIT, false, true, portMAX_DELAY); -} - extern const uint8_t client_cert_pem_start[] asm("_binary_client_crt_start"); extern const uint8_t client_cert_pem_end[] asm("_binary_client_crt_end"); extern const uint8_t client_key_pem_start[] asm("_binary_client_key_start"); @@ -148,8 +110,15 @@ void app_main() esp_log_level_set("TRANSPORT", ESP_LOG_VERBOSE); esp_log_level_set("OUTBOX", ESP_LOG_VERBOSE); - nvs_flash_init(); - wifi_init(); - mqtt_app_start(); + ESP_ERROR_CHECK(nvs_flash_init()); + tcpip_adapter_init(); + ESP_ERROR_CHECK(esp_event_loop_create_default()); + /* This helper function configures Wi-Fi or Ethernet, as selected in menuconfig. + * Read "Establishing Wi-Fi or Ethernet Connection" section in + * examples/protocols/README.md for more information about this function. + */ + ESP_ERROR_CHECK(example_connect()); + + mqtt_app_start(); } diff --git a/examples/protocols/mqtt/tcp/CMakeLists.txt b/examples/protocols/mqtt/tcp/CMakeLists.txt index 678d787af8..5a70e7aa01 100644 --- a/examples/protocols/mqtt/tcp/CMakeLists.txt +++ b/examples/protocols/mqtt/tcp/CMakeLists.txt @@ -2,6 +2,9 @@ # in this exact order for cmake to work correctly cmake_minimum_required(VERSION 3.5) -include($ENV{IDF_PATH}/tools/cmake/project.cmake) +# (Not part of the boilerplate) +# This example uses an extra component for common functions such as Wi-Fi and Ethernet connection. +set(EXTRA_COMPONENT_DIRS $ENV{IDF_PATH}/examples/common_components/protocol_examples_common) +include($ENV{IDF_PATH}/tools/cmake/project.cmake) project(mqtt_tcp) \ No newline at end of file diff --git a/examples/protocols/mqtt/tcp/Makefile b/examples/protocols/mqtt/tcp/Makefile index cd53fdbf5b..530276501d 100644 --- a/examples/protocols/mqtt/tcp/Makefile +++ b/examples/protocols/mqtt/tcp/Makefile @@ -4,4 +4,6 @@ # PROJECT_NAME := mqtt_tcp +EXTRA_COMPONENT_DIRS = $(IDF_PATH)/examples/common_components/protocol_examples_common + include $(IDF_PATH)/make/project.mk diff --git a/examples/protocols/mqtt/tcp/README.md b/examples/protocols/mqtt/tcp/README.md index 2fda24070b..aea6630944 100644 --- a/examples/protocols/mqtt/tcp/README.md +++ b/examples/protocols/mqtt/tcp/README.md @@ -14,13 +14,9 @@ This example can be executed on any ESP32 board, the only required interface is ### Configure the project -``` -make menuconfig -``` - -* Set serial port under Serial Flasher Options. - -* Set ssid and password for the board to connect to AP. +* Run `make menuconfig` (or `idf.py menuconfig` if using CMake build system) +* Configure Wi-Fi or Ethernet under "Example Connection Configuration" menu. See "Establishing Wi-Fi or Ethernet Connection" section in [examples/protocols/README.md](../../README.md) for more details. +* When using Make build system, set `Default serial port` under `Serial flasher config`. ### Build and Flash diff --git a/examples/protocols/mqtt/tcp/main/Kconfig.projbuild b/examples/protocols/mqtt/tcp/main/Kconfig.projbuild index f5c519baa4..fbd48103ba 100644 --- a/examples/protocols/mqtt/tcp/main/Kconfig.projbuild +++ b/examples/protocols/mqtt/tcp/main/Kconfig.projbuild @@ -1,17 +1,5 @@ menu "Example Configuration" - config WIFI_SSID - string "WiFi SSID" - default "myssid" - help - SSID (network name) for the example to connect to. - - config WIFI_PASSWORD - string "WiFi Password" - default "mypassword" - help - WiFi password (WPA or WPA2) for the example to use. - config BROKER_URL string "Broker URL" default "mqtt://iot.eclipse.org" diff --git a/examples/protocols/mqtt/tcp/main/app_main.c b/examples/protocols/mqtt/tcp/main/app_main.c index ce1640adb6..1863a013a3 100644 --- a/examples/protocols/mqtt/tcp/main/app_main.c +++ b/examples/protocols/mqtt/tcp/main/app_main.c @@ -1,3 +1,12 @@ +/* MQTT (over TCP) Example + + This example code is in the Public Domain (or CC0 licensed, at your option.) + + Unless required by applicable law or agreed to in writing, this + software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + CONDITIONS OF ANY KIND, either express or implied. +*/ + #include #include #include @@ -5,13 +14,14 @@ #include "esp_wifi.h" #include "esp_system.h" #include "nvs_flash.h" -#include "esp_event_loop.h" +#include "esp_event.h" +#include "tcpip_adapter.h" +#include "protocol_examples_common.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "freertos/semphr.h" #include "freertos/queue.h" -#include "freertos/event_groups.h" #include "lwip/sockets.h" #include "lwip/dns.h" @@ -22,9 +32,6 @@ static const char *TAG = "MQTT_EXAMPLE"; -static EventGroupHandle_t wifi_event_group; -const static int CONNECTED_BIT = BIT0; - static esp_err_t mqtt_event_handler(esp_mqtt_event_handle_t event) { @@ -76,48 +83,6 @@ static esp_err_t mqtt_event_handler(esp_mqtt_event_handle_t event) return ESP_OK; } -static esp_err_t wifi_event_handler(void *ctx, system_event_t *event) -{ - switch (event->event_id) { - case SYSTEM_EVENT_STA_START: - esp_wifi_connect(); - break; - case SYSTEM_EVENT_STA_GOT_IP: - xEventGroupSetBits(wifi_event_group, CONNECTED_BIT); - - break; - case SYSTEM_EVENT_STA_DISCONNECTED: - esp_wifi_connect(); - xEventGroupClearBits(wifi_event_group, CONNECTED_BIT); - break; - default: - break; - } - return ESP_OK; -} - -static void wifi_init(void) -{ - tcpip_adapter_init(); - wifi_event_group = xEventGroupCreate(); - ESP_ERROR_CHECK(esp_event_loop_init(wifi_event_handler, NULL)); - wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); - ESP_ERROR_CHECK(esp_wifi_init(&cfg)); - ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_RAM)); - wifi_config_t wifi_config = { - .sta = { - .ssid = CONFIG_WIFI_SSID, - .password = CONFIG_WIFI_PASSWORD, - }, - }; - ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA)); - ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config)); - ESP_LOGI(TAG, "start the WIFI SSID:[%s]", CONFIG_WIFI_SSID); - ESP_ERROR_CHECK(esp_wifi_start()); - ESP_LOGI(TAG, "Waiting for wifi"); - xEventGroupWaitBits(wifi_event_group, CONNECTED_BIT, false, true, portMAX_DELAY); -} - static void mqtt_app_start(void) { esp_mqtt_client_config_t mqtt_cfg = { @@ -168,7 +133,15 @@ void app_main() esp_log_level_set("TRANSPORT", ESP_LOG_VERBOSE); esp_log_level_set("OUTBOX", ESP_LOG_VERBOSE); - nvs_flash_init(); - wifi_init(); + ESP_ERROR_CHECK(nvs_flash_init()); + tcpip_adapter_init(); + ESP_ERROR_CHECK(esp_event_loop_create_default()); + + /* This helper function configures Wi-Fi or Ethernet, as selected in menuconfig. + * Read "Establishing Wi-Fi or Ethernet Connection" section in + * examples/protocols/README.md for more information about this function. + */ + ESP_ERROR_CHECK(example_connect()); + mqtt_app_start(); } diff --git a/examples/protocols/mqtt/ws/CMakeLists.txt b/examples/protocols/mqtt/ws/CMakeLists.txt index 58a2135dac..f0490061c9 100644 --- a/examples/protocols/mqtt/ws/CMakeLists.txt +++ b/examples/protocols/mqtt/ws/CMakeLists.txt @@ -2,6 +2,9 @@ # in this exact order for cmake to work correctly cmake_minimum_required(VERSION 3.5) -include($ENV{IDF_PATH}/tools/cmake/project.cmake) +# (Not part of the boilerplate) +# This example uses an extra component for common functions such as Wi-Fi and Ethernet connection. +set(EXTRA_COMPONENT_DIRS $ENV{IDF_PATH}/examples/common_components/protocol_examples_common) -project(mqtt_websocket) \ No newline at end of file +include($ENV{IDF_PATH}/tools/cmake/project.cmake) +project(mqtt_websocket) diff --git a/examples/protocols/mqtt/ws/Makefile b/examples/protocols/mqtt/ws/Makefile index 668719bf19..2b97fa44c9 100644 --- a/examples/protocols/mqtt/ws/Makefile +++ b/examples/protocols/mqtt/ws/Makefile @@ -4,4 +4,6 @@ # PROJECT_NAME := mqtt_websocket +EXTRA_COMPONENT_DIRS = $(IDF_PATH)/examples/common_components/protocol_examples_common + include $(IDF_PATH)/make/project.mk diff --git a/examples/protocols/mqtt/ws/README.md b/examples/protocols/mqtt/ws/README.md index 619519d92c..efe2efcb39 100644 --- a/examples/protocols/mqtt/ws/README.md +++ b/examples/protocols/mqtt/ws/README.md @@ -14,13 +14,9 @@ This example can be executed on any ESP32 board, the only required interface is ### Configure the project -``` -make menuconfig -``` - -* Set serial port under Serial Flasher Options. - -* Set ssid and password for the board to connect to AP. +* Run `make menuconfig` (or `idf.py menuconfig` if using CMake build system) +* Configure Wi-Fi or Ethernet under "Example Connection Configuration" menu. See "Establishing Wi-Fi or Ethernet Connection" section in [examples/protocols/README.md](../../README.md) for more details. +* When using Make build system, set `Default serial port` under `Serial flasher config`. ### Build and Flash diff --git a/examples/protocols/mqtt/ws/main/Kconfig.projbuild b/examples/protocols/mqtt/ws/main/Kconfig.projbuild index 9e47709c2e..46f3ad5652 100644 --- a/examples/protocols/mqtt/ws/main/Kconfig.projbuild +++ b/examples/protocols/mqtt/ws/main/Kconfig.projbuild @@ -1,17 +1,5 @@ menu "Example Configuration" - config WIFI_SSID - string "WiFi SSID" - default "myssid" - help - SSID (network name) for the example to connect to. - - config WIFI_PASSWORD - string "WiFi Password" - default "mypassword" - help - WiFi password (WPA or WPA2) for the example to use. - config BROKER_URI string "Broker URL" default "ws://iot.eclipse.org:80/ws" diff --git a/examples/protocols/mqtt/ws/main/app_main.c b/examples/protocols/mqtt/ws/main/app_main.c index 024be48bd0..0387e967ca 100644 --- a/examples/protocols/mqtt/ws/main/app_main.c +++ b/examples/protocols/mqtt/ws/main/app_main.c @@ -1,3 +1,11 @@ +/* MQTT over Websockets Example + + This example code is in the Public Domain (or CC0 licensed, at your option.) + + Unless required by applicable law or agreed to in writing, this + software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + CONDITIONS OF ANY KIND, either express or implied. +*/ #include #include #include @@ -5,13 +13,14 @@ #include "esp_wifi.h" #include "esp_system.h" #include "nvs_flash.h" -#include "esp_event_loop.h" +#include "esp_event.h" +#include "tcpip_adapter.h" +#include "protocol_examples_common.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "freertos/semphr.h" #include "freertos/queue.h" -#include "freertos/event_groups.h" #include "lwip/sockets.h" #include "lwip/dns.h" @@ -22,9 +31,6 @@ static const char *TAG = "MQTTWS_EXAMPLE"; -static EventGroupHandle_t wifi_event_group; -const static int CONNECTED_BIT = BIT0; - static esp_err_t mqtt_event_handler(esp_mqtt_event_handle_t event) { @@ -73,47 +79,6 @@ static esp_err_t mqtt_event_handler(esp_mqtt_event_handle_t event) return ESP_OK; } -static esp_err_t wifi_event_handler(void *ctx, system_event_t *event) -{ - switch (event->event_id) { - case SYSTEM_EVENT_STA_START: - esp_wifi_connect(); - break; - case SYSTEM_EVENT_STA_GOT_IP: - xEventGroupSetBits(wifi_event_group, CONNECTED_BIT); - - break; - case SYSTEM_EVENT_STA_DISCONNECTED: - esp_wifi_connect(); - xEventGroupClearBits(wifi_event_group, CONNECTED_BIT); - break; - default: - break; - } - return ESP_OK; -} - -static void wifi_init(void) -{ - tcpip_adapter_init(); - wifi_event_group = xEventGroupCreate(); - ESP_ERROR_CHECK(esp_event_loop_init(wifi_event_handler, NULL)); - wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); - ESP_ERROR_CHECK(esp_wifi_init(&cfg)); - ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_RAM)); - wifi_config_t wifi_config = { - .sta = { - .ssid = CONFIG_WIFI_SSID, - .password = CONFIG_WIFI_PASSWORD, - }, - }; - ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA)); - ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config)); - ESP_LOGI(TAG, "start the WIFI SSID:[%s]", CONFIG_WIFI_SSID); - ESP_ERROR_CHECK(esp_wifi_start()); - ESP_LOGI(TAG, "Waiting for wifi"); - xEventGroupWaitBits(wifi_event_group, CONNECTED_BIT, false, true, portMAX_DELAY); -} static void mqtt_app_start(void) { @@ -141,7 +106,15 @@ void app_main() esp_log_level_set("TRANSPORT", ESP_LOG_VERBOSE); esp_log_level_set("OUTBOX", ESP_LOG_VERBOSE); - nvs_flash_init(); - wifi_init(); + ESP_ERROR_CHECK(nvs_flash_init()); + tcpip_adapter_init(); + ESP_ERROR_CHECK(esp_event_loop_create_default()); + + /* This helper function configures Wi-Fi or Ethernet, as selected in menuconfig. + * Read "Establishing Wi-Fi or Ethernet Connection" section in + * examples/protocols/README.md for more information about this function. + */ + ESP_ERROR_CHECK(example_connect()); + mqtt_app_start(); } diff --git a/examples/protocols/mqtt/wss/CMakeLists.txt b/examples/protocols/mqtt/wss/CMakeLists.txt index 7ba5e62953..3e2d5fc23e 100644 --- a/examples/protocols/mqtt/wss/CMakeLists.txt +++ b/examples/protocols/mqtt/wss/CMakeLists.txt @@ -2,8 +2,11 @@ # in this exact order for cmake to work correctly cmake_minimum_required(VERSION 3.5) -include($ENV{IDF_PATH}/tools/cmake/project.cmake) +# (Not part of the boilerplate) +# This example uses an extra component for common functions such as Wi-Fi and Ethernet connection. +set(EXTRA_COMPONENT_DIRS $ENV{IDF_PATH}/examples/common_components/protocol_examples_common) +include($ENV{IDF_PATH}/tools/cmake/project.cmake) project(mqtt_websocket_secure) target_add_binary_data(mqtt_websocket_secure.elf "main/iot_eclipse_org.pem" TEXT) diff --git a/examples/protocols/mqtt/wss/Makefile b/examples/protocols/mqtt/wss/Makefile index 27047d0490..50ed13dd38 100644 --- a/examples/protocols/mqtt/wss/Makefile +++ b/examples/protocols/mqtt/wss/Makefile @@ -4,4 +4,6 @@ # PROJECT_NAME := mqtt_websocket_secure +EXTRA_COMPONENT_DIRS = $(IDF_PATH)/examples/common_components/protocol_examples_common + include $(IDF_PATH)/make/project.mk diff --git a/examples/protocols/mqtt/wss/README.md b/examples/protocols/mqtt/wss/README.md index 43d829ccbe..9433986a51 100644 --- a/examples/protocols/mqtt/wss/README.md +++ b/examples/protocols/mqtt/wss/README.md @@ -13,13 +13,9 @@ This example can be executed on any ESP32 board, the only required interface is ### Configure the project -``` -make menuconfig -``` - -* Set serial port under Serial Flasher Options. - -* Set ssid and password for the board to connect to AP. +* Run `make menuconfig` (or `idf.py menuconfig` if using CMake build system) +* Configure Wi-Fi or Ethernet under "Example Connection Configuration" menu. See "Establishing Wi-Fi or Ethernet Connection" section in [examples/protocols/README.md](../../README.md) for more details. +* When using Make build system, set `Default serial port` under `Serial flasher config`. Note how to create a PEM certificate for iot.eclipse.org: diff --git a/examples/protocols/mqtt/wss/main/Kconfig.projbuild b/examples/protocols/mqtt/wss/main/Kconfig.projbuild index a16174012b..d3f7bf51c0 100644 --- a/examples/protocols/mqtt/wss/main/Kconfig.projbuild +++ b/examples/protocols/mqtt/wss/main/Kconfig.projbuild @@ -1,17 +1,5 @@ menu "Example Configuration" - config WIFI_SSID - string "WiFi SSID" - default "myssid" - help - SSID (network name) for the example to connect to. - - config WIFI_PASSWORD - string "WiFi Password" - default "mypassword" - help - WiFi password (WPA or WPA2) for the example to use. - config BROKER_URI string "Broker URL" default "wss://iot.eclipse.org:443/ws" diff --git a/examples/protocols/mqtt/wss/main/app_main.c b/examples/protocols/mqtt/wss/main/app_main.c index 50595495a8..cbf8631e28 100644 --- a/examples/protocols/mqtt/wss/main/app_main.c +++ b/examples/protocols/mqtt/wss/main/app_main.c @@ -1,3 +1,11 @@ +/* MQTT over Secure Websockets Example + + This example code is in the Public Domain (or CC0 licensed, at your option.) + + Unless required by applicable law or agreed to in writing, this + software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + CONDITIONS OF ANY KIND, either express or implied. +*/ #include #include #include @@ -5,13 +13,14 @@ #include "esp_wifi.h" #include "esp_system.h" #include "nvs_flash.h" -#include "esp_event_loop.h" +#include "esp_event.h" +#include "tcpip_adapter.h" +#include "protocol_examples_common.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "freertos/semphr.h" #include "freertos/queue.h" -#include "freertos/event_groups.h" #include "lwip/sockets.h" #include "lwip/dns.h" @@ -22,52 +31,6 @@ static const char *TAG = "MQTTWSS_EXAMPLE"; -static EventGroupHandle_t wifi_event_group; -const static int CONNECTED_BIT = BIT0; - - - -static esp_err_t wifi_event_handler(void *ctx, system_event_t *event) -{ - switch (event->event_id) { - case SYSTEM_EVENT_STA_START: - esp_wifi_connect(); - break; - case SYSTEM_EVENT_STA_GOT_IP: - xEventGroupSetBits(wifi_event_group, CONNECTED_BIT); - - break; - case SYSTEM_EVENT_STA_DISCONNECTED: - esp_wifi_connect(); - xEventGroupClearBits(wifi_event_group, CONNECTED_BIT); - break; - default: - break; - } - return ESP_OK; -} - -static void wifi_init(void) -{ - tcpip_adapter_init(); - wifi_event_group = xEventGroupCreate(); - ESP_ERROR_CHECK(esp_event_loop_init(wifi_event_handler, NULL)); - wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); - ESP_ERROR_CHECK(esp_wifi_init(&cfg)); - ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_RAM)); - wifi_config_t wifi_config = { - .sta = { - .ssid = CONFIG_WIFI_SSID, - .password = CONFIG_WIFI_PASSWORD, - }, - }; - ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA)); - ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config)); - ESP_LOGI(TAG, "start the WIFI SSID:[%s]", CONFIG_WIFI_SSID); - ESP_ERROR_CHECK(esp_wifi_start()); - ESP_LOGI(TAG, "Waiting for wifi"); - xEventGroupWaitBits(wifi_event_group, CONNECTED_BIT, false, true, portMAX_DELAY); -} #if CONFIG_BROKER_CERTIFICATE_OVERRIDDEN == 1 static const uint8_t iot_eclipse_org_pem_start[] = "-----BEGIN CERTIFICATE-----\n" CONFIG_BROKER_CERTIFICATE_OVERRIDE "\n-----END CERTIFICATE-----"; @@ -149,7 +112,15 @@ void app_main() esp_log_level_set("TRANSPORT", ESP_LOG_VERBOSE); esp_log_level_set("OUTBOX", ESP_LOG_VERBOSE); - nvs_flash_init(); - wifi_init(); + ESP_ERROR_CHECK(nvs_flash_init()); + tcpip_adapter_init(); + ESP_ERROR_CHECK(esp_event_loop_create_default()); + + /* This helper function configures Wi-Fi or Ethernet, as selected in menuconfig. + * Read "Establishing Wi-Fi or Ethernet Connection" section in + * examples/protocols/README.md for more information about this function. + */ + ESP_ERROR_CHECK(example_connect()); + mqtt_app_start(); } diff --git a/examples/protocols/openssl_client/CMakeLists.txt b/examples/protocols/openssl_client/CMakeLists.txt index 5449461ce7..577d4ae082 100644 --- a/examples/protocols/openssl_client/CMakeLists.txt +++ b/examples/protocols/openssl_client/CMakeLists.txt @@ -2,5 +2,9 @@ # in this exact order for cmake to work correctly cmake_minimum_required(VERSION 3.5) +# (Not part of the boilerplate) +# This example uses an extra component for common functions such as Wi-Fi and Ethernet connection. +set(EXTRA_COMPONENT_DIRS $ENV{IDF_PATH}/examples/common_components/protocol_examples_common) + include($ENV{IDF_PATH}/tools/cmake/project.cmake) project(openssl_client) diff --git a/examples/protocols/openssl_client/Makefile b/examples/protocols/openssl_client/Makefile index 7e2f4fe7f8..1ae39bf11f 100644 --- a/examples/protocols/openssl_client/Makefile +++ b/examples/protocols/openssl_client/Makefile @@ -5,5 +5,7 @@ PROJECT_NAME := openssl_client +EXTRA_COMPONENT_DIRS = $(IDF_PATH)/examples/common_components/protocol_examples_common + include $(IDF_PATH)/make/project.mk diff --git a/examples/protocols/openssl_client/README.md b/examples/protocols/openssl_client/README.md index 2a6ac19881..07be757195 100644 --- a/examples/protocols/openssl_client/README.md +++ b/examples/protocols/openssl_client/README.md @@ -2,12 +2,13 @@ The Example contains of OpenSSL client demo. -First you should config the project by "make menuconfig": - Example Configuration -> - 1. Target Domain : the domain that you want to connect to, and default is "www.baidu.com". - 2. Target port number : the port number of the target domain, and default is 443. - 3. WIFI SSID : your own WIFI, which is connected to the Internet, and default is "myssid". - 4. WIFI Password : WIFI password, and default is "mypassword" +To configure the project, run `make menuconfig` (or `idf.py menuconfig` if using CMake build system). + +* Configure Wi-Fi or Ethernet under "Example Connection Configuration" menu. See "Establishing Wi-Fi or Ethernet Connection" section in [examples/protocols/README.md](../README.md) for more details. + +* When using Make build system, set `Default serial port` under `Serial flasher config`. + +* Configure target domain and port number under "Example Configuration" If you want to test the OpenSSL client demo: 1. compile the code and load the firmware diff --git a/examples/protocols/openssl_client/main/Kconfig.projbuild b/examples/protocols/openssl_client/main/Kconfig.projbuild index 93fa37b6ea..64b5b37304 100644 --- a/examples/protocols/openssl_client/main/Kconfig.projbuild +++ b/examples/protocols/openssl_client/main/Kconfig.projbuild @@ -13,16 +13,4 @@ menu "Example Configuration" help Target port number for the example to connect to. - config WIFI_SSID - string "WiFi SSID" - default "myssid" - help - SSID (network name) for the example to connect to. - - config WIFI_PASSWORD - string "WiFi Password" - default "mypassword" - help - WiFi password (WPA or WPA2) for the example to use. - endmenu diff --git a/examples/protocols/openssl_client/main/openssl_client_example.h b/examples/protocols/openssl_client/main/openssl_client_example.h index fbdecb0d27..8d1645164a 100644 --- a/examples/protocols/openssl_client/main/openssl_client_example.h +++ b/examples/protocols/openssl_client/main/openssl_client_example.h @@ -10,15 +10,6 @@ #ifndef _OPENSSL_EXAMPLE_H_ #define _OPENSSL_EXAMPLE_H_ -/* The examples use simple WiFi configuration that you can set via - 'make menuconfig'. - - If you'd rather not, just change the below entries to strings with - the config you want - ie #define EXAMPLE_WIFI_SSID "mywifissid" -*/ -#define EXAMPLE_WIFI_SSID CONFIG_WIFI_SSID -#define EXAMPLE_WIFI_PASS CONFIG_WIFI_PASSWORD - /* The examples use domain of "www.baidu.com" and port number of 433 that you can set via 'make menuconfig'. diff --git a/examples/protocols/openssl_client/main/openssl_client_example_main.c b/examples/protocols/openssl_client/main/openssl_client_example_main.c index 97bcf2abe6..a06ef6cdd4 100644 --- a/examples/protocols/openssl_client/main/openssl_client_example_main.c +++ b/examples/protocols/openssl_client/main/openssl_client_example_main.c @@ -15,24 +15,17 @@ #include "freertos/FreeRTOS.h" #include "freertos/task.h" -#include "freertos/event_groups.h" #include "esp_log.h" #include "esp_wifi.h" -#include "esp_event_loop.h" - +#include "esp_event.h" #include "nvs_flash.h" +#include "tcpip_adapter.h" +#include "protocol_examples_common.h" #include "lwip/sockets.h" #include "lwip/netdb.h" -static EventGroupHandle_t wifi_event_group; - -/* The event group allows multiple bits for each event, - but we only care about one event - are we connected - to the AP with an IP? */ -const static int CONNECTED_BIT = BIT0; - const static char *TAG = "openssl_example"; static void openssl_example_task(void *p) @@ -142,7 +135,7 @@ static void openssl_example_task(void *p) ESP_LOGI(TAG, "%s", recv_buf); } while (1); - ESP_LOGI(TAG, "totaly read %d bytes data from %s ......", recv_bytes, OPENSSL_EXAMPLE_TARGET_NAME); + ESP_LOGI(TAG, "totally read %d bytes data from %s ......", recv_bytes, OPENSSL_EXAMPLE_TARGET_NAME); failed5: SSL_shutdown(ssl); @@ -177,50 +170,18 @@ static void openssl_example_client_init(void) } } -static esp_err_t wifi_event_handler(void *ctx, system_event_t *event) -{ - switch(event->event_id) { - case SYSTEM_EVENT_STA_START: - esp_wifi_connect(); - break; - case SYSTEM_EVENT_STA_GOT_IP: - xEventGroupSetBits(wifi_event_group, CONNECTED_BIT); - openssl_example_client_init(); - break; - case SYSTEM_EVENT_STA_DISCONNECTED: - /* This is a workaround as ESP32 WiFi libs don't currently - auto-reassociate. */ - esp_wifi_connect(); - xEventGroupClearBits(wifi_event_group, CONNECTED_BIT); - break; - default: - break; - } - return ESP_OK; -} - -static void wifi_conn_init(void) -{ - tcpip_adapter_init(); - wifi_event_group = xEventGroupCreate(); - ESP_ERROR_CHECK( esp_event_loop_init(wifi_event_handler, NULL) ); - wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); - ESP_ERROR_CHECK( esp_wifi_init(&cfg) ); - ESP_ERROR_CHECK( esp_wifi_set_storage(WIFI_STORAGE_RAM) ); - wifi_config_t wifi_config = { - .sta = { - .ssid = EXAMPLE_WIFI_SSID, - .password = EXAMPLE_WIFI_PASS, - }, - }; - ESP_ERROR_CHECK( esp_wifi_set_mode(WIFI_MODE_STA) ); - ESP_ERROR_CHECK( esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config) ); - ESP_LOGI(TAG, "start the WIFI SSID:[%s] password:[%s]\n", EXAMPLE_WIFI_SSID, EXAMPLE_WIFI_PASS); - ESP_ERROR_CHECK( esp_wifi_start() ); -} - void app_main(void) { ESP_ERROR_CHECK( nvs_flash_init() ); - wifi_conn_init(); + ESP_ERROR_CHECK(nvs_flash_init()); + tcpip_adapter_init(); + ESP_ERROR_CHECK(esp_event_loop_create_default()); + + /* This helper function configures Wi-Fi or Ethernet, as selected in menuconfig. + * Read "Establishing Wi-Fi or Ethernet Connection" section in + * examples/protocols/README.md for more information about this function. + */ + ESP_ERROR_CHECK(example_connect()); + + openssl_example_client_init(); } diff --git a/examples/protocols/openssl_server/CMakeLists.txt b/examples/protocols/openssl_server/CMakeLists.txt index d3e5c5ccbe..9fb42034a5 100644 --- a/examples/protocols/openssl_server/CMakeLists.txt +++ b/examples/protocols/openssl_server/CMakeLists.txt @@ -2,5 +2,9 @@ # in this exact order for cmake to work correctly cmake_minimum_required(VERSION 3.5) +# (Not part of the boilerplate) +# This example uses an extra component for common functions such as Wi-Fi and Ethernet connection. +set(EXTRA_COMPONENT_DIRS $ENV{IDF_PATH}/examples/common_components/protocol_examples_common) + include($ENV{IDF_PATH}/tools/cmake/project.cmake) project(openssl_server) diff --git a/examples/protocols/openssl_server/Makefile b/examples/protocols/openssl_server/Makefile index f65f11a562..24d020d696 100644 --- a/examples/protocols/openssl_server/Makefile +++ b/examples/protocols/openssl_server/Makefile @@ -5,5 +5,7 @@ PROJECT_NAME := openssl_server +EXTRA_COMPONENT_DIRS = $(IDF_PATH)/examples/common_components/protocol_examples_common + include $(IDF_PATH)/make/project.mk diff --git a/examples/protocols/openssl_server/README.md b/examples/protocols/openssl_server/README.md index 916f619432..6d4506e933 100644 --- a/examples/protocols/openssl_server/README.md +++ b/examples/protocols/openssl_server/README.md @@ -2,10 +2,11 @@ The Example contains of OpenSSL server demo. -First you should configure the project by "make menuconfig": - Example Configuration -> - 1. WIFI SSID: WIFI network to which your PC is also connected to. - 2. WIFI Password: WIFI password +To configure the project, run `make menuconfig` (or `idf.py menuconfig` if using CMake build system). + +* Configure Wi-Fi or Ethernet under "Example Connection Configuration" menu. See "Establishing Wi-Fi or Ethernet Connection" section in [examples/protocols/README.md](../README.md) for more details. + +* When using Make build system, set `Default serial port` under `Serial flasher config`. IF you want to test the OpenSSL server demo: 1. compile the code and load the firmware diff --git a/examples/protocols/openssl_server/main/Kconfig.projbuild b/examples/protocols/openssl_server/main/Kconfig.projbuild deleted file mode 100644 index ed4e691688..0000000000 --- a/examples/protocols/openssl_server/main/Kconfig.projbuild +++ /dev/null @@ -1,15 +0,0 @@ -menu "Example Configuration" - - config WIFI_SSID - string "WiFi SSID" - default "myssid" - help - SSID (network name) for the example to connect to. - - config WIFI_PASSWORD - string "WiFi Password" - default "mypassword" - help - WiFi password (WPA or WPA2) for the example to use. - -endmenu diff --git a/examples/protocols/openssl_server/main/openssl_server_example.h b/examples/protocols/openssl_server/main/openssl_server_example.h index 8097b2b741..39276f9368 100644 --- a/examples/protocols/openssl_server/main/openssl_server_example.h +++ b/examples/protocols/openssl_server/main/openssl_server_example.h @@ -12,15 +12,6 @@ #include "sdkconfig.h" -/* The examples use simple WiFi configuration that you can set via - 'make menuconfig'. - - If you'd rather not, just change the below entries to strings with - the config you want - ie #define EXAMPLE_WIFI_SSID "mywifissid" -*/ -#define EXAMPLE_WIFI_SSID CONFIG_WIFI_SSID -#define EXAMPLE_WIFI_PASS CONFIG_WIFI_PASSWORD - #define OPENSSL_EXAMPLE_TASK_NAME "openssl_example" #define OPENSSL_EXAMPLE_TASK_STACK_WORDS 10240 #define OPENSSL_EXAMPLE_TASK_PRIORITY 8 diff --git a/examples/protocols/openssl_server/main/openssl_server_example_main.c b/examples/protocols/openssl_server/main/openssl_server_example_main.c index df3e0f7c0c..9db6fc04f0 100644 --- a/examples/protocols/openssl_server/main/openssl_server_example_main.c +++ b/examples/protocols/openssl_server/main/openssl_server_example_main.c @@ -15,23 +15,17 @@ #include "freertos/FreeRTOS.h" #include "freertos/task.h" -#include "freertos/event_groups.h" #include "esp_log.h" #include "esp_wifi.h" -#include "esp_event_loop.h" - +#include "esp_event.h" +#include "tcpip_adapter.h" #include "nvs_flash.h" +#include "protocol_examples_common.h" #include "lwip/sockets.h" #include "lwip/netdb.h" -static EventGroupHandle_t wifi_event_group; - -/* The event group allows multiple bits for each event, - but we only care about one event - are we connected - to the AP with an IP? */ -const static int CONNECTED_BIT = BIT0; const static char *TAG = "Openssl_example"; @@ -211,50 +205,17 @@ static void openssl_server_init(void) } } -static esp_err_t wifi_event_handler(void *ctx, system_event_t *event) -{ - switch(event->event_id) { - case SYSTEM_EVENT_STA_START: - esp_wifi_connect(); - break; - case SYSTEM_EVENT_STA_GOT_IP: - xEventGroupSetBits(wifi_event_group, CONNECTED_BIT); - openssl_server_init(); - break; - case SYSTEM_EVENT_STA_DISCONNECTED: - /* This is a workaround as ESP32 WiFi libs don't currently - auto-reassociate. */ - esp_wifi_connect(); - xEventGroupClearBits(wifi_event_group, CONNECTED_BIT); - break; - default: - break; - } - return ESP_OK; -} - -static void wifi_conn_init(void) -{ - tcpip_adapter_init(); - wifi_event_group = xEventGroupCreate(); - ESP_ERROR_CHECK( esp_event_loop_init(wifi_event_handler, NULL) ); - wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); - ESP_ERROR_CHECK( esp_wifi_init(&cfg) ); - ESP_ERROR_CHECK( esp_wifi_set_storage(WIFI_STORAGE_RAM) ); - wifi_config_t wifi_config = { - .sta = { - .ssid = EXAMPLE_WIFI_SSID, - .password = EXAMPLE_WIFI_PASS, - }, - }; - ESP_ERROR_CHECK( esp_wifi_set_mode(WIFI_MODE_STA) ); - ESP_ERROR_CHECK( esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config) ); - ESP_LOGI(TAG, "start the WIFI SSID:[%s] password:[%s]\n", EXAMPLE_WIFI_SSID, EXAMPLE_WIFI_PASS); - ESP_ERROR_CHECK( esp_wifi_start() ); -} - void app_main(void) { - ESP_ERROR_CHECK( nvs_flash_init() ); - wifi_conn_init(); + ESP_ERROR_CHECK(nvs_flash_init()); + tcpip_adapter_init(); + ESP_ERROR_CHECK(esp_event_loop_create_default()); + + /* This helper function configures Wi-Fi or Ethernet, as selected in menuconfig. + * Read "Establishing Wi-Fi or Ethernet Connection" section in + * examples/protocols/README.md for more information about this function. + */ + ESP_ERROR_CHECK(example_connect()); + + openssl_server_init(); } diff --git a/examples/protocols/sntp/CMakeLists.txt b/examples/protocols/sntp/CMakeLists.txt index dd46b088b1..48ca89b291 100644 --- a/examples/protocols/sntp/CMakeLists.txt +++ b/examples/protocols/sntp/CMakeLists.txt @@ -2,5 +2,9 @@ # in this exact order for cmake to work correctly cmake_minimum_required(VERSION 3.5) +# (Not part of the boilerplate) +# This example uses an extra component for common functions such as Wi-Fi and Ethernet connection. +set(EXTRA_COMPONENT_DIRS $ENV{IDF_PATH}/examples/common_components/protocol_examples_common) + include($ENV{IDF_PATH}/tools/cmake/project.cmake) project(sntp) diff --git a/examples/protocols/sntp/Makefile b/examples/protocols/sntp/Makefile index e6ef17be14..d3e9a53f15 100644 --- a/examples/protocols/sntp/Makefile +++ b/examples/protocols/sntp/Makefile @@ -5,5 +5,7 @@ PROJECT_NAME := sntp +EXTRA_COMPONENT_DIRS = $(IDF_PATH)/examples/common_components/protocol_examples_common + include $(IDF_PATH)/make/project.mk diff --git a/examples/protocols/sntp/README.md b/examples/protocols/sntp/README.md index 52db973b85..a336b2b9be 100644 --- a/examples/protocols/sntp/README.md +++ b/examples/protocols/sntp/README.md @@ -2,6 +2,14 @@ This example demonstrates the use of LwIP SNTP module to obtain time from Internet servers. See the README.md file in the upper level 'examples' directory for more information about examples. +## Configuring the Example + +To configure the project, run `make menuconfig` (or `idf.py menuconfig` if using CMake build system). + +* Configure Wi-Fi or Ethernet under "Example Connection Configuration" menu. See "Establishing Wi-Fi or Ethernet Connection" section in [examples/protocols/README.md](../README.md) for more details. + +* When using Make build system, set `Default serial port` under `Serial flasher config`. + ## Obtaining time using LwIP SNTP module When this example boots first time after ESP32 is reset, it connects to WiFi and obtains time using SNTP. diff --git a/examples/protocols/sntp/main/Kconfig.projbuild b/examples/protocols/sntp/main/Kconfig.projbuild deleted file mode 100644 index 803ab080a8..0000000000 --- a/examples/protocols/sntp/main/Kconfig.projbuild +++ /dev/null @@ -1,17 +0,0 @@ -menu "Example Configuration" - - config WIFI_SSID - string "WiFi SSID" - default "myssid" - help - SSID (network name) for the example to connect to. - - config WIFI_PASSWORD - string "WiFi Password" - default "mypassword" - help - WiFi password (WPA or WPA2) for the example to use. - - Can be left blank if the network has no security set. - -endmenu diff --git a/examples/protocols/sntp/main/sntp_example_main.c b/examples/protocols/sntp/main/sntp_example_main.c index 0cfdeb7a58..bf504bfce8 100644 --- a/examples/protocols/sntp/main/sntp_example_main.c +++ b/examples/protocols/sntp/main/sntp_example_main.c @@ -13,33 +13,16 @@ #include "freertos/task.h" #include "freertos/event_groups.h" #include "esp_system.h" -#include "esp_wifi.h" -#include "esp_event_loop.h" +#include "esp_event.h" #include "esp_log.h" #include "esp_attr.h" #include "esp_sleep.h" #include "nvs_flash.h" +#include "protocol_examples_common.h" #include "lwip/err.h" #include "lwip/apps/sntp.h" -/* The examples use simple WiFi configuration that you can set via - 'make menuconfig'. - - If you'd rather not, just change the below entries to strings with - the config you want - ie #define EXAMPLE_WIFI_SSID "mywifissid" -*/ -#define EXAMPLE_WIFI_SSID CONFIG_WIFI_SSID -#define EXAMPLE_WIFI_PASS CONFIG_WIFI_PASSWORD - -/* FreeRTOS event group to signal when we are connected & ready to make a request */ -static EventGroupHandle_t wifi_event_group; - -/* The event group allows multiple bits for each event, - but we only care about one event - are we connected - to the AP with an IP? */ -const int CONNECTED_BIT = BIT0; - static const char *TAG = "example"; /* Variable holding number of times ESP32 restarted since first boot. @@ -50,8 +33,6 @@ RTC_DATA_ATTR static int boot_count = 0; static void obtain_time(void); static void initialize_sntp(void); -static void initialise_wifi(void); -static esp_err_t event_handler(void *ctx, system_event_t *event); void app_main() @@ -94,9 +75,15 @@ void app_main() static void obtain_time(void) { ESP_ERROR_CHECK( nvs_flash_init() ); - initialise_wifi(); - xEventGroupWaitBits(wifi_event_group, CONNECTED_BIT, - false, true, portMAX_DELAY); + tcpip_adapter_init(); + ESP_ERROR_CHECK( esp_event_loop_create_default() ); + + /* This helper function configures Wi-Fi or Ethernet, as selected in menuconfig. + * Read "Establishing Wi-Fi or Ethernet Connection" section in + * examples/protocols/README.md for more information about this function. + */ + ESP_ERROR_CHECK(example_connect()); + initialize_sntp(); // wait for time to be set @@ -111,7 +98,7 @@ static void obtain_time(void) localtime_r(&now, &timeinfo); } - ESP_ERROR_CHECK( esp_wifi_stop() ); + ESP_ERROR_CHECK( example_disconnect() ); } static void initialize_sntp(void) @@ -121,44 +108,3 @@ static void initialize_sntp(void) sntp_setservername(0, "pool.ntp.org"); sntp_init(); } - -static void initialise_wifi(void) -{ - tcpip_adapter_init(); - wifi_event_group = xEventGroupCreate(); - ESP_ERROR_CHECK( esp_event_loop_init(event_handler, NULL) ); - wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); - ESP_ERROR_CHECK( esp_wifi_init(&cfg) ); - ESP_ERROR_CHECK( esp_wifi_set_storage(WIFI_STORAGE_RAM) ); - wifi_config_t wifi_config = { - .sta = { - .ssid = EXAMPLE_WIFI_SSID, - .password = EXAMPLE_WIFI_PASS, - }, - }; - ESP_LOGI(TAG, "Setting WiFi configuration SSID %s...", wifi_config.sta.ssid); - ESP_ERROR_CHECK( esp_wifi_set_mode(WIFI_MODE_STA) ); - ESP_ERROR_CHECK( esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config) ); - ESP_ERROR_CHECK( esp_wifi_start() ); -} - -static esp_err_t event_handler(void *ctx, system_event_t *event) -{ - switch(event->event_id) { - case SYSTEM_EVENT_STA_START: - esp_wifi_connect(); - break; - case SYSTEM_EVENT_STA_GOT_IP: - xEventGroupSetBits(wifi_event_group, CONNECTED_BIT); - break; - case SYSTEM_EVENT_STA_DISCONNECTED: - /* This is a workaround as ESP32 WiFi libs don't currently - auto-reassociate. */ - esp_wifi_connect(); - xEventGroupClearBits(wifi_event_group, CONNECTED_BIT); - break; - default: - break; - } - return ESP_OK; -} diff --git a/examples/protocols/sockets/tcp_client/CMakeLists.txt b/examples/protocols/sockets/tcp_client/CMakeLists.txt index 22aa37f1c1..aee70cad5e 100644 --- a/examples/protocols/sockets/tcp_client/CMakeLists.txt +++ b/examples/protocols/sockets/tcp_client/CMakeLists.txt @@ -2,5 +2,9 @@ # CMakeLists in this exact order for cmake to work correctly cmake_minimum_required(VERSION 3.5) +# (Not part of the boilerplate) +# This example uses an extra component for common functions such as Wi-Fi and Ethernet connection. +set(EXTRA_COMPONENT_DIRS $ENV{IDF_PATH}/examples/common_components/protocol_examples_common) + include($ENV{IDF_PATH}/tools/cmake/project.cmake) project(tcp_client) diff --git a/examples/protocols/sockets/tcp_client/Makefile b/examples/protocols/sockets/tcp_client/Makefile index b390190f28..eee056b3d3 100644 --- a/examples/protocols/sockets/tcp_client/Makefile +++ b/examples/protocols/sockets/tcp_client/Makefile @@ -5,5 +5,7 @@ PROJECT_NAME := tcp_client +EXTRA_COMPONENT_DIRS = $(IDF_PATH)/examples/common_components/protocol_examples_common + include $(IDF_PATH)/make/project.mk diff --git a/examples/protocols/sockets/tcp_client/README.md b/examples/protocols/sockets/tcp_client/README.md index be9e9f2d4b..415dea814e 100644 --- a/examples/protocols/sockets/tcp_client/README.md +++ b/examples/protocols/sockets/tcp_client/README.md @@ -44,10 +44,6 @@ Set following parameter under Serial Flasher Options: Set following parameters under Example Configuration Options: -* Set `WiFi SSID` of the Router (Access-Point). - -* Set `WiFi Password` of the Router (Access-Point). - * Set `IP version` of example to be IPV4 or IPV6. * Set `IPV4 Address` in case your chose IP version IPV4 above. @@ -56,6 +52,8 @@ Set following parameters under Example Configuration Options: * Set `Port` number that represents remote port the example will connect to. +Configure Wi-Fi or Ethernet under "Example Connection Configuration" menu. See "Establishing Wi-Fi or Ethernet Connection" section in [examples/protocols/README.md](../../README.md) for more details. + ## Build and Flash Build the project and flash it to the board, then run monitor tool to view serial output: diff --git a/examples/protocols/sockets/tcp_client/main/Kconfig.projbuild b/examples/protocols/sockets/tcp_client/main/Kconfig.projbuild index 9f0298f490..beabfa6f48 100644 --- a/examples/protocols/sockets/tcp_client/main/Kconfig.projbuild +++ b/examples/protocols/sockets/tcp_client/main/Kconfig.projbuild @@ -1,18 +1,5 @@ menu "Example Configuration" - config WIFI_SSID - string "WiFi SSID" - default "myssid" - help - SSID (network name) for the example to connect to. - - config WIFI_PASSWORD - string "WiFi Password" - default "mypassword" - help - WiFi password (WPA or WPA2) for the example to use. - Can be left blank if the network has no security set. - choice EXAMPLE_IP_MODE prompt "IP Version" help diff --git a/examples/protocols/sockets/tcp_client/main/tcp_client.c b/examples/protocols/sockets/tcp_client/main/tcp_client.c index 1d2486184a..96657d7981 100644 --- a/examples/protocols/sockets/tcp_client/main/tcp_client.c +++ b/examples/protocols/sockets/tcp_client/main/tcp_client.c @@ -13,9 +13,11 @@ #include "freertos/event_groups.h" #include "esp_system.h" #include "esp_wifi.h" -#include "esp_event_loop.h" +#include "esp_event.h" #include "esp_log.h" #include "nvs_flash.h" +#include "tcpip_adapter.h" +#include "protocol_examples_common.h" #include "lwip/err.h" #include "lwip/sockets.h" @@ -23,14 +25,6 @@ #include -/* The examples use simple WiFi configuration that you can set via - 'make menuconfig'. - If you'd rather not, just change the below entries to strings with - the config you want - ie #define EXAMPLE_WIFI_SSID "mywifissid" -*/ -#define EXAMPLE_WIFI_SSID CONFIG_WIFI_SSID -#define EXAMPLE_WIFI_PASS CONFIG_WIFI_PASSWORD - #ifdef CONFIG_EXAMPLE_IPV4 #define HOST_IP_ADDR CONFIG_EXAMPLE_IPV4_ADDR #else @@ -39,77 +33,9 @@ #define PORT CONFIG_EXAMPLE_PORT -/* FreeRTOS event group to signal when we are connected & ready to make a request */ -static EventGroupHandle_t wifi_event_group; - -const int IPV4_GOTIP_BIT = BIT0; -const int IPV6_GOTIP_BIT = BIT1; - static const char *TAG = "example"; static const char *payload = "Message from ESP32 "; -static esp_err_t event_handler(void *ctx, system_event_t *event) -{ - switch (event->event_id) { - case SYSTEM_EVENT_STA_START: - esp_wifi_connect(); - ESP_LOGI(TAG, "SYSTEM_EVENT_STA_START"); - break; - case SYSTEM_EVENT_STA_CONNECTED: - /* enable ipv6 */ - tcpip_adapter_create_ip6_linklocal(TCPIP_ADAPTER_IF_STA); - break; - case SYSTEM_EVENT_STA_GOT_IP: - xEventGroupSetBits(wifi_event_group, IPV4_GOTIP_BIT); - ESP_LOGI(TAG, "SYSTEM_EVENT_STA_GOT_IP"); - break; - case SYSTEM_EVENT_STA_DISCONNECTED: - /* This is a workaround as ESP32 WiFi libs don't currently auto-reassociate. */ - esp_wifi_connect(); - xEventGroupClearBits(wifi_event_group, IPV4_GOTIP_BIT); - xEventGroupClearBits(wifi_event_group, IPV6_GOTIP_BIT); - break; - case SYSTEM_EVENT_AP_STA_GOT_IP6: - xEventGroupSetBits(wifi_event_group, IPV6_GOTIP_BIT); - ESP_LOGI(TAG, "SYSTEM_EVENT_STA_GOT_IP6"); - - char *ip6 = ip6addr_ntoa(&event->event_info.got_ip6.ip6_info.ip); - ESP_LOGI(TAG, "IPv6: %s", ip6); - default: - break; - } - return ESP_OK; -} - -static void initialise_wifi(void) -{ - tcpip_adapter_init(); - wifi_event_group = xEventGroupCreate(); - ESP_ERROR_CHECK( esp_event_loop_init(event_handler, NULL) ); - wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); - ESP_ERROR_CHECK( esp_wifi_init(&cfg) ); - ESP_ERROR_CHECK( esp_wifi_set_storage(WIFI_STORAGE_RAM) ); - wifi_config_t wifi_config = { - .sta = { - .ssid = EXAMPLE_WIFI_SSID, - .password = EXAMPLE_WIFI_PASS, - }, - }; - ESP_LOGI(TAG, "Setting WiFi configuration SSID %s...", wifi_config.sta.ssid); - ESP_ERROR_CHECK( esp_wifi_set_mode(WIFI_MODE_STA) ); - ESP_ERROR_CHECK( esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config) ); - ESP_ERROR_CHECK( esp_wifi_start() ); -} - -static void wait_for_ip() -{ - uint32_t bits = IPV4_GOTIP_BIT | IPV6_GOTIP_BIT ; - - ESP_LOGI(TAG, "Waiting for AP connection..."); - xEventGroupWaitBits(wifi_event_group, bits, false, true, portMAX_DELAY); - ESP_LOGI(TAG, "Connected to AP"); -} - static void tcp_client_task(void *pvParameters) { char rx_buffer[128]; @@ -120,21 +46,21 @@ static void tcp_client_task(void *pvParameters) while (1) { #ifdef CONFIG_EXAMPLE_IPV4 - struct sockaddr_in destAddr; - destAddr.sin_addr.s_addr = inet_addr(HOST_IP_ADDR); - destAddr.sin_family = AF_INET; - destAddr.sin_port = htons(PORT); + struct sockaddr_in dest_addr; + dest_addr.sin_addr.s_addr = inet_addr(HOST_IP_ADDR); + dest_addr.sin_family = AF_INET; + dest_addr.sin_port = htons(PORT); addr_family = AF_INET; ip_protocol = IPPROTO_IP; - inet_ntoa_r(destAddr.sin_addr, addr_str, sizeof(addr_str) - 1); + inet_ntoa_r(dest_addr.sin_addr, addr_str, sizeof(addr_str) - 1); #else // IPV6 - struct sockaddr_in6 destAddr; - inet6_aton(HOST_IP_ADDR, &destAddr.sin6_addr); - destAddr.sin6_family = AF_INET6; - destAddr.sin6_port = htons(PORT); + struct sockaddr_in6 dest_addr; + inet6_aton(HOST_IP_ADDR, &dest_addr.sin6_addr); + dest_addr.sin6_family = AF_INET6; + dest_addr.sin6_port = htons(PORT); addr_family = AF_INET6; ip_protocol = IPPROTO_IPV6; - inet6_ntoa_r(destAddr.sin6_addr, addr_str, sizeof(addr_str) - 1); + inet6_ntoa_r(dest_addr.sin6_addr, addr_str, sizeof(addr_str) - 1); #endif int sock = socket(addr_family, SOCK_STREAM, ip_protocol); @@ -142,9 +68,9 @@ static void tcp_client_task(void *pvParameters) ESP_LOGE(TAG, "Unable to create socket: errno %d", errno); break; } - ESP_LOGI(TAG, "Socket created"); + ESP_LOGI(TAG, "Socket created, connecting to %s:%d", HOST_IP_ADDR, PORT); - int err = connect(sock, (struct sockaddr *)&destAddr, sizeof(destAddr)); + int err = connect(sock, (struct sockaddr *)&dest_addr, sizeof(dest_addr)); if (err != 0) { ESP_LOGE(TAG, "Socket unable to connect: errno %d", errno); break; @@ -154,12 +80,12 @@ static void tcp_client_task(void *pvParameters) while (1) { int err = send(sock, payload, strlen(payload), 0); if (err < 0) { - ESP_LOGE(TAG, "Error occured during sending: errno %d", errno); + ESP_LOGE(TAG, "Error occurred during sending: errno %d", errno); break; } int len = recv(sock, rx_buffer, sizeof(rx_buffer) - 1, 0); - // Error occured during receiving + // Error occurred during receiving if (len < 0) { ESP_LOGE(TAG, "recv failed: errno %d", errno); break; @@ -185,9 +111,15 @@ static void tcp_client_task(void *pvParameters) void app_main() { - ESP_ERROR_CHECK( nvs_flash_init() ); - initialise_wifi(); - wait_for_ip(); + ESP_ERROR_CHECK(nvs_flash_init()); + tcpip_adapter_init(); + ESP_ERROR_CHECK(esp_event_loop_create_default()); + + /* This helper function configures Wi-Fi or Ethernet, as selected in menuconfig. + * Read "Establishing Wi-Fi or Ethernet Connection" section in + * examples/protocols/README.md for more information about this function. + */ + ESP_ERROR_CHECK(example_connect()); xTaskCreate(tcp_client_task, "tcp_client", 4096, NULL, 5, NULL); } diff --git a/examples/protocols/sockets/tcp_server/CMakeLists.txt b/examples/protocols/sockets/tcp_server/CMakeLists.txt index 3514e60fce..9865464bd8 100644 --- a/examples/protocols/sockets/tcp_server/CMakeLists.txt +++ b/examples/protocols/sockets/tcp_server/CMakeLists.txt @@ -2,5 +2,9 @@ # CMakeLists in this exact order for cmake to work correctly cmake_minimum_required(VERSION 3.5) +# (Not part of the boilerplate) +# This example uses an extra component for common functions such as Wi-Fi and Ethernet connection. +set(EXTRA_COMPONENT_DIRS $ENV{IDF_PATH}/examples/common_components/protocol_examples_common) + include($ENV{IDF_PATH}/tools/cmake/project.cmake) project(tcp_server) diff --git a/examples/protocols/sockets/tcp_server/Makefile b/examples/protocols/sockets/tcp_server/Makefile index e965b90930..ccdc6d5416 100644 --- a/examples/protocols/sockets/tcp_server/Makefile +++ b/examples/protocols/sockets/tcp_server/Makefile @@ -5,5 +5,7 @@ PROJECT_NAME := tcp_server +EXTRA_COMPONENT_DIRS = $(IDF_PATH)/examples/common_components/protocol_examples_common + include $(IDF_PATH)/make/project.mk diff --git a/examples/protocols/sockets/tcp_server/README.md b/examples/protocols/sockets/tcp_server/README.md index f43dc0791b..ce47646c98 100644 --- a/examples/protocols/sockets/tcp_server/README.md +++ b/examples/protocols/sockets/tcp_server/README.md @@ -46,14 +46,12 @@ Set following parameter under Serial Flasher Options: Set following parameters under Example Configuration Options: -* Set `WiFi SSID` of the Router (Access-Point). - -* Set `WiFi Password` of the Router (Access-Point). - * Set `IP version` of the example to be IPV4 or IPV6. * Set `Port` number of the socket, that server example will create. +Configure Wi-Fi or Ethernet under "Example Connection Configuration" menu. See "Establishing Wi-Fi or Ethernet Connection" section in [examples/protocols/README.md](../../README.md) for more details. + ## Build and Flash Build the project and flash it to the board, then run monitor tool to view serial output: diff --git a/examples/protocols/sockets/tcp_server/main/Kconfig.projbuild b/examples/protocols/sockets/tcp_server/main/Kconfig.projbuild index 45a00225cd..822c019be7 100644 --- a/examples/protocols/sockets/tcp_server/main/Kconfig.projbuild +++ b/examples/protocols/sockets/tcp_server/main/Kconfig.projbuild @@ -1,18 +1,5 @@ menu "Example Configuration" - config WIFI_SSID - string "WiFi SSID" - default "myssid" - help - SSID (network name) for the example to connect to. - - config WIFI_PASSWORD - string "WiFi Password" - default "mypassword" - help - WiFi password (WPA or WPA2) for the example to use. - Can be left blank if the network has no security set. - choice EXAMPLE_IP_MODE prompt "IP Version" help @@ -23,6 +10,7 @@ menu "Example Configuration" config EXAMPLE_IPV6 bool "IPV6" + select EXAMPLE_CONNECT_IPV6 endchoice diff --git a/examples/protocols/sockets/tcp_server/main/tcp_server.c b/examples/protocols/sockets/tcp_server/main/tcp_server.c index 4f2c07d327..1e71096dce 100644 --- a/examples/protocols/sockets/tcp_server/main/tcp_server.c +++ b/examples/protocols/sockets/tcp_server/main/tcp_server.c @@ -10,12 +10,13 @@ #include #include "freertos/FreeRTOS.h" #include "freertos/task.h" -#include "freertos/event_groups.h" #include "esp_system.h" #include "esp_wifi.h" -#include "esp_event_loop.h" +#include "esp_event.h" #include "esp_log.h" #include "nvs_flash.h" +#include "tcpip_adapter.h" +#include "protocol_examples_common.h" #include "lwip/err.h" #include "lwip/sockets.h" @@ -23,85 +24,10 @@ #include -/* The examples use simple WiFi configuration that you can set via - 'make menuconfig'. - If you'd rather not, just change the below entries to strings with - the config you want - ie #define EXAMPLE_WIFI_SSID "mywifissid" -*/ -#define EXAMPLE_WIFI_SSID CONFIG_WIFI_SSID -#define EXAMPLE_WIFI_PASS CONFIG_WIFI_PASSWORD - #define PORT CONFIG_EXAMPLE_PORT -/* FreeRTOS event group to signal when we are connected & ready to make a request */ -static EventGroupHandle_t wifi_event_group; - -const int IPV4_GOTIP_BIT = BIT0; -const int IPV6_GOTIP_BIT = BIT1; - static const char *TAG = "example"; -static esp_err_t event_handler(void *ctx, system_event_t *event) -{ - switch (event->event_id) { - case SYSTEM_EVENT_STA_START: - esp_wifi_connect(); - ESP_LOGI(TAG, "SYSTEM_EVENT_STA_START"); - break; - case SYSTEM_EVENT_STA_CONNECTED: - /* enable ipv6 */ - tcpip_adapter_create_ip6_linklocal(TCPIP_ADAPTER_IF_STA); - break; - case SYSTEM_EVENT_STA_GOT_IP: - xEventGroupSetBits(wifi_event_group, IPV4_GOTIP_BIT); - ESP_LOGI(TAG, "SYSTEM_EVENT_STA_GOT_IP"); - break; - case SYSTEM_EVENT_STA_DISCONNECTED: - /* This is a workaround as ESP32 WiFi libs don't currently auto-reassociate. */ - esp_wifi_connect(); - xEventGroupClearBits(wifi_event_group, IPV4_GOTIP_BIT); - xEventGroupClearBits(wifi_event_group, IPV6_GOTIP_BIT); - break; - case SYSTEM_EVENT_AP_STA_GOT_IP6: - xEventGroupSetBits(wifi_event_group, IPV6_GOTIP_BIT); - ESP_LOGI(TAG, "SYSTEM_EVENT_STA_GOT_IP6"); - - char *ip6 = ip6addr_ntoa(&event->event_info.got_ip6.ip6_info.ip); - ESP_LOGI(TAG, "IPv6: %s", ip6); - default: - break; - } - return ESP_OK; -} - -static void initialise_wifi(void) -{ - tcpip_adapter_init(); - wifi_event_group = xEventGroupCreate(); - ESP_ERROR_CHECK( esp_event_loop_init(event_handler, NULL) ); - wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); - ESP_ERROR_CHECK( esp_wifi_init(&cfg) ); - ESP_ERROR_CHECK( esp_wifi_set_storage(WIFI_STORAGE_RAM) ); - wifi_config_t wifi_config = { - .sta = { - .ssid = EXAMPLE_WIFI_SSID, - .password = EXAMPLE_WIFI_PASS, - }, - }; - ESP_LOGI(TAG, "Setting WiFi configuration SSID %s...", wifi_config.sta.ssid); - ESP_ERROR_CHECK( esp_wifi_set_mode(WIFI_MODE_STA) ); - ESP_ERROR_CHECK( esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config) ); - ESP_ERROR_CHECK( esp_wifi_start() ); -} - -static void wait_for_ip() -{ - uint32_t bits = IPV4_GOTIP_BIT | IPV6_GOTIP_BIT ; - - ESP_LOGI(TAG, "Waiting for AP connection..."); - xEventGroupWaitBits(wifi_event_group, bits, false, true, portMAX_DELAY); - ESP_LOGI(TAG, "Connected to AP"); -} static void tcp_server_task(void *pvParameters) { @@ -113,21 +39,21 @@ static void tcp_server_task(void *pvParameters) while (1) { #ifdef CONFIG_EXAMPLE_IPV4 - struct sockaddr_in destAddr; - destAddr.sin_addr.s_addr = htonl(INADDR_ANY); - destAddr.sin_family = AF_INET; - destAddr.sin_port = htons(PORT); + struct sockaddr_in dest_addr; + dest_addr.sin_addr.s_addr = htonl(INADDR_ANY); + dest_addr.sin_family = AF_INET; + dest_addr.sin_port = htons(PORT); addr_family = AF_INET; ip_protocol = IPPROTO_IP; - inet_ntoa_r(destAddr.sin_addr, addr_str, sizeof(addr_str) - 1); + inet_ntoa_r(dest_addr.sin_addr, addr_str, sizeof(addr_str) - 1); #else // IPV6 - struct sockaddr_in6 destAddr; - bzero(&destAddr.sin6_addr.un, sizeof(destAddr.sin6_addr.un)); - destAddr.sin6_family = AF_INET6; - destAddr.sin6_port = htons(PORT); + struct sockaddr_in6 dest_addr; + bzero(&dest_addr.sin6_addr.un, sizeof(dest_addr.sin6_addr.un)); + dest_addr.sin6_family = AF_INET6; + dest_addr.sin6_port = htons(PORT); addr_family = AF_INET6; ip_protocol = IPPROTO_IPV6; - inet6_ntoa_r(destAddr.sin6_addr, addr_str, sizeof(addr_str) - 1); + inet6_ntoa_r(dest_addr.sin6_addr, addr_str, sizeof(addr_str) - 1); #endif int listen_sock = socket(addr_family, SOCK_STREAM, ip_protocol); @@ -137,23 +63,23 @@ static void tcp_server_task(void *pvParameters) } ESP_LOGI(TAG, "Socket created"); - int err = bind(listen_sock, (struct sockaddr *)&destAddr, sizeof(destAddr)); + int err = bind(listen_sock, (struct sockaddr *)&dest_addr, sizeof(dest_addr)); if (err != 0) { ESP_LOGE(TAG, "Socket unable to bind: errno %d", errno); break; } - ESP_LOGI(TAG, "Socket binded"); + ESP_LOGI(TAG, "Socket bound, port %d", PORT); err = listen(listen_sock, 1); if (err != 0) { - ESP_LOGE(TAG, "Error occured during listen: errno %d", errno); + ESP_LOGE(TAG, "Error occurred during listen: errno %d", errno); break; } ESP_LOGI(TAG, "Socket listening"); - struct sockaddr_in6 sourceAddr; // Large enough for both IPv4 or IPv6 - uint addrLen = sizeof(sourceAddr); - int sock = accept(listen_sock, (struct sockaddr *)&sourceAddr, &addrLen); + struct sockaddr_in6 source_addr; // Large enough for both IPv4 or IPv6 + uint addr_len = sizeof(source_addr); + int sock = accept(listen_sock, (struct sockaddr *)&source_addr, &addr_len); if (sock < 0) { ESP_LOGE(TAG, "Unable to accept connection: errno %d", errno); break; @@ -162,7 +88,7 @@ static void tcp_server_task(void *pvParameters) while (1) { int len = recv(sock, rx_buffer, sizeof(rx_buffer) - 1, 0); - // Error occured during receiving + // Error occurred during receiving if (len < 0) { ESP_LOGE(TAG, "recv failed: errno %d", errno); break; @@ -175,10 +101,10 @@ static void tcp_server_task(void *pvParameters) // Data received else { // Get the sender's ip address as string - if (sourceAddr.sin6_family == PF_INET) { - inet_ntoa_r(((struct sockaddr_in *)&sourceAddr)->sin_addr.s_addr, addr_str, sizeof(addr_str) - 1); - } else if (sourceAddr.sin6_family == PF_INET6) { - inet6_ntoa_r(sourceAddr.sin6_addr, addr_str, sizeof(addr_str) - 1); + if (source_addr.sin6_family == PF_INET) { + inet_ntoa_r(((struct sockaddr_in *)&source_addr)->sin_addr.s_addr, addr_str, sizeof(addr_str) - 1); + } else if (source_addr.sin6_family == PF_INET6) { + inet6_ntoa_r(source_addr.sin6_addr, addr_str, sizeof(addr_str) - 1); } rx_buffer[len] = 0; // Null-terminate whatever we received and treat like a string @@ -187,7 +113,7 @@ static void tcp_server_task(void *pvParameters) int err = send(sock, rx_buffer, len, 0); if (err < 0) { - ESP_LOGE(TAG, "Error occured during sending: errno %d", errno); + ESP_LOGE(TAG, "Error occurred during sending: errno %d", errno); break; } } @@ -204,9 +130,15 @@ static void tcp_server_task(void *pvParameters) void app_main() { - ESP_ERROR_CHECK( nvs_flash_init() ); - initialise_wifi(); - wait_for_ip(); + ESP_ERROR_CHECK(nvs_flash_init()); + tcpip_adapter_init(); + ESP_ERROR_CHECK(esp_event_loop_create_default()); + + /* This helper function configures Wi-Fi or Ethernet, as selected in menuconfig. + * Read "Establishing Wi-Fi or Ethernet Connection" section in + * examples/protocols/README.md for more information about this function. + */ + ESP_ERROR_CHECK(example_connect()); xTaskCreate(tcp_server_task, "tcp_server", 4096, NULL, 5, NULL); } diff --git a/examples/protocols/sockets/udp_client/CMakeLists.txt b/examples/protocols/sockets/udp_client/CMakeLists.txt index ee1d3f532f..2049b81939 100644 --- a/examples/protocols/sockets/udp_client/CMakeLists.txt +++ b/examples/protocols/sockets/udp_client/CMakeLists.txt @@ -2,5 +2,9 @@ # CMakeLists in this exact order for cmake to work correctly cmake_minimum_required(VERSION 3.5) +# (Not part of the boilerplate) +# This example uses an extra component for common functions such as Wi-Fi and Ethernet connection. +set(EXTRA_COMPONENT_DIRS $ENV{IDF_PATH}/examples/common_components/protocol_examples_common) + include($ENV{IDF_PATH}/tools/cmake/project.cmake) project(udp_client) diff --git a/examples/protocols/sockets/udp_client/Makefile b/examples/protocols/sockets/udp_client/Makefile index 34849eee2d..604aa5af36 100644 --- a/examples/protocols/sockets/udp_client/Makefile +++ b/examples/protocols/sockets/udp_client/Makefile @@ -5,5 +5,7 @@ PROJECT_NAME := udp_client +EXTRA_COMPONENT_DIRS = $(IDF_PATH)/examples/common_components/protocol_examples_common + include $(IDF_PATH)/make/project.mk diff --git a/examples/protocols/sockets/udp_client/README.md b/examples/protocols/sockets/udp_client/README.md index 80994e2c02..7232fb9f45 100644 --- a/examples/protocols/sockets/udp_client/README.md +++ b/examples/protocols/sockets/udp_client/README.md @@ -54,10 +54,6 @@ Set following parameter under Serial Flasher Options: Set following parameters under Example Configuration Options: -* Set `WiFi SSID` of the Router (Access-Point). - -* Set `WiFi Password` of the Router (Access-Point). - * Set `IP version` of example to be IPV4 or IPV6. * Set `IPV4 Address` in case your chose IP version IPV4 above. @@ -66,6 +62,9 @@ Set following parameters under Example Configuration Options: * Set `Port` number that represents remote port the example will send data and receive data from. +Configure Wi-Fi or Ethernet under "Example Connection Configuration" menu. See "Establishing Wi-Fi or Ethernet Connection" section in [examples/protocols/README.md](../../README.md) for more details. + + ## Build and Flash Build the project and flash it to the board, then run monitor tool to view serial output: diff --git a/examples/protocols/sockets/udp_client/main/Kconfig.projbuild b/examples/protocols/sockets/udp_client/main/Kconfig.projbuild index e06465e0db..d9b77d1857 100644 --- a/examples/protocols/sockets/udp_client/main/Kconfig.projbuild +++ b/examples/protocols/sockets/udp_client/main/Kconfig.projbuild @@ -1,18 +1,5 @@ menu "Example Configuration" - config WIFI_SSID - string "WiFi SSID" - default "myssid" - help - SSID (network name) for the example to connect to. - - config WIFI_PASSWORD - string "WiFi Password" - default "mypassword" - help - WiFi password (WPA or WPA2) for the example to use. - Can be left blank if the network has no security set. - choice EXAMPLE_IP_MODE prompt "IP Version" help @@ -23,6 +10,7 @@ menu "Example Configuration" config EXAMPLE_IPV6 bool "IPV6" + select EXAMPLE_CONNECT_IPV6 endchoice diff --git a/examples/protocols/sockets/udp_client/main/udp_client.c b/examples/protocols/sockets/udp_client/main/udp_client.c index 39a1d3a912..6639082a1d 100644 --- a/examples/protocols/sockets/udp_client/main/udp_client.c +++ b/examples/protocols/sockets/udp_client/main/udp_client.c @@ -13,9 +13,11 @@ #include "freertos/event_groups.h" #include "esp_system.h" #include "esp_wifi.h" -#include "esp_event_loop.h" +#include "esp_event.h" #include "esp_log.h" #include "nvs_flash.h" +#include "tcpip_adapter.h" +#include "protocol_examples_common.h" #include "lwip/err.h" #include "lwip/sockets.h" @@ -23,14 +25,6 @@ #include -/* The examples use simple WiFi configuration that you can set via - 'make menuconfig'. - If you'd rather not, just change the below entries to strings with - the config you want - ie #define EXAMPLE_WIFI_SSID "mywifissid" -*/ -#define EXAMPLE_WIFI_SSID CONFIG_WIFI_SSID -#define EXAMPLE_WIFI_PASS CONFIG_WIFI_PASSWORD - #ifdef CONFIG_EXAMPLE_IPV4 #define HOST_IP_ADDR CONFIG_EXAMPLE_IPV4_ADDR #else @@ -39,76 +33,9 @@ #define PORT CONFIG_EXAMPLE_PORT -/* FreeRTOS event group to signal when we are connected & ready to make a request */ -static EventGroupHandle_t wifi_event_group; - -const int IPV4_GOTIP_BIT = BIT0; -const int IPV6_GOTIP_BIT = BIT1; - static const char *TAG = "example"; static const char *payload = "Message from ESP32 "; -static esp_err_t event_handler(void *ctx, system_event_t *event) -{ - switch (event->event_id) { - case SYSTEM_EVENT_STA_START: - esp_wifi_connect(); - ESP_LOGI(TAG, "SYSTEM_EVENT_STA_START"); - break; - case SYSTEM_EVENT_STA_CONNECTED: - /* enable ipv6 */ - tcpip_adapter_create_ip6_linklocal(TCPIP_ADAPTER_IF_STA); - break; - case SYSTEM_EVENT_STA_GOT_IP: - xEventGroupSetBits(wifi_event_group, IPV4_GOTIP_BIT); - ESP_LOGI(TAG, "SYSTEM_EVENT_STA_GOT_IP"); - break; - case SYSTEM_EVENT_STA_DISCONNECTED: - /* This is a workaround as ESP32 WiFi libs don't currently auto-reassociate. */ - esp_wifi_connect(); - xEventGroupClearBits(wifi_event_group, IPV4_GOTIP_BIT); - xEventGroupClearBits(wifi_event_group, IPV6_GOTIP_BIT); - break; - case SYSTEM_EVENT_AP_STA_GOT_IP6: - xEventGroupSetBits(wifi_event_group, IPV6_GOTIP_BIT); - ESP_LOGI(TAG, "SYSTEM_EVENT_STA_GOT_IP6"); - - char *ip6 = ip6addr_ntoa(&event->event_info.got_ip6.ip6_info.ip); - ESP_LOGI(TAG, "IPv6: %s", ip6); - default: - break; - } - return ESP_OK; -} - -static void initialise_wifi(void) -{ - tcpip_adapter_init(); - wifi_event_group = xEventGroupCreate(); - ESP_ERROR_CHECK( esp_event_loop_init(event_handler, NULL) ); - wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); - ESP_ERROR_CHECK( esp_wifi_init(&cfg) ); - ESP_ERROR_CHECK( esp_wifi_set_storage(WIFI_STORAGE_RAM) ); - wifi_config_t wifi_config = { - .sta = { - .ssid = EXAMPLE_WIFI_SSID, - .password = EXAMPLE_WIFI_PASS, - }, - }; - ESP_LOGI(TAG, "Setting WiFi configuration SSID %s...", wifi_config.sta.ssid); - ESP_ERROR_CHECK( esp_wifi_set_mode(WIFI_MODE_STA) ); - ESP_ERROR_CHECK( esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config) ); - ESP_ERROR_CHECK( esp_wifi_start() ); -} - -static void wait_for_ip() -{ - uint32_t bits = IPV4_GOTIP_BIT | IPV6_GOTIP_BIT ; - - ESP_LOGI(TAG, "Waiting for AP connection..."); - xEventGroupWaitBits(wifi_event_group, bits, false, true, portMAX_DELAY); - ESP_LOGI(TAG, "Connected to AP"); -} static void udp_client_task(void *pvParameters) { @@ -120,21 +47,21 @@ static void udp_client_task(void *pvParameters) while (1) { #ifdef CONFIG_EXAMPLE_IPV4 - struct sockaddr_in destAddr; - destAddr.sin_addr.s_addr = inet_addr(HOST_IP_ADDR); - destAddr.sin_family = AF_INET; - destAddr.sin_port = htons(PORT); + struct sockaddr_in dest_addr; + dest_addr.sin_addr.s_addr = inet_addr(HOST_IP_ADDR); + dest_addr.sin_family = AF_INET; + dest_addr.sin_port = htons(PORT); addr_family = AF_INET; ip_protocol = IPPROTO_IP; - inet_ntoa_r(destAddr.sin_addr, addr_str, sizeof(addr_str) - 1); + inet_ntoa_r(dest_addr.sin_addr, addr_str, sizeof(addr_str) - 1); #else // IPV6 - struct sockaddr_in6 destAddr; - inet6_aton(HOST_IP_ADDR, &destAddr.sin6_addr); - destAddr.sin6_family = AF_INET6; - destAddr.sin6_port = htons(PORT); + struct sockaddr_in6 dest_addr; + inet6_aton(HOST_IP_ADDR, &dest_addr.sin6_addr); + dest_addr.sin6_family = AF_INET6; + dest_addr.sin6_port = htons(PORT); addr_family = AF_INET6; ip_protocol = IPPROTO_IPV6; - inet6_ntoa_r(destAddr.sin6_addr, addr_str, sizeof(addr_str) - 1); + inet6_ntoa_r(dest_addr.sin6_addr, addr_str, sizeof(addr_str) - 1); #endif int sock = socket(addr_family, SOCK_DGRAM, ip_protocol); @@ -142,22 +69,22 @@ static void udp_client_task(void *pvParameters) ESP_LOGE(TAG, "Unable to create socket: errno %d", errno); break; } - ESP_LOGI(TAG, "Socket created"); + ESP_LOGI(TAG, "Socket created, sending to %s:%d", HOST_IP_ADDR, PORT); while (1) { - int err = sendto(sock, payload, strlen(payload), 0, (struct sockaddr *)&destAddr, sizeof(destAddr)); + int err = sendto(sock, payload, strlen(payload), 0, (struct sockaddr *)&dest_addr, sizeof(dest_addr)); if (err < 0) { - ESP_LOGE(TAG, "Error occured during sending: errno %d", errno); + ESP_LOGE(TAG, "Error occurred during sending: errno %d", errno); break; } ESP_LOGI(TAG, "Message sent"); - struct sockaddr_in sourceAddr; // Large enough for both IPv4 or IPv6 - socklen_t socklen = sizeof(sourceAddr); - int len = recvfrom(sock, rx_buffer, sizeof(rx_buffer) - 1, 0, (struct sockaddr *)&sourceAddr, &socklen); + struct sockaddr_in source_addr; // Large enough for both IPv4 or IPv6 + socklen_t socklen = sizeof(source_addr); + int len = recvfrom(sock, rx_buffer, sizeof(rx_buffer) - 1, 0, (struct sockaddr *)&source_addr, &socklen); - // Error occured during receiving + // Error occurred during receiving if (len < 0) { ESP_LOGE(TAG, "recvfrom failed: errno %d", errno); break; @@ -183,9 +110,15 @@ static void udp_client_task(void *pvParameters) void app_main() { - ESP_ERROR_CHECK( nvs_flash_init() ); - initialise_wifi(); - wait_for_ip(); + ESP_ERROR_CHECK(nvs_flash_init()); + tcpip_adapter_init(); + ESP_ERROR_CHECK(esp_event_loop_create_default()); + + /* This helper function configures Wi-Fi or Ethernet, as selected in menuconfig. + * Read "Establishing Wi-Fi or Ethernet Connection" section in + * examples/protocols/README.md for more information about this function. + */ + ESP_ERROR_CHECK(example_connect()); xTaskCreate(udp_client_task, "udp_client", 4096, NULL, 5, NULL); } diff --git a/examples/protocols/sockets/udp_multicast/CMakeLists.txt b/examples/protocols/sockets/udp_multicast/CMakeLists.txt index fe4b8fe8ef..f89b3347a2 100644 --- a/examples/protocols/sockets/udp_multicast/CMakeLists.txt +++ b/examples/protocols/sockets/udp_multicast/CMakeLists.txt @@ -2,5 +2,9 @@ # in this exact order for cmake to work correctly cmake_minimum_required(VERSION 3.5) +# (Not part of the boilerplate) +# This example uses an extra component for common functions such as Wi-Fi and Ethernet connection. +set(EXTRA_COMPONENT_DIRS $ENV{IDF_PATH}/examples/common_components/protocol_examples_common) + include($ENV{IDF_PATH}/tools/cmake/project.cmake) project(udp-multicast) diff --git a/examples/protocols/sockets/udp_multicast/Makefile b/examples/protocols/sockets/udp_multicast/Makefile index 60f3d59db7..47e26b9534 100644 --- a/examples/protocols/sockets/udp_multicast/Makefile +++ b/examples/protocols/sockets/udp_multicast/Makefile @@ -5,5 +5,7 @@ PROJECT_NAME := udp-multicast +EXTRA_COMPONENT_DIRS = $(IDF_PATH)/examples/common_components/protocol_examples_common + include $(IDF_PATH)/make/project.mk diff --git a/examples/protocols/sockets/udp_multicast/README.md b/examples/protocols/sockets/udp_multicast/README.md index 8a937afc1d..7bc066db07 100644 --- a/examples/protocols/sockets/udp_multicast/README.md +++ b/examples/protocols/sockets/udp_multicast/README.md @@ -12,9 +12,12 @@ The behaviour of the example is: ## Configuration -The "Example Configuration" menu "make menuconfig" allows you to configure the details of the example: +Run `make menuconfig` (or `idf.py menuconfig` if using CMake build system). + +Configure Wi-Fi or Ethernet under "Example Connection Configuration" menu. See "Establishing Wi-Fi or Ethernet Connection" section in [examples/protocols/README.md](../../README.md) for more details. + +The "Example Configuration" menu allows you to configure the details of the example: -* WiFi SSD & Password * IP Mode: IPV4 & IPV6 dual, IPV4 only, or IPv6 only. * Multicast addresses for IPV4 and/or IPV6. * Enable multicast socket loopback (ie should the socket receive its own multicast transmissions.) diff --git a/examples/protocols/sockets/udp_multicast/main/Kconfig.projbuild b/examples/protocols/sockets/udp_multicast/main/Kconfig.projbuild index 7be2402814..99e01387b3 100644 --- a/examples/protocols/sockets/udp_multicast/main/Kconfig.projbuild +++ b/examples/protocols/sockets/udp_multicast/main/Kconfig.projbuild @@ -1,19 +1,5 @@ menu "Example Configuration" - config WIFI_SSID - string "WiFi SSID" - default "myssid" - help - SSID (network name) for the example to connect to. - - config WIFI_PASSWORD - string "WiFi Password" - default "mypassword" - help - WiFi password (WPA or WPA2) for the example to use. - - Can be left blank if the network has no security set. - choice EXAMPLE_IP_MODE prompt "Multicast IP type" help @@ -38,6 +24,7 @@ menu "Example Configuration" bool config EXAMPLE_IPV6 bool + select EXAMPLE_CONNECT_IPV6 config EXAMPLE_MULTICAST_IPV4_ADDR string "Multicast IPV4 Address (send & receive)" @@ -53,8 +40,9 @@ menu "Example Configuration" help IPV6 multicast address. Example will both send to and listen to this address. - The default FF02::FC address is a link-local multicast address. Consult IPV6 specifications or - documentation for information about meaning of different IPV6 multicast ranges. + The default FF02::FC address is a link-local multicast address. + Consult IPV6 specifications or documentation for information about + meaning of different IPV6 multicast ranges. config EXAMPLE_PORT int "Multicast port (send & receive)" @@ -78,15 +66,16 @@ menu "Example Configuration" choice EXAMPLE_MULTICAST_IF prompt "Multicast Interface" + default EXAMPLE_MULTICAST_LISTEN_DEFAULT_IF help Multicast socket can bind to default interface, or all interfaces. + config EXAMPLE_MULTICAST_LISTEN_ALL_IF + bool "All interfaces" + config EXAMPLE_MULTICAST_LISTEN_DEFAULT_IF bool "Default interface" - config EXAMPLE_MULTICAST_LISTEN_STA_IF - bool "WiFi STA interface" - endchoice endmenu diff --git a/examples/protocols/sockets/udp_multicast/main/udp_multicast_example_main.c b/examples/protocols/sockets/udp_multicast/main/udp_multicast_example_main.c index a21c24a609..e3bb742840 100644 --- a/examples/protocols/sockets/udp_multicast/main/udp_multicast_example_main.c +++ b/examples/protocols/sockets/udp_multicast/main/udp_multicast_example_main.c @@ -13,24 +13,23 @@ #include "freertos/event_groups.h" #include "esp_system.h" #include "esp_wifi.h" -#include "esp_event_loop.h" +#include "esp_event.h" #include "esp_log.h" #include "nvs_flash.h" +#include "tcpip_adapter.h" +#include "protocol_examples_common.h" #include "lwip/err.h" #include "lwip/sockets.h" #include "lwip/sys.h" #include -/* The examples use simple WiFi configuration that you can set via +/* The examples use simple configuration that you can set via 'make menuconfig'. If you'd rather not, just change the below entries to strings with - the config you want - ie #define EXAMPLE_WIFI_SSID "mywifissid" + the config you want - ie #define UDP_PORT 3333 */ -#define EXAMPLE_WIFI_SSID CONFIG_WIFI_SSID -#define EXAMPLE_WIFI_PASS CONFIG_WIFI_PASSWORD - #define UDP_PORT CONFIG_EXAMPLE_PORT #define MULTICAST_LOOPBACK CONFIG_EXAMPLE_LOOPBACK @@ -40,16 +39,7 @@ #define MULTICAST_IPV4_ADDR CONFIG_EXAMPLE_MULTICAST_IPV4_ADDR #define MULTICAST_IPV6_ADDR CONFIG_EXAMPLE_MULTICAST_IPV6_ADDR -#define LISTEN_DEFAULT_IF CONFIG_EXAMPLE_LISTEN_DEFAULT_IF - -/* FreeRTOS event group to signal when we are connected & ready to make a request */ -static EventGroupHandle_t wifi_event_group; - -/* The event group allows multiple bits for each event, - we use two - one for IPv4 "got ip", and - one for IPv6 "got ip". */ -const int IPV4_GOTIP_BIT = BIT0; -const int IPV6_GOTIP_BIT = BIT1; +#define LISTEN_ALL_IF EXAMPLE_MULTICAST_LISTEN_ALL_IF static const char *TAG = "multicast"; #ifdef CONFIG_EXAMPLE_IPV4 @@ -59,53 +49,6 @@ static const char *V4TAG = "mcast-ipv4"; static const char *V6TAG = "mcast-ipv6"; #endif -static esp_err_t event_handler(void *ctx, system_event_t *event) -{ - switch(event->event_id) { - case SYSTEM_EVENT_STA_START: - esp_wifi_connect(); - break; - case SYSTEM_EVENT_STA_CONNECTED: - /* enable ipv6 */ - tcpip_adapter_create_ip6_linklocal(TCPIP_ADAPTER_IF_STA); - break; - case SYSTEM_EVENT_STA_GOT_IP: - xEventGroupSetBits(wifi_event_group, IPV4_GOTIP_BIT); - break; - case SYSTEM_EVENT_STA_DISCONNECTED: - /* This is a workaround as ESP32 WiFi libs don't currently - auto-reassociate. */ - esp_wifi_connect(); - xEventGroupClearBits(wifi_event_group, IPV4_GOTIP_BIT); - xEventGroupClearBits(wifi_event_group, IPV6_GOTIP_BIT); - break; - case SYSTEM_EVENT_AP_STA_GOT_IP6: - xEventGroupSetBits(wifi_event_group, IPV6_GOTIP_BIT); - default: - break; - } - return ESP_OK; -} - -static void initialise_wifi(void) -{ - tcpip_adapter_init(); - wifi_event_group = xEventGroupCreate(); - ESP_ERROR_CHECK( esp_event_loop_init(event_handler, NULL) ); - wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); - ESP_ERROR_CHECK( esp_wifi_init(&cfg) ); - ESP_ERROR_CHECK( esp_wifi_set_storage(WIFI_STORAGE_RAM) ); - wifi_config_t wifi_config = { - .sta = { - .ssid = EXAMPLE_WIFI_SSID, - .password = EXAMPLE_WIFI_PASS, - }, - }; - ESP_LOGI(TAG, "Setting WiFi configuration SSID %s...", wifi_config.sta.ssid); - ESP_ERROR_CHECK( esp_wifi_set_mode(WIFI_MODE_STA) ); - ESP_ERROR_CHECK( esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config) ); - ESP_ERROR_CHECK( esp_wifi_start() ); -} #ifdef CONFIG_EXAMPLE_IPV4 /* Add a socket, either IPV4-only or IPV6 dual mode, to the IPV4 @@ -116,17 +59,17 @@ static int socket_add_ipv4_multicast_group(int sock, bool assign_source_if) struct in_addr iaddr = { 0 }; int err = 0; // Configure source interface -#if USE_DEFAULT_IF +#if LISTEN_ALL_IF imreq.imr_interface.s_addr = IPADDR_ANY; #else tcpip_adapter_ip_info_t ip_info = { 0 }; - err = tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_STA, &ip_info); + err = tcpip_adapter_get_ip_info(EXAMPLE_INTERFACE, &ip_info); if (err != ESP_OK) { ESP_LOGE(V4TAG, "Failed to get IP address info. Error 0x%x", err); goto err; } inet_addr_from_ip4addr(&iaddr, &ip_info.ip); -#endif +#endif // LISTEN_ALL_IF // Configure multicast address to listen to err = inet_aton(MULTICAST_IPV4_ADDR, &imreq.imr_multiaddr.s_addr); if (err != 1) { @@ -248,7 +191,7 @@ static int create_multicast_ipv6_socket() } // Selct the interface to use as multicast source for this socket. -#if USE_DEFAULT_IF +#if LISTEN_ALL_IF bzero(&if_inaddr.un, sizeof(if_inaddr.un)); #else // Read interface adapter link-local address and use it @@ -257,13 +200,13 @@ static int create_multicast_ipv6_socket() // (Note the interface may have other non-LL IPV6 addresses as well, // but it doesn't matter in this context as the address is only // used to identify the interface.) - err = tcpip_adapter_get_ip6_linklocal(TCPIP_ADAPTER_IF_STA, &if_ipaddr); + err = tcpip_adapter_get_ip6_linklocal(EXAMPLE_INTERFACE, &if_ipaddr); inet6_addr_from_ip6addr(&if_inaddr, &if_ipaddr); if (err != ESP_OK) { ESP_LOGE(V6TAG, "Failed to get IPV6 LL address. Error 0x%x", err); goto err; } -#endif +#endif // LISTEN_ALL_IF // Assign the multicast source interface, via its IP err = setsockopt(sock, IPPROTO_IPV6, IPV6_MULTICAST_IF, &if_inaddr, @@ -297,11 +240,11 @@ static int create_multicast_ipv6_socket() // group for listening... // Configure source interface -#if USE_DEFAULT_IF +#if LISTEN_ALL_IF v6imreq.imr_interface.s_addr = IPADDR_ANY; #else inet6_addr_from_ip6addr(&v6imreq.ipv6mr_interface, &if_ipaddr); -#endif +#endif // LISTEN_ALL_IF #ifdef CONFIG_EXAMPLE_IPV6 // Configure multicast address to listen to err = inet6_aton(MULTICAST_IPV6_ADDR, &v6imreq.ipv6mr_multiaddr); @@ -356,19 +299,6 @@ err: static void mcast_example_task(void *pvParameters) { while (1) { - /* Wait for all the IPs we care about to be set - */ - uint32_t bits = 0; -#ifdef CONFIG_EXAMPLE_IPV4 - bits |= IPV4_GOTIP_BIT; -#endif -#ifdef CONFIG_EXAMPLE_IPV6 - bits |= IPV6_GOTIP_BIT; -#endif - ESP_LOGI(TAG, "Waiting for AP connection..."); - xEventGroupWaitBits(wifi_event_group, bits, false, true, portMAX_DELAY); - ESP_LOGI(TAG, "Connected to AP"); - int sock; #ifdef CONFIG_EXAMPLE_IPV4_ONLY @@ -547,7 +477,15 @@ static void mcast_example_task(void *pvParameters) void app_main() { - ESP_ERROR_CHECK( nvs_flash_init() ); - initialise_wifi(); + ESP_ERROR_CHECK(nvs_flash_init()); + tcpip_adapter_init(); + ESP_ERROR_CHECK(esp_event_loop_create_default()); + + /* This helper function configures Wi-Fi or Ethernet, as selected in menuconfig. + * Read "Establishing Wi-Fi or Ethernet Connection" section in + * examples/protocols/README.md for more information about this function. + */ + ESP_ERROR_CHECK(example_connect()); + xTaskCreate(&mcast_example_task, "mcast_task", 4096, NULL, 5, NULL); } diff --git a/examples/protocols/sockets/udp_server/CMakeLists.txt b/examples/protocols/sockets/udp_server/CMakeLists.txt index d1edab0fc2..8614318094 100644 --- a/examples/protocols/sockets/udp_server/CMakeLists.txt +++ b/examples/protocols/sockets/udp_server/CMakeLists.txt @@ -2,5 +2,9 @@ # CMakeLists in this exact order for cmake to work correctly cmake_minimum_required(VERSION 3.5) +# (Not part of the boilerplate) +# This example uses an extra component for common functions such as Wi-Fi and Ethernet connection. +set(EXTRA_COMPONENT_DIRS $ENV{IDF_PATH}/examples/common_components/protocol_examples_common) + include($ENV{IDF_PATH}/tools/cmake/project.cmake) project(udp_server) diff --git a/examples/protocols/sockets/udp_server/Makefile b/examples/protocols/sockets/udp_server/Makefile index 36552c9bf6..bc11a43031 100644 --- a/examples/protocols/sockets/udp_server/Makefile +++ b/examples/protocols/sockets/udp_server/Makefile @@ -5,5 +5,7 @@ PROJECT_NAME := udp_server +EXTRA_COMPONENT_DIRS = $(IDF_PATH)/examples/common_components/protocol_examples_common + include $(IDF_PATH)/make/project.mk diff --git a/examples/protocols/sockets/udp_server/README.md b/examples/protocols/sockets/udp_server/README.md index 8fe64a73ed..3bf1fe370a 100644 --- a/examples/protocols/sockets/udp_server/README.md +++ b/examples/protocols/sockets/udp_server/README.md @@ -56,14 +56,12 @@ Set following parameter under Serial Flasher Options: Set following parameters under Example Configuration Options: -* Set `WiFi SSID` of the Router (Access-Point). - -* Set `WiFi Password` of the Router (Access-Point). - * Set `IP version` of the example to be IPV4 or IPV6. * Set `Port` number that represents remote port the example will create. +Configure Wi-Fi or Ethernet under "Example Connection Configuration" menu. See "Establishing Wi-Fi or Ethernet Connection" section in [examples/protocols/README.md](../../README.md) for more details. + ## Build and Flash Build the project and flash it to the board, then run monitor tool to view serial output: diff --git a/examples/protocols/sockets/udp_server/main/Kconfig.projbuild b/examples/protocols/sockets/udp_server/main/Kconfig.projbuild index 45a00225cd..822c019be7 100644 --- a/examples/protocols/sockets/udp_server/main/Kconfig.projbuild +++ b/examples/protocols/sockets/udp_server/main/Kconfig.projbuild @@ -1,18 +1,5 @@ menu "Example Configuration" - config WIFI_SSID - string "WiFi SSID" - default "myssid" - help - SSID (network name) for the example to connect to. - - config WIFI_PASSWORD - string "WiFi Password" - default "mypassword" - help - WiFi password (WPA or WPA2) for the example to use. - Can be left blank if the network has no security set. - choice EXAMPLE_IP_MODE prompt "IP Version" help @@ -23,6 +10,7 @@ menu "Example Configuration" config EXAMPLE_IPV6 bool "IPV6" + select EXAMPLE_CONNECT_IPV6 endchoice diff --git a/examples/protocols/sockets/udp_server/main/udp_server.c b/examples/protocols/sockets/udp_server/main/udp_server.c index 336388f703..ce82168323 100644 --- a/examples/protocols/sockets/udp_server/main/udp_server.c +++ b/examples/protocols/sockets/udp_server/main/udp_server.c @@ -10,99 +10,23 @@ #include #include "freertos/FreeRTOS.h" #include "freertos/task.h" -#include "freertos/event_groups.h" #include "esp_system.h" #include "esp_wifi.h" -#include "esp_event_loop.h" +#include "esp_event.h" #include "esp_log.h" #include "nvs_flash.h" +#include "tcpip_adapter.h" +#include "protocol_examples_common.h" #include "lwip/err.h" #include "lwip/sockets.h" #include "lwip/sys.h" #include - -/* The examples use simple WiFi configuration that you can set via - 'make menuconfig'. - If you'd rather not, just change the below entries to strings with - the config you want - ie #define EXAMPLE_WIFI_SSID "mywifissid" -*/ -#define EXAMPLE_WIFI_SSID CONFIG_WIFI_SSID -#define EXAMPLE_WIFI_PASS CONFIG_WIFI_PASSWORD - #define PORT CONFIG_EXAMPLE_PORT -/* FreeRTOS event group to signal when we are connected & ready to make a request */ -static EventGroupHandle_t wifi_event_group; - -const int IPV4_GOTIP_BIT = BIT0; -const int IPV6_GOTIP_BIT = BIT1; - static const char *TAG = "example"; -static esp_err_t event_handler(void *ctx, system_event_t *event) -{ - switch (event->event_id) { - case SYSTEM_EVENT_STA_START: - esp_wifi_connect(); - ESP_LOGI(TAG, "SYSTEM_EVENT_STA_START"); - break; - case SYSTEM_EVENT_STA_CONNECTED: - /* enable ipv6 */ - tcpip_adapter_create_ip6_linklocal(TCPIP_ADAPTER_IF_STA); - break; - case SYSTEM_EVENT_STA_GOT_IP: - xEventGroupSetBits(wifi_event_group, IPV4_GOTIP_BIT); - ESP_LOGI(TAG, "SYSTEM_EVENT_STA_GOT_IP"); - break; - case SYSTEM_EVENT_STA_DISCONNECTED: - /* This is a workaround as ESP32 WiFi libs don't currently auto-reassociate. */ - esp_wifi_connect(); - xEventGroupClearBits(wifi_event_group, IPV4_GOTIP_BIT); - xEventGroupClearBits(wifi_event_group, IPV6_GOTIP_BIT); - break; - case SYSTEM_EVENT_AP_STA_GOT_IP6: - xEventGroupSetBits(wifi_event_group, IPV6_GOTIP_BIT); - ESP_LOGI(TAG, "SYSTEM_EVENT_STA_GOT_IP6"); - - char *ip6 = ip6addr_ntoa(&event->event_info.got_ip6.ip6_info.ip); - ESP_LOGI(TAG, "IPv6: %s", ip6); - default: - break; - } - return ESP_OK; -} - -static void initialise_wifi(void) -{ - tcpip_adapter_init(); - wifi_event_group = xEventGroupCreate(); - ESP_ERROR_CHECK( esp_event_loop_init(event_handler, NULL) ); - wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); - ESP_ERROR_CHECK( esp_wifi_init(&cfg) ); - ESP_ERROR_CHECK( esp_wifi_set_storage(WIFI_STORAGE_RAM) ); - wifi_config_t wifi_config = { - .sta = { - .ssid = EXAMPLE_WIFI_SSID, - .password = EXAMPLE_WIFI_PASS, - }, - }; - ESP_LOGI(TAG, "Setting WiFi configuration SSID %s...", wifi_config.sta.ssid); - ESP_ERROR_CHECK( esp_wifi_set_mode(WIFI_MODE_STA) ); - ESP_ERROR_CHECK( esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config) ); - ESP_ERROR_CHECK( esp_wifi_start() ); -} - -static void wait_for_ip() -{ - uint32_t bits = IPV4_GOTIP_BIT | IPV6_GOTIP_BIT ; - - ESP_LOGI(TAG, "Waiting for AP connection..."); - xEventGroupWaitBits(wifi_event_group, bits, false, true, portMAX_DELAY); - ESP_LOGI(TAG, "Connected to AP"); -} - static void udp_server_task(void *pvParameters) { char rx_buffer[128]; @@ -113,21 +37,21 @@ static void udp_server_task(void *pvParameters) while (1) { #ifdef CONFIG_EXAMPLE_IPV4 - struct sockaddr_in destAddr; - destAddr.sin_addr.s_addr = htonl(INADDR_ANY); - destAddr.sin_family = AF_INET; - destAddr.sin_port = htons(PORT); + struct sockaddr_in dest_addr; + dest_addr.sin_addr.s_addr = htonl(INADDR_ANY); + dest_addr.sin_family = AF_INET; + dest_addr.sin_port = htons(PORT); addr_family = AF_INET; ip_protocol = IPPROTO_IP; - inet_ntoa_r(destAddr.sin_addr, addr_str, sizeof(addr_str) - 1); + inet_ntoa_r(dest_addr.sin_addr, addr_str, sizeof(addr_str) - 1); #else // IPV6 - struct sockaddr_in6 destAddr; - bzero(&destAddr.sin6_addr.un, sizeof(destAddr.sin6_addr.un)); - destAddr.sin6_family = AF_INET6; - destAddr.sin6_port = htons(PORT); + struct sockaddr_in6 dest_addr; + bzero(&dest_addr.sin6_addr.un, sizeof(dest_addr.sin6_addr.un)); + dest_addr.sin6_family = AF_INET6; + dest_addr.sin6_port = htons(PORT); addr_family = AF_INET6; ip_protocol = IPPROTO_IPV6; - inet6_ntoa_r(destAddr.sin6_addr, addr_str, sizeof(addr_str) - 1); + inet6_ntoa_r(dest_addr.sin6_addr, addr_str, sizeof(addr_str) - 1); #endif int sock = socket(addr_family, SOCK_DGRAM, ip_protocol); @@ -137,20 +61,20 @@ static void udp_server_task(void *pvParameters) } ESP_LOGI(TAG, "Socket created"); - int err = bind(sock, (struct sockaddr *)&destAddr, sizeof(destAddr)); + int err = bind(sock, (struct sockaddr *)&dest_addr, sizeof(dest_addr)); if (err < 0) { ESP_LOGE(TAG, "Socket unable to bind: errno %d", errno); } - ESP_LOGI(TAG, "Socket binded"); + ESP_LOGI(TAG, "Socket bound, port %d", PORT); while (1) { ESP_LOGI(TAG, "Waiting for data"); - struct sockaddr_in6 sourceAddr; // Large enough for both IPv4 or IPv6 - socklen_t socklen = sizeof(sourceAddr); - int len = recvfrom(sock, rx_buffer, sizeof(rx_buffer) - 1, 0, (struct sockaddr *)&sourceAddr, &socklen); + struct sockaddr_in6 source_addr; // Large enough for both IPv4 or IPv6 + socklen_t socklen = sizeof(source_addr); + int len = recvfrom(sock, rx_buffer, sizeof(rx_buffer) - 1, 0, (struct sockaddr *)&source_addr, &socklen); - // Error occured during receiving + // Error occurred during receiving if (len < 0) { ESP_LOGE(TAG, "recvfrom failed: errno %d", errno); break; @@ -158,19 +82,19 @@ static void udp_server_task(void *pvParameters) // Data received else { // Get the sender's ip address as string - if (sourceAddr.sin6_family == PF_INET) { - inet_ntoa_r(((struct sockaddr_in *)&sourceAddr)->sin_addr.s_addr, addr_str, sizeof(addr_str) - 1); - } else if (sourceAddr.sin6_family == PF_INET6) { - inet6_ntoa_r(sourceAddr.sin6_addr, addr_str, sizeof(addr_str) - 1); + if (source_addr.sin6_family == PF_INET) { + inet_ntoa_r(((struct sockaddr_in *)&source_addr)->sin_addr.s_addr, addr_str, sizeof(addr_str) - 1); + } else if (source_addr.sin6_family == PF_INET6) { + inet6_ntoa_r(source_addr.sin6_addr, addr_str, sizeof(addr_str) - 1); } rx_buffer[len] = 0; // Null-terminate whatever we received and treat like a string... ESP_LOGI(TAG, "Received %d bytes from %s:", len, addr_str); ESP_LOGI(TAG, "%s", rx_buffer); - int err = sendto(sock, rx_buffer, len, 0, (struct sockaddr *)&sourceAddr, sizeof(sourceAddr)); + int err = sendto(sock, rx_buffer, len, 0, (struct sockaddr *)&source_addr, sizeof(source_addr)); if (err < 0) { - ESP_LOGE(TAG, "Error occured during sending: errno %d", errno); + ESP_LOGE(TAG, "Error occurred during sending: errno %d", errno); break; } } @@ -187,9 +111,15 @@ static void udp_server_task(void *pvParameters) void app_main() { - ESP_ERROR_CHECK( nvs_flash_init() ); - initialise_wifi(); - wait_for_ip(); + ESP_ERROR_CHECK(nvs_flash_init()); + tcpip_adapter_init(); + ESP_ERROR_CHECK(esp_event_loop_create_default()); + + /* This helper function configures Wi-Fi or Ethernet, as selected in menuconfig. + * Read "Establishing Wi-Fi or Ethernet Connection" section in + * examples/protocols/README.md for more information about this function. + */ + ESP_ERROR_CHECK(example_connect()); xTaskCreate(udp_server_task, "udp_server", 4096, NULL, 5, NULL); } diff --git a/tools/ci/build_examples_cmake.sh b/tools/ci/build_examples_cmake.sh index 5772a81d11..25717f43a3 100755 --- a/tools/ci/build_examples_cmake.sh +++ b/tools/ci/build_examples_cmake.sh @@ -66,7 +66,7 @@ LOG_SUSPECTED=${LOG_PATH}/common_log.txt touch ${LOG_SUSPECTED} SDKCONFIG_DEFAULTS_CI=sdkconfig.ci -EXAMPLE_PATHS=$( find ${IDF_PATH}/examples/ -type f -name CMakeLists.txt | grep -v "/components/" | grep -v "/main/" | sort ) +EXAMPLE_PATHS=$( find ${IDF_PATH}/examples/ -type f -name CMakeLists.txt | grep -v "/components/" | grep -v "/common_components/" | grep -v "/main/" | sort ) if [ $# -eq 0 ] then diff --git a/tools/ci/check_examples_cmake_make.sh b/tools/ci/check_examples_cmake_make.sh index 64463ab214..ed560a21bc 100755 --- a/tools/ci/check_examples_cmake_make.sh +++ b/tools/ci/check_examples_cmake_make.sh @@ -2,7 +2,7 @@ # While we support GNU Make & CMake together, check the same examples are present for both -CMAKE_EXAMPLE_PATHS=$( find ${IDF_PATH}/examples/ -type f -name CMakeLists.txt | grep -v "/components/" | grep -v "/main/" | grep -v "/build_system/cmake/") +CMAKE_EXAMPLE_PATHS=$( find ${IDF_PATH}/examples/ -type f -name CMakeLists.txt | grep -v "/components/" | grep -v "/common_components/" | grep -v "/main/" | grep -v "/build_system/cmake/") MAKE_EXAMPLE_PATHS=$( find ${IDF_PATH}/examples/ -type f -name Makefile | grep -v "/build_system/cmake/") CMAKE_EXAMPLE_PATHS="$(/usr/bin/dirname $CMAKE_EXAMPLE_PATHS | sort -n)"