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

2219 lines
60 KiB
C++

/*
* LEAmDNS_Structs.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 "LEAmDNS_Priv.h"
#include "LEAmDNS_lwIPdefs.h"
namespace esp8266 {
/*
* LEAmDNS
*/
namespace MDNSImplementation {
/**
* STRUCTS
*/
/**
* MDNSResponder::stcMDNSServiceTxt
*
* One MDNS TXT item.
* m_pcValue may be '\0'.
* Objects can be chained together (list, m_pNext).
* A 'm_bTemp' flag differentiates between static and dynamic items.
* Output as byte array 'c#=1' is supported.
*/
/*
* MDNSResponder::stcMDNSServiceTxt::stcMDNSServiceTxt constructor
*/
MDNSResponder::stcMDNSServiceTxt::stcMDNSServiceTxt(const char* p_pcKey /*= 0*/,
const char* p_pcValue /*= 0*/,
bool p_bTemp /*= false*/)
: m_pNext(0),
m_pcKey(0),
m_pcValue(0),
m_bTemp(p_bTemp) {
setKey(p_pcKey);
setValue(p_pcValue);
}
/*
* MDNSResponder::stcMDNSServiceTxt::stcMDNSServiceTxt copy-constructor
*/
MDNSResponder::stcMDNSServiceTxt::stcMDNSServiceTxt(const MDNSResponder::stcMDNSServiceTxt& p_Other)
: m_pNext(0),
m_pcKey(0),
m_pcValue(0),
m_bTemp(false) {
operator=(p_Other);
}
/*
* MDNSResponder::stcMDNSServiceTxt::~stcMDNSServiceTxt destructor
*/
MDNSResponder::stcMDNSServiceTxt::~stcMDNSServiceTxt(void) {
clear();
}
/*
* MDNSResponder::stcMDNSServiceTxt::operator=
*/
MDNSResponder::stcMDNSServiceTxt& MDNSResponder::stcMDNSServiceTxt::operator=(const MDNSResponder::stcMDNSServiceTxt& p_Other) {
if (&p_Other != this) {
clear();
set(p_Other.m_pcKey, p_Other.m_pcValue, p_Other.m_bTemp);
}
return *this;
}
/*
* MDNSResponder::stcMDNSServiceTxt::clear
*/
bool MDNSResponder::stcMDNSServiceTxt::clear(void) {
releaseKey();
releaseValue();
return true;
}
/*
* MDNSResponder::stcMDNSServiceTxt::allocKey
*/
char* MDNSResponder::stcMDNSServiceTxt::allocKey(size_t p_stLength) {
releaseKey();
if (p_stLength) {
m_pcKey = new char[p_stLength + 1];
}
return m_pcKey;
}
/*
* MDNSResponder::stcMDNSServiceTxt::setKey
*/
bool MDNSResponder::stcMDNSServiceTxt::setKey(const char* p_pcKey,
size_t p_stLength) {
bool bResult = false;
releaseKey();
if (p_stLength) {
if (allocKey(p_stLength)) {
strncpy(m_pcKey, p_pcKey, p_stLength);
m_pcKey[p_stLength] = 0;
bResult = true;
}
}
return bResult;
}
/*
* MDNSResponder::stcMDNSServiceTxt::setKey
*/
bool MDNSResponder::stcMDNSServiceTxt::setKey(const char* p_pcKey) {
return setKey(p_pcKey, (p_pcKey ? strlen(p_pcKey) : 0));
}
/*
* MDNSResponder::stcMDNSServiceTxt::releaseKey
*/
bool MDNSResponder::stcMDNSServiceTxt::releaseKey(void) {
if (m_pcKey) {
delete[] m_pcKey;
m_pcKey = 0;
}
return true;
}
/*
* MDNSResponder::stcMDNSServiceTxt::allocValue
*/
char* MDNSResponder::stcMDNSServiceTxt::allocValue(size_t p_stLength) {
releaseValue();
if (p_stLength) {
m_pcValue = new char[p_stLength + 1];
}
return m_pcValue;
}
/*
* MDNSResponder::stcMDNSServiceTxt::setValue
*/
bool MDNSResponder::stcMDNSServiceTxt::setValue(const char* p_pcValue,
size_t p_stLength) {
bool bResult = false;
releaseValue();
if (p_stLength) {
if (allocValue(p_stLength)) {
strncpy(m_pcValue, p_pcValue, p_stLength);
m_pcValue[p_stLength] = 0;
bResult = true;
}
}
else { // No value -> also OK
bResult = true;
}
return bResult;
}
/*
* MDNSResponder::stcMDNSServiceTxt::setValue
*/
bool MDNSResponder::stcMDNSServiceTxt::setValue(const char* p_pcValue) {
return setValue(p_pcValue, (p_pcValue ? strlen(p_pcValue) : 0));
}
/*
* MDNSResponder::stcMDNSServiceTxt::releaseValue
*/
bool MDNSResponder::stcMDNSServiceTxt::releaseValue(void) {
if (m_pcValue) {
delete[] m_pcValue;
m_pcValue = 0;
}
return true;
}
/*
* MDNSResponder::stcMDNSServiceTxt::set
*/
bool MDNSResponder::stcMDNSServiceTxt::set(const char* p_pcKey,
const char* p_pcValue,
bool p_bTemp /*= false*/) {
m_bTemp = p_bTemp;
return ((setKey(p_pcKey)) &&
(setValue(p_pcValue)));
}
/*
* MDNSResponder::stcMDNSServiceTxt::update
*/
bool MDNSResponder::stcMDNSServiceTxt::update(const char* p_pcValue) {
return setValue(p_pcValue);
}
/*
* MDNSResponder::stcMDNSServiceTxt::length
*
* length of eg. 'c#=1' without any closing '\0'
*/
size_t MDNSResponder::stcMDNSServiceTxt::length(void) const {
size_t stLength = 0;
if (m_pcKey) {
stLength += strlen(m_pcKey); // Key
stLength += 1; // '='
stLength += (m_pcValue ? strlen(m_pcValue) : 0); // Value
}
return stLength;
}
/**
* MDNSResponder::stcMDNSServiceTxts
*
* A list of zero or more MDNS TXT items.
* Dynamic TXT items can be removed by 'removeTempTxts'.
* A TXT item can be looke up by its 'key' member.
* Export as ';'-separated byte array is supported.
* Export as 'length byte coded' byte array is supported.
* Comparision ((all A TXT items in B and equal) AND (all B TXT items in A and equal)) is supported.
*
*/
/*
* MDNSResponder::stcMDNSServiceTxts::stcMDNSServiceTxts contructor
*/
MDNSResponder::stcMDNSServiceTxts::stcMDNSServiceTxts(void)
: m_pTxts(0) {
}
/*
* MDNSResponder::stcMDNSServiceTxts::stcMDNSServiceTxts copy-constructor
*/
MDNSResponder::stcMDNSServiceTxts::stcMDNSServiceTxts(const stcMDNSServiceTxts& p_Other)
: m_pTxts(0) {
operator=(p_Other);
}
/*
* MDNSResponder::stcMDNSServiceTxts::~stcMDNSServiceTxts destructor
*/
MDNSResponder::stcMDNSServiceTxts::~stcMDNSServiceTxts(void) {
clear();
}
/*
* MDNSResponder::stcMDNSServiceTxts::operator=
*/
MDNSResponder::stcMDNSServiceTxts& MDNSResponder::stcMDNSServiceTxts::operator=(const stcMDNSServiceTxts& p_Other) {
if (this != &p_Other) {
clear();
for (stcMDNSServiceTxt* pOtherTxt=p_Other.m_pTxts; pOtherTxt; pOtherTxt=pOtherTxt->m_pNext) {
add(new stcMDNSServiceTxt(*pOtherTxt));
}
}
return *this;
}
/*
* MDNSResponder::stcMDNSServiceTxts::clear
*/
bool MDNSResponder::stcMDNSServiceTxts::clear(void) {
while (m_pTxts) {
stcMDNSServiceTxt* pNext = m_pTxts->m_pNext;
delete m_pTxts;
m_pTxts = pNext;
}
return true;
}
/*
* MDNSResponder::stcMDNSServiceTxts::add
*/
bool MDNSResponder::stcMDNSServiceTxts::add(MDNSResponder::stcMDNSServiceTxt* p_pTxt) {
bool bResult = false;
if (p_pTxt) {
p_pTxt->m_pNext = m_pTxts;
m_pTxts = p_pTxt;
bResult = true;
}
return bResult;
}
/*
* MDNSResponder::stcMDNSServiceTxts::remove
*/
bool MDNSResponder::stcMDNSServiceTxts::remove(stcMDNSServiceTxt* p_pTxt) {
bool bResult = false;
if (p_pTxt) {
stcMDNSServiceTxt* pPred = m_pTxts;
while ((pPred) &&
(pPred->m_pNext != p_pTxt)) {
pPred = pPred->m_pNext;
}
if (pPred) {
pPred->m_pNext = p_pTxt->m_pNext;
delete p_pTxt;
bResult = true;
}
else if (m_pTxts == p_pTxt) { // No predecesor, but first item
m_pTxts = p_pTxt->m_pNext;
delete p_pTxt;
bResult = true;
}
}
return bResult;
}
/*
* MDNSResponder::stcMDNSServiceTxts::removeTempTxts
*/
bool MDNSResponder::stcMDNSServiceTxts::removeTempTxts(void) {
bool bResult = true;
stcMDNSServiceTxt* pTxt = m_pTxts;
while ((bResult) &&
(pTxt)) {
stcMDNSServiceTxt* pNext = pTxt->m_pNext;
if (pTxt->m_bTemp) {
bResult = remove(pTxt);
}
pTxt = pNext;
}
return bResult;
}
/*
* MDNSResponder::stcMDNSServiceTxts::find
*/
MDNSResponder::stcMDNSServiceTxt* MDNSResponder::stcMDNSServiceTxts::find(const char* p_pcKey) {
stcMDNSServiceTxt* pResult = 0;
for (stcMDNSServiceTxt* pTxt=m_pTxts; pTxt; pTxt=pTxt->m_pNext) {
if ((p_pcKey) &&
(0 == strcmp(pTxt->m_pcKey, p_pcKey))) {
pResult = pTxt;
break;
}
}
return pResult;
}
/*
* MDNSResponder::stcMDNSServiceTxts::find
*/
const MDNSResponder::stcMDNSServiceTxt* MDNSResponder::stcMDNSServiceTxts::find(const char* p_pcKey) const {
const stcMDNSServiceTxt* pResult = 0;
for (const stcMDNSServiceTxt* pTxt=m_pTxts; pTxt; pTxt=pTxt->m_pNext) {
if ((p_pcKey) &&
(0 == strcmp(pTxt->m_pcKey, p_pcKey))) {
pResult = pTxt;
break;
}
}
return pResult;
}
/*
* MDNSResponder::stcMDNSServiceTxts::find
*/
MDNSResponder::stcMDNSServiceTxt* MDNSResponder::stcMDNSServiceTxts::find(const stcMDNSServiceTxt* p_pTxt) {
stcMDNSServiceTxt* pResult = 0;
for (stcMDNSServiceTxt* pTxt=m_pTxts; pTxt; pTxt=pTxt->m_pNext) {
if (p_pTxt == pTxt) {
pResult = pTxt;
break;
}
}
return pResult;
}
/*
* MDNSResponder::stcMDNSServiceTxts::length
*/
uint16_t MDNSResponder::stcMDNSServiceTxts::length(void) const {
uint16_t u16Length = 0;
stcMDNSServiceTxt* pTxt = m_pTxts;
while (pTxt) {
u16Length += 1; // Length byte
u16Length += pTxt->length(); // Text
pTxt = pTxt->m_pNext;
}
return u16Length;
}
/*
* MDNSResponder::stcMDNSServiceTxts::c_strLength
*
* (incl. closing '\0'). Length bytes place is used for delimiting ';' and closing '\0'
*/
size_t MDNSResponder::stcMDNSServiceTxts::c_strLength(void) const {
return length();
}
/*
* MDNSResponder::stcMDNSServiceTxts::c_str
*/
bool MDNSResponder::stcMDNSServiceTxts::c_str(char* p_pcBuffer) {
bool bResult = false;
if (p_pcBuffer) {
bResult = true;
*p_pcBuffer = 0;
for (stcMDNSServiceTxt* pTxt=m_pTxts; ((bResult) && (pTxt)); pTxt = pTxt->m_pNext) {
size_t stLength;
if ((bResult = (0 != (stLength = (pTxt->m_pcKey ? strlen(pTxt->m_pcKey) : 0))))) {
if (pTxt != m_pTxts) {
*p_pcBuffer++ = ';';
}
strncpy(p_pcBuffer, pTxt->m_pcKey, stLength); p_pcBuffer[stLength] = 0;
p_pcBuffer += stLength;
*p_pcBuffer++ = '=';
if ((stLength = (pTxt->m_pcValue ? strlen(pTxt->m_pcValue) : 0))) {
strncpy(p_pcBuffer, pTxt->m_pcValue, stLength); p_pcBuffer[stLength] = 0;
p_pcBuffer += stLength;
}
}
}
*p_pcBuffer++ = 0;
}
return bResult;
}
/*
* MDNSResponder::stcMDNSServiceTxts::bufferLength
*
* (incl. closing '\0').
*/
size_t MDNSResponder::stcMDNSServiceTxts::bufferLength(void) const {
return (length() + 1);
}
/*
* MDNSResponder::stcMDNSServiceTxts::toBuffer
*/
bool MDNSResponder::stcMDNSServiceTxts::buffer(char* p_pcBuffer) {
bool bResult = false;
if (p_pcBuffer) {
bResult = true;
*p_pcBuffer = 0;
for (stcMDNSServiceTxt* pTxt=m_pTxts; ((bResult) && (pTxt)); pTxt = pTxt->m_pNext) {
*(unsigned char*)p_pcBuffer++ = pTxt->length();
size_t stLength;
if ((bResult = (0 != (stLength = (pTxt->m_pcKey ? strlen(pTxt->m_pcKey) : 0))))) {
memcpy(p_pcBuffer, pTxt->m_pcKey, stLength);
p_pcBuffer += stLength;
*p_pcBuffer++ = '=';
if ((stLength = (pTxt->m_pcValue ? strlen(pTxt->m_pcValue) : 0))) {
memcpy(p_pcBuffer, pTxt->m_pcValue, stLength);
p_pcBuffer += stLength;
}
}
}
*p_pcBuffer++ = 0;
}
return bResult;
}
/*
* MDNSResponder::stcMDNSServiceTxts::compare
*/
bool MDNSResponder::stcMDNSServiceTxts::compare(const MDNSResponder::stcMDNSServiceTxts& p_Other) const {
bool bResult = false;
if ((bResult = (length() == p_Other.length()))) {
// Compare A->B
for (const stcMDNSServiceTxt* pTxt=m_pTxts; ((bResult) && (pTxt)); pTxt=pTxt->m_pNext) {
const stcMDNSServiceTxt* pOtherTxt = p_Other.find(pTxt->m_pcKey);
bResult = ((pOtherTxt) &&
(pTxt->m_pcValue) &&
(pOtherTxt->m_pcValue) &&
(strlen(pTxt->m_pcValue) == strlen(pOtherTxt->m_pcValue)) &&
(0 == strcmp(pTxt->m_pcValue, pOtherTxt->m_pcValue)));
}
// Compare B->A
for (const stcMDNSServiceTxt* pOtherTxt=p_Other.m_pTxts; ((bResult) && (pOtherTxt)); pOtherTxt=pOtherTxt->m_pNext) {
const stcMDNSServiceTxt* pTxt = find(pOtherTxt->m_pcKey);
bResult = ((pTxt) &&
(pOtherTxt->m_pcValue) &&
(pTxt->m_pcValue) &&
(strlen(pOtherTxt->m_pcValue) == strlen(pTxt->m_pcValue)) &&
(0 == strcmp(pOtherTxt->m_pcValue, pTxt->m_pcValue)));
}
}
return bResult;
}
/*
* MDNSResponder::stcMDNSServiceTxts::operator==
*/
bool MDNSResponder::stcMDNSServiceTxts::operator==(const stcMDNSServiceTxts& p_Other) const {
return compare(p_Other);
}
/*
* MDNSResponder::stcMDNSServiceTxts::operator!=
*/
bool MDNSResponder::stcMDNSServiceTxts::operator!=(const stcMDNSServiceTxts& p_Other) const {
return !compare(p_Other);
}
/**
* MDNSResponder::stcMDNS_MsgHeader
*
* A MDNS message haeder.
*
*/
/*
* MDNSResponder::stcMDNS_MsgHeader::stcMDNS_MsgHeader
*/
MDNSResponder::stcMDNS_MsgHeader::stcMDNS_MsgHeader(uint16_t p_u16ID /*= 0*/,
bool p_bQR /*= false*/,
unsigned char p_ucOpcode /*= 0*/,
bool p_bAA /*= false*/,
bool p_bTC /*= false*/,
bool p_bRD /*= false*/,
bool p_bRA /*= false*/,
unsigned char p_ucRCode /*= 0*/,
uint16_t p_u16QDCount /*= 0*/,
uint16_t p_u16ANCount /*= 0*/,
uint16_t p_u16NSCount /*= 0*/,
uint16_t p_u16ARCount /*= 0*/)
: m_u16ID(p_u16ID),
m_1bQR(p_bQR), m_4bOpcode(p_ucOpcode), m_1bAA(p_bAA), m_1bTC(p_bTC), m_1bRD(p_bRD),
m_1bRA(p_bRA), m_3bZ(0), m_4bRCode(p_ucRCode),
m_u16QDCount(p_u16QDCount),
m_u16ANCount(p_u16ANCount),
m_u16NSCount(p_u16NSCount),
m_u16ARCount(p_u16ARCount) {
}
/**
* MDNSResponder::stcMDNS_RRDomain
*
* A MDNS domain object.
* The labels of the domain are stored (DNS-like encoded) in 'm_acName':
* [length byte]varlength label[length byte]varlength label[0]
* 'm_u16NameLength' stores the used length of 'm_acName'.
* Dynamic label addition is supported.
* Comparison is supported.
* Export as byte array 'esp8266.local' is supported.
*
*/
/*
* MDNSResponder::stcMDNS_RRDomain::stcMDNS_RRDomain constructor
*/
MDNSResponder::stcMDNS_RRDomain::stcMDNS_RRDomain(void)
: m_u16NameLength(0) {
clear();
}
/*
* MDNSResponder::stcMDNS_RRDomain::stcMDNS_RRDomain copy-constructor
*/
MDNSResponder::stcMDNS_RRDomain::stcMDNS_RRDomain(const stcMDNS_RRDomain& p_Other)
: m_u16NameLength(0) {
operator=(p_Other);
}
/*
* MDNSResponder::stcMDNS_RRDomain::operator =
*/
MDNSResponder::stcMDNS_RRDomain& MDNSResponder::stcMDNS_RRDomain::operator=(const stcMDNS_RRDomain& p_Other) {
if (&p_Other != this) {
memcpy(m_acName, p_Other.m_acName, sizeof(m_acName));
m_u16NameLength = p_Other.m_u16NameLength;
}
return *this;
}
/*
* MDNSResponder::stcMDNS_RRDomain::clear
*/
bool MDNSResponder::stcMDNS_RRDomain::clear(void) {
memset(m_acName, 0, sizeof(m_acName));
m_u16NameLength = 0;
return true;
}
/*
* MDNSResponder::stcMDNS_RRDomain::addLabel
*/
bool MDNSResponder::stcMDNS_RRDomain::addLabel(const char* p_pcLabel,
bool p_bPrependUnderline /*= false*/) {
bool bResult = false;
size_t stLength = (p_pcLabel
? (strlen(p_pcLabel) + (p_bPrependUnderline ? 1 : 0))
: 0);
if ((MDNS_DOMAIN_LABEL_MAXLENGTH >= stLength) &&
(MDNS_DOMAIN_MAXLENGTH >= (m_u16NameLength + (1 + stLength)))) {
// Length byte
m_acName[m_u16NameLength] = (unsigned char)stLength; // Might be 0!
++m_u16NameLength;
// Label
if (stLength) {
if (p_bPrependUnderline) {
m_acName[m_u16NameLength++] = '_';
--stLength;
}
strncpy(&(m_acName[m_u16NameLength]), p_pcLabel, stLength); m_acName[m_u16NameLength + stLength] = 0;
m_u16NameLength += stLength;
}
bResult = true;
}
return bResult;
}
/*
* MDNSResponder::stcMDNS_RRDomain::compare
*/
bool MDNSResponder::stcMDNS_RRDomain::compare(const stcMDNS_RRDomain& p_Other) const {
bool bResult = false;
if (m_u16NameLength == p_Other.m_u16NameLength) {
const char* pT = m_acName;
const char* pO = p_Other.m_acName;
while ((pT) &&
(pO) &&
(*((unsigned char*)pT) == *((unsigned char*)pO)) && // Same length AND
(0 == strncasecmp((pT + 1), (pO + 1), *((unsigned char*)pT)))) { // Same content
if (*((unsigned char*)pT)) { // Not 0
pT += (1 + *((unsigned char*)pT)); // Shift by length byte and lenght
pO += (1 + *((unsigned char*)pO));
}
else { // Is 0 -> Successfully reached the end
bResult = true;
break;
}
}
}
return bResult;
}
/*
* MDNSResponder::stcMDNS_RRDomain::operator ==
*/
bool MDNSResponder::stcMDNS_RRDomain::operator==(const stcMDNS_RRDomain& p_Other) const {
return compare(p_Other);
}
/*
* MDNSResponder::stcMDNS_RRDomain::operator !=
*/
bool MDNSResponder::stcMDNS_RRDomain::operator!=(const stcMDNS_RRDomain& p_Other) const {
return !compare(p_Other);
}
/*
* MDNSResponder::stcMDNS_RRDomain::operator >
*/
bool MDNSResponder::stcMDNS_RRDomain::operator>(const stcMDNS_RRDomain& p_Other) const {
// TODO: Check, if this is a good idea...
return !compare(p_Other);
}
/*
* MDNSResponder::stcMDNS_RRDomain::c_strLength
*/
size_t MDNSResponder::stcMDNS_RRDomain::c_strLength(void) const {
size_t stLength = 0;
unsigned char* pucLabelLength = (unsigned char*)m_acName;
while (*pucLabelLength) {
stLength += (*pucLabelLength + 1 /* +1 for '.' or '\0'*/);
pucLabelLength += (*pucLabelLength + 1);
}
return stLength;
}
/*
* MDNSResponder::stcMDNS_RRDomain::c_str
*/
bool MDNSResponder::stcMDNS_RRDomain::c_str(char* p_pcBuffer) {
bool bResult = false;
if (p_pcBuffer) {
*p_pcBuffer = 0;
unsigned char* pucLabelLength = (unsigned char*)m_acName;
while (*pucLabelLength) {
memcpy(p_pcBuffer, (const char*)(pucLabelLength + 1), *pucLabelLength);
p_pcBuffer += *pucLabelLength;
pucLabelLength += (*pucLabelLength + 1);
*p_pcBuffer++ = (*pucLabelLength ? '.' : '\0');
}
bResult = true;
}
return bResult;
}
/**
* MDNSResponder::stcMDNS_RRAttributes
*
* A MDNS attributes object.
*
*/
/*
* MDNSResponder::stcMDNS_RRAttributes::stcMDNS_RRAttributes constructor
*/
MDNSResponder::stcMDNS_RRAttributes::stcMDNS_RRAttributes(uint16_t p_u16Type /*= 0*/,
uint16_t p_u16Class /*= 1 DNS_RRCLASS_IN Internet*/)
: m_u16Type(p_u16Type),
m_u16Class(p_u16Class) {
}
/*
* MDNSResponder::stcMDNS_RRAttributes::stcMDNS_RRAttributes copy-constructor
*/
MDNSResponder::stcMDNS_RRAttributes::stcMDNS_RRAttributes(const MDNSResponder::stcMDNS_RRAttributes& p_Other) {
operator=(p_Other);
}
/*
* MDNSResponder::stcMDNS_RRAttributes::operator =
*/
MDNSResponder::stcMDNS_RRAttributes& MDNSResponder::stcMDNS_RRAttributes::operator=(const MDNSResponder::stcMDNS_RRAttributes& p_Other) {
if (&p_Other != this) {
m_u16Type = p_Other.m_u16Type;
m_u16Class = p_Other.m_u16Class;
}
return *this;
}
/**
* MDNSResponder::stcMDNS_RRHeader
*
* A MDNS record header (domain and attributes) object.
*
*/
/*
* MDNSResponder::stcMDNS_RRHeader::stcMDNS_RRHeader constructor
*/
MDNSResponder::stcMDNS_RRHeader::stcMDNS_RRHeader(void) {
}
/*
* MDNSResponder::stcMDNS_RRHeader::stcMDNS_RRHeader copy-constructor
*/
MDNSResponder::stcMDNS_RRHeader::stcMDNS_RRHeader(const stcMDNS_RRHeader& p_Other) {
operator=(p_Other);
}
/*
* MDNSResponder::stcMDNS_RRHeader::operator =
*/
MDNSResponder::stcMDNS_RRHeader& MDNSResponder::stcMDNS_RRHeader::operator=(const MDNSResponder::stcMDNS_RRHeader& p_Other) {
if (&p_Other != this) {
m_Domain = p_Other.m_Domain;
m_Attributes = p_Other.m_Attributes;
}
return *this;
}
/*
* MDNSResponder::stcMDNS_RRHeader::clear
*/
bool MDNSResponder::stcMDNS_RRHeader::clear(void) {
m_Domain.clear();
return true;
}
/**
* MDNSResponder::stcMDNS_RRQuestion
*
* A MDNS question record object (header + question flags)
*
*/
/*
* MDNSResponder::stcMDNS_RRQuestion::stcMDNS_RRQuestion constructor
*/
MDNSResponder::stcMDNS_RRQuestion::stcMDNS_RRQuestion(void)
: m_pNext(0),
m_bUnicast(false) {
}
/**
* MDNSResponder::stcMDNS_RRAnswer
*
* A MDNS answer record object (header + answer content).
* This is a 'virtual' base class for all other MDNS answer classes.
*
*/
/*
* MDNSResponder::stcMDNS_RRAnswer::stcMDNS_RRAnswer constructor
*/
MDNSResponder::stcMDNS_RRAnswer::stcMDNS_RRAnswer(enuAnswerType p_AnswerType,
const MDNSResponder::stcMDNS_RRHeader& p_Header,
uint32_t p_u32TTL)
: m_pNext(0),
m_AnswerType(p_AnswerType),
m_Header(p_Header),
m_u32TTL(p_u32TTL) {
// Extract 'cache flush'-bit
m_bCacheFlush = (m_Header.m_Attributes.m_u16Class & 0x8000);
m_Header.m_Attributes.m_u16Class &= (~0x8000);
}
/*
* MDNSResponder::stcMDNS_RRAnswer::~stcMDNS_RRAnswer destructor
*/
MDNSResponder::stcMDNS_RRAnswer::~stcMDNS_RRAnswer(void) {
}
/*
* MDNSResponder::stcMDNS_RRAnswer::answerType
*/
MDNSResponder::enuAnswerType MDNSResponder::stcMDNS_RRAnswer::answerType(void) const {
return m_AnswerType;
}
/*
* MDNSResponder::stcMDNS_RRAnswer::clear
*/
bool MDNSResponder::stcMDNS_RRAnswer::clear(void) {
m_pNext = 0;
m_Header.clear();
return true;
}
/**
* MDNSResponder::stcMDNS_RRAnswerA
*
* A MDNS A answer object.
* Extends the base class by an IP4 address member.
*
*/
#ifdef MDNS_IP4_SUPPORT
/*
* MDNSResponder::stcMDNS_RRAnswerA::stcMDNS_RRAnswerA constructor
*/
MDNSResponder::stcMDNS_RRAnswerA::stcMDNS_RRAnswerA(const MDNSResponder::stcMDNS_RRHeader& p_Header,
uint32_t p_u32TTL)
: stcMDNS_RRAnswer(AnswerType_A, p_Header, p_u32TTL),
m_IPAddress(0, 0, 0, 0) {
}
/*
* MDNSResponder::stcMDNS_RRAnswerA::stcMDNS_RRAnswerA destructor
*/
MDNSResponder::stcMDNS_RRAnswerA::~stcMDNS_RRAnswerA(void) {
clear();
}
/*
* MDNSResponder::stcMDNS_RRAnswerA::clear
*/
bool MDNSResponder::stcMDNS_RRAnswerA::clear(void) {
m_IPAddress = IPAddress(0, 0, 0, 0);
return true;
}
#endif
/**
* MDNSResponder::stcMDNS_RRAnswerPTR
*
* A MDNS PTR answer object.
* Extends the base class by a MDNS domain member.
*
*/
/*
* MDNSResponder::stcMDNS_RRAnswerPTR::stcMDNS_RRAnswerPTR constructor
*/
MDNSResponder::stcMDNS_RRAnswerPTR::stcMDNS_RRAnswerPTR(const MDNSResponder::stcMDNS_RRHeader& p_Header,
uint32_t p_u32TTL)
: stcMDNS_RRAnswer(AnswerType_PTR, p_Header, p_u32TTL) {
}
/*
* MDNSResponder::stcMDNS_RRAnswerPTR::~stcMDNS_RRAnswerPTR destructor
*/
MDNSResponder::stcMDNS_RRAnswerPTR::~stcMDNS_RRAnswerPTR(void) {
clear();
}
/*
* MDNSResponder::stcMDNS_RRAnswerPTR::clear
*/
bool MDNSResponder::stcMDNS_RRAnswerPTR::clear(void) {
m_PTRDomain.clear();
return true;
}
/**
* MDNSResponder::stcMDNS_RRAnswerTXT
*
* A MDNS TXT answer object.
* Extends the base class by a MDNS TXT items list member.
*
*/
/*
* MDNSResponder::stcMDNS_RRAnswerTXT::stcMDNS_RRAnswerTXT constructor
*/
MDNSResponder::stcMDNS_RRAnswerTXT::stcMDNS_RRAnswerTXT(const MDNSResponder::stcMDNS_RRHeader& p_Header,
uint32_t p_u32TTL)
: stcMDNS_RRAnswer(AnswerType_TXT, p_Header, p_u32TTL) {
}
/*
* MDNSResponder::stcMDNS_RRAnswerTXT::~stcMDNS_RRAnswerTXT destructor
*/
MDNSResponder::stcMDNS_RRAnswerTXT::~stcMDNS_RRAnswerTXT(void) {
clear();
}
/*
* MDNSResponder::stcMDNS_RRAnswerTXT::clear
*/
bool MDNSResponder::stcMDNS_RRAnswerTXT::clear(void) {
m_Txts.clear();
return true;
}
/**
* MDNSResponder::stcMDNS_RRAnswerAAAA
*
* A MDNS AAAA answer object.
* (Should) extend the base class by an IP6 address member.
*
*/
#ifdef MDNS_IP6_SUPPORT
/*
* MDNSResponder::stcMDNS_RRAnswerAAAA::stcMDNS_RRAnswerAAAA constructor
*/
MDNSResponder::stcMDNS_RRAnswerAAAA::stcMDNS_RRAnswerAAAA(const MDNSResponder::stcMDNS_RRHeader& p_Header,
uint32_t p_u32TTL)
: stcMDNS_RRAnswer(AnswerType_AAAA, p_Header, p_u32TTL) {
}
/*
* MDNSResponder::stcMDNS_RRAnswerAAAA::~stcMDNS_RRAnswerAAAA destructor
*/
MDNSResponder::stcMDNS_RRAnswerAAAA::~stcMDNS_RRAnswerAAAA(void) {
clear();
}
/*
* MDNSResponder::stcMDNS_RRAnswerAAAA::clear
*/
bool MDNSResponder::stcMDNS_RRAnswerAAAA::clear(void) {
return true;
}
#endif
/**
* MDNSResponder::stcMDNS_RRAnswerSRV
*
* A MDNS SRV answer object.
* Extends the base class by a port member.
*
*/
/*
* MDNSResponder::stcMDNS_RRAnswerSRV::stcMDNS_RRAnswerSRV constructor
*/
MDNSResponder::stcMDNS_RRAnswerSRV::stcMDNS_RRAnswerSRV(const MDNSResponder::stcMDNS_RRHeader& p_Header,
uint32_t p_u32TTL)
: stcMDNS_RRAnswer(AnswerType_SRV, p_Header, p_u32TTL),
m_u16Priority(0),
m_u16Weight(0),
m_u16Port(0) {
}
/*
* MDNSResponder::stcMDNS_RRAnswerSRV::~stcMDNS_RRAnswerSRV destructor
*/
MDNSResponder::stcMDNS_RRAnswerSRV::~stcMDNS_RRAnswerSRV(void) {
clear();
}
/*
* MDNSResponder::stcMDNS_RRAnswerSRV::clear
*/
bool MDNSResponder::stcMDNS_RRAnswerSRV::clear(void) {
m_u16Priority = 0;
m_u16Weight = 0;
m_u16Port = 0;
m_SRVDomain.clear();
return true;
}
/**
* MDNSResponder::stcMDNS_RRAnswerGeneric
*
* An unknown (generic) MDNS answer object.
* Extends the base class by a RDATA buffer member.
*
*/
/*
* MDNSResponder::stcMDNS_RRAnswerGeneric::stcMDNS_RRAnswerGeneric constructor
*/
MDNSResponder::stcMDNS_RRAnswerGeneric::stcMDNS_RRAnswerGeneric(const stcMDNS_RRHeader& p_Header,
uint32_t p_u32TTL)
: stcMDNS_RRAnswer(AnswerType_Generic, p_Header, p_u32TTL),
m_u16RDLength(0),
m_pu8RDData(0) {
}
/*
* MDNSResponder::stcMDNS_RRAnswerGeneric::~stcMDNS_RRAnswerGeneric destructor
*/
MDNSResponder::stcMDNS_RRAnswerGeneric::~stcMDNS_RRAnswerGeneric(void) {
clear();
}
/*
* MDNSResponder::stcMDNS_RRAnswerGeneric::clear
*/
bool MDNSResponder::stcMDNS_RRAnswerGeneric::clear(void) {
if (m_pu8RDData) {
delete[] m_pu8RDData;
m_pu8RDData = 0;
}
m_u16RDLength = 0;
return true;
}
/**
* MDNSResponder::stcProbeInformation
*
* Probing status information for a host or service domain
*
*/
/*
* MDNSResponder::stcProbeInformation::stcProbeInformation constructor
*/
MDNSResponder::stcProbeInformation::stcProbeInformation(void)
: m_ProbingStatus(ProbingStatus_WaitingForData),
m_u8SentCount(0),
m_Timeout(esp8266::polledTimeout::oneShotMs::neverExpires),
m_bConflict(false),
m_bTiebreakNeeded(false),
m_fnHostProbeResultCallback(0),
m_fnServiceProbeResultCallback(0) {
}
/*
* MDNSResponder::stcProbeInformation::clear
*/
bool MDNSResponder::stcProbeInformation::clear(bool p_bClearUserdata /*= false*/) {
m_ProbingStatus = ProbingStatus_WaitingForData;
m_u8SentCount = 0;
m_Timeout.resetToNeverExpires();
m_bConflict = false;
m_bTiebreakNeeded = false;
if (p_bClearUserdata) {
m_fnHostProbeResultCallback = 0;
m_fnServiceProbeResultCallback = 0;
}
return true;
}
/**
* MDNSResponder::stcMDNSService
*
* A MDNS service object (to be announced by the MDNS responder)
* The service instance may be '\0'; in this case the hostname is used
* and the flag m_bAutoName is set. If the hostname changes, all 'auto-
* named' services are renamed also.
* m_u8Replymask is used while preparing a response to a MDNS query. It is
* resetted in '_sendMDNSMessage' afterwards.
*/
/*
* MDNSResponder::stcMDNSService::stcMDNSService constructor
*/
MDNSResponder::stcMDNSService::stcMDNSService(const char* p_pcName /*= 0*/,
const char* p_pcService /*= 0*/,
const char* p_pcProtocol /*= 0*/)
: m_pNext(0),
m_pcName(0),
m_bAutoName(false),
m_pcService(0),
m_pcProtocol(0),
m_u16Port(0),
m_u8ReplyMask(0),
m_fnTxtCallback(0) {
setName(p_pcName);
setService(p_pcService);
setProtocol(p_pcProtocol);
}
/*
* MDNSResponder::stcMDNSService::~stcMDNSService destructor
*/
MDNSResponder::stcMDNSService::~stcMDNSService(void) {
releaseName();
releaseService();
releaseProtocol();
}
/*
* MDNSResponder::stcMDNSService::setName
*/
bool MDNSResponder::stcMDNSService::setName(const char* p_pcName) {
bool bResult = false;
releaseName();
size_t stLength = (p_pcName ? strlen(p_pcName) : 0);
if (stLength) {
if ((bResult = (0 != (m_pcName = new char[stLength + 1])))) {
strncpy(m_pcName, p_pcName, stLength);
m_pcName[stLength] = 0;
}
}
else {
bResult = true;
}
return bResult;
}
/*
* MDNSResponder::stcMDNSService::releaseName
*/
bool MDNSResponder::stcMDNSService::releaseName(void) {
if (m_pcName) {
delete[] m_pcName;
m_pcName = 0;
}
return true;
}
/*
* MDNSResponder::stcMDNSService::setService
*/
bool MDNSResponder::stcMDNSService::setService(const char* p_pcService) {
bool bResult = false;
releaseService();
size_t stLength = (p_pcService ? strlen(p_pcService) : 0);
if (stLength) {
if ((bResult = (0 != (m_pcService = new char[stLength + 1])))) {
strncpy(m_pcService, p_pcService, stLength);
m_pcService[stLength] = 0;
}
}
else {
bResult = true;
}
return bResult;
}
/*
* MDNSResponder::stcMDNSService::releaseService
*/
bool MDNSResponder::stcMDNSService::releaseService(void) {
if (m_pcService) {
delete[] m_pcService;
m_pcService = 0;
}
return true;
}
/*
* MDNSResponder::stcMDNSService::setProtocol
*/
bool MDNSResponder::stcMDNSService::setProtocol(const char* p_pcProtocol) {
bool bResult = false;
releaseProtocol();
size_t stLength = (p_pcProtocol ? strlen(p_pcProtocol) : 0);
if (stLength) {
if ((bResult = (0 != (m_pcProtocol = new char[stLength + 1])))) {
strncpy(m_pcProtocol, p_pcProtocol, stLength);
m_pcProtocol[stLength] = 0;
}
}
else {
bResult = true;
}
return bResult;
}
/*
* MDNSResponder::stcMDNSService::releaseProtocol
*/
bool MDNSResponder::stcMDNSService::releaseProtocol(void) {
if (m_pcProtocol) {
delete[] m_pcProtocol;
m_pcProtocol = 0;
}
return true;
}
/**
* MDNSResponder::stcMDNSServiceQuery
*
* A MDNS service query object.
* Service queries may be static or dynamic.
* As the static service query is processed in the blocking function 'queryService',
* only one static service service may exist. The processing of the answers is done
* on the WiFi-stack side of the ESP stack structure (via 'UDPContext.onRx(_update)').
*
*/
/**
* MDNSResponder::stcMDNSServiceQuery::stcAnswer
*
* One answer for a service query.
* Every answer must contain
* - a service instance entry (pivot),
* and may contain
* - a host domain,
* - a port
* - an IP4 address
* (- an IP6 address)
* - a MDNS TXTs
* The existance of a component is flaged in 'm_u32ContentFlags'.
* For every answer component a TTL value is maintained.
* Answer objects can be connected to a linked list.
*
* For the host domain, service domain and TXTs components, a char array
* representation can be retrieved (which is created on demand).
*
*/
/**
* MDNSResponder::stcMDNSServiceQuery::stcAnswer::stcTTL
*
* The TTL (Time-To-Live) for an specific answer content.
* The 80% and outdated states are calculated based on the current time (millis)
* and the 'set' time (also millis).
* If the answer is scheduled for an update, the corresponding flag should be set.
*
* /
/ *
* MDNSResponder::stcMDNSServiceQuery::stcAnswer::stcTTL::stcTTL constructor
* /
MDNSResponder::stcMDNSServiceQuery::stcAnswer::stcTTL::stcTTL(uint32_t p_u32TTL / *= 0* /)
: m_bUpdateScheduled(false) {
set(p_u32TTL * 1000);
}
/ *
* MDNSResponder::stcMDNSServiceQuery::stcAnswer::stcTTL::set
* /
bool MDNSResponder::stcMDNSServiceQuery::stcAnswer::stcTTL::set(uint32_t p_u32TTL) {
m_TTLTimeFlag.restart(p_u32TTL * 1000);
m_bUpdateScheduled = false;
return true;
}
/ *
* MDNSResponder::stcMDNSServiceQuery::stcAnswer::stcTTL::has80Percent
* /
bool MDNSResponder::stcMDNSServiceQuery::stcAnswer::stcTTL::has80Percent(void) const {
return ((m_TTLTimeFlag.getTimeout()) &&
(!m_bUpdateScheduled) &&
(m_TTLTimeFlag.hypotheticalTimeout((m_TTLTimeFlag.getTimeout() * 800) / 1000)));
}
/ *
* MDNSResponder::stcMDNSServiceQuery::stcAnswer::stcTTL::isOutdated
* /
bool MDNSResponder::stcMDNSServiceQuery::stcAnswer::stcTTL::isOutdated(void) const {
return ((m_TTLTimeFlag.getTimeout()) &&
(m_TTLTimeFlag.flagged()));
}*/
/**
* MDNSResponder::stcMDNSServiceQuery::stcAnswer::stcTTL
*
* The TTL (Time-To-Live) for an specific answer content.
* The 80% and outdated states are calculated based on the current time (millis)
* and the 'set' time (also millis).
* If the answer is scheduled for an update, the corresponding flag should be set.
*
*/
/*
* MDNSResponder::stcMDNSServiceQuery::stcAnswer::stcTTL::stcTTL constructor
*/
MDNSResponder::stcMDNSServiceQuery::stcAnswer::stcTTL::stcTTL(void)
: m_u32TTL(0),
m_TTLTimeout(esp8266::polledTimeout::oneShotMs::neverExpires),
m_timeoutLevel(TIMEOUTLEVEL_UNSET) {
}
/*
* MDNSResponder::stcMDNSServiceQuery::stcAnswer::stcTTL::set
*/
bool MDNSResponder::stcMDNSServiceQuery::stcAnswer::stcTTL::set(uint32_t p_u32TTL) {
m_u32TTL = p_u32TTL;
if (m_u32TTL) {
m_timeoutLevel = TIMEOUTLEVEL_BASE; // Set to 80%
m_TTLTimeout.reset(timeout());
}
else {
m_timeoutLevel = TIMEOUTLEVEL_UNSET; // undef
m_TTLTimeout.resetToNeverExpires();
}
return true;
}
/*
* MDNSResponder::stcMDNSServiceQuery::stcAnswer::stcTTL::flagged
*/
bool MDNSResponder::stcMDNSServiceQuery::stcAnswer::stcTTL::flagged(void) {
return ((m_u32TTL) &&
(TIMEOUTLEVEL_UNSET != m_timeoutLevel) &&
(m_TTLTimeout.expired()));
}
/*
* MDNSResponder::stcMDNSServiceQuery::stcAnswer::stcTTL::restart
*/
bool MDNSResponder::stcMDNSServiceQuery::stcAnswer::stcTTL::restart(void) {
bool bResult = true;
if ((TIMEOUTLEVEL_BASE <= m_timeoutLevel) && // >= 80% AND
(TIMEOUTLEVEL_FINAL > m_timeoutLevel)) { // < 100%
m_timeoutLevel += TIMEOUTLEVEL_INTERVAL; // increment by 5%
m_TTLTimeout.reset(timeout());
}
else {
bResult = false;
m_TTLTimeout.resetToNeverExpires();
m_timeoutLevel = TIMEOUTLEVEL_UNSET;
}
return bResult;
}
/*
* MDNSResponder::stcMDNSServiceQuery::stcAnswer::stcTTL::prepareDeletion
*/
bool MDNSResponder::stcMDNSServiceQuery::stcAnswer::stcTTL::prepareDeletion(void) {
m_timeoutLevel = TIMEOUTLEVEL_FINAL;
m_TTLTimeout.reset(1 * 1000); // See RFC 6762, 10.1
return true;
}
/*
* MDNSResponder::stcMDNSServiceQuery::stcAnswer::stcTTL::finalTimeoutLevel
*/
bool MDNSResponder::stcMDNSServiceQuery::stcAnswer::stcTTL::finalTimeoutLevel(void) const {
return (TIMEOUTLEVEL_FINAL == m_timeoutLevel);
}
/*
* MDNSResponder::stcMDNSServiceQuery::stcAnswer::stcTTL::timeout
*/
unsigned long MDNSResponder::stcMDNSServiceQuery::stcAnswer::stcTTL::timeout(void) const {
uint32_t u32Timeout = esp8266::polledTimeout::oneShotMs::neverExpires;
if (TIMEOUTLEVEL_BASE == m_timeoutLevel) { // 80%
u32Timeout = (m_u32TTL * 800); // to milliseconds
}
else if ((TIMEOUTLEVEL_BASE < m_timeoutLevel) && // >80% AND
(TIMEOUTLEVEL_FINAL >= m_timeoutLevel)) { // <= 100%
u32Timeout = (m_u32TTL * 50);
} // else: invalid
return u32Timeout;
}
#ifdef MDNS_IP4_SUPPORT
/**
* MDNSResponder::stcMDNSServiceQuery::stcAnswer::stcIP4Address
*
*/
/*
* MDNSResponder::stcMDNSServiceQuery::stcAnswer::stcIP4Address::stcIP4Address constructor
*/
MDNSResponder::stcMDNSServiceQuery::stcAnswer::stcIP4Address::stcIP4Address(IPAddress p_IPAddress,
uint32_t p_u32TTL /*= 0*/)
: m_pNext(0),
m_IPAddress(p_IPAddress) {
m_TTL.set(p_u32TTL);
}
#endif
/**
* MDNSResponder::stcMDNSServiceQuery::stcAnswer
*/
/*
* MDNSResponder::stcMDNSServiceQuery::stcAnswer::stcAnswer constructor
*/
MDNSResponder::stcMDNSServiceQuery::stcAnswer::stcAnswer(void)
: m_pNext(0),
m_pcServiceDomain(0),
m_pcHostDomain(0),
m_u16Port(0),
m_pcTxts(0),
#ifdef MDNS_IP4_SUPPORT
m_pIP4Addresses(0),
#endif
#ifdef MDNS_IP6_SUPPORT
m_pIP6Addresses(0),
#endif
m_u32ContentFlags(0) {
}
/*
* MDNSResponder::stcMDNSServiceQuery::stcAnswer::~stcAnswer destructor
*/
MDNSResponder::stcMDNSServiceQuery::stcAnswer::~stcAnswer(void) {
clear();
}
/*
* MDNSResponder::stcMDNSServiceQuery::stcAnswer::clear
*/
bool MDNSResponder::stcMDNSServiceQuery::stcAnswer::clear(void) {
return ((releaseTxts()) &&
#ifdef MDNS_IP4_SUPPORT
(releaseIP4Addresses()) &&
#endif
#ifdef MDNS_IP6_SUPPORT
(releaseIP6Addresses())
#endif
(releaseHostDomain()) &&
(releaseServiceDomain()));
}
/*
* MDNSResponder::stcMDNSServiceQuery::stcAnswer::allocServiceDomain
*
* Alloc memory for the char array representation of the service domain.
*
*/
char* MDNSResponder::stcMDNSServiceQuery::stcAnswer::allocServiceDomain(size_t p_stLength) {
releaseServiceDomain();
if (p_stLength) {
m_pcServiceDomain = new char[p_stLength];
}
return m_pcServiceDomain;
}
/*
* MDNSResponder::stcMDNSServiceQuery::stcAnswer::releaseServiceDomain
*/
bool MDNSResponder::stcMDNSServiceQuery::stcAnswer::releaseServiceDomain(void) {
if (m_pcServiceDomain) {
delete[] m_pcServiceDomain;
m_pcServiceDomain = 0;
}
return true;
}
/*
* MDNSResponder::stcMDNSServiceQuery::stcAnswer::allocHostDomain
*
* Alloc memory for the char array representation of the host domain.
*
*/
char* MDNSResponder::stcMDNSServiceQuery::stcAnswer::allocHostDomain(size_t p_stLength) {
releaseHostDomain();
if (p_stLength) {
m_pcHostDomain = new char[p_stLength];
}
return m_pcHostDomain;
}
/*
* MDNSResponder::stcMDNSServiceQuery::stcAnswer::releaseHostDomain
*/
bool MDNSResponder::stcMDNSServiceQuery::stcAnswer::releaseHostDomain(void) {
if (m_pcHostDomain) {
delete[] m_pcHostDomain;
m_pcHostDomain = 0;
}
return true;
}
/*
* MDNSResponder::stcMDNSServiceQuery::stcAnswer::allocTxts
*
* Alloc memory for the char array representation of the TXT items.
*
*/
char* MDNSResponder::stcMDNSServiceQuery::stcAnswer::allocTxts(size_t p_stLength) {
releaseTxts();
if (p_stLength) {
m_pcTxts = new char[p_stLength];
}
return m_pcTxts;
}
/*
* MDNSResponder::stcMDNSServiceQuery::stcAnswer::releaseTxts
*/
bool MDNSResponder::stcMDNSServiceQuery::stcAnswer::releaseTxts(void) {
if (m_pcTxts) {
delete[] m_pcTxts;
m_pcTxts = 0;
}
return true;
}
#ifdef MDNS_IP4_SUPPORT
/*
* MDNSResponder::stcMDNSServiceQuery::stcAnswer::releaseIP4Addresses
*/
bool MDNSResponder::stcMDNSServiceQuery::stcAnswer::releaseIP4Addresses(void) {
while (m_pIP4Addresses) {
stcIP4Address* pNext = m_pIP4Addresses->m_pNext;
delete m_pIP4Addresses;
m_pIP4Addresses = pNext;
}
return true;
}
/*
* MDNSResponder::stcMDNSServiceQuery::stcAnswer::addIP4Address
*/
bool MDNSResponder::stcMDNSServiceQuery::stcAnswer::addIP4Address(MDNSResponder::stcMDNSServiceQuery::stcAnswer::stcIP4Address* p_pIP4Address) {
bool bResult = false;
if (p_pIP4Address) {
p_pIP4Address->m_pNext = m_pIP4Addresses;
m_pIP4Addresses = p_pIP4Address;
bResult = true;
}
return bResult;
}
/*
* MDNSResponder::stcMDNSServiceQuery::stcAnswer::removeIP4Address
*/
bool MDNSResponder::stcMDNSServiceQuery::stcAnswer::removeIP4Address(MDNSResponder::stcMDNSServiceQuery::stcAnswer::stcIP4Address* p_pIP4Address) {
bool bResult = false;
if (p_pIP4Address) {
stcIP4Address* pPred = m_pIP4Addresses;
while ((pPred) &&
(pPred->m_pNext != p_pIP4Address)) {
pPred = pPred->m_pNext;
}
if (pPred) {
pPred->m_pNext = p_pIP4Address->m_pNext;
delete p_pIP4Address;
bResult = true;
}
else if (m_pIP4Addresses == p_pIP4Address) { // No predecesor, but first item
m_pIP4Addresses = p_pIP4Address->m_pNext;
delete p_pIP4Address;
bResult = true;
}
}
return bResult;
}
/*
* MDNSResponder::stcMDNSServiceQuery::stcAnswer::findIP4Address (const)
*/
const MDNSResponder::stcMDNSServiceQuery::stcAnswer::stcIP4Address* MDNSResponder::stcMDNSServiceQuery::stcAnswer::findIP4Address(const IPAddress& p_IPAddress) const {
return (stcIP4Address*)(((const stcAnswer*)this)->findIP4Address(p_IPAddress));
}
/*
* MDNSResponder::stcMDNSServiceQuery::stcAnswer::findIP4Address
*/
MDNSResponder::stcMDNSServiceQuery::stcAnswer::stcIP4Address* MDNSResponder::stcMDNSServiceQuery::stcAnswer::findIP4Address(const IPAddress& p_IPAddress) {
stcIP4Address* pIP4Address = m_pIP4Addresses;
while (pIP4Address) {
if (pIP4Address->m_IPAddress == p_IPAddress) {
break;
}
pIP4Address = pIP4Address->m_pNext;
}
return pIP4Address;
}
/*
* MDNSResponder::stcMDNSServiceQuery::stcAnswer::IP4AddressCount
*/
uint32_t MDNSResponder::stcMDNSServiceQuery::stcAnswer::IP4AddressCount(void) const {
uint32_t u32Count = 0;
stcIP4Address* pIP4Address = m_pIP4Addresses;
while (pIP4Address) {
++u32Count;
pIP4Address = pIP4Address->m_pNext;
}
return u32Count;
}
/*
* MDNSResponder::stcMDNSServiceQuery::stcAnswer::IP4AddressAtIndex
*/
MDNSResponder::stcMDNSServiceQuery::stcAnswer::stcIP4Address* MDNSResponder::stcMDNSServiceQuery::stcAnswer::IP4AddressAtIndex(uint32_t p_u32Index) {
return (stcIP4Address*)(((const stcAnswer*)this)->IP4AddressAtIndex(p_u32Index));
}
/*
* MDNSResponder::stcMDNSServiceQuery::stcAnswer::IP4AddressAtIndex (const)
*/
const MDNSResponder::stcMDNSServiceQuery::stcAnswer::stcIP4Address* MDNSResponder::stcMDNSServiceQuery::stcAnswer::IP4AddressAtIndex(uint32_t p_u32Index) const {
const stcIP4Address* pIP4Address = 0;
if (((uint32_t)(-1) != p_u32Index) &&
(m_pIP4Addresses)) {
uint32_t u32Index;
for (pIP4Address=m_pIP4Addresses, u32Index=0; ((pIP4Address) && (u32Index<p_u32Index)); pIP4Address=pIP4Address->m_pNext, ++u32Index);
}
return pIP4Address;
}
#endif
#ifdef MDNS_IP6_SUPPORT
/*
* MDNSResponder::stcMDNSServiceQuery::stcAnswer::releaseIP6Addresses
*/
bool MDNSResponder::stcMDNSServiceQuery::stcAnswer::releaseIP6Addresses(void) {
while (m_pIP6Addresses) {
stcIP6Address* pNext = m_pIP6Addresses->m_pNext;
delete m_pIP6Addresses;
m_pIP6Addresses = pNext;
}
return true;
}
/*
* MDNSResponder::stcMDNSServiceQuery::stcAnswer::addIP6Address
*/
bool MDNSResponder::stcMDNSServiceQuery::stcAnswer::addIP6Address(MDNSResponder::stcMDNSServiceQuery::stcAnswer::stcIP6Address* p_pIP6Address) {
bool bResult = false;
if (p_pIP6Address) {
p_pIP6Address->m_pNext = m_pIP6Addresses;
m_pIP6Addresses = p_pIP6Address;
bResult = true;
}
return bResult;
}
/*
* MDNSResponder::stcMDNSServiceQuery::stcAnswer::removeIP6Address
*/
bool MDNSResponder::stcMDNSServiceQuery::stcAnswer::removeIP6Address(MDNSResponder::stcMDNSServiceQuery::stcAnswer::stcIP6Address* p_pIP6Address) {
bool bResult = false;
if (p_pIP6Address) {
stcIP6Address* pPred = m_pIP6Addresses;
while ((pPred) &&
(pPred->m_pNext != p_pIP6Address)) {
pPred = pPred->m_pNext;
}
if (pPred) {
pPred->m_pNext = p_pIP6Address->m_pNext;
delete p_pIP6Address;
bResult = true;
}
else if (m_pIP6Addresses == p_pIP6Address) { // No predecesor, but first item
m_pIP6Addresses = p_pIP6Address->m_pNext;
delete p_pIP6Address;
bResult = true;
}
}
return bResult;
}
/*
* MDNSResponder::stcMDNSServiceQuery::stcAnswer::findIP6Address
*/
MDNSResponder::stcMDNSServiceQuery::stcAnswer::stcIP6Address* MDNSResponder::stcMDNSServiceQuery::stcAnswer::findIP6Address(const IP6Address& p_IPAddress) {
return (stcIP6Address*)(((const stcAnswer*)this)->findIP6Address(p_IPAddress));
}
/*
* MDNSResponder::stcMDNSServiceQuery::stcAnswer::findIP6Address (const)
*/
const MDNSResponder::stcMDNSServiceQuery::stcAnswer::stcIP6Address* MDNSResponder::stcMDNSServiceQuery::stcAnswer::findIP6Address(const IPAddress& p_IPAddress) const {
const stcIP6Address* pIP6Address = m_pIP6Addresses;
while (pIP6Address) {
if (p_IP6Address->m_IPAddress == p_IPAddress) {
break;
}
pIP6Address = pIP6Address->m_pNext;
}
return pIP6Address;
}
/*
* MDNSResponder::stcMDNSServiceQuery::stcAnswer::IP6AddressCount
*/
uint32_t MDNSResponder::stcMDNSServiceQuery::stcAnswer::IP6AddressCount(void) const {
uint32_t u32Count = 0;
stcIP6Address* pIP6Address = m_pIP6Addresses;
while (pIP6Address) {
++u32Count;
pIP6Address = pIP6Address->m_pNext;
}
return u32Count;
}
/*
* MDNSResponder::stcMDNSServiceQuery::stcAnswer::IP6AddressAtIndex (const)
*/
const MDNSResponder::stcMDNSServiceQuery::stcAnswer::stcIP6Address* MDNSResponder::stcMDNSServiceQuery::stcAnswer::IP6AddressAtIndex(uint32_t p_u32Index) const {
return (stcIP6Address*)(((const stcAnswer*)this)->IP6AddressAtIndex(p_u32Index));
}
/*
* MDNSResponder::stcMDNSServiceQuery::stcAnswer::IP6AddressAtIndex
*/
MDNSResponder::stcMDNSServiceQuery::stcAnswer::stcIP6Address* MDNSResponder::stcMDNSServiceQuery::stcAnswer::IP6AddressAtIndex(uint32_t p_u32Index) {
stcIP6Address* pIP6Address = 0;
if (((uint32_t)(-1) != p_u32Index) &&
(m_pIP6Addresses)) {
uint32_t u32Index;
for (pIP6Address=m_pIP6Addresses, u32Index=0; ((pIP6Address) && (u32Index<p_u32Index)); pIP6Address=pIP6Address->m_pNext, ++u32Index);
}
return pIP6Address;
}
#endif
/**
* MDNSResponder::stcMDNSServiceQuery
*
* A service query object.
* A static query is flaged via 'm_bLegacyQuery'; while the function 'queryService'
* is waiting for answers, the internal flag 'm_bAwaitingAnswers' is set. When the
* timeout is reached, the flag is removed. These two flags are only used for static
* service queries.
* All answers to the service query are stored in 'm_pAnswers' list.
* Individual answers may be addressed by index (in the list of answers).
* Every time a answer component is added (or changes) in a dynamic service query,
* the callback 'm_fnCallback' is called.
* The answer list may be searched by service and host domain.
*
* Service query object may be connected to a linked list.
*/
/*
* MDNSResponder::stcMDNSServiceQuery::stcMDNSServiceQuery constructor
*/
MDNSResponder::stcMDNSServiceQuery::stcMDNSServiceQuery(void)
: m_pNext(0),
m_fnCallback(0),
m_bLegacyQuery(false),
m_u8SentCount(0),
m_ResendTimeout(esp8266::polledTimeout::oneShotMs::neverExpires),
m_bAwaitingAnswers(true),
m_pAnswers(0) {
clear();
}
/*
* MDNSResponder::stcMDNSServiceQuery::~stcMDNSServiceQuery destructor
*/
MDNSResponder::stcMDNSServiceQuery::~stcMDNSServiceQuery(void) {
clear();
}
/*
* MDNSResponder::stcMDNSServiceQuery::clear
*/
bool MDNSResponder::stcMDNSServiceQuery::clear(void) {
m_fnCallback = 0;
m_bLegacyQuery = false;
m_u8SentCount = 0;
m_ResendTimeout.resetToNeverExpires();
m_bAwaitingAnswers = true;
while (m_pAnswers) {
stcAnswer* pNext = m_pAnswers->m_pNext;
delete m_pAnswers;
m_pAnswers = pNext;
}
return true;
}
/*
* MDNSResponder::stcMDNSServiceQuery::answerCount
*/
uint32_t MDNSResponder::stcMDNSServiceQuery::answerCount(void) const {
uint32_t u32Count = 0;
stcAnswer* pAnswer = m_pAnswers;
while (pAnswer) {
++u32Count;
pAnswer = pAnswer->m_pNext;
}
return u32Count;
}
/*
* MDNSResponder::stcMDNSServiceQuery::answerAtIndex
*/
const MDNSResponder::stcMDNSServiceQuery::stcAnswer* MDNSResponder::stcMDNSServiceQuery::answerAtIndex(uint32_t p_u32Index) const {
const stcAnswer* pAnswer = 0;
if (((uint32_t)(-1) != p_u32Index) &&
(m_pAnswers)) {
uint32_t u32Index;
for (pAnswer=m_pAnswers, u32Index=0; ((pAnswer) && (u32Index<p_u32Index)); pAnswer=pAnswer->m_pNext, ++u32Index);
}
return pAnswer;
}
/*
* MDNSResponder::stcMDNSServiceQuery::answerAtIndex
*/
MDNSResponder::stcMDNSServiceQuery::stcAnswer* MDNSResponder::stcMDNSServiceQuery::answerAtIndex(uint32_t p_u32Index) {
return (stcAnswer*)(((const stcMDNSServiceQuery*)this)->answerAtIndex(p_u32Index));
}
/*
* MDNSResponder::stcMDNSServiceQuery::indexOfAnswer
*/
uint32_t MDNSResponder::stcMDNSServiceQuery::indexOfAnswer(const MDNSResponder::stcMDNSServiceQuery::stcAnswer* p_pAnswer) const {
uint32_t u32Index = 0;
for (const stcAnswer* pAnswer=m_pAnswers; pAnswer; pAnswer=pAnswer->m_pNext, ++u32Index) {
if (pAnswer == p_pAnswer) {
return u32Index;
}
}
return ((uint32_t)(-1));
}
/*
* MDNSResponder::stcMDNSServiceQuery::addAnswer
*/
bool MDNSResponder::stcMDNSServiceQuery::addAnswer(MDNSResponder::stcMDNSServiceQuery::stcAnswer* p_pAnswer) {
bool bResult = false;
if (p_pAnswer) {
p_pAnswer->m_pNext = m_pAnswers;
m_pAnswers = p_pAnswer;
bResult = true;
}
return bResult;
}
/*
* MDNSResponder::stcMDNSServiceQuery::removeAnswer
*/
bool MDNSResponder::stcMDNSServiceQuery::removeAnswer(MDNSResponder::stcMDNSServiceQuery::stcAnswer* p_pAnswer) {
bool bResult = false;
if (p_pAnswer) {
stcAnswer* pPred = m_pAnswers;
while ((pPred) &&
(pPred->m_pNext != p_pAnswer)) {
pPred = pPred->m_pNext;
}
if (pPred) {
pPred->m_pNext = p_pAnswer->m_pNext;
delete p_pAnswer;
bResult = true;
}
else if (m_pAnswers == p_pAnswer) { // No predecesor, but first item
m_pAnswers = p_pAnswer->m_pNext;
delete p_pAnswer;
bResult = true;
}
}
return bResult;
}
/*
* MDNSResponder::stcMDNSServiceQuery::findAnswerForServiceDomain
*/
MDNSResponder::stcMDNSServiceQuery::stcAnswer* MDNSResponder::stcMDNSServiceQuery::findAnswerForServiceDomain(const MDNSResponder::stcMDNS_RRDomain& p_ServiceDomain) {
stcAnswer* pAnswer = m_pAnswers;
while (pAnswer) {
if (pAnswer->m_ServiceDomain == p_ServiceDomain) {
break;
}
pAnswer = pAnswer->m_pNext;
}
return pAnswer;
}
/*
* MDNSResponder::stcMDNSServiceQuery::findAnswerForHostDomain
*/
MDNSResponder::stcMDNSServiceQuery::stcAnswer* MDNSResponder::stcMDNSServiceQuery::findAnswerForHostDomain(const MDNSResponder::stcMDNS_RRDomain& p_HostDomain) {
stcAnswer* pAnswer = m_pAnswers;
while (pAnswer) {
if (pAnswer->m_HostDomain == p_HostDomain) {
break;
}
pAnswer = pAnswer->m_pNext;
}
return pAnswer;
}
/**
* MDNSResponder::stcMDNSSendParameter
*
* A 'collection' of properties and flags for one MDNS query or response.
* Mainly managed by the 'Control' functions.
* The current offset in the UPD output buffer is tracked to be able to do
* a simple host or service domain compression.
*
*/
/**
* MDNSResponder::stcMDNSSendParameter::stcDomainCacheItem
*
* A cached host or service domain, incl. the offset in the UDP output buffer.
*
*/
/*
* MDNSResponder::stcMDNSSendParameter::stcDomainCacheItem::stcDomainCacheItem constructor
*/
MDNSResponder::stcMDNSSendParameter::stcDomainCacheItem::stcDomainCacheItem(const void* p_pHostnameOrService,
bool p_bAdditionalData,
uint32_t p_u16Offset)
: m_pNext(0),
m_pHostnameOrService(p_pHostnameOrService),
m_bAdditionalData(p_bAdditionalData),
m_u16Offset(p_u16Offset) {
}
/**
* MDNSResponder::stcMDNSSendParameter
*/
/*
* MDNSResponder::stcMDNSSendParameter::stcMDNSSendParameter constructor
*/
MDNSResponder::stcMDNSSendParameter::stcMDNSSendParameter(void)
: m_pQuestions(0),
m_pDomainCacheItems(0) {
clear();
}
/*
* MDNSResponder::stcMDNSSendParameter::~stcMDNSSendParameter destructor
*/
MDNSResponder::stcMDNSSendParameter::~stcMDNSSendParameter(void) {
clear();
}
/*
* MDNSResponder::stcMDNSSendParameter::clear
*/
bool MDNSResponder::stcMDNSSendParameter::clear(void) {
m_u16ID = 0;
m_u8HostReplyMask = 0;
m_u16Offset = 0;
m_bLegacyQuery = false;
m_bResponse = false;
m_bAuthorative = false;
m_bUnicast = false;
m_bUnannounce = false;
m_bCacheFlush = true;
while (m_pQuestions) {
stcMDNS_RRQuestion* pNext = m_pQuestions->m_pNext;
delete m_pQuestions;
m_pQuestions = pNext;
}
while (m_pDomainCacheItems) {
stcDomainCacheItem* pNext = m_pDomainCacheItems->m_pNext;
delete m_pDomainCacheItems;
m_pDomainCacheItems = pNext;
}
return true;
}
/*
* MDNSResponder::stcMDNSSendParameter::shiftOffset
*/
bool MDNSResponder::stcMDNSSendParameter::shiftOffset(uint16_t p_u16Shift) {
m_u16Offset += p_u16Shift;
return true;
}
/*
* MDNSResponder::stcMDNSSendParameter::addDomainCacheItem
*/
bool MDNSResponder::stcMDNSSendParameter::addDomainCacheItem(const void* p_pHostnameOrService,
bool p_bAdditionalData,
uint16_t p_u16Offset) {
bool bResult = false;
stcDomainCacheItem* pNewItem = 0;
if ((p_pHostnameOrService) &&
(p_u16Offset) &&
((pNewItem = new stcDomainCacheItem(p_pHostnameOrService, p_bAdditionalData, p_u16Offset)))) {
pNewItem->m_pNext = m_pDomainCacheItems;
bResult = ((m_pDomainCacheItems = pNewItem));
}
return bResult;
}
/*
* MDNSResponder::stcMDNSSendParameter::findCachedDomainOffset
*/
uint16_t MDNSResponder::stcMDNSSendParameter::findCachedDomainOffset(const void* p_pHostnameOrService,
bool p_bAdditionalData) const {
const stcDomainCacheItem* pCacheItem = m_pDomainCacheItems;
for (; pCacheItem; pCacheItem=pCacheItem->m_pNext) {
if ((pCacheItem->m_pHostnameOrService == p_pHostnameOrService) &&
(pCacheItem->m_bAdditionalData == p_bAdditionalData)) { // Found cache item
break;
}
}
return (pCacheItem ? pCacheItem->m_u16Offset : 0);
}
} // namespace MDNSImplementation
} // namespace esp8266