Skip to content

Commit a546d64

Browse files
swarrenigrr
authored andcommitted
ESP8266mDNS: support AP and STA interfaces at once
Bind the UDP connection to IP_ADDR_ANY rather than a specific interface IP, so that it can receive queries from all interfaces at once. When processing a query, detect which interface it was received on, and pass this information to the reply code. Set the IP multicast interface before each transmission, so that we can route each packet to a different interface if required. These changes enable the code to respond correctly on both AP and STA interfaces at once. The original code only worked correctly for the STA interface if both were enabled. When advertizing all services, do it on both AP and STA interfaces if they're both enabled. Provide an API for the application to notify the MDNS code if the AP configuration changes (enabled, disabled, IP changed). Ideally, the WiFi core would provide an event callback for this purpose, as it does for STA changes, but it does not appear to, so the application must provide this information.
1 parent eb1ac10 commit a546d64

File tree

2 files changed

+40
-38
lines changed

2 files changed

+40
-38
lines changed

libraries/ESP8266mDNS/ESP8266mDNS.cpp

Lines changed: 37 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,10 @@ bool MDNSResponder::begin(const char* hostname){
170170
return _listen();
171171
}
172172

173+
void MDNSResponder::notifyAPChange() {
174+
_restart();
175+
}
176+
173177
void MDNSResponder::_restart() {
174178
if (_conn) {
175179
_conn->unref();
@@ -181,23 +185,13 @@ void MDNSResponder::_restart() {
181185
bool MDNSResponder::_listen() {
182186
// Open the MDNS socket if it isn't already open.
183187
if (!_conn) {
184-
uint32_t ourIp = _getOurIp();
185-
if(ourIp == 0){
186-
#ifdef MDNS_DEBUG_RX
187-
Serial.println("MDNS: no IP address to listen on");
188-
#endif
189-
return false;
190-
}
191188
#ifdef MDNS_DEBUG_RX
192-
Serial.print("MDNS listening on IP: ");
193-
Serial.println(IPAddress(ourIp));
189+
Serial.println("MDNS listening");
194190
#endif
195-
ip_addr_t ifaddr;
196-
ifaddr.addr = ourIp;
197191
ip_addr_t multicast_addr;
198192
multicast_addr.addr = (uint32_t) MDNS_MULTICAST_ADDR;
199193

200-
if (igmp_joingroup(&ifaddr, &multicast_addr)!= ERR_OK) {
194+
if (igmp_joingroup(IP_ADDR_ANY, &multicast_addr)!= ERR_OK) {
201195
return false;
202196
}
203197

@@ -207,7 +201,6 @@ bool MDNSResponder::_listen() {
207201
if (!_conn->listen(*IP_ADDR_ANY, MDNS_PORT)) {
208202
return false;
209203
}
210-
_conn->setMulticastInterface(ifaddr);
211204
_conn->setMulticastTTL(MDNS_MULTICAST_TTL);
212205
_conn->onRx(std::bind(&MDNSResponder::update, this));
213206
_conn->connect(multicast_addr, MDNS_PORT);
@@ -444,24 +437,6 @@ uint16_t MDNSResponder::_getServicePort(char *name, char *proto){
444437
return 0;
445438
}
446439

447-
uint32_t MDNSResponder::_getOurIp(){
448-
int mode = wifi_get_opmode();
449-
if(mode & STATION_MODE){
450-
struct ip_info staIpInfo;
451-
wifi_get_ip_info(STATION_IF, &staIpInfo);
452-
return staIpInfo.ip.addr;
453-
} else if (mode & SOFTAP_MODE) {
454-
struct ip_info staIpInfo;
455-
wifi_get_ip_info(SOFTAP_IF, &staIpInfo);
456-
return staIpInfo.ip.addr;
457-
} else {
458-
#ifdef MDNS_DEBUG_ERR
459-
Serial.printf("ERR_NO_LOCAL_IP\n");
460-
#endif
461-
return 0;
462-
}
463-
}
464-
465440
void MDNSResponder::_parsePacket(){
466441
int i;
467442
char tmp;
@@ -868,7 +843,20 @@ void MDNSResponder::_parsePacket(){
868843
else if(questions[i] == MDNS_TYPE_PTR) responseMask |= 0xF;
869844
}
870845

871-
return _reply(responseMask, serviceName, protoName, servicePort);
846+
struct ip_info ip_info;
847+
bool match_ap = false;
848+
if (wifi_get_opmode() & SOFTAP_MODE) {
849+
struct ip_info remote_ip_info;
850+
remote_ip_info.ip.addr = _conn->getRemoteAddress();
851+
wifi_get_ip_info(SOFTAP_IF, &ip_info);
852+
if (ip_info.ip.addr && ip_addr_netcmp(&remote_ip_info.ip, &ip_info.ip, &ip_info.netmask))
853+
match_ap = true;
854+
}
855+
if (!match_ap)
856+
wifi_get_ip_info(STATION_IF, &ip_info);
857+
uint32_t ip = ip_info.ip.addr;
858+
859+
return _reply(responseMask, serviceName, protoName, servicePort, ip);
872860
}
873861

874862
void MDNSResponder::enableArduino(uint16_t port, bool auth){
@@ -882,17 +870,28 @@ void MDNSResponder::enableArduino(uint16_t port, bool auth){
882870

883871
size_t MDNSResponder::advertiseServices(){
884872
MDNSService* servicePtr;
873+
struct ip_info ip_info;
874+
uint32_t ip;
885875
size_t i = 0;
886876
for (servicePtr = _services; servicePtr; servicePtr = servicePtr->_next) {
887877
if(servicePtr->_port > 0){
888-
_reply(0x0F, servicePtr->_name, servicePtr->_proto, servicePtr->_port);
878+
wifi_get_ip_info(SOFTAP_IF, &ip_info);
879+
ip = ip_info.ip.addr;
880+
if (ip)
881+
_reply(0x0F, servicePtr->_name, servicePtr->_proto, servicePtr->_port, ip);
882+
883+
wifi_get_ip_info(SOFTAP_IF, &ip_info);
884+
ip = ip_info.ip.addr;
885+
if (ip)
886+
_reply(0x0F, servicePtr->_name, servicePtr->_proto, servicePtr->_port, ip);
887+
889888
i++;
890889
}
891890
}
892891
return i;
893892
}
894893

895-
void MDNSResponder::_reply(uint8_t replyMask, char * service, char *proto, uint16_t port){
894+
void MDNSResponder::_reply(uint8_t replyMask, char * service, char *proto, uint16_t port, uint32_t ip) {
896895
int i;
897896
if(replyMask == 0) return;
898897

@@ -1062,7 +1061,6 @@ void MDNSResponder::_reply(uint8_t replyMask, char * service, char *proto, uint1
10621061
_conn->append(reinterpret_cast<const char*>(localName), localNameLen); // "local"
10631062
_conn->append(reinterpret_cast<const char*>(&terminator), 1); // terminator
10641063

1065-
uint32_t ip = _getOurIp();
10661064
uint8_t aaaAttrs[10] = {
10671065
0x00, 0x01, //TYPE A
10681066
0x80, 0x01, //Class IN, with cache flush
@@ -1081,7 +1079,10 @@ void MDNSResponder::_reply(uint8_t replyMask, char * service, char *proto, uint1
10811079
_conn->append(reinterpret_cast<const char*>(aaaRData), 4);
10821080
}
10831081

1084-
_conn->send();
1082+
ip_addr_t ifaddr;
1083+
ifaddr.addr = ip;
1084+
_conn->setMulticastInterface(ifaddr);
1085+
_conn->send();
10851086
}
10861087

10871088
#if !defined(NO_GLOBAL_INSTANCES) && !defined(NO_GLOBAL_MDNS)

libraries/ESP8266mDNS/ESP8266mDNS.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,8 @@ class MDNSResponder {
6666
bool begin(const char* hostName, IPAddress ip, uint32_t ttl=120){
6767
return begin(hostName);
6868
}
69+
/* Application should call this whenever AP is configured/disabled */
70+
void notifyAPChange();
6971
void update();
7072

7173
void addService(char *service, char *proto, uint16_t port);
@@ -118,12 +120,11 @@ class MDNSResponder {
118120
WiFiEventHandler _gotIPHandler;
119121

120122

121-
uint32_t _getOurIp();
122123
uint16_t _getServicePort(char *service, char *proto);
123124
MDNSTxt * _getServiceTxt(char *name, char *proto);
124125
uint16_t _getServiceTxtLen(char *name, char *proto);
125126
void _parsePacket();
126-
void _reply(uint8_t replyMask, char * service, char *proto, uint16_t port);
127+
void _reply(uint8_t replyMask, char * service, char *proto, uint16_t port, uint32_t ip);
127128
size_t advertiseServices(); // advertise all hosted services
128129
MDNSAnswer* _getAnswerFromIdx(int idx);
129130
int _getNumAnswers();

0 commit comments

Comments
 (0)