Merge branch 'feature/esp_netif_interface_update' into 'master'

tcpip_adapter refactor: ready for review

Closes IDF-39

See merge request espressif/esp-idf!5373
This commit is contained in:
Ivan Grokhotkov 2019-11-14 21:27:53 +08:00
commit 9e8fa4bb18
168 changed files with 6717 additions and 3090 deletions

View file

@ -46,7 +46,7 @@ static void ip_event_handler(void* arg, esp_event_base_t event_base,
case IP_EVENT_STA_GOT_IP:
event = (ip_event_got_ip_t*)event_data;
ESP_LOGI(TAG, "IP_EVENT_STA_GOT_IP");
ESP_LOGI(TAG, "got ip:%s\n", ip4addr_ntoa(&event->ip_info.ip));
ESP_LOGI(TAG, "got ip:" IPSTR "\n", IP2STR(&event->ip_info.ip));
break;
default:
break;
@ -94,8 +94,10 @@ TEST_CASE("adc2 work with wifi","[adc]")
r = nvs_flash_init();
}
TEST_ESP_OK( r);
tcpip_adapter_init();
esp_netif_init();
event_init();
esp_netif_create_default_wifi_sta();
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
TEST_ESP_OK(esp_wifi_init(&cfg));
wifi_config_t wifi_config = {
@ -144,5 +146,5 @@ TEST_CASE("adc2 work with wifi","[adc]")
printf("test passed...\n");
TEST_IGNORE_MESSAGE("this test case is ignored due to the critical memory leak of tcpip_adapter and event_loop.");
TEST_IGNORE_MESSAGE("this test case is ignored due to the critical memory leak of esp_netif and event_loop.");
}

View file

@ -23,6 +23,9 @@
#if __has_include("esp_mesh.h")
#include "esp_mesh.h"
#endif
#if __has_include("esp_netif_types.h")
#include "esp_netif_types.h"
#endif
#if __has_include("esp_now.h")
#include "esp_now.h"
#endif
@ -50,9 +53,6 @@
#if __has_include("nvs.h")
#include "nvs.h"
#endif
#if __has_include("tcpip_adapter.h")
#include "tcpip_adapter.h"
#endif
#if __has_include("ulp_common.h")
#include "ulp_common.h"
#endif
@ -454,30 +454,33 @@ static const esp_err_msg_t esp_err_msg_table[] = {
# ifdef ESP_ERR_MESH_VOTING
ERR_TBL_IT(ESP_ERR_MESH_VOTING), /* 16406 0x4016 */
# endif
// components/tcpip_adapter/include/tcpip_adapter.h
# ifdef ESP_ERR_TCPIP_ADAPTER_BASE
ERR_TBL_IT(ESP_ERR_TCPIP_ADAPTER_BASE), /* 20480 0x5000 */
// components/esp_netif/include/esp_netif_types.h
# ifdef ESP_ERR_ESP_NETIF_BASE
ERR_TBL_IT(ESP_ERR_ESP_NETIF_BASE), /* 20480 0x5000 */
# endif
# ifdef ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS
ERR_TBL_IT(ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS), /* 20481 0x5001 */
# ifdef ESP_ERR_ESP_NETIF_INVALID_PARAMS
ERR_TBL_IT(ESP_ERR_ESP_NETIF_INVALID_PARAMS), /* 20481 0x5001 */
# endif
# ifdef ESP_ERR_TCPIP_ADAPTER_IF_NOT_READY
ERR_TBL_IT(ESP_ERR_TCPIP_ADAPTER_IF_NOT_READY), /* 20482 0x5002 */
# ifdef ESP_ERR_ESP_NETIF_IF_NOT_READY
ERR_TBL_IT(ESP_ERR_ESP_NETIF_IF_NOT_READY), /* 20482 0x5002 */
# endif
# ifdef ESP_ERR_TCPIP_ADAPTER_DHCPC_START_FAILED
ERR_TBL_IT(ESP_ERR_TCPIP_ADAPTER_DHCPC_START_FAILED), /* 20483 0x5003 */
# ifdef ESP_ERR_ESP_NETIF_DHCPC_START_FAILED
ERR_TBL_IT(ESP_ERR_ESP_NETIF_DHCPC_START_FAILED), /* 20483 0x5003 */
# endif
# ifdef ESP_ERR_TCPIP_ADAPTER_DHCP_ALREADY_STARTED
ERR_TBL_IT(ESP_ERR_TCPIP_ADAPTER_DHCP_ALREADY_STARTED), /* 20484 0x5004 */
# ifdef ESP_ERR_ESP_NETIF_DHCP_ALREADY_STARTED
ERR_TBL_IT(ESP_ERR_ESP_NETIF_DHCP_ALREADY_STARTED), /* 20484 0x5004 */
# endif
# ifdef ESP_ERR_TCPIP_ADAPTER_DHCP_ALREADY_STOPPED
ERR_TBL_IT(ESP_ERR_TCPIP_ADAPTER_DHCP_ALREADY_STOPPED), /* 20485 0x5005 */
# ifdef ESP_ERR_ESP_NETIF_DHCP_ALREADY_STOPPED
ERR_TBL_IT(ESP_ERR_ESP_NETIF_DHCP_ALREADY_STOPPED), /* 20485 0x5005 */
# endif
# ifdef ESP_ERR_TCPIP_ADAPTER_NO_MEM
ERR_TBL_IT(ESP_ERR_TCPIP_ADAPTER_NO_MEM), /* 20486 0x5006 */
# ifdef ESP_ERR_ESP_NETIF_NO_MEM
ERR_TBL_IT(ESP_ERR_ESP_NETIF_NO_MEM), /* 20486 0x5006 */
# endif
# ifdef ESP_ERR_TCPIP_ADAPTER_DHCP_NOT_STOPPED
ERR_TBL_IT(ESP_ERR_TCPIP_ADAPTER_DHCP_NOT_STOPPED), /* 20487 0x5007 */
# ifdef ESP_ERR_ESP_NETIF_DHCP_NOT_STOPPED
ERR_TBL_IT(ESP_ERR_ESP_NETIF_DHCP_NOT_STOPPED), /* 20487 0x5007 */
# endif
# ifdef ESP_ERR_ESP_NETIF_DRIVER_ATTACH_FAILED
ERR_TBL_IT(ESP_ERR_ESP_NETIF_DRIVER_ATTACH_FAILED), /* 20488 0x5008 */
# endif
// components/esp_common/include/esp_err.h
# ifdef ESP_ERR_FLASH_BASE

View file

@ -30,5 +30,5 @@ idf_component_register(SRCS "${srcs}"
INCLUDE_DIRS ${include}
LDFRAGMENTS ${linker}
REQUIRES "esp_event"
PRIV_REQUIRES "tcpip_adapter" "driver" "log")
PRIV_REQUIRES "esp_netif" "driver" "log")

View file

@ -85,6 +85,7 @@ typedef struct {
* - ESP_FAIL: error occurred when processing extra lowlevel deinitialization
*/
esp_err_t (*on_lowlevel_deinit_done)(esp_eth_handle_t eth_handle);
} esp_eth_config_t;
/**
@ -115,6 +116,21 @@ typedef struct {
*/
esp_err_t esp_eth_driver_install(const esp_eth_config_t *config, esp_eth_handle_t *out_hdl);
/**
* @brief Start ethernet driver **ONLY** in standalone mode, i.e. without TCP/IP stack
*
* Note that ethernet driver is typically started as soon as it is attached to esp-netif.
* This API should only be called if ethernet is used separately without esp-netif, for example
* when esp_eth_config_t.stack_input is not NULL.
*
* @param[in] eth_handle handle of Ethernet driver
*
* @return
* - ESP_OK: starts ethernet driver
* - ESP_ERR_INVALID_STATE: if event loop hasn't been initialized
*/
esp_err_t esp_eth_driver_start(esp_eth_handle_t eth_handle);
/**
* @brief Uninstall Ethernet driver
*
@ -139,7 +155,7 @@ esp_err_t esp_eth_driver_uninstall(esp_eth_handle_t hdl);
* - ESP_ERR_INVALID_ARG: transmit frame buffer failed because of some invalid argument
* - ESP_FAIL: transmit frame buffer failed because some other error occurred
*/
esp_err_t esp_eth_transmit(esp_eth_handle_t hdl, uint8_t *buf, uint32_t length);
esp_err_t esp_eth_transmit(void* hdl, void *buf, uint32_t length);
/**
* @brief General Receive
@ -174,6 +190,22 @@ esp_err_t esp_eth_receive(esp_eth_handle_t hdl, uint8_t *buf, uint32_t *length);
*/
esp_err_t esp_eth_ioctl(esp_eth_handle_t hdl, esp_eth_io_cmd_t cmd, void *data);
/**
* @brief Register default ethernet handlers
*
* @param[in] esp_netif esp network interface handle created for this driver
* (note: appropriate ethernet handle not yet properly initialized when setting up
* default handlers)
*/
esp_err_t esp_eth_set_default_handlers(void* esp_netif);
/**
* @brief Unregister default ethernet handlers
*
* @param[in] esp_netif esp network interface handle created for this driver
*/
esp_err_t esp_eth_clear_default_handlers(void* esp_netif);
#ifdef __cplusplus
}
#endif

View file

@ -18,6 +18,8 @@
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/timers.h"
#include "esp_netif.h"
#include "tcpip_adapter_compatible/tcpip_adapter_compat.h"
static const char *TAG = "esp_eth";
#define ETH_CHECK(a, str, goto_tag, ret_value, ...) \
@ -44,6 +46,7 @@ ESP_EVENT_DEFINE_BASE(ETH_EVENT);
* In the callback, user can do any low level operations (e.g. enable/disable crystal clock).
*/
typedef struct {
esp_netif_driver_base_t base;
esp_eth_mediator_t mediator;
esp_eth_phy_t *phy;
esp_eth_mac_t *mac;
@ -83,7 +86,7 @@ static esp_err_t eth_stack_input(esp_eth_mediator_t *eth, uint8_t *buffer, uint3
{
esp_eth_driver_t *eth_driver = __containerof(eth, esp_eth_driver_t, mediator);
if (!eth_driver->stack_input) {
return tcpip_adapter_eth_input(buffer, length, NULL);
return esp_netif_receive(eth_driver->base.netif, buffer, length, NULL);
} else {
return eth_driver->stack_input((esp_eth_handle_t)eth_driver, buffer, length);
}
@ -148,11 +151,48 @@ static void eth_check_link_timer_cb(TimerHandle_t xTimer)
phy->get_link(phy);
}
static esp_err_t esp_eth_post_attach_driver_start(esp_netif_t * esp_netif, void * args)
{
uint8_t eth_mac[6];
esp_eth_driver_t *eth_driver = args;
eth_driver->base.netif = esp_netif;
// Set driver related config to esp-netif
esp_netif_driver_ifconfig_t driver_ifconfig = {
.handle = eth_driver,
.transmit = esp_eth_transmit,
.driver_free_rx_buffer = NULL
};
ESP_ERROR_CHECK(esp_netif_set_driver_config(esp_netif, &driver_ifconfig));
esp_eth_ioctl(eth_driver, ETH_CMD_G_MAC_ADDR, eth_mac);
ESP_LOGI(TAG, "%x %x %x %x %x %x", eth_mac[0], eth_mac[1], eth_mac[2], eth_mac[3], eth_mac[4], eth_mac[5]);
esp_netif_set_mac(esp_netif, eth_mac);
ESP_LOGI(TAG, "ETH netif started");
return esp_eth_driver_start(eth_driver);
}
////////////////////////////////User face APIs////////////////////////////////////////////////
// User has to pass the handle of Ethernet driver to each API.
// Different Ethernet driver instance is identified with a unique handle.
// It's helpful for us to support multiple Ethernet port on ESP32.
//////////////////////////////////////////////////////////////////////////////////////////////
esp_err_t esp_eth_driver_start(esp_eth_handle_t eth_handle)
{
esp_err_t ret = ESP_OK;
esp_eth_driver_t *eth_driver = eth_handle;
ETH_CHECK(xTimerStart(eth_driver->check_link_timer, 0) == pdPASS, "start eth_link_timer failed", err_start_timer, ESP_FAIL);
ETH_CHECK(esp_event_post(ETH_EVENT, ETHERNET_EVENT_START, &eth_driver, sizeof(eth_driver), 0) == ESP_OK,
"send ETHERNET_EVENT_START event failed", err_event, ESP_FAIL);
return ret;
err_start_timer:
xTimerDelete(eth_driver->check_link_timer, 0);
err_event:
esp_eth_driver_uninstall(eth_driver);
return ret;
}
esp_err_t esp_eth_driver_install(const esp_eth_config_t *config, esp_eth_handle_t *out_hdl)
{
@ -183,15 +223,10 @@ esp_err_t esp_eth_driver_install(const esp_eth_config_t *config, esp_eth_handle_
eth_driver->check_link_timer = xTimerCreate("eth_link_timer", pdMS_TO_TICKS(config->check_link_period_ms), pdTRUE,
eth_driver, eth_check_link_timer_cb);
ETH_CHECK(eth_driver->check_link_timer, "create eth_link_timer failed", err_create_timer, ESP_FAIL);
ETH_CHECK(xTimerStart(eth_driver->check_link_timer, 0) == pdPASS, "start eth_link_timer failed", err_start_timer, ESP_FAIL);
ETH_CHECK(esp_event_post(ETH_EVENT, ETHERNET_EVENT_START, &eth_driver, sizeof(eth_driver), 0) == ESP_OK,
"send ETHERNET_EVENT_START event failed", err_event, ESP_FAIL);
eth_driver->base.post_attach = esp_eth_post_attach_driver_start;
*out_hdl = (esp_eth_handle_t)eth_driver;
tcpip_adapter_compat_start_eth(eth_driver);
return ESP_OK;
err_event:
xTimerStop(eth_driver->check_link_timer, 0);
err_start_timer:
xTimerDelete(eth_driver->check_link_timer, 0);
err_create_timer:
phy->deinit(phy);
err_init_phy:
@ -221,7 +256,7 @@ err:
return ret;
}
esp_err_t esp_eth_transmit(esp_eth_handle_t hdl, uint8_t *buf, uint32_t length)
esp_err_t esp_eth_transmit(void* hdl, void *buf, uint32_t length)
{
esp_err_t ret = ESP_OK;
esp_eth_driver_t *eth_driver = (esp_eth_driver_t *)hdl;
@ -282,3 +317,55 @@ esp_err_t esp_eth_ioctl(esp_eth_handle_t hdl, esp_eth_io_cmd_t cmd, void *data)
err:
return ret;
}
esp_err_t esp_eth_clear_default_handlers(void* esp_netif)
{
esp_err_t ret;
ETH_CHECK(esp_netif, "esp-netif handle can't be null", fail, ESP_ERR_INVALID_ARG);
esp_event_handler_unregister(ETH_EVENT, ETHERNET_EVENT_START, esp_netif_action_start);
esp_event_handler_unregister(ETH_EVENT, ETHERNET_EVENT_STOP, esp_netif_action_stop);
esp_event_handler_unregister(ETH_EVENT, ETHERNET_EVENT_CONNECTED, esp_netif_action_connected);
esp_event_handler_unregister(ETH_EVENT, ETHERNET_EVENT_DISCONNECTED, esp_netif_action_disconnected);
esp_event_handler_unregister(IP_EVENT, IP_EVENT_ETH_GOT_IP, esp_netif_action_got_ip);
return ESP_OK;
fail:
return ret;
}
esp_err_t esp_eth_set_default_handlers(void* esp_netif)
{
esp_err_t ret;
ETH_CHECK(esp_netif, "esp-netif handle can't be null", fail, ESP_ERR_INVALID_ARG);
ret = esp_event_handler_register(ETH_EVENT, ETHERNET_EVENT_START, esp_netif_action_start, esp_netif);
if (ret != ESP_OK) {
goto fail;
}
ret = esp_event_handler_register(ETH_EVENT, ETHERNET_EVENT_STOP, esp_netif_action_stop, esp_netif);
if (ret != ESP_OK) {
goto fail;
}
ret = esp_event_handler_register(ETH_EVENT, ETHERNET_EVENT_CONNECTED, esp_netif_action_connected, esp_netif);
if (ret != ESP_OK) {
goto fail;
}
ret = esp_event_handler_register(ETH_EVENT, ETHERNET_EVENT_DISCONNECTED, esp_netif_action_disconnected, esp_netif);
if (ret != ESP_OK) {
goto fail;
}
ret = esp_event_handler_register(IP_EVENT, IP_EVENT_ETH_GOT_IP, esp_netif_action_got_ip, esp_netif);
if (ret != ESP_OK) {
goto fail;
}
return ESP_OK;
fail:
esp_eth_clear_default_handlers(esp_netif);
return ret;
}

View file

@ -4,7 +4,6 @@
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/event_groups.h"
#include "tcpip_adapter.h"
#include "unity.h"
#include "test_utils.h"
#include "esp_event.h"
@ -15,6 +14,9 @@
#include "lwip/sockets.h"
#include "ping/ping_sock.h"
#define GOT_IP_BIT BIT(0)
#define ETHERNET_GET_IP_TIMEOUT_MS (20000)
static const char *TAG = "esp_eth_test";
#define ETH_START_BIT BIT(0)
@ -62,8 +64,7 @@ static void got_ip_event_handler(void *arg, esp_event_base_t event_base,
{
EventGroupHandle_t eth_event_group = (EventGroupHandle_t)arg;
ip_event_got_ip_t *event = (ip_event_got_ip_t *)event_data;
const tcpip_adapter_ip_info_t *ip_info = &event->ip_info;
const esp_netif_ip_info_t *ip_info = &event->ip_info;
ESP_LOGI(TAG, "Ethernet Got IP Address");
ESP_LOGI(TAG, "~~~~~~~~~~~");
ESP_LOGI(TAG, "ETHIP:" IPSTR, IP2STR(&ip_info->ip));
@ -148,6 +149,8 @@ TEST_CASE("esp32 ethernet event test", "[ethernet][test_env=UT_T2_Ethernet]")
EventGroupHandle_t eth_event_group = xEventGroupCreate();
TEST_ASSERT(eth_event_group != NULL);
TEST_ESP_OK(esp_event_loop_create_default());
esp_netif_config_t cfg = ESP_NETIF_DEFAULT_ETH();
esp_netif_t* eth_netif = esp_netif_new(&cfg);
TEST_ESP_OK(esp_event_handler_register(ETH_EVENT, ESP_EVENT_ANY_ID, &eth_event_handler, eth_event_group));
eth_mac_config_t mac_config = ETH_MAC_DEFAULT_CONFIG();
esp_eth_mac_t *mac = esp_eth_mac_new_esp32(&mac_config);
@ -156,6 +159,7 @@ TEST_CASE("esp32 ethernet event test", "[ethernet][test_env=UT_T2_Ethernet]")
esp_eth_config_t eth_config = ETH_DEFAULT_CONFIG(mac, phy);
esp_eth_handle_t eth_handle = NULL;
TEST_ESP_OK(esp_eth_driver_install(&eth_config, &eth_handle));
TEST_ESP_OK(esp_netif_attach(eth_netif, eth_handle));
/* wait for connection start */
bits = xEventGroupWaitBits(eth_event_group, ETH_START_BIT, true, true, pdMS_TO_TICKS(ETH_START_TIMEOUT_MS));
TEST_ASSERT((bits & ETH_START_BIT) == ETH_START_BIT);
@ -173,6 +177,7 @@ TEST_CASE("esp32 ethernet event test", "[ethernet][test_env=UT_T2_Ethernet]")
TEST_ESP_OK(esp_event_handler_unregister(ETH_EVENT, ESP_EVENT_ANY_ID, eth_event_handler));
TEST_ESP_OK(esp_event_loop_delete_default());
vEventGroupDelete(eth_event_group);
esp_netif_destroy(eth_netif);
}
TEST_CASE("esp32 ethernet dhcp test", "[ethernet][test_env=UT_T2_Ethernet]")
@ -182,7 +187,10 @@ TEST_CASE("esp32 ethernet dhcp test", "[ethernet][test_env=UT_T2_Ethernet]")
TEST_ASSERT(eth_event_group != NULL);
test_case_uses_tcpip();
TEST_ESP_OK(esp_event_loop_create_default());
TEST_ESP_OK(tcpip_adapter_set_default_eth_handlers());
esp_netif_config_t cfg = ESP_NETIF_DEFAULT_ETH();
esp_netif_t* eth_netif = esp_netif_new(&cfg);
TEST_ESP_OK(esp_eth_set_default_handlers(eth_netif));
TEST_ESP_OK(esp_event_handler_register(ETH_EVENT, ESP_EVENT_ANY_ID, &eth_event_handler, eth_event_group));
TEST_ESP_OK(esp_event_handler_register(IP_EVENT, IP_EVENT_ETH_GOT_IP, &got_ip_event_handler, eth_event_group));
eth_mac_config_t mac_config = ETH_MAC_DEFAULT_CONFIG();
@ -192,6 +200,8 @@ TEST_CASE("esp32 ethernet dhcp test", "[ethernet][test_env=UT_T2_Ethernet]")
esp_eth_config_t eth_config = ETH_DEFAULT_CONFIG(mac, phy);
esp_eth_handle_t eth_handle = NULL;
TEST_ESP_OK(esp_eth_driver_install(&eth_config, &eth_handle));
TEST_ESP_OK(esp_netif_attach(eth_netif, eth_handle));
/* wait for IP lease */
bits = xEventGroupWaitBits(eth_event_group, ETH_GOT_IP_BIT, true, true, pdMS_TO_TICKS(ETH_GET_IP_TIMEOUT_MS));
TEST_ASSERT((bits & ETH_GOT_IP_BIT) == ETH_GOT_IP_BIT);
@ -205,9 +215,10 @@ TEST_CASE("esp32 ethernet dhcp test", "[ethernet][test_env=UT_T2_Ethernet]")
TEST_ESP_OK(mac->del(mac));
TEST_ESP_OK(esp_event_handler_unregister(IP_EVENT, IP_EVENT_ETH_GOT_IP, got_ip_event_handler));
TEST_ESP_OK(esp_event_handler_unregister(ETH_EVENT, ESP_EVENT_ANY_ID, eth_event_handler));
TEST_ESP_OK(tcpip_adapter_clear_default_eth_handlers());
TEST_ESP_OK(esp_eth_clear_default_handlers(eth_netif));
TEST_ESP_OK(esp_event_loop_delete_default());
vEventGroupDelete(eth_event_group);
esp_netif_destroy(eth_netif);
}
TEST_CASE("esp32 ethernet icmp test", "[ethernet][test_env=UT_T2_Ethernet]")
@ -217,7 +228,10 @@ TEST_CASE("esp32 ethernet icmp test", "[ethernet][test_env=UT_T2_Ethernet]")
TEST_ASSERT(eth_event_group != NULL);
test_case_uses_tcpip();
TEST_ESP_OK(esp_event_loop_create_default());
TEST_ESP_OK(tcpip_adapter_set_default_eth_handlers());
esp_netif_config_t cfg = ESP_NETIF_DEFAULT_ETH();
esp_netif_t* eth_netif = esp_netif_new(&cfg);
TEST_ESP_OK(esp_eth_set_default_handlers(eth_netif));
TEST_ESP_OK(esp_event_handler_register(ETH_EVENT, ESP_EVENT_ANY_ID, &eth_event_handler, eth_event_group));
TEST_ESP_OK(esp_event_handler_register(IP_EVENT, IP_EVENT_ETH_GOT_IP, &got_ip_event_handler, eth_event_group));
eth_mac_config_t mac_config = ETH_MAC_DEFAULT_CONFIG();
@ -227,6 +241,7 @@ TEST_CASE("esp32 ethernet icmp test", "[ethernet][test_env=UT_T2_Ethernet]")
esp_eth_config_t eth_config = ETH_DEFAULT_CONFIG(mac, phy);
esp_eth_handle_t eth_handle = NULL;
TEST_ESP_OK(esp_eth_driver_install(&eth_config, &eth_handle));
TEST_ESP_OK(esp_netif_attach(eth_netif, eth_handle));
/* wait for IP lease */
bits = xEventGroupWaitBits(eth_event_group, ETH_GOT_IP_BIT, true, true, pdMS_TO_TICKS(ETH_GET_IP_TIMEOUT_MS));
TEST_ASSERT((bits & ETH_GOT_IP_BIT) == ETH_GOT_IP_BIT);
@ -282,9 +297,10 @@ TEST_CASE("esp32 ethernet icmp test", "[ethernet][test_env=UT_T2_Ethernet]")
TEST_ESP_OK(phy->del(phy));
TEST_ESP_OK(mac->del(mac));
TEST_ESP_OK(esp_event_handler_unregister(IP_EVENT, IP_EVENT_ETH_GOT_IP, got_ip_event_handler));
TEST_ESP_OK(tcpip_adapter_clear_default_eth_handlers());
TEST_ESP_OK(esp_eth_clear_default_handlers(eth_netif));
TEST_ESP_OK(esp_event_loop_delete_default());
vEventGroupDelete(eth_event_group);
esp_netif_destroy(eth_netif);
}
#if CONFIG_ETH_USE_SPI_ETHERNET
@ -309,9 +325,11 @@ TEST_CASE("dm9051 io test", "[ethernet][ignore]")
};
TEST_ESP_OK(spi_bus_add_device(HSPI_HOST, &devcfg, &spi_handle));
gpio_install_isr_service(0);
tcpip_adapter_init();
esp_netif_init();
TEST_ESP_OK(esp_event_loop_create_default());
TEST_ESP_OK(tcpip_adapter_set_default_eth_handlers());
esp_netif_config_t cfg = ESP_NETIF_DEFAULT_ETH();
esp_netif_t* eth_netif = esp_netif_new(&cfg);
TEST_ESP_OK(esp_eth_set_default_handlers(eth_netif));
TEST_ESP_OK(esp_event_handler_register(ETH_EVENT, ESP_EVENT_ANY_ID, &eth_event_handler, NULL));
TEST_ESP_OK(esp_event_handler_register(IP_EVENT, IP_EVENT_ETH_GOT_IP, &got_ip_event_handler, NULL));
eth_mac_config_t mac_config = ETH_MAC_DEFAULT_CONFIG();
@ -322,6 +340,7 @@ TEST_CASE("dm9051 io test", "[ethernet][ignore]")
esp_eth_config_t config = ETH_DEFAULT_CONFIG(mac, phy);
esp_eth_handle_t eth_handle = NULL;
TEST_ESP_OK(esp_eth_driver_install(&config, &eth_handle));
TEST_ESP_OK(esp_netif_attach(eth_netif, eth_handle));
vTaskDelay(pdMS_TO_TICKS(portMAX_DELAY));
TEST_ESP_OK(esp_eth_driver_uninstall(eth_handle));
TEST_ESP_OK(phy->del(phy));

View file

@ -11,7 +11,7 @@ idf_component_register(SRCS "default_event_loop.c"
"event_send.c"
INCLUDE_DIRS "include"
PRIV_INCLUDE_DIRS "private_include"
REQUIRES log tcpip_adapter
REQUIRES log esp_netif
PRIV_REQUIRES ${priv_requires}
LDFRAGMENTS linker.lf)

View file

@ -14,8 +14,8 @@
#include "esp_err.h"
#include "esp_log.h"
#include "esp_event_legacy.h"
#include "esp_event.h"
#include "esp_event_legacy.h"
#include "sdkconfig.h"

View file

@ -16,7 +16,7 @@
#include "esp_log.h"
#include "esp_event_legacy.h"
#include "esp_wifi_types.h"
#include "tcpip_adapter.h"
#include "esp_netif.h"
#if CONFIG_ETH_ENABLED
#include "esp_eth.h"
#endif
@ -271,16 +271,8 @@ static void esp_system_event_debug(const system_event_t* event)
break;
}
case SYSTEM_EVENT_GOT_IP6: {
const ip6_addr_t *addr = &event->event_info.got_ip6.ip6_info.ip;
ESP_LOGD(TAG, "SYSTEM_EVENT_AP_STA_GOT_IP6 address %04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x",
IP6_ADDR_BLOCK1(addr),
IP6_ADDR_BLOCK2(addr),
IP6_ADDR_BLOCK3(addr),
IP6_ADDR_BLOCK4(addr),
IP6_ADDR_BLOCK5(addr),
IP6_ADDR_BLOCK6(addr),
IP6_ADDR_BLOCK7(addr),
IP6_ADDR_BLOCK8(addr));
const esp_ip6_addr_t *addr = &event->event_info.got_ip6.ip6_info.ip;
ESP_LOGD(TAG, "SYSTEM_EVENT_AP_STA_GOT_IP6 address " IPV6STR, IPV62STR(*addr));
break;
}
#if CONFIG_IDF_TARGET_ESP32

View file

@ -19,7 +19,7 @@
#include "esp_err.h"
#include "esp_wifi_types.h"
#include "tcpip_adapter.h"
#include "esp_netif.h"
#ifdef __cplusplus
extern "C" {

View file

@ -17,7 +17,7 @@
#include <stdio.h>
#include <stdarg.h>
#include "tcpip_adapter.h"
#include "esp_netif.h"
#include "lwip/sockets.h"
#include "esp32/rom/md5_hash.h"
#include "mbedtls/base64.h"

View file

@ -0,0 +1,10 @@
idf_component_register(SRCS "esp_netif_handlers.c"
"esp_netif_objects.c"
"esp_netif_defaults.c"
"lwip/esp_netif_lwip.c"
"loopback/esp_netif_loopback.c"
"lwip/esp_netif_lwip_defaults.c"
"lwip/esp_netif_sta_list.c"
INCLUDE_DIRS include
PRIV_INCLUDE_DIRS lwip private_include
REQUIRES lwip esp_eth tcpip_adapter)

View file

@ -1,6 +1,6 @@
menu "TCP/IP Adapter"
menu "ESP NETIF Adapter"
config NETIF_IP_LOST_TIMER_INTERVAL
config ESP_NETIF_IP_LOST_TIMER_INTERVAL
int "IP Address lost timer interval (seconds)"
range 0 65535
default 120
@ -13,15 +13,28 @@ menu "TCP/IP Adapter"
the timer expires. The IP lost timer is stopped if the station get the IP again before
the timer expires.
choice NETIF_USE_TCPIP_STACK_LIB
choice ESP_NETIF_USE_TCPIP_STACK_LIB
prompt "TCP/IP Stack Library"
default TCPIP_LWIP
default ESP_NETIF_TCPIP_LWIP
help
Choose the TCP/IP Stack to work, for example, LwIP, uIP, etc.
config TCPIP_LWIP
config ESP_NETIF_TCPIP_LWIP
bool "LwIP"
help
lwIP is a small independent implementation of the TCP/IP protocol suite.
config ESP_NETIF_LOOPBACK
bool "Loopback"
help
Dummy implementation of esp-netif functionality which connects driver transmit
to receive function. This option is for testing purpose only
endchoice
config ESP_NETIF_TCPIP_ADAPTER_COMPATIBLE_LAYER
bool "Enable backward compatible tcpip_adapter interface"
default y
help
Backward compatible interface to tcpip_adapter is enabled by default to support
legacy TCP/IP stack initialisation code. Disable this option to use only esp-netif
interface.
endmenu

View file

@ -0,0 +1,81 @@
# ESP-NETIF architecture
| (A) USER CODE |
| |
.............| init settings events |
. +----------------------------------------+
. . | *
. . V *
--------+ +===========================+ * +-----------------------+
| | new/config get/set | * | |
| | |...*.....| init |
| |---------------------------| * | |
init | | |**** | |
start |********| event handler |*********| DHCP |
stop | | | | |
| |---------------------------| | |
| | | | NETIF |
+-----| | | +-----------------+ |
| glue|----<---| esp_netif_transmit |--<------| netif_output | |
| | | | | | |
| |---->---| esp_netif_receive |-->------| netif_input | |
| | | | + ----------------+ |
| |....<...| esp_netif_free_rx_buffer |...<.....| packet buffer |
+-----| | | | |
| | | | |
(B) | | | +-----------------------+
--------+ +===========================+
communication NETWORK STACK
DRIVER ESP-NETIF
## Components:
### A) User code, boiler plate
Overall application interaction with communication media and network stack
* initialization code
- create a new instance of ESP-NETIF
- configure the object with
1) netif specific options (flags, behaviour, name)
2) network stack options (netif init and input functions, not publicly available)
3) IO driver specific options (transmit, tx_free functions, IO driver handle)
- setup event handlers
- use default handlers for common interfaces defined in IO drivers; or define a specific handlers
for customised behaviour/new interfaces
- register handlers for app related events (such as IP lost/acquired)
- interact with network interfaces using ESP-NETIF API
### B) Communication driver, IO driver, media driver
* event handler
- define behaviour patterns of interaction with ESP-NETIF (example: ehternet link-up -> turn netif on)
* glue IO layer: adapt the input/output functions to use esp-netif transmit/input/free_rx
- install driver_transmit to appropriate ESP-NETIF object, so that outgoing packets from
network stack are passed to the IO driver
- calls esp_netif_receive to pass incoming data to network stack
### C) ESP-NETIF, former tcpip_adapter
* init API (new, configure)
* IO API: for passing data between IO driver and network stack
* event/action API (esp-netif lifecycle management)
- building blocks for designing event handlers
* setters, getters
* network stack abstraction: enabling user interaction with TCP/IP stack
- netif up/down
- DHCP server, client
- DNS API
* driver conversion utilities
### D) Network stack: no public interaction with user code (wrtt interfaces)
## Data/event flow:
* `........` Initialization line from user code to esp-netif and comm driver
* `--<--->--` Data packets going from communication media to TCP/IP stack and back
* `********` Events agregated in ESP-NETIP propagates to driver, user code and network stack
* `|` User settings and runtime configuration

View file

@ -0,0 +1,6 @@
#
# Component Makefile
#
COMPONENT_ADD_INCLUDEDIRS := include
COMPONENT_PRIV_INCLUDEDIRS := private_include lwip
COMPONENT_SRCDIRS := . lwip loopback

View file

@ -0,0 +1,69 @@
// Copyright 2015-2019 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "esp_netif.h"
#include "esp_wifi_default.h"
#if CONFIG_ETH_ENABLED
#include "esp_eth.h"
#endif
//
// Purpose of this module is to provide
// - general esp-netif definitions of default objects for STA, AP, ETH
// - default init / create functions for basic default interfaces
//
#define IP4TOUINT32(a,b,c,d) (((uint32_t)((a) & 0xffU) << 24) | \
((uint32_t)((b) & 0xffU) << 16) | \
((uint32_t)((c) & 0xffU) << 8) | \
(uint32_t)((d) & 0xffU))
#define IP4TOADDR(a,b,c,d) esp_netif_htonl(IP4TOUINT32(a, b, c, d))
//
// Default configuration of common interfaces, such as STA, AP, ETH
//
const esp_netif_inherent_config_t _g_esp_netif_inherent_sta_config = {
.flags = ESP_NETIF_DHCP_CLIENT | ESP_NETIF_FLAG_GARP | ESP_NETIF_FLAG_EVENT_IP_MODIFIED,
.lost_ip_event = IP_EVENT_STA_LOST_IP,
.get_ip_event = IP_EVENT_STA_GOT_IP,
.if_key = "WIFI_STA_DEF",
.if_desc = "sta",
.route_prio = 100
};
static const esp_netif_ip_info_t soft_ap_ip = {
.ip = { .addr = IP4TOADDR( 192, 168, 4, 1) },
.gw = { .addr = IP4TOADDR( 192, 168, 4, 1) },
.netmask = { .addr = IP4TOADDR( 255, 255, 255, 0) },
};
const esp_netif_inherent_config_t _g_esp_netif_inherent_ap_config = {
.flags = ESP_NETIF_DHCP_SERVER | ESP_NETIF_FLAG_AUTOUP,
.ip_info = (esp_netif_ip_info_t*)&soft_ap_ip,
.if_key = "WIFI_AP_DEF",
.if_desc = "ap",
.route_prio = 10
};
const esp_netif_inherent_config_t _g_esp_netif_inherent_eth_config = {
.get_ip_event = IP_EVENT_ETH_GOT_IP,
.lost_ip_event = 0,
.flags = ESP_NETIF_DHCP_CLIENT | ESP_NETIF_FLAG_GARP | ESP_NETIF_FLAG_EVENT_IP_MODIFIED,
.if_key = "ETH_DEF",
.if_desc = "eth",
.route_prio = 50
};

View file

@ -0,0 +1,101 @@
// Copyright 2019 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <string.h>
#include "esp_netif.h"
#include "esp_event.h"
#include "esp_err.h"
#include "esp_log.h"
#include "esp_netif_private.h"
//
// Purpose of this module is to define general event handler primitives
// enabling application code to them either directly or with minimal modification
// for example with a separate pre/post handler.
// This module has no dependency on a specific network stack (lwip)
//
static const char *TAG = "esp_netif_handlers";
void esp_netif_action_start(void *esp_netif, esp_event_base_t base, int32_t event_id, void *data)
{
ESP_LOGD(TAG, "esp_netif action has started with netif%p from event_id=%d", esp_netif, event_id);
esp_netif_start(esp_netif);
}
void esp_netif_action_stop(void *esp_netif, esp_event_base_t base, int32_t event_id, void *data)
{
ESP_LOGD(TAG, "esp_netif action stopped with netif%p from event_id=%d", esp_netif, event_id);
esp_netif_stop(esp_netif);
}
void esp_netif_action_connected(void *esp_netif, esp_event_base_t base, int32_t event_id, void *data)
{
esp_netif_dhcp_status_t status;
ESP_LOGD(TAG, "esp_netif action connected with netif%p from event_id=%d", esp_netif, event_id);
esp_netif_up(esp_netif);
esp_netif_dhcpc_get_status(esp_netif, &status);
if (status == ESP_NETIF_DHCP_INIT) {
esp_netif_dhcpc_start(esp_netif);
} else if (status == ESP_NETIF_DHCP_STOPPED) {
//
esp_netif_ip_info_t ip;
esp_netif_ip_info_t old_ip;
esp_netif_get_ip_info(esp_netif, &ip);
esp_netif_get_old_ip_info(esp_netif, &old_ip);
if (esp_netif_is_valid_static_ip(&ip)) {
ip_event_got_ip_t evt = {
.esp_netif = esp_netif,
.if_index = -1, // to indicate ptr to if used
.ip_changed = false,
};
if (memcmp(&ip, &old_ip, sizeof(ip))) {
evt.ip_changed = true;
}
memcpy(&evt.ip_info, &ip, sizeof(esp_netif_ip_info_t));
esp_netif_set_old_ip_info(esp_netif, &ip);
ESP_NETIF_CALL_CHECK("esp_event_send_internal in esp_netif_action_connected",
esp_event_send_internal(IP_EVENT, esp_netif_get_event_id(esp_netif, ESP_NETIF_IP_EVENT_GOT_IP) ,
&evt, sizeof(evt), 0), ESP_OK);
ESP_LOGD(TAG, "static ip: ip changed=%d", evt.ip_changed);
} else {
ESP_LOGE(TAG, "invalid static ip");
}
}
}
void esp_netif_action_disconnected(void *esp_netif, esp_event_base_t base, int32_t event_id, void *data)
{
ESP_LOGD(TAG, "esp_netif action disconnected with netif%p from event_id=%d", esp_netif, event_id);
esp_netif_down(esp_netif);
}
void esp_netif_action_got_ip(void *esp_netif, esp_event_base_t base, int32_t event_id, void *data)
{
ESP_LOGD(TAG, "esp_netif action got_ip with netif%p from event_id=%d", esp_netif, event_id);
const ip_event_got_ip_t *event = (const ip_event_got_ip_t *) data;
ESP_LOGI(TAG, "%s ip: " IPSTR ", mask: " IPSTR ", gw: " IPSTR, esp_netif_get_desc(esp_netif),
IP2STR(&event->ip_info.ip),
IP2STR(&event->ip_info.netmask),
IP2STR(&event->ip_info.gw));
}

View file

@ -0,0 +1,188 @@
// Copyright 2015-2019 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "esp_netif.h"
#include "sys/queue.h"
#include "esp_log.h"
#include "freertos/FreeRTOS.h"
#include "freertos/semphr.h"
#include "esp_netif_private.h"
#include <string.h>
//
// Purpose of this module is to provide list of esp-netif structures
// - this module has no dependency on a specific network stack (lwip)
//
static const char *TAG = "esp_netif_objects";
typedef struct slist_netifs_s slist_netifs_t;
struct slist_netifs_s {
esp_netif_t *netif;
SLIST_ENTRY(slist_netifs_s) next;
};
SLIST_HEAD(slisthead, slist_netifs_s) s_head = { .slh_first = NULL, };
static size_t s_esp_netif_counter = 0;
static xSemaphoreHandle s_list_lock = NULL;
ESP_EVENT_DEFINE_BASE(IP_EVENT);
esp_err_t esp_netif_list_lock(void)
{
if (s_list_lock == NULL) {
s_list_lock = xSemaphoreCreateMutex();
if (s_list_lock == NULL) {
return ESP_ERR_NO_MEM;
}
}
xSemaphoreTake(s_list_lock, portMAX_DELAY);
return ESP_OK;
}
void esp_netif_list_unlock(void)
{
assert(s_list_lock);
xSemaphoreGive(s_list_lock);
if (s_esp_netif_counter == 0) {
vQueueDelete(s_list_lock);
s_list_lock = NULL;
}
}
//
// List manipulation functions
//
esp_err_t esp_netif_add_to_list(esp_netif_t *netif)
{
esp_err_t ret;
struct slist_netifs_s *item = calloc(1, sizeof(struct slist_netifs_s));
ESP_LOGD(TAG, "%s %p", __func__, netif);
if (item == NULL) {
return ESP_ERR_NO_MEM;
}
item->netif = netif;
if ((ret = esp_netif_list_lock()) != ESP_OK) {
return ret;
}
SLIST_INSERT_HEAD(&s_head, item, next);
++s_esp_netif_counter;
ESP_LOGD(TAG, "%s netif added successfully (total netifs: %d)", __func__, s_esp_netif_counter);
esp_netif_list_unlock();
return ESP_OK;
}
esp_err_t esp_netif_remove_from_list(esp_netif_t *netif)
{
struct slist_netifs_s *item;
esp_err_t ret;
if ((ret = esp_netif_list_lock()) != ESP_OK) {
return ret;
}
ESP_LOGV(TAG, "%s %p", __func__, netif);
SLIST_FOREACH(item, &s_head, next) {
if (item->netif == netif) {
SLIST_REMOVE(&s_head, item, slist_netifs_s, next);
assert(s_esp_netif_counter > 0);
--s_esp_netif_counter;
ESP_LOGD(TAG, "%s netif successfully removed (total netifs: %d)", __func__, s_esp_netif_counter);
free(item);
esp_netif_list_unlock();
return ESP_OK;
}
}
esp_netif_list_unlock();
return ESP_ERR_NOT_FOUND;
}
size_t esp_netif_get_nr_of_ifs(void)
{
return s_esp_netif_counter;
}
esp_netif_t* esp_netif_next(esp_netif_t* netif)
{
esp_err_t ret;
esp_netif_t* result;
if ((ret = esp_netif_list_lock()) != ESP_OK) {
ESP_LOGE(TAG, "Failed to lock esp-netif list with %d", ret);
return NULL;
}
result = esp_netif_next_unsafe(netif);
esp_netif_list_unlock();
return result;
}
esp_netif_t* esp_netif_next_unsafe(esp_netif_t* netif)
{
ESP_LOGV(TAG, "%s %p", __func__, netif);
struct slist_netifs_s *item;
// Getting the first netif if argument is NULL
if (netif == NULL) {
item = SLIST_FIRST(&s_head);
return (item == NULL) ? NULL : item->netif;
}
// otherwise the next one (after the supplied netif)
SLIST_FOREACH(item, &s_head, next) {
if (item->netif == netif) {
item = SLIST_NEXT(item, next);
return (item == NULL) ? NULL : item->netif;
}
}
return NULL;
}
bool esp_netif_is_netif_listed(esp_netif_t *esp_netif)
{
esp_err_t ret;
if ((ret = esp_netif_list_lock()) != ESP_OK) {
ESP_LOGE(TAG, "Failed to lock esp-netif list with %d", ret);
return NULL;
}
// looking for the netif in the list of registered interfaces
esp_netif_t *it = esp_netif_next_unsafe(NULL);
do {
if (it && it == esp_netif) {
esp_netif_list_unlock();
return true;
}
} while (NULL != (it = esp_netif_next_unsafe(it)));
esp_netif_list_unlock();
return false;
}
esp_netif_t *esp_netif_get_handle_from_ifkey(const char *if_key)
{
esp_err_t ret;
if ((ret = esp_netif_list_lock()) != ESP_OK) {
ESP_LOGE(TAG, "Failed to lock esp-netif list with %d", ret);
return NULL;
}
esp_netif_t *esp_netif = esp_netif_next_unsafe(NULL);
do {
if (esp_netif && strcmp(if_key, esp_netif_get_ifkey(esp_netif))==0) {
esp_netif_list_unlock();
return esp_netif;
}
} while (NULL != (esp_netif = esp_netif_next_unsafe(esp_netif)));
esp_netif_list_unlock();
return NULL;
}

View file

@ -0,0 +1,739 @@
// Copyright 2019 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef _ESP_NETIF_H_
#define _ESP_NETIF_H_
#include <stdint.h>
#include "esp_wifi_types.h"
#include "sdkconfig.h"
#include "esp_netif_ip_addr.h"
#include "esp_netif_types.h"
#include "esp_netif_defaults.h"
//
// Note: tcpip_adapter legacy API has to be included by default to provide full compatibility
// for applications that used tcpip_adapter API without explicit inclusion of tcpip_adapter.h
//
#if CONFIG_ESP_NETIF_TCPIP_ADAPTER_COMPATIBLE_LAYER
#define _ESP_NETIF_SUPPRESS_LEGACY_WARNING_
#include "tcpip_adapter.h"
#undef _ESP_NETIF_SUPPRESS_LEGACY_WARNING_
#endif // CONFIG_ESP_NETIF_TCPIP_ADAPTER_COMPATIBLE_LAYER
/**
* @defgroup ESP_NETIF_INIT_API ESP-NETIF Initialization API
* @brief Initialization and deinitialization of underlying TCP/IP stack and esp-netif instances
*
*/
/** @addtogroup ESP_NETIF_INIT_API
* @{
*/
/**
* @brief Initialize the underlying TCP/IP stack
*
* @return
* - ESP_OK on success
* - ESP_FAIL if initializing failed
* @note This function should be called exactly once from application code, when the application starts up.
*/
esp_err_t esp_netif_init(void);
/**
* @brief Deinitialize the esp-netif component (and the underlying TCP/IP stack)
*
* Note: Deinitialization is not supported yet
*
* @return
* - ESP_ERR_INVALID_STATE if esp_netif not initialized
* - ESP_ERR_NOT_SUPPORTED otherwise
*/
esp_err_t esp_netif_deinit(void);
/**
* @brief Creates an instance of new esp-netif object based on provided config
*
* @param[in] esp_netif_config pointer esp-netif configuration
*
* @return
* - pointer to esp-netif object on success
* - NULL otherwise
*/
esp_netif_t *esp_netif_new(const esp_netif_config_t *esp_netif_config);
/**
* @brief Destroys the esp_netif object
*
* @param[in] esp_netif pointer to the object to be deleted
*/
void esp_netif_destroy(esp_netif_t *esp_netif);
/**
* @brief Configures driver related options of esp_netif object
*
* @param[inout] esp_netif pointer to the object to be configured
* @param[in] driver_config pointer esp-netif io driver related configuration
* @return
* - ESP_OK on success
* - ESP_ERR_ESP_NETIF_INVALID_PARAMS if invalid parameters provided
*
*/
esp_err_t esp_netif_set_driver_config(esp_netif_t *esp_netif,
const esp_netif_driver_ifconfig_t *driver_config);
/**
* @brief Attaches esp_netif instance to the io driver handle
*
* Calling this function enables connecting specific esp_netif object
* with already initialized io driver to update esp_netif object with driver
* specific configuration (i.e. calls post_attach callback, which typically
* sets io driver callbacks to esp_netif instance and starts the driver)
*
* @param[inout] esp_netif pointer to esp_netif object to be attached
* @param[in] driver_handle pointer to the driver handle
* @return
* - ESP_OK on success
* - ESP_ERR_ESP_NETIF_DRIVER_ATTACH_FAILED if driver's pot_attach callback failed
*/
esp_err_t esp_netif_attach(esp_netif_t *esp_netif, esp_netif_iodriver_handle driver_handle);
/**
* @}
*/
/**
* @defgroup ESP_NETIF_DATA_IO_API ESP-NETIF Input Output API
* @brief Input and Output functions to pass data packets from communication media (IO driver)
* to TCP/IP stack.
*
* These functions are usually not directly called from user code, but installed, or registered
* as callbacks in either IO driver on one hand or TCP/IP stack on the other. More specifically
* esp_netif_receive is typically called from io driver on reception callback to input the packets
* to TCP/IP stack. Similarly esp_netif_transmit is called from the TCP/IP stack whenever
* a packet ought to output to the communication media.
*
* @note These IO functions are registerd (installed) automatically for default interfaces
* (interfaces with the keys such as WIFI_STA_DEF, WIFI_AP_DEF, ETH_DEF). Custom interface
* has to register these IO functions when creating interface using @ref esp_netif_new
*
*/
/** @addtogroup ESP_NETIF_DATA_IO_API
* @{
*/
/**
* @brief Passes the raw packets from communication media to the appropriate TCP/IP stack
*
* This function is called from the configured (peripheral) driver layer.
* The data are then forwarded as frames to the TCP/IP stack.
*
* @param[in] esp_netif Handle to esp-netif instance
* @param[in] buffer Received data
* @param[in] len Length of the data frame
* @param[in] eb Pointer to internal buffer (used in Wi-Fi driver)
*
* @return
* - ESP_OK
*/
esp_err_t esp_netif_receive(esp_netif_t *esp_netif, void *buffer, size_t len, void *eb);
/**
* @}
*/
/**
* @defgroup ESP_NETIF_LIFECYCLE ESP-NETIF Lifecycle control
* @brief These APIS define basic building blocks to control network interface lifecycle, i.e.
* start, stop, set_up or set_down. These functions can be directly used as event handlers
* registered to follow the events from communication media.
*/
/** @addtogroup ESP_NETIF_LIFECYCLE
* @{
*/
/**
* @brief Default building block for network interface action upon IO driver start event
* Creates network interface, if AUTOUP enabled turns the interface on,
* if DHCPS enabled starts dhcp server
*
* @note This API can be directly used as event handler
*
* @param[in] esp_netif Handle to esp-netif instance
* @param base
* @param event_id
* @param data
*/
void esp_netif_action_start(void *esp_netif, esp_event_base_t base, int32_t event_id, void *data);
/**
* @brief Default building block for network interface action upon IO driver stop event
*
* @note This API can be directly used as event handler
*
* @param[in] esp_netif Handle to esp-netif instance
* @param base
* @param event_id
* @param data
*/
void esp_netif_action_stop(void *esp_netif, esp_event_base_t base, int32_t event_id, void *data);
/**
* @brief Default building block for network interface action upon IO driver connected event
*
* @note This API can be directly used as event handler
*
* @param[in] esp_netif Handle to esp-netif instance
* @param base
* @param event_id
* @param data
*/
void esp_netif_action_connected(void *esp_netif, esp_event_base_t base, int32_t event_id, void *data);
/**
* @brief Default building block for network interface action upon IO driver disconnected event
*
* @note This API can be directly used as event handler
*
* @param[in] esp_netif Handle to esp-netif instance
* @param base
* @param event_id
* @param data
*/
void esp_netif_action_disconnected(void *esp_netif, esp_event_base_t base, int32_t event_id, void *data);
/**
* @brief Default building block for network interface action upon network got IP event
*
* @note This API can be directly used as event handler
*
* @param[in] esp_netif Handle to esp-netif instance
* @param base
* @param event_id
* @param data
*/
void esp_netif_action_got_ip(void *esp_netif, esp_event_base_t base, int32_t event_id, void *data);
/**
* @}
*/
/**
* @defgroup ESP_NETIF_GET_SET ESP-NETIF Runtime configuration
* @brief Getters and setters for various TCP/IP related parameters
*/
/** @addtogroup ESP_NETIF_GET_SET
* @{
*/
/**
* @brief Set the mac address for the interface instance
* @param[in] esp_netif Handle to esp-netif instance
* @param[in] mac Desired mac address for the related network interface
* @return ESP_OK
*/
esp_err_t esp_netif_set_mac(esp_netif_t *esp_netif, uint8_t mac[]);
/**
* @brief Set the hostname of an interface
*
* @param[in] esp_netif Handle to esp-netif instance
* @param[in] hostname New hostname for the interface. Maximum length 32 bytes.
*
* @return
* - ESP_OK - success
* - ESP_ERR_ESP_NETIF_IF_NOT_READY - interface status error
* - ESP_ERR_ESP_NETIF_INVALID_PARAMS - parameter error
*/
esp_err_t esp_netif_set_hostname(esp_netif_t *esp_netif, const char *hostname);
/**
* @brief Get interface hostname.
*
* @param[in] esp_netif Handle to esp-netif instance
* @param[out] hostname Returns a pointer to the hostname. May be NULL if no hostname is set. If set non-NULL, pointer remains valid (and string may change if the hostname changes).
*
* @return
* - ESP_OK - success
* - ESP_ERR_ESP_NETIF_IF_NOT_READY - interface status error
* - ESP_ERR_ESP_NETIF_INVALID_PARAMS - parameter error
*/
esp_err_t esp_netif_get_hostname(esp_netif_t *esp_netif, const char **hostname);
/**
* @brief Test if supplied interface is up or down
*
* @param[in] esp_netif Handle to esp-netif instance
*
* @return
* - true - Interface is up
* - false - Interface is down
*/
bool esp_netif_is_netif_up(esp_netif_t *esp_netif);
/**
* @brief Get interface's IP address information
*
* If the interface is up, IP information is read directly from the TCP/IP stack.
* If the interface is down, IP information is read from a copy kept in the ESP-NETIF instance
*
* @param[in] esp_netif Handle to esp-netif instance
* @param[out] ip_info If successful, IP information will be returned in this argument.
*
* @return
* - ESP_OK
* - ESP_ERR_ESP_NETIF_INVALID_PARAMS
*/
esp_err_t esp_netif_get_ip_info(esp_netif_t *esp_netif, esp_netif_ip_info_t *ip_info);
/**
* @brief Get interface's old IP information
*
* Returns an "old" IP address previously stored for the interface when the valid IP changed.
*
* If the IP lost timer has expired (meaning the interface was down for longer than the configured interval)
* then the old IP information will be zero.
*
* @param[in] esp_netif Handle to esp-netif instance
* @param[out] ip_info If successful, IP information will be returned in this argument.
*
* @return
* - ESP_OK
* - ESP_ERR_ESP_NETIF_INVALID_PARAMS
*/
esp_err_t esp_netif_get_old_ip_info(esp_netif_t *esp_netif, esp_netif_ip_info_t *ip_info);
/**
* @brief Set interface's IP address information
*
* This function is mainly used to set a static IP on an interface.
*
* If the interface is up, the new IP information is set directly in the TCP/IP stack.
*
* The copy of IP information kept in the ESP-NETIF instance is also updated (this
* copy is returned if the IP is queried while the interface is still down.)
*
* @note DHCP client/server must be stopped (if enabled for this interface) before setting new IP information.
*
* @note Calling this interface for may generate a SYSTEM_EVENT_STA_GOT_IP or SYSTEM_EVENT_ETH_GOT_IP event.
*
* @param[in] esp_netif Handle to esp-netif instance
* @param[in] ip_info IP information to set on the specified interface
*
* @return
* - ESP_OK
* - ESP_ERR_ESP_NETIF_INVALID_PARAMS
* - ESP_ERR_ESP_NETIF_DHCP_NOT_STOPPED If DHCP server or client is still running
*/
esp_err_t esp_netif_set_ip_info(esp_netif_t *esp_netif, const esp_netif_ip_info_t *ip_info);
/**
* @brief Set interface old IP information
*
* This function is called from the DHCP client (if enabled), before a new IP is set.
* It is also called from the default handlers for the SYSTEM_EVENT_STA_CONNECTED and SYSTEM_EVENT_ETH_CONNECTED events.
*
* Calling this function stores the previously configured IP, which can be used to determine if the IP changes in the future.
*
* If the interface is disconnected or down for too long, the "IP lost timer" will expire (after the configured interval) and set the old IP information to zero.
*
* @param[in] esp_netif Handle to esp-netif instance
* @param[in] ip_info Store the old IP information for the specified interface
*
* @return
* - ESP_OK
* - ESP_ERR_ESP_NETIF_INVALID_PARAMS
*/
esp_err_t esp_netif_set_old_ip_info(esp_netif_t *esp_netif, const esp_netif_ip_info_t *ip_info);
/**
* @brief Get net interface index from network stack implementation
*
* @note This index could be used in `setsockopt()` to bind socket with multicast interface
*
* @param[in] esp_netif Handle to esp-netif instance
*
* @return
* implementation specific index of interface represented with supplied esp_netif
*/
int esp_netif_get_netif_impl_index(esp_netif_t *esp_netif);
/**
* @}
*/
/**
* @defgroup ESP_NETIF_NET_DHCP ESP-NETIF DHCP Settings
* @brief Network stack related interface to DHCP client and server
*/
/** @addtogroup ESP_NETIF_NET_DHCP
* @{
*/
/**
* @brief Set or Get DHCP server option
*
* @param[in] esp_netif Handle to esp-netif instance
* @param[in] opt_op ESP_NETIF_OP_SET to set an option, ESP_NETIF_OP_GET to get an option.
* @param[in] opt_id Option index to get or set, must be one of the supported enum values.
* @param[inout] opt_val Pointer to the option parameter.
* @param[in] opt_len Length of the option parameter.
*
* @return
* - ESP_OK
* - ESP_ERR_ESP_NETIF_INVALID_PARAMS
* - ESP_ERR_ESP_NETIF_DHCP_ALREADY_STOPPED
* - ESP_ERR_ESP_NETIF_DHCP_ALREADY_STARTED
*/
esp_err_t esp_netif_dhcps_option(esp_netif_t *esp_netif, esp_netif_dhcp_option_mode_t opt_op, esp_netif_dhcp_option_id_t opt_id, void *opt_val, uint32_t opt_len);
/**
* @brief Set or Get DHCP client option
*
* @param[in] esp_netif Handle to esp-netif instance
* @param[in] opt_op ESP_NETIF_OP_SET to set an option, ESP_NETIF_OP_GET to get an option.
* @param[in] opt_id Option index to get or set, must be one of the supported enum values.
* @param[inout] opt_val Pointer to the option parameter.
* @param[in] opt_len Length of the option parameter.
*
* @return
* - ESP_OK
* - ESP_ERR_ESP_NETIF_INVALID_PARAMS
* - ESP_ERR_ESP_NETIF_DHCP_ALREADY_STOPPED
* - ESP_ERR_ESP_NETIF_DHCP_ALREADY_STARTED
*/
esp_err_t esp_netif_dhcpc_option(esp_netif_t *esp_netif, esp_netif_dhcp_option_mode_t opt_op, esp_netif_dhcp_option_id_t opt_id, void *opt_val, uint32_t opt_len);
/**
* @brief Start DHCP client (only if enabled in interface object)
*
* @note The default event handlers for the SYSTEM_EVENT_STA_CONNECTED and SYSTEM_EVENT_ETH_CONNECTED events call this function.
*
* @param[in] esp_netif Handle to esp-netif instance
*
* @return
* - ESP_OK
* - ESP_ERR_ESP_NETIF_INVALID_PARAMS
* - ESP_ERR_ESP_NETIF_DHCP_ALREADY_STARTED
* - ESP_ERR_ESP_NETIF_DHCPC_START_FAILED
*/
esp_err_t esp_netif_dhcpc_start(esp_netif_t *esp_netif);
/**
* @brief Stop DHCP client (only if enabled in interface object)
*
* @note Calling action_netif_stop() will also stop the DHCP Client if it is running.
*
* @param[in] esp_netif Handle to esp-netif instance
*
* @return
* - ESP_OK
* - ESP_ERR_ESP_NETIF_INVALID_PARAMS
* - ESP_ERR_ESP_NETIF_DHCP_ALREADY_STOPPED
* - ESP_ERR_ESP_NETIF_IF_NOT_READY
*/
esp_err_t esp_netif_dhcpc_stop(esp_netif_t *esp_netif);
/**
* @brief Get DHCP client status
*
* @param[in] esp_netif Handle to esp-netif instance
* @param[out] status If successful, the status of DHCP client will be returned in this argument.
*
* @return
* - ESP_OK
*/
esp_err_t esp_netif_dhcpc_get_status(esp_netif_t *esp_netif, esp_netif_dhcp_status_t *status);
/**
* @brief Get DHCP Server status
*
* @param[in] esp_netif Handle to esp-netif instance
* @param[out] status If successful, the status of the DHCP server will be returned in this argument.
*
* @return
* - ESP_OK
*/
esp_err_t esp_netif_dhcps_get_status(esp_netif_t *esp_netif, esp_netif_dhcp_status_t *status);
/**
* @brief Start DHCP server (only if enabled in interface object)
*
* @param[in] esp_netif Handle to esp-netif instance
*
* @return
* - ESP_OK
* - ESP_ERR_ESP_NETIF_INVALID_PARAMS
* - ESP_ERR_ESP_NETIF_DHCP_ALREADY_STARTED
*/
esp_err_t esp_netif_dhcps_start(esp_netif_t *esp_netif);
/**
* @brief Stop DHCP server (only if enabled in interface object)
*
* @param[in] esp_netif Handle to esp-netif instance
*
* @return
* - ESP_OK
* - ESP_ERR_ESP_NETIF_INVALID_PARAMS
* - ESP_ERR_ESP_NETIF_DHCP_ALREADY_STOPPED
* - ESP_ERR_ESP_NETIF_IF_NOT_READY
*/
esp_err_t esp_netif_dhcps_stop(esp_netif_t *esp_netif);
/**
* @}
*/
/**
* @defgroup ESP_NETIF_NET_DNS ESP-NETIF DNS Settings
* @brief Network stack related interface to NDS
*/
/** @addtogroup ESP_NETIF_NET_DNS
* @{
*/
/**
* @brief Set DNS Server information
*
* This function behaves differently if DHCP server or client is enabled
*
* If DHCP client is enabled, main and backup DNS servers will be updated automatically
* from the DHCP lease if the relevant DHCP options are set. Fallback DNS Server is never updated from the DHCP lease
* and is designed to be set via this API.
* If DHCP client is disabled, all DNS server types can be set via this API only.
*
* If DHCP server is enabled, the Main DNS Server setting is used by the DHCP server to provide a DNS Server option
* to DHCP clients (Wi-Fi stations).
* - The default Main DNS server is typically the IP of the Wi-Fi AP interface itself.
* - This function can override it by setting server type ESP_NETIF_DNS_MAIN.
* - Other DNS Server types are not supported for the Wi-Fi AP interface.
*
* @param[in] esp_netif Handle to esp-netif instance
* @param[in] type Type of DNS Server to set: ESP_NETIF_DNS_MAIN, ESP_NETIF_DNS_BACKUP, ESP_NETIF_DNS_FALLBACK
* @param[in] dns DNS Server address to set
*
* @return
* - ESP_OK on success
* - ESP_ERR_ESP_NETIF_INVALID_PARAMS invalid params
*/
esp_err_t esp_netif_set_dns_info(esp_netif_t *esp_netif, esp_netif_dns_type_t type, esp_netif_dns_info_t *dns);
/**
* @brief Get DNS Server information
*
* Return the currently configured DNS Server address for the specified interface and Server type.
*
* This may be result of a previous call to esp_netif_set_dns_info(). If the interface's DHCP client is enabled,
* the Main or Backup DNS Server may be set by the current DHCP lease.
*
* @param[in] esp_netif Handle to esp-netif instance
* @param[in] type Type of DNS Server to get: ESP_NETIF_DNS_MAIN, ESP_NETIF_DNS_BACKUP, ESP_NETIF_DNS_FALLBACK
* @param[out] dns DNS Server result is written here on success
*
* @return
* - ESP_OK on success
* - ESP_ERR_ESP_NETIF_INVALID_PARAMS invalid params
*/
esp_err_t esp_netif_get_dns_info(esp_netif_t *esp_netif, esp_netif_dns_type_t type, esp_netif_dns_info_t *dns);
/**
* @}
*/
/**
* @defgroup ESP_NETIF_NET_IP ESP-NETIF IP address related interface
* @brief Network stack related interface to IP
*/
/** @addtogroup ESP_NETIF_NET_IP
* @{
*/
/**
* @brief Create interface link-local IPv6 address
*
* Cause the TCP/IP stack to create a link-local IPv6 address for the specified interface.
*
* This function also registers a callback for the specified interface, so that if the link-local address becomes
* verified as the preferred address then a SYSTEM_EVENT_GOT_IP6 event will be sent.
*
* @param[in] esp_netif Handle to esp-netif instance
*
* @return
* - ESP_OK
* - ESP_ERR_ESP_NETIF_INVALID_PARAMS
*/
esp_err_t esp_netif_create_ip6_linklocal(esp_netif_t *esp_netif);
/**
* @brief Get interface link-local IPv6 address
*
* If the specified interface is up and a preferred link-local IPv6 address
* has been created for the interface, return a copy of it.
*
* @param[in] esp_netif Handle to esp-netif instance
* @param[out] if_ip6 IPv6 information will be returned in this argument if successful.
*
* @return
* - ESP_OK
* - ESP_FAIL If interface is down, does not have a link-local IPv6 address,
* or the link-local IPv6 address is not a preferred address.
*/
esp_err_t esp_netif_get_ip6_linklocal(esp_netif_t *esp_netif, esp_ip6_addr_t *if_ip6);
/**
* @brief Sets IPv4 address to the specified octets
*
* @param[out] addr IP address to be set
* @param a the first octet (127 for IP 127.0.0.1)
* @param b
* @param c
* @param d
*/
void esp_netif_set_ip4_addr(esp_ip4_addr_t *addr, uint8_t a, uint8_t b, uint8_t c, uint8_t d);
/**
* @brief Converts numeric IP address into decimal dotted ASCII representation.
*
* @param addr ip address in network order to convert
* @param buf target buffer where the string is stored
* @param buflen length of buf
* @return either pointer to buf which now holds the ASCII
* representation of addr or NULL if buf was too small
*/
char * esp_ip4addr_ntoa(const esp_ip4_addr_t *addr, char *buf, int buflen);
/**
* @brief Ascii internet address interpretation routine
* The value returned is in network order.
*
* @param addr IP address in ascii representation (e.g. "127.0.0.1")
* @return ip address in network order
*/
uint32_t esp_ip4addr_aton(const char *addr);
/**
* @}
*/
/**
* @defgroup ESP_NETIF_CONVERT ESP-NETIF Conversion utilities
* @brief ESP-NETIF conversion utilities to related keys, flags, implementation handle
*/
/** @addtogroup ESP_NETIF_CONVERT
* @{
*/
/**
* @brief Gets media driver handle for this esp-netif instance
*
* @param[in] esp_netif Handle to esp-netif instance
*
* @return opaque pointer of related IO driver
*/
esp_netif_iodriver_handle esp_netif_get_io_driver(esp_netif_t *esp_netif);
/**
* @brief Searches over a list of created objects to find an instance with supplied if key
*
* @param if_key Textual description of network interface
*
* @return Handle to esp-netif instance
*/
esp_netif_t *esp_netif_get_handle_from_ifkey(const char *if_key);
/**
* @brief Returns configured flags for this interface
*
* @param[in] esp_netif Handle to esp-netif instance
*
* @return Configuration flags
*/
esp_netif_flags_t esp_netif_get_flags(esp_netif_t *esp_netif);
/**
* @brief Returns configured interface key for this esp-netif instance
*
* @param[in] esp_netif Handle to esp-netif instance
*
* @return Textual description of related interface
*/
const char *esp_netif_get_ifkey(esp_netif_t *esp_netif);
/**
* @brief Returns configured interface type for this esp-netif instance
*
* @param[in] esp_netif Handle to esp-netif instance
*
* @return Enumerated type of this interface, such as station, AP, ethernet
*/
const char *esp_netif_get_desc(esp_netif_t *esp_netif);
/**
* @brief Returns configured event for this esp-netif instance and supplied event type
*
* @param[in] esp_netif Handle to esp-netif instance
*
* @param event_type (either get or lost IP)
*
* @return specific event id which is configured to be raised if the interface lost or acquired IP address
* -1 if supplied event_type is not known
*/
int32_t esp_netif_get_event_id(esp_netif_t *esp_netif, esp_netif_ip_event_type_t event_type);
/**
* @}
*/
/**
* @defgroup ESP_NETIF_LIST ESP-NETIF List of interfaces
* @brief APIs to enumerate all registered interfaces
*/
/** @addtogroup ESP_NETIF_LIST
* @{
*/
/**
* @brief Iterates over list of interfaces. Returns first netif if NULL given as parameter
*
* @param[in] esp_netif Handle to esp-netif instance
*
* @return First netif from the list if supplied parameter is NULL, next one otherwise
*/
esp_netif_t* esp_netif_next(esp_netif_t* esp_netif);
/**
* @brief Returns number of registered esp_netif objects
*
* @return Number of esp_netifs
*/
size_t esp_netif_get_nr_of_ifs(void);
/**
* @}
*/
#endif /* _ESP_NETIF_H_ */

View file

@ -0,0 +1,88 @@
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef _ESP_NETIF_DEFAULTS_H
#define _ESP_NETIF_DEFAULTS_H
//
// Macros to assemble master configs with partial configs from netif, stack and driver
//
/**
* @brief Default configuration reference of ethernet interface
*/
#define ESP_NETIF_DEFAULT_ETH() \
{ \
.base = ESP_NETIF_BASE_DEFAULT_ETH, \
.stack = ESP_NETIF_NETSTACK_DEFAULT_ETH, \
.driver = NULL, \
}
/**
* @brief Default configuration reference of WIFI AP
*/
#define ESP_NETIF_DEFAULT_WIFI_AP() \
{ \
.base = ESP_NETIF_BASE_DEFAULT_WIFI_AP, \
.stack = ESP_NETIF_NETSTACK_DEFAULT_WIFI_AP, \
.driver = NULL, \
}
/**
* @brief Default configuration reference of WIFI STA
*/
#define ESP_NETIF_DEFAULT_WIFI_STA() \
{ \
.base = ESP_NETIF_BASE_DEFAULT_WIFI_STA, \
.stack = ESP_NETIF_NETSTACK_DEFAULT_WIFI_STA, \
.driver = NULL, \
}
/**
* @brief Default base config (esp-netif inherent) of WIFI STA
*/
#define ESP_NETIF_BASE_DEFAULT_WIFI_STA &_g_esp_netif_inherent_sta_config
/**
* @brief Default base config (esp-netif inherent) of WIFI AP
*/
#define ESP_NETIF_BASE_DEFAULT_WIFI_AP &_g_esp_netif_inherent_ap_config
/**
* @brief Default base config (esp-netif inherent) of ethernet interface
*/
#define ESP_NETIF_BASE_DEFAULT_ETH &_g_esp_netif_inherent_eth_config
#define ESP_NETIF_NETSTACK_DEFAULT_ETH _g_esp_netif_netstack_default_eth
#define ESP_NETIF_NETSTACK_DEFAULT_WIFI_STA _g_esp_netif_netstack_default_wifi_sta
#define ESP_NETIF_NETSTACK_DEFAULT_WIFI_AP _g_esp_netif_netstack_default_wifi_ap
//
// Include default network stacks configs
// - Network stack configurations are provided in a specific network stack
// implementation that is invisible to user API
// - Here referenced only as opaque pointers
//
extern const esp_netif_netstack_config_t *_g_esp_netif_netstack_default_eth;
extern const esp_netif_netstack_config_t *_g_esp_netif_netstack_default_wifi_sta;
extern const esp_netif_netstack_config_t *_g_esp_netif_netstack_default_wifi_ap;
//
// Include default common configs inherent to esp-netif
// - These inherent configs are defined in esp_netif_defaults.c and describe
// common behavioural patters for common interfaces such as STA, AP, ETH
//
extern const esp_netif_inherent_config_t _g_esp_netif_inherent_sta_config;
extern const esp_netif_inherent_config_t _g_esp_netif_inherent_ap_config;
extern const esp_netif_inherent_config_t _g_esp_netif_inherent_eth_config;
#endif //_ESP_NETIF_DEFAULTS_H

View file

@ -0,0 +1,98 @@
// Copyright 2015-2019 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef _ESP_NETIF_IP_ADDR_H_
#define _ESP_NETIF_IP_ADDR_H_
#include <machine/endian.h>
#if BYTE_ORDER == BIG_ENDIAN
#define esp_netif_htonl(x) ((uint32_t)(x))
#else
#define esp_netif_htonl(x) ((((x) & (uint32_t)0x000000ffUL) << 24) | \
(((x) & (uint32_t)0x0000ff00UL) << 8) | \
(((x) & (uint32_t)0x00ff0000UL) >> 8) | \
(((x) & (uint32_t)0xff000000UL) >> 24))
#endif
#define esp_netif_ip4_makeu32(a,b,c,d) (((uint32_t)((a) & 0xff) << 24) | \
((uint32_t)((b) & 0xff) << 16) | \
((uint32_t)((c) & 0xff) << 8) | \
(uint32_t)((d) & 0xff))
// Access address in 16-bit block
#define ESP_IP6_ADDR_BLOCK1(ip6addr) ((uint16_t)((esp_netif_htonl((ip6addr)->addr[0]) >> 16) & 0xffff))
#define ESP_IP6_ADDR_BLOCK2(ip6addr) ((uint16_t)((esp_netif_htonl((ip6addr)->addr[0])) & 0xffff))
#define ESP_IP6_ADDR_BLOCK3(ip6addr) ((uint16_t)((esp_netif_htonl((ip6addr)->addr[1]) >> 16) & 0xffff))
#define ESP_IP6_ADDR_BLOCK4(ip6addr) ((uint16_t)((esp_netif_htonl((ip6addr)->addr[1])) & 0xffff))
#define ESP_IP6_ADDR_BLOCK5(ip6addr) ((uint16_t)((esp_netif_htonl((ip6addr)->addr[2]) >> 16) & 0xffff))
#define ESP_IP6_ADDR_BLOCK6(ip6addr) ((uint16_t)((esp_netif_htonl((ip6addr)->addr[2])) & 0xffff))
#define ESP_IP6_ADDR_BLOCK7(ip6addr) ((uint16_t)((esp_netif_htonl((ip6addr)->addr[3]) >> 16) & 0xffff))
#define ESP_IP6_ADDR_BLOCK8(ip6addr) ((uint16_t)((esp_netif_htonl((ip6addr)->addr[3])) & 0xffff))
#define IPSTR "%d.%d.%d.%d"
#define esp_ip4_addr_get_byte(ipaddr, idx) (((const uint8_t*)(&(ipaddr)->addr))[idx])
#define esp_ip4_addr1(ipaddr) esp_ip4_addr_get_byte(ipaddr, 0)
#define esp_ip4_addr2(ipaddr) esp_ip4_addr_get_byte(ipaddr, 1)
#define esp_ip4_addr3(ipaddr) esp_ip4_addr_get_byte(ipaddr, 2)
#define esp_ip4_addr4(ipaddr) esp_ip4_addr_get_byte(ipaddr, 3)
#define esp_ip4_addr1_16(ipaddr) ((uint16_t)esp_ip4_addr1(ipaddr))
#define esp_ip4_addr2_16(ipaddr) ((uint16_t)esp_ip4_addr2(ipaddr))
#define esp_ip4_addr3_16(ipaddr) ((uint16_t)esp_ip4_addr3(ipaddr))
#define esp_ip4_addr4_16(ipaddr) ((uint16_t)esp_ip4_addr4(ipaddr))
#define IP2STR(ipaddr) esp_ip4_addr1_16(ipaddr), \
esp_ip4_addr2_16(ipaddr), \
esp_ip4_addr3_16(ipaddr), \
esp_ip4_addr4_16(ipaddr)
#define IPV6STR "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x"
#define IPV62STR(ipaddr) ESP_IP6_ADDR_BLOCK1(&(ipaddr)), \
ESP_IP6_ADDR_BLOCK2(&(ipaddr)), \
ESP_IP6_ADDR_BLOCK3(&(ipaddr)), \
ESP_IP6_ADDR_BLOCK4(&(ipaddr)), \
ESP_IP6_ADDR_BLOCK5(&(ipaddr)), \
ESP_IP6_ADDR_BLOCK6(&(ipaddr)), \
ESP_IP6_ADDR_BLOCK7(&(ipaddr)), \
ESP_IP6_ADDR_BLOCK8(&(ipaddr))
#define ESP_IPADDR_TYPE_V4 0U
#define ESP_IPADDR_TYPE_V6 6U
#define ESP_IPADDR_TYPE_ANY 46U
struct esp_ip6_addr {
uint32_t addr[4];
uint8_t zone;
};
struct esp_ip4_addr {
uint32_t addr;
};
typedef struct esp_ip4_addr esp_ip4_addr_t;
typedef struct esp_ip6_addr esp_ip6_addr_t;
typedef struct _ip_addr {
union {
esp_ip6_addr_t ip6;
esp_ip4_addr_t ip4;
} u_addr;
uint8_t type;
} esp_ip_addr_t;
#endif //_ESP_NETIF_IP_ADDR_H_

View file

@ -0,0 +1,79 @@
// Copyright 2015-2019 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef _ESP_NETIF_NET_STACK_H_
#define _ESP_NETIF_NET_STACK_H_
//
// Network stack API: This ESP-NETIF API are supposed to be called only from internals of TCP/IP stack
//
/** @addtogroup ESP_NETIF_CONVERT
* @{
*/
/**
* @brief Returns esp-netif handle
*
* @param[in] dev opaque ptr to network interface of specific TCP/IP stack
*
* @return handle to related esp-netif instance
*/
esp_netif_t* esp_netif_get_handle_from_netif_impl(void *dev);
/**
* @brief Returns network stack specific implementation handle
*
* @param[in] esp_netif Handle to esp-netif instance
*
* @return handle to related network stack netif handle
*/
void* esp_netif_get_netif_impl(esp_netif_t *esp_netif);
/**
* @}
*/
/** @addtogroup ESP_NETIF_DATA_IO_API
* @{
*/
/**
* @brief Outputs packets from the TCP/IP stack to the media to be transmitted
*
* This function gets called from network stack to output packets to IO driver.
*
* @param[in] esp_netif Handle to esp-netif instance
* @param[in] data Data to be tranmitted
* @param[in] len Length of the data frame
*/
esp_err_t esp_netif_transmit(esp_netif_t *esp_netif, void* data, size_t len);
/**
* @brief Free the rx buffer allocated by the media driver
*
* This function gets called from network stack when the rx buffer to be freed in IO driver context,
* i.e. to deallocate a buffer owned by io driver (when data packets were passed to higher levels
* to avoid copying)
*
* @param[in] esp_netif Handle to esp-netif instance
* @param[in] void* buffer: rx buffer pointer
*/
void esp_netif_free_rx_buffer(void *esp_netif, void* buffer);
/**
* @}
*/
#endif //_ESP_NETIF_NET_STACK_H_

View file

@ -0,0 +1,62 @@
// Copyright 2019 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef _ESP_NETIF_STA_LIST_H_
#define _ESP_NETIF_STA_LIST_H_
#include "esp_netif_types.h"
/**
* @brief station list info element
*/
typedef struct {
uint8_t mac[6]; /**< Station MAC address */
esp_ip4_addr_t ip; /**< Station assigned IP address */
} esp_netif_sta_info_t;
/**
* @brief station list structure
*/
typedef struct {
esp_netif_sta_info_t sta[ESP_WIFI_MAX_CONN_NUM]; /**< Connected stations */
int num; /**< Number of connected stations */
} esp_netif_sta_list_t;
/**
* @defgroup ESP_NETIF_STA_LIST ESP-NETIF STA list api
* @brief List of stations for Wi-Fi AP interface
*
*/
/** @addtogroup ESP_NETIF_STA_LIST
* @{
*/
/**
* @brief Get IP information for stations connected to the Wi-Fi AP interface
*
* @param[in] wifi_sta_list Wi-Fi station info list, returned from esp_wifi_ap_get_sta_list()
* @param[out] netif_sta_list IP layer station info list, corresponding to MAC addresses provided in wifi_sta_list
*
* @return
* - ESP_OK
* - ESP_ERR_ESP_NETIF_NO_MEM
* - ESP_ERR_ESP_NETIF_INVALID_PARAMS
*/
esp_err_t esp_netif_get_sta_list(const wifi_sta_list_t *wifi_sta_list, esp_netif_sta_list_t *netif_sta_list);
/**
* @}
*/
#endif //_ESP_NETIF_STA_LIST_H_

View file

@ -0,0 +1,201 @@
// Copyright 2015-2019 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef _ESP_NETIF_TYPES_H_
#define _ESP_NETIF_TYPES_H_
/**
* @brief Definition of ESP-NETIF based errors
*/
#define ESP_ERR_ESP_NETIF_BASE 0x5000
#define ESP_ERR_ESP_NETIF_INVALID_PARAMS ESP_ERR_ESP_NETIF_BASE + 0x01
#define ESP_ERR_ESP_NETIF_IF_NOT_READY ESP_ERR_ESP_NETIF_BASE + 0x02
#define ESP_ERR_ESP_NETIF_DHCPC_START_FAILED ESP_ERR_ESP_NETIF_BASE + 0x03
#define ESP_ERR_ESP_NETIF_DHCP_ALREADY_STARTED ESP_ERR_ESP_NETIF_BASE + 0x04
#define ESP_ERR_ESP_NETIF_DHCP_ALREADY_STOPPED ESP_ERR_ESP_NETIF_BASE + 0x05
#define ESP_ERR_ESP_NETIF_NO_MEM ESP_ERR_ESP_NETIF_BASE + 0x06
#define ESP_ERR_ESP_NETIF_DHCP_NOT_STOPPED ESP_ERR_ESP_NETIF_BASE + 0x07
#define ESP_ERR_ESP_NETIF_DRIVER_ATTACH_FAILED ESP_ERR_ESP_NETIF_BASE + 0x08
/** @brief Type of esp_netif_object server */
struct esp_netif_obj;
typedef struct esp_netif_obj esp_netif_t;
/** @brief Type of DNS server */
typedef enum {
ESP_NETIF_DNS_MAIN= 0, /**< DNS main server address*/
ESP_NETIF_DNS_BACKUP, /**< DNS backup server address (Wi-Fi STA and Ethernet only) */
ESP_NETIF_DNS_FALLBACK, /**< DNS fallback server address (Wi-Fi STA and Ethernet only) */
ESP_NETIF_DNS_MAX
} esp_netif_dns_type_t;
/** @brief DNS server info */
typedef struct {
esp_ip_addr_t ip; /**< IPV4 address of DNS server */
} esp_netif_dns_info_t;
/** @brief Status of DHCP client or DHCP server */
typedef enum {
ESP_NETIF_DHCP_INIT = 0, /**< DHCP client/server is in initial state (not yet started) */
ESP_NETIF_DHCP_STARTED, /**< DHCP client/server has been started */
ESP_NETIF_DHCP_STOPPED, /**< DHCP client/server has been stopped */
ESP_NETIF_DHCP_STATUS_MAX
} esp_netif_dhcp_status_t;
/** @brief Mode for DHCP client or DHCP server option functions */
typedef enum{
ESP_NETIF_OP_START = 0,
ESP_NETIF_OP_SET, /**< Set option */
ESP_NETIF_OP_GET, /**< Get option */
ESP_NETIF_OP_MAX
} esp_netif_dhcp_option_mode_t;
/** @brief Supported options for DHCP client or DHCP server */
typedef enum{
ESP_NETIF_DOMAIN_NAME_SERVER = 6, /**< Domain name server */
ESP_NETIF_ROUTER_SOLICITATION_ADDRESS = 32, /**< Solicitation router address */
ESP_NETIF_REQUESTED_IP_ADDRESS = 50, /**< Request specific IP address */
ESP_NETIF_IP_ADDRESS_LEASE_TIME = 51, /**< Request IP address lease time */
ESP_NETIF_IP_REQUEST_RETRY_TIME = 52, /**< Request IP address retry counter */
} esp_netif_dhcp_option_id_t;
/** IP event declarations */
typedef enum {
IP_EVENT_STA_GOT_IP, /*!< ESP32 station got IP from connected AP */
IP_EVENT_STA_LOST_IP, /*!< ESP32 station lost IP and the IP is reset to 0 */
IP_EVENT_AP_STAIPASSIGNED, /*!< ESP32 soft-AP assign an IP to a connected station */
IP_EVENT_GOT_IP6, /*!< ESP32 station or ap or ethernet interface v6IP addr is preferred */
IP_EVENT_ETH_GOT_IP, /*!< ESP32 ethernet got IP from connected AP */
} ip_event_t;
/** @brief IP event base declaration */
ESP_EVENT_DECLARE_BASE(IP_EVENT);
/** Event structure for IP_EVENT_STA_GOT_IP, IP_EVENT_ETH_GOT_IP events */
typedef struct {
esp_ip4_addr_t ip; /**< Interface IPV4 address */
esp_ip4_addr_t netmask; /**< Interface IPV4 netmask */
esp_ip4_addr_t gw; /**< Interface IPV4 gateway address */
} esp_netif_ip_info_t;
/** @brief IPV6 IP address information
*/
typedef struct {
esp_ip6_addr_t ip; /**< Interface IPV6 address */
} esp_netif_ip6_info_t;
typedef struct {
int if_index; /*!< Interface index for which the event is received (left for legacy compilation) */
esp_netif_t *esp_netif; /*!< Pointer to corresponding esp-netif object */
esp_netif_ip_info_t ip_info; /*!< IP address, netmask, gatway IP address */
bool ip_changed; /*!< Whether the assigned IP has changed or not */
} ip_event_got_ip_t;
/** Event structure for IP_EVENT_GOT_IP6 event */
typedef struct {
int if_index; /*!< Interface index for which the event is received (left for legacy compilation) */
esp_netif_t *esp_netif; /*!< Pointer to corresponding esp-netif object */
esp_netif_ip6_info_t ip6_info; /*!< IPv6 address of the interface */
} ip_event_got_ip6_t;
/** Event structure for IP_EVENT_AP_STAIPASSIGNED event */
typedef struct {
esp_ip4_addr_t ip; /*!< IP address which was assigned to the station */
} ip_event_ap_staipassigned_t;
typedef enum esp_netif_flags {
ESP_NETIF_DHCP_CLIENT = 1 << 0,
ESP_NETIF_DHCP_SERVER = 1 << 1,
ESP_NETIF_FLAG_AUTOUP = 1 << 2,
ESP_NETIF_FLAG_GARP = 1 << 3,
ESP_NETIF_FLAG_EVENT_IP_MODIFIED = 1 << 4
} esp_netif_flags_t;
typedef enum esp_netif_ip_event_type {
ESP_NETIF_IP_EVENT_GOT_IP = 1,
ESP_NETIF_IP_EVENT_LOST_IP = 2,
} esp_netif_ip_event_type_t;
//
// ESP-NETIF interface configuration:
// 1) general (behavioral) config (esp_netif_config_t)
// 2) (peripheral) driver specific config (esp_netif_driver_ifconfig_t)
// 3) network stack specific config (esp_netif_net_stack_ifconfig_t) -- no publicly available
//
typedef struct esp_netif_inherent_config {
esp_netif_flags_t flags; /*!< flags that define esp-netif behavior */
uint8_t mac[6]; /*!< initial mac address for this interface */
esp_netif_ip_info_t* ip_info; /*!< initial ip address for this interface */
uint32_t get_ip_event; /*!< event id to be raised when interface gets an IP */
uint32_t lost_ip_event; /*!< event id to be raised when interface losts its IP */
const char * if_key; /*!< string identifier of the interface */
const char * if_desc; /*!< textual description of the interface */
int route_prio; /*!< numeric priority of this interface to become a default
routing if (if other netifs are up) */
} esp_netif_inherent_config_t;
typedef struct esp_netif_config esp_netif_config_t;
/**
* @brief IO driver handle type
*/
typedef void * esp_netif_iodriver_handle;
typedef struct esp_netif_driver_base_s {
esp_err_t (*post_attach)(esp_netif_t *netif, esp_netif_iodriver_handle h);
esp_netif_t *netif;
} esp_netif_driver_base_t;
/**
* @brief Specific IO driver configuration
*/
struct esp_netif_driver_ifconfig {
esp_netif_iodriver_handle handle;
esp_err_t (*transmit)(void *h, void *buffer, size_t len);
void (*driver_free_rx_buffer)(void *h, void* buffer);
};
typedef struct esp_netif_driver_ifconfig esp_netif_driver_ifconfig_t;
/**
* @brief Specific L3 network stack configuration
*/
typedef struct esp_netif_netstack_config esp_netif_netstack_config_t;
/**
* @brief Generic esp_netif configuration
*/
struct esp_netif_config {
const esp_netif_inherent_config_t *base;
const esp_netif_driver_ifconfig_t *driver;
const esp_netif_netstack_config_t *stack;
};
/**
* @brief ESP-NETIF Receive function type
*/
typedef esp_err_t (*esp_netif_receive_t)(esp_netif_t *esp_netif, void *buffer, size_t len, void *eb);
#endif // _ESP_NETIF_TYPES_H_

View file

@ -0,0 +1,452 @@
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <string.h>
#include "esp_netif_lwip_internal.h"
#include "esp_netif.h"
#include "esp_netif_private.h"
#if CONFIG_ESP_NETIF_LOOPBACK
#include "esp_log.h"
//
// Purpose of this module is to implement minimal loopback netif to facilitate
// low level driver testing
//
#define ESP_NETIF_HOSTNAME_MAX_SIZE 32
static const char *TAG = "esp_netif_loopback";
static bool s_netif_initialized = false;
static bool s_netif_started = false;
static bool s_netif_up = false;
/**
* @brief Main esp-netif container with interface related information
*
*
*/
struct esp_netif_obj {
// default interface addresses
uint8_t mac[NETIF_MAX_HWADDR_LEN];
esp_netif_ip_info_t* ip_info;
esp_netif_ip_info_t* ip_info_old;
// io driver related
void* driver_handle;
esp_err_t (*driver_transmit)(void *h, void *buffer, size_t len);
void (*driver_free_rx_buffer)(void *h, void* buffer);
// misc flags, types, keys, priority
esp_netif_flags_t flags;
char * hostname;
char * if_key;
char * if_desc;
int route_prio;
};
void esp_netif_set_ip4_addr(esp_ip4_addr_t *addr, uint8_t a, uint8_t b, uint8_t c, uint8_t d)
{
memset(addr, 0, sizeof(esp_ip4_addr_t));
addr->addr = esp_netif_htonl(esp_netif_ip4_makeu32(a,b,c,d));
}
char * esp_ip4addr_ntoa(const esp_ip4_addr_t *addr, char *buf, int buflen)
{
return NULL;
}
esp_netif_iodriver_handle esp_netif_get_io_driver(esp_netif_t *esp_netif)
{
return esp_netif->driver_handle;
}
esp_netif_t* esp_netif_get_handle_from_netif_impl(void *dev)
{
return NULL;
}
void* esp_netif_get_netif_impl(esp_netif_t *esp_netif)
{
return NULL;
}
esp_err_t esp_netif_init(void)
{
ESP_LOGI(TAG, "loopback initialization");
if (s_netif_initialized) {
ESP_LOGE(TAG, "esp-netif has already been initialized");
return ESP_ERR_INVALID_SIZE;
}
s_netif_initialized = true;
ESP_LOGD(TAG, "esp-netif has been successfully initialized");
return ESP_OK;
}
esp_err_t esp_netif_deinit(void)
{
ESP_LOGI(TAG, "loopback initialization");
if (!s_netif_initialized) {
ESP_LOGE(TAG, "esp-netif has not been initialized yet");
return ESP_ERR_INVALID_SIZE;
}
s_netif_initialized = false;
ESP_LOGD(TAG, "esp-netif has been successfully deinitialized");
return ESP_OK;
}
static esp_err_t esp_netif_init_configuration(esp_netif_t *esp_netif, const esp_netif_config_t *cfg)
{
// Basic esp_netif and lwip is a mandatory configuration and cannot be updated after esp_netif_new()
if (cfg == NULL || cfg->base == NULL || cfg->stack == NULL) {
return ESP_ERR_ESP_NETIF_INVALID_PARAMS;
}
// Configure general esp-netif properties
memcpy(esp_netif->mac, cfg->base->mac, NETIF_MAX_HWADDR_LEN);
if (cfg->base->ip_info == NULL) {
ip4_addr_set_zero(&esp_netif->ip_info->ip);
ip4_addr_set_zero(&esp_netif->ip_info->gw);
ip4_addr_set_zero(&esp_netif->ip_info->netmask);
} else {
memcpy(esp_netif->ip_info, cfg->base->ip_info, sizeof(esp_netif_ip_info_t));
}
memcpy(esp_netif->ip_info_old, esp_netif->ip_info, sizeof(esp_netif_ip_info_t));
// Setup main config parameters
esp_netif->flags = cfg->base->flags;
if (cfg->base->if_key) {
esp_netif->if_key = strdup(cfg->base->if_key);
}
if (cfg->base->if_desc) {
esp_netif->if_desc = strdup(cfg->base->if_desc);
}
if (cfg->base->route_prio) {
esp_netif->route_prio = cfg->base->route_prio;
}
// Network stack is bypassed in loopback interface
// Install IO functions only if provided -- connects driver and netif
// this configuration could be updated after esp_netif_new(), typically in post_attach callback
if (cfg->driver) {
const esp_netif_driver_ifconfig_t *esp_netif_driver_config = cfg->driver;
if (esp_netif_driver_config->handle) {
esp_netif->driver_handle = esp_netif_driver_config->handle;
}
if (esp_netif_driver_config->transmit) {
esp_netif->driver_transmit = esp_netif_driver_config->transmit;
}
if (esp_netif_driver_config->driver_free_rx_buffer) {
esp_netif->driver_free_rx_buffer = esp_netif_driver_config->driver_free_rx_buffer;
}
}
return ESP_OK;
}
esp_netif_t *esp_netif_new(const esp_netif_config_t *esp_netif_config)
{
// mandatory configuration must be provided when creating esp_netif object
if (esp_netif_config == NULL) {
return NULL;
}
// Create parent esp-netif object
esp_netif_t *esp_netif = calloc(1, sizeof(struct esp_netif_obj));
if (!esp_netif) {
return NULL;
}
// Create ip info
esp_netif_ip_info_t *ip_info = calloc(1, sizeof(esp_netif_ip_info_t));
if (!ip_info) {
free(esp_netif);
return NULL;
}
esp_netif->ip_info = ip_info;
// creating another ip info (to store old ip)
ip_info = calloc(1, sizeof(esp_netif_ip_info_t));
if (!ip_info) {
free(esp_netif->ip_info);
free(esp_netif);
return NULL;
}
esp_netif->ip_info_old = ip_info;
esp_netif_add_to_list(esp_netif);
// Configure the created object with provided configuration
esp_err_t ret = esp_netif_init_configuration(esp_netif, esp_netif_config);
if (ret != ESP_OK) {
ESP_LOGE(TAG, "Initial configuration of esp_netif failed with %d", ret);
esp_netif_destroy(esp_netif);
return NULL;
}
return esp_netif;
}
void esp_netif_destroy(esp_netif_t *esp_netif)
{
if (esp_netif) {
esp_netif_remove_from_list(esp_netif);
free(esp_netif->ip_info);
free(esp_netif->ip_info_old);
free(esp_netif->if_key);
free(esp_netif->if_desc);
free(esp_netif);
}
}
esp_err_t esp_netif_attach(esp_netif_t *esp_netif, esp_netif_iodriver_handle driver_handle)
{
esp_netif_driver_base_t *base_driver = driver_handle;
esp_netif->driver_handle = driver_handle;
if (base_driver->post_attach) {
esp_err_t ret = base_driver->post_attach(esp_netif, driver_handle);
if (ret != ESP_OK) {
ESP_LOGE(TAG, "Post-attach callback of driver(%p) failed with %d", driver_handle, ret);
return ESP_ERR_ESP_NETIF_DRIVER_ATTACH_FAILED;
}
}
return ESP_OK;
}
esp_err_t esp_netif_set_driver_config(esp_netif_t *esp_netif,
const esp_netif_driver_ifconfig_t *driver_config)
{
if (esp_netif == NULL || driver_config == NULL) {
return ESP_ERR_ESP_NETIF_INVALID_PARAMS;
}
esp_netif->driver_handle = driver_config->handle;
esp_netif->driver_transmit = driver_config->transmit;
esp_netif->driver_free_rx_buffer = driver_config->driver_free_rx_buffer;
return ESP_OK;
}
esp_err_t esp_netif_set_mac(esp_netif_t *esp_netif, uint8_t mac[])
{
return ESP_ERR_NOT_SUPPORTED;
}
esp_err_t esp_netif_start(esp_netif_t *esp_netif)
{
ESP_LOGI(TAG, "Netif started");
s_netif_started = true;
return ESP_OK;
}
esp_err_t esp_netif_stop(esp_netif_t *esp_netif)
{
ESP_LOGI(TAG, "Netif stopped");
s_netif_started = false;
return ESP_OK;
}
//
// IO translate functions
//
void esp_netif_free_rx_buffer(void *h, void* buffer)
{
esp_netif_t *esp_netif = h;
esp_netif->driver_free_rx_buffer(esp_netif->driver_handle, buffer);
}
esp_err_t esp_netif_transmit(esp_netif_t *esp_netif, void* data, size_t len)
{
ESP_LOGV(TAG, "Transmitting data: ptr:%p, size:%d", data, len);
return (esp_netif->driver_transmit)(esp_netif->driver_handle, data, len);
}
esp_err_t esp_netif_receive(esp_netif_t *esp_netif, void *buffer, size_t len, void *eb)
{
ESP_LOGV(TAG, "Received data: ptr:%p, size:%d", buffer, len);
esp_netif_transmit(esp_netif, buffer, len);
if (eb) {
esp_netif_free_rx_buffer(esp_netif, eb);
}
return ESP_OK;
}
esp_err_t esp_netif_dhcpc_stop(esp_netif_t *esp_netif)
{
return ESP_ERR_NOT_SUPPORTED;
}
esp_err_t esp_netif_dhcpc_start(esp_netif_t *esp_netif)
{
return ESP_ERR_NOT_SUPPORTED;
}
esp_err_t esp_netif_dhcps_get_status(esp_netif_t *esp_netif, esp_netif_dhcp_status_t *status)
{
return ESP_ERR_NOT_SUPPORTED;
}
esp_err_t esp_netif_dhcpc_get_status(esp_netif_t *esp_netif, esp_netif_dhcp_status_t *status)
{
return ESP_ERR_NOT_SUPPORTED;
}
esp_err_t esp_netif_dhcps_start(esp_netif_t *esp_netif)
{
return ESP_ERR_NOT_SUPPORTED;
}
esp_err_t esp_netif_dhcps_stop(esp_netif_t *esp_netif)
{
return ESP_ERR_NOT_SUPPORTED;
}
esp_err_t esp_netif_set_hostname(esp_netif_t *esp_netif, const char *hostname)
{
return ESP_ERR_NOT_SUPPORTED;
}
esp_err_t esp_netif_get_hostname(esp_netif_t *esp_netif, const char **hostname)
{
return ESP_ERR_NOT_SUPPORTED;
}
esp_err_t esp_netif_up(esp_netif_t *esp_netif)
{
ESP_LOGI(TAG, "Netif going up");
s_netif_up = true;
return ESP_OK;
}
esp_err_t esp_netif_down(esp_netif_t *esp_netif)
{
ESP_LOGI(TAG, "Netif going down");
s_netif_up = false;
return ESP_OK;
}
bool esp_netif_is_netif_up(esp_netif_t *esp_netif)
{
return s_netif_up;
}
esp_err_t esp_netif_get_old_ip_info(esp_netif_t *esp_netif, esp_netif_ip_info_t *ip_info)
{
ESP_LOGD(TAG, "%s esp_netif:%p", __func__, esp_netif);
if (esp_netif == NULL || ip_info == NULL) {
return ESP_ERR_INVALID_ARG;
}
memcpy(ip_info, esp_netif->ip_info_old, sizeof(esp_netif_ip_info_t));
return ESP_OK;
}
esp_err_t esp_netif_get_ip_info(esp_netif_t *esp_netif, esp_netif_ip_info_t *ip_info)
{
ESP_LOGD(TAG, "%s esp_netif:%p", __func__, esp_netif);
if (esp_netif == NULL || ip_info == NULL) {
return ESP_ERR_INVALID_ARG;
}
memcpy(ip_info, esp_netif->ip_info, sizeof(esp_netif_ip_info_t));
return ESP_OK;
}
bool esp_netif_is_valid_static_ip(esp_netif_ip_info_t *ip_info)
{
return true;
}
esp_err_t esp_netif_set_old_ip_info(esp_netif_t *esp_netif, const esp_netif_ip_info_t *ip_info)
{
ESP_LOGD(TAG, "%s esp_netif:%p", __func__, esp_netif);
if (esp_netif == NULL || ip_info == NULL) {
return ESP_ERR_INVALID_ARG;
}
memcpy(esp_netif->ip_info_old, ip_info, sizeof(esp_netif_ip_info_t));
return ESP_OK;
}
esp_err_t esp_netif_set_dns_info(esp_netif_t *esp_netif, esp_netif_dns_type_t type, esp_netif_dns_info_t *dns)
{
return ESP_ERR_NOT_SUPPORTED;
}
esp_err_t esp_netif_get_dns_info(esp_netif_t *esp_netif, esp_netif_dns_type_t type, esp_netif_dns_info_t *dns)
{
return ESP_ERR_NOT_SUPPORTED;
}
esp_err_t esp_netif_get_sta_list(const wifi_sta_list_t *wifi_sta_list, esp_netif_sta_list_t *netif_sta_list)
{
return ESP_ERR_NOT_SUPPORTED;
}
esp_err_t esp_netif_create_ip6_linklocal(esp_netif_t *esp_netif)
{
return ESP_ERR_NOT_SUPPORTED;
}
esp_err_t esp_netif_get_ip6_linklocal(esp_netif_t *esp_netif, esp_ip6_addr_t *if_ip6)
{
return ESP_ERR_NOT_SUPPORTED;
}
esp_netif_flags_t esp_netif_get_flags(esp_netif_t *esp_netif)
{
return esp_netif->flags;
}
const char *esp_netif_get_ifkey(esp_netif_t *esp_netif)
{
return esp_netif->if_key;
}
const char *esp_netif_get_desc(esp_netif_t *esp_netif)
{
return esp_netif->if_desc;
}
uint32_t esp_netif_get_event_id(esp_netif_t *esp_netif, esp_netif_ip_event_type_t event_type)
{
return 0;
}
esp_err_t esp_netif_dhcps_option(esp_netif_t *esp_netif, esp_netif_dhcp_option_mode_t opt_op, esp_netif_dhcp_option_id_t opt_id, void *opt_val,
uint32_t opt_len)
{
return ESP_ERR_NOT_SUPPORTED;
}
esp_err_t esp_netif_dhcpc_option(esp_netif_t *esp_netif, esp_netif_dhcp_option_mode_t opt_op, esp_netif_dhcp_option_id_t opt_id, void *opt_val,
uint32_t opt_len)
{
return ESP_ERR_NOT_SUPPORTED;
}
int esp_netif_get_netif_impl_index(esp_netif_t *esp_netif)
{
return 0;
}
#endif /* CONFIG_ESP_NETIF_LOOPBACK */

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,41 @@
// Copyright 2019 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "esp_netif.h"
#include "esp_netif_lwip_internal.h"
#include "netif/wlanif.h"
#include "netif/ethernetif.h"
//
// Purpose of this object is to define default network stack configuration
// of basic types of interfaces using lwip network stack
//
static const struct esp_netif_netstack_config s_eth_netif_config = {
.init_fn = ethernetif_init,
.input_fn = ethernetif_input
};
static const struct esp_netif_netstack_config s_wifi_netif_config_ap = {
.init_fn = wlanif_init_ap,
.input_fn = wlanif_input
};
static const struct esp_netif_netstack_config s_wifi_netif_config_sta = {
.init_fn = wlanif_init_sta,
.input_fn = wlanif_input
};
const esp_netif_netstack_config_t *_g_esp_netif_netstack_default_eth = &s_eth_netif_config;
const esp_netif_netstack_config_t *_g_esp_netif_netstack_default_wifi_sta = &s_wifi_netif_config_sta;
const esp_netif_netstack_config_t *_g_esp_netif_netstack_default_wifi_ap = &s_wifi_netif_config_ap;

View file

@ -0,0 +1,47 @@
// Copyright 2015-2018 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include "esp_netif.h"
#include "lwip/netif.h"
// LWIP netif specific network stack configuration
struct esp_netif_netstack_config {
err_t (*init_fn)(struct netif*);
void (*input_fn)(struct netif *netif, void *buffer, size_t len, void *eb);
};
struct esp_netif_api_msg_s;
typedef int (*esp_netif_api_fn)(struct esp_netif_api_msg_s *msg);
typedef struct esp_netif_api_msg_s {
int type; /**< The first field MUST be int */
int ret;
esp_netif_api_fn api_fn;
esp_netif_t *esp_netif;
void *data;
} esp_netif_api_msg_t;
typedef struct esp_netif_dns_param_s {
esp_netif_dns_type_t dns_type;
esp_netif_dns_info_t *dns_info;
} esp_netif_dns_param_t;
typedef struct esp_netif_ip_lost_timer_s {
bool timer_running;
} esp_netif_ip_lost_timer_t;

View file

@ -0,0 +1,43 @@
// Copyright 2019 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <string.h>
#include "esp_netif.h"
#include "esp_netif_sta_list.h"
#include "dhcpserver/dhcpserver.h"
#include "esp_log.h"
#if CONFIG_ESP_NETIF_TCPIP_LWIP
static const char *TAG = "esp_netif_sta_list";
esp_err_t esp_netif_get_sta_list(const wifi_sta_list_t *wifi_sta_list, esp_netif_sta_list_t *netif_sta_list)
{
ESP_LOGD(TAG, "%s entered", __func__);
if ((wifi_sta_list == NULL) || (netif_sta_list == NULL)) {
return ESP_ERR_ESP_NETIF_INVALID_PARAMS;
}
memset(netif_sta_list, 0, sizeof(esp_netif_sta_list_t));
netif_sta_list->num = wifi_sta_list->num;
for (int i = 0; i < wifi_sta_list->num; i++) {
memcpy(netif_sta_list->sta[i].mac, wifi_sta_list->sta[i].mac, 6);
dhcp_search_ip_on_mac(netif_sta_list->sta[i].mac, (ip4_addr_t*)&netif_sta_list->sta[i].ip);
}
return ESP_OK;
}
#endif // CONFIG_ESP_NETIF_TCPIP_LWIP

View file

@ -0,0 +1,148 @@
// Copyright 2015-2019 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef _ESP_NETIF_PRIVATE_H_
#define _ESP_NETIF_PRIVATE_H_
#define ESP_NETIF_CALL_CHECK(info, api_call, ret) \
do{\
esp_err_t __err = (api_call);\
if ((ret) != __err) {\
ESP_LOGE(TAG, "%s %d %s ret=0x%X", __FUNCTION__, __LINE__, (info), __err);\
return;\
}\
} while(0)
/**
* @brief Cause the TCP/IP stack to start the ESP-NETIF instance interface
*
* @param[in] esp_netif Handle to esp-netif instance
*
* @return
* - ESP_OK
* - ESP_ERR_ESP_NETIF_INVALID_PARAMS
* - ESP_ERR_NO_MEM
*/
esp_err_t esp_netif_start(esp_netif_t *esp_netif);
/**
* @brief Cause the TCP/IP stack to stop a network interface defined as ESP-NETIF instance
*
* Causes TCP/IP stack to clean up this interface. This includes stopping the DHCP server or client, if they are started.
*
* @note To stop an interface from application code, the media driver-specific API (esp_wifi_stop() or esp_eth_stop())
* shall be called, the driver layer will then send a stop event and the event handler should call this API.
*
* @param[in] esp_netif Handle to esp-netif instance
*
* @return
* - ESP_OK
* - ESP_ERR_ESP_NETIF_INVALID_PARAMS
* - ESP_ERR_ESP_NETIF_IF_NOT_READY
*/
esp_err_t esp_netif_stop(esp_netif_t *esp_netif);
/**
* @brief Cause the TCP/IP stack to bring up an interface
* This function is called automatically by default called from event handlers/actions
*
* @note This function is not normally used with Wi-Fi AP interface. If the AP interface is started, it is up.
*
* @param[in] esp_netif Handle to esp-netif instance
*
* @return
* - ESP_OK
* - ESP_ERR_ESP_NETIF_IF_NOT_READY
*/
esp_err_t esp_netif_up(esp_netif_t *esp_netif);
/**
* @brief Cause the TCP/IP stack to shutdown an interface
* This function is called automatically by default called from event handlers/actions
*
* @note This function is not normally used with Wi-Fi AP interface. If the AP interface is stopped, it is down.
*
* @param[in] esp_netif Handle to esp-netif instance
*
* @return
* - ESP_OK
* - ESP_ERR_ESP_NETIF_INVALID_PARAMS - parameter error
*/
esp_err_t esp_netif_down(esp_netif_t *esp_netif);
/**
* @brief Returns true if underlying TCP/IP stack finds the ip_info as valid static address
*
* @param[in] ip_info
* @return true if address assumed to be valid static IP address
*/
bool esp_netif_is_valid_static_ip(esp_netif_ip_info_t *ip_info);
/**
* @brief Adds created interface to the list of netifs
*
* @param[in] esp_netif Handle to esp-netif instance
*
* @return
* - ESP_OK -- Success
* - ESP_ERR_NO_MEM -- Cannot be added due to memory allocation failure
*/
esp_err_t esp_netif_add_to_list(esp_netif_t* netif);
/**
* @brief Removes interface to be destroyed from the list of netifs
*
* @param[in] esp_netif Handle to esp-netif instance
*
* @return
* - ESP_OK -- Success
* - ESP_ERR_NOT_FOUND -- This netif was not found in the netif list
*/
esp_err_t esp_netif_remove_from_list(esp_netif_t* netif);
/**
* @brief Iterates over list of interfaces without list locking. Returns first netif if NULL given as parameter
*
* Used for bulk search loops to avoid locking and unlocking every iteration. esp_netif_list_lock and esp_netif_list_unlock
* must be used to guard the search loop
*
* @param[in] esp_netif Handle to esp-netif instance
*
* @return First netif from the list if supplied parameter is NULL, next one otherwise
*/
esp_netif_t* esp_netif_next_unsafe(esp_netif_t* netif);
/**
* @brief Locking network interface list. Use only in connection with esp_netif_next_unsafe
*
* @return ESP_OK on success, specific mutex error if failed to lock
*/
esp_err_t esp_netif_list_lock(void);
/**
* @brief Unlocking network interface list. Use only in connection with esp_netif_next_unsafe
*
*/
void esp_netif_list_unlock(void);
/**
* @brief Iterates over list of registered interfaces to check if supplied netif is listed
*
* @param esp_netif network interface to check
*
* @return true if supplied interface is listed
*/
bool esp_netif_is_netif_listed(esp_netif_t *esp_netif);
#endif //_ESP_NETIF_PRIVATE_H_

View file

@ -0,0 +1,5 @@
set(COMPONENT_SRCDIRS ".")
set(COMPONENT_PRIV_INCLUDEDIRS "../private_include" ".")
set(COMPONENT_PRIV_REQUIRES unity test_utils esp_netif nvs_flash)
register_component()

View file

@ -0,0 +1,5 @@
#
#Component Makefile
#
COMPONENT_PRIV_INCLUDEDIRS := ../private_include .
COMPONENT_ADD_LDFLAGS = -Wl,--whole-archive -l$(COMPONENT_NAME) -Wl,--no-whole-archive

View file

@ -0,0 +1,189 @@
#include "unity.h"
#include "test_utils.h"
#include "esp_netif.h"
#include "esp_wifi.h"
#include "nvs_flash.h"
TEST_CASE("esp_netif: init and destroy", "[esp_netif]")
{
esp_netif_config_t cfg = ESP_NETIF_DEFAULT_WIFI_STA();
esp_netif_t *esp_netif = esp_netif_new(NULL);
TEST_ASSERT_EQUAL(NULL, esp_netif);
esp_netif = esp_netif_new(&cfg);
TEST_ASSERT_NOT_EQUAL(NULL, esp_netif);
esp_netif_destroy(esp_netif);
}
TEST_CASE("esp_netif: get from if_key", "[esp_netif][leaks=0]")
{
// init default netif
esp_netif_config_t cfg = ESP_NETIF_DEFAULT_WIFI_STA();
esp_netif_t *esp_netif = esp_netif_new(&cfg);
TEST_ASSERT_NOT_NULL(esp_netif);
// check it's accessible by key
TEST_ASSERT_EQUAL(esp_netif, esp_netif_get_handle_from_ifkey("WIFI_STA_DEF"));
// destroy it
esp_netif_destroy(esp_netif);
// check it's also destroyed in list
TEST_ASSERT_EQUAL(NULL, esp_netif_get_handle_from_ifkey("WIFI_STA_DEF"));
}
TEST_CASE("esp_netif: create and delete multiple netifs", "[esp_netif][leaks=0]")
{
// interface key has to be a unique identifier
const char* if_keys[] = { "if1", "if2", "if3", "if4", "if5", "if6", "if7", "if8", "if9" };
const int nr_of_netifs = sizeof(if_keys)/sizeof(char*);
esp_netif_t *netifs[nr_of_netifs];
// create 10 wifi stations
for (int i=0; i<nr_of_netifs; ++i) {
esp_netif_inherent_config_t base_netif_config = { .if_key = if_keys[i]};
esp_netif_config_t cfg = { .base = &base_netif_config, .stack = ESP_NETIF_NETSTACK_DEFAULT_WIFI_STA };
netifs[i] = esp_netif_new(&cfg);
TEST_ASSERT_NOT_NULL(netifs[i]);
}
// there's no AP within created stations
TEST_ASSERT_EQUAL(NULL, esp_netif_get_handle_from_ifkey("WIFI_AP_DEF"));
// destroy
for (int i=0; i<nr_of_netifs; ++i) {
esp_netif_destroy(netifs[i]);
}
}
TEST_CASE("esp_netif: test dhcp client state transitions for wifi station", "[esp_netif]")
{
// init default wifi netif
test_case_uses_tcpip();
TEST_ESP_OK(nvs_flash_init());
esp_netif_config_t cfg = ESP_NETIF_DEFAULT_WIFI_STA();
esp_netif_t *sta = esp_netif_new(&cfg);
TEST_ASSERT_NOT_NULL(sta);
esp_netif_attach_wifi_station(sta);
wifi_init_config_t wifi_cfg = WIFI_INIT_CONFIG_DEFAULT();
TEST_ESP_OK(esp_wifi_init(&wifi_cfg));
esp_netif_dhcp_status_t state;
// testing DHCP states per netif state transitions
esp_netif_action_start(sta, NULL, 0, NULL);
TEST_ASSERT_EQUAL(ESP_OK, esp_netif_dhcpc_get_status(sta, &state));
TEST_ASSERT_EQUAL(ESP_NETIF_DHCP_INIT, state);
esp_netif_action_connected(sta, NULL, 0, NULL);
TEST_ASSERT_EQUAL(ESP_OK, esp_netif_dhcpc_get_status(sta, &state));
TEST_ASSERT_EQUAL(ESP_NETIF_DHCP_STARTED, state);
esp_netif_action_stop(sta, NULL, 0, NULL);
TEST_ASSERT_EQUAL(ESP_OK, esp_netif_dhcpc_get_status(sta, &state));
TEST_ASSERT_EQUAL(ESP_NETIF_DHCP_INIT, state);
// destroy default wifi netif
esp_netif_destroy(sta);
TEST_ASSERT(esp_wifi_stop() == ESP_OK);
TEST_ASSERT(esp_wifi_deinit() == ESP_OK);
nvs_flash_deinit();
}
TEST_CASE("esp_netif: test dhcp server state transitions for wifi soft AP", "[esp_netif]")
{
// init default wifi netif
test_case_uses_tcpip();
TEST_ESP_OK(nvs_flash_init());
esp_netif_config_t cfg = ESP_NETIF_DEFAULT_WIFI_AP();
esp_netif_t *ap = esp_netif_new(&cfg);
TEST_ASSERT_NOT_NULL(ap);
esp_netif_attach_wifi_station(ap);
wifi_init_config_t wifi_cfg = WIFI_INIT_CONFIG_DEFAULT();
TEST_ESP_OK(esp_wifi_init(&wifi_cfg));
esp_netif_dhcp_status_t state;
// testing DHCP server states per netif state transitions
esp_netif_action_start(ap, NULL, 0, NULL);
TEST_ASSERT_EQUAL(ESP_OK, esp_netif_dhcps_get_status(ap, &state));
TEST_ASSERT_EQUAL(ESP_NETIF_DHCP_STARTED, state);
esp_netif_action_stop(ap, NULL, 0, NULL);
TEST_ASSERT_EQUAL(ESP_OK, esp_netif_dhcps_get_status(ap, &state));
TEST_ASSERT_EQUAL(ESP_NETIF_DHCP_INIT, state);
// destroy default wifi netif
esp_netif_destroy(ap);
TEST_ASSERT(esp_wifi_stop() == ESP_OK);
TEST_ASSERT(esp_wifi_deinit() == ESP_OK);
nvs_flash_deinit();
}
TEST_CASE("esp_netif: test dhcp state transitions for mesh netifs", "[esp_netif]")
{
esp_netif_t *ap = NULL;
esp_netif_t *sta = NULL;
esp_netif_dhcp_status_t state;
// init two mesh network interfaces
test_case_uses_tcpip();
TEST_ESP_OK(nvs_flash_init());
TEST_ESP_OK(esp_event_loop_create_default());
TEST_ESP_OK(esp_netif_create_default_wifi_mesh_netifs(&sta, &ap));
TEST_ASSERT_NOT_NULL(sta);
TEST_ASSERT_NOT_NULL(ap);
wifi_init_config_t wifi_cfg = WIFI_INIT_CONFIG_DEFAULT();
TEST_ESP_OK(esp_wifi_init(&wifi_cfg));
// test both server and client are *not* STARTED after interfaces created
TEST_ESP_OK(esp_netif_dhcpc_get_status(sta, &state));
TEST_ASSERT_NOT_EQUAL(ESP_NETIF_DHCP_STARTED, state);
TEST_ESP_OK(esp_netif_dhcps_get_status(ap, &state));
TEST_ASSERT_NOT_EQUAL(ESP_NETIF_DHCP_STARTED, state);
// test both server and client are still *not* STARTED after start
esp_netif_action_start(ap, NULL, 0, NULL);
esp_netif_action_start(sta, NULL, 0, NULL);
TEST_ESP_OK(esp_netif_dhcpc_get_status(sta, &state));
TEST_ASSERT_NOT_EQUAL(ESP_NETIF_DHCP_STARTED, state);
TEST_ESP_OK(esp_netif_dhcps_get_status(ap, &state));
TEST_ASSERT_NOT_EQUAL(ESP_NETIF_DHCP_STARTED, state);
// test both server and client are still *not* STARTED even after connect
esp_netif_action_connected(ap, NULL, 0, NULL);
esp_netif_action_connected(sta, NULL, 0, NULL);
TEST_ESP_OK(esp_netif_dhcpc_get_status(sta, &state));
TEST_ASSERT_NOT_EQUAL(ESP_NETIF_DHCP_STARTED, state);
TEST_ESP_OK(esp_netif_dhcps_get_status(ap, &state));
TEST_ASSERT_NOT_EQUAL(ESP_NETIF_DHCP_STARTED, state);
// test station gets promoted to be a root (so DHCP client started manually) and client is in STATED state
esp_netif_dhcpc_start(sta);
esp_netif_action_connected(sta, NULL, 0, NULL);
TEST_ESP_OK(esp_netif_dhcpc_get_status(sta, &state));
TEST_ASSERT_EQUAL(ESP_NETIF_DHCP_STARTED, state);
esp_netif_dhcpc_stop(sta);
// test both server and client are still *not* STARTED even after stop
esp_netif_action_stop(sta, NULL, 0, NULL);
esp_netif_action_stop(ap, NULL, 0, NULL);
TEST_ESP_OK(esp_netif_dhcpc_get_status(sta, &state));
TEST_ASSERT_NOT_EQUAL(ESP_NETIF_DHCP_STARTED, state);
TEST_ESP_OK(esp_netif_dhcps_get_status(ap, &state));
TEST_ASSERT_NOT_EQUAL(ESP_NETIF_DHCP_STARTED, state);
// destroy event_loop, netifs, wifi, nvs
TEST_ESP_OK(esp_event_loop_delete_default());
esp_netif_destroy(ap);
esp_netif_destroy(sta);
TEST_ASSERT(esp_wifi_stop() == ESP_OK);
TEST_ASSERT(esp_wifi_deinit() == ESP_OK);
nvs_flash_deinit();
}

View file

@ -15,8 +15,10 @@ idf_component_register(SRCS "src/coexist.c"
"src/smartconfig.c"
"src/smartconfig_ack.c"
"src/wifi_init.c"
"src/wifi_default.c"
"src/wifi_netif.c"
INCLUDE_DIRS "include" "${idf_target}/include"
PRIV_REQUIRES wpa_supplicant nvs_flash
PRIV_REQUIRES wpa_supplicant nvs_flash esp_netif
LDFRAGMENTS "${ldfragments}")
idf_build_get_property(build_dir BUILD_DIR)

View file

@ -88,6 +88,7 @@
#include "esp_wifi.h"
#include "esp_wifi_types.h"
#include "esp_mesh_internal.h"
#include "lwip/ip_addr.h"
#ifdef __cplusplus
extern "C" {

View file

@ -15,4 +15,84 @@
#ifndef _ESP_WIFI_DEFAULT_H
#define _ESP_WIFI_DEFAULT_H
/**
* @brief Attaches wifi station interface to supplied netif
*
* @param esp_netif instance to attach the wifi station to
*
* @return
* - ESP_OK on success
* - ESP_FAIL if attach failed
*/
esp_err_t esp_netif_attach_wifi_station(esp_netif_t *esp_netif);
/**
* @brief Attaches wifi soft AP interface to supplied netif
*
* @param esp_netif instance to attach the wifi AP to
*
* @return
* - ESP_OK on success
* - ESP_FAIL if attach failed
*/
esp_err_t esp_netif_attach_wifi_ap(esp_netif_t *esp_netif);
/**
* @brief Sets default wifi event handlers for STA interface
*
* @return
* - ESP_OK on success, error returned from esp_event_handler_register if failed
*/
esp_err_t esp_wifi_set_default_wifi_sta_handlers(void);
/**
* @brief Sets default wifi event handlers for STA interface
*
* @return
* - ESP_OK on success, error returned from esp_event_handler_register if failed
*/
esp_err_t esp_wifi_set_default_wifi_ap_handlers(void);
/**
* @brief Clears default wifi event handlers for supplied network interface
*
* @param esp_netif instance of corresponding if object
*
* @return
* - ESP_OK on success, error returned from esp_event_handler_register if failed
*/
esp_err_t esp_wifi_clear_default_wifi_driver_and_handlers(void *esp_netif);
/**
* @brief Creates default WIFI AP. In case of any init error this API aborts.
*
* @return pointer to esp-netif instance
*/
esp_netif_t* esp_netif_create_default_wifi_ap(void);
/**
* @brief Creates default WIFI STA. In case of any init error this API aborts.
*
* @return pointer to esp-netif instance
*/
esp_netif_t* esp_netif_create_default_wifi_sta(void);
/**
* @brief Creates default STA and AP network interfaces for esp-mesh.
*
* Both netifs are almost identical to the default station and softAP, but with
* DHCP client and server disabled. Please note that the DHCP client is typically
* enabled only if the device is promoted to a root node.
*
* Returns created interfaces which could be ignored setting parameters to NULL
* if an application code does not need to save the interface instances
* for further processing.
*
* @param[out] p_netif_sta pointer where the resultant STA interface is saved (if non NULL)
* @param[out] p_netif_ap pointer where the resultant AP interface is saved (if non NULL)
*
* @return ESP_OK on success
*/
esp_err_t esp_netif_create_default_wifi_mesh_netifs(esp_netif_t **p_netif_sta, esp_netif_t **p_netif_ap);
#endif //_ESP_WIFI_DEFAULT_H

View file

@ -0,0 +1,84 @@
// Copyright 2019 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef _ESP_WIFI_NETIF_H
#define _ESP_WIFI_NETIF_H
/**
* @brief Number of WiFi interfaces used by wifi-netif abstraction
*/
#define MAX_WIFI_IFS (2)
/**
* @brief Forward declaration of WiFi interface handle
*/
typedef struct wifi_netif_driver* wifi_netif_driver_t;
/**
* @brief Creates wifi driver instance to be used with esp-netif
*
* @param wifi_if wifi interface type (station, softAP)
*
* @return
* - pointer to wifi interface handle on success
* - NULL otherwise
*/
wifi_netif_driver_t esp_wifi_create_if_driver(wifi_interface_t wifi_if);
/**
* @brief Destroys wifi driver instance
*
* @param h pointer to wifi interface handle
*
*/
void esp_wifi_destroy_if_driver(wifi_netif_driver_t h);
/**
* @brief Return mac of specified wifi driver instance
*
* @param[in] ifx pointer to wifi interface handle
* @param[out] mac output mac address
*
* @return ESP_OK on success
*
*/
esp_err_t esp_wifi_get_if_mac(wifi_netif_driver_t ifx, uint8_t mac[6]);
/**
* @brief Return true if the supplied interface instance is ready after start.
* Typically used when registering on receive callback, which ought to be
* installed as soon as AP started, but once STA gets connected.
*
* @param[in] ifx pointer to wifi interface handle
*
* @return
* - true if ready after intertace started (typically Access Point type)
* - false if ready once intertace connected (typically for Station type)
*/
bool esp_wifi_is_if_ready_when_started(wifi_netif_driver_t ifx);
/**
* @brief Register interface receive callback function with argument
*
* @param[in] ifx pointer to wifi interface handle
* @param[in] fn funtion to be registered (typically esp_netif_receive)
* @param[in] arg argument to be supplied to registered function (typically esp_netif ptr)
*
* @return ESP_OK on success
*
*/
esp_err_t esp_wifi_register_if_rxcb(wifi_netif_driver_t ifx, esp_netif_receive_t fn, void * arg);
#endif //_ESP_WIFI_NETIF_H

View file

@ -21,7 +21,7 @@
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "lwip/sockets.h"
#include "tcpip_adapter.h"
#include "esp_netif.h"
#include "esp_log.h"
#include "esp_wifi.h"
#include "esp_event.h"
@ -69,7 +69,7 @@ static int sc_ack_send_get_errno(int fd)
static void sc_ack_send_task(void *pvParameters)
{
sc_ack_t *ack = (sc_ack_t *)pvParameters;
tcpip_adapter_ip_info_t local_ip;
esp_netif_ip_info_t local_ip;
uint8_t remote_ip[4];
memcpy(remote_ip, ack->ctx.ip, sizeof(remote_ip));
int remote_port = (ack->type == SC_TYPE_ESPTOUCH) ? SC_ACK_TOUCH_SERVER_PORT : SC_ACK_AIRKISS_SERVER_PORT;
@ -94,7 +94,7 @@ static void sc_ack_send_task(void *pvParameters)
while (s_sc_ack_send) {
/* Get local IP address of station */
ret = tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_STA, &local_ip);
ret = esp_netif_get_ip_info(esp_netif_get_handle_from_ifkey("WIFI_STA_DEF"), &local_ip);
if ((ESP_OK == ret) && (local_ip.ip.addr != INADDR_ANY)) {
/* If ESP touch, smartconfig ACK contains local IP address. */
if (ack->type == SC_TYPE_ESPTOUCH) {

View file

@ -0,0 +1,368 @@
// Copyright 2019 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "esp_wifi.h"
#include "esp_netif.h"
#include "esp_log.h"
#include "esp_private/wifi.h"
#include "esp_wifi_netif.h"
#include <string.h>
//
// Purpose of this module is to provide basic wifi initialization setup for
// default station and AP and to register default handles for these interfaces
//
static const char* TAG = "wifi_init_default";
static esp_netif_t *s_wifi_netifs[MAX_WIFI_IFS] = { NULL };
static bool wifi_default_handlers_set = false;
static esp_err_t disconnect_and_destroy(esp_netif_t* esp_netif);
//
// Default event handlers
//
/**
* @brief Wifi start action when station or AP get started
*/
static void wifi_start(void *esp_netif, esp_event_base_t base, int32_t event_id, void *data)
{
uint8_t mac[6];
esp_err_t ret;
ESP_LOGD(TAG, "%s esp-netif:%p event-id%d", __func__, esp_netif, event_id);
wifi_netif_driver_t driver = esp_netif_get_io_driver(esp_netif);
if ((ret = esp_wifi_get_if_mac(driver, mac)) != ESP_OK) {
ESP_LOGE(TAG, "esp_wifi_get_mac failed with %d", ret);
return;
}
ESP_LOGD(TAG, "WIFI mac address: %x %x %x %x %x %x", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
if (esp_wifi_is_if_ready_when_started(driver)) {
if ((ret = esp_wifi_register_if_rxcb(driver, esp_netif_receive, esp_netif)) != ESP_OK) {
ESP_LOGE(TAG, "esp_wifi_register_if_rxcb for if=%p failed with %d", driver, ret);
return;
}
}
esp_netif_set_mac(esp_netif, mac);
esp_netif_action_start(esp_netif, base, event_id, data);
}
/**
* @brief Wifi default handlers for specific events for station and APs
*/
static void wifi_default_action_sta_start(void *arg, esp_event_base_t base, int32_t event_id, void *data)
{
if (s_wifi_netifs[WIFI_IF_STA] != NULL) {
wifi_start(s_wifi_netifs[WIFI_IF_STA], base, event_id, data);
}
}
static void wifi_default_action_sta_stop(void *arg, esp_event_base_t base, int32_t event_id, void *data)
{
if (s_wifi_netifs[WIFI_IF_STA] != NULL) {
esp_netif_action_stop(s_wifi_netifs[WIFI_IF_STA], base, event_id, data);
}
}
static void wifi_default_action_sta_connected(void *arg, esp_event_base_t base, int32_t event_id, void *data)
{
if (s_wifi_netifs[WIFI_IF_STA] != NULL) {
esp_err_t ret;
esp_netif_t *esp_netif = s_wifi_netifs[WIFI_IF_STA];
wifi_netif_driver_t driver = esp_netif_get_io_driver(esp_netif);
if (!esp_wifi_is_if_ready_when_started(driver)) {
// if interface not ready when started, rxcb to be registered on connection
if ((ret = esp_wifi_register_if_rxcb(driver, esp_netif_receive, esp_netif)) != ESP_OK) {
ESP_LOGE(TAG, "esp_wifi_register_if_rxcb for if=%p failed with %d", driver, ret);
return;
}
}
esp_netif_action_connected(s_wifi_netifs[WIFI_IF_STA], base, event_id, data);
}
}
static void wifi_default_action_sta_disconnected(void *arg, esp_event_base_t base, int32_t event_id, void *data)
{
if (s_wifi_netifs[WIFI_IF_STA] != NULL) {
esp_netif_action_disconnected(s_wifi_netifs[WIFI_IF_STA], base, event_id, data);
}
}
static void wifi_default_action_ap_start(void *arg, esp_event_base_t base, int32_t event_id, void *data)
{
if (s_wifi_netifs[WIFI_IF_AP] != NULL) {
wifi_start(s_wifi_netifs[WIFI_IF_AP], base, event_id, data);
}
}
static void wifi_default_action_ap_stop(void *arg, esp_event_base_t base, int32_t event_id, void *data)
{
if (s_wifi_netifs[WIFI_IF_AP] != NULL) {
esp_netif_action_stop(s_wifi_netifs[WIFI_IF_AP], base, event_id, data);
}
}
static void wifi_default_action_sta_got_ip(void *arg, esp_event_base_t base, int32_t event_id, void *data)
{
if (s_wifi_netifs[WIFI_IF_STA] != NULL) {
ESP_LOGD(TAG, "Got IP wifi default handler entered");
int ret = esp_wifi_internal_set_sta_ip();
if (ret != ESP_OK) {
ESP_LOGI(TAG, "esp_wifi_internal_set_sta_ip failed with %d", ret);
}
esp_netif_action_got_ip(s_wifi_netifs[WIFI_IF_STA], base, event_id, data);
}
}
/**
* @brief Clear default handlers
*/
esp_err_t _esp_wifi_clear_default_wifi_handlers(void)
{
esp_event_handler_unregister(WIFI_EVENT, WIFI_EVENT_STA_START, wifi_default_action_sta_start);
esp_event_handler_unregister(WIFI_EVENT, WIFI_EVENT_STA_STOP, wifi_default_action_sta_stop);
esp_event_handler_unregister(WIFI_EVENT, WIFI_EVENT_STA_CONNECTED, wifi_default_action_sta_connected);
esp_event_handler_unregister(WIFI_EVENT, WIFI_EVENT_STA_DISCONNECTED, wifi_default_action_sta_disconnected);
esp_event_handler_unregister(WIFI_EVENT, WIFI_EVENT_AP_START, wifi_default_action_ap_start);
esp_event_handler_unregister(WIFI_EVENT, WIFI_EVENT_AP_STOP, wifi_default_action_ap_stop);
esp_event_handler_unregister(IP_EVENT, IP_EVENT_STA_GOT_IP, wifi_default_action_sta_got_ip);
esp_unregister_shutdown_handler((shutdown_handler_t)esp_wifi_stop);
wifi_default_handlers_set = false;
return ESP_OK;
}
/**
* @brief Set default handlers
*/
esp_err_t _esp_wifi_set_default_wifi_handlers(void)
{
if (wifi_default_handlers_set) {
return ESP_OK;
}
esp_err_t err;
err = esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_STA_START, wifi_default_action_sta_start, NULL);
if (err != ESP_OK) {
goto fail;
}
err = esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_STA_STOP, wifi_default_action_sta_stop, NULL);
if (err != ESP_OK) {
goto fail;
}
err = esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_STA_CONNECTED, wifi_default_action_sta_connected, NULL);
if (err != ESP_OK) {
goto fail;
}
err = esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_STA_DISCONNECTED, wifi_default_action_sta_disconnected, NULL);
if (err != ESP_OK) {
goto fail;
}
err = esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_AP_START, wifi_default_action_ap_start, NULL);
if (err != ESP_OK) {
goto fail;
}
err = esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_AP_STOP, wifi_default_action_ap_stop, NULL);
if (err != ESP_OK) {
goto fail;
}
err = esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, wifi_default_action_sta_got_ip, NULL);
if (err != ESP_OK) {
goto fail;
}
err = esp_register_shutdown_handler((shutdown_handler_t)esp_wifi_stop);
if (err != ESP_OK && err != ESP_ERR_INVALID_STATE) {
goto fail;
}
wifi_default_handlers_set = true;
return ESP_OK;
fail:
_esp_wifi_clear_default_wifi_handlers();
return err;
}
/**
* @brief Set default handlers for station (official API)
*/
esp_err_t esp_wifi_set_default_wifi_sta_handlers(void)
{
return _esp_wifi_set_default_wifi_handlers();
}
/**
* @brief Set default handlers for AP (official API)
*/
esp_err_t esp_wifi_set_default_wifi_ap_handlers(void)
{
return _esp_wifi_set_default_wifi_handlers();
}
/**
* @brief Clear default handlers and destroy appropriate objects (official API)
*/
esp_err_t esp_wifi_clear_default_wifi_driver_and_handlers(void *esp_netif)
{
int i;
for (i = 0; i< MAX_WIFI_IFS; ++i) {
// clear internal static pointers to netifs
if (s_wifi_netifs[i] == esp_netif) {
s_wifi_netifs[i] = NULL;
}
// check if all netifs are cleared to delete default handlers
if (s_wifi_netifs[i] != NULL) {
break;
}
}
if (i == MAX_WIFI_IFS) { // if all wifi default netifs are null
ESP_LOGD(TAG, "Clearing wifi default handlers");
_esp_wifi_clear_default_wifi_handlers();
}
return disconnect_and_destroy(esp_netif);
}
//
// Object manipulation
//
/**
* @brief Create and destroy objects
*/
static esp_err_t disconnect_and_destroy(esp_netif_t* esp_netif)
{
wifi_netif_driver_t driver = esp_netif_get_io_driver(esp_netif);
esp_netif_driver_ifconfig_t driver_ifconfig = { };
esp_err_t ret = esp_netif_set_driver_config(esp_netif, &driver_ifconfig);
esp_wifi_destroy_if_driver(driver);
return ret;
}
static esp_err_t create_and_attach(wifi_interface_t wifi_if, esp_netif_t* esp_netif)
{
wifi_netif_driver_t driver = esp_wifi_create_if_driver(wifi_if);
if (driver == NULL) {
ESP_LOGE(TAG, "Failed to create wifi interface handle");
return ESP_FAIL;
}
return esp_netif_attach(esp_netif, driver);
}
esp_err_t esp_netif_attach_wifi_station(esp_netif_t *esp_netif)
{
if (esp_netif == NULL) {
return ESP_ERR_INVALID_ARG;
}
s_wifi_netifs[WIFI_IF_STA] = esp_netif;
return create_and_attach(WIFI_IF_STA, esp_netif);
}
esp_err_t esp_netif_attach_wifi_ap(esp_netif_t *esp_netif)
{
if (esp_netif == NULL) {
return ESP_ERR_INVALID_ARG;
}
s_wifi_netifs[WIFI_IF_AP] = esp_netif;
return create_and_attach(WIFI_IF_AP, esp_netif);
}
//
// Default WiFi creation from user code
//
/**
* @brief User init default AP (official API)
*/
esp_netif_t* esp_netif_create_default_wifi_ap(void)
{
esp_netif_config_t cfg = ESP_NETIF_DEFAULT_WIFI_AP();
esp_netif_t *netif = esp_netif_new(&cfg);
assert(netif);
esp_netif_attach_wifi_ap(netif);
esp_wifi_set_default_wifi_ap_handlers();
return netif;
}
/**
* @brief User init default station (official API)
*/
esp_netif_t* esp_netif_create_default_wifi_sta(void)
{
esp_netif_config_t cfg = ESP_NETIF_DEFAULT_WIFI_STA();
esp_netif_t *netif = esp_netif_new(&cfg);
assert(netif);
esp_netif_attach_wifi_station(netif);
esp_wifi_set_default_wifi_sta_handlers();
return netif;
}
/**
* @brief Creates mesh network interfaces based on default STA and AP,
* but without DHCP, this is to be enabled separately only on root node
*/
esp_err_t esp_netif_create_default_wifi_mesh_netifs(esp_netif_t **p_netif_sta, esp_netif_t **p_netif_ap)
{
// Create "almost" default AP, with un-flagged DHCP server
esp_netif_inherent_config_t netif_cfg;
memcpy(&netif_cfg, ESP_NETIF_BASE_DEFAULT_WIFI_AP, sizeof(netif_cfg));
netif_cfg.flags &= ~ESP_NETIF_DHCP_SERVER;
esp_netif_config_t cfg_ap = {
.base = &netif_cfg,
.stack = ESP_NETIF_NETSTACK_DEFAULT_WIFI_AP,
};
esp_netif_t *netif_ap = esp_netif_new(&cfg_ap);
assert(netif_ap);
ESP_ERROR_CHECK(esp_netif_attach_wifi_ap(netif_ap));
ESP_ERROR_CHECK(esp_wifi_set_default_wifi_ap_handlers());
// ...and stop DHCP server to be compatible with former tcpip_adapter (to keep the ESP_NETIF_DHCP_STOPPED state)
ESP_ERROR_CHECK(esp_netif_dhcps_stop(netif_ap));
// Create "almost" default station, but with un-flagged DHCP client
memcpy(&netif_cfg, ESP_NETIF_BASE_DEFAULT_WIFI_STA, sizeof(netif_cfg));
netif_cfg.flags &= ~ESP_NETIF_DHCP_CLIENT;
esp_netif_config_t cfg_sta = {
.base = &netif_cfg,
.stack = ESP_NETIF_NETSTACK_DEFAULT_WIFI_STA,
};
esp_netif_t *netif_sta = esp_netif_new(&cfg_sta);
assert(netif_sta);
ESP_ERROR_CHECK(esp_netif_attach_wifi_station(netif_sta));
ESP_ERROR_CHECK(esp_wifi_set_default_wifi_sta_handlers());
// ...and stop DHCP client (to be started separately if the station were promoted to root)
ESP_ERROR_CHECK(esp_netif_dhcpc_stop(netif_sta));
if (p_netif_sta) {
*p_netif_sta = netif_sta;
}
if (p_netif_ap) {
*p_netif_ap = netif_ap;
}
return ESP_OK;
}

View file

@ -19,6 +19,8 @@
#include "esp_pm.h"
#include "soc/rtc.h"
#include "esp_wpa.h"
#include "esp_netif.h"
#include "tcpip_adapter_compatible/tcpip_adapter_compat.h"
#if (CONFIG_ESP32_WIFI_RX_BA_WIN > CONFIG_ESP32_WIFI_DYNAMIC_RX_BUFFER_NUM)
#error "WiFi configuration check: WARNING, WIFI_RX_BA_WIN should not be larger than WIFI_DYNAMIC_RX_BUFFER_NUM!"
@ -108,7 +110,9 @@ esp_err_t esp_wifi_deinit(void)
ESP_LOGE(TAG, "Failed to deinit Wi-Fi driver (0x%x)", err);
}
#if CONFIG_ESP_NETIF_TCPIP_ADAPTER_COMPATIBLE_LAYER
tcpip_adapter_clear_default_wifi_handlers();
#endif
return err;
}
@ -124,10 +128,12 @@ esp_err_t esp_wifi_init(const wifi_init_config_t *config)
}
}
#endif
#if CONFIG_ESP_NETIF_TCPIP_ADAPTER_COMPATIBLE_LAYER
esp_err_t err = tcpip_adapter_set_default_wifi_handlers();
if (err != ESP_OK) {
ESP_LOGW(TAG, "Failed to set default Wi-Fi event handlers (0x%x)", err);
}
#endif
esp_err_t result = esp_wifi_init_internal(config);
if (result == ESP_OK) {
esp_wifi_set_debug_log();

View file

@ -0,0 +1,146 @@
// Copyright 2019 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "esp_wifi.h"
#include "esp_netif.h"
#include "esp_log.h"
#include "esp_private/wifi.h"
#include "esp_wifi_netif.h"
//
// Purpose of this module is provide object oriented abstraction to wifi interfaces
// in order to integrate wifi as esp-netif driver
//
/**
* @brief WiFi netif driver structure
*/
typedef struct wifi_netif_driver {
esp_netif_driver_base_t base;
wifi_interface_t wifi_if;
}* wifi_netif_driver_t;
static const char* TAG = "wifi_netif";
/**
* @brief Local storage for netif handles and callbacks for specific wifi interfaces
*/
static esp_netif_receive_t s_wifi_rxcbs[MAX_WIFI_IFS] = { NULL };
static esp_netif_t *s_wifi_netifs[MAX_WIFI_IFS] = { NULL };
/**
* @brief WiFi netif driver IO functions, a thin glue layer
* to the original wifi interface API
*/
static esp_err_t wifi_sta_receive(void *buffer, uint16_t len, void *eb)
{
return s_wifi_rxcbs[WIFI_IF_STA](s_wifi_netifs[WIFI_IF_STA], buffer, len, eb);
}
static esp_err_t wifi_ap_receive(void *buffer, uint16_t len, void *eb)
{
return s_wifi_rxcbs[WIFI_IF_AP](s_wifi_netifs[WIFI_IF_AP], buffer, len, eb);
}
static void wifi_free(void *h, void* buffer)
{
esp_wifi_internal_free_rx_buffer(buffer);
}
static esp_err_t wifi_transmit(void *h, void *buffer, size_t len)
{
wifi_netif_driver_t driver = h;
return esp_wifi_internal_tx(driver->wifi_if, buffer, len);
}
static esp_err_t wifi_driver_start(esp_netif_t * esp_netif, void * args)
{
wifi_netif_driver_t driver = args;
driver->base.netif = esp_netif;
esp_netif_driver_ifconfig_t driver_ifconfig = {
.handle = driver,
.transmit = wifi_transmit,
.driver_free_rx_buffer = wifi_free
};
return esp_netif_set_driver_config(esp_netif, &driver_ifconfig);
}
void esp_wifi_destroy_if_driver(wifi_netif_driver_t h)
{
free(h);
}
wifi_netif_driver_t esp_wifi_create_if_driver(wifi_interface_t wifi_if)
{
wifi_netif_driver_t driver = calloc(1, sizeof(struct wifi_netif_driver));
if (driver == NULL) {
ESP_LOGE(TAG, "No memory to create a wifi interface handle");
return NULL;
}
driver->wifi_if = wifi_if;
driver->base.post_attach = wifi_driver_start;
return driver;
}
esp_err_t esp_wifi_get_if_mac(wifi_netif_driver_t ifx, uint8_t mac[6])
{
wifi_interface_t wifi_interface = ifx->wifi_if;
return esp_wifi_get_mac(wifi_interface, mac);
}
bool esp_wifi_is_if_ready_when_started(wifi_netif_driver_t ifx)
{
// WiFi rxcb to be register wifi rxcb on start for AP only, station gets it registered on connect event
return (ifx->wifi_if == WIFI_IF_AP);
}
esp_err_t esp_wifi_register_if_rxcb(wifi_netif_driver_t ifx, esp_netif_receive_t fn, void * arg)
{
if (ifx->base.netif != arg) {
ESP_LOGE(TAG, "Invalid argument: supplied netif=%p does not equal to interface netif=%p", arg, ifx->base.netif);
return ESP_ERR_INVALID_ARG;
}
wifi_interface_t wifi_interface = ifx->wifi_if;
s_wifi_rxcbs[wifi_interface] = fn;
wifi_rxcb_t rxcb = NULL;
esp_err_t ret;
switch (wifi_interface)
{
case WIFI_IF_STA:
rxcb = wifi_sta_receive;
break;
case WIFI_IF_AP:
rxcb = wifi_ap_receive;
break;
default:
break;
}
if (rxcb == NULL) {
ESP_LOGE(TAG, "Unknown wifi interface id if=%d", wifi_interface);
return ESP_ERR_NOT_SUPPORTED;
}
if ((ret = esp_wifi_internal_reg_rxcb(wifi_interface, rxcb)) != ESP_OK) {
ESP_LOGE(TAG, "esp_wifi_internal_reg_rxcb for if=%d failed with %d", wifi_interface, ret);
return ESP_ERR_INVALID_STATE;
}
s_wifi_netifs[wifi_interface] = ifx->base.netif;
return ESP_OK;
}

View file

@ -64,8 +64,7 @@ static void ip_event_handler(void* arg, esp_event_base_t event_base,
case IP_EVENT_STA_GOT_IP:
event = (ip_event_got_ip_t*)event_data;
ESP_LOGI(TAG, "IP_EVENT_STA_GOT_IP");
ESP_LOGI(TAG, "got ip:%s\n",
ip4addr_ntoa(&event->ip_info.ip));
ESP_LOGI(TAG, "got ip:" IPSTR "\n", IP2STR(&event->ip_info.ip));
if (wifi_events) {
xEventGroupSetBits(wifi_events, GOT_IP_EVENT);
}
@ -81,6 +80,9 @@ static esp_err_t event_init(void)
ESP_ERROR_CHECK(esp_event_loop_create_default());
ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &wifi_event_handler, NULL));
ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, ESP_EVENT_ANY_ID, &ip_event_handler, NULL));
esp_netif_create_default_wifi_sta();
esp_netif_create_default_wifi_ap();
return ESP_OK;
}
@ -145,8 +147,8 @@ TEST_CASE("wifi stop and deinit","[wifi]")
}
TEST_ESP_OK(r);
//init tcpip
ESP_LOGI(TAG, EMPH_STR("tcpip_adapter_init"));
tcpip_adapter_init();
ESP_LOGI(TAG, EMPH_STR("esp_netif_init"));
esp_netif_init();
//init event loop
ESP_LOGI(TAG, EMPH_STR("event_init"));
@ -164,7 +166,7 @@ TEST_CASE("wifi stop and deinit","[wifi]")
nvs_flash_deinit();
ESP_LOGI(TAG, "test passed...");
TEST_IGNORE_MESSAGE("this test case is ignored due to the critical memory leak of tcpip_adapter and event_loop.");
TEST_IGNORE_MESSAGE("this test case is ignored due to the critical memory leak of esp_netif and event_loop.");
}
static void start_wifi_as_softap(void)

View file

@ -47,7 +47,7 @@ static void ip_event_handler(void* arg, esp_event_base_t event_base, int32_t eve
case IP_EVENT_STA_GOT_IP:
event = (ip_event_got_ip_t*)event_data;
ESP_LOGI(TAG, "IP_EVENT_STA_GOT_IP");
ESP_LOGI(TAG, "got ip:%s\n", ip4addr_ntoa(&event->ip_info.ip));
ESP_LOGI(TAG, "got ip:" IPSTR, IP2STR(&event->ip_info.ip));
if (wifi_events) {
xEventGroupSetBits(wifi_events, GOT_IP_EVENT);
}
@ -123,9 +123,9 @@ static void wifi_start_stop_task(void* arg)
r = nvs_flash_init();
}
TEST_ESP_OK(r);
//init tcpip
ESP_LOGI(TAG, EMPH_STR("tcpip_adapter_init"));
tcpip_adapter_init();
//init tcpip stack
ESP_LOGI(TAG, EMPH_STR("esp_netif_init"));
esp_netif_init();
//init event loop
ESP_LOGI(TAG, EMPH_STR("event_init"));
event_init();

View file

@ -89,7 +89,6 @@ set(srcs
"port/esp32/debug/lwip_debug.c"
"port/esp32/freertos/sys_arch.c"
"port/esp32/netif/dhcp_state.c"
"port/esp32/netif/nettestif.c"
"port/esp32/netif/wlanif.c")
if(CONFIG_LWIP_PPP_SUPPORT)
@ -134,7 +133,7 @@ idf_component_register(SRCS "${srcs}"
INCLUDE_DIRS "${include_dirs}"
LDFRAGMENTS linker.lf
REQUIRES vfs esp_wifi
PRIV_REQUIRES esp_eth tcpip_adapter nvs_flash)
PRIV_REQUIRES esp_eth esp_netif tcpip_adapter nvs_flash)
# lots of LWIP source files evaluate macros that check address of stack variables
target_compile_options(${COMPONENT_LIB} PRIVATE -Wno-address)

View file

@ -20,7 +20,7 @@
#include "lwip/udp.h"
#include "lwip/mem.h"
#include "lwip/ip_addr.h"
#include "tcpip_adapter.h"
#include "esp_netif.h"
#include "dhcpserver/dhcpserver.h"
#include "dhcpserver/dhcpserver_options.h"
@ -81,7 +81,7 @@ typedef struct _list_node {
static const u32_t magic_cookie = 0x63538263;
static struct udp_pcb *pcb_dhcps = NULL;
static struct netif *dhcps_netif = NULL;
static ip4_addr_t broadcast_dhcps;
static ip4_addr_t server_address;
static ip4_addr_t dns_server = {0};
@ -325,19 +325,19 @@ static u8_t *add_offer_options(u8_t *optptr)
*optptr++ = ip4_addr4(&ipadd);
if (dhcps_router_enabled(dhcps_offer)) {
tcpip_adapter_ip_info_t if_ip;
//bzero(&if_ip, sizeof(struct ip_info));
memset(&if_ip , 0x00, sizeof(tcpip_adapter_ip_info_t));
esp_netif_ip_info_t if_ip;
memset(&if_ip , 0x00, sizeof(esp_netif_ip_info_t));
esp_netif_get_ip_info(dhcps_netif->state, &if_ip);
tcpip_adapter_get_ip_info(ESP_IF_WIFI_AP, &if_ip);
ip4_addr_t* gw_ip = (ip4_addr_t*)&if_ip.gw;
if (!ip4_addr_isany_val(if_ip.gw)) {
if (!ip4_addr_isany_val(*gw_ip)) {
*optptr++ = DHCP_OPTION_ROUTER;
*optptr++ = 4;
*optptr++ = ip4_addr1(&if_ip.gw);
*optptr++ = ip4_addr2(&if_ip.gw);
*optptr++ = ip4_addr3(&if_ip.gw);
*optptr++ = ip4_addr4(&if_ip.gw);
*optptr++ = ip4_addr1(gw_ip);
*optptr++ = ip4_addr2(gw_ip);
*optptr++ = ip4_addr3(gw_ip);
*optptr++ = ip4_addr4(gw_ip);
}
}
@ -525,6 +525,7 @@ static void send_offer(struct dhcps_msg *m, u16_t len)
ip_addr_t ip_temp = IPADDR4_INIT(0x0);
ip4_addr_set(ip_2_ip4(&ip_temp), &broadcast_dhcps);
struct udp_pcb *pcb_dhcps = dhcps_netif->dhcps_pcb;
#if DHCPS_DEBUG
SendOffer_err_t = udp_sendto(pcb_dhcps, p, &ip_temp, DHCPS_CLIENT_PORT);
DHCPS_LOG("dhcps: send_offer>>udp_sendto result %x\n", SendOffer_err_t);
@ -602,6 +603,7 @@ static void send_nak(struct dhcps_msg *m, u16_t len)
ip_addr_t ip_temp = IPADDR4_INIT(0x0);
ip4_addr_set(ip_2_ip4(&ip_temp), &broadcast_dhcps);
struct udp_pcb *pcb_dhcps = dhcps_netif->dhcps_pcb;
#if DHCPS_DEBUG
SendNak_err_t = udp_sendto(pcb_dhcps, p, &ip_temp, DHCPS_CLIENT_PORT);
DHCPS_LOG("dhcps: send_nak>>udp_sendto result %x\n", SendNak_err_t);
@ -678,6 +680,7 @@ static void send_ack(struct dhcps_msg *m, u16_t len)
ip_addr_t ip_temp = IPADDR4_INIT(0x0);
ip4_addr_set(ip_2_ip4(&ip_temp), &broadcast_dhcps);
struct udp_pcb *pcb_dhcps = dhcps_netif->dhcps_pcb;
SendAck_err_t = udp_sendto(pcb_dhcps, p, &ip_temp, DHCPS_CLIENT_PORT);
#if DHCPS_DEBUG
DHCPS_LOG("dhcps: send_ack>>udp_sendto result %x\n", SendAck_err_t);
@ -1135,19 +1138,20 @@ void dhcps_set_new_lease_cb(dhcps_cb_t cb)
*******************************************************************************/
void dhcps_start(struct netif *netif, ip4_addr_t ip)
{
struct netif *apnetif = netif;
dhcps_netif = netif;
if (apnetif->dhcps_pcb != NULL) {
udp_remove(apnetif->dhcps_pcb);
if (dhcps_netif->dhcps_pcb != NULL) {
udp_remove(dhcps_netif->dhcps_pcb);
}
pcb_dhcps = udp_new();
dhcps_netif->dhcps_pcb = udp_new();
struct udp_pcb *pcb_dhcps = dhcps_netif->dhcps_pcb;
if (pcb_dhcps == NULL || ip4_addr_isany_val(ip)) {
printf("dhcps_start(): could not obtain pcb\n");
}
apnetif->dhcps_pcb = pcb_dhcps;
dhcps_netif->dhcps_pcb = pcb_dhcps;
IP4_ADDR(&broadcast_dhcps, 255, 255, 255, 255);
@ -1326,5 +1330,5 @@ dhcps_dns_getserver(void)
{
return dns_server;
}
#endif
#endif // ESP_DHCP

@ -1 +1 @@
Subproject commit f2bd195eed8f0d6e5cb784bccdba6c9b2e487e75
Subproject commit c483f30ba22ac3c56c113f2466c39e7d6f60ab89

View file

@ -231,7 +231,7 @@
#define LWIP_DHCP_IP_ADDR_RESTORE() dhcp_ip_addr_restore(netif)
#define LWIP_DHCP_IP_ADDR_STORE() dhcp_ip_addr_store(netif)
#define LWIP_DHCP_IP_ADDR_ERASE() dhcp_ip_addr_erase(esp_netif[tcpip_if])
#define LWIP_DHCP_IP_ADDR_ERASE(esp_netif) dhcp_ip_addr_erase(esp_netif)
#endif

View file

@ -24,7 +24,7 @@ bool dhcp_ip_addr_restore(void *netif);
void dhcp_ip_addr_store(void *netif);
void dhcp_ip_addr_erase(void *netif);
void dhcp_ip_addr_erase(void *esp_netif);
#ifdef __cplusplus
}

View file

@ -24,7 +24,7 @@ extern "C" {
err_t ethernetif_init(struct netif *netif);
void ethernetif_input(struct netif *netif, void *buffer, u16_t len);
void ethernetif_input(struct netif *netif, void *buffer, size_t len, void *eb);
void netif_reg_addr_change_cb(void* cb);

View file

@ -1,33 +0,0 @@
// Copyright 2015-2019 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef _NETTEST_LWIP_IF_H_
#define _NETTEST_LWIP_IF_H_
#include "lwip/err.h"
#ifdef __cplusplus
extern "C" {
#endif
err_t nettestif_init(struct netif *netif);
void nettestif_input(void *buffer, u16_t len);
#ifdef __cplusplus
}
#endif
#endif /* _NETTEST_LWIP_IF_H_ */

View file

@ -18,8 +18,6 @@
#include "esp_wifi.h"
#include "esp_private/wifi.h"
#include "lwip/err.h"
#ifdef __cplusplus
@ -29,7 +27,8 @@ extern "C" {
err_t wlanif_init_ap(struct netif *netif);
err_t wlanif_init_sta(struct netif *netif);
void wlanif_input(struct netif *netif, void *buffer, u16_t len, void* eb);
void wlanif_input(struct netif *netif, void *buffer, size_t len, void* eb);
err_t wlanif_init(struct netif *netif);
wifi_interface_t wifi_get_interface(void *dev);

View file

@ -19,17 +19,14 @@
#include "lwip/dhcp.h"
#include "lwip/netif.h"
#include "esp_interface.h"
#include "tcpip_adapter.h"
#include "esp_netif.h"
#include "esp_netif_net_stack.h"
#include "netif/dhcp_state.h"
#define DHCP_NAMESPACE "dhcp_state"
#define VALID_NETIF_ID(id) ((id < ESP_IF_MAX) && (id != ESP_IF_WIFI_AP))
static uint32_t restored_ip_addr[TCPIP_ADAPTER_IF_MAX];
static const char *interface_key[] = {"IF_STA", "IF_AP", "IF_ETH", "IF_TEST"};
_Static_assert(sizeof(interface_key) / sizeof(char*) == TCPIP_ADAPTER_IF_MAX,
"Number interface keys differs from number of interfaces");
// DHCP_Client has to be enabled for this netif
#define VALID_NETIF_ID(netif) (ESP_NETIF_DHCP_CLIENT&esp_netif_get_flags(netif))
bool dhcp_ip_addr_restore(void *netif)
{
@ -37,13 +34,12 @@ bool dhcp_ip_addr_restore(void *netif)
bool err = false;
struct netif *net = (struct netif *)netif;
struct dhcp *dhcp = netif_dhcp_data(net);
esp_interface_t netif_id = tcpip_adapter_get_esp_if(net);
esp_netif_t *esp_netif = esp_netif_get_handle_from_netif_impl(netif);
if(VALID_NETIF_ID(netif_id)) {
if(VALID_NETIF_ID(esp_netif)) {
uint32_t *ip_addr = &dhcp->offered_ip_addr.addr;
if (nvs_open(DHCP_NAMESPACE, NVS_READONLY, &nvs) == ESP_OK) {
if (nvs_get_u32(nvs, interface_key[netif_id], ip_addr) == ESP_OK) {
restored_ip_addr[netif_id] = *ip_addr;
if (nvs_get_u32(nvs, esp_netif_get_ifkey(esp_netif), ip_addr) == ESP_OK) {
err = true;
}
nvs_close(nvs);
@ -58,28 +54,24 @@ void dhcp_ip_addr_store(void *netif)
struct netif *net = (struct netif *)netif;
struct dhcp *dhcp = netif_dhcp_data(net);
uint32_t ip_addr = dhcp->offered_ip_addr.addr;
esp_interface_t netif_id = tcpip_adapter_get_esp_if(net);
esp_netif_t *esp_netif = esp_netif_get_handle_from_netif_impl(netif);
if(VALID_NETIF_ID(netif_id)) {
if (restored_ip_addr[netif_id] != ip_addr) {
if (nvs_open(DHCP_NAMESPACE, NVS_READWRITE, &nvs) == ESP_OK) {
nvs_set_u32(nvs, interface_key[netif_id], ip_addr);
nvs_commit(nvs);
nvs_close(nvs);
}
if(VALID_NETIF_ID(esp_netif)) {
if (nvs_open(DHCP_NAMESPACE, NVS_READWRITE, &nvs) == ESP_OK) {
nvs_set_u32(nvs,esp_netif_get_ifkey(esp_netif), ip_addr);
nvs_commit(nvs);
nvs_close(nvs);
}
}
}
void dhcp_ip_addr_erase(void *netif)
void dhcp_ip_addr_erase(void *esp_netif)
{
nvs_handle_t nvs;
struct netif *net = (struct netif *)netif;
esp_interface_t netif_id = tcpip_adapter_get_esp_if(net);
if(VALID_NETIF_ID(netif_id)) {
if(VALID_NETIF_ID(esp_netif)) {
if (nvs_open(DHCP_NAMESPACE, NVS_READWRITE, &nvs) == ESP_OK) {
nvs_erase_key(nvs, interface_key[netif_id]);
nvs_erase_key(nvs, esp_netif_get_ifkey(esp_netif));
nvs_commit(nvs);
nvs_close(nvs);
}

View file

@ -49,7 +49,8 @@
#include <string.h>
#include "esp_eth.h"
#include "tcpip_adapter.h"
#include "esp_netif.h"
#include "esp_netif_net_stack.h"
/* Define those to better describe your network interface. */
#define IFNAME0 'e'
@ -61,7 +62,7 @@
* @param buf memory alloc in L2 layer
* @note this function is also the callback when invoke pbuf_free
*/
static void ethernet_free_rx_buf_l2(void *buf)
static void ethernet_free_rx_buf_l2(struct netif *netif, void *buf)
{
free(buf);
}
@ -105,17 +106,15 @@ static void ethernet_low_level_init(struct netif *netif)
static err_t ethernet_low_level_output(struct netif *netif, struct pbuf *p)
{
struct pbuf *q = p;
esp_interface_t eth_if = tcpip_adapter_get_esp_if(netif);
esp_netif_t *esp_netif = esp_netif_get_handle_from_netif_impl(netif);
esp_err_t ret = ESP_FAIL;
esp_eth_handle_t eth_handle = (esp_eth_handle_t)netif->state;
if (eth_if != ESP_IF_ETH) {
LWIP_DEBUGF(NETIF_DEBUG, ("eth_if=%d netif=%p pbuf=%p len=%d\n", eth_if, netif, p, p->len));
if (!esp_netif) {
LWIP_DEBUGF(NETIF_DEBUG, ("corresponding esp-netif is NULL: netif=%p pbuf=%p len=%d\n", netif, p, p->len));
return ERR_IF;
}
if (q->next == NULL) {
ret = esp_eth_transmit(eth_handle, q->payload, q->len);
ret = esp_netif_transmit(esp_netif, q->payload, q->len);
} else {
LWIP_DEBUGF(PBUF_DEBUG, ("low_level_output: pbuf is a list, application may has bug"));
q = pbuf_alloc(PBUF_RAW_TX, p->tot_len, PBUF_RAM);
@ -129,7 +128,7 @@ static err_t ethernet_low_level_output(struct netif *netif, struct pbuf *p)
} else {
return ERR_MEM;
}
ret = esp_eth_transmit(eth_handle, q->payload, q->len);
ret = esp_netif_transmit(esp_netif, q->payload, q->len);
/* content in payload has been copied to DMA buffer, it's safe to free pbuf now */
pbuf_free(q);
}
@ -152,13 +151,13 @@ static err_t ethernet_low_level_output(struct netif *netif, struct pbuf *p)
* @param buffer ethernet buffer
* @param len length of buffer
*/
void ethernetif_input(struct netif *netif, void *buffer, uint16_t len)
void ethernetif_input(struct netif *netif, void *buffer, size_t len, void *eb)
{
struct pbuf *p;
if (buffer == NULL || !netif_is_up(netif)) {
if (buffer) {
ethernet_free_rx_buf_l2(buffer);
ethernet_free_rx_buf_l2(netif, buffer);
}
return;
}
@ -166,7 +165,7 @@ void ethernetif_input(struct netif *netif, void *buffer, uint16_t len)
/* acquire new pbuf, type: PBUF_REF */
p = pbuf_alloc(PBUF_RAW, len, PBUF_REF);
if (p == NULL) {
ethernet_free_rx_buf_l2(buffer);
ethernet_free_rx_buf_l2(netif, buffer);
return;
}
p->payload = buffer;
@ -194,7 +193,8 @@ void ethernetif_input(struct netif *netif, void *buffer, uint16_t len)
err_t ethernetif_init(struct netif *netif)
{
LWIP_ASSERT("netif != NULL", (netif != NULL));
esp_eth_handle_t eth_handle = (esp_eth_handle_t)netif->state;
/* Have to get the esp-netif handle from netif first and then driver==ethernet handle from there */
esp_eth_handle_t eth_handle = esp_netif_get_io_driver(esp_netif_get_handle_from_netif_impl(netif));
/* Initialize interface hostname */
#if LWIP_NETIF_HOSTNAME
#if ESP_LWIP
@ -207,6 +207,7 @@ err_t ethernetif_init(struct netif *netif)
/* Initialize the snmp variables and counters inside the struct netif. */
eth_speed_t speed;
esp_eth_ioctl(eth_handle, ETH_CMD_G_SPEED, &speed);
if (speed == ETH_SPEED_100M) {
NETIF_INIT_SNMP(netif, snmp_ifType_ethernet_csmacd, 100000000);

View file

@ -1,105 +0,0 @@
#include "lwip/opt.h"
#include "lwip/def.h"
#include "lwip/mem.h"
#include "lwip/pbuf.h"
#include "lwip/stats.h"
#include "lwip/snmp.h"
#include "lwip/ethip6.h"
#include "netif/etharp.h"
#include "netif/wlanif.h"
#include <stdio.h>
#include <string.h>
#include "tcpip_adapter.h"
static struct netif *g_last_netif = NULL;
err_t nettestif_output(struct netif *netif, struct pbuf *p)
{
int i;
char *dat = p->payload;
/* output the packet to stdout */
printf("\nPacketOut:[");
for (i=0; i<p->len; i++) {
printf("%02x", *dat++);
}
printf("]\n");
return ERR_OK;
}
err_t nettestif_init(struct netif *netif)
{
g_last_netif = netif;
netif->hostname = CONFIG_LWIP_LOCAL_HOSTNAME;
/*
* Initialize the snmp variables and counters inside the struct netif.
* The last argument should be replaced with your link speed, in units
* of bits per second.
*/
NETIF_INIT_SNMP(netif, snmp_ifType_ethernet_csmacd, 100);
/* We directly use etharp_output() here to save a function call.
* You can instead declare your own function an call etharp_output()
* from it if you have to do some checks before sending (e.g. if link
* is available...) */
netif->output = etharp_output;
#if LWIP_IPV6
netif->output_ip6 = ethip6_output;
#endif /* LWIP_IPV6 */
netif->linkoutput = nettestif_output;
/* set MAC hardware address length */
netif->hwaddr_len = ETHARP_HWADDR_LEN;
/* set MAC hardware address */
/* maximum transfer unit */
netif->mtu = 1500;
/* device capabilities */
/* don't set NETIF_FLAG_ETHARP if this device is not an ethernet one */
netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP;
#if ESP_LWIP
#if LWIP_IGMP
netif->flags |= NETIF_FLAG_IGMP;
#endif
#endif
return ERR_OK;
}
void nettestif_input(void *buffer, u16_t len)
{
struct pbuf *p;
if (g_last_netif == NULL) {
printf("error!");
return;
}
printf("simul in: %d\n", len);
if (len==0) return;
p = pbuf_alloc(PBUF_RAW, len, PBUF_RAM);
p->l2_owner = NULL;
memcpy(p->payload, buffer, len);
/* full packet send to tcpip_thread to process
* on success - the packet is processed and deallocated in tcpip stack
* on failure - log error and deallocate the packet
*/
if (g_last_netif->input(p, g_last_netif) != ERR_OK) {
LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_input: IP input error\n"));
pbuf_free(p);
}
}

View file

@ -50,8 +50,20 @@
#include <stdio.h>
#include <string.h>
#include "tcpip_adapter.h"
#include "esp_netif.h"
#include "esp_netif_net_stack.h"
/**
* @brief Free resources allocated in L2 layer
*
* @param buf memory alloc in L2 layer
* @note this function is also the callback when invoke pbuf_free
*/
static void lwip_netif_wifi_free_rx_buffer(struct netif *netif, void *buf)
{
esp_netif_t *esp_netif = esp_netif_get_handle_from_netif_impl(netif);
esp_netif_free_rx_buffer(esp_netif, buf);
}
/**
* In this function, the hardware should be initialized.
@ -82,7 +94,7 @@ low_level_init(struct netif *netif)
#endif
#if !ESP_L2_TO_L3_COPY
netif->l2_buffer_free_notify = esp_wifi_internal_free_rx_buffer;
netif->l2_buffer_free_notify = lwip_netif_wifi_free_rx_buffer;
#endif
}
@ -104,16 +116,17 @@ low_level_init(struct netif *netif)
static err_t ESP_IRAM_ATTR
low_level_output(struct netif *netif, struct pbuf *p)
{
wifi_interface_t wifi_if = tcpip_adapter_get_esp_if(netif);
struct pbuf *q = p;
err_t ret;
if (wifi_if >= ESP_IF_MAX) {
esp_netif_t *esp_netif = esp_netif_get_handle_from_netif_impl(netif);
if (esp_netif == NULL) {
return ERR_IF;
}
struct pbuf *q = p;
err_t ret;
if(q->next == NULL) {
ret = esp_wifi_internal_tx(wifi_if, q->payload, q->len);
ret = esp_netif_transmit(esp_netif, q->payload, q->len);
} else {
LWIP_DEBUGF(PBUF_DEBUG, ("low_level_output: pbuf is a list, application may has bug"));
q = pbuf_alloc(PBUF_RAW_TX, p->tot_len, PBUF_RAM);
@ -123,7 +136,8 @@ low_level_output(struct netif *netif, struct pbuf *p)
} else {
return ERR_MEM;
}
ret = esp_wifi_internal_tx(wifi_if, q->payload, q->len);
ret = esp_netif_transmit(esp_netif, q->payload, q->len);
pbuf_free(q);
}
@ -140,13 +154,14 @@ low_level_output(struct netif *netif, struct pbuf *p)
* @param netif the lwip network interface structure for this ethernetif
*/
void ESP_IRAM_ATTR
wlanif_input(struct netif *netif, void *buffer, u16_t len, void* eb)
wlanif_input(struct netif *netif, void *buffer, size_t len, void* eb)
{
esp_netif_t *esp_netif = esp_netif_get_handle_from_netif_impl(netif);
struct pbuf *p;
if(!buffer || !netif_is_up(netif)) {
if (eb) {
esp_wifi_internal_free_rx_buffer(eb);
esp_netif_free_rx_buffer(esp_netif, eb);
}
return;
}
@ -154,16 +169,18 @@ wlanif_input(struct netif *netif, void *buffer, u16_t len, void* eb)
#if (ESP_L2_TO_L3_COPY == 1)
p = pbuf_alloc(PBUF_RAW, len, PBUF_RAM);
if (p == NULL) {
esp_wifi_internal_free_rx_buffer(eb);
// esp_wifi_internal_free_rx_buffer(eb);
esp_netif_free_rx_buffer(esp_netif, eb);
return;
}
p->l2_owner = NULL;
memcpy(p->payload, buffer, len);
esp_wifi_internal_free_rx_buffer(eb);
esp_netif_free_rx_buffer(esp_netif, eb);
// esp_wifi_internal_free_rx_buffer(eb);
#else
p = pbuf_alloc(PBUF_RAW, len, PBUF_REF);
if (p == NULL){
esp_wifi_internal_free_rx_buffer(eb);
esp_netif_free_rx_buffer(esp_netif, eb);
return;
}
p->payload = buffer;

View file

@ -3,5 +3,5 @@ idf_component_register(SRCS "mdns.c"
"mdns_networking.c"
INCLUDE_DIRS "include"
PRIV_INCLUDE_DIRS "private_include"
REQUIRES lwip mbedtls console tcpip_adapter)
REQUIRES lwip mbedtls console esp_netif)

View file

@ -18,7 +18,7 @@
extern "C" {
#endif
#include <tcpip_adapter.h>
#include <esp_netif.h>
#include "esp_event.h"
#define MDNS_TYPE_A 0x0001
@ -52,17 +52,25 @@ typedef struct {
* @brief mDNS query linked list IP item
*/
typedef struct mdns_ip_addr_s {
ip_addr_t addr; /*!< IP address */
esp_ip_addr_t addr; /*!< IP address */
struct mdns_ip_addr_s * next; /*!< next IP, or NULL for the last IP in the list */
} mdns_ip_addr_t;
typedef enum mdns_if_internal {
MDNS_IF_STA = 0,
MDNS_IF_AP = 1,
MDNS_IF_ETH = 2,
MDNS_IF_MAX
} mdns_if_t;
/**
* @brief mDNS query result structure
*/
typedef struct mdns_result_s {
struct mdns_result_s * next; /*!< next result, or NULL for the last result in the list */
tcpip_adapter_if_t tcpip_if; /*!< interface on which the result came (AP/STA/ETH) */
mdns_if_t tcpip_if; /*!< interface index */
mdns_ip_protocol_t ip_protocol; /*!< ip_protocol type of the interface (v4/v6) */
// PTR
char * instance_name; /*!< instance name */
@ -329,7 +337,7 @@ esp_err_t mdns_query_txt(const char * instance_name, const char * service_type,
* - ESP_ERR_NO_MEM memory error
* - ESP_ERR_INVALID_ARG parameter error
*/
esp_err_t mdns_query_a(const char * host_name, uint32_t timeout, ip4_addr_t * addr);
esp_err_t mdns_query_a(const char * host_name, uint32_t timeout, esp_ip4_addr_t * addr);
/**
* @brief Query mDNS for A record
@ -344,7 +352,7 @@ esp_err_t mdns_query_a(const char * host_name, uint32_t timeout, ip4_addr_t * ad
* - ESP_ERR_NO_MEM memory error
* - ESP_ERR_INVALID_ARG parameter error
*/
esp_err_t mdns_query_aaaa(const char * host_name, uint32_t timeout, ip6_addr_t * addr);
esp_err_t mdns_query_aaaa(const char * host_name, uint32_t timeout, esp_ip6_addr_t * addr);
/**
* @brief System event handler

View file

@ -37,11 +37,42 @@ static volatile TaskHandle_t _mdns_service_task_handle = NULL;
static SemaphoreHandle_t _mdns_service_semaphore = NULL;
static void _mdns_search_finish_done(void);
static mdns_search_once_t * _mdns_search_find_from(mdns_search_once_t * search, mdns_name_t * name, uint16_t type, tcpip_adapter_if_t tcpip_if, mdns_ip_protocol_t ip_protocol);
static void _mdns_search_result_add_ip(mdns_search_once_t * search, const char * hostname, ip_addr_t * ip, tcpip_adapter_if_t tcpip_if, mdns_ip_protocol_t ip_protocol);
static void _mdns_search_result_add_srv(mdns_search_once_t * search, const char * hostname, uint16_t port, tcpip_adapter_if_t tcpip_if, mdns_ip_protocol_t ip_protocol);
static void _mdns_search_result_add_txt(mdns_search_once_t * search, mdns_txt_item_t * txt, size_t txt_count, tcpip_adapter_if_t tcpip_if, mdns_ip_protocol_t ip_protocol);
static mdns_result_t * _mdns_search_result_add_ptr(mdns_search_once_t * search, const char * instance, tcpip_adapter_if_t tcpip_if, mdns_ip_protocol_t ip_protocol);
static mdns_search_once_t * _mdns_search_find_from(mdns_search_once_t * search, mdns_name_t * name, uint16_t type, mdns_if_t tcpip_if, mdns_ip_protocol_t ip_protocol);
static void _mdns_search_result_add_ip(mdns_search_once_t * search, const char * hostname, esp_ip_addr_t * ip, mdns_if_t tcpip_if, mdns_ip_protocol_t ip_protocol);
static void _mdns_search_result_add_srv(mdns_search_once_t * search, const char * hostname, uint16_t port, mdns_if_t tcpip_if, mdns_ip_protocol_t ip_protocol);
static void _mdns_search_result_add_txt(mdns_search_once_t * search, mdns_txt_item_t * txt, size_t txt_count, mdns_if_t tcpip_if, mdns_ip_protocol_t ip_protocol);
static mdns_result_t * _mdns_search_result_add_ptr(mdns_search_once_t * search, const char * instance, mdns_if_t tcpip_if, mdns_ip_protocol_t ip_protocol);
/*
* @brief Internal collection of mdns supported interfaces
*
*/
static esp_netif_t * s_esp_netifs[MDNS_IF_MAX] = {};
/*
* @brief Convert mnds if to esp-netif handle
*/
esp_netif_t *_mdns_get_esp_netif(mdns_if_t tcpip_if)
{
if (tcpip_if < MDNS_IF_MAX) {
return s_esp_netifs[tcpip_if];
}
return NULL;
}
/*
* @brief Convert esp-netif handle to mnds if
*/
static mdns_if_t _mdns_get_if_from_esp_netif(esp_netif_t *interface)
{
for (int i=0; i<MDNS_IF_MAX; ++i) {
if (interface == s_esp_netifs[i])
return i;
}
return MDNS_IF_MAX;
}
static inline bool _str_null_or_empty(const char * str){
return (str == NULL || *str == 0);
@ -801,23 +832,23 @@ static uint16_t _mdns_append_question(uint8_t * packet, uint16_t * index, mdns_o
* @brief Helper to get either ETH or STA if the other is provided
* Used when two interfaces are on the same subnet
*/
static tcpip_adapter_if_t _mdns_get_other_if (tcpip_adapter_if_t tcpip_if)
static mdns_if_t _mdns_get_other_if (mdns_if_t tcpip_if)
{
if (tcpip_if == TCPIP_ADAPTER_IF_STA) {
return TCPIP_ADAPTER_IF_ETH;
} else if (tcpip_if == TCPIP_ADAPTER_IF_ETH) {
return TCPIP_ADAPTER_IF_STA;
if (tcpip_if == MDNS_IF_STA) {
return MDNS_IF_ETH;
} else if (tcpip_if == MDNS_IF_ETH) {
return MDNS_IF_STA;
}
return TCPIP_ADAPTER_IF_MAX;
return MDNS_IF_MAX;
}
/**
* @brief Check if interface is duplicate (two interfaces on the same subnet)
*/
static bool _mdns_if_is_dup(tcpip_adapter_if_t tcpip_if)
static bool _mdns_if_is_dup(mdns_if_t tcpip_if)
{
tcpip_adapter_if_t other_if = _mdns_get_other_if (tcpip_if);
if (other_if == TCPIP_ADAPTER_IF_MAX) {
mdns_if_t other_if = _mdns_get_other_if (tcpip_if);
if (other_if == MDNS_IF_MAX) {
return false;
}
if (_mdns_server->interfaces[tcpip_if].pcbs[MDNS_IP_PROTOCOL_V4].state == PCB_DUP
@ -833,7 +864,7 @@ static bool _mdns_if_is_dup(tcpip_adapter_if_t tcpip_if)
/**
* @brief Check if IPv6 address is NULL
*/
static bool _ipv6_address_is_zero(ip6_addr_t ip6)
static bool _ipv6_address_is_zero(esp_ip6_addr_t ip6)
{
uint8_t i;
uint8_t * data = (uint8_t *)ip6.addr;
@ -850,7 +881,7 @@ static bool _ipv6_address_is_zero(ip6_addr_t ip6)
*
* @return number of answers added to the packet
*/
static uint8_t _mdns_append_answer(uint8_t * packet, uint16_t * index, mdns_out_answer_t * answer, tcpip_adapter_if_t tcpip_if)
static uint8_t _mdns_append_answer(uint8_t * packet, uint16_t * index, mdns_out_answer_t * answer, mdns_if_t tcpip_if)
{
if (answer->type == MDNS_TYPE_PTR) {
@ -871,11 +902,11 @@ static uint8_t _mdns_append_answer(uint8_t * packet, uint16_t * index, mdns_out_
} else if (answer->type == MDNS_TYPE_SDPTR) {
return _mdns_append_sdptr_record(packet, index, answer->service, answer->flush, answer->bye) > 0;
} else if (answer->type == MDNS_TYPE_A) {
tcpip_adapter_ip_info_t if_ip_info;
esp_netif_ip_info_t if_ip_info;
if (!_mdns_server->interfaces[tcpip_if].pcbs[MDNS_IP_PROTOCOL_V4].pcb && _mdns_server->interfaces[tcpip_if].pcbs[MDNS_IP_PROTOCOL_V4].state != PCB_DUP) {
return 0;
}
if (tcpip_adapter_get_ip_info(tcpip_if, &if_ip_info)) {
if (esp_netif_get_ip_info(_mdns_get_esp_netif(tcpip_if), &if_ip_info)) {
return 0;
}
if (_mdns_append_a_record(packet, index, if_ip_info.ip.addr, answer->flush, answer->bye) <= 0) {
@ -884,8 +915,8 @@ static uint8_t _mdns_append_answer(uint8_t * packet, uint16_t * index, mdns_out_
if (!_mdns_if_is_dup(tcpip_if)) {
return 1;
}
tcpip_adapter_if_t other_if = _mdns_get_other_if (tcpip_if);
if (tcpip_adapter_get_ip_info(other_if, &if_ip_info)) {
mdns_if_t other_if = _mdns_get_other_if (tcpip_if);
if (esp_netif_get_ip_info(_mdns_get_esp_netif(other_if), &if_ip_info)) {
return 1;
}
if (_mdns_append_a_record(packet, index, if_ip_info.ip.addr, answer->flush, answer->bye) > 0) {
@ -893,11 +924,11 @@ static uint8_t _mdns_append_answer(uint8_t * packet, uint16_t * index, mdns_out_
}
return 1;
} else if (answer->type == MDNS_TYPE_AAAA) {
struct ip6_addr if_ip6;
struct esp_ip6_addr if_ip6;
if (!_mdns_server->interfaces[tcpip_if].pcbs[MDNS_IP_PROTOCOL_V6].pcb && _mdns_server->interfaces[tcpip_if].pcbs[MDNS_IP_PROTOCOL_V6].state != PCB_DUP) {
return 0;
}
if (tcpip_adapter_get_ip6_linklocal(tcpip_if, &if_ip6)) {
if (esp_netif_get_ip6_linklocal(_mdns_get_esp_netif(tcpip_if), &if_ip6)) {
return 0;
}
if (_ipv6_address_is_zero(if_ip6)) {
@ -909,8 +940,8 @@ static uint8_t _mdns_append_answer(uint8_t * packet, uint16_t * index, mdns_out_
if (!_mdns_if_is_dup(tcpip_if)) {
return 1;
}
tcpip_adapter_if_t other_if = _mdns_get_other_if (tcpip_if);
if (tcpip_adapter_get_ip6_linklocal(other_if, &if_ip6)) {
mdns_if_t other_if = _mdns_get_other_if (tcpip_if);
if (esp_netif_get_ip6_linklocal(_mdns_get_esp_netif(other_if), &if_ip6)) {
return 1;
}
if (_mdns_append_aaaa_record(packet, index, (uint8_t*)if_ip6.addr, answer->flush, answer->bye) > 0) {
@ -1046,7 +1077,7 @@ static void _mdns_clear_tx_queue_head(void)
* @param tcpip_if the interface
* @param ip_protocol pcb type V4/V6
*/
static void _mdns_clear_pcb_tx_queue_head(tcpip_adapter_if_t tcpip_if, mdns_ip_protocol_t ip_protocol)
static void _mdns_clear_pcb_tx_queue_head(mdns_if_t tcpip_if, mdns_ip_protocol_t ip_protocol)
{
mdns_tx_packet_t * q, * p;
while (_mdns_server->tx_queue_head && _mdns_server->tx_queue_head->tcpip_if == tcpip_if && _mdns_server->tx_queue_head->ip_protocol == ip_protocol) {
@ -1074,7 +1105,7 @@ static void _mdns_clear_pcb_tx_queue_head(tcpip_adapter_if_t tcpip_if, mdns_ip_p
* @param tcpip_if the interface
* @param ip_protocol pcb type V4/V6
*/
static mdns_tx_packet_t * _mdns_get_next_pcb_packet(tcpip_adapter_if_t tcpip_if, mdns_ip_protocol_t ip_protocol)
static mdns_tx_packet_t * _mdns_get_next_pcb_packet(mdns_if_t tcpip_if, mdns_ip_protocol_t ip_protocol)
{
mdns_tx_packet_t * q = _mdns_server->tx_queue_head;
while (q) {
@ -1089,7 +1120,7 @@ static mdns_tx_packet_t * _mdns_get_next_pcb_packet(tcpip_adapter_if_t tcpip_if,
/**
* @brief Find, remove and free answer from the scheduled packets
*/
static void _mdns_remove_scheduled_answer(tcpip_adapter_if_t tcpip_if, mdns_ip_protocol_t ip_protocol, uint16_t type, mdns_srv_item_t * service)
static void _mdns_remove_scheduled_answer(mdns_if_t tcpip_if, mdns_ip_protocol_t ip_protocol, uint16_t type, mdns_srv_item_t * service)
{
mdns_srv_item_t s = {NULL, NULL};
if (!service) {
@ -1178,7 +1209,7 @@ static bool _mdns_alloc_answer(mdns_out_answer_t ** destnation, uint16_t type, m
/**
* @brief Allocate new packet for sending
*/
static mdns_tx_packet_t * _mdns_alloc_packet_default(tcpip_adapter_if_t tcpip_if, mdns_ip_protocol_t ip_protocol)
static mdns_tx_packet_t * _mdns_alloc_packet_default(mdns_if_t tcpip_if, mdns_ip_protocol_t ip_protocol)
{
mdns_tx_packet_t * packet = (mdns_tx_packet_t*)malloc(sizeof(mdns_tx_packet_t));
if (!packet) {
@ -1192,8 +1223,8 @@ static mdns_tx_packet_t * _mdns_alloc_packet_default(tcpip_adapter_if_t tcpip_if
if (ip_protocol == MDNS_IP_PROTOCOL_V4) {
IP_ADDR4(&packet->dst, 224, 0, 0, 251);
} else {
ip_addr_t addr = IPADDR6_INIT(0x000002ff, 0, 0, 0xfb000000);
memcpy(&packet->dst, &addr, sizeof(ip_addr_t));
esp_ip_addr_t addr = IPADDR6_INIT(0x000002ff, 0, 0, 0xfb000000);
memcpy(&packet->dst, &addr, sizeof(esp_ip_addr_t));
}
return packet;
}
@ -1275,7 +1306,7 @@ static void _mdns_create_answer_from_parsed_packet(mdns_parsed_packet_t * parsed
q = q->next;
}
if (unicast || !send_flush) {
memcpy(&packet->dst, &parsed_packet->src, sizeof(ip_addr_t));
memcpy(&packet->dst, &parsed_packet->src, sizeof(esp_ip_addr_t));
packet->port = parsed_packet->src_port;
}
@ -1309,7 +1340,7 @@ static bool _mdns_question_exists(mdns_out_question_t * needle, mdns_out_questio
/**
* @brief Create probe packet for particular services on particular PCB
*/
static mdns_tx_packet_t * _mdns_create_probe_packet(tcpip_adapter_if_t tcpip_if, mdns_ip_protocol_t ip_protocol, mdns_srv_item_t * services[], size_t len, bool first, bool include_ip)
static mdns_tx_packet_t * _mdns_create_probe_packet(mdns_if_t tcpip_if, mdns_ip_protocol_t ip_protocol, mdns_srv_item_t * services[], size_t len, bool first, bool include_ip)
{
mdns_tx_packet_t * packet = _mdns_alloc_packet_default(tcpip_if, ip_protocol);
if (!packet) {
@ -1385,7 +1416,7 @@ static mdns_tx_packet_t * _mdns_create_probe_packet(tcpip_adapter_if_t tcpip_if,
/**
* @brief Create announce packet for particular services on particular PCB
*/
static mdns_tx_packet_t * _mdns_create_announce_packet(tcpip_adapter_if_t tcpip_if, mdns_ip_protocol_t ip_protocol, mdns_srv_item_t * services[], size_t len, bool include_ip)
static mdns_tx_packet_t * _mdns_create_announce_packet(mdns_if_t tcpip_if, mdns_ip_protocol_t ip_protocol, mdns_srv_item_t * services[], size_t len, bool include_ip)
{
mdns_tx_packet_t * packet = _mdns_alloc_packet_default(tcpip_if, ip_protocol);
if (!packet) {
@ -1451,7 +1482,7 @@ static mdns_tx_packet_t * _mdns_create_announce_from_probe(mdns_tx_packet_t * pr
/**
* @brief Send by for particular services on particular PCB
*/
static void _mdns_pcb_send_bye(tcpip_adapter_if_t tcpip_if, mdns_ip_protocol_t ip_protocol, mdns_srv_item_t ** services, size_t len, bool include_ip)
static void _mdns_pcb_send_bye(mdns_if_t tcpip_if, mdns_ip_protocol_t ip_protocol, mdns_srv_item_t ** services, size_t len, bool include_ip)
{
mdns_tx_packet_t * packet = _mdns_alloc_packet_default(tcpip_if, ip_protocol);
if (!packet) {
@ -1476,7 +1507,7 @@ static void _mdns_pcb_send_bye(tcpip_adapter_if_t tcpip_if, mdns_ip_protocol_t i
/**
* @brief Send probe for additional services on particular PCB
*/
static void _mdns_init_pcb_probe_new_service(tcpip_adapter_if_t tcpip_if, mdns_ip_protocol_t ip_protocol, mdns_srv_item_t ** services, size_t len, bool probe_ip)
static void _mdns_init_pcb_probe_new_service(mdns_if_t tcpip_if, mdns_ip_protocol_t ip_protocol, mdns_srv_item_t ** services, size_t len, bool probe_ip)
{
mdns_pcb_t * pcb = &_mdns_server->interfaces[tcpip_if].pcbs[ip_protocol];
size_t services_final_len = len;
@ -1532,7 +1563,7 @@ static void _mdns_init_pcb_probe_new_service(tcpip_adapter_if_t tcpip_if, mdns_i
* - If pcb probing then add only non-probing services and restarts probing
* - If pcb not probing, run probing for all specified services
*/
static void _mdns_init_pcb_probe(tcpip_adapter_if_t tcpip_if, mdns_ip_protocol_t ip_protocol, mdns_srv_item_t ** services, size_t len, bool probe_ip)
static void _mdns_init_pcb_probe(mdns_if_t tcpip_if, mdns_ip_protocol_t ip_protocol, mdns_srv_item_t ** services, size_t len, bool probe_ip)
{
mdns_pcb_t * pcb = &_mdns_server->interfaces[tcpip_if].pcbs[ip_protocol];
@ -1572,7 +1603,7 @@ static void _mdns_init_pcb_probe(tcpip_adapter_if_t tcpip_if, mdns_ip_protocol_t
/**
* @brief Restart the responder on particular PCB
*/
static void _mdns_restart_pcb(tcpip_adapter_if_t tcpip_if, mdns_ip_protocol_t ip_protocol)
static void _mdns_restart_pcb(mdns_if_t tcpip_if, mdns_ip_protocol_t ip_protocol)
{
size_t srv_count = 0;
mdns_srv_item_t * a = _mdns_server->services;
@ -1600,10 +1631,10 @@ static void _mdns_send_bye(mdns_srv_item_t ** services, size_t len, bool include
return;
}
for (i=0; i<TCPIP_ADAPTER_IF_MAX; i++) {
for (i=0; i<MDNS_IF_MAX; i++) {
for (j=0; j<MDNS_IP_PROTOCOL_MAX; j++) {
if (_mdns_server->interfaces[i].pcbs[j].pcb && _mdns_server->interfaces[i].pcbs[j].state == PCB_RUNNING) {
_mdns_pcb_send_bye((tcpip_adapter_if_t)i, (mdns_ip_protocol_t)j, services, len, include_ip);
_mdns_pcb_send_bye((mdns_if_t)i, (mdns_ip_protocol_t)j, services, len, include_ip);
}
}
}
@ -1612,7 +1643,7 @@ static void _mdns_send_bye(mdns_srv_item_t ** services, size_t len, bool include
/**
* @brief Send announcement on particular PCB
*/
static void _mdns_announce_pcb(tcpip_adapter_if_t tcpip_if, mdns_ip_protocol_t ip_protocol, mdns_srv_item_t ** services, size_t len, bool include_ip)
static void _mdns_announce_pcb(mdns_if_t tcpip_if, mdns_ip_protocol_t ip_protocol, mdns_srv_item_t ** services, size_t len, bool include_ip)
{
mdns_pcb_t * _pcb = &_mdns_server->interfaces[tcpip_if].pcbs[ip_protocol];
size_t i;
@ -1659,7 +1690,7 @@ static void _mdns_announce_pcb(tcpip_adapter_if_t tcpip_if, mdns_ip_protocol_t i
static void _mdns_probe_all_pcbs(mdns_srv_item_t ** services, size_t len, bool probe_ip, bool clear_old_probe)
{
uint8_t i, j;
for (i=0; i<TCPIP_ADAPTER_IF_MAX; i++) {
for (i=0; i<MDNS_IF_MAX; i++) {
for (j=0; j<MDNS_IP_PROTOCOL_MAX; j++) {
if (_mdns_server->interfaces[i].pcbs[j].pcb) {
mdns_pcb_t * _pcb = &_mdns_server->interfaces[i].pcbs[j];
@ -1669,7 +1700,7 @@ static void _mdns_probe_all_pcbs(mdns_srv_item_t ** services, size_t len, bool p
_pcb->probe_services_len = 0;
_pcb->probe_running = false;
}
_mdns_init_pcb_probe((tcpip_adapter_if_t)i, (mdns_ip_protocol_t)j, services, len, probe_ip);
_mdns_init_pcb_probe((mdns_if_t)i, (mdns_ip_protocol_t)j, services, len, probe_ip);
}
}
}
@ -1681,9 +1712,9 @@ static void _mdns_probe_all_pcbs(mdns_srv_item_t ** services, size_t len, bool p
static void _mdns_announce_all_pcbs(mdns_srv_item_t ** services, size_t len, bool include_ip)
{
uint8_t i, j;
for (i=0; i<TCPIP_ADAPTER_IF_MAX; i++) {
for (i=0; i<MDNS_IF_MAX; i++) {
for (j=0; j<MDNS_IP_PROTOCOL_MAX; j++) {
_mdns_announce_pcb((tcpip_adapter_if_t)i, (mdns_ip_protocol_t)j, services, len, include_ip);
_mdns_announce_pcb((mdns_if_t)i, (mdns_ip_protocol_t)j, services, len, include_ip);
}
}
}
@ -2141,10 +2172,10 @@ static int _mdns_check_txt_collision(mdns_service_t * service, const uint8_t * d
/**
* @brief Set interface as duplicate if another is found on the same subnet
*/
static void _mdns_dup_interface(tcpip_adapter_if_t tcpip_if)
static void _mdns_dup_interface(mdns_if_t tcpip_if)
{
uint8_t i;
tcpip_adapter_if_t other_if = _mdns_get_other_if (tcpip_if);
mdns_if_t other_if = _mdns_get_other_if (tcpip_if);
for (i=0; i<MDNS_IP_PROTOCOL_MAX; i++) {
if (_mdns_server->interfaces[other_if].pcbs[i].pcb) {
//stop this interface and mark as dup
@ -2161,27 +2192,27 @@ static void _mdns_dup_interface(tcpip_adapter_if_t tcpip_if)
/**
* @brief Detect IPv4 address collision
*/
static int _mdns_check_a_collision(ip4_addr_t * ip, tcpip_adapter_if_t tcpip_if)
static int _mdns_check_a_collision(esp_ip4_addr_t * ip, mdns_if_t tcpip_if)
{
tcpip_adapter_ip_info_t if_ip_info;
tcpip_adapter_ip_info_t other_ip_info;
esp_netif_ip_info_t if_ip_info;
esp_netif_ip_info_t other_ip_info;
if (!ip->addr) {
return 1;//denial! they win
}
if (tcpip_adapter_get_ip_info(tcpip_if, &if_ip_info)) {
if (esp_netif_get_ip_info(_mdns_get_esp_netif(tcpip_if), &if_ip_info)) {
return 1;//they win
}
int ret = memcmp((uint8_t*)&if_ip_info.ip.addr, (uint8_t*)&ip->addr, sizeof(ip4_addr_t));
int ret = memcmp((uint8_t*)&if_ip_info.ip.addr, (uint8_t*)&ip->addr, sizeof(esp_ip4_addr_t));
if (ret > 0) {
return -1;//we win
} else if (ret < 0) {
//is it the other interface?
tcpip_adapter_if_t other_if = _mdns_get_other_if (tcpip_if);
if (other_if == TCPIP_ADAPTER_IF_MAX) {
mdns_if_t other_if = _mdns_get_other_if (tcpip_if);
if (other_if == MDNS_IF_MAX) {
return 1;//AP interface! They win
}
if (tcpip_adapter_get_ip_info(other_if, &other_ip_info)) {
if (esp_netif_get_ip_info(_mdns_get_esp_netif(other_if), &other_ip_info)) {
return 1;//IPv4 not active! They win
}
if (ip->addr != other_ip_info.ip.addr) {
@ -2196,14 +2227,14 @@ static int _mdns_check_a_collision(ip4_addr_t * ip, tcpip_adapter_if_t tcpip_if)
/**
* @brief Detect IPv6 address collision
*/
static int _mdns_check_aaaa_collision(ip6_addr_t * ip, tcpip_adapter_if_t tcpip_if)
static int _mdns_check_aaaa_collision(esp_ip6_addr_t * ip, mdns_if_t tcpip_if)
{
struct ip6_addr if_ip6;
struct ip6_addr other_ip6;
struct esp_ip6_addr if_ip6;
struct esp_ip6_addr other_ip6;
if (_ipv6_address_is_zero(*ip)) {
return 1;//denial! they win
}
if (tcpip_adapter_get_ip6_linklocal(tcpip_if, &if_ip6)) {
if (esp_netif_get_ip6_linklocal(_mdns_get_esp_netif(tcpip_if), &if_ip6)) {
return 1;//they win
}
int ret = memcmp((uint8_t*)&if_ip6.addr, (uint8_t*)ip->addr, _MDNS_SIZEOF_IP6_ADDR);
@ -2211,11 +2242,11 @@ static int _mdns_check_aaaa_collision(ip6_addr_t * ip, tcpip_adapter_if_t tcpip_
return -1;//we win
} else if (ret < 0) {
//is it the other interface?
tcpip_adapter_if_t other_if = _mdns_get_other_if (tcpip_if);
if (other_if == TCPIP_ADAPTER_IF_MAX) {
mdns_if_t other_if = _mdns_get_other_if (tcpip_if);
if (other_if == MDNS_IF_MAX) {
return 1;//AP interface! They win
}
if (tcpip_adapter_get_ip6_linklocal(other_if, &other_ip6)) {
if (esp_netif_get_ip6_linklocal(_mdns_get_esp_netif(other_if), &other_ip6)) {
return 1;//IPv6 not active! They win
}
if (memcmp((uint8_t*)&other_ip6.addr, (uint8_t*)ip->addr, _MDNS_SIZEOF_IP6_ADDR)) {
@ -2917,7 +2948,7 @@ void mdns_parse_packet(mdns_rx_packet_t * packet)
}
} else if (type == MDNS_TYPE_AAAA) {//ipv6
ip_addr_t ip6;
esp_ip_addr_t ip6;
ip6.type = IPADDR_TYPE_V6;
memcpy(ip6.u_addr.ip6.addr, data_ptr, MDNS_ANSWER_AAAA_SIZE);
if (search_result) {
@ -2963,7 +2994,7 @@ void mdns_parse_packet(mdns_rx_packet_t * packet)
}
} else if (type == MDNS_TYPE_A) {
ip_addr_t ip;
esp_ip_addr_t ip;
ip.type = IPADDR_TYPE_V4;
memcpy(&(ip.u_addr.ip4.addr), data_ptr, 4);
if (search_result) {
@ -3037,7 +3068,7 @@ clear_rx_packet:
/**
* @brief Enable mDNS interface
*/
void _mdns_enable_pcb(tcpip_adapter_if_t tcpip_if, mdns_ip_protocol_t ip_protocol)
void _mdns_enable_pcb(mdns_if_t tcpip_if, mdns_ip_protocol_t ip_protocol)
{
if (!_mdns_server->interfaces[tcpip_if].pcbs[ip_protocol].pcb) {
if (_mdns_pcb_init(tcpip_if, ip_protocol)) {
@ -3050,13 +3081,13 @@ void _mdns_enable_pcb(tcpip_adapter_if_t tcpip_if, mdns_ip_protocol_t ip_protoco
/**
* @brief Disable mDNS interface
*/
void _mdns_disable_pcb(tcpip_adapter_if_t tcpip_if, mdns_ip_protocol_t ip_protocol)
void _mdns_disable_pcb(mdns_if_t tcpip_if, mdns_ip_protocol_t ip_protocol)
{
if (_mdns_server->interfaces[tcpip_if].pcbs[ip_protocol].pcb) {
_mdns_clear_pcb_tx_queue_head(tcpip_if, ip_protocol);
_mdns_pcb_deinit(tcpip_if, ip_protocol);
tcpip_adapter_if_t other_if = _mdns_get_other_if (tcpip_if);
if (other_if != TCPIP_ADAPTER_IF_MAX && _mdns_server->interfaces[other_if].pcbs[ip_protocol].state == PCB_DUP) {
mdns_if_t other_if = _mdns_get_other_if (tcpip_if);
if (other_if != MDNS_IF_MAX && _mdns_server->interfaces[other_if].pcbs[ip_protocol].state == PCB_DUP) {
_mdns_server->interfaces[other_if].pcbs[ip_protocol].state = PCB_OFF;
_mdns_enable_pcb(other_if, ip_protocol);
}
@ -3068,32 +3099,43 @@ void _mdns_disable_pcb(tcpip_adapter_if_t tcpip_if, mdns_ip_protocol_t ip_protoc
* @brief Dispatch interface changes based on system events
*/
static void _mdns_handle_system_event(esp_event_base_t event_base,
int32_t event_id, tcpip_adapter_if_t interface)
int32_t event_id, esp_netif_t* interface)
{
if (!_mdns_server) {
return;
}
tcpip_adapter_dhcp_status_t dcst;
// Initialize handles to esp-netif if appropriate mdns supported interface started
if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START) {
s_esp_netifs[MDNS_IF_STA] = esp_netif_get_handle_from_ifkey("WIFI_STA_DEF");
} else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_AP_START) {
s_esp_netifs[MDNS_IF_AP] = esp_netif_get_handle_from_ifkey("WIFI_AP_DEF");
#if CONFIG_ETH_ENABLED
} else if (event_base == ETH_EVENT && event_id == ETHERNET_EVENT_START) {
s_esp_netifs[MDNS_IF_ETH] = esp_netif_get_handle_from_ifkey("ETH_DEF");
#endif
}
esp_netif_dhcp_status_t dcst;
if (event_base == WIFI_EVENT) {
switch(event_id) {
case WIFI_EVENT_STA_CONNECTED:
if (!tcpip_adapter_dhcpc_get_status(TCPIP_ADAPTER_IF_STA, &dcst)) {
if (dcst == TCPIP_ADAPTER_DHCP_STOPPED) {
_mdns_enable_pcb(TCPIP_ADAPTER_IF_STA, MDNS_IP_PROTOCOL_V4);
if (!esp_netif_dhcpc_get_status(_mdns_get_esp_netif(MDNS_IF_STA), &dcst)) {
if (dcst == ESP_NETIF_DHCP_STOPPED) {
_mdns_enable_pcb(MDNS_IF_STA, MDNS_IP_PROTOCOL_V4);
}
}
break;
case WIFI_EVENT_STA_DISCONNECTED:
_mdns_disable_pcb(TCPIP_ADAPTER_IF_STA, MDNS_IP_PROTOCOL_V4);
_mdns_disable_pcb(TCPIP_ADAPTER_IF_STA, MDNS_IP_PROTOCOL_V6);
_mdns_disable_pcb(MDNS_IF_STA, MDNS_IP_PROTOCOL_V4);
_mdns_disable_pcb(MDNS_IF_STA, MDNS_IP_PROTOCOL_V6);
break;
case WIFI_EVENT_AP_START:
_mdns_enable_pcb(TCPIP_ADAPTER_IF_AP, MDNS_IP_PROTOCOL_V4);
_mdns_enable_pcb(MDNS_IF_AP, MDNS_IP_PROTOCOL_V4);
break;
case WIFI_EVENT_AP_STOP:
_mdns_disable_pcb(TCPIP_ADAPTER_IF_AP, MDNS_IP_PROTOCOL_V4);
_mdns_disable_pcb(TCPIP_ADAPTER_IF_AP, MDNS_IP_PROTOCOL_V6);
_mdns_disable_pcb(MDNS_IF_AP, MDNS_IP_PROTOCOL_V4);
_mdns_disable_pcb(MDNS_IF_AP, MDNS_IP_PROTOCOL_V6);
break;
default:
break;
@ -3103,15 +3145,15 @@ static void _mdns_handle_system_event(esp_event_base_t event_base,
else if (event_base == ETH_EVENT) {
switch (event_id) {
case ETHERNET_EVENT_CONNECTED:
if (!tcpip_adapter_dhcpc_get_status(TCPIP_ADAPTER_IF_ETH, &dcst)) {
if (dcst == TCPIP_ADAPTER_DHCP_STOPPED) {
_mdns_enable_pcb(TCPIP_ADAPTER_IF_ETH, MDNS_IP_PROTOCOL_V4);
if (!esp_netif_dhcpc_get_status(_mdns_get_esp_netif(MDNS_IF_ETH), &dcst)) {
if (dcst == ESP_NETIF_DHCP_STOPPED) {
_mdns_enable_pcb(MDNS_IF_ETH, MDNS_IP_PROTOCOL_V4);
}
}
break;
case ETHERNET_EVENT_DISCONNECTED:
_mdns_disable_pcb(TCPIP_ADAPTER_IF_ETH, MDNS_IP_PROTOCOL_V4);
_mdns_disable_pcb(TCPIP_ADAPTER_IF_ETH, MDNS_IP_PROTOCOL_V6);
_mdns_disable_pcb(MDNS_IF_ETH, MDNS_IP_PROTOCOL_V4);
_mdns_disable_pcb(MDNS_IF_ETH, MDNS_IP_PROTOCOL_V6);
break;
default:
break;
@ -3121,17 +3163,21 @@ static void _mdns_handle_system_event(esp_event_base_t event_base,
else if (event_base == IP_EVENT) {
switch (event_id) {
case IP_EVENT_STA_GOT_IP:
_mdns_enable_pcb(TCPIP_ADAPTER_IF_STA, MDNS_IP_PROTOCOL_V4);
_mdns_announce_pcb(TCPIP_ADAPTER_IF_STA, MDNS_IP_PROTOCOL_V6, NULL, 0, true);
_mdns_enable_pcb(MDNS_IF_STA, MDNS_IP_PROTOCOL_V4);
_mdns_announce_pcb(MDNS_IF_STA, MDNS_IP_PROTOCOL_V6, NULL, 0, true);
break;
#if CONFIG_ETH_ENABLED
case IP_EVENT_ETH_GOT_IP:
_mdns_enable_pcb(TCPIP_ADAPTER_IF_ETH, MDNS_IP_PROTOCOL_V4);
_mdns_enable_pcb(MDNS_IF_ETH, MDNS_IP_PROTOCOL_V4);
break;
#endif
case IP_EVENT_GOT_IP6:
_mdns_enable_pcb(interface, MDNS_IP_PROTOCOL_V6);
_mdns_announce_pcb(interface, MDNS_IP_PROTOCOL_V4, NULL, 0, true);
{
mdns_if_t mdns_if = _mdns_get_if_from_esp_netif(interface);
_mdns_enable_pcb(mdns_if, MDNS_IP_PROTOCOL_V6);
_mdns_announce_pcb(mdns_if, MDNS_IP_PROTOCOL_V4, NULL, 0, true);
}
break;
default:
break;
@ -3248,7 +3294,7 @@ static void _mdns_search_finish_done(void)
/**
* @brief Create linked IP (copy) from parsed one
*/
static mdns_ip_addr_t * _mdns_result_addr_create_ip(ip_addr_t * ip)
static mdns_ip_addr_t * _mdns_result_addr_create_ip(esp_ip_addr_t * ip)
{
mdns_ip_addr_t * a = (mdns_ip_addr_t *)malloc(sizeof(mdns_ip_addr_t));
if (!a) {
@ -3268,7 +3314,7 @@ static mdns_ip_addr_t * _mdns_result_addr_create_ip(ip_addr_t * ip)
/**
* @brief Chain new IP to search result
*/
static void _mdns_result_add_ip(mdns_result_t * r, ip_addr_t * ip)
static void _mdns_result_add_ip(mdns_result_t * r, esp_ip_addr_t * ip)
{
mdns_ip_addr_t * a = r->addr;
while (a) {
@ -3293,7 +3339,7 @@ static void _mdns_result_add_ip(mdns_result_t * r, ip_addr_t * ip)
/**
* @brief Called from parser to add A/AAAA data to search result
*/
static void _mdns_search_result_add_ip(mdns_search_once_t * search, const char * hostname, ip_addr_t * ip, tcpip_adapter_if_t tcpip_if, mdns_ip_protocol_t ip_protocol)
static void _mdns_search_result_add_ip(mdns_search_once_t * search, const char * hostname, esp_ip_addr_t * ip, mdns_if_t tcpip_if, mdns_ip_protocol_t ip_protocol)
{
mdns_result_t * r = NULL;
mdns_ip_addr_t * a = NULL;
@ -3346,7 +3392,7 @@ static void _mdns_search_result_add_ip(mdns_search_once_t * search, const char *
/**
* @brief Called from parser to add PTR data to search result
*/
static mdns_result_t * _mdns_search_result_add_ptr(mdns_search_once_t * search, const char * instance, tcpip_adapter_if_t tcpip_if, mdns_ip_protocol_t ip_protocol)
static mdns_result_t * _mdns_search_result_add_ptr(mdns_search_once_t * search, const char * instance, mdns_if_t tcpip_if, mdns_ip_protocol_t ip_protocol)
{
mdns_result_t * r = search->result;
while (r) {
@ -3382,7 +3428,7 @@ static mdns_result_t * _mdns_search_result_add_ptr(mdns_search_once_t * search,
/**
* @brief Called from parser to add SRV data to search result
*/
static void _mdns_search_result_add_srv(mdns_search_once_t * search, const char * hostname, uint16_t port, tcpip_adapter_if_t tcpip_if, mdns_ip_protocol_t ip_protocol)
static void _mdns_search_result_add_srv(mdns_search_once_t * search, const char * hostname, uint16_t port, mdns_if_t tcpip_if, mdns_ip_protocol_t ip_protocol)
{
mdns_result_t * r = search->result;
while (r) {
@ -3416,7 +3462,7 @@ static void _mdns_search_result_add_srv(mdns_search_once_t * search, const char
/**
* @brief Called from parser to add TXT data to search result
*/
static void _mdns_search_result_add_txt(mdns_search_once_t * search, mdns_txt_item_t * txt, size_t txt_count, tcpip_adapter_if_t tcpip_if, mdns_ip_protocol_t ip_protocol)
static void _mdns_search_result_add_txt(mdns_search_once_t * search, mdns_txt_item_t * txt, size_t txt_count, mdns_if_t tcpip_if, mdns_ip_protocol_t ip_protocol)
{
int i;
mdns_result_t * r = search->result;
@ -3460,7 +3506,7 @@ free_txt:
/**
* @brief Called from packet parser to find matching running search
*/
static mdns_search_once_t * _mdns_search_find_from(mdns_search_once_t * s, mdns_name_t * name, uint16_t type, tcpip_adapter_if_t tcpip_if, mdns_ip_protocol_t ip_protocol)
static mdns_search_once_t * _mdns_search_find_from(mdns_search_once_t * s, mdns_name_t * name, uint16_t type, mdns_if_t tcpip_if, mdns_ip_protocol_t ip_protocol)
{
mdns_result_t * r = NULL;
while (s) {
@ -3530,7 +3576,7 @@ static mdns_search_once_t * _mdns_search_find_from(mdns_search_once_t * s, mdns_
/**
* @brief Create search packet for partidular interface
*/
static mdns_tx_packet_t * _mdns_create_search_packet(mdns_search_once_t * search, tcpip_adapter_if_t tcpip_if, mdns_ip_protocol_t ip_protocol)
static mdns_tx_packet_t * _mdns_create_search_packet(mdns_search_once_t * search, mdns_if_t tcpip_if, mdns_ip_protocol_t ip_protocol)
{
mdns_result_t * r = NULL;
mdns_tx_packet_t * packet = _mdns_alloc_packet_default(tcpip_if, ip_protocol);
@ -3586,7 +3632,7 @@ static mdns_tx_packet_t * _mdns_create_search_packet(mdns_search_once_t * search
/**
* @brief Send search packet to particular interface
*/
static void _mdns_search_send_pcb(mdns_search_once_t * search, tcpip_adapter_if_t tcpip_if, mdns_ip_protocol_t ip_protocol)
static void _mdns_search_send_pcb(mdns_search_once_t * search, mdns_if_t tcpip_if, mdns_ip_protocol_t ip_protocol)
{
mdns_tx_packet_t * packet = NULL;
if (_mdns_server->interfaces[tcpip_if].pcbs[ip_protocol].pcb && _mdns_server->interfaces[tcpip_if].pcbs[ip_protocol].state > PCB_INIT) {
@ -3621,9 +3667,9 @@ static void _mdns_search_send(mdns_search_once_t * search)
}
uint8_t i, j;
for (i=0; i<TCPIP_ADAPTER_IF_MAX; i++) {
for (i=0; i<MDNS_IF_MAX; i++) {
for (j=0; j<MDNS_IP_PROTOCOL_MAX; j++) {
_mdns_search_send_pcb(search, (tcpip_adapter_if_t)i, (mdns_ip_protocol_t)j);
_mdns_search_send_pcb(search, (mdns_if_t)i, (mdns_ip_protocol_t)j);
}
}
}
@ -4161,7 +4207,7 @@ static void event_handler(void* arg, esp_event_base_t event_base,
action->data.sys_event.event_id = event_id;
if (event_base == IP_EVENT && event_id == IP_EVENT_GOT_IP6) {
ip_event_got_ip6_t* event = (ip_event_got_ip6_t*) event_data;
action->data.sys_event.interface = event->if_index;
action->data.sys_event.interface = event->esp_netif;
}
if (xQueueSend(_mdns_server->action_queue, &action, (portTickType)0) != pdPASS) {
@ -4207,14 +4253,14 @@ esp_err_t mdns_init(void)
}
#endif
uint8_t i;
ip6_addr_t tmp_addr6;
tcpip_adapter_ip_info_t if_ip_info;
esp_ip6_addr_t tmp_addr6;
esp_netif_ip_info_t if_ip_info;
for (i=0; i<TCPIP_ADAPTER_IF_MAX; i++) {
if (!tcpip_adapter_get_ip6_linklocal(i, &tmp_addr6) && !_ipv6_address_is_zero(tmp_addr6)) {
for (i=0; i<MDNS_IF_MAX; i++) {
if (!esp_netif_get_ip6_linklocal(_mdns_get_esp_netif(i), &tmp_addr6) && !_ipv6_address_is_zero(tmp_addr6)) {
_mdns_enable_pcb(i, MDNS_IP_PROTOCOL_V6);
}
if (!tcpip_adapter_get_ip_info(i, &if_ip_info) && if_ip_info.ip.addr) {
if (!esp_netif_get_ip_info(_mdns_get_esp_netif(i), &if_ip_info) && if_ip_info.ip.addr) {
_mdns_enable_pcb(i, MDNS_IP_PROTOCOL_V4);
}
}
@ -4228,7 +4274,7 @@ esp_err_t mdns_init(void)
return ESP_OK;
free_all_and_disable_pcbs:
for (i=0; i<TCPIP_ADAPTER_IF_MAX; i++) {
for (i=0; i<MDNS_IF_MAX; i++) {
_mdns_disable_pcb(i, MDNS_IP_PROTOCOL_V6);
_mdns_disable_pcb(i, MDNS_IP_PROTOCOL_V4);
}
@ -4255,7 +4301,7 @@ void mdns_free(void)
}
mdns_service_remove_all();
_mdns_service_task_stop();
for (i=0; i<TCPIP_ADAPTER_IF_MAX; i++) {
for (i=0; i<MDNS_IF_MAX; i++) {
for (j=0; j<MDNS_IP_PROTOCOL_MAX; j++) {
_mdns_pcb_deinit(i, j);
}
@ -4711,7 +4757,7 @@ esp_err_t mdns_query_txt(const char * instance, const char * service, const char
return mdns_query(instance, service, proto, MDNS_TYPE_TXT, timeout, 1, result);
}
esp_err_t mdns_query_a(const char * name, uint32_t timeout, ip4_addr_t * addr)
esp_err_t mdns_query_a(const char * name, uint32_t timeout, esp_ip4_addr_t * addr)
{
mdns_result_t * result = NULL;
esp_err_t err;
@ -4744,7 +4790,7 @@ esp_err_t mdns_query_a(const char * name, uint32_t timeout, ip4_addr_t * addr)
return ESP_ERR_NOT_FOUND;
}
esp_err_t mdns_query_aaaa(const char * name, uint32_t timeout, ip6_addr_t * addr)
esp_err_t mdns_query_aaaa(const char * name, uint32_t timeout, esp_ip6_addr_t * addr)
{
mdns_result_t * result = NULL;
esp_err_t err;
@ -4964,12 +5010,17 @@ void mdns_debug_packet(const uint8_t * data, size_t len)
}
_mdns_dbg_printf("\n");
} else if (type == MDNS_TYPE_AAAA) {
<<<<<<< HEAD
ip6_addr_t ip6;
memcpy(&ip6, data_ptr, MDNS_ANSWER_AAAA_SIZE);
=======
esp_ip6_addr_t ip6;
memcpy(&ip6, data_ptr, sizeof(esp_ip6_addr_t));
>>>>>>> mdns: update mdns to use esp-netif for mdns supported services such as STA, AP, ETH
_mdns_dbg_printf(IPV6STR "\n", IPV62STR(ip6));
} else if (type == MDNS_TYPE_A) {
ip4_addr_t ip;
memcpy(&ip, data_ptr, sizeof(ip4_addr_t));
esp_ip4_addr_t ip;
memcpy(&ip, data_ptr, sizeof(esp_ip4_addr_t));
_mdns_dbg_printf(IPSTR "\n", IP2STR(&ip));
} else if (type == MDNS_TYPE_NSEC) {
const uint8_t * old_ptr = data_ptr;

View file

@ -42,7 +42,7 @@ static void mdns_print_results(mdns_result_t * results)
}
a = r->addr;
while (a) {
if (a->addr.type == IPADDR_TYPE_V6) {
if (a->addr.type == ESP_IPADDR_TYPE_V6) {
printf(" AAAA: " IPV6STR "\n", IPV62STR(a->addr.u_addr.ip6));
} else {
printf(" A : " IPSTR "\n", IP2STR(&(a->addr.u_addr.ip4)));
@ -81,7 +81,7 @@ static int cmd_mdns_query_a(int argc, char** argv)
printf("Query A: %s.local, Timeout: %d\n", hostname, timeout);
struct ip4_addr addr;
struct esp_ip4_addr addr;
addr.addr = 0;
esp_err_t err = mdns_query_a(hostname, timeout, &addr);
@ -138,7 +138,7 @@ static int cmd_mdns_query_aaaa(int argc, char** argv)
printf("Query AAAA: %s.local, Timeout: %d\n", hostname, timeout);
struct ip6_addr addr;
struct esp_ip6_addr addr;
memset(addr.addr, 0, 16);
esp_err_t err = mdns_query_aaaa(hostname, timeout, &addr);

View file

@ -6,6 +6,7 @@
#include <string.h>
#include "mdns_networking.h"
#include "esp_log.h"
#include "esp_netif_net_stack.h"
extern mdns_server_t * _mdns_server;
@ -60,21 +61,18 @@ static void _udp_pcb_main_deinit(void)
/**
* @brief Low level UDP Multicast membership control
*/
static esp_err_t _udp_join_group(tcpip_adapter_if_t tcpip_if, mdns_ip_protocol_t ip_protocol, bool join)
static esp_err_t _udp_join_group(mdns_if_t if_inx, mdns_ip_protocol_t ip_protocol, bool join)
{
struct netif * netif = NULL;
void * nif = NULL;
esp_netif_t *tcpip_if = _mdns_get_esp_netif(if_inx);
if (!tcpip_adapter_is_netif_up(tcpip_if)) {
if (!esp_netif_is_netif_up(tcpip_if)) {
// Network interface went down before event propagated, skipping IGMP config
return ESP_ERR_INVALID_STATE;
}
esp_err_t err = tcpip_adapter_get_netif(tcpip_if, &nif);
if (err) {
return ESP_ERR_INVALID_ARG;
}
netif = (struct netif *)nif;
netif = esp_netif_get_netif_impl(tcpip_if);
assert(netif);
if (ip_protocol == MDNS_IP_PROTOCOL_V4) {
ip_addr_t multicast_addr;
@ -126,7 +124,7 @@ static void _udp_recv(void *arg, struct udp_pcb *upcb, struct pbuf *pb, const ip
continue;
}
packet->tcpip_if = TCPIP_ADAPTER_IF_MAX;
packet->tcpip_if = MDNS_IF_MAX;
packet->pb = this_pb;
packet->src_port = rport;
memcpy(&packet->src, raddr, sizeof(ip_addr_t));
@ -145,12 +143,10 @@ static void _udp_recv(void *arg, struct udp_pcb *upcb, struct pbuf *pb, const ip
//lwip does not return the proper pcb if you have more than one for the same multicast address (but different interfaces)
struct netif * netif = NULL;
void * nif = NULL;
struct udp_pcb * pcb = NULL;
for (i=0; i<TCPIP_ADAPTER_IF_MAX; i++) {
for (i=0; i<MDNS_IF_MAX; i++) {
pcb = _mdns_server->interfaces[i].pcbs[packet->ip_protocol].pcb;
tcpip_adapter_get_netif (i, &nif);
netif = (struct netif *)nif;
netif = esp_netif_get_netif_impl(_mdns_get_esp_netif(i));
if (pcb && netif && netif == ip_current_input_netif ()) {
if (packet->src.type == IPADDR_TYPE_V4) {
if ((packet->src.u_addr.ip4.addr & netif->netmask.u_addr.ip4.addr) != (netif->ip_addr.u_addr.ip4.addr & netif->netmask.u_addr.ip4.addr)) {
@ -179,7 +175,7 @@ static void _udp_recv(void *arg, struct udp_pcb *upcb, struct pbuf *pb, const ip
*/
static bool _udp_pcb_is_in_use(void){
int i, p;
for (i=0; i<TCPIP_ADAPTER_IF_MAX; i++) {
for (i=0; i<MDNS_IF_MAX; i++) {
for (p=0; p<MDNS_IP_PROTOCOL_MAX; p++) {
if(_mdns_server->interfaces[i].pcbs[p].pcb){
return true;
@ -192,7 +188,7 @@ static bool _udp_pcb_is_in_use(void){
/**
* @brief Stop PCB Main code
*/
static void _udp_pcb_deinit(tcpip_adapter_if_t tcpip_if, mdns_ip_protocol_t ip_protocol)
static void _udp_pcb_deinit(mdns_if_t tcpip_if, mdns_ip_protocol_t ip_protocol)
{
if (!_mdns_server) {
return;
@ -217,7 +213,7 @@ static void _udp_pcb_deinit(tcpip_adapter_if_t tcpip_if, mdns_ip_protocol_t ip_p
/**
* @brief Start PCB Main code
*/
static esp_err_t _udp_pcb_init(tcpip_adapter_if_t tcpip_if, mdns_ip_protocol_t ip_protocol)
static esp_err_t _udp_pcb_init(mdns_if_t tcpip_if, mdns_ip_protocol_t ip_protocol)
{
if (!_mdns_server || _mdns_server->interfaces[tcpip_if].pcbs[ip_protocol].pcb) {
return ESP_ERR_INVALID_STATE;
@ -240,7 +236,7 @@ static esp_err_t _udp_pcb_init(tcpip_adapter_if_t tcpip_if, mdns_ip_protocol_t i
typedef struct {
struct tcpip_api_call_data call;
tcpip_adapter_if_t tcpip_if;
mdns_if_t tcpip_if;
mdns_ip_protocol_t ip_protocol;
struct pbuf *pbt;
const ip_addr_t *ip;
@ -274,7 +270,7 @@ static err_t _mdns_pcb_deinit_api(struct tcpip_api_call_data *api_call_msg)
* - _mdns prefixed
* - commented in mdns_networking.h header
*/
esp_err_t _mdns_pcb_init(tcpip_adapter_if_t tcpip_if, mdns_ip_protocol_t ip_protocol)
esp_err_t _mdns_pcb_init(mdns_if_t tcpip_if, mdns_ip_protocol_t ip_protocol)
{
mdns_api_call_t msg = {
.tcpip_if = tcpip_if,
@ -284,7 +280,7 @@ esp_err_t _mdns_pcb_init(tcpip_adapter_if_t tcpip_if, mdns_ip_protocol_t ip_prot
return msg.err;
}
esp_err_t _mdns_pcb_deinit(tcpip_adapter_if_t tcpip_if, mdns_ip_protocol_t ip_protocol)
esp_err_t _mdns_pcb_deinit(mdns_if_t tcpip_if, mdns_ip_protocol_t ip_protocol)
{
mdns_api_call_t msg = {
.tcpip_if = tcpip_if,
@ -299,19 +295,19 @@ static err_t _mdns_udp_pcb_write_api(struct tcpip_api_call_data *api_call_msg)
void * nif = NULL;
mdns_api_call_t * msg = (mdns_api_call_t *)api_call_msg;
mdns_pcb_t * _pcb = &_mdns_server->interfaces[msg->tcpip_if].pcbs[msg->ip_protocol];
esp_err_t err = tcpip_adapter_get_netif(msg->tcpip_if, &nif);
if (err) {
nif = esp_netif_get_netif_impl(_mdns_get_esp_netif(msg->tcpip_if));
if (!nif) {
pbuf_free(msg->pbt);
msg->err = err;
return err;
msg->err = ERR_IF;
return ERR_IF;
}
err = udp_sendto_if (_pcb->pcb, msg->pbt, msg->ip, msg->port, (struct netif *)nif);
esp_err_t err = udp_sendto_if (_pcb->pcb, msg->pbt, msg->ip, msg->port, (struct netif *)nif);
pbuf_free(msg->pbt);
msg->err = err;
return err;
}
size_t _mdns_udp_pcb_write(tcpip_adapter_if_t tcpip_if, mdns_ip_protocol_t ip_protocol, const ip_addr_t *ip, uint16_t port, uint8_t * data, size_t len)
size_t _mdns_udp_pcb_write(mdns_if_t tcpip_if, mdns_ip_protocol_t ip_protocol, const esp_ip_addr_t *ip, uint16_t port, uint8_t * data, size_t len)
{
struct pbuf* pbt = pbuf_alloc(PBUF_TRANSPORT, len, PBUF_RAM);
if (pbt == NULL) {
@ -323,7 +319,7 @@ size_t _mdns_udp_pcb_write(tcpip_adapter_if_t tcpip_if, mdns_ip_protocol_t ip_pr
.tcpip_if = tcpip_if,
.ip_protocol = ip_protocol,
.pbt = pbt,
.ip = ip,
.ip = (ip_addr_t *)ip,
.port = port
};
tcpip_api_call(_mdns_udp_pcb_write_api, &msg.call);

View file

@ -34,12 +34,12 @@ esp_err_t _mdns_send_rx_action(mdns_rx_packet_t * packet);
/**
* @brief Start PCB
*/
esp_err_t _mdns_pcb_init(tcpip_adapter_if_t tcpip_if, mdns_ip_protocol_t ip_protocol);
esp_err_t _mdns_pcb_init(mdns_if_t tcpip_if, mdns_ip_protocol_t ip_protocol);
/**
* @brief Stop PCB
*/
esp_err_t _mdns_pcb_deinit(tcpip_adapter_if_t tcpip_if, mdns_ip_protocol_t ip_protocol);
esp_err_t _mdns_pcb_deinit(mdns_if_t tcpip_if, mdns_ip_protocol_t ip_protocol);
/**
* @brief send packet over UDP
@ -50,6 +50,6 @@ esp_err_t _mdns_pcb_deinit(tcpip_adapter_if_t tcpip_if, mdns_ip_protocol_t ip_pr
*
* @return length of sent packet or 0 on error
*/
size_t _mdns_udp_pcb_write(tcpip_adapter_if_t tcpip_if, mdns_ip_protocol_t ip_protocol, const ip_addr_t *ip, uint16_t port, uint8_t * data, size_t len);
size_t _mdns_udp_pcb_write(mdns_if_t tcpip_if, mdns_ip_protocol_t ip_protocol, const esp_ip_addr_t *ip, uint16_t port, uint8_t * data, size_t len);
#endif /* ESP_MDNS_NETWORKING_H_ */

View file

@ -214,10 +214,10 @@ typedef struct mdns_parsed_record_s {
} mdns_parsed_record_t;
typedef struct {
tcpip_adapter_if_t tcpip_if;
mdns_if_t tcpip_if;
mdns_ip_protocol_t ip_protocol;
//struct udp_pcb *pcb;
ip_addr_t src;
esp_ip_addr_t src;
uint16_t src_port;
uint8_t multicast;
uint8_t authoritative;
@ -229,11 +229,11 @@ typedef struct {
} mdns_parsed_packet_t;
typedef struct {
tcpip_adapter_if_t tcpip_if;
mdns_if_t tcpip_if;
mdns_ip_protocol_t ip_protocol;
struct pbuf *pb;
ip_addr_t src;
ip_addr_t dest;
esp_ip_addr_t src;
esp_ip_addr_t dest;
uint16_t src_port;
uint8_t multicast;
} mdns_rx_packet_t;
@ -283,9 +283,9 @@ typedef struct mdns_out_answer_s {
typedef struct mdns_tx_packet_s {
struct mdns_tx_packet_s * next;
uint32_t send_at;
tcpip_adapter_if_t tcpip_if;
mdns_if_t tcpip_if;
mdns_ip_protocol_t ip_protocol;
ip_addr_t dst;
esp_ip_addr_t dst;
uint16_t port;
uint16_t flags;
uint8_t distributed;
@ -333,7 +333,7 @@ typedef struct mdns_search_once_s {
typedef struct mdns_server_s {
struct {
mdns_pcb_t pcbs[MDNS_IP_PROTOCOL_MAX];
} interfaces[TCPIP_ADAPTER_IF_MAX];
} interfaces[MDNS_IF_MAX];
const char * hostname;
const char * instance;
mdns_srv_item_t * services;
@ -352,7 +352,7 @@ typedef struct {
struct {
esp_event_base_t event_base;
int32_t event_id;
tcpip_adapter_if_t interface;
esp_netif_t* interface;
} sys_event;
struct {
mdns_srv_item_t * service;
@ -393,4 +393,16 @@ typedef struct {
} data;
} mdns_action_t;
/*
* @brief Convert mnds if to esp-netif handle
*
* @param tcpip_if mdns supported interface as internal enum
*
* @return
* - ptr to esp-netif on success
* - NULL if no available netif for current interface index
*/
esp_netif_t *_mdns_get_esp_netif(mdns_if_t tcpip_if);
#endif /* MDNS_PRIVATE_H_ */

View file

@ -73,8 +73,8 @@ TEST_CASE("mdns api return expected err-code and do not leak memory", "[mdns][le
TEST_CASE("mdns query api return expected err-code and do not leak memory", "[leaks=64]")
{
mdns_result_t * results = NULL;
ip6_addr_t addr6;
ip4_addr_t addr4;
esp_ip6_addr_t addr6;
esp_ip4_addr_t addr4;
test_case_uses_tcpip();
TEST_ASSERT_EQUAL(ESP_OK, esp_event_loop_create_default());

View file

@ -1,3 +1,3 @@
idf_component_register(SRCS "event_handlers.c" "tcpip_adapter_lwip.c"
idf_component_register(SRCS "tcpip_adapter_compat.c"
INCLUDE_DIRS include
REQUIRES lwip esp_eth)
REQUIRES esp_netif)

View file

@ -1,312 +0,0 @@
// Copyright 2018 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <string.h>
#include "tcpip_adapter.h"
#include "esp_event.h"
#include "esp_wifi.h"
#include "esp_private/wifi.h"
#if CONFIG_ETH_ENABLED
#include "esp_eth.h"
#endif
#include "esp_err.h"
#include "esp_log.h"
static const char *TAG = "tcpip_adapter";
#define API_CALL_CHECK(info, api_call, ret) \
do{\
esp_err_t __err = (api_call);\
if ((ret) != __err) {\
ESP_LOGE(TAG, "%s %d %s ret=0x%X", __FUNCTION__, __LINE__, (info), __err);\
return;\
}\
} while(0)
static void handle_ap_start(void *arg, esp_event_base_t base, int32_t event_id, void *data);
static void handle_ap_stop(void *arg, esp_event_base_t base, int32_t event_id, void *data);
static void handle_sta_start(void *arg, esp_event_base_t base, int32_t event_id, void *data);
static void handle_sta_stop(void *arg, esp_event_base_t base, int32_t event_id, void *data);
static void handle_sta_connected(void *arg, esp_event_base_t base, int32_t event_id, void *data);
static void handle_sta_disconnected(void *arg, esp_event_base_t base, int32_t event_id, void *data);
static void handle_sta_got_ip(void *arg, esp_event_base_t base, int32_t event_id, void *data);
#if CONFIG_ETH_ENABLED
static void handle_eth_start(void *arg, esp_event_base_t base, int32_t event_id, void *data);
static void handle_eth_stop(void *arg, esp_event_base_t base, int32_t event_id, void *data);
static void handle_eth_connected(void *arg, esp_event_base_t base, int32_t event_id, void *data);
static void handle_eth_disconnected(void *arg, esp_event_base_t base, int32_t event_id, void *data);
static void handle_eth_got_ip(void *arg, esp_event_base_t base, int32_t event_id, void *data);
static void handle_eth_start(void *arg, esp_event_base_t base, int32_t event_id, void *data)
{
tcpip_adapter_ip_info_t eth_ip;
uint8_t eth_mac[6];
esp_eth_handle_t eth_handle = *(esp_eth_handle_t*)data;
esp_eth_ioctl(eth_handle, ETH_CMD_G_MAC_ADDR, eth_mac);
tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_ETH, &eth_ip);
tcpip_adapter_eth_start(eth_mac, &eth_ip, eth_handle);
}
static void handle_eth_stop(void *arg, esp_event_base_t base, int32_t event_id, void *data)
{
tcpip_adapter_stop(TCPIP_ADAPTER_IF_ETH);
}
static void handle_eth_connected(void *arg, esp_event_base_t base, int32_t event_id, void *data)
{
tcpip_adapter_dhcp_status_t status;
tcpip_adapter_up(TCPIP_ADAPTER_IF_ETH);
tcpip_adapter_dhcpc_get_status(TCPIP_ADAPTER_IF_ETH, &status);
if (status == TCPIP_ADAPTER_DHCP_INIT) {
tcpip_adapter_dhcpc_start(TCPIP_ADAPTER_IF_ETH);
} else if (status == TCPIP_ADAPTER_DHCP_STOPPED) {
tcpip_adapter_ip_info_t eth_ip;
tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_ETH, &eth_ip);
if (!(ip4_addr_isany_val(eth_ip.ip) || ip4_addr_isany_val(eth_ip.netmask))) {
ip_event_got_ip_t evt;
//notify event
evt.if_index = TCPIP_ADAPTER_IF_ETH;
memcpy(&evt.ip_info, &eth_ip, sizeof(tcpip_adapter_ip_info_t));
API_CALL_CHECK("handle_eth_connected", esp_event_send_internal(IP_EVENT, IP_EVENT_ETH_GOT_IP, &evt, sizeof(evt), 0), ESP_OK);
} else {
ESP_LOGE(TAG, "invalid static ip");
}
}
}
static void handle_eth_disconnected(void *arg, esp_event_base_t base, int32_t event_id, void *data)
{
tcpip_adapter_down(TCPIP_ADAPTER_IF_ETH);
}
static void handle_eth_got_ip(void *arg, esp_event_base_t base, int32_t event_id, void *data)
{
const ip_event_got_ip_t *event = (const ip_event_got_ip_t *) data;
ESP_LOGI(TAG, "eth ip: " IPSTR ", mask: " IPSTR ", gw: " IPSTR,
IP2STR(&event->ip_info.ip),
IP2STR(&event->ip_info.netmask),
IP2STR(&event->ip_info.gw));
}
#endif
static void handle_sta_got_ip(void *arg, esp_event_base_t base, int32_t event_id, void *data)
{
API_CALL_CHECK("esp_wifi_internal_set_sta_ip", esp_wifi_internal_set_sta_ip(), ESP_OK);
const ip_event_got_ip_t *event = (const ip_event_got_ip_t *) data;
ESP_LOGI(TAG, "sta ip: " IPSTR ", mask: " IPSTR ", gw: " IPSTR,
IP2STR(&event->ip_info.ip),
IP2STR(&event->ip_info.netmask),
IP2STR(&event->ip_info.gw));
}
static void handle_ap_start(void *arg, esp_event_base_t base, int32_t event_id, void *data)
{
tcpip_adapter_ip_info_t ap_ip;
uint8_t ap_mac[6];
API_CALL_CHECK("esp_wifi_internal_reg_rxcb", esp_wifi_internal_reg_rxcb(ESP_IF_WIFI_AP, (wifi_rxcb_t)tcpip_adapter_ap_input), ESP_OK);
API_CALL_CHECK("esp_wifi_mac_get", esp_wifi_get_mac(ESP_IF_WIFI_AP, ap_mac), ESP_OK);
tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_AP, &ap_ip);
tcpip_adapter_ap_start(ap_mac, &ap_ip);
}
static void handle_ap_stop(void *arg, esp_event_base_t base, int32_t event_id, void *data)
{
API_CALL_CHECK("esp_wifi_internal_reg_rxcb", esp_wifi_internal_reg_rxcb(ESP_IF_WIFI_AP, NULL), ESP_OK);
tcpip_adapter_stop(TCPIP_ADAPTER_IF_AP);
}
static void handle_sta_start(void *arg, esp_event_base_t base, int32_t event_id, void *data)
{
tcpip_adapter_ip_info_t sta_ip;
uint8_t sta_mac[6];
API_CALL_CHECK("esp_wifi_mac_get", esp_wifi_get_mac(ESP_IF_WIFI_STA, sta_mac), ESP_OK);
tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_STA, &sta_ip);
tcpip_adapter_sta_start(sta_mac, &sta_ip);
}
static void handle_sta_stop(void *arg, esp_event_base_t base, int32_t event_id, void *data)
{
tcpip_adapter_stop(TCPIP_ADAPTER_IF_STA);
}
static void handle_sta_connected(void *arg, esp_event_base_t base, int32_t event_id, void *data)
{
tcpip_adapter_dhcp_status_t status;
API_CALL_CHECK("esp_wifi_internal_reg_rxcb", esp_wifi_internal_reg_rxcb(ESP_IF_WIFI_STA, (wifi_rxcb_t)tcpip_adapter_sta_input), ESP_OK);
tcpip_adapter_up(TCPIP_ADAPTER_IF_STA);
tcpip_adapter_dhcpc_get_status(TCPIP_ADAPTER_IF_STA, &status);
if (status == TCPIP_ADAPTER_DHCP_INIT) {
tcpip_adapter_dhcpc_start(TCPIP_ADAPTER_IF_STA);
} else if (status == TCPIP_ADAPTER_DHCP_STOPPED) {
tcpip_adapter_ip_info_t sta_ip;
tcpip_adapter_ip_info_t sta_old_ip;
tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_STA, &sta_ip);
tcpip_adapter_get_old_ip_info(TCPIP_ADAPTER_IF_STA, &sta_old_ip);
if (!(ip4_addr_isany_val(sta_ip.ip) || ip4_addr_isany_val(sta_ip.netmask))) {
ip_event_got_ip_t evt;
evt.if_index = TCPIP_ADAPTER_IF_STA;
evt.ip_changed = false;
if (memcmp(&sta_ip, &sta_old_ip, sizeof(sta_ip))) {
evt.ip_changed = true;
}
memcpy(&evt.ip_info, &sta_ip, sizeof(tcpip_adapter_ip_info_t));
tcpip_adapter_set_old_ip_info(TCPIP_ADAPTER_IF_STA, &sta_ip);
API_CALL_CHECK("handle_sta_connected", esp_event_send_internal(IP_EVENT, IP_EVENT_STA_GOT_IP, &evt, sizeof(evt), 0), ESP_OK);
ESP_LOGD(TAG, "static ip: ip changed=%d", evt.ip_changed);
} else {
ESP_LOGE(TAG, "invalid static ip");
}
}
}
static void handle_sta_disconnected(void *arg, esp_event_base_t base, int32_t event_id, void *data)
{
tcpip_adapter_down(TCPIP_ADAPTER_IF_STA);
API_CALL_CHECK("esp_wifi_internal_reg_rxcb", esp_wifi_internal_reg_rxcb(ESP_IF_WIFI_STA, NULL), ESP_OK);
}
esp_err_t tcpip_adapter_set_default_wifi_handlers(void)
{
esp_err_t err;
err = esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_STA_START, handle_sta_start, NULL);
if (err != ESP_OK) {
goto fail;
}
err = esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_STA_STOP, handle_sta_stop, NULL);
if (err != ESP_OK) {
goto fail;
}
err = esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_STA_CONNECTED, handle_sta_connected, NULL);
if (err != ESP_OK) {
goto fail;
}
err = esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_STA_DISCONNECTED, handle_sta_disconnected, NULL);
if (err != ESP_OK) {
goto fail;
}
err = esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_AP_START, handle_ap_start, NULL);
if (err != ESP_OK) {
goto fail;
}
err = esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_AP_STOP, handle_ap_stop, NULL);
if (err != ESP_OK) {
goto fail;
}
err = esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, handle_sta_got_ip, NULL);
if (err != ESP_OK) {
goto fail;
}
err = esp_register_shutdown_handler((shutdown_handler_t)esp_wifi_stop);
if (err != ESP_OK && err != ESP_ERR_INVALID_STATE) {
goto fail;
}
return ESP_OK;
fail:
tcpip_adapter_clear_default_wifi_handlers();
return err;
}
esp_err_t tcpip_adapter_clear_default_wifi_handlers(void)
{
esp_event_handler_unregister(WIFI_EVENT, WIFI_EVENT_STA_START, handle_sta_start);
esp_event_handler_unregister(WIFI_EVENT, WIFI_EVENT_STA_STOP, handle_sta_stop);
esp_event_handler_unregister(WIFI_EVENT, WIFI_EVENT_STA_CONNECTED, handle_sta_connected);
esp_event_handler_unregister(WIFI_EVENT, WIFI_EVENT_STA_DISCONNECTED, handle_sta_disconnected);
esp_event_handler_unregister(WIFI_EVENT, WIFI_EVENT_AP_START, handle_ap_start);
esp_event_handler_unregister(WIFI_EVENT, WIFI_EVENT_AP_STOP, handle_ap_stop);
esp_event_handler_unregister(IP_EVENT, IP_EVENT_STA_GOT_IP, handle_sta_got_ip);
esp_unregister_shutdown_handler((shutdown_handler_t)esp_wifi_stop);
return ESP_OK;
}
#if CONFIG_ETH_ENABLED
esp_err_t tcpip_adapter_set_default_eth_handlers(void)
{
esp_err_t err;
err = esp_event_handler_register(ETH_EVENT, ETHERNET_EVENT_START, handle_eth_start, NULL);
if (err != ESP_OK) {
goto fail;
}
err = esp_event_handler_register(ETH_EVENT, ETHERNET_EVENT_STOP, handle_eth_stop, NULL);
if (err != ESP_OK) {
goto fail;
}
err = esp_event_handler_register(ETH_EVENT, ETHERNET_EVENT_CONNECTED, handle_eth_connected, NULL);
if (err != ESP_OK) {
goto fail;
}
err = esp_event_handler_register(ETH_EVENT, ETHERNET_EVENT_DISCONNECTED, handle_eth_disconnected, NULL);
if (err != ESP_OK) {
goto fail;
}
err = esp_event_handler_register(IP_EVENT, IP_EVENT_ETH_GOT_IP, handle_eth_got_ip, NULL);
if (err != ESP_OK) {
goto fail;
}
return ESP_OK;
fail:
tcpip_adapter_clear_default_eth_handlers();
return err;
}
esp_err_t tcpip_adapter_clear_default_eth_handlers(void)
{
esp_event_handler_unregister(ETH_EVENT, ETHERNET_EVENT_START, handle_eth_start);
esp_event_handler_unregister(ETH_EVENT, ETHERNET_EVENT_STOP, handle_eth_stop);
esp_event_handler_unregister(ETH_EVENT, ETHERNET_EVENT_CONNECTED, handle_eth_connected);
esp_event_handler_unregister(ETH_EVENT, ETHERNET_EVENT_DISCONNECTED, handle_eth_disconnected);
esp_event_handler_unregister(IP_EVENT, IP_EVENT_ETH_GOT_IP, handle_eth_got_ip);
return ESP_OK;
}
#endif

View file

@ -1,4 +1,4 @@
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
// Copyright 2015-2019 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@ -11,746 +11,238 @@
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef _ESP_NETIF_SUPPRESS_LEGACY_WARNING_
#warning "This header is deprecated, please use new network related API in esp_netif.h"
#include "esp_netif.h"
#endif
#ifndef _TCPIP_ADAPTER_H_
#define _TCPIP_ADAPTER_H_
#include <stdint.h>
#include "sys/queue.h"
#include "esp_wifi_types.h"
#include "sdkconfig.h"
#if CONFIG_TCPIP_LWIP
#include "lwip/ip_addr.h"
#include "dhcpserver/dhcpserver.h"
typedef dhcps_lease_t tcpip_adapter_dhcps_lease_t;
#ifdef __cplusplus
extern "C" {
#endif
#define IP2STR(ipaddr) ip4_addr1_16(ipaddr), \
ip4_addr2_16(ipaddr), \
ip4_addr3_16(ipaddr), \
ip4_addr4_16(ipaddr)
#define IPSTR "%d.%d.%d.%d"
#define IPV62STR(ipaddr) IP6_ADDR_BLOCK1(&(ipaddr)), \
IP6_ADDR_BLOCK2(&(ipaddr)), \
IP6_ADDR_BLOCK3(&(ipaddr)), \
IP6_ADDR_BLOCK4(&(ipaddr)), \
IP6_ADDR_BLOCK5(&(ipaddr)), \
IP6_ADDR_BLOCK6(&(ipaddr)), \
IP6_ADDR_BLOCK7(&(ipaddr)), \
IP6_ADDR_BLOCK8(&(ipaddr))
#define IPV6STR "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x"
/** @brief IPV4 IP address information
*/
typedef struct {
ip4_addr_t ip; /**< Interface IPV4 address */
ip4_addr_t netmask; /**< Interface IPV4 netmask */
ip4_addr_t gw; /**< Interface IPV4 gateway address */
} tcpip_adapter_ip_info_t;
/** @brief IPV6 IP address information
*/
typedef struct {
ip6_addr_t ip; /**< Interface IPV6 address */
} tcpip_adapter_ip6_info_t;
/** @brief IP address info of station connected to WLAN AP
*
* @note See also wifi_sta_info_t (MAC layer information only)
*/
typedef struct {
uint8_t mac[6]; /**< Station MAC address */
ip4_addr_t ip; /**< Station assigned IP address */
} tcpip_adapter_sta_info_t;
/** @brief WLAN AP: Connected stations list
*
* Used to retrieve IP address information about connected stations.
*/
typedef struct {
tcpip_adapter_sta_info_t sta[ESP_WIFI_MAX_CONN_NUM]; /**< Connected stations */
int num; /**< Number of connected stations */
} tcpip_adapter_sta_list_t;
#endif
#define ESP_ERR_TCPIP_ADAPTER_BASE 0x5000
#define ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS ESP_ERR_TCPIP_ADAPTER_BASE + 0x01
#define ESP_ERR_TCPIP_ADAPTER_IF_NOT_READY ESP_ERR_TCPIP_ADAPTER_BASE + 0x02
#define ESP_ERR_TCPIP_ADAPTER_DHCPC_START_FAILED ESP_ERR_TCPIP_ADAPTER_BASE + 0x03
#define ESP_ERR_TCPIP_ADAPTER_DHCP_ALREADY_STARTED ESP_ERR_TCPIP_ADAPTER_BASE + 0x04
#define ESP_ERR_TCPIP_ADAPTER_DHCP_ALREADY_STOPPED ESP_ERR_TCPIP_ADAPTER_BASE + 0x05
#define ESP_ERR_TCPIP_ADAPTER_NO_MEM ESP_ERR_TCPIP_ADAPTER_BASE + 0x06
#define ESP_ERR_TCPIP_ADAPTER_DHCP_NOT_STOPPED ESP_ERR_TCPIP_ADAPTER_BASE + 0x07
/* @brief On-chip network interfaces */
typedef enum {
TCPIP_ADAPTER_IF_STA = 0, /**< Wi-Fi STA (station) interface */
TCPIP_ADAPTER_IF_AP, /**< Wi-Fi soft-AP interface */
TCPIP_ADAPTER_IF_ETH, /**< Ethernet interface */
TCPIP_ADAPTER_IF_TEST, /**< tcpip stack test interface */
TCPIP_ADAPTER_IF_MAX
} tcpip_adapter_if_t;
/** @brief Type of DNS server */
typedef enum {
TCPIP_ADAPTER_DNS_MAIN= 0, /**< DNS main server address*/
TCPIP_ADAPTER_DNS_BACKUP, /**< DNS backup server address (Wi-Fi STA and Ethernet only) */
TCPIP_ADAPTER_DNS_FALLBACK, /**< DNS fallback server address (Wi-Fi STA and Ethernet only) */
TCPIP_ADAPTER_DNS_MAX
} tcpip_adapter_dns_type_t;
/** @brief DNS server info */
typedef struct {
ip_addr_t ip; /**< IPV4 address of DNS server */
} tcpip_adapter_dns_info_t;
/** @brief Status of DHCP client or DHCP server */
typedef enum {
TCPIP_ADAPTER_DHCP_INIT = 0, /**< DHCP client/server is in initial state (not yet started) */
TCPIP_ADAPTER_DHCP_STARTED, /**< DHCP client/server has been started */
TCPIP_ADAPTER_DHCP_STOPPED, /**< DHCP client/server has been stopped */
TCPIP_ADAPTER_DHCP_STATUS_MAX
} tcpip_adapter_dhcp_status_t;
/** @brief Mode for DHCP client or DHCP server option functions */
typedef enum{
TCPIP_ADAPTER_OP_START = 0,
TCPIP_ADAPTER_OP_SET, /**< Set option */
TCPIP_ADAPTER_OP_GET, /**< Get option */
TCPIP_ADAPTER_OP_MAX
} tcpip_adapter_dhcp_option_mode_t;
/* Deprecated name for tcpip_adapter_dhcp_option_mode_t, to remove after ESP-IDF V4.0 */
typedef tcpip_adapter_dhcp_option_mode_t tcpip_adapter_option_mode_t;
/** @brief Supported options for DHCP client or DHCP server */
typedef enum{
TCPIP_ADAPTER_DOMAIN_NAME_SERVER = 6, /**< Domain name server */
TCPIP_ADAPTER_ROUTER_SOLICITATION_ADDRESS = 32, /**< Solicitation router address */
TCPIP_ADAPTER_REQUESTED_IP_ADDRESS = 50, /**< Request specific IP address */
TCPIP_ADAPTER_IP_ADDRESS_LEASE_TIME = 51, /**< Request IP address lease time */
TCPIP_ADAPTER_IP_REQUEST_RETRY_TIME = 52, /**< Request IP address retry counter */
} tcpip_adapter_dhcp_option_id_t;
/* Deprecated name for tcpip_adapter_dhcp_option_id_t, to remove after ESP-IDF V4.0 */
typedef tcpip_adapter_dhcp_option_id_t tcpip_adapter_option_id_t;
/** IP event declarations */
typedef enum {
IP_EVENT_STA_GOT_IP, /*!< ESP32 station got IP from connected AP */
IP_EVENT_STA_LOST_IP, /*!< ESP32 station lost IP and the IP is reset to 0 */
IP_EVENT_AP_STAIPASSIGNED, /*!< ESP32 soft-AP assign an IP to a connected station */
IP_EVENT_GOT_IP6, /*!< ESP32 station or ap or ethernet interface v6IP addr is preferred */
IP_EVENT_ETH_GOT_IP, /*!< ESP32 ethernet got IP from connected AP */
} ip_event_t;
/** @brief IP event base declaration */
ESP_EVENT_DECLARE_BASE(IP_EVENT);
/** Event structure for IP_EVENT_STA_GOT_IP, IP_EVENT_ETH_GOT_IP events */
typedef struct {
tcpip_adapter_if_t if_index; /*!< Interface for which the event is received */
tcpip_adapter_ip_info_t ip_info; /*!< IP address, netmask, gatway IP address */
bool ip_changed; /*!< Whether the assigned IP has changed or not */
} ip_event_got_ip_t;
/** Event structure for IP_EVENT_GOT_IP6 event */
typedef struct {
tcpip_adapter_if_t if_index; /*!< Interface for which the event is received */
tcpip_adapter_ip6_info_t ip6_info; /*!< IPv6 address of the interface */
} ip_event_got_ip6_t;
/** Event structure for IP_EVENT_AP_STAIPASSIGNED event */
typedef struct {
ip4_addr_t ip; /*!< IP address which was assigned to the station */
} ip_event_ap_staipassigned_t;
#include "esp_netif.h"
#include "tcpip_adapter_types.h"
/**
* @brief Initialize the underlying TCP/IP stack
*
* @note This function should be called exactly once from application code, when the application starts up.
* @brief tcpip adapter legacy init. It is used only to set the compatibility mode of esp-netif, which
* will enable backward compatibility of esp-netif.
*/
void tcpip_adapter_init(void);
void tcpip_adapter_init(void) __attribute__ ((deprecated));
/**
* @brief Cause the TCP/IP stack to start the Ethernet interface with specified MAC and IP
* @brief Compatiblity mode: convert the esp-netif handle to tcpip_adapter legacy interface enum
*
* @note This function should be called after the Ethernet MAC hardware is initialized. In the default configuration, application code does not need to call this function - it is called automatically by the default handler for the SYSTEM_EVENT_ETH_START event.
* @param esp_netif
*
* @param[in] mac Set MAC address of this interface
* @param[in] ip_info Set IP address of this interface
* @param[in] args extra args passed to tcpip_adapter
*
* @return
* - ESP_OK
* - ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS
* - ESP_ERR_NO_MEM
* @return corresponding interface if valid or known esp_netif provided, TCPIP_ADAPTER_IF_MAX otherwise
*/
esp_err_t tcpip_adapter_eth_start(uint8_t *mac, tcpip_adapter_ip_info_t *ip_info, void *args);
tcpip_adapter_if_t tcpip_adapter_if_from_esp_netif(esp_netif_t *esp_netif);
/**
* @brief Cause the TCP/IP stack to start the Wi-Fi station interface with specified MAC and IP
* @brief Translates to esp_netif_get_ip_info
*
*
* @note This function should be called after the Wi-Fi Station hardware is initialized. In the default configuration, application code does not need to call this function - it is called automatically by the default handler for the SYSTEM_EVENT_STA_START event.
*
* @param[in] mac Set MAC address of this interface
* @param[in] ip_info Set IP address of this interface
*
* @return
* - ESP_OK
* - ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS
* - ESP_ERR_NO_MEM
*/
esp_err_t tcpip_adapter_sta_start(uint8_t *mac, tcpip_adapter_ip_info_t *ip_info);
/**
* @brief Cause the TCP/IP stack to start the Wi-Fi AP interface with specified MAC and IP
*
* @note This function should be called after the Wi-Fi AP hardware is initialized. In the default configuration, application code does not need to call this function - it is called automatically by the default handler for the SYSTEM_EVENT_AP_START event.
*
* DHCP server will be started automatically when this function is called.
*
* @param[in] mac Set MAC address of this interface
* @param[in] ip_info Set IP address of this interface
*
* @return
* - ESP_OK
* - ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS
* - ESP_ERR_NO_MEM
*/
esp_err_t tcpip_adapter_ap_start(uint8_t *mac, tcpip_adapter_ip_info_t *ip_info);
/**
* @brief Cause the TCP/IP stack to stop a network interface
*
* Causes TCP/IP stack to clean up this interface. This includes stopping the DHCP server or client, if they are started.
*
* @note This API is called by the default Wi-Fi and Ethernet event handlers if the underlying network driver reports that the
* interface has stopped.
*
* @note To stop an interface from application code, call the network-specific API (esp_wifi_stop() or esp_eth_stop()).
* The driver layer will then send a stop event and the event handler should call this API.
* Otherwise, the driver and MAC layer will remain started.
*
* @param[in] tcpip_if Interface which will be stopped
*
* @return
* - ESP_OK
* - ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS
* - ESP_ERR_TCPIP_ADAPTER_IF_NOT_READY
*/
esp_err_t tcpip_adapter_stop(tcpip_adapter_if_t tcpip_if);
/**
* @brief Cause the TCP/IP stack to bring up an interface
*
* @note This function is called automatically by the default event handlers for the Wi-Fi Station and Ethernet interfaces,
* in response to the SYSTEM_EVENT_STA_CONNECTED and SYSTEM_EVENT_ETH_CONNECTED events, respectively.
*
* @note This function is not normally used with Wi-Fi AP interface. If the AP interface is started, it is up.
*
* @param[in] tcpip_if Interface to bring up
*
* @return
* - ESP_OK
* - ESP_ERR_TCPIP_ADAPTER_IF_NOT_READY
*/
esp_err_t tcpip_adapter_up(tcpip_adapter_if_t tcpip_if);
/**
* @brief Cause the TCP/IP stack to shutdown an interface
*
* @note This function is called automatically by the default event handlers for the Wi-Fi Station and Ethernet interfaces,
* in response to the SYSTEM_EVENT_STA_DISCONNECTED and SYSTEM_EVENT_ETH_DISCONNECTED events, respectively.
*
* @note This function is not normally used with Wi-Fi AP interface. If the AP interface is stopped, it is down.
*
* @param[in] tcpip_if Interface to shutdown
*
* @return
* - ESP_OK
* - ESP_ERR_TCPIP_ADAPTER_IF_NOT_READY
*/
esp_err_t tcpip_adapter_down(tcpip_adapter_if_t tcpip_if);
/**
* @brief Get interface's IP address information
*
* If the interface is up, IP information is read directly from the TCP/IP stack.
*
* If the interface is down, IP information is read from a copy kept in the TCP/IP adapter
* library itself.
*
* @param[in] tcpip_if Interface to get IP information
* @param[out] ip_info If successful, IP information will be returned in this argument.
*
* @return
* - ESP_OK
* - ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS
* @param tcpip_if Interface type corresponding to appropriate instance of esp-netif
* @param ip_info See esp_netif_get_ip_info
* @return See esp_netif_get_ip_info
*/
esp_err_t tcpip_adapter_get_ip_info(tcpip_adapter_if_t tcpip_if, tcpip_adapter_ip_info_t *ip_info);
/**
* @brief Set interface's IP address information
* @brief Translates to esp_netif_get_ip6_linklocal
*
* This function is mainly used to set a static IP on an interface.
*
* If the interface is up, the new IP information is set directly in the TCP/IP stack.
*
* The copy of IP information kept in the TCP/IP adapter library is also updated (this
* copy is returned if the IP is queried while the interface is still down.)
*
* @note DHCP client/server must be stopped before setting new IP information.
*
* @note Calling this interface for the Wi-Fi STA or Ethernet interfaces may generate a
* SYSTEM_EVENT_STA_GOT_IP or SYSTEM_EVENT_ETH_GOT_IP event.
*
* @param[in] tcpip_if Interface to set IP information
* @param[in] ip_info IP information to set on the specified interface
*
* @return
* - ESP_OK
* - ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS
* - ESP_ERR_TCPIP_ADAPTER_DHCP_NOT_STOPPED If DHCP server or client is still running
*/
esp_err_t tcpip_adapter_set_ip_info(tcpip_adapter_if_t tcpip_if, const tcpip_adapter_ip_info_t *ip_info);
/**
* @brief Set DNS Server information
*
* This function behaves differently for different interfaces:
*
* - For Wi-Fi Station interface and Ethernet interface, up to three types of DNS server can be set (in order of priority):
* - Main DNS Server (TCPIP_ADAPTER_DNS_MAIN)
* - Backup DNS Server (TCPIP_ADAPTER_DNS_BACKUP)
* - Fallback DNS Server (TCPIP_ADAPTER_DNS_FALLBACK)
*
* If DHCP client is enabled, main and backup DNS servers will be updated automatically from the DHCP lease if the relevant DHCP options are set. Fallback DNS Server is never updated from the DHCP lease and is designed to be set via this API.
*
* If DHCP client is disabled, all DNS server types can be set via this API only.
*
* - For Wi-Fi AP interface, the Main DNS Server setting is used by the DHCP server to provide a DNS Server option to DHCP clients (Wi-Fi stations).
* - The default Main DNS server is the IP of the Wi-Fi AP interface itself.
* - This function can override it by setting server type TCPIP_ADAPTER_DNS_MAIN.
* - Other DNS Server types are not supported for the Wi-Fi AP interface.
*
* @param[in] tcpip_if Interface to set DNS Server information
* @param[in] type Type of DNS Server to set: TCPIP_ADAPTER_DNS_MAIN, TCPIP_ADAPTER_DNS_BACKUP, TCPIP_ADAPTER_DNS_FALLBACK
* @param[in] dns DNS Server address to set
*
* @return
* - ESP_OK on success
* - ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS invalid params
*/
esp_err_t tcpip_adapter_set_dns_info(tcpip_adapter_if_t tcpip_if, tcpip_adapter_dns_type_t type, tcpip_adapter_dns_info_t *dns);
/**
* @brief Get DNS Server information
*
* Return the currently configured DNS Server address for the specified interface and Server type.
*
* This may be result of a previous call to tcpip_adapter_set_dns_info(). If the interface's DHCP client is enabled,
* the Main or Backup DNS Server may be set by the current DHCP lease.
*
* @param[in] tcpip_if Interface to get DNS Server information
* @param[in] type Type of DNS Server to get: TCPIP_ADAPTER_DNS_MAIN, TCPIP_ADAPTER_DNS_BACKUP, TCPIP_ADAPTER_DNS_FALLBACK
* @param[out] dns DNS Server result is written here on success
*
* @return
* - ESP_OK on success
* - ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS invalid params
*/
esp_err_t tcpip_adapter_get_dns_info(tcpip_adapter_if_t tcpip_if, tcpip_adapter_dns_type_t type, tcpip_adapter_dns_info_t *dns);
/**
* @brief Get interface's old IP information
*
* Returns an "old" IP address previously stored for the interface when the valid IP changed.
*
* If the IP lost timer has expired (meaning the interface was down for longer than the configured interval)
* then the old IP information will be zero.
*
* @param[in] tcpip_if Interface to get old IP information
* @param[out] ip_info If successful, IP information will be returned in this argument.
*
* @return
* - ESP_OK
* - ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS
*/
esp_err_t tcpip_adapter_get_old_ip_info(tcpip_adapter_if_t tcpip_if, tcpip_adapter_ip_info_t *ip_info);
/**
* @brief Set interface old IP information
*
* This function is called from the DHCP client for the Wi-Fi STA and Ethernet interfaces, before a new IP is set. It is also called from the default handlers for the SYSTEM_EVENT_STA_CONNECTED and SYSTEM_EVENT_ETH_CONNECTED events.
*
* Calling this function stores the previously configured IP, which can be used to determine if the IP changes in the future.
*
* If the interface is disconnected or down for too long, the "IP lost timer" will expire (after the configured interval) and set the old IP information to zero.
*
* @param[in] tcpip_if Interface to set old IP information
* @param[in] ip_info Store the old IP information for the specified interface
*
* @return
* - ESP_OK
* - ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS
*/
esp_err_t tcpip_adapter_set_old_ip_info(tcpip_adapter_if_t tcpip_if, const tcpip_adapter_ip_info_t *ip_info);
/**
* @brief Create interface link-local IPv6 address
*
* Cause the TCP/IP stack to create a link-local IPv6 address for the specified interface.
*
* This function also registers a callback for the specified interface, so that if the link-local address becomes verified as the preferred address then a SYSTEM_EVENT_GOT_IP6 event will be sent.
*
* @param[in] tcpip_if Interface to create a link-local IPv6 address
*
* @return
* - ESP_OK
* - ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS
*/
esp_err_t tcpip_adapter_create_ip6_linklocal(tcpip_adapter_if_t tcpip_if);
/**
* @brief Get interface link-local IPv6 address
*
* If the specified interface is up and a preferred link-local IPv6 address
* has been created for the interface, return a copy of it.
*
* @param[in] tcpip_if Interface to get link-local IPv6 address
* @param[out] if_ip6 IPv6 information will be returned in this argument if successful.
*
* @return
* - ESP_OK
* - ESP_FAIL If interface is down, does not have a link-local IPv6 address, or the link-local IPv6 address is not a preferred address.
* @param tcpip_if Interface type corresponding to appropriate instance of esp-netif
* @param if_ip6 See esp_netif_get_ip6_linklocal
* @return See esp_netif_get_ip6_linklocal
*/
esp_err_t tcpip_adapter_get_ip6_linklocal(tcpip_adapter_if_t tcpip_if, ip6_addr_t *if_ip6);
#if 0
esp_err_t tcpip_adapter_get_mac(tcpip_adapter_if_t tcpip_if, uint8_t *mac);
esp_err_t tcpip_adapter_set_mac(tcpip_adapter_if_t tcpip_if, uint8_t *mac);
#endif
/**
* @brief Get DHCP Server status
*
* @param[in] tcpip_if Interface to get status of DHCP server.
* @param[out] status If successful, the status of the DHCP server will be returned in this argument.
*
* @return
* - ESP_OK
*/
esp_err_t tcpip_adapter_dhcps_get_status(tcpip_adapter_if_t tcpip_if, tcpip_adapter_dhcp_status_t *status);
/**
* @brief Set or Get DHCP server option
*
* @param[in] opt_op TCPIP_ADAPTER_OP_SET to set an option, TCPIP_ADAPTER_OP_GET to get an option.
* @param[in] opt_id Option index to get or set, must be one of the supported enum values.
* @param[inout] opt_val Pointer to the option parameter.
* @param[in] opt_len Length of the option parameter.
*
* @return
* - ESP_OK
* - ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS
* - ESP_ERR_TCPIP_ADAPTER_DHCP_ALREADY_STOPPED
* - ESP_ERR_TCPIP_ADAPTER_DHCP_ALREADY_STARTED
*/
esp_err_t tcpip_adapter_dhcps_option(tcpip_adapter_dhcp_option_mode_t opt_op, tcpip_adapter_dhcp_option_id_t opt_id, void *opt_val, uint32_t opt_len);
/**
* @brief Start DHCP server
*
* @note Currently DHCP server is only supported on the Wi-Fi AP interface.
*
* @param[in] tcpip_if Interface to start DHCP server. Must be TCPIP_ADAPTER_IF_AP.
*
* @return
* - ESP_OK
* - ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS
* - ESP_ERR_TCPIP_ADAPTER_DHCP_ALREADY_STARTED
*/
esp_err_t tcpip_adapter_dhcps_start(tcpip_adapter_if_t tcpip_if);
/**
* @brief Stop DHCP server
*
* @note Currently DHCP server is only supported on the Wi-Fi AP interface.
*
* @param[in] tcpip_if Interface to stop DHCP server. Must be TCPIP_ADAPTER_IF_AP.
*
* @return
* - ESP_OK
* - ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS
* - ESP_ERR_TCPIP_ADAPTER_DHCP_ALREADY_STOPPED
* - ESP_ERR_TCPIP_ADAPTER_IF_NOT_READY
*/
esp_err_t tcpip_adapter_dhcps_stop(tcpip_adapter_if_t tcpip_if);
/**
* @brief Get DHCP client status
*
* @param[in] tcpip_if Interface to get status of DHCP client
* @param[out] status If successful, the status of DHCP client will be returned in this argument.
*
* @return
* - ESP_OK
* @brief`Translates to esp_netif_dhcpc_get_status
* @param tcpip_if Interface type corresponding to appropriate instance of esp-netif
* @param status
* @return See esp_netif_dhcpc_get_status
*/
esp_err_t tcpip_adapter_dhcpc_get_status(tcpip_adapter_if_t tcpip_if, tcpip_adapter_dhcp_status_t *status);
/**
* @brief Set or Get DHCP client's option
*
* @note This function is not yet implemented
*
* @param[in] opt_op TCPIP_ADAPTER_OP_SET to set an option, TCPIP_ADAPTER_OP_GET to get an option.
* @param[in] opt_id Option index to get or set, must be one of the supported enum values.
* @param[inout] opt_val Pointer to the option parameter.
* @param[in] opt_len Length of the option parameter.
*
* @return
* - ESP_ERR_NOT_SUPPORTED (not implemented)
*/
esp_err_t tcpip_adapter_dhcpc_option(tcpip_adapter_dhcp_option_mode_t opt_op, tcpip_adapter_dhcp_option_id_t opt_id, void *opt_val, uint32_t opt_len);
/**
* @brief Start DHCP client
*
* @note DHCP Client is only supported for the Wi-Fi station and Ethernet interfaces.
*
* @note The default event handlers for the SYSTEM_EVENT_STA_CONNECTED and SYSTEM_EVENT_ETH_CONNECTED events call this function.
*
* @param[in] tcpip_if Interface to start the DHCP client
*
* @return
* - ESP_OK
* - ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS
* - ESP_ERR_TCPIP_ADAPTER_DHCP_ALREADY_STARTED
* - ESP_ERR_TCPIP_ADAPTER_DHCPC_START_FAILED
*/
esp_err_t tcpip_adapter_dhcpc_start(tcpip_adapter_if_t tcpip_if);
/**
* @brief Stop DHCP client
*
* @note DHCP Client is only supported for the Wi-Fi station and Ethernet interfaces.
*
* @note Calling tcpip_adapter_stop() or tcpip_adapter_down() will also stop the DHCP Client if it is running.
*
* @param[in] tcpip_if Interface to stop the DHCP client
*
* @return
* - ESP_OK
* - ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS
* - ESP_ERR_TCPIP_ADAPTER_DHCP_ALREADY_STOPPED
* - ESP_ERR_TCPIP_ADAPTER_IF_NOT_READY
*/
esp_err_t tcpip_adapter_dhcpc_stop(tcpip_adapter_if_t tcpip_if);
/**
* @brief Receive an Ethernet frame from the Ethernet interface
*
* This function will automatically be installed by esp_eth_init(). The Ethernet driver layer will then call this function to forward frames to the TCP/IP stack.
*
* @note Application code does not usually need to use this function directly.
*
* @param[in] buffer Received data
* @param[in] len Length of the data frame
* @param[in] eb Pointer to internal Wi-Fi buffer (ignored for Ethernet)
*
* @return
* - ESP_OK
*/
esp_err_t tcpip_adapter_eth_input(void *buffer, uint16_t len, void *eb);
/**
* @brief Receive an 802.11 data frame from the Wi-Fi Station interface
*
* This function should be installed by calling esp_wifi_reg_rxcb(). The Wi-Fi driver layer will then call this function to forward frames to the TCP/IP stack.
*
* @note Installation happens automatically in the default handler for the SYSTEM_EVENT_STA_CONNECTED event.
*
* @note Application code does not usually need to call this function directly.
*
* @param[in] buffer Received data
* @param[in] len Length of the data frame
* @param[in] eb Pointer to internal Wi-Fi buffer
*
* @return
* - ESP_OK
*/
esp_err_t tcpip_adapter_sta_input(void *buffer, uint16_t len, void *eb);
/**
* @brief Receive an 802.11 data frame from the Wi-Fi AP interface
*
* This function should be installed by calling esp_wifi_reg_rxcb(). The Wi-Fi driver layer will then call this function to forward frames to the TCP/IP stack.
*
* @note Installation happens automatically in the default handler for the SYSTEM_EVENT_AP_START event.
*
* @note Application code does not usually need to call this function directly.
*
* @param[in] buffer Received data
* @param[in] len Length of the data frame
* @param[in] eb Pointer to internal Wi-Fi buffer
*
* @return
* - ESP_OK
*/
esp_err_t tcpip_adapter_ap_input(void *buffer, uint16_t len, void *eb);
/**
* @brief Get network interface index
*
* Get network interface from TCP/IP implementation-specific interface pointer.
*
* @param[in] dev Implementation-specific TCP/IP stack interface pointer.
*
* @return
* - ESP_IF_WIFI_STA
* - ESP_IF_WIFI_AP
* - ESP_IF_ETH
* - ESP_IF_MAX - invalid parameter
*/
esp_interface_t tcpip_adapter_get_esp_if(void *dev);
/**
* @brief Get IP information for stations connected to the Wi-Fi AP interface
*
* @param[in] wifi_sta_list Wi-Fi station info list, returned from esp_wifi_ap_get_sta_list()
* @param[out] tcpip_sta_list IP layer station info list, corresponding to MAC addresses provided in wifi_sta_list
*
* @return
* - ESP_OK
* - ESP_ERR_TCPIP_ADAPTER_NO_MEM
* - ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS
*/
esp_err_t tcpip_adapter_get_sta_list(const wifi_sta_list_t *wifi_sta_list, tcpip_adapter_sta_list_t *tcpip_sta_list);
#define TCPIP_HOSTNAME_MAX_SIZE 32
/**
* @brief Set the hostname of an interface
*
* @param[in] tcpip_if Interface to set the hostname
* @param[in] hostname New hostname for the interface. Maximum length 32 bytes.
*
* @return
* - ESP_OK - success
* - ESP_ERR_TCPIP_ADAPTER_IF_NOT_READY - interface status error
* - ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS - parameter error
*/
esp_err_t tcpip_adapter_set_hostname(tcpip_adapter_if_t tcpip_if, const char *hostname);
/**
* @brief Get interface hostname.
*
* @param[in] tcpip_if Interface to get the hostname
* @param[out] hostname Returns a pointer to the hostname. May be NULL if no hostname is set. If set non-NULL, pointer remains valid (and string may change if the hostname changes).
*
* @return
* - ESP_OK - success
* - ESP_ERR_TCPIP_ADAPTER_IF_NOT_READY - interface status error
* - ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS - parameter error
*/
esp_err_t tcpip_adapter_get_hostname(tcpip_adapter_if_t tcpip_if, const char **hostname);
/**
* @brief Get the TCP/IP stack-specific interface that is assigned to a given interface
*
* @note For lwIP, this returns a pointer to a netif structure.
*
* @param[in] tcpip_if Interface to get the implementation-specific interface
* @param[out] netif Pointer to the implementation-specific interface
*
* @return
* - ESP_OK - success
* - ESP_ERR_TCPIP_ADAPTER_IF_NOT_READY - interface status error
* - ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS - parameter error
*/
esp_err_t tcpip_adapter_get_netif(tcpip_adapter_if_t tcpip_if, void ** netif);
/**
* @brief Test if supplied interface is up or down
*
* @param[in] tcpip_if Interface to test up/down status
*
* @return
* - true - Interface is up
* - false - Interface is down
* @brief Translates to esp_netif_is_netif_up
* @param tcpip_if Interface type corresponding to appropriate instance of esp-netif
* @return see esp_netif_is_netif_up
*/
bool tcpip_adapter_is_netif_up(tcpip_adapter_if_t tcpip_if);
/**
* @brief Cause the TCP/IP stack to start the test interface with specified MAC and IP.
* Test interface is used to exercise network stack with injected packets from SW.
*
* @param[in] mac Set MAC address of this interface
* @param[in] ip_info Set IP address of this interface
*
* @return
* - ESP_OK
* - ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS
* - ESP_ERR_NO_MEM
* @brief Translates to esp_netif_get_netif
* @param tcpip_if Interface type corresponding to appropriate instance of esp-netif
* @param netif
* @return see esp_netif_get_netif
*/
esp_err_t tcpip_adapter_test_start(uint8_t *mac, tcpip_adapter_ip_info_t *ip_info);
esp_err_t tcpip_adapter_get_netif(tcpip_adapter_if_t tcpip_if, void ** netif);
/**
* @brief Install default event handlers for Ethernet interface
* @return
* - ESP_OK on success
* - one of the errors from esp_event on failure
* @brief Translates to esp_netif_create_ip6_linklocal
* @param tcpip_if Interface type corresponding to appropriate instance of esp-netif
* @return see esp_netif_create_ip6_linklocal
*/
esp_err_t tcpip_adapter_create_ip6_linklocal(tcpip_adapter_if_t tcpip_if);
/**
* @brief Compatible version of setting ethernet default handlers
* @note Compatible version of wifi handlers are provided in a separate header,
* as this used to be called privately from wifi_init()
* @return ESP_OK on success
*/
esp_err_t tcpip_adapter_set_default_eth_handlers(void);
/**
* @brief Uninstall default event handlers for Ethernet interface
* @return
* - ESP_OK on success
* - one of the errors from esp_event on failure
* @brief Compatible version of network stack input function. Translates to esp_netif_receive()
*/
esp_err_t tcpip_adapter_clear_default_eth_handlers(void);
esp_err_t tcpip_adapter_eth_input(void *buffer, uint16_t len, void *eb);
/**
* @brief Install default event handlers for Wi-Fi interfaces (station and AP)
* @return
* - ESP_OK on success
* - one of the errors from esp_event on failure
* @brief Compatible version of network stack input function. Translates to esp_netif_receive()
*/
esp_err_t tcpip_adapter_set_default_wifi_handlers(void);
esp_err_t tcpip_adapter_sta_input(void *buffer, uint16_t len, void *eb);
/**
* @brief Uninstall default event handlers for Wi-Fi interfaces (station and AP)
* @return
* - ESP_OK on success
* - one of the errors from esp_event on failure
* @brief Compatible version of network stack input function. Translates to esp_netif_receive()
*/
esp_err_t tcpip_adapter_ap_input(void *buffer, uint16_t len, void *eb);
/**
* @brief Compatible version of former tcpip_adapter API to clear default WIFI handlers
* @return ESP_OK on success
*/
esp_err_t tcpip_adapter_clear_default_wifi_handlers(void);
/**
* @brief Search nefit index through netif interface
* @param[in] tcpip_if Interface to search for netif index
* @return
* - netif_index on success
* - -1 if an invalid parameter is supplied
* @brief Compatible version of former tcpip_adapter API to clear default ethernet handlers
* @return ESP_OK on success
*/
esp_err_t tcpip_adapter_clear_default_eth_handlers(void);
/**
* @brief Compatible version of former tcpip_adapter API of esp_netif_dhcps_stop
*/
esp_err_t tcpip_adapter_dhcps_stop(tcpip_adapter_if_t tcpip_if);
/**
* @brief Compatible version of former tcpip_adapter API of esp_netif_dhcpc_stop
*/
esp_err_t tcpip_adapter_dhcpc_stop(tcpip_adapter_if_t tcpip_if);
/**
* @brief Compatible version of former tcpip_adapter API of esp_netif_dhcps_start
*/
esp_err_t tcpip_adapter_dhcps_start(tcpip_adapter_if_t tcpip_if);
/**
* @brief Compatible version of former tcpip_adapter API of esp_netif_dhcpc_start
*/
esp_err_t tcpip_adapter_dhcpc_start(tcpip_adapter_if_t tcpip_if);
/**
* @brief Compatible version of former tcpip_adapter API of esp_netif_dhcps_get_status
*/
esp_err_t tcpip_adapter_dhcps_get_status(tcpip_adapter_if_t tcpip_if, tcpip_adapter_dhcp_status_t *status);
/**
* @brief Compatible version of former tcpip_adapter API of esp_netif_dhcps_option
*/
esp_err_t tcpip_adapter_dhcps_option(tcpip_adapter_dhcp_option_mode_t opt_op, tcpip_adapter_dhcp_option_id_t opt_id, void *opt_val, uint32_t opt_len);
/**
* @brief Compatible version of former tcpip_adapter API of esp_netif_dhcpc_option
*/
esp_err_t tcpip_adapter_dhcpc_option(tcpip_adapter_dhcp_option_mode_t opt_op, tcpip_adapter_dhcp_option_id_t opt_id, void *opt_val, uint32_t opt_len);
/**
* @brief Compatible version of former tcpip_adapter API of esp_netif_set_ip_info
*/
esp_err_t tcpip_adapter_set_ip_info(tcpip_adapter_if_t tcpip_if, const tcpip_adapter_ip_info_t *ip_info);
/**
* @brief Compatible version of former tcpip_adapter API of esp_netif_get_dns_info
*/
esp_err_t tcpip_adapter_get_dns_info(tcpip_adapter_if_t tcpip_if, tcpip_adapter_dns_type_t type, tcpip_adapter_dns_info_t *dns);
/**
* @brief Compatible version of former tcpip_adapter API of esp_netif_set_dns_info
*/
esp_err_t tcpip_adapter_set_dns_info(tcpip_adapter_if_t tcpip_if, tcpip_adapter_dns_type_t type, tcpip_adapter_dns_info_t *dns);
/**
* @brief Compatible version of former tcpip_adapter API of esp_netif_get_netif_impl_index
*/
int tcpip_adapter_get_netif_index(tcpip_adapter_if_t tcpip_if);
#ifdef __cplusplus
}
#endif
/**
* @brief Compatible version of former tcpip_adapter API of esp_netif_get_sta_list
*/
esp_err_t tcpip_adapter_get_sta_list(const wifi_sta_list_t *wifi_sta_list, tcpip_adapter_sta_list_t *tcpip_sta_list);
#endif /* _TCPIP_ADAPTER_H_ */
/**
* @brief Compatible version of former tcpip_adapter API of esp_netif_action_start for default ethernet
*/
esp_err_t tcpip_adapter_eth_start(uint8_t *mac, tcpip_adapter_ip_info_t *ip_info, void *args);
/**
* @brief Compatible version of former tcpip_adapter API of esp_netif_action_start for default station
*/
esp_err_t tcpip_adapter_sta_start(uint8_t *mac, tcpip_adapter_ip_info_t *ip_info);
/**
* @brief Compatible version of former tcpip_adapter API of esp_netif_action_start for default softAP
*/
esp_err_t tcpip_adapter_ap_start(uint8_t *mac, tcpip_adapter_ip_info_t *ip_info);
/**
* @brief Compatible version of former tcpip_adapter API of esp_netif_action_stop
*/
esp_err_t tcpip_adapter_stop(tcpip_adapter_if_t tcpip_if);
/**
* @brief Compatible version of former tcpip_adapter API of esp_netif_up
*/
esp_err_t tcpip_adapter_up(tcpip_adapter_if_t tcpip_if);
/**
* @brief Compatible version of former tcpip_adapter API of esp_netif_down
*/
esp_err_t tcpip_adapter_down(tcpip_adapter_if_t tcpip_if);
/**
* @brief Compatible version of former tcpip_adapter API of esp_netif_get_old_ip_info
*/
esp_err_t tcpip_adapter_get_old_ip_info(tcpip_adapter_if_t tcpip_if, tcpip_adapter_ip_info_t *ip_info);
/**
* @brief Compatible version of former tcpip_adapter API of esp_netif_set_old_ip_info
*/
esp_err_t tcpip_adapter_set_old_ip_info(tcpip_adapter_if_t tcpip_if, const tcpip_adapter_ip_info_t *ip_info);
/**
* @brief Compatible version of former tcpip_adapter API of esp_netif_get_handle_from_netif_impl
*/
esp_interface_t tcpip_adapter_get_esp_if(void *dev);
/**
* @brief Compatible version of former tcpip_adapter API of esp_netif_set_hostname
*/
esp_err_t tcpip_adapter_set_hostname(tcpip_adapter_if_t tcpip_if, const char *hostname);
/**
* @brief Compatible version of former tcpip_adapter API of esp_netif_get_hostname
*/
esp_err_t tcpip_adapter_get_hostname(tcpip_adapter_if_t tcpip_if, const char **hostname);
/**
* @brief This function is called from wifi_init to assure backward compatibility mode
* of tcpip_adapter. In case of legacy use, default instances of ap and sta
* are created and handlers are registered
*
* @return ESP_OK on success
*/
esp_err_t tcpip_adapter_set_default_wifi_handlers(void);
#endif //_TCPIP_ADAPTER_H_

View file

@ -0,0 +1,57 @@
// Copyright 2015-2019 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef _TCPIP_ADAPTER_COMPAT_H_
#define _TCPIP_ADAPTER_COMPAT_H_
/**
* @brief This function is called from ethernet driver init code to facilitate
* autostart fo the driver in backward compatible tcpip_adapter way
*
* @note This api is provided in a separate header, which is included internally only (from wifi driver)
* rather then user initialization code.
*
* @param[in] h Handle to the ethernet driver
*
* @return ESP_OK on success
*/
esp_err_t tcpip_adapter_compat_start_eth(void* h);
/**
* @brief This function is called from wifi_init to assure backward compatibility mode
* of tcpip_adapter. In case of legacy use, default instances of ap and sta
* are created and handlers are registered
*
* @note This API is provided in a separate header, which is included internally only (from wifi_init)
* rather then user initialization code. At this same time this API is also a public API of former tcqpip_adapter
* and thus provided also in tcpip_adapter.h
*
* @return ESP_OK on success
*/
esp_err_t tcpip_adapter_set_default_wifi_handlers(void);
/**
* @brief This function is called from wifi_init to assure backward compatibility mode
* of tcpip_adapter. In case of legacy use, default instances of ap and sta
* are destroyed and handlers are unregistered
*
* @note This API is provided in a separate header, which is included internally only (from wifi_init)
* rather then user initialization code. At this same time this API is also a public API of former tcqpip_adapter
* and thus provided also in tcpip_adapter.h
*
* @return ESP_OK on success
*/
esp_err_t tcpip_adapter_clear_default_wifi_handlers(void);
#endif //_TCPIP_ADAPTER_COMPAT_H_

View file

@ -1,66 +0,0 @@
// Copyright 2015-2018 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include "tcpip_adapter.h"
#include "sys/queue.h"
struct tcpip_adapter_api_msg_s;
typedef int (*tcpip_adapter_api_fn)(struct tcpip_adapter_api_msg_s *msg);
typedef struct tcpip_adapter_api_msg_s {
int type; /**< The first field MUST be int */
int ret;
tcpip_adapter_api_fn api_fn;
tcpip_adapter_if_t tcpip_if;
tcpip_adapter_ip_info_t *ip_info;
uint8_t *mac;
void *data;
} tcpip_adapter_api_msg_t;
typedef struct tcpip_adapter_dns_param_s {
tcpip_adapter_dns_type_t dns_type;
tcpip_adapter_dns_info_t *dns_info;
} tcpip_adapter_dns_param_t;
typedef struct tcpip_adapter_ip_lost_timer_s {
bool timer_running;
} tcpip_adapter_ip_lost_timer_t;
#define TCPIP_ADAPTER_TRHEAD_SAFE 1
#define TCPIP_ADAPTER_IPC_LOCAL 0
#define TCPIP_ADAPTER_IPC_REMOTE 1
#define TCPIP_ADAPTER_IPC_CALL(_if, _mac, _ip, _data, _fn) do {\
tcpip_adapter_api_msg_t msg;\
if (tcpip_inited == false) {\
ESP_LOGE(TAG, "tcpip_adapter is not initialized!");\
abort();\
}\
memset(&msg, 0, sizeof(msg));\
msg.tcpip_if = (_if);\
msg.mac = (uint8_t*)(_mac);\
msg.ip_info = (tcpip_adapter_ip_info_t*)(_ip);\
msg.data = (void*)(_data);\
msg.api_fn = (_fn);\
if (TCPIP_ADAPTER_IPC_REMOTE == tcpip_adapter_ipc_check(&msg)) {\
ESP_LOGV(TAG, "check: remote, if=%d fn=%p\n", (_if), (_fn));\
return msg.ret;\
} else {\
ESP_LOGV(TAG, "check: local, if=%d fn=%p\n", (_if), (_fn));\
}\
} while(0)

View file

@ -0,0 +1,73 @@
// Copyright 2015-2019 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef _TCPIP_ADAPTER_TYPES_H_
#define _TCPIP_ADAPTER_TYPES_H_
#include "lwip/ip_addr.h"
#include "dhcpserver/dhcpserver.h"
#include "esp_netif_sta_list.h"
//
// Define compatible types if tcpip_adapter interface used
//
#define TCPIP_ADAPTER_DHCP_STARTED ESP_NETIF_DHCP_STARTED
#define TCPIP_ADAPTER_DHCP_STOPPED ESP_NETIF_DHCP_STOPPED
#define TCPIP_ADAPTER_DHCP_INIT ESP_NETIF_DHCP_INIT
#define TCPIP_ADAPTER_OP_SET ESP_NETIF_OP_SET
#define TCPIP_ADAPTER_OP_GET ESP_NETIF_OP_GET
#define TCPIP_ADAPTER_DOMAIN_NAME_SERVER ESP_NETIF_DOMAIN_NAME_SERVER
#define TCPIP_ADAPTER_ROUTER_SOLICITATION_ADDRESS ESP_NETIF_ROUTER_SOLICITATION_ADDRESS
#define TCPIP_ADAPTER_REQUESTED_IP_ADDRESS ESP_NETIF_REQUESTED_IP_ADDRESS
#define TCPIP_ADAPTER_IP_ADDRESS_LEASE_TIME ESP_NETIF_IP_ADDRESS_LEASE_TIME
#define TCPIP_ADAPTER_IP_REQUEST_RETRY_TIME ESP_NETIF_IP_REQUEST_RETRY_TIME
/** @brief Legacy error code definitions
*
*/
#define ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS ESP_ERR_ESP_NETIF_INVALID_PARAMS
#define ESP_ERR_TCPIP_ADAPTER_IF_NOT_READY ESP_ERR_ESP_NETIF_IF_NOT_READY
#define ESP_ERR_TCPIP_ADAPTER_DHCPC_START_FAILED ESP_ERR_ESP_NETIF_DHCPC_START_FAILED
#define ESP_ERR_TCPIP_ADAPTER_DHCP_ALREADY_STARTED ESP_ERR_ESP_NETIF_DHCP_ALREADY_STARTED
#define ESP_ERR_TCPIP_ADAPTER_DHCP_ALREADY_STOPPED ESP_ERR_ESP_NETIF_DHCP_ALREADY_STOPPED
#define ESP_ERR_TCPIP_ADAPTER_NO_MEM ESP_ERR_ESP_NETIF_NO_MEM
#define ESP_ERR_TCPIP_ADAPTER_DHCP_NOT_STOPPED ESP_ERR_ESP_NETIF_DHCP_NOT_STOPPED
typedef enum {
TCPIP_ADAPTER_IF_STA = 0, /**< Wi-Fi STA (station) interface */
TCPIP_ADAPTER_IF_AP, /**< Wi-Fi soft-AP interface */
TCPIP_ADAPTER_IF_ETH, /**< Ethernet interface */
TCPIP_ADAPTER_IF_TEST, /**< tcpip stack test interface */
TCPIP_ADAPTER_IF_MAX
} tcpip_adapter_if_t;
/** @brief legacy ip_info type
*/
typedef struct {
ip4_addr_t ip; /**< Interface IPV4 address */
ip4_addr_t netmask; /**< Interface IPV4 netmask */
ip4_addr_t gw; /**< Interface IPV4 gateway address */
} tcpip_adapter_ip_info_t;
/** @brief legacy typedefs
*/
typedef esp_netif_dhcp_status_t tcpip_adapter_dhcp_status_t;
typedef dhcps_lease_t tcpip_adapter_dhcps_lease_t;
typedef esp_netif_dhcp_option_mode_t tcpip_adapter_dhcp_option_mode_t;
typedef esp_netif_dhcp_option_id_t tcpip_adapter_dhcp_option_id_t;
typedef esp_netif_dns_type_t tcpip_adapter_dns_type_t;
typedef esp_netif_dns_info_t tcpip_adapter_dns_info_t;
typedef esp_netif_sta_list_t tcpip_adapter_sta_list_t;
typedef esp_netif_sta_info_t tcpip_adapter_sta_info_t;
#endif // _TCPIP_ADAPTER_TYPES_H_

View file

@ -1,5 +0,0 @@
# sdkconfig replacement configurations for deprecated options formatted as
# CONFIG_DEPRECATED_OPTION CONFIG_NEW_OPTION
CONFIG_IP_LOST_TIMER_INTERVAL CONFIG_NETIF_IP_LOST_TIMER_INTERVAL
CONFIG_USE_TCPIP_STACK_LIB CONFIG_NETIF_USE_TCPIP_STACK_LIB

View file

@ -0,0 +1,385 @@
// Copyright 2015-2019 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "esp_netif.h"
#include "esp_private/wifi.h"
#include "esp_log.h"
#include "esp_netif_net_stack.h"
#if CONFIG_ESP_NETIF_TCPIP_ADAPTER_COMPATIBLE_LAYER
#if CONFIG_ETH_ENABLED
#include "esp_eth.h"
#endif
#include "tcpip_adapter_types.h"
#include "esp_wifi_default.h"
//
// Accessing some internal default interfaces and esp-netifs
//
extern void _esp_wifi_set_default_ap_netif(esp_netif_t* esp_netif);
extern void _esp_wifi_set_default_sta_netif(esp_netif_t* esp_netif);
extern esp_err_t _esp_wifi_set_default_wifi_handlers(void);
extern esp_err_t _esp_wifi_clear_default_wifi_handlers(void);
extern esp_err_t esp_netif_up(esp_netif_t *esp_netif);
extern esp_err_t esp_netif_down(esp_netif_t *esp_netif);
//
// Purpose of this module is to provide backward compatible version of esp-netif
// with legacy tcpip_adapter interface
//
static const char* TAG = "tcpip_adapter_compat";
static esp_netif_t *s_esp_netifs[TCPIP_ADAPTER_IF_MAX] = { NULL };
static const char* s_netif_keyif[TCPIP_ADAPTER_IF_MAX] = {
"WIFI_STA_DEF",
"WIFI_AP_DEF",
"ETH_DEF",
};
static bool s_tcpip_adapter_compat = false;
static void wifi_create_and_start_ap(void *esp_netif, esp_event_base_t base, int32_t event_id, void *data)
{
if (s_esp_netifs[TCPIP_ADAPTER_IF_AP] == NULL) {
esp_netif_config_t cfg = ESP_NETIF_DEFAULT_WIFI_AP();
esp_netif_t *ap_netif = esp_netif_new(&cfg);
esp_netif_attach_wifi_ap(ap_netif);
esp_wifi_set_default_wifi_sta_handlers();
s_esp_netifs[TCPIP_ADAPTER_IF_AP] = ap_netif;
}
}
static void wifi_create_and_start_sta(void *esp_netif, esp_event_base_t base, int32_t event_id, void *data)
{
if (s_esp_netifs[TCPIP_ADAPTER_IF_STA] == NULL) {
esp_netif_config_t cfg = ESP_NETIF_DEFAULT_WIFI_STA();
esp_netif_t *sta_netif = esp_netif_new(&cfg);
esp_netif_attach_wifi_station(sta_netif);
esp_wifi_set_default_wifi_sta_handlers();
s_esp_netifs[TCPIP_ADAPTER_IF_STA] = sta_netif;
}
}
static inline esp_netif_t * netif_from_if(tcpip_adapter_if_t interface)
{
if (interface < TCPIP_ADAPTER_IF_MAX) {
if (s_esp_netifs[interface] == NULL) {
s_esp_netifs[interface] = esp_netif_get_handle_from_ifkey(s_netif_keyif[interface]);
if (s_esp_netifs[interface] == NULL && s_tcpip_adapter_compat) {
// if not found in compat mode -> create it
if (interface == TCPIP_ADAPTER_IF_STA) {
wifi_create_and_start_sta(NULL, 0, 0, NULL);
s_esp_netifs[interface] = esp_netif_get_handle_from_ifkey("WIFI_STA_DEF");
} else if (interface == TCPIP_ADAPTER_IF_AP) {
wifi_create_and_start_ap(NULL, 0, 0, NULL);
s_esp_netifs[interface] = esp_netif_get_handle_from_ifkey("WIFI_AP_DEF");
}
}
}
return s_esp_netifs[interface];
}
return NULL;
}
void tcpip_adapter_init(void)
{
s_tcpip_adapter_compat = true;
esp_err_t err;
if (ESP_OK != (err = esp_netif_init())) {
ESP_LOGE(TAG, "ESP-NETIF initialization failed with %d in tcpip_adapter compatibility mode", err);
}
}
#if CONFIG_ETH_ENABLED
static void tcpip_adapter_attach_eth_to_netif(void *esp_netif, esp_event_base_t base, int32_t event_id, void *data)
{
esp_eth_handle_t eth_handle = *(esp_eth_handle_t*)data;
esp_netif_attach(esp_netif, eth_handle);
}
esp_err_t tcpip_adapter_clear_default_eth_handlers(void)
{
ESP_ERROR_CHECK(esp_event_handler_unregister(ETH_EVENT, ETHERNET_EVENT_START, tcpip_adapter_attach_eth_to_netif));
return esp_eth_clear_default_handlers(netif_from_if(TCPIP_ADAPTER_IF_ETH));
}
esp_err_t tcpip_adapter_set_default_eth_handlers(void)
{
if (s_tcpip_adapter_compat) {
esp_netif_config_t cfg = ESP_NETIF_DEFAULT_ETH();
esp_netif_t *eth_netif = esp_netif_new(&cfg);
s_esp_netifs[TCPIP_ADAPTER_IF_ETH] = eth_netif;
// provide a separate "after driver start" hook to attach
esp_err_t ret = esp_event_handler_register(ETH_EVENT, ETHERNET_EVENT_START, tcpip_adapter_attach_eth_to_netif, eth_netif);
if (ret != ESP_OK) {
ESP_LOGE(TAG, "Failed to register ");
return ret;
}
return esp_eth_set_default_handlers(eth_netif);
}
return ESP_OK;
}
#endif
esp_err_t tcpip_adapter_eth_input(void *buffer, uint16_t len, void *eb)
{
return esp_netif_receive(netif_from_if(TCPIP_ADAPTER_IF_ETH), buffer, len, eb);
}
esp_err_t tcpip_adapter_sta_input(void *buffer, uint16_t len, void *eb)
{
return esp_netif_receive(netif_from_if(TCPIP_ADAPTER_IF_STA), buffer, len, eb);
}
esp_err_t tcpip_adapter_ap_input(void *buffer, uint16_t len, void *eb)
{
return esp_netif_receive(netif_from_if(TCPIP_ADAPTER_IF_AP), buffer, len, eb);
}
esp_err_t tcpip_adapter_compat_start_eth(void* eth_driver)
{
if (s_tcpip_adapter_compat) {
esp_netif_t *esp_netif = netif_from_if(TCPIP_ADAPTER_IF_ETH);
esp_netif_attach(esp_netif, eth_driver);
}
return ESP_OK;
}
esp_err_t tcpip_adapter_set_default_wifi_handlers(void)
{
#if CONFIG_ESP_NETIF_TCPIP_ADAPTER_COMPATIBLE_LAYER
if (s_tcpip_adapter_compat) {
// create instances and register default handlers only on start event
esp_err_t err = esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_STA_START, wifi_create_and_start_sta, NULL);
if (err != ESP_OK) {
return err;
}
err = esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_AP_START, wifi_create_and_start_ap, NULL);
if (err != ESP_OK) {
return err;
}
_esp_wifi_set_default_wifi_handlers();
}
return ESP_OK;
#else
ESP_LOGE(TAG, "%s: tcpip adapter compatibility layer is disabled", __func__);
return ESP_ERR_INVALID_STATE;
#endif
}
esp_err_t tcpip_adapter_clear_default_wifi_handlers(void)
{
return _esp_wifi_clear_default_wifi_handlers();
}
tcpip_adapter_if_t tcpip_adapter_if_from_esp_netif(esp_netif_t *esp_netif)
{
for (int i=0; i<TCPIP_ADAPTER_IF_MAX; ++i) {
if (esp_netif == s_esp_netifs[i])
return i;
}
return TCPIP_ADAPTER_IF_MAX;
}
esp_err_t tcpip_adapter_get_ip_info(tcpip_adapter_if_t tcpip_if, tcpip_adapter_ip_info_t *ip_info)
{
return esp_netif_get_ip_info(netif_from_if(tcpip_if), (esp_netif_ip_info_t *)ip_info);
}
esp_err_t tcpip_adapter_get_ip6_linklocal(tcpip_adapter_if_t tcpip_if, ip6_addr_t *if_ip6)
{
return esp_netif_get_ip6_linklocal(netif_from_if(tcpip_if), (esp_ip6_addr_t*)if_ip6);
}
esp_err_t tcpip_adapter_dhcpc_get_status(tcpip_adapter_if_t tcpip_if, tcpip_adapter_dhcp_status_t *status)
{
return esp_netif_dhcpc_get_status(netif_from_if(tcpip_if), status);
}
bool tcpip_adapter_is_netif_up(tcpip_adapter_if_t tcpip_if)
{
return esp_netif_is_netif_up(netif_from_if(tcpip_if));
}
esp_err_t tcpip_adapter_get_netif(tcpip_adapter_if_t tcpip_if, void ** netif)
{
esp_netif_t *esp_netif = netif_from_if(tcpip_if);
if (esp_netif) {
void* net_stack_netif = esp_netif_get_netif_impl(esp_netif);
*netif = net_stack_netif;
return ESP_OK;
}
return ESP_ERR_INVALID_ARG;
}
esp_err_t tcpip_adapter_create_ip6_linklocal(tcpip_adapter_if_t tcpip_if)
{
return esp_netif_create_ip6_linklocal(netif_from_if(tcpip_if));
}
esp_err_t tcpip_adapter_dhcps_stop(tcpip_adapter_if_t tcpip_if)
{
return esp_netif_dhcps_stop(netif_from_if(tcpip_if));
}
esp_err_t tcpip_adapter_dhcpc_stop(tcpip_adapter_if_t tcpip_if)
{
return esp_netif_dhcpc_stop(netif_from_if(tcpip_if));
}
esp_err_t tcpip_adapter_dhcps_start(tcpip_adapter_if_t tcpip_if)
{
return esp_netif_dhcps_start(netif_from_if(tcpip_if));
}
esp_err_t tcpip_adapter_dhcpc_start(tcpip_adapter_if_t tcpip_if)
{
return esp_netif_dhcpc_start(netif_from_if(tcpip_if));
}
esp_err_t tcpip_adapter_dhcps_get_status(tcpip_adapter_if_t tcpip_if, tcpip_adapter_dhcp_status_t *status)
{
return esp_netif_dhcps_get_status(netif_from_if(tcpip_if), status);
}
esp_err_t tcpip_adapter_dhcps_option(tcpip_adapter_dhcp_option_mode_t opt_op, tcpip_adapter_dhcp_option_id_t opt_id, void *opt_val, uint32_t opt_len)
{
// Note: legacy mode supports dhcps only for default wifi AP
return esp_netif_dhcps_option(esp_netif_get_handle_from_ifkey("WIFI_AP_DEF"), opt_op, opt_id, opt_val, opt_len);
}
esp_err_t tcpip_adapter_dhcpc_option(tcpip_adapter_dhcp_option_mode_t opt_op, tcpip_adapter_dhcp_option_id_t opt_id, void *opt_val, uint32_t opt_len)
{
return esp_netif_dhcpc_option(NULL, opt_op, opt_id, opt_val, opt_len);
}
esp_err_t tcpip_adapter_set_ip_info(tcpip_adapter_if_t tcpip_if, const tcpip_adapter_ip_info_t *ip_info)
{
return esp_netif_set_ip_info(netif_from_if(tcpip_if), (esp_netif_ip_info_t *)ip_info);
}
esp_err_t tcpip_adapter_get_dns_info(tcpip_adapter_if_t tcpip_if, tcpip_adapter_dns_type_t type, tcpip_adapter_dns_info_t *dns)
{
return esp_netif_get_dns_info(netif_from_if(tcpip_if), type, dns);
}
esp_err_t tcpip_adapter_set_dns_info(tcpip_adapter_if_t tcpip_if, tcpip_adapter_dns_type_t type, tcpip_adapter_dns_info_t *dns)
{
return esp_netif_set_dns_info(netif_from_if(tcpip_if), type, dns);
}
int tcpip_adapter_get_netif_index(tcpip_adapter_if_t tcpip_if)
{
return esp_netif_get_netif_impl_index(netif_from_if(tcpip_if));
}
esp_err_t tcpip_adapter_get_sta_list(const wifi_sta_list_t *wifi_sta_list, tcpip_adapter_sta_list_t *tcpip_sta_list)
{
return esp_netif_get_sta_list(wifi_sta_list, tcpip_sta_list);
}
static esp_err_t tcpip_adapter_compat_start_netif(esp_netif_t *netif, uint8_t *mac, tcpip_adapter_ip_info_t *ip_info)
{
if (netif == NULL || mac == NULL || ip_info == NULL) {
return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS;
}
esp_netif_set_mac(netif, mac);
esp_netif_set_ip_info(netif, (esp_netif_ip_info_t *)ip_info);
esp_netif_action_start(netif, NULL, 0, NULL);
return ESP_OK;
}
esp_err_t tcpip_adapter_eth_start(uint8_t *mac, tcpip_adapter_ip_info_t *ip_info, void *args)
{
return tcpip_adapter_compat_start_netif(netif_from_if(TCPIP_ADAPTER_IF_ETH),
mac, ip_info);
}
esp_err_t tcpip_adapter_sta_start(uint8_t *mac, tcpip_adapter_ip_info_t *ip_info)
{
return tcpip_adapter_compat_start_netif(netif_from_if(TCPIP_ADAPTER_IF_STA),
mac, ip_info);
}
esp_err_t tcpip_adapter_ap_start(uint8_t *mac, tcpip_adapter_ip_info_t *ip_info)
{
return tcpip_adapter_compat_start_netif(netif_from_if(TCPIP_ADAPTER_IF_AP),
mac, ip_info);
}
esp_err_t tcpip_adapter_stop(tcpip_adapter_if_t tcpip_if)
{
esp_netif_t *netif = netif_from_if(tcpip_if);
if (netif == NULL) {
return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS;
}
esp_netif_action_stop(netif_from_if(tcpip_if), NULL, 0, NULL);
return ESP_OK;
}
esp_err_t tcpip_adapter_up(tcpip_adapter_if_t tcpip_if)
{
return esp_netif_up(netif_from_if(tcpip_if));
}
esp_err_t tcpip_adapter_down(tcpip_adapter_if_t tcpip_if)
{
return esp_netif_down(netif_from_if(tcpip_if));
}
esp_err_t tcpip_adapter_get_old_ip_info(tcpip_adapter_if_t tcpip_if, tcpip_adapter_ip_info_t *ip_info)
{
return esp_netif_get_old_ip_info(netif_from_if(tcpip_if), (esp_netif_ip_info_t *)ip_info);
}
esp_err_t tcpip_adapter_set_old_ip_info(tcpip_adapter_if_t tcpip_if, const tcpip_adapter_ip_info_t *ip_info)
{
return esp_netif_set_old_ip_info(netif_from_if(tcpip_if), (esp_netif_ip_info_t *)ip_info);
}
esp_interface_t tcpip_adapter_get_esp_if(void *dev)
{
esp_netif_t *netif = esp_netif_get_handle_from_netif_impl(dev);
for (int i=0; i< TCPIP_ADAPTER_IF_MAX; ++i) {
if (s_esp_netifs[i] == netif) {
return i;
}
}
return ESP_IF_MAX;
}
esp_err_t tcpip_adapter_set_hostname(tcpip_adapter_if_t tcpip_if, const char *hostname)
{
return esp_netif_set_hostname(netif_from_if(tcpip_if), hostname);
}
esp_err_t tcpip_adapter_get_hostname(tcpip_adapter_if_t tcpip_if, const char **hostname)
{
return esp_netif_get_hostname(netif_from_if(tcpip_if), hostname);
}
#else
esp_err_t tcpip_adapter_compat_start_eth(void* eth_driver)
{
return ESP_OK;
}
#endif

File diff suppressed because it is too large Load diff

View file

@ -18,7 +18,7 @@
#include <esp_log.h>
#include <esp_wifi.h>
#include <tcpip_adapter.h>
#include <esp_netif.h>
#include "wifi_provisioning/wifi_config.h"
#include "wifi_provisioning/wifi_scan.h"
@ -64,10 +64,10 @@ static esp_err_t get_status_handler(wifi_prov_config_get_data_t *resp_data, wifi
ESP_LOGD(TAG, "Got state : connected");
/* IP Addr assigned to STA */
tcpip_adapter_ip_info_t ip_info;
tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_STA, &ip_info);
char *ip_addr = ip4addr_ntoa(&ip_info.ip);
strcpy(resp_data->conn_info.ip_addr, ip_addr);
esp_netif_ip_info_t ip_info;
esp_netif_get_ip_info(esp_netif_get_handle_from_ifkey("WIFI_STA_DEF"), &ip_info);
esp_ip4addr_ntoa(&ip_info.ip, resp_data->conn_info.ip_addr, sizeof(resp_data->conn_info.ip_addr));
/* AP information to which STA is connected */
wifi_ap_record_t ap_info;

View file

@ -109,8 +109,8 @@ INPUT = \
../../components/soc/esp32/include/soc/touch_channel.h \
../../components/soc/esp32/include/soc/uart_channel.h \
../../components/soc/esp32/include/soc/rtc_gpio_channel.h \
## tcpip_adapter - API Reference
../../components/tcpip_adapter/include/tcpip_adapter.h \
## esp_netif - API Reference
../../components/esp_netif/include/esp_netif.h \
##
## Protocols - API Reference
##

View file

@ -16,7 +16,7 @@ Adapted APIs
Some common lwIP "app" APIs are supported indirectly by ESP-IDF:
- DHCP Server & Client are supported indirectly via the :doc:`/api-reference/network/tcpip_adapter` functionality
- DHCP Server & Client are supported indirectly via the :doc:`/api-reference/network/esp_netif` functionality
- Simple Network Time Protocol (SNTP) is supported via the :component_file:`lwip/include/apps/esp_sntp.h` functions (see also :example:`protocols/sntp`)
- ICMP Ping is supported using a variation on the lwIP ping API. See :doc:`/api-reference/protocols/icmp_echo`.
- NetBIOS lookup is available using the standard lwIP API. :example:`protocols/http_server/restful_server` has an option to demonstrate using NetBIOS to look up a host on the LAN.

View file

@ -122,7 +122,7 @@ The ESP32 Wi-Fi programming model is depicted as follows:
The Wi-Fi driver can be considered a black box that knows nothing about high-layer code, such as the TCP/IP stack, application task, event task, etc. The application task (code) generally calls :doc:`Wi-Fi driver APIs <../api-reference/network/esp_wifi>` to initialize Wi-Fi and handles Wi-Fi events when necessary. Wi-Fi driver receives API calls, handles them, and post events to the application.
Wi-Fi event handling is based on the :doc:`esp_event library <../api-reference/system/esp_event>`. Events are sent by the Wi-Fi driver to the :ref:`default event loop <esp-event-default-loops>`. Application may handle these events in callbacks registered using :cpp:func:`esp_event_handler_register`. Wi-Fi events are also handled by :doc:`tcpip_adapter component <../api-reference/network/tcpip_adapter>` to provide a set of default behaviors. For example, when Wi-Fi station connects to an AP, tcpip_adapter will automatically start the DHCP client.
Wi-Fi event handling is based on the :doc:`esp_event library <../api-reference/system/esp_event>`. Events are sent by the Wi-Fi driver to the :ref:`default event loop <esp-event-default-loops>`. Application may handle these events in callbacks registered using :cpp:func:`esp_event_handler_register`. Wi-Fi events are also handled by :doc:`esp_netif component <../api-reference/network/esp_netif>` to provide a set of default behaviors. For example, when Wi-Fi station connects to an AP, esp_netif will automatically start the DHCP client (by default).
ESP32 Wi-Fi Event Description
------------------------------------
@ -300,15 +300,17 @@ Below is a "big scenario" which describes some small scenarios in Station mode:
1. Wi-Fi/LwIP Init Phase
++++++++++++++++++++++++++++++
- s1.1: The main task calls tcpip_adapter_init() to create an LwIP core task and initialize LwIP-related work.
- s1.1: The main task calls esp_netif_init() to create an LwIP core task and initialize LwIP-related work.
- s1.2: The main task calls esp_event_loop_init() to create a system Event task and initialize an application event's callback function. In the scenario above, the application event's callback function does nothing but relaying the event to the application task.
- s1.3: The main task calls esp_wifi_init() to create the Wi-Fi driver task and initialize the Wi-Fi driver.
- s1.3: The main task calls esp_netif_create_default_wifi_ap() or esp_netif_create_default_wifi_sta() to create default network interface instance binding station or AP with TCP/IP stack.
- s1.4: The main task calls OS API to create the application task.
- s1.4: The main task calls esp_wifi_init() to create the Wi-Fi driver task and initialize the Wi-Fi driver.
Step 1.1~1.4 is a recommended sequence that initializes a Wi-Fi-/LwIP-based application. However, it is **NOT** a must-follow sequence, which means that you can create the application task in step 1.1 and put all other initializations in the application task. Moreover, you may not want to create the application task in the initialization phase if the application task depends on the sockets. Rather, you can defer the task creation until the IP is obtained.
- s1.5: The main task calls OS API to create the application task.
Step 1.1~1.5 is a recommended sequence that initializes a Wi-Fi-/LwIP-based application. However, it is **NOT** a must-follow sequence, which means that you can create the application task in step 1.1 and put all other initializations in the application task. Moreover, you may not want to create the application task in the initialization phase if the application task depends on the sockets. Rather, you can defer the task creation until the IP is obtained.
2. Wi-Fi Configuration Phase
+++++++++++++++++++++++++++++++

View file

@ -0,0 +1,146 @@
ESP-NETIF
=========
The purpose of ESP-NETIF library is twofold:
- It provides an abstraction layer for the application on top of the TCP/IP stack. This will allow applications to choose between IP stacks in the future.
- The APIs it provides are thread safe, even if the underlying TCP/IP stack APIs are not.
ESP-IDF currently implements ESP-NETIF for the lwIP TCP/IP stack only. However, the adapter itself is TCP/IP implementation agnostic and different implementations are possible.
Some ESP-NETIF API functions are intended to be called by application code, for example to get/set interface IP addresses, configure DHCP. Other functions are intended for internal ESP-IDF use by the network driver layer.
In many cases, applications do not need to call ESP-NETIF APIs directly as they are called from the default network event handlers.
ESP-NETIF architecture
======================
.. code-block:: text
| (A) USER CODE |
| |
.............| init settings events |
. +----------------------------------------+
. . | *
. . | *
--------+ +===========================+ * +-----------------------+
| | new/config get/set | * | |
| | |...*.....| init |
| |---------------------------| * | |
init | | |**** | |
start |********| event handler |*********| DHCP |
stop | | | | |
| |---------------------------| | |
| | | | NETIF |
+-----| | | +-----------------+ |
| glue|----<---| esp_netif_transmit |--<------| netif_output | |
| | | | | | |
| |---->---| esp_netif_receive |-->------| netif_input | |
| | | | + ----------------+ |
| |....<...| esp_netif_free_rx_buffer |...<.....| packet buffer |
+-----| | | | |
| | | | (D) |
(B) | | (C) | +-----------------------+
--------+ +===========================+
communication NETWORK STACK
DRIVER ESP-NETIF
Data and event flow in the diagram
----------------------------------
* ``........`` Initialization line from user code to ESP-NETIF and communication driver
* ``--<--->--`` Data packets going from communication media to TCP/IP stack and back
* ``********`` Events aggregated in ESP-NETIF propagates to driver, user code and network stack
* ``|`` User settings and runtime configuration
ESP-NETIF interaction
---------------------
A) User code, boiler plate
^^^^^^^^^^^^^^^^^^^^^^^^^^
Overall application interaction with a specific IO driver for communication media and configured TCP/IP network stack
is abstracted using ESP-NETIF APIs and outlined as below:
A) Initialization code
1) Initializes IO driver
2) Creates a new instance of ESP-NETIF and configure with
* ESP-NETIF specific options (flags, behaviour, name)
* Network stack options (netif init and input functions, not publicly available)
* IO driver specific options (transmit, free rx buffer functions, IO driver handle)
3) Attaches the IO driver handle to the ESP-NETIF instance created in the above steps
4) Configures event handlers
* use default handlers for common interfaces defined in IO drivers; or define a specific handlers for customised behaviour/new interfaces
* register handlers for app related events (such as IP lost/acquired)
B) Interaction with network interfaces using ESP-NETIF API
* Getting and setting TCP/IP related parameters (DHCP, IP, etc)
* Receiving IP events (connect/disconnect)
* Controlling application lifecycle (set interface up/down)
Please note that the initialization code as well as registering event handlers for default interfaces,
such as WiFi softAP and WiFi station, are provided as a separate APIs (for example ``esp_netif_create_default_wifi_ap()`` and
``esp_netif_create_default_wifi_sta()``) to facilitate simple startup code for most applications.
B) Communication driver, IO driver, media driver
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Communication driver plays these two important roles in relation with ESP-NETIF:
1) Event handlers: Define behaviour patterns of interaction with ESP-NETIF (for example: ethernet link-up -> turn netif on)
2) Glue IO layer: Adapts the input/output functions to use ESP-NETIF transmit, receive and free receive buffer
* Installs driver_transmit to appropriate ESP-NETIF object, so that outgoing packets from network stack are passed to the IO driver
* Calls ``esp_netif_receive()`` to pass incoming data to network stack
C) ESP-NETIF, former tcpip_adapter
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
ESP-NETIF is an intermediary between an IO driver and a network stack, connecting packet data path between these two.
As that it provides a set of interfaces for attaching a driver to ESP-NETIF object (runtime) and
configuring a network stack (compile time). In addition to that a set of API is provided to control network interface lifecycle
and its TCP/IP properties. As an overview, the ESP-NETIF public interface could be divided into these 6 groups:
1) Initialization APIs (to create and configure ESP-NETIF instance)
2) Input/Output API (for passing data between IO driver and network stack)
3) Event or Action API
* Used for network interface lifecycle management
* ESP-NETIF provides building blocks for designing event handlers
4) Setters and Getters for basic network interface properties
5) Network stack abstraction: enabling user interaction with TCP/IP stack
* Set interface up or down
* DHCP server and client API
* DNS API
6) Driver conversion utilities
D) Network stack
^^^^^^^^^^^^^^^^
Network stack has no public interaction with application code with regard to public interfaces and shall be fully abstracted by
ESP-NETIF API.
API Reference
-------------
.. include:: /_build/inc/esp_netif.inc

View file

@ -36,7 +36,7 @@ IP Network Layer
.. toctree::
:maxdepth: 1
TCP/IP Adapter <tcpip_adapter.rst>
ESP-NETIF <esp_netif.rst>
Code examples for TCP/IP socket APIs are provided in the :example:`protocols/sockets` directory of ESP-IDF examples.

View file

@ -1,19 +0,0 @@
TCP/IP Adapter
==============
The purpose of TCP/IP Adapter library is twofold:
- It provides an abstraction layer for the application on top of the TCP/IP stack. This will allow applications to choose between IP stacks in the future.
- The APIs it provides are thread safe, even if the underlying TCP/IP stack APIs are not.
ESP-IDF currently implements TCP/IP Adapter for the lwIP TCP/IP stack only. However, the adapter itself is TCP/IP implementation agnostic and different implementations are possible.
Some TCP/IP Adapter API functions are intended to be called by application code, for example to get/set interface IP addresses, configure DHCP. Other functions are intended for internal ESP-IDF use by the network driver layer.
In many cases, applications do not need to call TCP/IP Adapter APIs directly as they are called from the default network event handlers.
API Reference
-------------
.. include:: /_build/inc/tcpip_adapter.inc

View file

@ -0,0 +1,2 @@
.. include:: ../../../en/api-reference/network/esp_netif.rst

View file

@ -36,7 +36,7 @@ IP 网络层协议
.. toctree::
:maxdepth: 1
TCP/IP Adapter <tcpip_adapter.rst>
ESP-NETIF <esp_netif.rst>
TCP/IP 套接字 API 的示例代码存放在 ESP-IDF 示例项目的 :example:`protocols/sockets` 目录下。

View file

@ -1,2 +0,0 @@
.. include:: ../../../en/api-reference/network/tcpip_adapter.rst

View file

@ -197,9 +197,11 @@ static void wifi_event_handler(void* arg, esp_event_base_t event_base,
static void initialise_wifi(void)
{
tcpip_adapter_init();
esp_netif_init();
wifi_event_group = xEventGroupCreate();
ESP_ERROR_CHECK(esp_event_loop_create_default());
esp_netif_t *sta_netif = esp_netif_create_default_wifi_sta();
assert(sta_netif);
ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &wifi_event_handler, NULL));
ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &ip_event_handler, NULL));

View file

@ -16,7 +16,7 @@
#include "freertos/FreeRTOS.h"
#include "freertos/event_groups.h"
#include "esp_wifi.h"
#include "tcpip_adapter.h"
#include "esp_netif.h"
#include "iperf.h"
typedef struct {
@ -51,6 +51,8 @@ static const char *TAG = "iperf";
static EventGroupHandle_t wifi_event_group;
const int CONNECTED_BIT = BIT0;
const int DISCONNECTED_BIT = BIT1;
static esp_netif_t * sta_netif = NULL;
static esp_netif_t * ap_netif = NULL;
static void scan_done_handler(void)
{
@ -124,9 +126,13 @@ void initialise_wifi(void)
return;
}
tcpip_adapter_init();
esp_netif_init();
wifi_event_group = xEventGroupCreate();
ESP_ERROR_CHECK(esp_event_loop_create_default());
esp_netif_t *sta_netif = esp_netif_create_default_wifi_sta();
assert(sta_netif);
esp_netif_t *ap_netif = esp_netif_create_default_wifi_ap();
assert(ap_netif);
ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &wifi_event_handler, NULL));
ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &ip_event_handler, NULL));
@ -286,22 +292,22 @@ static int wifi_cmd_query(int argc, char **argv)
static uint32_t wifi_get_local_ip(void)
{
int bits = xEventGroupWaitBits(wifi_event_group, CONNECTED_BIT, 0, 1, 0);
tcpip_adapter_if_t ifx = TCPIP_ADAPTER_IF_AP;
tcpip_adapter_ip_info_t ip_info;
esp_netif_t * ifx = ap_netif;
esp_netif_ip_info_t ip_info;
wifi_mode_t mode;
esp_wifi_get_mode(&mode);
if (WIFI_MODE_STA == mode) {
bits = xEventGroupWaitBits(wifi_event_group, CONNECTED_BIT, 0, 1, 0);
if (bits & CONNECTED_BIT) {
ifx = TCPIP_ADAPTER_IF_STA;
ifx = sta_netif;
} else {
ESP_LOGE(TAG, "sta has no IP");
return 0;
}
}
tcpip_adapter_get_ip_info(ifx, &ip_info);
esp_netif_get_ip_info(ifx, &ip_info);
return ip_info.ip.addr;
}
@ -331,7 +337,7 @@ static int wifi_cmd_iperf(int argc, char **argv)
if (iperf_args.ip->count == 0) {
cfg.flag |= IPERF_FLAG_SERVER;
} else {
cfg.dip = ipaddr_addr(iperf_args.ip->sval[0]);
cfg.dip = esp_ip4addr_aton(iperf_args.ip->sval[0]);
cfg.flag |= IPERF_FLAG_CLIENT;
}

View file

@ -1,2 +1,4 @@
idf_component_register(SRCS "connect.c" "stdin_out.c"
INCLUDE_DIRS "include")
INCLUDE_DIRS "include"
PRIV_REQUIRES esp_netif
)

View file

@ -12,11 +12,12 @@
#include "sdkconfig.h"
#include "esp_event.h"
#include "esp_wifi.h"
#include "esp_wifi_default.h"
#if CONFIG_EXAMPLE_CONNECT_ETHERNET
#include "esp_eth.h"
#endif
#include "esp_log.h"
#include "tcpip_adapter.h"
#include "esp_netif.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/event_groups.h"
@ -33,11 +34,12 @@
#endif
static EventGroupHandle_t s_connect_event_group;
static ip4_addr_t s_ip_addr;
static esp_ip4_addr_t s_ip_addr;
static const char *s_connection_name;
static esp_netif_t *s_example_esp_netif = NULL;
#ifdef CONFIG_EXAMPLE_CONNECT_IPV6
static ip6_addr_t s_ipv6_addr;
static esp_ip6_addr_t s_ipv6_addr;
#endif
static const char *TAG = "example_connect";
@ -51,6 +53,7 @@ static void stop(void);
static void on_got_ip(void *arg, esp_event_base_t event_base,
int32_t event_id, void *event_data)
{
ESP_LOGI(TAG, "Got IP event!");
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);
@ -61,6 +64,7 @@ static void on_got_ip(void *arg, esp_event_base_t event_base,
static void on_got_ipv6(void *arg, esp_event_base_t event_base,
int32_t event_id, void *event_data)
{
ESP_LOGI(TAG, "Got IPv6 event!");
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);
@ -76,6 +80,7 @@ esp_err_t example_connect(void)
s_connect_event_group = xEventGroupCreate();
start();
ESP_ERROR_CHECK(esp_register_shutdown_handler(&stop));
ESP_LOGI(TAG, "Waiting for IP");
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));
@ -113,10 +118,10 @@ static void on_wifi_disconnect(void *arg, esp_event_base_t event_base,
#ifdef CONFIG_EXAMPLE_CONNECT_IPV6
static void on_wifi_connect(void *arg, esp_event_base_t event_base,
static void on_wifi_connect(void *esp_netif, esp_event_base_t event_base,
int32_t event_id, void *event_data)
{
tcpip_adapter_create_ip6_linklocal(TCPIP_ADAPTER_IF_STA);
esp_netif_create_ip6_linklocal(esp_netif);
}
#endif // CONFIG_EXAMPLE_CONNECT_IPV6
@ -126,10 +131,21 @@ static void start(void)
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
ESP_ERROR_CHECK(esp_wifi_init(&cfg));
esp_netif_config_t netif_config = ESP_NETIF_DEFAULT_WIFI_STA();
esp_netif_t* netif = esp_netif_new(&netif_config);
assert(netif);
esp_netif_attach_wifi_station(netif);
esp_wifi_set_default_wifi_sta_handlers();
s_example_esp_netif = netif;
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(WIFI_EVENT, WIFI_EVENT_STA_CONNECTED, &on_wifi_connect, netif));
ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_GOT_IP6, &on_got_ipv6, NULL));
#endif
@ -162,6 +178,9 @@ static void stop(void)
}
ESP_ERROR_CHECK(err);
ESP_ERROR_CHECK(esp_wifi_deinit());
ESP_ERROR_CHECK(esp_wifi_clear_default_wifi_driver_and_handlers(s_example_esp_netif));
esp_netif_destroy(s_example_esp_netif);
s_example_esp_netif = NULL;
}
#endif // CONFIG_EXAMPLE_CONNECT_WIFI
@ -170,13 +189,13 @@ static void stop(void)
#ifdef CONFIG_EXAMPLE_CONNECT_IPV6
/** Event handler for Ethernet events */
static void on_eth_event(void *arg, esp_event_base_t event_base,
static void on_eth_event(void *esp_netif, 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);
esp_netif_create_ip6_linklocal(esp_netif);
break;
default:
break;
@ -191,10 +210,19 @@ static esp_eth_phy_t *s_phy = NULL;
static void start(void)
{
ESP_ERROR_CHECK(tcpip_adapter_set_default_eth_handlers());
esp_netif_config_t netif_config = ESP_NETIF_DEFAULT_ETH();
esp_netif_t* netif = esp_netif_new(&netif_config);
assert(netif);
ESP_ERROR_CHECK(esp_eth_set_default_handlers(netif));
s_example_esp_netif = netif;
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(ETH_EVENT, ETHERNET_EVENT_CONNECTED, &on_eth_event, netif));
ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_GOT_IP6, &on_got_ipv6, NULL));
#endif
eth_mac_config_t mac_config = ETH_MAC_DEFAULT_CONFIG();
@ -241,7 +269,10 @@ static void start(void)
#endif
esp_eth_config_t config = ETH_DEFAULT_CONFIG(s_mac, s_phy);
ESP_ERROR_CHECK(esp_eth_driver_install(&config, &s_eth_handle));
esp_netif_attach(netif, s_eth_handle);
s_connection_name = "Ethernet";
}
@ -255,6 +286,15 @@ static void stop(void)
ESP_ERROR_CHECK(esp_eth_driver_uninstall(s_eth_handle));
ESP_ERROR_CHECK(s_phy->del(s_phy));
ESP_ERROR_CHECK(s_mac->del(s_mac));
esp_eth_clear_default_handlers(s_example_esp_netif);
esp_netif_destroy(s_example_esp_netif);
s_example_esp_netif = NULL;
}
#endif // CONFIG_EXAMPLE_CONNECT_ETHERNET
esp_netif_t *get_example_netif(void)
{
return s_example_esp_netif;
}

View file

@ -14,14 +14,14 @@ extern "C" {
#endif
#include "esp_err.h"
#include "tcpip_adapter.h"
#include "esp_netif.h"
#ifdef CONFIG_EXAMPLE_CONNECT_ETHERNET
#define EXAMPLE_INTERFACE TCPIP_ADAPTER_IF_ETH
#define EXAMPLE_INTERFACE get_example_netif()
#endif
#ifdef CONFIG_EXAMPLE_CONNECT_WIFI
#define EXAMPLE_INTERFACE TCPIP_ADAPTER_IF_STA
#define EXAMPLE_INTERFACE get_example_netif()
#endif
/**
@ -54,6 +54,11 @@ esp_err_t example_disconnect(void);
*/
esp_err_t example_configure_stdin_stdout(void);
/**
* @brief Returns esp-netif pointer created by example_connect()
*
*/
esp_netif_t *get_example_netif(void);
#ifdef __cplusplus
}
#endif

View file

@ -10,7 +10,7 @@
#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "tcpip_adapter.h"
#include "esp_netif.h"
#include "esp_eth.h"
#include "esp_event.h"
#include "esp_log.h"
@ -52,7 +52,7 @@ static void got_ip_event_handler(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;
const tcpip_adapter_ip_info_t *ip_info = &event->ip_info;
const esp_netif_ip_info_t *ip_info = &event->ip_info;
ESP_LOGI(TAG, "Ethernet Got IP Address");
ESP_LOGI(TAG, "~~~~~~~~~~~");
@ -64,10 +64,12 @@ static void got_ip_event_handler(void *arg, esp_event_base_t event_base,
void app_main(void)
{
tcpip_adapter_init();
esp_netif_init();
ESP_ERROR_CHECK(esp_event_loop_create_default());
ESP_ERROR_CHECK(tcpip_adapter_set_default_eth_handlers());
esp_netif_config_t cfg = ESP_NETIF_DEFAULT_ETH();
esp_netif_t* eth_netif = esp_netif_new(&cfg);
ESP_ERROR_CHECK(esp_eth_set_default_handlers(eth_netif));
ESP_ERROR_CHECK(esp_event_handler_register(ETH_EVENT, ESP_EVENT_ANY_ID, &eth_event_handler, NULL));
ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_ETH_GOT_IP, &got_ip_event_handler, NULL));
@ -112,4 +114,5 @@ void app_main(void)
esp_eth_config_t config = ETH_DEFAULT_CONFIG(mac, phy);
esp_eth_handle_t eth_handle = NULL;
ESP_ERROR_CHECK(esp_eth_driver_install(&config, &eth_handle));
ESP_ERROR_CHECK(esp_netif_attach(eth_netif, eth_handle));
}

View file

@ -185,6 +185,7 @@ static void initialize_ethernet(void)
config.stack_input = pkt_eth2wifi;
ESP_ERROR_CHECK(esp_eth_driver_install(&config, &s_eth_handle));
esp_eth_ioctl(s_eth_handle, ETH_CMD_S_PROMISCUOUS, (void *)true);
esp_eth_driver_start(s_eth_handle);
}
static void initialize_wifi(void)
@ -192,7 +193,6 @@ static void initialize_wifi(void)
ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, wifi_event_handler, NULL));
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
ESP_ERROR_CHECK(esp_wifi_init(&cfg));
ESP_ERROR_CHECK(tcpip_adapter_clear_default_wifi_handlers());
ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_RAM));
wifi_config_t wifi_config = {
.ap = {

View file

@ -10,7 +10,7 @@
#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/event_groups.h"
#include "tcpip_adapter.h"
#include "esp_netif.h"
#include "esp_log.h"
#include "esp_console.h"
#include "esp_event.h"
@ -19,11 +19,12 @@
#include "iperf.h"
#include "sdkconfig.h"
static tcpip_adapter_ip_info_t ip;
static esp_netif_ip_info_t ip;
static bool started = false;
static EventGroupHandle_t eth_event_group;
static const int GOTIP_BIT = BIT0;
static esp_eth_handle_t eth_handle = NULL;
static esp_netif_t* eth_netif = NULL;
/* "ethernet" command */
static struct {
@ -43,7 +44,7 @@ static int eth_cmd_control(int argc, char **argv)
uint8_t mac_addr[6];
esp_eth_ioctl(eth_handle, ETH_CMD_G_MAC_ADDR, mac_addr);
printf("HW ADDR: " MACSTR "\r\n", MAC2STR(mac_addr));
tcpip_adapter_get_ip_info(ESP_IF_ETH, &ip);
esp_netif_get_ip_info(eth_netif, &ip);
printf("ETHIP: " IPSTR "\r\n", IP2STR(&ip.ip));
printf("ETHMASK: " IPSTR "\r\n", IP2STR(&ip.netmask));
printf("ETHGW: " IPSTR "\r\n", IP2STR(&ip.gw));
@ -94,7 +95,7 @@ static int eth_cmd_iperf(int argc, char **argv)
}
/* iperf -c SERVER_ADDRESS */
else {
cfg.dip = ipaddr_addr(iperf_args.ip->sval[0]);
cfg.dip = esp_ip4addr_aton(iperf_args.ip->sval[0]);
cfg.flag |= IPERF_FLAG_CLIENT;
}
@ -176,9 +177,11 @@ static void event_handler(void *arg, esp_event_base_t event_base,
void register_ethernet(void)
{
eth_event_group = xEventGroupCreate();
tcpip_adapter_init();
esp_netif_init();
ESP_ERROR_CHECK(esp_event_loop_create_default());
ESP_ERROR_CHECK(tcpip_adapter_set_default_eth_handlers());
esp_netif_config_t cfg = ESP_NETIF_DEFAULT_ETH();
eth_netif = esp_netif_new(&cfg);
ESP_ERROR_CHECK(esp_eth_set_default_handlers(eth_netif));
ESP_ERROR_CHECK(esp_event_handler_register(ETH_EVENT, ESP_EVENT_ANY_ID, &event_handler, NULL));
ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_ETH_GOT_IP, &event_handler, NULL));
@ -222,6 +225,7 @@ void register_ethernet(void)
#endif
esp_eth_config_t config = ETH_DEFAULT_CONFIG(mac, phy);
ESP_ERROR_CHECK(esp_eth_driver_install(&config, &eth_handle));
ESP_ERROR_CHECK(esp_netif_attach(eth_netif, eth_handle));
eth_control_args.control = arg_str1(NULL, NULL, "<info>", "Get info of Ethernet");
eth_control_args.end = arg_end(1);

View file

@ -37,6 +37,7 @@ static bool is_running = true;
static bool is_mesh_connected = false;
static mesh_addr_t mesh_parent_addr;
static int mesh_layer = -1;
static esp_netif_t *netif_sta = NULL;
mesh_light_ctl_t light_on = {
.cmd = MESH_CONTROL_CMD,
@ -244,7 +245,7 @@ void mesh_event_handler(void *arg, esp_event_base_t event_base,
mesh_connected_indicator(mesh_layer);
is_mesh_connected = true;
if (esp_mesh_is_root()) {
tcpip_adapter_dhcpc_start(TCPIP_ADAPTER_IF_STA);
esp_netif_dhcpc_start(netif_sta);
}
esp_mesh_comm_p2p_start();
}
@ -367,7 +368,8 @@ void ip_event_handler(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;
ESP_LOGI(MESH_TAG, "<IP_EVENT_STA_GOT_IP>IP:%s", ip4addr_ntoa(&event->ip_info.ip));
ESP_LOGI(MESH_TAG, "<IP_EVENT_STA_GOT_IP>IP:" IPSTR, IP2STR(&event->ip_info.ip));
}
void app_main(void)
@ -375,15 +377,11 @@ void app_main(void)
ESP_ERROR_CHECK(mesh_light_init());
ESP_ERROR_CHECK(nvs_flash_init());
/* tcpip initialization */
tcpip_adapter_init();
/* for mesh
* stop DHCP server on softAP interface by default
* stop DHCP client on station interface by default
* */
ESP_ERROR_CHECK(tcpip_adapter_dhcps_stop(TCPIP_ADAPTER_IF_AP));
ESP_ERROR_CHECK(tcpip_adapter_dhcpc_stop(TCPIP_ADAPTER_IF_STA));
esp_netif_init();
/* event initialization */
ESP_ERROR_CHECK(esp_event_loop_create_default());
/* crete network interfaces for mesh (only station instance saved for further manipulation, soft AP instance ignored */
ESP_ERROR_CHECK(esp_netif_create_default_wifi_mesh_netifs(&netif_sta, NULL));
/* wifi initialization */
wifi_init_config_t config = WIFI_INIT_CONFIG_DEFAULT();
ESP_ERROR_CHECK(esp_wifi_init(&config));

View file

@ -36,6 +36,7 @@ static const char *MESH_TAG = "mesh_main";
static const uint8_t MESH_ID[6] = { 0x77, 0x77, 0x77, 0x77, 0x77, 0x77};
static mesh_addr_t mesh_parent_addr;
static int mesh_layer = -1;
static esp_netif_t *netif_sta = NULL;
/*******************************************************
* Function Declarations
@ -228,7 +229,7 @@ void mesh_event_handler(void *arg, esp_event_base_t event_base,
last_layer = mesh_layer;
mesh_connected_indicator(mesh_layer);
if (esp_mesh_is_root()) {
tcpip_adapter_dhcpc_start(TCPIP_ADAPTER_IF_STA);
esp_netif_dhcpc_start(netif_sta);
}
}
break;
@ -292,7 +293,7 @@ void ip_event_handler(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;
ESP_LOGI(MESH_TAG, "<IP_EVENT_STA_GOT_IP>IP:%s", ip4addr_ntoa(&event->ip_info.ip));
ESP_LOGI(MESH_TAG, "<IP_EVENT_STA_GOT_IP>IP:" IPSTR, IP2STR(&event->ip_info.ip));
}
void app_main(void)
@ -300,15 +301,11 @@ void app_main(void)
ESP_ERROR_CHECK(mesh_light_init());
ESP_ERROR_CHECK(nvs_flash_init());
/* tcpip initialization */
tcpip_adapter_init();
/* for mesh
* stop DHCP server on softAP interface by default
* stop DHCP client on station interface by default
* */
ESP_ERROR_CHECK(tcpip_adapter_dhcps_stop(TCPIP_ADAPTER_IF_AP));
ESP_ERROR_CHECK(tcpip_adapter_dhcpc_stop(TCPIP_ADAPTER_IF_STA));
esp_netif_init();
/* event initialization */
ESP_ERROR_CHECK(esp_event_loop_create_default());
/* crete network interfaces for mesh (only station instance saved for further manipulation, soft AP instance ignored */
ESP_ERROR_CHECK(esp_netif_create_default_wifi_mesh_netifs(&netif_sta, NULL));
/* wifi initialization */
wifi_init_config_t config = WIFI_INIT_CONFIG_DEFAULT();
ESP_ERROR_CHECK(esp_wifi_init(&config));

View file

@ -16,7 +16,6 @@
#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;
@ -137,7 +136,7 @@ void read_line(char * line, int max_chars);
extern "C" void app_main(void)
{
ESP_ERROR_CHECK(nvs_flash_init());
tcpip_adapter_init();
esp_netif_init();
ESP_ERROR_CHECK(esp_event_loop_create_default());
/* This helper function configures Wi-Fi or Ethernet, as selected in menuconfig.

View file

@ -19,7 +19,6 @@
#include "chat_message.hpp"
#include "protocol_examples_common.h"
#include "esp_event.h"
#include "tcpip_adapter.h"
#include "nvs_flash.h"
@ -205,7 +204,7 @@ private:
extern "C" void app_main(void)
{
ESP_ERROR_CHECK(nvs_flash_init());
tcpip_adapter_init();
esp_netif_init();
ESP_ERROR_CHECK(esp_event_loop_create_default());
/* This helper function configures Wi-Fi or Ethernet, as selected in menuconfig.

View file

@ -3,7 +3,6 @@
#include <iostream>
#include "protocol_examples_common.h"
#include "esp_event.h"
#include "tcpip_adapter.h"
#include "nvs_flash.h"
using asio::ip::tcp;
@ -87,7 +86,7 @@ private:
extern "C" void app_main(void)
{
ESP_ERROR_CHECK(nvs_flash_init());
tcpip_adapter_init();
esp_netif_init();
ESP_ERROR_CHECK(esp_event_loop_create_default());
/* This helper function configures Wi-Fi or Ethernet, as selected in menuconfig.

View file

@ -15,7 +15,6 @@
#include "protocol_examples_common.h"
#include "esp_event.h"
#include "tcpip_adapter.h"
#include "nvs_flash.h"
@ -69,7 +68,7 @@ private:
extern "C" void app_main(void)
{
ESP_ERROR_CHECK(nvs_flash_init());
tcpip_adapter_init();
esp_netif_init();
ESP_ERROR_CHECK(esp_event_loop_create_default());
/* This helper function configures Wi-Fi or Ethernet, as selected in menuconfig.

View file

@ -440,7 +440,7 @@ clean_up:
void app_main(void)
{
ESP_ERROR_CHECK( nvs_flash_init() );
tcpip_adapter_init();
esp_netif_init();
ESP_ERROR_CHECK(esp_event_loop_create_default());
/* This helper function configures Wi-Fi or Ethernet, as selected in menuconfig.

View file

@ -306,7 +306,7 @@ clean_up:
void app_main(void)
{
ESP_ERROR_CHECK( nvs_flash_init() );
tcpip_adapter_init();
esp_netif_init();
ESP_ERROR_CHECK(esp_event_loop_create_default());
/* This helper function configures Wi-Fi or Ethernet, as selected in menuconfig.

View file

@ -15,7 +15,7 @@
#include "esp_system.h"
#include "nvs_flash.h"
#include "esp_event.h"
#include "tcpip_adapter.h"
#include "esp_netif.h"
#include "protocol_examples_common.h"
#include "esp_tls.h"
@ -541,7 +541,7 @@ void app_main(void)
ret = nvs_flash_init();
}
ESP_ERROR_CHECK(ret);
tcpip_adapter_init();
esp_netif_init();
ESP_ERROR_CHECK(esp_event_loop_create_default());
/* This helper function configures Wi-Fi or Ethernet, as selected in menuconfig.

View file

@ -55,8 +55,7 @@ static void event_handler(void* arg, esp_event_base_t event_base,
ESP_LOGI(TAG,"connect to the AP fail");
} else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) {
ip_event_got_ip_t* event = (ip_event_got_ip_t*) event_data;
ESP_LOGI(TAG, "got ip:%s",
ip4addr_ntoa(&event->ip_info.ip));
ESP_LOGI(TAG, "got ip:" IPSTR, IP2STR(&event->ip_info.ip));
s_retry_num = 0;
xEventGroupSetBits(s_wifi_event_group, WIFI_CONNECTED_BIT);
}
@ -66,9 +65,11 @@ void wifi_init_sta(void)
{
s_wifi_event_group = xEventGroupCreate();
tcpip_adapter_init();
esp_netif_init();
ESP_ERROR_CHECK(esp_event_loop_create_default());
esp_netif_t *sta_netif = esp_netif_create_default_wifi_sta();
assert(sta_netif);
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
ESP_ERROR_CHECK(esp_wifi_init(&cfg));

Some files were not shown because too many files have changed in this diff Show more