Skip to content

Commit 502d946

Browse files
authored
Initialize SoftAP DhcpServer object on demand (#8546)
* Initialize SoftAP DhcpServer object on demand Remove dependency on global ctor, and just construct the object when someone asks us to do it. Only dependency right now is netif_git, which is expected to be initialized by the lwip code some time before dhcps_start happens. Removing ip_info from begin(), since we never reference later on. Also removing the specific check for netif id and simplify the ctors. Update tests and recover old nonos-sdk dhcps functions that were not implemented. * nonos helpers have a separate header * wifi ap needs this anyway, simplify sketch includes * missing example * existing name :/ * trying to fix header dependency * restyle * not a c header * no need to init * move dhcp server getter to WiFi more... arduino'ish? we ahve object as namespace, plus everything else related to softAP is there redundant includes, redundant mock impl (out-of-scope here to fix) * ...move things back, still expose as WiFi method * review fix * include -nonos header in wifi lib though * no more lwip include * style * need mock dhcpserver instance
1 parent 61e7605 commit 502d946

File tree

15 files changed

+233
-334
lines changed

15 files changed

+233
-334
lines changed
+66-34
Original file line numberDiff line numberDiff line change
@@ -1,63 +1,95 @@
11
/*
2-
lwIPDhcpServer-NonOS.cpp - DHCP server wrapper
2+
NonOS DHCP server helpers
33
4-
Copyright (c) 2020 esp8266 arduino. All rights reserved.
4+
Copyright (c) 2020-2022 esp8266 arduino. All rights reserved.
55
This file is part of the esp8266 core for Arduino environment.
6-
76
This library is free software; you can redistribute it and/or
87
modify it under the terms of the GNU Lesser General Public
98
License as published by the Free Software Foundation; either
109
version 2.1 of the License, or (at your option) any later version.
11-
1210
This library is distributed in the hope that it will be useful,
1311
but WITHOUT ANY WARRANTY; without even the implied warranty of
1412
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1513
Lesser General Public License for more details.
16-
1714
You should have received a copy of the GNU Lesser General Public
1815
License along with this library; if not, write to the Free Software
1916
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
2017
*/
2118

22-
// STARTS/STOPS DHCP SERVER ON WIFI AP INTERFACE
23-
// these functions must exists as-is with "C" interface,
24-
// nonos-sdk calls them at boot time and later
25-
26-
#include <lwip/init.h> // LWIP_VERSION
19+
#include "LwipDhcpServer-NonOS.h"
2720

21+
#include <lwip/init.h>
2822
#include <lwip/netif.h>
29-
#include "LwipDhcpServer.h"
3023

31-
extern netif netif_git[2];
32-
33-
// global DHCP instance for softAP interface
34-
DhcpServer dhcpSoftAP(&netif_git[SOFTAP_IF]);
24+
// Global static DHCP instance for softAP interface
25+
// (since the netif object never goes away, even when AP is disabled)
26+
// Initial version fully emulates nonos-sdk api in DhcpServer class,
27+
// before trying to further change it and possibly break legacy behaviour
28+
DhcpServer& getNonOSDhcpServer()
29+
{
30+
extern netif netif_git[2];
31+
static DhcpServer server(&netif_git[SOFTAP_IF]);
32+
return server;
33+
}
3534

3635
extern "C"
3736
{
38-
void dhcps_start(struct ip_info* info, netif* apnetif)
39-
{
40-
// apnetif is esp interface, replaced by lwip2's
41-
// netif_git[SOFTAP_IF] interface in constructor
42-
(void)apnetif;
43-
44-
#if 0
45-
// can't use C++ now, global ctors are not initialized yet
46-
dhcpSoftAP.begin(info);
47-
#else
48-
(void)info;
49-
// initial version: emulate nonos-sdk in DhcpServer class before
50-
// trying to change legacy behavor
51-
// `fw_has_started_softap_dhcps` will be read in DhcpServer::DhcpServer
52-
// which is called when c++ ctors are initialized, specifically
53-
// dhcpSoftAP initialized with AP interface number above.
54-
fw_has_started_softap_dhcps = 1;
55-
#endif
37+
// `ip_info` is useless, since we get the information from the netif directly
38+
// `netif` would be netif_git[SOFTAP_IF], which we get from the lwip2 glue
39+
void dhcps_start(ip_info*, netif*)
40+
{
41+
auto& server = getNonOSDhcpServer();
42+
if (!server.isRunning())
43+
{
44+
server.begin();
45+
}
5646
}
5747

5848
void dhcps_stop()
5949
{
60-
dhcpSoftAP.end();
50+
auto& server = getNonOSDhcpServer();
51+
if (server.isRunning())
52+
{
53+
server.end();
54+
}
55+
}
56+
57+
// providing the rest of the nonos-sdk API, which was originally removed in 3.0.0
58+
59+
bool wifi_softap_set_dhcps_lease(dhcps_lease* please)
60+
{
61+
auto& server = getNonOSDhcpServer();
62+
return server.set_dhcps_lease(please);
63+
}
64+
65+
bool wifi_softap_get_dhcps_lease(dhcps_lease* please)
66+
{
67+
auto& server = getNonOSDhcpServer();
68+
return server.get_dhcps_lease(please);
69+
}
70+
71+
uint32 wifi_softap_get_dhcps_lease_time()
72+
{
73+
auto& server = getNonOSDhcpServer();
74+
return server.get_dhcps_lease_time();
75+
}
76+
77+
bool wifi_softap_set_dhcps_lease_time(uint32 minutes)
78+
{
79+
auto& server = getNonOSDhcpServer();
80+
return server.set_dhcps_lease_time(minutes);
81+
}
82+
83+
bool wifi_softap_reset_dhcps_lease_time()
84+
{
85+
auto& server = getNonOSDhcpServer();
86+
return server.reset_dhcps_lease_time();
87+
}
88+
89+
bool wifi_softap_add_dhcps_lease(uint8* macaddr)
90+
{
91+
auto& server = getNonOSDhcpServer();
92+
return server.add_dhcps_lease(macaddr);
6193
}
6294

6395
} // extern "C"

cores/esp8266/LwipDhcpServer-NonOS.h

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/*
2+
NonOS DHCP server helpers
3+
4+
Copyright (c) 2020-2022 esp8266 arduino. All rights reserved.
5+
This file is part of the esp8266 core for Arduino environment.
6+
This library is free software; you can redistribute it and/or
7+
modify it under the terms of the GNU Lesser General Public
8+
License as published by the Free Software Foundation; either
9+
version 2.1 of the License, or (at your option) any later version.
10+
This library is distributed in the hope that it will be useful,
11+
but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13+
Lesser General Public License for more details.
14+
You should have received a copy of the GNU Lesser General Public
15+
License along with this library; if not, write to the Free Software
16+
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17+
*/
18+
19+
#pragma once
20+
21+
#include "LwipDhcpServer.h"
22+
23+
// Global static DHCP instance for softAP interface
24+
DhcpServer& getNonOSDhcpServer();

cores/esp8266/LwipDhcpServer.cpp

+12-45
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,6 @@
3636

3737
#include <lwip/init.h> // LWIP_VERSION
3838

39-
#define DHCPS_LEASE_TIME_DEF (120)
40-
4139
#define USE_DNS
4240

4341
#include "lwip/inet.h"
@@ -166,7 +164,7 @@ const char mem_debug_file[] ICACHE_RODATA_ATTR = __FILE__;
166164
int ret = 1, errval = (err); \
167165
if (errval != ERR_OK) \
168166
{ \
169-
os_printf("DHCPS ERROR: %s (lwip:%d)\n", what, errval); \
167+
os_printf("DHCPS ERROR: %s (lwip:%s(%d))\n", what, lwip_strerr(errval), errval); \
170168
ret = 0; \
171169
} \
172170
ret; \
@@ -175,36 +173,9 @@ const char mem_debug_file[] ICACHE_RODATA_ATTR = __FILE__;
175173
#define LWIP_IS_OK(what, err) ((err) == ERR_OK)
176174
#endif
177175

178-
const uint32 DhcpServer::magic_cookie = 0x63538263; // https://tools.ietf.org/html/rfc1497
179-
180-
int fw_has_started_softap_dhcps = 0;
181-
182176
////////////////////////////////////////////////////////////////////////////////////
183177

184-
DhcpServer::DhcpServer(netif* netif) : _netif(netif)
185-
{
186-
pcb_dhcps = nullptr;
187-
dns_address.addr = 0;
188-
plist = nullptr;
189-
offer = 0xFF;
190-
renew = false;
191-
dhcps_lease_time = DHCPS_LEASE_TIME_DEF; // minute
192-
193-
if (netif->num == SOFTAP_IF && fw_has_started_softap_dhcps == 1)
194-
{
195-
// When nonos-sdk starts DHCPS at boot:
196-
// 1. `fw_has_started_softap_dhcps` is already initialized to 1
197-
// 2. global ctor DhcpServer's `dhcpSoftAP(&netif_git[SOFTAP_IF])` is called
198-
// 3. (that's here) => begin(legacy-values) is called
199-
ip_info ip = {
200-
{ 0x0104a8c0 }, // IP 192.168.4.1
201-
{ 0x00ffffff }, // netmask 255.255.255.0
202-
{ 0 } // gateway 0.0.0.0
203-
};
204-
begin(&ip);
205-
fw_has_started_softap_dhcps = 2; // not 1, ending initial boot sequence
206-
}
207-
};
178+
DhcpServer::DhcpServer(netif* netif) : _netif(netif) { }
208179

209180
// wifi_softap_set_station_info is missing in user_interface.h:
210181
extern "C" void wifi_softap_set_station_info(uint8_t* mac, struct ipv4_addr*);
@@ -516,7 +487,7 @@ void DhcpServer::create_msg(struct dhcps_msg* m)
516487
memset((char*)m->sname, 0, sizeof(m->sname));
517488
memset((char*)m->file, 0, sizeof(m->file));
518489
memset((char*)m->options, 0, sizeof(m->options));
519-
memcpy((char*)m->options, &magic_cookie, sizeof(magic_cookie));
490+
memcpy((char*)m->options, &MagicCookie, sizeof(MagicCookie));
520491
}
521492
///////////////////////////////////////////////////////////////////////////////////
522493
/*
@@ -821,7 +792,7 @@ uint8_t DhcpServer::parse_options(uint8_t* optptr, sint16_t len)
821792
///////////////////////////////////////////////////////////////////////////////////
822793
sint16_t DhcpServer::parse_msg(struct dhcps_msg* m, u16_t len)
823794
{
824-
if (memcmp((char*)m->options, &magic_cookie, sizeof(magic_cookie)) == 0)
795+
if (memcmp((char*)m->options, &MagicCookie, sizeof(MagicCookie)) == 0)
825796
{
826797
struct ipv4_addr ip;
827798
memcpy(&ip.addr, m->ciaddr, sizeof(ip.addr));
@@ -1008,17 +979,19 @@ void DhcpServer::init_dhcps_lease(uint32 ip)
1008979
}
1009980
///////////////////////////////////////////////////////////////////////////////////
1010981

1011-
bool DhcpServer::begin(struct ip_info* info)
982+
bool DhcpServer::begin()
1012983
{
1013984
if (pcb_dhcps != nullptr)
1014985
{
1015986
udp_remove(pcb_dhcps);
1016987
}
1017988

1018989
pcb_dhcps = udp_new();
1019-
if (pcb_dhcps == nullptr || info == nullptr)
990+
if (pcb_dhcps == nullptr)
1020991
{
992+
#if DHCPS_DEBUG
1021993
os_printf("dhcps_start(): could not obtain pcb\n");
994+
#endif
1022995
return false;
1023996
}
1024997

@@ -1030,7 +1003,7 @@ bool DhcpServer::begin(struct ip_info* info)
10301003
ip_2_ip4(&broadcast_dhcps)->addr |= ~ip_2_ip4(&_netif->netmask)->addr;
10311004
// XXXFIXMEIPV6 broadcast address?
10321005

1033-
server_address = info->ip;
1006+
server_address = *ip_2_ip4(&_netif->ip_addr);
10341007
init_dhcps_lease(server_address.addr);
10351008

10361009
udp_bind(pcb_dhcps, IP_ADDR_ANY, DHCPS_SERVER_PORT);
@@ -1040,12 +1013,6 @@ bool DhcpServer::begin(struct ip_info* info)
10401013
"pcb_dhcps\n");
10411014
#endif
10421015

1043-
if (_netif->num == SOFTAP_IF)
1044-
{
1045-
wifi_set_ip_info(SOFTAP_IF, info); // added for lwip-git, not sure whether useful
1046-
}
1047-
_netif->flags |= NETIF_FLAG_UP | NETIF_FLAG_LINK_UP; // added for lwip-git
1048-
10491016
return true;
10501017
}
10511018

@@ -1091,9 +1058,9 @@ void DhcpServer::end()
10911058
}
10921059
}
10931060

1094-
bool DhcpServer::isRunning()
1061+
bool DhcpServer::isRunning() const
10951062
{
1096-
return !!_netif->state;
1063+
return pcb_dhcps != nullptr;
10971064
}
10981065

10991066
/******************************************************************************
@@ -1342,7 +1309,7 @@ bool DhcpServer::reset_dhcps_lease_time(void)
13421309
{
13431310
return false;
13441311
}
1345-
dhcps_lease_time = DHCPS_LEASE_TIME_DEF;
1312+
dhcps_lease_time = DefaultLeaseTime;
13461313
return true;
13471314
}
13481315

cores/esp8266/LwipDhcpServer.h

+14-20
Original file line numberDiff line numberDiff line change
@@ -28,22 +28,24 @@
2828
// nearly as-is. This is an initial version to guaranty legacy behavior
2929
// with same default values.
3030

31-
#ifndef __DHCPS_H__
32-
#define __DHCPS_H__
31+
#pragma once
3332

3433
#include <lwip/init.h> // LWIP_VERSION
3534

3635
class DhcpServer
3736
{
3837
public:
39-
DhcpServer(netif* netif);
38+
static constexpr int DefaultLeaseTime = 720; // minutes
39+
static constexpr uint32 MagicCookie = 0x63538263; // https://tools.ietf.org/html/rfc1497
40+
41+
DhcpServer(netif*);
4042
~DhcpServer();
4143

4244
void setDns(int num, const ipv4_addr_t* dns);
4345

44-
bool begin(ip_info* info);
46+
bool begin();
4547
void end();
46-
bool isRunning();
48+
bool isRunning() const;
4749

4850
// this is the C interface encapsulated in a class
4951
// (originally dhcpserver.c in lwIP-v1.4 in NonOS-SDK)
@@ -91,25 +93,17 @@ class DhcpServer
9193
void dhcps_client_leave(u8* bssid, struct ipv4_addr* ip, bool force);
9294
uint32 dhcps_client_update(u8* bssid, struct ipv4_addr* ip);
9395

94-
netif* _netif;
96+
netif* _netif = nullptr;
9597

96-
struct udp_pcb* pcb_dhcps;
97-
ip_addr_t broadcast_dhcps;
98-
struct ipv4_addr server_address;
99-
struct ipv4_addr client_address;
100-
struct ipv4_addr dns_address;
101-
uint32 dhcps_lease_time;
98+
udp_pcb* pcb_dhcps = nullptr;
99+
ip_addr_t broadcast_dhcps {};
100+
ipv4_addr server_address {};
101+
ipv4_addr client_address {};
102+
ipv4_addr dns_address {};
103+
uint32 dhcps_lease_time = DefaultLeaseTime;
102104

103105
struct dhcps_lease dhcps_lease;
104106
list_node* plist;
105107
uint8 offer;
106108
bool renew;
107-
108-
static const uint32 magic_cookie;
109109
};
110-
111-
// SoftAP DHCP server always exists and is started on boot
112-
extern DhcpServer dhcpSoftAP;
113-
extern "C" int fw_has_started_softap_dhcps;
114-
115-
#endif // __DHCPS_H__

libraries/DNSServer/examples/NAPTCaptivePortal/NAPTCaptivePortal.ino

-1
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,6 @@
7474
#include <ESP8266WiFi.h>
7575
#include <lwip/napt.h>
7676
#include <lwip/dns.h>
77-
#include <dhcpserver.h>
7877
#include <WiFiClient.h>
7978
#include <ESP8266WebServer.h>
8079
#include <DNSServer.h>

libraries/ESP8266WiFi/examples/RangeExtender-NAPT/RangeExtender-NAPT.ino

+3-3
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
#include <ESP8266WiFi.h>
1414
#include <lwip/napt.h>
1515
#include <lwip/dns.h>
16-
#include <LwipDhcpServer.h>
1716

1817
#define NAPT 1000
1918
#define NAPT_PORT 10
@@ -54,8 +53,9 @@ void setup() {
5453
Serial.printf("\nSTA: %s (dns: %s / %s)\n", WiFi.localIP().toString().c_str(), WiFi.dnsIP(0).toString().c_str(), WiFi.dnsIP(1).toString().c_str());
5554

5655
// give DNS servers to AP side
57-
dhcpSoftAP.dhcps_set_dns(0, WiFi.dnsIP(0));
58-
dhcpSoftAP.dhcps_set_dns(1, WiFi.dnsIP(1));
56+
auto& server = WiFi.softAPDhcpServer();
57+
server.dhcps_set_dns(0, WiFi.dnsIP(0));
58+
server.dhcps_set_dns(1, WiFi.dnsIP(1));
5959

6060
WiFi.softAPConfig( // enable AP, with android-compatible google domain
6161
IPAddress(172, 217, 28, 254), IPAddress(172, 217, 28, 254), IPAddress(255, 255, 255, 0));

0 commit comments

Comments
 (0)