1
0
mirror of https://github.com/esp8266/Arduino.git synced 2025-04-22 21:23:07 +03:00
esp8266/libraries/ESP8266mDNS/src/LEAmDNS_Helpers.cpp
Allman-astyler eea9999dc5 Revert "Allman now (#6080)" (#6090)
This reverts commit 98125f88605cd7e46e9be4e1b3ad0600dd5d2b51.
2019-05-14 00:09:54 +02:00

751 lines
24 KiB
C++

/*
* LEAmDNS_Helpers.cpp
*
* License (MIT license):
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
*/
#include "lwip/igmp.h"
#include "LEAmDNS_lwIPdefs.h"
#include "LEAmDNS_Priv.h"
namespace {
/*
* strrstr (static)
*
* Backwards search for p_pcPattern in p_pcString
* Based on: https://stackoverflow.com/a/1634398/2778898
*
*/
const char* strrstr(const char*__restrict p_pcString, const char*__restrict p_pcPattern) {
const char* pcResult = 0;
size_t stStringLength = (p_pcString ? strlen(p_pcString) : 0);
size_t stPatternLength = (p_pcPattern ? strlen(p_pcPattern) : 0);
if ((stStringLength) &&
(stPatternLength) &&
(stPatternLength <= stStringLength)) {
// Pattern is shorter or has the same length tham the string
for (const char* s=(p_pcString + stStringLength - stPatternLength); s>=p_pcString; --s) {
if (0 == strncmp(s, p_pcPattern, stPatternLength)) {
pcResult = s;
break;
}
}
}
return pcResult;
}
} // anonymous
namespace esp8266 {
/*
* LEAmDNS
*/
namespace MDNSImplementation {
/**
* HELPERS
*/
/*
* MDNSResponder::indexDomain (static)
*
* Updates the given domain 'p_rpcHostname' by appending a delimiter and an index number.
*
* If the given domain already hasa numeric index (after the given delimiter), this index
* incremented. If not, the delimiter and index '2' is added.
*
* If 'p_rpcHostname' is empty (==0), the given default name 'p_pcDefaultHostname' is used,
* if no default is given, 'esp8266' is used.
*
*/
/*static*/ bool MDNSResponder::indexDomain(char*& p_rpcDomain,
const char* p_pcDivider /*= "-"*/,
const char* p_pcDefaultDomain /*= 0*/) {
bool bResult = false;
// Ensure a divider exists; use '-' as default
const char* pcDivider = (p_pcDivider ?: "-");
if (p_rpcDomain) {
const char* pFoundDivider = strrstr(p_rpcDomain, pcDivider);
if (pFoundDivider) { // maybe already extended
char* pEnd = 0;
unsigned long ulIndex = strtoul((pFoundDivider + strlen(pcDivider)), &pEnd, 10);
if ((ulIndex) &&
((pEnd - p_rpcDomain) == (ptrdiff_t)strlen(p_rpcDomain)) &&
(!*pEnd)) { // Valid (old) index found
char acIndexBuffer[16];
sprintf(acIndexBuffer, "%lu", (++ulIndex));
size_t stLength = ((pFoundDivider - p_rpcDomain + strlen(pcDivider)) + strlen(acIndexBuffer) + 1);
char* pNewHostname = new char[stLength];
if (pNewHostname) {
memcpy(pNewHostname, p_rpcDomain, (pFoundDivider - p_rpcDomain + strlen(pcDivider)));
pNewHostname[pFoundDivider - p_rpcDomain + strlen(pcDivider)] = 0;
strcat(pNewHostname, acIndexBuffer);
delete[] p_rpcDomain;
p_rpcDomain = pNewHostname;
bResult = true;
}
else {
DEBUG_EX_ERR(DEBUG_OUTPUT.println(F("[MDNSResponder] indexDomain: FAILED to alloc new hostname!")););
}
}
else {
pFoundDivider = 0; // Flag the need to (base) extend the hostname
}
}
if (!pFoundDivider) { // not yet extended (or failed to increment extension) -> start indexing
size_t stLength = strlen(p_rpcDomain) + (strlen(pcDivider) + 1 + 1); // Name + Divider + '2' + '\0'
char* pNewHostname = new char[stLength];
if (pNewHostname) {
sprintf(pNewHostname, "%s%s2", p_rpcDomain, pcDivider);
delete[] p_rpcDomain;
p_rpcDomain = pNewHostname;
bResult = true;
}
else {
DEBUG_EX_ERR(DEBUG_OUTPUT.println(F("[MDNSResponder] indexDomain: FAILED to alloc new hostname!")););
}
}
}
else {
// No given host domain, use base or default
const char* cpcDefaultName = (p_pcDefaultDomain ?: "esp8266");
size_t stLength = strlen(cpcDefaultName) + 1; // '\0'
p_rpcDomain = new char[stLength];
if (p_rpcDomain) {
strncpy(p_rpcDomain, cpcDefaultName, stLength);
bResult = true;
}
else {
DEBUG_EX_ERR(DEBUG_OUTPUT.println(F("[MDNSResponder] indexDomain: FAILED to alloc new hostname!")););
}
}
DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] indexDomain: %s\n"), p_rpcDomain););
return bResult;
}
/*
* UDP CONTEXT
*/
bool MDNSResponder::_callProcess(void) {
DEBUG_EX_INFO(DEBUG_OUTPUT.printf("[MDNSResponder] _callProcess (%lu, triggered by: %s)\n", millis(), m_pUDPContext->getRemoteAddress().toString().c_str()););
return _process(false);
}
/*
* MDNSResponder::_allocUDPContext
*
* (Re-)Creates the one-and-only UDP context for the MDNS responder.
* The context is added to the 'multicast'-group and listens to the MDNS port (5353).
* The travel-distance for multicast messages is set to 1 (local, via MDNS_MULTICAST_TTL).
* Messages are received via the MDNSResponder '_update' function. CAUTION: This function
* is called from the WiFi stack side of the ESP stack system.
*
*/
bool MDNSResponder::_allocUDPContext(void) {
DEBUG_EX_INFO(DEBUG_OUTPUT.println("[MDNSResponder] _allocUDPContext"););
bool bResult = false;
_releaseUDPContext();
#ifdef MDNS_IP4_SUPPORT
ip_addr_t multicast_addr = DNS_MQUERY_IPV4_GROUP_INIT;
#endif
#ifdef MDNS_IP6_SUPPORT
//TODO: set multicast address (lwip_joingroup() is IPv4 only at the time of writing)
multicast_addr.addr = DNS_MQUERY_IPV6_GROUP_INIT;
#endif
if (ERR_OK == igmp_joingroup(IP4_ADDR_ANY4, ip_2_ip4(&multicast_addr))) {
m_pUDPContext = new UdpContext;
m_pUDPContext->ref();
if (m_pUDPContext->listen(IP4_ADDR_ANY, DNS_MQUERY_PORT)) {
m_pUDPContext->setMulticastTTL(MDNS_MULTICAST_TTL);
m_pUDPContext->onRx(std::bind(&MDNSResponder::_callProcess, this));
bResult = m_pUDPContext->connect(&multicast_addr, DNS_MQUERY_PORT);
}
}
return bResult;
}
/*
* MDNSResponder::_releaseUDPContext
*/
bool MDNSResponder::_releaseUDPContext(void) {
if (m_pUDPContext) {
m_pUDPContext->unref();
m_pUDPContext = 0;
}
return true;
}
/*
* SERVICE QUERY
*/
/*
* MDNSResponder::_allocServiceQuery
*/
MDNSResponder::stcMDNSServiceQuery* MDNSResponder::_allocServiceQuery(void) {
stcMDNSServiceQuery* pServiceQuery = new stcMDNSServiceQuery;
if (pServiceQuery) {
// Link to query list
pServiceQuery->m_pNext = m_pServiceQueries;
m_pServiceQueries = pServiceQuery;
}
return m_pServiceQueries;
}
/*
* MDNSResponder::_removeServiceQuery
*/
bool MDNSResponder::_removeServiceQuery(MDNSResponder::stcMDNSServiceQuery* p_pServiceQuery) {
bool bResult = false;
if (p_pServiceQuery) {
stcMDNSServiceQuery* pPred = m_pServiceQueries;
while ((pPred) &&
(pPred->m_pNext != p_pServiceQuery)) {
pPred = pPred->m_pNext;
}
if (pPred) {
pPred->m_pNext = p_pServiceQuery->m_pNext;
delete p_pServiceQuery;
bResult = true;
}
else { // No predecesor
if (m_pServiceQueries == p_pServiceQuery) {
m_pServiceQueries = p_pServiceQuery->m_pNext;
delete p_pServiceQuery;
bResult = true;
}
else {
DEBUG_EX_ERR(DEBUG_OUTPUT.println("[MDNSResponder] _releaseServiceQuery: INVALID service query!"););
}
}
}
return bResult;
}
/*
* MDNSResponder::_removeLegacyServiceQuery
*/
bool MDNSResponder::_removeLegacyServiceQuery(void) {
stcMDNSServiceQuery* pLegacyServiceQuery = _findLegacyServiceQuery();
return (pLegacyServiceQuery ? _removeServiceQuery(pLegacyServiceQuery) : true);
}
/*
* MDNSResponder::_findServiceQuery
*
* 'Convert' hMDNSServiceQuery to stcMDNSServiceQuery* (ensure existance)
*
*/
MDNSResponder::stcMDNSServiceQuery* MDNSResponder::_findServiceQuery(MDNSResponder::hMDNSServiceQuery p_hServiceQuery) {
stcMDNSServiceQuery* pServiceQuery = m_pServiceQueries;
while (pServiceQuery) {
if ((hMDNSServiceQuery)pServiceQuery == p_hServiceQuery) {
break;
}
pServiceQuery = pServiceQuery->m_pNext;
}
return pServiceQuery;
}
/*
* MDNSResponder::_findLegacyServiceQuery
*/
MDNSResponder::stcMDNSServiceQuery* MDNSResponder::_findLegacyServiceQuery(void) {
stcMDNSServiceQuery* pServiceQuery = m_pServiceQueries;
while (pServiceQuery) {
if (pServiceQuery->m_bLegacyQuery) {
break;
}
pServiceQuery = pServiceQuery->m_pNext;
}
return pServiceQuery;
}
/*
* MDNSResponder::_releaseServiceQueries
*/
bool MDNSResponder::_releaseServiceQueries(void) {
while (m_pServiceQueries) {
stcMDNSServiceQuery* pNext = m_pServiceQueries->m_pNext;
delete m_pServiceQueries;
m_pServiceQueries = pNext;
}
return true;
}
/*
* MDNSResponder::_findNextServiceQueryByServiceType
*/
MDNSResponder::stcMDNSServiceQuery* MDNSResponder::_findNextServiceQueryByServiceType(const stcMDNS_RRDomain& p_ServiceTypeDomain,
const stcMDNSServiceQuery* p_pPrevServiceQuery) {
stcMDNSServiceQuery* pMatchingServiceQuery = 0;
stcMDNSServiceQuery* pServiceQuery = (p_pPrevServiceQuery ? p_pPrevServiceQuery->m_pNext : m_pServiceQueries);
while (pServiceQuery) {
if (p_ServiceTypeDomain == pServiceQuery->m_ServiceTypeDomain) {
pMatchingServiceQuery = pServiceQuery;
break;
}
pServiceQuery = pServiceQuery->m_pNext;
}
return pMatchingServiceQuery;
}
/*
* HOSTNAME
*/
/*
* MDNSResponder::_setHostname
*/
bool MDNSResponder::_setHostname(const char* p_pcHostname) {
//DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _allocHostname (%s)\n"), p_pcHostname););
bool bResult = false;
_releaseHostname();
size_t stLength = 0;
if ((p_pcHostname) &&
(MDNS_DOMAIN_LABEL_MAXLENGTH >= (stLength = strlen(p_pcHostname)))) { // char max size for a single label
// Copy in hostname characters as lowercase
if ((bResult = (0 != (m_pcHostname = new char[stLength + 1])))) {
#ifdef MDNS_FORCE_LOWERCASE_HOSTNAME
size_t i = 0;
for (; i<stLength; ++i) {
m_pcHostname[i] = (isupper(p_pcHostname[i]) ? tolower(p_pcHostname[i]) : p_pcHostname[i]);
}
m_pcHostname[i] = 0;
#else
strncpy(m_pcHostname, p_pcHostname, (stLength + 1));
#endif
}
}
return bResult;
}
/*
* MDNSResponder::_releaseHostname
*/
bool MDNSResponder::_releaseHostname(void) {
if (m_pcHostname) {
delete[] m_pcHostname;
m_pcHostname = 0;
}
return true;
}
/*
* SERVICE
*/
/*
* MDNSResponder::_allocService
*/
MDNSResponder::stcMDNSService* MDNSResponder::_allocService(const char* p_pcName,
const char* p_pcService,
const char* p_pcProtocol,
uint16_t p_u16Port) {
stcMDNSService* pService = 0;
if (((!p_pcName) ||
(MDNS_DOMAIN_LABEL_MAXLENGTH >= strlen(p_pcName))) &&
(p_pcService) &&
(MDNS_SERVICE_NAME_LENGTH >= strlen(p_pcService)) &&
(p_pcProtocol) &&
(MDNS_SERVICE_PROTOCOL_LENGTH >= strlen(p_pcProtocol)) &&
(p_u16Port) &&
(0 != (pService = new stcMDNSService)) &&
(pService->setName(p_pcName ?: m_pcHostname)) &&
(pService->setService(p_pcService)) &&
(pService->setProtocol(p_pcProtocol))) {
pService->m_bAutoName = (0 == p_pcName);
pService->m_u16Port = p_u16Port;
// Add to list (or start list)
pService->m_pNext = m_pServices;
m_pServices = pService;
}
return pService;
}
/*
* MDNSResponder::_releaseService
*/
bool MDNSResponder::_releaseService(MDNSResponder::stcMDNSService* p_pService) {
bool bResult = false;
if (p_pService) {
stcMDNSService* pPred = m_pServices;
while ((pPred) &&
(pPred->m_pNext != p_pService)) {
pPred = pPred->m_pNext;
}
if (pPred) {
pPred->m_pNext = p_pService->m_pNext;
delete p_pService;
bResult = true;
}
else { // No predecesor
if (m_pServices == p_pService) {
m_pServices = p_pService->m_pNext;
delete p_pService;
bResult = true;
}
else {
DEBUG_EX_ERR(DEBUG_OUTPUT.println("[MDNSResponder] _releaseService: INVALID service!"););
}
}
}
return bResult;
}
/*
* MDNSResponder::_releaseServices
*/
bool MDNSResponder::_releaseServices(void) {
stcMDNSService* pService = m_pServices;
while (pService) {
_releaseService(pService);
pService = m_pServices;
}
return true;
}
/*
* MDNSResponder::_findService
*/
MDNSResponder::stcMDNSService* MDNSResponder::_findService(const char* p_pcName,
const char* p_pcService,
const char* p_pcProtocol) {
stcMDNSService* pService = m_pServices;
while (pService) {
if ((0 == strcmp(pService->m_pcName, p_pcName)) &&
(0 == strcmp(pService->m_pcService, p_pcService)) &&
(0 == strcmp(pService->m_pcProtocol, p_pcProtocol))) {
break;
}
pService = pService->m_pNext;
}
return pService;
}
/*
* MDNSResponder::_findService
*/
MDNSResponder::stcMDNSService* MDNSResponder::_findService(const MDNSResponder::hMDNSService p_hService) {
stcMDNSService* pService = m_pServices;
while (pService) {
if (p_hService == (hMDNSService)pService) {
break;
}
pService = pService->m_pNext;
}
return pService;
}
/*
* SERVICE TXT
*/
/*
* MDNSResponder::_allocServiceTxt
*/
MDNSResponder::stcMDNSServiceTxt* MDNSResponder::_allocServiceTxt(MDNSResponder::stcMDNSService* p_pService,
const char* p_pcKey,
const char* p_pcValue,
bool p_bTemp) {
stcMDNSServiceTxt* pTxt = 0;
if ((p_pService) &&
(p_pcKey) &&
(MDNS_SERVICE_TXT_MAXLENGTH > (p_pService->m_Txts.length() +
1 + // Length byte
(p_pcKey ? strlen(p_pcKey) : 0) +
1 + // '='
(p_pcValue ? strlen(p_pcValue) : 0)))) {
pTxt = new stcMDNSServiceTxt;
if (pTxt) {
size_t stLength = (p_pcKey ? strlen(p_pcKey) : 0);
pTxt->m_pcKey = new char[stLength + 1];
if (pTxt->m_pcKey) {
strncpy(pTxt->m_pcKey, p_pcKey, stLength); pTxt->m_pcKey[stLength] = 0;
}
if (p_pcValue) {
stLength = (p_pcValue ? strlen(p_pcValue) : 0);
pTxt->m_pcValue = new char[stLength + 1];
if (pTxt->m_pcValue) {
strncpy(pTxt->m_pcValue, p_pcValue, stLength); pTxt->m_pcValue[stLength] = 0;
}
}
pTxt->m_bTemp = p_bTemp;
// Add to list (or start list)
p_pService->m_Txts.add(pTxt);
}
}
return pTxt;
}
/*
* MDNSResponder::_releaseServiceTxt
*/
bool MDNSResponder::_releaseServiceTxt(MDNSResponder::stcMDNSService* p_pService,
MDNSResponder::stcMDNSServiceTxt* p_pTxt) {
return ((p_pService) &&
(p_pTxt) &&
(p_pService->m_Txts.remove(p_pTxt)));
}
/*
* MDNSResponder::_updateServiceTxt
*/
MDNSResponder::stcMDNSServiceTxt* MDNSResponder::_updateServiceTxt(MDNSResponder::stcMDNSService* p_pService,
MDNSResponder::stcMDNSServiceTxt* p_pTxt,
const char* p_pcValue,
bool p_bTemp) {
if ((p_pService) &&
(p_pTxt) &&
(MDNS_SERVICE_TXT_MAXLENGTH > (p_pService->m_Txts.length() -
(p_pTxt->m_pcValue ? strlen(p_pTxt->m_pcValue) : 0) +
(p_pcValue ? strlen(p_pcValue) : 0)))) {
p_pTxt->update(p_pcValue);
p_pTxt->m_bTemp = p_bTemp;
}
return p_pTxt;
}
/*
* MDNSResponder::_findServiceTxt
*/
MDNSResponder::stcMDNSServiceTxt* MDNSResponder::_findServiceTxt(MDNSResponder::stcMDNSService* p_pService,
const char* p_pcKey) {
return (p_pService ? p_pService->m_Txts.find(p_pcKey) : 0);
}
/*
* MDNSResponder::_findServiceTxt
*/
MDNSResponder::stcMDNSServiceTxt* MDNSResponder::_findServiceTxt(MDNSResponder::stcMDNSService* p_pService,
const hMDNSTxt p_hTxt) {
return (((p_pService) && (p_hTxt)) ? p_pService->m_Txts.find((stcMDNSServiceTxt*)p_hTxt) : 0);
}
/*
* MDNSResponder::_addServiceTxt
*/
MDNSResponder::stcMDNSServiceTxt* MDNSResponder::_addServiceTxt(MDNSResponder::stcMDNSService* p_pService,
const char* p_pcKey,
const char* p_pcValue,
bool p_bTemp) {
stcMDNSServiceTxt* pResult = 0;
if ((p_pService) &&
(p_pcKey) &&
(strlen(p_pcKey))) {
stcMDNSServiceTxt* pTxt = p_pService->m_Txts.find(p_pcKey);
if (pTxt) {
pResult = _updateServiceTxt(p_pService, pTxt, p_pcValue, p_bTemp);
}
else {
pResult = _allocServiceTxt(p_pService, p_pcKey, p_pcValue, p_bTemp);
}
}
return pResult;
}
MDNSResponder::stcMDNSServiceTxt* MDNSResponder::_answerKeyValue(const hMDNSServiceQuery p_hServiceQuery,
const uint32_t p_u32AnswerIndex) {
stcMDNSServiceQuery* pServiceQuery = _findServiceQuery(p_hServiceQuery);
stcMDNSServiceQuery::stcAnswer* pSQAnswer = (pServiceQuery ? pServiceQuery->answerAtIndex(p_u32AnswerIndex) : 0);
// Fill m_pcTxts (if not already done)
return (pSQAnswer) ? pSQAnswer->m_Txts.m_pTxts : 0;
}
/*
* MDNSResponder::_collectServiceTxts
*/
bool MDNSResponder::_collectServiceTxts(MDNSResponder::stcMDNSService& p_rService) {
// Call Dynamic service callbacks
if (m_fnServiceTxtCallback) {
m_fnServiceTxtCallback((hMDNSService)&p_rService);
}
if (p_rService.m_fnTxtCallback) {
p_rService.m_fnTxtCallback((hMDNSService)&p_rService);
}
return true;
}
/*
* MDNSResponder::_releaseTempServiceTxts
*/
bool MDNSResponder::_releaseTempServiceTxts(MDNSResponder::stcMDNSService& p_rService) {
return (p_rService.m_Txts.removeTempTxts());
}
/*
* MISC
*/
#ifdef DEBUG_ESP_MDNS_RESPONDER
/*
* MDNSResponder::_printRRDomain
*/
bool MDNSResponder::_printRRDomain(const MDNSResponder::stcMDNS_RRDomain& p_RRDomain) const {
//DEBUG_OUTPUT.printf_P(PSTR("Domain: "));
const char* pCursor = p_RRDomain.m_acName;
uint8_t u8Length = *pCursor++;
if (u8Length) {
while (u8Length) {
for (uint8_t u=0; u<u8Length; ++u) {
DEBUG_OUTPUT.printf_P(PSTR("%c"), *(pCursor++));
}
u8Length = *pCursor++;
if (u8Length) {
DEBUG_OUTPUT.printf_P(PSTR("."));
}
}
}
else { // empty domain
DEBUG_OUTPUT.printf_P(PSTR("-empty-"));
}
//DEBUG_OUTPUT.printf_P(PSTR("\n"));
return true;
}
/*
* MDNSResponder::_printRRAnswer
*/
bool MDNSResponder::_printRRAnswer(const MDNSResponder::stcMDNS_RRAnswer& p_RRAnswer) const {
DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] RRAnswer: "));
_printRRDomain(p_RRAnswer.m_Header.m_Domain);
DEBUG_OUTPUT.printf_P(PSTR(" Type:0x%04X Class:0x%04X TTL:%u, "), p_RRAnswer.m_Header.m_Attributes.m_u16Type, p_RRAnswer.m_Header.m_Attributes.m_u16Class, p_RRAnswer.m_u32TTL);
switch (p_RRAnswer.m_Header.m_Attributes.m_u16Type & (~0x8000)) { // Topmost bit might carry 'cache flush' flag
#ifdef MDNS_IP4_SUPPORT
case DNS_RRTYPE_A:
DEBUG_OUTPUT.printf_P(PSTR("A IP:%s"), ((const stcMDNS_RRAnswerA*)&p_RRAnswer)->m_IPAddress.toString().c_str());
break;
#endif
case DNS_RRTYPE_PTR:
DEBUG_OUTPUT.printf_P(PSTR("PTR "));
_printRRDomain(((const stcMDNS_RRAnswerPTR*)&p_RRAnswer)->m_PTRDomain);
break;
case DNS_RRTYPE_TXT: {
size_t stTxtLength = ((const stcMDNS_RRAnswerTXT*)&p_RRAnswer)->m_Txts.c_strLength();
char* pTxts = new char[stTxtLength];
if (pTxts) {
((/*const c_str()!!*/stcMDNS_RRAnswerTXT*)&p_RRAnswer)->m_Txts.c_str(pTxts);
DEBUG_OUTPUT.printf_P(PSTR("TXT(%u) %s"), stTxtLength, pTxts);
delete[] pTxts;
}
break;
}
#ifdef MDNS_IP6_SUPPORT
case DNS_RRTYPE_AAAA:
DEBUG_OUTPUT.printf_P(PSTR("AAAA IP:%s"), ((stcMDNS_RRAnswerA*&)p_rpRRAnswer)->m_IPAddress.toString().c_str());
break;
#endif
case DNS_RRTYPE_SRV:
DEBUG_OUTPUT.printf_P(PSTR("SRV Port:%u "), ((const stcMDNS_RRAnswerSRV*)&p_RRAnswer)->m_u16Port);
_printRRDomain(((const stcMDNS_RRAnswerSRV*)&p_RRAnswer)->m_SRVDomain);
break;
default:
DEBUG_OUTPUT.printf_P(PSTR("generic "));
break;
}
DEBUG_OUTPUT.printf_P(PSTR("\n"));
return true;
}
#endif
} // namespace MDNSImplementation
} // namespace esp8266