Merge branch 'feature/dhcp_skip_discovery' into 'master'

DHCP restore last ip and skip discovery

See merge request idf/esp-idf!3132
This commit is contained in:
Ivan Grokhotkov 2018-09-17 12:27:56 +08:00
commit eea49d250a
5 changed files with 146 additions and 0 deletions

View file

@ -160,6 +160,14 @@ config LWIP_DHCP_DOES_ARP_CHECK
Enabling this option performs a check (via ARP request) if the offered IP address Enabling this option performs a check (via ARP request) if the offered IP address
is not already in use by another host on the network. is not already in use by another host on the network.
config LWIP_DHCP_RESTORE_LAST_IP
bool "DHCP: Restore last IP obtained from DHCP server"
default n
help
When this option is enabled, DHCP client tries to re-obtain last valid IP address obtained from DHCP server.
Last valid DHCP configuration is stored in nvs and restored afrer reset/power-up. If IP is still available,
there is no need for sending discovery message to DHCP server and save some time.
menu "DHCP server" menu "DHCP server"
config LWIP_DHCPS_LEASE_UNIT config LWIP_DHCPS_LEASE_UNIT

View file

@ -44,6 +44,8 @@
#include "esp_system.h" #include "esp_system.h"
#include "sdkconfig.h" #include "sdkconfig.h"
#include "netif/dhcp_state.h"
/* Enable all Espressif-only options */ /* Enable all Espressif-only options */
/* /*
@ -220,6 +222,19 @@
*/ */
#define DHCP_DOES_ARP_CHECK CONFIG_LWIP_DHCP_DOES_ARP_CHECK #define DHCP_DOES_ARP_CHECK CONFIG_LWIP_DHCP_DOES_ARP_CHECK
/**
* CONFIG_LWIP_DHCP_RESTORE_LAST_IP==1: Last valid IP address obtained from DHCP server
* is restored after reset/power-up.
*/
#if CONFIG_LWIP_DHCP_RESTORE_LAST_IP
#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])
#endif
/* /*
------------------------------------ ------------------------------------
---------- AUTOIP options ---------- ---------- AUTOIP options ----------

View file

@ -0,0 +1,33 @@
// 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.
#ifndef _DHCP_STATE_H_
#define _DHCP_STATE_H_
#ifdef __cplusplus
extern "C" {
#endif
bool dhcp_ip_addr_restore(void *netif);
void dhcp_ip_addr_store(void *netif);
void dhcp_ip_addr_erase(void *netif);
#ifdef __cplusplus
}
#endif
#endif /* _DHCP_STATE_H_ */

View file

@ -0,0 +1,87 @@
// 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 <stdio.h>
#include <assert.h>
#include "nvs.h"
#include "lwip/opt.h"
#include "lwip/dhcp.h"
#include "lwip/netif.h"
#include "esp_interface.h"
#include "tcpip_adapter.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"};
_Static_assert(sizeof(interface_key) / sizeof(char*) == TCPIP_ADAPTER_IF_MAX,
"Number interface keys differs from number of interfaces");
bool dhcp_ip_addr_restore(void *netif)
{
nvs_handle nvs;
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);
if(VALID_NETIF_ID(netif_id)) {
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;
err = true;
}
nvs_close(nvs);
}
}
return err;
}
void dhcp_ip_addr_store(void *netif)
{
nvs_handle nvs;
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);
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);
}
}
}
}
void dhcp_ip_addr_erase(void *netif)
{
nvs_handle 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 (nvs_open(DHCP_NAMESPACE, NVS_READWRITE, &nvs) == ESP_OK) {
nvs_erase_key(nvs, interface_key[netif_id]);
nvs_commit(nvs);
nvs_close(nvs);
}
}
}

View file

@ -1074,6 +1074,9 @@ esp_err_t tcpip_adapter_dhcpc_stop(tcpip_adapter_if_t tcpip_if)
ESP_LOGD(TAG, "dhcp client stop successfully"); ESP_LOGD(TAG, "dhcp client stop successfully");
dhcpc_status[tcpip_if] = TCPIP_ADAPTER_DHCP_STOPPED; dhcpc_status[tcpip_if] = TCPIP_ADAPTER_DHCP_STOPPED;
LWIP_DHCP_IP_ADDR_ERASE();
return ESP_OK; return ESP_OK;
} }