Skip to content

Commit e5d50a6

Browse files
authored
Split AddrList into object-iterator-container components (#5410)
* Split AddrList into object-iterator-container components * Update AddrList.h Remove gist code
1 parent 773f306 commit e5d50a6

File tree

2 files changed

+117
-89
lines changed

2 files changed

+117
-89
lines changed

cores/esp8266/AddrList.h

+106-78
Original file line numberDiff line numberDiff line change
@@ -21,15 +21,15 @@
2121
This class allows to explore all configured IP addresses
2222
in lwIP netifs, with that kind of c++ loop:
2323
24-
for (auto a: ifList)
24+
for (auto a: addrList)
2525
out.printf("IF='%s' index=%d legacy=%d IPv4=%d local=%d hostname='%s' addr= %s\n",
26-
a->iface().c_str(),
27-
a->number(),
28-
a->addr().isLegacy(),
29-
a->addr().isV4(),
30-
a->addr().isLocal(),
31-
a->hostname().c_str(),
32-
a->addr().toString().c_str());
26+
a.iface().c_str(),
27+
a.number(),
28+
a.addr().isLegacy(),
29+
a.addr().isV4(),
30+
a.addr().isLocal(),
31+
a.hostname().c_str(),
32+
a.addr().toString().c_str());
3333
3434
This loop:
3535
@@ -41,8 +41,8 @@
4141
can be replaced by:
4242
4343
for (bool configured = false; !configured; ) {
44-
for (auto iface: ifList)
45-
if ((configured = !iface->addr().isLocal())
44+
for (auto iface: addrList)
45+
if ((configured = !iface.addr().isLocal())
4646
break;
4747
Serial.print('.');
4848
delay(500);
@@ -51,9 +51,9 @@
5151
waiting for an IPv6 global address:
5252
5353
for (bool configured = false; !configured; ) {
54-
for (auto iface: ifList)
55-
if ((configured = ( !iface->addr()->isV4()
56-
&& !iface->addr().isLocal())))
54+
for (auto iface: addrList)
55+
if ((configured = ( !iface.addr().isV4()
56+
&& !iface.addr().isLocal())))
5757
break;
5858
Serial.print('.');
5959
delay(500);
@@ -62,10 +62,10 @@
6262
waiting for an IPv6 global address, on a specific interface:
6363
6464
for (bool configured = false; !configured; ) {
65-
for (auto iface: ifList)
66-
if ((configured = ( !iface->addr()->isV4()
67-
&& !iface->addr().isLocal()
68-
&& iface->number() == STATION_IF)))
65+
for (auto iface: addrList)
66+
if ((configured = ( !iface.addr().isV4()
67+
&& !iface.addr().isLocal()
68+
&& iface.number() == STATION_IF)))
6969
break;
7070
Serial.print('.');
7171
delay(500);
@@ -85,84 +85,112 @@
8585
#endif
8686

8787

88-
class AddrListClass {
88+
namespace esp8266
89+
{
8990

90-
// no member in this class
91-
// lwIP's global 'struct netif* netif_list' is used
92-
// designed to be used with 'for (auto x: ifList)'
91+
namespace AddressListImplementation
92+
{
9393

94-
public:
9594

96-
class const_iterator {
95+
struct netifWrapper
96+
{
97+
netifWrapper(netif * netif) : _netif(netif), _num(-1) {}
98+
netifWrapper(const netifWrapper & o) : _netif(o._netif), _num(o._num) {}
9799

98-
public:
100+
netifWrapper& operator=(const netifWrapper & o) {_netif = o._netif; _num = o._num; return *this;}
99101

100-
// iterator operations:
102+
bool equal (const netifWrapper & o)
103+
{
104+
return _netif == o._netif && (!_netif || _num == o._num);
105+
}
101106

102-
const_iterator (bool begin = true): _netif(begin? netif_list: nullptr), _num(-1) { ++*this; }
103-
const_iterator (const const_iterator& o): _netif(o._netif), _num(o._num) { }
104-
const_iterator& operator= (const const_iterator& o) { _netif = o._netif; _num = o._num; return *this; }
105107

106-
bool operator!= (const const_iterator& o) { return !equal(o); }
107-
bool operator== (const const_iterator& o) { return equal(o); }
108+
bool isLegacy() const { return _num == 0; }
109+
bool isLocal() const { return addr().isLocal(); }
110+
IPAddress addr () const { return ipFromNetifNum(); }
111+
IPAddress netmask () const { return _netif->netmask; }
112+
IPAddress gw () const { return _netif->gw; }
113+
String iface () const { return String(_netif->name[0]) + _netif->name[1]; }
114+
const char* hostname () const { return _netif->hostname?: emptyString.c_str(); }
115+
const char* mac () const { return (const char*)_netif->hwaddr; }
116+
int number () const { return _netif->num; }
108117

109-
const_iterator operator++(int) {
110-
const_iterator ret = *this;
111-
++(*this);
112-
return ret;
113-
}
118+
const ip_addr_t* ipFromNetifNum () const
119+
{
120+
#if LWIP_IPV6
121+
return _num ? &_netif->ip6_addr[_num - 1] : &_netif->ip_addr;
122+
#else
123+
return &_netif->ip_addr;
124+
#endif
125+
}
114126

115-
const_iterator& operator++() {
116-
while (_netif) {
117-
if (++_num == IF_NUM_ADDRESSES) {
118-
_num = -1;
119-
_netif = _netif->next;
120-
continue;
121-
}
122-
if (!ip_addr_isany(_ip_from_netif_num()))
123-
break;
124-
}
125-
return *this;
126-
}
127127

128-
// (*iterator) emulation:
128+
netif * _netif;
129+
int _num;
130+
};
129131

130-
const const_iterator& operator* () const { return *this; }
131-
const const_iterator* operator-> () const { return this; }
132132

133-
bool isLegacy() const { return _num == 0; }
134-
bool isLocal() const { return addr().isLocal(); }
135-
IPAddress addr () const { return _ip_from_netif_num(); }
136-
IPAddress netmask () const { return _netif->netmask; }
137-
IPAddress gw () const { return _netif->gw; }
138-
String iface () const { return String(_netif->name[0]) + _netif->name[1]; }
139-
const char* hostname () const { return _netif->hostname?: emptyString.c_str(); }
140-
const char* mac () const { return (const char*)_netif->hwaddr; }
141-
int number () const { return _netif->num; }
142133

143-
protected:
134+
class AddressListIterator
135+
{
136+
public:
137+
AddressListIterator(const netifWrapper &o) : netIf(o) {}
138+
AddressListIterator(netif * netif) : netIf(netif) {}
139+
140+
const netifWrapper& operator* () const {return netIf;}
141+
const netifWrapper* operator->() const {return &netIf;}
142+
143+
bool operator==(AddressListIterator & o) {return netIf.equal(*o);}
144+
bool operator!=(AddressListIterator & o) {return !netIf.equal(*o);}
145+
146+
AddressListIterator & operator= (const AddressListIterator& o) {netIf = o.netIf; return *this; }
147+
148+
AddressListIterator operator++(int)
149+
{
150+
AddressListIterator ret = *this;
151+
++(*this);
152+
return ret;
153+
}
154+
155+
AddressListIterator & operator++()
156+
{
157+
while (netIf._netif)
158+
{
159+
if (++netIf._num == IF_NUM_ADDRESSES)
160+
{
161+
netIf = netifWrapper(netIf._netif->next); //num is inited to -1
162+
continue;
163+
}
164+
if (!ip_addr_isany(netIf.ipFromNetifNum()))
165+
break;
166+
}
167+
return *this;
168+
}
169+
170+
netifWrapper netIf;
171+
};
144172

145-
bool equal (const const_iterator& o) {
146-
return _netif == o._netif
147-
&& (!_netif || _num == o._num);
148-
}
149173

150-
const ip_addr_t* _ip_from_netif_num () const {
151-
#if LWIP_IPV6
152-
return _num? &_netif->ip6_addr[_num - 1]: &_netif->ip_addr;
153-
#else
154-
return &_netif->ip_addr;
155-
#endif
156-
}
157174

158-
netif* _netif;
159-
int _num; // address index (0 is legacy, _num-1 is ip6_addr[]'s index)
160-
};
175+
class AddressList
176+
{
177+
public:
178+
using const_iterator = const AddressListIterator;
179+
180+
const_iterator begin() const {return const_iterator(netif_list);}
181+
const_iterator end() const {return const_iterator(nullptr);}
161182

162-
const const_iterator begin () const { return const_iterator(true); }
163-
const const_iterator end () const { return const_iterator(false); }
164183
};
165184

166-
extern AddrListClass addrList;
167185

168-
#endif // __ADDRLIST_H
186+
inline AddressList::const_iterator begin(const AddressList &a) {return a.begin();}
187+
inline AddressList::const_iterator end(const AddressList &a) {return a.end();}
188+
189+
} //AddressListImplementation
190+
191+
} //esp8266
192+
193+
extern esp8266::AddressListImplementation::AddressList addrList;
194+
195+
196+
#endif

libraries/esp8266/examples/IPv6/IPv6.ino

+11-11
Original file line numberDiff line numberDiff line change
@@ -66,16 +66,16 @@ void status(Print& out) {
6666
out.println(F("(with 'telnet <addr> or 'nc -u <addr> 23')"));
6767
for (auto a : addrList) {
6868
out.printf("IF='%s' IPv6=%d local=%d hostname='%s' addr= %s",
69-
a->iface().c_str(),
70-
!a->addr().isV4(),
71-
a->addr().isLocal(),
72-
a->hostname(),
73-
a->addr().toString().c_str());
69+
a.iface().c_str(),
70+
!a.addr().isV4(),
71+
a.addr().isLocal(),
72+
a.hostname(),
73+
a.addr().toString().c_str());
7474

75-
if (a->isLegacy()) {
75+
if (a.isLegacy()) {
7676
out.printf(" / mask:%s / gw:%s",
77-
a->netmask().toString().c_str(),
78-
a->gw().toString().c_str());
77+
a.netmask().toString().c_str(),
78+
a.gw().toString().c_str());
7979
}
8080

8181
out.println();
@@ -121,9 +121,9 @@ void setup() {
121121

122122
for (bool configured = false; !configured;) {
123123
for (auto addr : addrList)
124-
if ((configured = !addr->isLocal()
125-
// && addr->isV6() // uncomment when IPv6 is mandatory
126-
// && addr->ifnumber() == STATION_IF
124+
if ((configured = !addr.isLocal()
125+
// && addr.isV6() // uncomment when IPv6 is mandatory
126+
// && addr.ifnumber() == STATION_IF
127127
)) {
128128
break;
129129
}

0 commit comments

Comments
 (0)