|
21 | 21 | This class allows to explore all configured IP addresses
|
22 | 22 | in lwIP netifs, with that kind of c++ loop:
|
23 | 23 |
|
24 |
| - for (auto a: ifList) |
| 24 | + for (auto a: addrList) |
25 | 25 | 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()); |
33 | 33 |
|
34 | 34 | This loop:
|
35 | 35 |
|
|
41 | 41 | can be replaced by:
|
42 | 42 |
|
43 | 43 | 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()) |
46 | 46 | break;
|
47 | 47 | Serial.print('.');
|
48 | 48 | delay(500);
|
|
51 | 51 | waiting for an IPv6 global address:
|
52 | 52 |
|
53 | 53 | 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()))) |
57 | 57 | break;
|
58 | 58 | Serial.print('.');
|
59 | 59 | delay(500);
|
|
62 | 62 | waiting for an IPv6 global address, on a specific interface:
|
63 | 63 |
|
64 | 64 | 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))) |
69 | 69 | break;
|
70 | 70 | Serial.print('.');
|
71 | 71 | delay(500);
|
|
85 | 85 | #endif
|
86 | 86 |
|
87 | 87 |
|
88 |
| -class AddrListClass { |
| 88 | +namespace esp8266 |
| 89 | +{ |
89 | 90 |
|
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 | +{ |
93 | 93 |
|
94 |
| - public: |
95 | 94 |
|
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) {} |
97 | 99 |
|
98 |
| - public: |
| 100 | + netifWrapper& operator=(const netifWrapper & o) {_netif = o._netif; _num = o._num; return *this;} |
99 | 101 |
|
100 |
| - // iterator operations: |
| 102 | + bool equal (const netifWrapper & o) |
| 103 | + { |
| 104 | + return _netif == o._netif && (!_netif || _num == o._num); |
| 105 | + } |
101 | 106 |
|
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; } |
105 | 107 |
|
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; } |
108 | 117 |
|
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 | + } |
114 | 126 |
|
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 |
| - } |
127 | 127 |
|
128 |
| - // (*iterator) emulation: |
| 128 | + netif * _netif; |
| 129 | + int _num; |
| 130 | +}; |
129 | 131 |
|
130 |
| - const const_iterator& operator* () const { return *this; } |
131 |
| - const const_iterator* operator-> () const { return this; } |
132 | 132 |
|
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; } |
142 | 133 |
|
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 | +}; |
144 | 172 |
|
145 |
| - bool equal (const const_iterator& o) { |
146 |
| - return _netif == o._netif |
147 |
| - && (!_netif || _num == o._num); |
148 |
| - } |
149 | 173 |
|
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 |
| - } |
157 | 174 |
|
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);} |
161 | 182 |
|
162 |
| - const const_iterator begin () const { return const_iterator(true); } |
163 |
| - const const_iterator end () const { return const_iterator(false); } |
164 | 183 | };
|
165 | 184 |
|
166 |
| -extern AddrListClass addrList; |
167 | 185 |
|
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 |
0 commit comments