From d45294efffb51e3a79930a61eff2f399933e7349 Mon Sep 17 00:00:00 2001 From: Eric Wilkison Date: Tue, 15 Dec 2015 05:07:57 -0800 Subject: [PATCH 1/8] fix invalid packets, removes compression --- libraries/ESP8266mDNS/ESP8266mDNS.cpp | 262 ++++++++++++++------------ 1 file changed, 141 insertions(+), 121 deletions(-) diff --git a/libraries/ESP8266mDNS/ESP8266mDNS.cpp b/libraries/ESP8266mDNS/ESP8266mDNS.cpp index e11bae5b0..56c07870e 100644 --- a/libraries/ESP8266mDNS/ESP8266mDNS.cpp +++ b/libraries/ESP8266mDNS/ESP8266mDNS.cpp @@ -380,17 +380,40 @@ void MDNSResponder::_reply(uint8_t replyMask, char * service, char *proto, uint1 if(replyMask == 0) return; #ifdef MDNS_DEBUG_TX - os_printf("TX: mask:%01X, service:%s, proto:%s, port:%u\n", replyMask, service, proto, port); + Serial.printf("TX: mask:%01X, service:%s, proto:%s, port:%u\n", replyMask, service, proto, port); #endif - char nameLen = os_strlen(_hostName); - size_t serviceLen = os_strlen(service); + char * hostName = _hostName; + size_t hostNameLen = os_strlen(hostName); + + char underscore[] = "_"; + + // build service name with _ + char serviceName[os_strlen(service)+2]; + os_strcpy(serviceName,underscore); + os_strcat(serviceName, service); + size_t serviceNameLen = os_strlen(serviceName); + + //build proto name with _ + char protoName[5]; + os_strcpy(protoName,underscore); + os_strcat(protoName, proto); + size_t protoNameLen = 4; + + //local string + char localName[] = "local"; + size_t localNameLen = 5; + + //terminator + char terminator[] = "\0"; uint8_t answerCount = 0; for(i=0;i<4;i++){ if(replyMask & (1 << i)) answerCount++; } + + //Write the header _conn->flush(); uint8_t head[12] = { 0x00, 0x00, //ID = 0 @@ -402,139 +425,136 @@ void MDNSResponder::_reply(uint8_t replyMask, char * service, char *proto, uint1 }; _conn->append(reinterpret_cast(head), 12); - if((replyMask & 0x8) == 0){ - _conn->append(reinterpret_cast(&nameLen), 1); - _conn->append(reinterpret_cast(_hostName), nameLen); - } - - if(replyMask & 0xE){ - uint8_t servHead[2] = {(uint8_t)(serviceLen+1), '_'}; - uint8_t protoHead[2] = {0x4, '_'}; - _conn->append(reinterpret_cast(servHead), 2); - _conn->append(reinterpret_cast(service), serviceLen); - _conn->append(reinterpret_cast(protoHead), 2); - _conn->append(reinterpret_cast(proto), 3); - } - - uint8_t local[7] = { - 0x05, //strlen(_local) - 0x6C, 0x6F, 0x63, 0x61, 0x6C, //local - 0x00, //End of domain - }; - _conn->append(reinterpret_cast(local), 7); - // PTR Response if(replyMask & 0x8){ - uint8_t ptr[10] = { - 0x00, 0x0c, //PTR record query - 0x00, 0x01, //Class IN - 0x00, 0x00, 0x11, 0x94, //TTL 4500 - 0x00, (uint8_t)(3 + nameLen), //***DATA LEN (3 + strlen(host)) - }; - _conn->append(reinterpret_cast(ptr), 10); - _conn->append(reinterpret_cast(&nameLen), 1); - _conn->append(reinterpret_cast(_hostName), nameLen); - uint8_t ptrTail[2] = {0xC0, 0x0C}; - _conn->append(reinterpret_cast(ptrTail), 2); - } - - // TXT Response - if(replyMask & 0x4){ - if(replyMask & 0x8){ - uint8_t txtHead[10] = { - 0xC0, (uint8_t)(36 + serviceLen),//send the name - 0x00, 0x10, //Type TXT - 0x80, 0x01, //Class IN, with cache flush - 0x00, 0x00, 0x11, 0x94, //TTL 4500 - }; - _conn->append(reinterpret_cast(txtHead), 10); - } - - if(strcmp(reinterpret_cast("arduino"), service) == 0){ - //arduino - //arduino service dependance should be removed and properties abstracted - const char *tcpCheckExtra = "tcp_check=no"; - uint8_t tcpCheckExtraLen = os_strlen(tcpCheckExtra); - - const char *sshUploadExtra = "ssh_upload=no"; - uint8_t sshUploadExtraLen = os_strlen(sshUploadExtra); - - char boardName[64]; - const char *boardExtra = "board="; - os_sprintf(boardName, "%s%s", boardExtra, ARDUINO_BOARD); - uint8_t boardNameLen = os_strlen(boardName); - - char authUpload[16]; - const char *authUploadExtra = "auth_upload="; - os_sprintf(authUpload, "%s%s", authUploadExtra, reinterpret_cast((_arduinoAuth)?"yes":"no")); - uint8_t authUploadLen = os_strlen(authUpload); + // Send the Name field (ie. "_http._tcp.local") + _conn->append(reinterpret_cast(&serviceNameLen), 1); // lenght of "_http" + _conn->append(reinterpret_cast(serviceName), serviceNameLen); // "_http" + _conn->append(reinterpret_cast(&protoNameLen), 1); // lenght of "_tcp" + _conn->append(reinterpret_cast(protoName), protoNameLen); // "_tcp" + _conn->append(reinterpret_cast(&localNameLen), 1); // lenght "local" + _conn->append(reinterpret_cast(localName), localNameLen); // "local" + _conn->append(reinterpret_cast(&terminator), 1); // terminator - uint16_t textDataLen = (1 + boardNameLen) + (1 + tcpCheckExtraLen) + (1 + sshUploadExtraLen) + (1 + authUploadLen); - uint8_t txt[2] = {(uint8_t)(textDataLen >> 8), (uint8_t)(textDataLen)}; //DATA LEN - _conn->append(reinterpret_cast(txt), 2); - - _conn->append(reinterpret_cast(&boardNameLen), 1); - _conn->append(reinterpret_cast(boardName), boardNameLen); - _conn->append(reinterpret_cast(&authUploadLen), 1); - _conn->append(reinterpret_cast(authUpload), authUploadLen); - _conn->append(reinterpret_cast(&tcpCheckExtraLen), 1); - _conn->append(reinterpret_cast(tcpCheckExtra), tcpCheckExtraLen); - _conn->append(reinterpret_cast(&sshUploadExtraLen), 1); - _conn->append(reinterpret_cast(sshUploadExtra), sshUploadExtraLen); - } else { - //not arduino - //we should figure out an API so TXT properties can be added for services - uint8_t txt[2] = {0,0}; - _conn->append(reinterpret_cast(txt), 2); - } + //Send the type, class, ttl and rdata length + uint8_t ptrDataLen = hostNameLen + serviceNameLen + protoNameLen + localNameLen + 5; // 5 is four label sizes and the terminator + uint8_t ptrAttrs[10] = { + 0x00, 0x0c, //PTR record query + 0x00, 0x01, //Class IN + 0x00, 0x00, 0x11, 0x94, //TTL 4500 + 0x00, ptrDataLen, //RData length + }; + _conn->append(reinterpret_cast(ptrAttrs), 10); + + //Send the RData (ie. "esp8266._http._tcp.local") + _conn->append(reinterpret_cast(&hostNameLen), 1); // lenght of "esp8266" + _conn->append(reinterpret_cast(hostName), hostNameLen); // "esp8266" + _conn->append(reinterpret_cast(&serviceNameLen), 1); // lenght of "_http" + _conn->append(reinterpret_cast(serviceName), serviceNameLen); // "_http" + _conn->append(reinterpret_cast(&protoNameLen), 1); // lenght of "_tcp" + _conn->append(reinterpret_cast(protoName), protoNameLen); // "_tcp" + _conn->append(reinterpret_cast(&localNameLen), 1); // lenght "local" + _conn->append(reinterpret_cast(localName), localNameLen); // "local" + _conn->append(reinterpret_cast(&terminator), 1); // terminator } - // SRV Response - if(replyMask & 0x2){ - if(replyMask & 0xC){//send the name - uint8_t srvHead[2] = {0xC0, 0x0C}; - if(replyMask & 0x8) - srvHead[1] = 36 + serviceLen; - _conn->append(reinterpret_cast(srvHead), 2); - } + //TXT Responce + if(replyMask & 0x4){ + //Send the name field (ie. "esp8266._http._tcp.local") + _conn->append(reinterpret_cast(&hostNameLen), 1); // lenght of "esp8266" + _conn->append(reinterpret_cast(hostName), hostNameLen); // "esp8266" + _conn->append(reinterpret_cast(&serviceNameLen), 1); // lenght of "_http" + _conn->append(reinterpret_cast(serviceName), serviceNameLen); // "_http" + _conn->append(reinterpret_cast(&protoNameLen), 1); // lenght of "_tcp" + _conn->append(reinterpret_cast(protoName), protoNameLen); // "_tcp" + _conn->append(reinterpret_cast(&localNameLen), 1); // lenght "local" + _conn->append(reinterpret_cast(localName), localNameLen); // "local" + _conn->append(reinterpret_cast(&terminator), 1); // terminator - uint8_t srv[16] = { - 0x00, 0x21, //Type SRV - 0x80, 0x01, //Class IN, with cache flush - 0x00, 0x00, 0x00, 0x78, //TTL 120 - 0x00, (uint8_t)(9 + nameLen), //DATA LEN (9 + strlen(host)) - 0x00, 0x00, //Priority 0 - 0x00, 0x00, //Weight 0 - (uint8_t)((port >> 8) & 0xFF), (uint8_t)(port & 0xFF) + //Send the type, class, ttl and rdata length + uint8_t txtDataLen = 0; + uint8_t txtAttrs[10] = { + 0x00, 0x10, //TXT record query + 0x00, 0x01, //Class IN + 0x00, 0x00, 0x11, 0x94, //TTL 4500 + 0x00, txtDataLen, //RData length }; - _conn->append(reinterpret_cast(srv), 16); - _conn->append(reinterpret_cast(&nameLen), 1); - _conn->append(reinterpret_cast(_hostName), nameLen); - uint8_t srvTail[2] = {0xC0, (uint8_t)(20 + serviceLen + nameLen)}; - if(replyMask & 0x8) - srvTail[1] = 19 + serviceLen; - _conn->append(reinterpret_cast(srvTail), 2); + _conn->append(reinterpret_cast(txtAttrs), 10); + + //Send the RData + //TODO - Build TXT Redords + } + + + //SRV Responce + if(replyMask & 0x2){ + //Send the name field (ie. "esp8266._http._tcp.local") + _conn->append(reinterpret_cast(&hostNameLen), 1); // lenght of "esp8266" + _conn->append(reinterpret_cast(hostName), hostNameLen); // "esp8266" + _conn->append(reinterpret_cast(&serviceNameLen), 1); // lenght of "_http" + _conn->append(reinterpret_cast(serviceName), serviceNameLen); // "_http" + _conn->append(reinterpret_cast(&protoNameLen), 1); // lenght of "_tcp" + _conn->append(reinterpret_cast(protoName), protoNameLen); // "_tcp" + _conn->append(reinterpret_cast(&localNameLen), 1); // lenght "local" + _conn->append(reinterpret_cast(localName), localNameLen); // "local" + _conn->append(reinterpret_cast(&terminator), 1); // terminator + + //Send the type, class, ttl, rdata length, priority and weight + uint8_t srvDataSize = hostNameLen + localNameLen + 3; // 3 is 2 lable size bytes and the terminator + srvDataSize += 6; // Size of Priority, weight and port + uint8_t srvAttrs[10] = { + 0x00, 0x21, //Type SRV + 0x80, 0x01, //Class IN, with cache flush + 0x00, 0x00, 0x00, 0x78, //TTL 120 + 0x00, srvDataSize, //RData length + }; + _conn->append(reinterpret_cast(srvAttrs), 10); + + //Send the RData Priority weight and port + uint8_t srvRData[6] = { + 0x00, 0x00, //Priority 0 + 0x00, 0x00, //Weight 0 + (uint8_t)((port >> 8) & 0xFF), (uint8_t)(port & 0xFF) + }; + _conn->append(reinterpret_cast(srvRData), 6); + //Send the RData (ie. "esp8266.local") + _conn->append(reinterpret_cast(&hostNameLen), 1); // lenght of "esp8266" + _conn->append(reinterpret_cast(hostName), hostNameLen); // "esp8266" + _conn->append(reinterpret_cast(&localNameLen), 1); // lenght "local" + _conn->append(reinterpret_cast(localName), localNameLen); // "local" + _conn->append(reinterpret_cast(&terminator), 1); // terminator + } // A Response if(replyMask & 0x1){ - uint32_t ip = _getOurIp(); - if(replyMask & 0x2){//send the name (no compression for now) - _conn->append(reinterpret_cast(&nameLen), 1); - _conn->append(reinterpret_cast(_hostName), nameLen); - _conn->append(reinterpret_cast(local), 7); - } + //Send the RData (ie. "esp8266.local") + _conn->append(reinterpret_cast(&hostNameLen), 1); // lenght of "esp8266" + _conn->append(reinterpret_cast(hostName), hostNameLen); // "esp8266" + _conn->append(reinterpret_cast(&localNameLen), 1); // lenght "local" + _conn->append(reinterpret_cast(localName), localNameLen); // "local" + _conn->append(reinterpret_cast(&terminator), 1); // terminator - uint8_t aaa[14] = { - 0x00, 0x01, //TYPE A - 0x80, 0x01, //Class IN, with cache flush + uint32_t ip = _getOurIp(); + uint8_t aaaAttrs[10] = { + 0x00, 0x01, //TYPE A + 0x80, 0x01, //Class IN, with cache flush 0x00, 0x00, 0x00, 0x78, //TTL 120 - 0x00, 0x04, //DATA LEN - (uint8_t)(ip & 0xFF), (uint8_t)((ip >> 8) & 0xFF), (uint8_t)((ip >> 16) & 0xFF), (uint8_t)((ip >> 24) & 0xFF) + 0x00, 0x04, //DATA LEN }; - _conn->append(reinterpret_cast(aaa), 14); + _conn->append(reinterpret_cast(aaaAttrs), 10); + + // Send RData + uint8_t aaaRData[4] = { + (uint8_t)(ip & 0xFF), //IP first octet + (uint8_t)((ip >> 8) & 0xFF), //IP second octet + (uint8_t)((ip >> 16) & 0xFF), //IP third octet + (uint8_t)((ip >> 24) & 0xFF) //IP fourth octet + }; + _conn->append(reinterpret_cast(aaaRData), 4); } - _conn->send(); + + _conn->send(); } MDNSResponder MDNS = MDNSResponder(); From f34f84be74cca90c24c17e62f96f85d8a0b72c85 Mon Sep 17 00:00:00 2001 From: Eric Wilkison Date: Tue, 15 Dec 2015 05:17:53 -0800 Subject: [PATCH 2/8] Fix add multiple services --- libraries/ESP8266mDNS/ESP8266mDNS.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/libraries/ESP8266mDNS/ESP8266mDNS.cpp b/libraries/ESP8266mDNS/ESP8266mDNS.cpp index 56c07870e..dbbda90a3 100644 --- a/libraries/ESP8266mDNS/ESP8266mDNS.cpp +++ b/libraries/ESP8266mDNS/ESP8266mDNS.cpp @@ -146,8 +146,13 @@ void MDNSResponder::addService(char *name, char *proto, uint16_t port){ os_strcpy(srv->_proto, proto); srv->_port = port; srv->_next = 0; - if(_services) _services->_next = srv; - else _services = srv; + + if(_services == 0) _services = srv; + else{ + MDNSService* servicePtr = _services; + while(servicePtr->_next !=0) servicePtr = servicePtr->_next; + servicePtr->_next = srv; + } } uint16_t MDNSResponder::_getServicePort(char *name, char *proto){ From 758107f35dc6b19547938e87a3a02804b38f9a8f Mon Sep 17 00:00:00 2001 From: Eric Wilkison Date: Tue, 15 Dec 2015 05:39:49 -0800 Subject: [PATCH 3/8] Add TXT support --- libraries/ESP8266mDNS/ESP8266mDNS.cpp | 170 +++++++++++++++++++++----- libraries/ESP8266mDNS/ESP8266mDNS.h | 20 ++- 2 files changed, 159 insertions(+), 31 deletions(-) diff --git a/libraries/ESP8266mDNS/ESP8266mDNS.cpp b/libraries/ESP8266mDNS/ESP8266mDNS.cpp index dbbda90a3..5150792dd 100644 --- a/libraries/ESP8266mDNS/ESP8266mDNS.cpp +++ b/libraries/ESP8266mDNS/ESP8266mDNS.cpp @@ -85,7 +85,7 @@ static const IPAddress MDNS_MULTICAST_ADDR(224, 0, 0, 251); static const int MDNS_MULTICAST_TTL = 1; static const int MDNS_PORT = 5353; -MDNSResponder::MDNSResponder() : _conn(0) { _services = 0; _arduinoAuth = false; } +MDNSResponder::MDNSResponder() : _conn(0) { _services = 0; } MDNSResponder::~MDNSResponder() {} bool MDNSResponder::begin(const char* domain){ @@ -138,6 +138,58 @@ void MDNSResponder::update() { _parsePacket(); } + + + + + + + +bool MDNSResponder::addServiceTxt(char *name, char *proto, char *txt){ + MDNSService* servicePtr; + + //DEBUG Serial.printf("Starting addServiceTxt(name=%s,proto=%s,txt=%s)\n", name,proto,txt); + //DEBUG delay(20); + uint8_t txtLen = os_strlen(txt) + 1; //One accounts for length byte added when building the txt responce + if ( txtLen > 128) return false; + //Find the service + for (servicePtr = _services; servicePtr; servicePtr = servicePtr->_next) { + //DEBUG Serial.printf("Checking service name=%s,proto=%s\n", servicePtr->_name,servicePtr->_proto); + //DEBUG delay(20); + if(strcmp(servicePtr->_name, name) == 0 && strcmp(servicePtr->_proto, proto) == 0){ + if (servicePtr->_txtLen + txtLen > 1300) return false; //max txt record size + //DEBUG Serial.printf("found match service name=%s,proto=%s\n", servicePtr->_name,servicePtr->_proto); + //DEBUG delay(20); + struct MDNSTxt *newtxt = (struct MDNSTxt*)(os_malloc(sizeof(struct MDNSTxt))); + os_strcpy(newtxt->_txt, txt); + newtxt->_next = 0; + if(servicePtr->_txts == 0) { //no services have been added + servicePtr->_txts = newtxt; + servicePtr->_txtLen += txtLen; + //DEBUG Serial.printf("Adding First TXT of %s to service %s and proto %s\n", newtxt->_txt,servicePtr->_name,servicePtr->_proto); + //DEBUG Serial.printf("New txt length: %d\n",servicePtr->_txtLen); + return true; + } + else{ + MDNSTxt * txtPtr = servicePtr->_txts; + while(txtPtr->_next !=0) { + txtPtr = txtPtr->_next; + //DEBUG Serial.println("Incramenting txt pointer"); + } + txtPtr->_next = newtxt; + servicePtr->_txtLen += txtLen; + //DEBUG Serial.printf("Adding Another TXT of %s to service %s and proto %s\n", newtxt->_txt,servicePtr->_name,servicePtr->_proto); + //DEBUG Serial.printf("New txt length: %d\n",servicePtr->_txtLen); + return true; + } + /* + */ + } + } + return false; + //DEBUG Serial.println("No Service Found When adding a txt"); +} + void MDNSResponder::addService(char *name, char *proto, uint16_t port){ if(_getServicePort(name, proto) != 0) return; if(os_strlen(name) > 32 || os_strlen(proto) != 3) return; //bad arguments @@ -146,15 +198,55 @@ void MDNSResponder::addService(char *name, char *proto, uint16_t port){ os_strcpy(srv->_proto, proto); srv->_port = port; srv->_next = 0; - + srv->_txts = 0; + srv->_txtLen = 0; + if(_services == 0) _services = srv; else{ MDNSService* servicePtr = _services; while(servicePtr->_next !=0) servicePtr = servicePtr->_next; servicePtr->_next = srv; } + } +MDNSTxt * MDNSResponder::_getServiceTxt(char *name, char *proto){ + MDNSService* servicePtr; + for (servicePtr = _services; servicePtr; servicePtr = servicePtr->_next) { + if(servicePtr->_port > 0 && strcmp(servicePtr->_name, name) == 0 && strcmp(servicePtr->_proto, proto) == 0){ + if (servicePtr->_txts == 0) return false; + else{ + return servicePtr->_txts; + } + } + } + return 0; +} + +uint16_t MDNSResponder::_getServiceTxtLen(char *name, char *proto){ + MDNSService* servicePtr; + for (servicePtr = _services; servicePtr; servicePtr = servicePtr->_next) { + if(servicePtr->_port > 0 && strcmp(servicePtr->_name, name) == 0 && strcmp(servicePtr->_proto, proto) == 0){ + if (servicePtr->_txts == 0) return false; + else{ + return servicePtr->_txtLen; + } + } + } + return 0; +} + + + + + + + + + + + + uint16_t MDNSResponder::_getServicePort(char *name, char *proto){ MDNSService* servicePtr; for (servicePtr = _services; servicePtr; servicePtr = servicePtr->_next) { @@ -177,7 +269,7 @@ uint32_t MDNSResponder::_getOurIp(){ return staIpInfo.ip.addr; } else { #ifdef MDNS_DEBUG_ERR - os_printf("ERR_NO_LOCAL_IP\n"); + Serial.printf("ERR_NO_LOCAL_IP\n"); #endif return 0; } @@ -224,7 +316,7 @@ void MDNSResponder::_parsePacket(){ if(hostNameLen > 0 && strcmp(_hostName, hostName) != 0){ #ifdef MDNS_DEBUG_ERR - os_printf("ERR_NO_HOST: %s\n", hostName); + Serial.printf("ERR_NO_HOST: %s\n", hostName); #endif _conn->flush(); return; @@ -249,14 +341,14 @@ void MDNSResponder::_parsePacket(){ localParsed = true; } else { #ifdef MDNS_DEBUG_ERR - os_printf("ERR_FQDN: %s\n", serviceName); + Serial.printf("ERR_FQDN: %s\n", serviceName); #endif _conn->flush(); return; } } else { #ifdef MDNS_DEBUG_ERR - os_printf("ERR_SERVICE: %s\n", serviceName); + Serial.printf("ERR_SERVICE: %s\n", serviceName); #endif _conn->flush(); return; @@ -273,7 +365,7 @@ void MDNSResponder::_parsePacket(){ protoParsed = true; } else { #ifdef MDNS_DEBUG_ERR - os_printf("ERR_PROTO: %s\n", protoName); + Serial.printf("ERR_PROTO: %s\n", protoName); #endif _conn->flush(); return; @@ -290,7 +382,7 @@ void MDNSResponder::_parsePacket(){ localParsed = true; } else { #ifdef MDNS_DEBUG_ERR - os_printf("ERR_FQDN: %s\n", localName); + Serial.printf("ERR_FQDN: %s\n", localName); #endif _conn->flush(); return; @@ -301,14 +393,14 @@ void MDNSResponder::_parsePacket(){ servicePort = _getServicePort(serviceName, protoName); if(servicePort == 0){ #ifdef MDNS_DEBUG_ERR - os_printf("ERR_NO_SERVICE: %s\n", serviceName); + Serial.printf("ERR_NO_SERVICE: %s\n", serviceName); #endif _conn->flush(); return; } } else if(serviceNameLen > 0 || protoNameLen > 0){ #ifdef MDNS_DEBUG_ERR - os_printf("ERR_SERVICE_PROTO: %s\n", serviceName); + Serial.printf("ERR_SERVICE_PROTO: %s\n", serviceName); #endif _conn->flush(); return; @@ -317,7 +409,7 @@ void MDNSResponder::_parsePacket(){ // RESPOND #ifdef MDNS_DEBUG_RX - os_printf("RX: REQ, ID:%u, Q:%u, A:%u, NS:%u, ADD:%u\n", packetHeader[0], packetHeader[2], packetHeader[3], packetHeader[4], packetHeader[5]); + Serial.printf("RX: REQ, ID:%u, Q:%u, A:%u, NS:%u, ADD:%u\n", packetHeader[0], packetHeader[2], packetHeader[3], packetHeader[4], packetHeader[5]); #endif uint16_t currentType; @@ -344,24 +436,24 @@ void MDNSResponder::_parsePacket(){ } #ifdef MDNS_DEBUG_RX - os_printf("REQ: "); - if(hostNameLen > 0) os_printf("%s.", hostName); - if(serviceNameLen > 0) os_printf("_%s.", serviceName); - if(protoNameLen > 0) os_printf("_%s.", protoName); - os_printf("local. "); + Serial.printf("REQ: "); + if(hostNameLen > 0) Serial.printf("%s.", hostName); + if(serviceNameLen > 0) Serial.printf("_%s.", serviceName); + if(protoNameLen > 0) Serial.printf("_%s.", protoName); + Serial.printf("local. "); - if(currentType == MDNS_TYPE_AAAA) os_printf(" AAAA "); - else if(currentType == MDNS_TYPE_A) os_printf(" A "); - else if(currentType == MDNS_TYPE_PTR) os_printf(" PTR "); - else if(currentType == MDNS_TYPE_SRV) os_printf(" SRV "); - else if(currentType == MDNS_TYPE_TXT) os_printf(" TXT "); - else os_printf(" 0x%04X ", currentType); + if(currentType == MDNS_TYPE_AAAA) Serial.printf(" AAAA "); + else if(currentType == MDNS_TYPE_A) Serial.printf(" A "); + else if(currentType == MDNS_TYPE_PTR) Serial.printf(" PTR "); + else if(currentType == MDNS_TYPE_SRV) Serial.printf(" SRV "); + else if(currentType == MDNS_TYPE_TXT) Serial.printf(" TXT "); + else Serial.printf(" 0x%04X ", currentType); - if(currentClass == MDNS_CLASS_IN) os_printf(" IN "); - else if(currentClass == MDNS_CLASS_IN_FLUSH_CACHE) os_printf(" IN[F] "); - else os_printf(" 0x%04X ", currentClass); + if(currentClass == MDNS_CLASS_IN) Serial.printf(" IN "); + else if(currentClass == MDNS_CLASS_IN_FLUSH_CACHE) Serial.printf(" IN[F] "); + else Serial.printf(" 0x%04X ", currentClass); - os_printf("\n"); + Serial.printf("\n"); #endif } uint8_t responseMask = 0; @@ -376,8 +468,20 @@ void MDNSResponder::_parsePacket(){ } void MDNSResponder::enableArduino(uint16_t port, bool auth){ - _arduinoAuth = auth; + + char boardName[64]; + const char *boardExtra = "board="; + os_sprintf(boardName, "%s%s", boardExtra, ARDUINO_BOARD); + + char authUpload[16]; + const char *authUploadExtra = "auth_upload="; + os_sprintf(authUpload, "%s%s", authUploadExtra, (auth) ? "yes":"no"); + addService("arduino", "tcp", port); + addServiceTxt("arduino", "tcp", "tcp_check=no"); + addServiceTxt("arduino", "tcp", "ssh_upload=no"); + addServiceTxt("arduino", "tcp", (const char*)boardName); + addServiceTxt("arduino", "tcp", (const char*)authUpload); } void MDNSResponder::_reply(uint8_t replyMask, char * service, char *proto, uint16_t port){ @@ -477,7 +581,7 @@ void MDNSResponder::_reply(uint8_t replyMask, char * service, char *proto, uint1 _conn->append(reinterpret_cast(&terminator), 1); // terminator //Send the type, class, ttl and rdata length - uint8_t txtDataLen = 0; + uint8_t txtDataLen = _getServiceTxtLen(service,proto); uint8_t txtAttrs[10] = { 0x00, 0x10, //TXT record query 0x00, 0x01, //Class IN @@ -487,7 +591,15 @@ void MDNSResponder::_reply(uint8_t replyMask, char * service, char *proto, uint1 _conn->append(reinterpret_cast(txtAttrs), 10); //Send the RData - //TODO - Build TXT Redords + MDNSTxt * txtPtr = _getServiceTxt(service,proto); + while(txtPtr !=0){ + uint8_t txtLen = os_strlen(txtPtr->_txt); + _conn->append(reinterpret_cast(&txtLen), 1); // lenght of txt + _conn->append(reinterpret_cast(txtPtr->_txt), txtLen); // the txt + //DEBUG Serial.print("We have txts: "); + //DEBUG Serial.println(txtPtr->_txt); + txtPtr = txtPtr->_next; + } } diff --git a/libraries/ESP8266mDNS/ESP8266mDNS.h b/libraries/ESP8266mDNS/ESP8266mDNS.h index 5958c40d1..cd6e969c3 100644 --- a/libraries/ESP8266mDNS/ESP8266mDNS.h +++ b/libraries/ESP8266mDNS/ESP8266mDNS.h @@ -57,6 +57,13 @@ struct MDNSService { char _name[32]; char _proto[3]; uint16_t _port; + struct MDNSTxt * _txts; + uint16_t _txtLen; // length of all txts +}; + +struct MDNSTxt{ + MDNSTxt * _next; + char _txt[128]; }; class MDNSResponder { @@ -78,16 +85,25 @@ public: addService(service.c_str(), proto.c_str(), port); } - void enableArduino(uint16_t port, bool auth=false); + bool addServiceTxt(char *name, char *proto, char *txt); + void addServiceTxt(const char *name, const char *proto, const char *txt){ + addServiceTxt((char *)name, (char *)proto, (char *)txt); + } + void addServiceTxt(String name, String proto, String txt){ + addServiceTxt(name.c_str(), proto.c_str(), txt.c_str()); + } + +void enableArduino(uint16_t port, bool auth=false); private: struct MDNSService * _services; UdpContext* _conn; char _hostName[128]; - bool _arduinoAuth; 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); }; From 971bd9b75c93054b874a32b1f0918d5ddf1f400a Mon Sep 17 00:00:00 2001 From: Eric Wilkison Date: Tue, 15 Dec 2015 06:05:35 -0800 Subject: [PATCH 4/8] Change addServiceTxt to key/val pair --- libraries/ESP8266mDNS/ESP8266mDNS.cpp | 29 +++++++++++++++------------ libraries/ESP8266mDNS/ESP8266mDNS.h | 10 ++++----- 2 files changed, 21 insertions(+), 18 deletions(-) diff --git a/libraries/ESP8266mDNS/ESP8266mDNS.cpp b/libraries/ESP8266mDNS/ESP8266mDNS.cpp index 5150792dd..edddc0b70 100644 --- a/libraries/ESP8266mDNS/ESP8266mDNS.cpp +++ b/libraries/ESP8266mDNS/ESP8266mDNS.cpp @@ -145,12 +145,13 @@ void MDNSResponder::update() { -bool MDNSResponder::addServiceTxt(char *name, char *proto, char *txt){ +bool MDNSResponder::addServiceTxt(char *name, char *proto, char *key, char *value){ MDNSService* servicePtr; //DEBUG Serial.printf("Starting addServiceTxt(name=%s,proto=%s,txt=%s)\n", name,proto,txt); //DEBUG delay(20); - uint8_t txtLen = os_strlen(txt) + 1; //One accounts for length byte added when building the txt responce + uint8_t txtLen = os_strlen(key) + os_strlen(value) + 1; // Add one for equals sign + txtLen+=1; //accounts for length byte added when building the txt responce if ( txtLen > 128) return false; //Find the service for (servicePtr = _services; servicePtr; servicePtr = servicePtr->_next) { @@ -161,7 +162,9 @@ bool MDNSResponder::addServiceTxt(char *name, char *proto, char *txt){ //DEBUG Serial.printf("found match service name=%s,proto=%s\n", servicePtr->_name,servicePtr->_proto); //DEBUG delay(20); struct MDNSTxt *newtxt = (struct MDNSTxt*)(os_malloc(sizeof(struct MDNSTxt))); - os_strcpy(newtxt->_txt, txt); + os_strcpy(newtxt->_txt, key); + os_strcat(newtxt->_txt, "="); + os_strcat(newtxt->_txt, value); newtxt->_next = 0; if(servicePtr->_txts == 0) { //no services have been added servicePtr->_txts = newtxt; @@ -469,19 +472,19 @@ void MDNSResponder::_parsePacket(){ void MDNSResponder::enableArduino(uint16_t port, bool auth){ - char boardName[64]; - const char *boardExtra = "board="; - os_sprintf(boardName, "%s%s", boardExtra, ARDUINO_BOARD); +// char boardName[64]; +// const char *boardExtra = "board="; +// os_sprintf(boardName, "%s%s", boardExtra, ARDUINO_BOARD); - char authUpload[16]; - const char *authUploadExtra = "auth_upload="; - os_sprintf(authUpload, "%s%s", authUploadExtra, (auth) ? "yes":"no"); +// char authUpload[16]; +// const char *authUploadExtra = "auth_upload="; +// os_sprintf(authUpload, "%s%s", authUploadExtra, (auth) ? "yes":"no"); addService("arduino", "tcp", port); - addServiceTxt("arduino", "tcp", "tcp_check=no"); - addServiceTxt("arduino", "tcp", "ssh_upload=no"); - addServiceTxt("arduino", "tcp", (const char*)boardName); - addServiceTxt("arduino", "tcp", (const char*)authUpload); + addServiceTxt("arduino", "tcp", "tcp_check", "no"); + addServiceTxt("arduino", "tcp", "ssh_upload", "no"); + addServiceTxt("arduino", "tcp", "board", ARDUINO_BOARD); + addServiceTxt("arduino", "tcp", "auth_upload", (auth) ? "yes":"no"); } void MDNSResponder::_reply(uint8_t replyMask, char * service, char *proto, uint16_t port){ diff --git a/libraries/ESP8266mDNS/ESP8266mDNS.h b/libraries/ESP8266mDNS/ESP8266mDNS.h index cd6e969c3..2cbd9c0a5 100644 --- a/libraries/ESP8266mDNS/ESP8266mDNS.h +++ b/libraries/ESP8266mDNS/ESP8266mDNS.h @@ -85,12 +85,12 @@ public: addService(service.c_str(), proto.c_str(), port); } - bool addServiceTxt(char *name, char *proto, char *txt); - void addServiceTxt(const char *name, const char *proto, const char *txt){ - addServiceTxt((char *)name, (char *)proto, (char *)txt); + bool addServiceTxt(char *name, char *proto, char * key, char * value); + void addServiceTxt(const char *name, const char *proto, const char *key,const char * value){ + addServiceTxt((char *)name, (char *)proto, (char *)key, (char *)value); } - void addServiceTxt(String name, String proto, String txt){ - addServiceTxt(name.c_str(), proto.c_str(), txt.c_str()); + void addServiceTxt(String name, String proto, String key, String value){ + addServiceTxt(name.c_str(), proto.c_str(), key.c_str(), value.c_str()); } void enableArduino(uint16_t port, bool auth=false); From 8d9f174826a77e3e5c1258c0c0e0a000c4054468 Mon Sep 17 00:00:00 2001 From: Eric Wilkison Date: Tue, 15 Dec 2015 13:29:59 -0800 Subject: [PATCH 5/8] Add human readable instance name property --- libraries/ESP8266mDNS/ESP8266mDNS.cpp | 54 +++++++++++++++------------ libraries/ESP8266mDNS/ESP8266mDNS.h | 13 ++++++- 2 files changed, 42 insertions(+), 25 deletions(-) diff --git a/libraries/ESP8266mDNS/ESP8266mDNS.cpp b/libraries/ESP8266mDNS/ESP8266mDNS.cpp index edddc0b70..e2cc2b8a0 100644 --- a/libraries/ESP8266mDNS/ESP8266mDNS.cpp +++ b/libraries/ESP8266mDNS/ESP8266mDNS.cpp @@ -55,9 +55,9 @@ extern "C" { -//#define MDNS_DEBUG_ERR -//#define MDNS_DEBUG_TX -//#define MDNS_DEBUG_RX +#define MDNS_DEBUG_ERR +#define MDNS_DEBUG_TX +#define MDNS_DEBUG_RX #define MDNS_NAME_REF 0xC000 @@ -88,19 +88,22 @@ static const int MDNS_PORT = 5353; MDNSResponder::MDNSResponder() : _conn(0) { _services = 0; } MDNSResponder::~MDNSResponder() {} -bool MDNSResponder::begin(const char* domain){ +bool MDNSResponder::begin(const char* hostname){ // Open the MDNS socket if it isn't already open. - size_t n = strlen(domain); - if (n > 255) { // Can only handle domains that are 255 chars in length. + size_t n = strlen(hostname); + if (n > 63) { // max size for a single label. return false; } - // Copy in domain characters as lowercase + // Copy in hostname characters as lowercase for (size_t i = 0; i < n; ++i) - _hostName[i] = tolower(domain[i]); + _hostName[i] = tolower(hostname[i]); _hostName[n] = '\0'; + // Copy hostname to default instance name + os_strcpy(_instanceName,hostname); + // Open the MDNS socket if it isn't already open. if (!_conn) { uint32_t ourIp = _getOurIp(); @@ -139,10 +142,10 @@ void MDNSResponder::update() { } - - - - +void MDNSResponder::setInstanceName(char * name){ + if (os_strlen(name) > 63) return; + else os_strcpy(_instanceName,name); +} bool MDNSResponder::addServiceTxt(char *name, char *proto, char *key, char *value){ @@ -317,9 +320,11 @@ void MDNSResponder::_parsePacket(){ hostNameLen = 0; } - if(hostNameLen > 0 && strcmp(_hostName, hostName) != 0){ + if(hostNameLen > 0 && strcmp(_hostName, hostName) != 0 && strcmp(_instanceName, hostName) != 0 ){ #ifdef MDNS_DEBUG_ERR Serial.printf("ERR_NO_HOST: %s\n", hostName); + Serial.printf("hostname: %s\n", hostName); + Serial.printf("instance: %s\n", _instanceName); #endif _conn->flush(); return; @@ -495,6 +500,9 @@ void MDNSResponder::_reply(uint8_t replyMask, char * service, char *proto, uint1 Serial.printf("TX: mask:%01X, service:%s, proto:%s, port:%u\n", replyMask, service, proto, port); #endif + char * instanceName = _instanceName; + size_t instanceNameLen = os_strlen(instanceName); + char * hostName = _hostName; size_t hostNameLen = os_strlen(hostName); @@ -549,7 +557,7 @@ void MDNSResponder::_reply(uint8_t replyMask, char * service, char *proto, uint1 _conn->append(reinterpret_cast(&terminator), 1); // terminator //Send the type, class, ttl and rdata length - uint8_t ptrDataLen = hostNameLen + serviceNameLen + protoNameLen + localNameLen + 5; // 5 is four label sizes and the terminator + uint8_t ptrDataLen = instanceNameLen + serviceNameLen + protoNameLen + localNameLen + 5; // 5 is four label sizes and the terminator uint8_t ptrAttrs[10] = { 0x00, 0x0c, //PTR record query 0x00, 0x01, //Class IN @@ -558,9 +566,9 @@ void MDNSResponder::_reply(uint8_t replyMask, char * service, char *proto, uint1 }; _conn->append(reinterpret_cast(ptrAttrs), 10); - //Send the RData (ie. "esp8266._http._tcp.local") - _conn->append(reinterpret_cast(&hostNameLen), 1); // lenght of "esp8266" - _conn->append(reinterpret_cast(hostName), hostNameLen); // "esp8266" + //Send the RData (ie. "My IOT device._http._tcp.local") + _conn->append(reinterpret_cast(&instanceNameLen), 1); // lenght of "My IOT device" + _conn->append(reinterpret_cast(instanceName), instanceNameLen);// "My IOT device" _conn->append(reinterpret_cast(&serviceNameLen), 1); // lenght of "_http" _conn->append(reinterpret_cast(serviceName), serviceNameLen); // "_http" _conn->append(reinterpret_cast(&protoNameLen), 1); // lenght of "_tcp" @@ -572,9 +580,9 @@ void MDNSResponder::_reply(uint8_t replyMask, char * service, char *proto, uint1 //TXT Responce if(replyMask & 0x4){ - //Send the name field (ie. "esp8266._http._tcp.local") - _conn->append(reinterpret_cast(&hostNameLen), 1); // lenght of "esp8266" - _conn->append(reinterpret_cast(hostName), hostNameLen); // "esp8266" + //Send the name field (ie. "My IOT device._http._tcp.local") + _conn->append(reinterpret_cast(&instanceNameLen), 1); // lenght of "My IOT device" + _conn->append(reinterpret_cast(instanceName), instanceNameLen);// "My IOT device" _conn->append(reinterpret_cast(&serviceNameLen), 1); // lenght of "_http" _conn->append(reinterpret_cast(serviceName), serviceNameLen); // "_http" _conn->append(reinterpret_cast(&protoNameLen), 1); // lenght of "_tcp" @@ -608,9 +616,9 @@ void MDNSResponder::_reply(uint8_t replyMask, char * service, char *proto, uint1 //SRV Responce if(replyMask & 0x2){ - //Send the name field (ie. "esp8266._http._tcp.local") - _conn->append(reinterpret_cast(&hostNameLen), 1); // lenght of "esp8266" - _conn->append(reinterpret_cast(hostName), hostNameLen); // "esp8266" + //Send the name field (ie. "My IOT device._http._tcp.local") + _conn->append(reinterpret_cast(&instanceNameLen), 1); // lenght of "My IOT device" + _conn->append(reinterpret_cast(instanceName), instanceNameLen);// "My IOT device" _conn->append(reinterpret_cast(&serviceNameLen), 1); // lenght of "_http" _conn->append(reinterpret_cast(serviceName), serviceNameLen); // "_http" _conn->append(reinterpret_cast(&protoNameLen), 1); // lenght of "_tcp" diff --git a/libraries/ESP8266mDNS/ESP8266mDNS.h b/libraries/ESP8266mDNS/ESP8266mDNS.h index 2cbd9c0a5..4f75204f8 100644 --- a/libraries/ESP8266mDNS/ESP8266mDNS.h +++ b/libraries/ESP8266mDNS/ESP8266mDNS.h @@ -93,12 +93,21 @@ public: addServiceTxt(name.c_str(), proto.c_str(), key.c_str(), value.c_str()); } -void enableArduino(uint16_t port, bool auth=false); + void enableArduino(uint16_t port, bool auth=false); + + void setInstanceName(char * name); + void setInstanceName(const char * name){ + setInstanceName((char*) name); + } + void setInstanceName(String name){ + setInstanceName(name.c_str()); + } private: struct MDNSService * _services; UdpContext* _conn; - char _hostName[128]; + char _hostName[63]; + char _instanceName[63]; uint32_t _getOurIp(); uint16_t _getServicePort(char *service, char *proto); From 99b3e2df26af3841f9b6bf6072b8cbc32ca24496 Mon Sep 17 00:00:00 2001 From: Eric Wilkison Date: Thu, 17 Dec 2015 14:13:03 -0800 Subject: [PATCH 6/8] remove debug code --- libraries/ESP8266mDNS/ESP8266mDNS.cpp | 71 ++++++++------------------- 1 file changed, 21 insertions(+), 50 deletions(-) diff --git a/libraries/ESP8266mDNS/ESP8266mDNS.cpp b/libraries/ESP8266mDNS/ESP8266mDNS.cpp index e2cc2b8a0..9879e665d 100644 --- a/libraries/ESP8266mDNS/ESP8266mDNS.cpp +++ b/libraries/ESP8266mDNS/ESP8266mDNS.cpp @@ -55,9 +55,9 @@ extern "C" { -#define MDNS_DEBUG_ERR -#define MDNS_DEBUG_TX -#define MDNS_DEBUG_RX +//#define MDNS_DEBUG_ERR +//#define MDNS_DEBUG_TX +//#define MDNS_DEBUG_RX #define MDNS_NAME_REF 0xC000 @@ -151,49 +151,39 @@ void MDNSResponder::setInstanceName(char * name){ bool MDNSResponder::addServiceTxt(char *name, char *proto, char *key, char *value){ MDNSService* servicePtr; - //DEBUG Serial.printf("Starting addServiceTxt(name=%s,proto=%s,txt=%s)\n", name,proto,txt); - //DEBUG delay(20); uint8_t txtLen = os_strlen(key) + os_strlen(value) + 1; // Add one for equals sign txtLen+=1; //accounts for length byte added when building the txt responce if ( txtLen > 128) return false; //Find the service for (servicePtr = _services; servicePtr; servicePtr = servicePtr->_next) { - //DEBUG Serial.printf("Checking service name=%s,proto=%s\n", servicePtr->_name,servicePtr->_proto); - //DEBUG delay(20); + //Checking Service names if(strcmp(servicePtr->_name, name) == 0 && strcmp(servicePtr->_proto, proto) == 0){ if (servicePtr->_txtLen + txtLen > 1300) return false; //max txt record size - //DEBUG Serial.printf("found match service name=%s,proto=%s\n", servicePtr->_name,servicePtr->_proto); - //DEBUG delay(20); - struct MDNSTxt *newtxt = (struct MDNSTxt*)(os_malloc(sizeof(struct MDNSTxt))); - os_strcpy(newtxt->_txt, key); - os_strcat(newtxt->_txt, "="); - os_strcat(newtxt->_txt, value); - newtxt->_next = 0; - if(servicePtr->_txts == 0) { //no services have been added - servicePtr->_txts = newtxt; - servicePtr->_txtLen += txtLen; - //DEBUG Serial.printf("Adding First TXT of %s to service %s and proto %s\n", newtxt->_txt,servicePtr->_name,servicePtr->_proto); - //DEBUG Serial.printf("New txt length: %d\n",servicePtr->_txtLen); - return true; - } - else{ - MDNSTxt * txtPtr = servicePtr->_txts; - while(txtPtr->_next !=0) { - txtPtr = txtPtr->_next; - //DEBUG Serial.println("Incramenting txt pointer"); + //found a service name match + struct MDNSTxt *newtxt = (struct MDNSTxt*)(os_malloc(sizeof(struct MDNSTxt))); + os_strcpy(newtxt->_txt, key); + os_strcat(newtxt->_txt, "="); + os_strcat(newtxt->_txt, value); + newtxt->_next = 0; + if(servicePtr->_txts == 0) { //no services have been added + //Adding First TXT to service + servicePtr->_txts = newtxt; + servicePtr->_txtLen += txtLen; + return true; } + else{ + MDNSTxt * txtPtr = servicePtr->_txts; + while(txtPtr->_next !=0) { + txtPtr = txtPtr->_next; + } + //adding another TXT to service txtPtr->_next = newtxt; servicePtr->_txtLen += txtLen; - //DEBUG Serial.printf("Adding Another TXT of %s to service %s and proto %s\n", newtxt->_txt,servicePtr->_name,servicePtr->_proto); - //DEBUG Serial.printf("New txt length: %d\n",servicePtr->_txtLen); return true; } - /* - */ } } return false; - //DEBUG Serial.println("No Service Found When adding a txt"); } void MDNSResponder::addService(char *name, char *proto, uint16_t port){ @@ -242,17 +232,6 @@ uint16_t MDNSResponder::_getServiceTxtLen(char *name, char *proto){ return 0; } - - - - - - - - - - - uint16_t MDNSResponder::_getServicePort(char *name, char *proto){ MDNSService* servicePtr; for (servicePtr = _services; servicePtr; servicePtr = servicePtr->_next) { @@ -477,14 +456,6 @@ void MDNSResponder::_parsePacket(){ void MDNSResponder::enableArduino(uint16_t port, bool auth){ -// char boardName[64]; -// const char *boardExtra = "board="; -// os_sprintf(boardName, "%s%s", boardExtra, ARDUINO_BOARD); - -// char authUpload[16]; -// const char *authUploadExtra = "auth_upload="; -// os_sprintf(authUpload, "%s%s", authUploadExtra, (auth) ? "yes":"no"); - addService("arduino", "tcp", port); addServiceTxt("arduino", "tcp", "tcp_check", "no"); addServiceTxt("arduino", "tcp", "ssh_upload", "no"); From f7d8a027e8b8578cf5b27b3805c2ba172558d3c0 Mon Sep 17 00:00:00 2001 From: Eric Wilkison Date: Thu, 17 Dec 2015 14:29:15 -0800 Subject: [PATCH 7/8] Fix begin overwriting instancename --- libraries/ESP8266mDNS/ESP8266mDNS.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/libraries/ESP8266mDNS/ESP8266mDNS.cpp b/libraries/ESP8266mDNS/ESP8266mDNS.cpp index 9879e665d..304b93724 100644 --- a/libraries/ESP8266mDNS/ESP8266mDNS.cpp +++ b/libraries/ESP8266mDNS/ESP8266mDNS.cpp @@ -85,7 +85,10 @@ static const IPAddress MDNS_MULTICAST_ADDR(224, 0, 0, 251); static const int MDNS_MULTICAST_TTL = 1; static const int MDNS_PORT = 5353; -MDNSResponder::MDNSResponder() : _conn(0) { _services = 0; } +MDNSResponder::MDNSResponder() : _conn(0) { + _services = 0; + _instanceName[0] = 0; +} MDNSResponder::~MDNSResponder() {} bool MDNSResponder::begin(const char* hostname){ @@ -101,8 +104,8 @@ bool MDNSResponder::begin(const char* hostname){ _hostName[i] = tolower(hostname[i]); _hostName[n] = '\0'; - // Copy hostname to default instance name - os_strcpy(_instanceName,hostname); + // If instance name is not already set copy hostname to instance name + if (os_strlen(_instanceName) == 0) os_strcpy(_instanceName,hostname); // Open the MDNS socket if it isn't already open. if (!_conn) { From c40cb79ec244a496b7bc3a7e874adf28fb1995ec Mon Sep 17 00:00:00 2001 From: Eric Wilkison Date: Fri, 18 Dec 2015 11:37:53 -0800 Subject: [PATCH 8/8] -replace char _hostName[63], char _instanceName[63], and char _txt[128] with Strings. Calling enableArduino allocates four TXT records, and there is quite an overhead of storing tcp_check=no inside an 128-byte buffer. Plus you gain flexibility by supporting TXT records larger than 128 bytes. Host and instance names should also be less than 63 characters most of the time.\n-move definitions of struct MDNSService and struct MDNSTxt to .cpp file, and use forward declaratio --- libraries/ESP8266mDNS/ESP8266mDNS.cpp | 95 +++++++++++++++------------ libraries/ESP8266mDNS/ESP8266mDNS.h | 27 +++----- 2 files changed, 61 insertions(+), 61 deletions(-) diff --git a/libraries/ESP8266mDNS/ESP8266mDNS.cpp b/libraries/ESP8266mDNS/ESP8266mDNS.cpp index 304b93724..2e5c711fb 100644 --- a/libraries/ESP8266mDNS/ESP8266mDNS.cpp +++ b/libraries/ESP8266mDNS/ESP8266mDNS.cpp @@ -85,9 +85,25 @@ static const IPAddress MDNS_MULTICAST_ADDR(224, 0, 0, 251); static const int MDNS_MULTICAST_TTL = 1; static const int MDNS_PORT = 5353; +struct MDNSService { + MDNSService* _next; + char _name[32]; + char _proto[3]; + uint16_t _port; + struct MDNSTxt * _txts; + uint16_t _txtLen; // length of all txts +}; + +struct MDNSTxt{ + MDNSTxt * _next; + String _txt; +}; + + + MDNSResponder::MDNSResponder() : _conn(0) { _services = 0; - _instanceName[0] = 0; + _instanceName = ""; } MDNSResponder::~MDNSResponder() {} @@ -100,12 +116,11 @@ bool MDNSResponder::begin(const char* hostname){ } // Copy in hostname characters as lowercase - for (size_t i = 0; i < n; ++i) - _hostName[i] = tolower(hostname[i]); - _hostName[n] = '\0'; + _hostName = hostname; + _hostName.toLowerCase(); // If instance name is not already set copy hostname to instance name - if (os_strlen(_instanceName) == 0) os_strcpy(_instanceName,hostname); + if (_instanceName.equals("") ) _instanceName=hostname; // Open the MDNS socket if it isn't already open. if (!_conn) { @@ -145,9 +160,9 @@ void MDNSResponder::update() { } -void MDNSResponder::setInstanceName(char * name){ - if (os_strlen(name) > 63) return; - else os_strcpy(_instanceName,name); +void MDNSResponder::setInstanceName(String name){ + if (name.length() > 63) return; + else _instanceName = name; } @@ -156,29 +171,26 @@ bool MDNSResponder::addServiceTxt(char *name, char *proto, char *key, char *valu uint8_t txtLen = os_strlen(key) + os_strlen(value) + 1; // Add one for equals sign txtLen+=1; //accounts for length byte added when building the txt responce - if ( txtLen > 128) return false; //Find the service for (servicePtr = _services; servicePtr; servicePtr = servicePtr->_next) { //Checking Service names if(strcmp(servicePtr->_name, name) == 0 && strcmp(servicePtr->_proto, proto) == 0){ + //found a service name match if (servicePtr->_txtLen + txtLen > 1300) return false; //max txt record size - //found a service name match - struct MDNSTxt *newtxt = (struct MDNSTxt*)(os_malloc(sizeof(struct MDNSTxt))); - os_strcpy(newtxt->_txt, key); - os_strcat(newtxt->_txt, "="); - os_strcat(newtxt->_txt, value); - newtxt->_next = 0; - if(servicePtr->_txts == 0) { //no services have been added - //Adding First TXT to service - servicePtr->_txts = newtxt; - servicePtr->_txtLen += txtLen; - return true; + MDNSTxt *newtxt = new MDNSTxt; + newtxt->_txt = String(key) + "=" + String(value); + newtxt->_next = 0; + if(servicePtr->_txts == 0) { //no services have been added + //Adding First TXT to service + servicePtr->_txts = newtxt; + servicePtr->_txtLen += txtLen; + return true; + } + else{ + MDNSTxt * txtPtr = servicePtr->_txts; + while(txtPtr->_next !=0) { + txtPtr = txtPtr->_next; } - else{ - MDNSTxt * txtPtr = servicePtr->_txts; - while(txtPtr->_next !=0) { - txtPtr = txtPtr->_next; - } //adding another TXT to service txtPtr->_next = newtxt; servicePtr->_txtLen += txtLen; @@ -302,11 +314,11 @@ void MDNSResponder::_parsePacket(){ hostNameLen = 0; } - if(hostNameLen > 0 && strcmp(_hostName, hostName) != 0 && strcmp(_instanceName, hostName) != 0 ){ + if(hostNameLen > 0 && !_hostName.equals(hostName) && !_instanceName.equals(hostName)){ #ifdef MDNS_DEBUG_ERR Serial.printf("ERR_NO_HOST: %s\n", hostName); - Serial.printf("hostname: %s\n", hostName); - Serial.printf("instance: %s\n", _instanceName); + Serial.printf("hostname: %s\n", _hostName.c_str() ); + Serial.printf("instance: %s\n", _instanceName.c_str() ); #endif _conn->flush(); return; @@ -474,11 +486,12 @@ void MDNSResponder::_reply(uint8_t replyMask, char * service, char *proto, uint1 Serial.printf("TX: mask:%01X, service:%s, proto:%s, port:%u\n", replyMask, service, proto, port); #endif - char * instanceName = _instanceName; - size_t instanceNameLen = os_strlen(instanceName); + + String instanceName = _instanceName; + size_t instanceNameLen = instanceName.length(); - char * hostName = _hostName; - size_t hostNameLen = os_strlen(hostName); + String hostName = _hostName; + size_t hostNameLen = hostName.length(); char underscore[] = "_"; @@ -542,7 +555,7 @@ void MDNSResponder::_reply(uint8_t replyMask, char * service, char *proto, uint1 //Send the RData (ie. "My IOT device._http._tcp.local") _conn->append(reinterpret_cast(&instanceNameLen), 1); // lenght of "My IOT device" - _conn->append(reinterpret_cast(instanceName), instanceNameLen);// "My IOT device" + _conn->append(reinterpret_cast(instanceName.c_str()), instanceNameLen);// "My IOT device" _conn->append(reinterpret_cast(&serviceNameLen), 1); // lenght of "_http" _conn->append(reinterpret_cast(serviceName), serviceNameLen); // "_http" _conn->append(reinterpret_cast(&protoNameLen), 1); // lenght of "_tcp" @@ -556,7 +569,7 @@ void MDNSResponder::_reply(uint8_t replyMask, char * service, char *proto, uint1 if(replyMask & 0x4){ //Send the name field (ie. "My IOT device._http._tcp.local") _conn->append(reinterpret_cast(&instanceNameLen), 1); // lenght of "My IOT device" - _conn->append(reinterpret_cast(instanceName), instanceNameLen);// "My IOT device" + _conn->append(reinterpret_cast(instanceName.c_str()), instanceNameLen);// "My IOT device" _conn->append(reinterpret_cast(&serviceNameLen), 1); // lenght of "_http" _conn->append(reinterpret_cast(serviceName), serviceNameLen); // "_http" _conn->append(reinterpret_cast(&protoNameLen), 1); // lenght of "_tcp" @@ -578,11 +591,9 @@ void MDNSResponder::_reply(uint8_t replyMask, char * service, char *proto, uint1 //Send the RData MDNSTxt * txtPtr = _getServiceTxt(service,proto); while(txtPtr !=0){ - uint8_t txtLen = os_strlen(txtPtr->_txt); - _conn->append(reinterpret_cast(&txtLen), 1); // lenght of txt - _conn->append(reinterpret_cast(txtPtr->_txt), txtLen); // the txt - //DEBUG Serial.print("We have txts: "); - //DEBUG Serial.println(txtPtr->_txt); + uint8_t txtLen = txtPtr->_txt.length(); + _conn->append(reinterpret_cast(&txtLen), 1); // lenght of txt + _conn->append(reinterpret_cast(txtPtr->_txt.c_str()), txtLen);// the txt txtPtr = txtPtr->_next; } } @@ -592,7 +603,7 @@ void MDNSResponder::_reply(uint8_t replyMask, char * service, char *proto, uint1 if(replyMask & 0x2){ //Send the name field (ie. "My IOT device._http._tcp.local") _conn->append(reinterpret_cast(&instanceNameLen), 1); // lenght of "My IOT device" - _conn->append(reinterpret_cast(instanceName), instanceNameLen);// "My IOT device" + _conn->append(reinterpret_cast(instanceName.c_str()), instanceNameLen);// "My IOT device" _conn->append(reinterpret_cast(&serviceNameLen), 1); // lenght of "_http" _conn->append(reinterpret_cast(serviceName), serviceNameLen); // "_http" _conn->append(reinterpret_cast(&protoNameLen), 1); // lenght of "_tcp" @@ -621,7 +632,7 @@ void MDNSResponder::_reply(uint8_t replyMask, char * service, char *proto, uint1 _conn->append(reinterpret_cast(srvRData), 6); //Send the RData (ie. "esp8266.local") _conn->append(reinterpret_cast(&hostNameLen), 1); // lenght of "esp8266" - _conn->append(reinterpret_cast(hostName), hostNameLen); // "esp8266" + _conn->append(reinterpret_cast(hostName.c_str()), hostNameLen);// "esp8266" _conn->append(reinterpret_cast(&localNameLen), 1); // lenght "local" _conn->append(reinterpret_cast(localName), localNameLen); // "local" _conn->append(reinterpret_cast(&terminator), 1); // terminator @@ -632,7 +643,7 @@ void MDNSResponder::_reply(uint8_t replyMask, char * service, char *proto, uint1 if(replyMask & 0x1){ //Send the RData (ie. "esp8266.local") _conn->append(reinterpret_cast(&hostNameLen), 1); // lenght of "esp8266" - _conn->append(reinterpret_cast(hostName), hostNameLen); // "esp8266" + _conn->append(reinterpret_cast(hostName.c_str()), hostNameLen);// "esp8266" _conn->append(reinterpret_cast(&localNameLen), 1); // lenght "local" _conn->append(reinterpret_cast(localName), localNameLen); // "local" _conn->append(reinterpret_cast(&terminator), 1); // terminator diff --git a/libraries/ESP8266mDNS/ESP8266mDNS.h b/libraries/ESP8266mDNS/ESP8266mDNS.h index 4f75204f8..28ef7155c 100644 --- a/libraries/ESP8266mDNS/ESP8266mDNS.h +++ b/libraries/ESP8266mDNS/ESP8266mDNS.h @@ -52,19 +52,8 @@ License (MIT license): class UdpContext; -struct MDNSService { - MDNSService* _next; - char _name[32]; - char _proto[3]; - uint16_t _port; - struct MDNSTxt * _txts; - uint16_t _txtLen; // length of all txts -}; - -struct MDNSTxt{ - MDNSTxt * _next; - char _txt[128]; -}; +struct MDNSService; +struct MDNSTxt; class MDNSResponder { public: @@ -95,19 +84,19 @@ public: void enableArduino(uint16_t port, bool auth=false); - void setInstanceName(char * name); + void setInstanceName(String name); void setInstanceName(const char * name){ - setInstanceName((char*) name); + setInstanceName(String(name)); } - void setInstanceName(String name){ - setInstanceName(name.c_str()); + void setInstanceName(char * name){ + setInstanceName(String(name)); } private: struct MDNSService * _services; UdpContext* _conn; - char _hostName[63]; - char _instanceName[63]; + String _hostName; + String _instanceName; uint32_t _getOurIp(); uint16_t _getServicePort(char *service, char *proto);