mirror of
https://github.com/esp8266/Arduino.git
synced 2025-07-07 06:01:35 +03:00
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
This commit is contained in:
@ -1,63 +1,95 @@
|
||||
/*
|
||||
lwIPDhcpServer-NonOS.cpp - DHCP server wrapper
|
||||
NonOS DHCP server helpers
|
||||
|
||||
Copyright (c) 2020 esp8266 arduino. All rights reserved.
|
||||
Copyright (c) 2020-2022 esp8266 arduino. All rights reserved.
|
||||
This file is part of the esp8266 core for Arduino environment.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
// STARTS/STOPS DHCP SERVER ON WIFI AP INTERFACE
|
||||
// these functions must exists as-is with "C" interface,
|
||||
// nonos-sdk calls them at boot time and later
|
||||
|
||||
#include <lwip/init.h> // LWIP_VERSION
|
||||
#include "LwipDhcpServer-NonOS.h"
|
||||
|
||||
#include <lwip/init.h>
|
||||
#include <lwip/netif.h>
|
||||
#include "LwipDhcpServer.h"
|
||||
|
||||
extern netif netif_git[2];
|
||||
|
||||
// global DHCP instance for softAP interface
|
||||
DhcpServer dhcpSoftAP(&netif_git[SOFTAP_IF]);
|
||||
// Global static DHCP instance for softAP interface
|
||||
// (since the netif object never goes away, even when AP is disabled)
|
||||
// Initial version fully emulates nonos-sdk api in DhcpServer class,
|
||||
// before trying to further change it and possibly break legacy behaviour
|
||||
DhcpServer& getNonOSDhcpServer()
|
||||
{
|
||||
extern netif netif_git[2];
|
||||
static DhcpServer server(&netif_git[SOFTAP_IF]);
|
||||
return server;
|
||||
}
|
||||
|
||||
extern "C"
|
||||
{
|
||||
void dhcps_start(struct ip_info* info, netif* apnetif)
|
||||
// `ip_info` is useless, since we get the information from the netif directly
|
||||
// `netif` would be netif_git[SOFTAP_IF], which we get from the lwip2 glue
|
||||
void dhcps_start(ip_info*, netif*)
|
||||
{
|
||||
// apnetif is esp interface, replaced by lwip2's
|
||||
// netif_git[SOFTAP_IF] interface in constructor
|
||||
(void)apnetif;
|
||||
|
||||
#if 0
|
||||
// can't use C++ now, global ctors are not initialized yet
|
||||
dhcpSoftAP.begin(info);
|
||||
#else
|
||||
(void)info;
|
||||
// initial version: emulate nonos-sdk in DhcpServer class before
|
||||
// trying to change legacy behavor
|
||||
// `fw_has_started_softap_dhcps` will be read in DhcpServer::DhcpServer
|
||||
// which is called when c++ ctors are initialized, specifically
|
||||
// dhcpSoftAP initialized with AP interface number above.
|
||||
fw_has_started_softap_dhcps = 1;
|
||||
#endif
|
||||
auto& server = getNonOSDhcpServer();
|
||||
if (!server.isRunning())
|
||||
{
|
||||
server.begin();
|
||||
}
|
||||
}
|
||||
|
||||
void dhcps_stop()
|
||||
{
|
||||
dhcpSoftAP.end();
|
||||
auto& server = getNonOSDhcpServer();
|
||||
if (server.isRunning())
|
||||
{
|
||||
server.end();
|
||||
}
|
||||
}
|
||||
|
||||
// providing the rest of the nonos-sdk API, which was originally removed in 3.0.0
|
||||
|
||||
bool wifi_softap_set_dhcps_lease(dhcps_lease* please)
|
||||
{
|
||||
auto& server = getNonOSDhcpServer();
|
||||
return server.set_dhcps_lease(please);
|
||||
}
|
||||
|
||||
bool wifi_softap_get_dhcps_lease(dhcps_lease* please)
|
||||
{
|
||||
auto& server = getNonOSDhcpServer();
|
||||
return server.get_dhcps_lease(please);
|
||||
}
|
||||
|
||||
uint32 wifi_softap_get_dhcps_lease_time()
|
||||
{
|
||||
auto& server = getNonOSDhcpServer();
|
||||
return server.get_dhcps_lease_time();
|
||||
}
|
||||
|
||||
bool wifi_softap_set_dhcps_lease_time(uint32 minutes)
|
||||
{
|
||||
auto& server = getNonOSDhcpServer();
|
||||
return server.set_dhcps_lease_time(minutes);
|
||||
}
|
||||
|
||||
bool wifi_softap_reset_dhcps_lease_time()
|
||||
{
|
||||
auto& server = getNonOSDhcpServer();
|
||||
return server.reset_dhcps_lease_time();
|
||||
}
|
||||
|
||||
bool wifi_softap_add_dhcps_lease(uint8* macaddr)
|
||||
{
|
||||
auto& server = getNonOSDhcpServer();
|
||||
return server.add_dhcps_lease(macaddr);
|
||||
}
|
||||
|
||||
} // extern "C"
|
||||
|
24
cores/esp8266/LwipDhcpServer-NonOS.h
Normal file
24
cores/esp8266/LwipDhcpServer-NonOS.h
Normal file
@ -0,0 +1,24 @@
|
||||
/*
|
||||
NonOS DHCP server helpers
|
||||
|
||||
Copyright (c) 2020-2022 esp8266 arduino. All rights reserved.
|
||||
This file is part of the esp8266 core for Arduino environment.
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "LwipDhcpServer.h"
|
||||
|
||||
// Global static DHCP instance for softAP interface
|
||||
DhcpServer& getNonOSDhcpServer();
|
@ -36,8 +36,6 @@
|
||||
|
||||
#include <lwip/init.h> // LWIP_VERSION
|
||||
|
||||
#define DHCPS_LEASE_TIME_DEF (120)
|
||||
|
||||
#define USE_DNS
|
||||
|
||||
#include "lwip/inet.h"
|
||||
@ -166,7 +164,7 @@ const char mem_debug_file[] ICACHE_RODATA_ATTR = __FILE__;
|
||||
int ret = 1, errval = (err); \
|
||||
if (errval != ERR_OK) \
|
||||
{ \
|
||||
os_printf("DHCPS ERROR: %s (lwip:%d)\n", what, errval); \
|
||||
os_printf("DHCPS ERROR: %s (lwip:%s(%d))\n", what, lwip_strerr(errval), errval); \
|
||||
ret = 0; \
|
||||
} \
|
||||
ret; \
|
||||
@ -175,36 +173,9 @@ const char mem_debug_file[] ICACHE_RODATA_ATTR = __FILE__;
|
||||
#define LWIP_IS_OK(what, err) ((err) == ERR_OK)
|
||||
#endif
|
||||
|
||||
const uint32 DhcpServer::magic_cookie = 0x63538263; // https://tools.ietf.org/html/rfc1497
|
||||
|
||||
int fw_has_started_softap_dhcps = 0;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
DhcpServer::DhcpServer(netif* netif) : _netif(netif)
|
||||
{
|
||||
pcb_dhcps = nullptr;
|
||||
dns_address.addr = 0;
|
||||
plist = nullptr;
|
||||
offer = 0xFF;
|
||||
renew = false;
|
||||
dhcps_lease_time = DHCPS_LEASE_TIME_DEF; // minute
|
||||
|
||||
if (netif->num == SOFTAP_IF && fw_has_started_softap_dhcps == 1)
|
||||
{
|
||||
// When nonos-sdk starts DHCPS at boot:
|
||||
// 1. `fw_has_started_softap_dhcps` is already initialized to 1
|
||||
// 2. global ctor DhcpServer's `dhcpSoftAP(&netif_git[SOFTAP_IF])` is called
|
||||
// 3. (that's here) => begin(legacy-values) is called
|
||||
ip_info ip = {
|
||||
{ 0x0104a8c0 }, // IP 192.168.4.1
|
||||
{ 0x00ffffff }, // netmask 255.255.255.0
|
||||
{ 0 } // gateway 0.0.0.0
|
||||
};
|
||||
begin(&ip);
|
||||
fw_has_started_softap_dhcps = 2; // not 1, ending initial boot sequence
|
||||
}
|
||||
};
|
||||
DhcpServer::DhcpServer(netif* netif) : _netif(netif) { }
|
||||
|
||||
// wifi_softap_set_station_info is missing in user_interface.h:
|
||||
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)
|
||||
memset((char*)m->sname, 0, sizeof(m->sname));
|
||||
memset((char*)m->file, 0, sizeof(m->file));
|
||||
memset((char*)m->options, 0, sizeof(m->options));
|
||||
memcpy((char*)m->options, &magic_cookie, sizeof(magic_cookie));
|
||||
memcpy((char*)m->options, &MagicCookie, sizeof(MagicCookie));
|
||||
}
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
/*
|
||||
@ -821,7 +792,7 @@ uint8_t DhcpServer::parse_options(uint8_t* optptr, sint16_t len)
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
sint16_t DhcpServer::parse_msg(struct dhcps_msg* m, u16_t len)
|
||||
{
|
||||
if (memcmp((char*)m->options, &magic_cookie, sizeof(magic_cookie)) == 0)
|
||||
if (memcmp((char*)m->options, &MagicCookie, sizeof(MagicCookie)) == 0)
|
||||
{
|
||||
struct ipv4_addr ip;
|
||||
memcpy(&ip.addr, m->ciaddr, sizeof(ip.addr));
|
||||
@ -1008,7 +979,7 @@ void DhcpServer::init_dhcps_lease(uint32 ip)
|
||||
}
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool DhcpServer::begin(struct ip_info* info)
|
||||
bool DhcpServer::begin()
|
||||
{
|
||||
if (pcb_dhcps != nullptr)
|
||||
{
|
||||
@ -1016,9 +987,11 @@ bool DhcpServer::begin(struct ip_info* info)
|
||||
}
|
||||
|
||||
pcb_dhcps = udp_new();
|
||||
if (pcb_dhcps == nullptr || info == nullptr)
|
||||
if (pcb_dhcps == nullptr)
|
||||
{
|
||||
#if DHCPS_DEBUG
|
||||
os_printf("dhcps_start(): could not obtain pcb\n");
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1030,7 +1003,7 @@ bool DhcpServer::begin(struct ip_info* info)
|
||||
ip_2_ip4(&broadcast_dhcps)->addr |= ~ip_2_ip4(&_netif->netmask)->addr;
|
||||
// XXXFIXMEIPV6 broadcast address?
|
||||
|
||||
server_address = info->ip;
|
||||
server_address = *ip_2_ip4(&_netif->ip_addr);
|
||||
init_dhcps_lease(server_address.addr);
|
||||
|
||||
udp_bind(pcb_dhcps, IP_ADDR_ANY, DHCPS_SERVER_PORT);
|
||||
@ -1040,12 +1013,6 @@ bool DhcpServer::begin(struct ip_info* info)
|
||||
"pcb_dhcps\n");
|
||||
#endif
|
||||
|
||||
if (_netif->num == SOFTAP_IF)
|
||||
{
|
||||
wifi_set_ip_info(SOFTAP_IF, info); // added for lwip-git, not sure whether useful
|
||||
}
|
||||
_netif->flags |= NETIF_FLAG_UP | NETIF_FLAG_LINK_UP; // added for lwip-git
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1091,9 +1058,9 @@ void DhcpServer::end()
|
||||
}
|
||||
}
|
||||
|
||||
bool DhcpServer::isRunning()
|
||||
bool DhcpServer::isRunning() const
|
||||
{
|
||||
return !!_netif->state;
|
||||
return pcb_dhcps != nullptr;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
@ -1342,7 +1309,7 @@ bool DhcpServer::reset_dhcps_lease_time(void)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
dhcps_lease_time = DHCPS_LEASE_TIME_DEF;
|
||||
dhcps_lease_time = DefaultLeaseTime;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -28,22 +28,24 @@
|
||||
// nearly as-is. This is an initial version to guaranty legacy behavior
|
||||
// with same default values.
|
||||
|
||||
#ifndef __DHCPS_H__
|
||||
#define __DHCPS_H__
|
||||
#pragma once
|
||||
|
||||
#include <lwip/init.h> // LWIP_VERSION
|
||||
|
||||
class DhcpServer
|
||||
{
|
||||
public:
|
||||
DhcpServer(netif* netif);
|
||||
static constexpr int DefaultLeaseTime = 720; // minutes
|
||||
static constexpr uint32 MagicCookie = 0x63538263; // https://tools.ietf.org/html/rfc1497
|
||||
|
||||
DhcpServer(netif*);
|
||||
~DhcpServer();
|
||||
|
||||
void setDns(int num, const ipv4_addr_t* dns);
|
||||
|
||||
bool begin(ip_info* info);
|
||||
bool begin();
|
||||
void end();
|
||||
bool isRunning();
|
||||
bool isRunning() const;
|
||||
|
||||
// this is the C interface encapsulated in a class
|
||||
// (originally dhcpserver.c in lwIP-v1.4 in NonOS-SDK)
|
||||
@ -91,25 +93,17 @@ protected:
|
||||
void dhcps_client_leave(u8* bssid, struct ipv4_addr* ip, bool force);
|
||||
uint32 dhcps_client_update(u8* bssid, struct ipv4_addr* ip);
|
||||
|
||||
netif* _netif;
|
||||
netif* _netif = nullptr;
|
||||
|
||||
struct udp_pcb* pcb_dhcps;
|
||||
ip_addr_t broadcast_dhcps;
|
||||
struct ipv4_addr server_address;
|
||||
struct ipv4_addr client_address;
|
||||
struct ipv4_addr dns_address;
|
||||
uint32 dhcps_lease_time;
|
||||
udp_pcb* pcb_dhcps = nullptr;
|
||||
ip_addr_t broadcast_dhcps {};
|
||||
ipv4_addr server_address {};
|
||||
ipv4_addr client_address {};
|
||||
ipv4_addr dns_address {};
|
||||
uint32 dhcps_lease_time = DefaultLeaseTime;
|
||||
|
||||
struct dhcps_lease dhcps_lease;
|
||||
list_node* plist;
|
||||
uint8 offer;
|
||||
bool renew;
|
||||
|
||||
static const uint32 magic_cookie;
|
||||
};
|
||||
|
||||
// SoftAP DHCP server always exists and is started on boot
|
||||
extern DhcpServer dhcpSoftAP;
|
||||
extern "C" int fw_has_started_softap_dhcps;
|
||||
|
||||
#endif // __DHCPS_H__
|
||||
|
Reference in New Issue
Block a user