Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mdns multi interface #2864

Merged
merged 2 commits into from
Jan 17, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
110 changes: 47 additions & 63 deletions libraries/ESP8266mDNS/ESP8266mDNS.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -146,43 +146,34 @@ MDNSResponder::~MDNSResponder() {
}
}

bool MDNSResponder::begin(const char* hostName){
return _begin(hostName, 0, 120);
}

bool MDNSResponder::begin(const char* hostName, IPAddress ip, uint32_t ttl){
return _begin(hostName, ip, ttl);
}

bool MDNSResponder::_begin(const char *hostName, uint32_t ip, uint32_t ttl){
size_t n = strlen(hostName);
bool MDNSResponder::begin(const char* hostname){
size_t n = strlen(hostname);
if (n > 63) { // max size for a single label.
return false;
}

_ip = ip;

// Copy in hostname characters as lowercase
_hostName = hostName;
_hostName = hostname;
_hostName.toLowerCase();

// If instance name is not already set copy hostname to instance name
if (_instanceName.equals("") ) _instanceName=hostName;
if (_instanceName.equals("") ) _instanceName=hostname;

//only if the IP hasn't been set manually, use the events
if (ip == 0) {
_gotIPHandler = WiFi.onStationModeGotIP([this](const WiFiEventStationModeGotIP& event){
_restart();
});
_gotIPHandler = WiFi.onStationModeGotIP([this](const WiFiEventStationModeGotIP& event){
_restart();
});

_disconnectedHandler = WiFi.onStationModeDisconnected([this](const WiFiEventStationModeDisconnected& event) {
_restart();
});
}
_disconnectedHandler = WiFi.onStationModeDisconnected([this](const WiFiEventStationModeDisconnected& event) {
_restart();
});

return _listen();
}

void MDNSResponder::notifyAPChange() {
_restart();
}

void MDNSResponder::_restart() {
if (_conn) {
_conn->unref();
Expand All @@ -194,23 +185,13 @@ void MDNSResponder::_restart() {
bool MDNSResponder::_listen() {
// Open the MDNS socket if it isn't already open.
if (!_conn) {
uint32_t ourIp = _getOurIp();
if(ourIp == 0){
#ifdef MDNS_DEBUG_RX
Serial.println("MDNS: no IP address to listen on");
#endif
return false;
}
#ifdef MDNS_DEBUG_RX
Serial.print("MDNS listening on IP: ");
Serial.println(IPAddress(ourIp));
Serial.println("MDNS listening");
#endif
ip_addr_t ifaddr;
ifaddr.addr = ourIp;
ip_addr_t multicast_addr;
multicast_addr.addr = (uint32_t) MDNS_MULTICAST_ADDR;

if (igmp_joingroup(&ifaddr, &multicast_addr)!= ERR_OK) {
if (igmp_joingroup(IP_ADDR_ANY, &multicast_addr)!= ERR_OK) {
return false;
}

Expand All @@ -220,7 +201,6 @@ bool MDNSResponder::_listen() {
if (!_conn->listen(*IP_ADDR_ANY, MDNS_PORT)) {
return false;
}
_conn->setMulticastInterface(ifaddr);
_conn->setMulticastTTL(MDNS_MULTICAST_TTL);
_conn->onRx(std::bind(&MDNSResponder::update, this));
_conn->connect(multicast_addr, MDNS_PORT);
Expand Down Expand Up @@ -457,28 +437,6 @@ uint16_t MDNSResponder::_getServicePort(char *name, char *proto){
return 0;
}

uint32_t MDNSResponder::_getOurIp(){
int mode = wifi_get_opmode();

//if has a manually set IP use this
if(_ip){
return _ip;
} else if(mode & STATION_MODE){
struct ip_info staIpInfo;
wifi_get_ip_info(STATION_IF, &staIpInfo);
return staIpInfo.ip.addr;
} else if (mode & SOFTAP_MODE) {
struct ip_info staIpInfo;
wifi_get_ip_info(SOFTAP_IF, &staIpInfo);
return staIpInfo.ip.addr;
} else {
#ifdef MDNS_DEBUG_ERR
Serial.printf("ERR_NO_LOCAL_IP\n");
#endif
return 0;
}
}

void MDNSResponder::_parsePacket(){
int i;
char tmp;
Expand Down Expand Up @@ -885,7 +843,20 @@ void MDNSResponder::_parsePacket(){
else if(questions[i] == MDNS_TYPE_PTR) responseMask |= 0xF;
}

return _reply(responseMask, serviceName, protoName, servicePort);
struct ip_info ip_info;
bool match_ap = false;
if (wifi_get_opmode() & SOFTAP_MODE) {
struct ip_info remote_ip_info;
remote_ip_info.ip.addr = _conn->getRemoteAddress();
wifi_get_ip_info(SOFTAP_IF, &ip_info);
if (ip_info.ip.addr && ip_addr_netcmp(&remote_ip_info.ip, &ip_info.ip, &ip_info.netmask))
match_ap = true;
}
if (!match_ap)
wifi_get_ip_info(STATION_IF, &ip_info);
uint32_t ip = ip_info.ip.addr;

return _reply(responseMask, serviceName, protoName, servicePort, ip);
}

void MDNSResponder::enableArduino(uint16_t port, bool auth){
Expand All @@ -899,17 +870,28 @@ void MDNSResponder::enableArduino(uint16_t port, bool auth){

size_t MDNSResponder::advertiseServices(){
MDNSService* servicePtr;
struct ip_info ip_info;
uint32_t ip;
size_t i = 0;
for (servicePtr = _services; servicePtr; servicePtr = servicePtr->_next) {
if(servicePtr->_port > 0){
_reply(0x0F, servicePtr->_name, servicePtr->_proto, servicePtr->_port);
wifi_get_ip_info(SOFTAP_IF, &ip_info);
ip = ip_info.ip.addr;
if (ip)
_reply(0x0F, servicePtr->_name, servicePtr->_proto, servicePtr->_port, ip);

wifi_get_ip_info(SOFTAP_IF, &ip_info);
ip = ip_info.ip.addr;
if (ip)
_reply(0x0F, servicePtr->_name, servicePtr->_proto, servicePtr->_port, ip);

i++;
}
}
return i;
}

void MDNSResponder::_reply(uint8_t replyMask, char * service, char *proto, uint16_t port){
void MDNSResponder::_reply(uint8_t replyMask, char * service, char *proto, uint16_t port, uint32_t ip) {
int i;
if(replyMask == 0) return;

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

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

_conn->send();
ip_addr_t ifaddr;
ifaddr.addr = ip;
_conn->setMulticastInterface(ifaddr);
_conn->send();
}

#if !defined(NO_GLOBAL_INSTANCES) && !defined(NO_GLOBAL_MDNS)
Expand Down
12 changes: 7 additions & 5 deletions libraries/ESP8266mDNS/ESP8266mDNS.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,11 @@ class MDNSResponder {
~MDNSResponder();
bool begin(const char* hostName);
//for compatibility
bool begin(const char* hostName, IPAddress ip, uint32_t ttl=120);
bool begin(const char* hostName, IPAddress ip, uint32_t ttl=120){
return begin(hostName);
}
/* Application should call this whenever AP is configured/disabled */
void notifyAPChange();
void update();

void addService(char *service, char *proto, uint16_t port);
Expand Down Expand Up @@ -114,15 +118,13 @@ class MDNSResponder {
bool _waitingForAnswers;
WiFiEventHandler _disconnectedHandler;
WiFiEventHandler _gotIPHandler;
uint32_t _ip;


bool _begin(const char* hostName, uint32_t ip, uint32_t ttl);
uint32_t _getOurIp();
uint16_t _getServicePort(char *service, char *proto);
MDNSTxt * _getServiceTxt(char *name, char *proto);
uint16_t _getServiceTxtLen(char *name, char *proto);
void _parsePacket();
void _reply(uint8_t replyMask, char * service, char *proto, uint16_t port);
void _reply(uint8_t replyMask, char * service, char *proto, uint16_t port, uint32_t ip);
size_t advertiseServices(); // advertise all hosted services
MDNSAnswer* _getAnswerFromIdx(int idx);
int _getNumAnswers();
Expand Down