]> granicus.if.org Git - esp-idf/commitdiff
lwip: DHCP restore last IP
authorMartinValik <martin.valik@mail.com>
Wed, 29 Aug 2018 08:22:54 +0000 (10:22 +0200)
committerIvan Grokhotkov <ivan@espressif.com>
Mon, 17 Sep 2018 03:11:25 +0000 (11:11 +0800)
Closes https://github.com/espressif/esp-idf/issues/799

components/lwip/Kconfig
components/lwip/port/esp32/include/lwipopts.h
components/lwip/port/esp32/include/netif/dhcp_state.h [new file with mode: 0644]
components/lwip/port/esp32/netif/dhcp_state.c [new file with mode: 0644]
components/tcpip_adapter/tcpip_adapter_lwip.c

index 3fd6ab4662364dfdb3a54945b4509303cb969bc0..f8802d1177d80ce1cb98f9736ee834c2e7f57e22 100644 (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
         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"
 
 config LWIP_DHCPS_LEASE_UNIT
index db6f98246237a6cf8765977c51b9545fe905091f..53b598609c6bde706f80bc47ec310bb341b99afe 100644 (file)
@@ -44,6 +44,8 @@
 #include "esp_system.h"
 #include "sdkconfig.h"
 
+#include "netif/dhcp_state.h"
+
 /* Enable all Espressif-only options */
 
 /*
  */
 #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 ----------
diff --git a/components/lwip/port/esp32/include/netif/dhcp_state.h b/components/lwip/port/esp32/include/netif/dhcp_state.h
new file mode 100644 (file)
index 0000000..ffea116
--- /dev/null
@@ -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_ */
\ No newline at end of file
diff --git a/components/lwip/port/esp32/netif/dhcp_state.c b/components/lwip/port/esp32/netif/dhcp_state.c
new file mode 100644 (file)
index 0000000..9301ff3
--- /dev/null
@@ -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);
+        }
+    }
+}
\ No newline at end of file
index e06a2205dce3a5404f77642c64c4c70e415e651c..85a76da815ab574fa937890fe1b0cdf4c33967f6 100644 (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");
     dhcpc_status[tcpip_if] = TCPIP_ADAPTER_DHCP_STOPPED;
+
+    LWIP_DHCP_IP_ADDR_ERASE();
+    
     return ESP_OK;
 }