blob: eee9518c930fb5536fc6f0413cbc58d895deae23 [file] [log] [blame]
/*
*
* Copyright (c) 2020 Project CHIP Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <lib/dnssd/Discovery_ImplPlatform.h>
#include <inttypes.h>
#include <crypto/RandUtils.h>
#include <lib/core/CHIPConfig.h>
#include <lib/core/CHIPSafeCasts.h>
#include <lib/dnssd/DnssdCache.h>
#include <lib/dnssd/ServiceNaming.h>
#include <lib/dnssd/TxtFields.h>
#include <lib/dnssd/platform/Dnssd.h>
#include <lib/support/CHIPMemString.h>
#include <lib/support/CodeUtils.h>
#include <lib/support/ErrorStr.h>
#include <lib/support/logging/CHIPLogging.h>
#include <platform/CHIPDeviceConfig.h>
#include <platform/CHIPDeviceLayer.h>
namespace chip {
namespace Dnssd {
namespace {
static void HandleNodeResolve(void * context, DnssdService * result, const Span<Inet::IPAddress> & extraIPs, CHIP_ERROR error)
{
ResolverDelegateProxy * proxy = static_cast<ResolverDelegateProxy *>(context);
if (CHIP_NO_ERROR != error)
{
proxy->Release();
return;
}
DiscoveredNodeData nodeData;
Platform::CopyString(nodeData.hostName, result->mHostName);
Platform::CopyString(nodeData.instanceName, result->mName);
size_t addressesFound = 0;
if (result->mAddress.HasValue())
{
nodeData.ipAddress[addressesFound] = result->mAddress.Value();
nodeData.interfaceId = result->mInterface;
++addressesFound;
}
for (auto & ip : extraIPs)
{
if (addressesFound == ArraySize(nodeData.ipAddress))
{
// Out of space.
ChipLogProgress(Discovery, "Can't add more IPs to DiscoveredNodeData");
break;
}
nodeData.ipAddress[addressesFound] = ip;
++addressesFound;
}
nodeData.numIPs = addressesFound;
nodeData.port = result->mPort;
for (size_t i = 0; i < result->mTextEntrySize; ++i)
{
ByteSpan key(reinterpret_cast<const uint8_t *>(result->mTextEntries[i].mKey), strlen(result->mTextEntries[i].mKey));
ByteSpan val(result->mTextEntries[i].mData, result->mTextEntries[i].mDataSize);
FillNodeDataFromTxt(key, val, nodeData);
}
proxy->OnNodeDiscovered(nodeData);
proxy->Release();
}
static void HandleNodeIdResolve(void * context, DnssdService * result, const Span<Inet::IPAddress> & extraIPs, CHIP_ERROR error)
{
ResolverDelegateProxy * proxy = static_cast<ResolverDelegateProxy *>(context);
if (CHIP_NO_ERROR != error)
{
proxy->OnOperationalNodeResolutionFailed(PeerId(), error);
proxy->Release();
return;
}
VerifyOrDie(proxy != nullptr);
if (result == nullptr)
{
proxy->OnOperationalNodeResolutionFailed(PeerId(), CHIP_ERROR_UNKNOWN_RESOURCE_ID);
proxy->Release();
return;
}
VerifyOrDie(proxy != nullptr);
PeerId peerId;
error = ExtractIdFromInstanceName(result->mName, &peerId);
if (CHIP_NO_ERROR != error)
{
proxy->OnOperationalNodeResolutionFailed(PeerId(), error);
proxy->Release();
return;
}
VerifyOrDie(proxy != nullptr);
ResolvedNodeData nodeData;
Platform::CopyString(nodeData.mHostName, result->mHostName);
nodeData.mInterfaceId = result->mInterface;
nodeData.mPort = result->mPort;
nodeData.mPeerId = peerId;
// TODO: Use seconds?
const System::Clock::Timestamp currentTime = System::SystemClock().GetMonotonicTimestamp();
nodeData.mExpiryTime = currentTime + System::Clock::Seconds16(result->mTtlSeconds);
size_t addressesFound = 0;
if (result->mAddress.HasValue())
{
nodeData.mAddress[addressesFound] = result->mAddress.Value();
++addressesFound;
}
for (auto & ip : extraIPs)
{
if (addressesFound == ArraySize(nodeData.mAddress))
{
// Out of space.
ChipLogProgress(Discovery, "Can't add more IPs to ResolvedNodeData");
break;
}
nodeData.mAddress[addressesFound] = ip;
++addressesFound;
}
nodeData.mNumIPs = addressesFound;
for (size_t i = 0; i < result->mTextEntrySize; ++i)
{
ByteSpan key(reinterpret_cast<const uint8_t *>(result->mTextEntries[i].mKey), strlen(result->mTextEntries[i].mKey));
ByteSpan val(result->mTextEntries[i].mData, result->mTextEntries[i].mDataSize);
FillNodeDataFromTxt(key, val, nodeData);
}
nodeData.LogNodeIdResolved();
proxy->OnOperationalNodeResolved(nodeData);
proxy->Release();
}
static void HandleNodeBrowse(void * context, DnssdService * services, size_t servicesSize, CHIP_ERROR error)
{
ResolverDelegateProxy * proxy = static_cast<ResolverDelegateProxy *>(context);
for (size_t i = 0; i < servicesSize; ++i)
{
proxy->Retain();
// For some platforms browsed services are already resolved, so verify if resolve is really needed or call resolve callback
if (!services[i].mAddress.HasValue())
{
ChipDnssdResolve(&services[i], services[i].mInterface, HandleNodeResolve, context);
}
else
{
HandleNodeResolve(context, &services[i], Span<Inet::IPAddress>(), error);
}
}
proxy->Release();
}
CHIP_ERROR AddPtrRecord(DiscoveryFilter filter, const char ** entries, size_t & entriesCount, char * buffer, size_t bufferLen)
{
ReturnErrorOnFailure(MakeServiceSubtype(buffer, bufferLen, filter));
entries[entriesCount++] = buffer;
return CHIP_NO_ERROR;
}
CHIP_ERROR AddPtrRecord(DiscoveryFilterType type, const char ** entries, size_t & entriesCount, char * buffer, size_t bufferLen,
CommissioningMode value)
{
VerifyOrReturnError(value != CommissioningMode::kDisabled, CHIP_NO_ERROR);
return AddPtrRecord(DiscoveryFilter(type), entries, entriesCount, buffer, bufferLen);
}
CHIP_ERROR AddPtrRecord(DiscoveryFilterType type, const char ** entries, size_t & entriesCount, char * buffer, size_t bufferLen,
uint64_t value)
{
return AddPtrRecord(DiscoveryFilter(type, value), entries, entriesCount, buffer, bufferLen);
}
template <class T>
CHIP_ERROR AddPtrRecord(DiscoveryFilterType type, const char ** entries, size_t & entriesCount, char * buffer, size_t bufferLen,
chip::Optional<T> value)
{
VerifyOrReturnError(value.HasValue(), CHIP_NO_ERROR);
return AddPtrRecord(type, entries, entriesCount, buffer, bufferLen, value.Value());
}
CHIP_ERROR ENFORCE_FORMAT(4, 5)
CopyTextRecordValue(char * buffer, size_t bufferLen, int minCharactersWritten, const char * format, ...)
{
va_list args;
va_start(args, format);
int charactersWritten = vsnprintf(buffer, bufferLen, format, args);
va_end(args);
return charactersWritten >= minCharactersWritten ? CHIP_NO_ERROR : CHIP_ERROR_INVALID_STRING_LENGTH;
}
CHIP_ERROR CopyTextRecordValue(char * buffer, size_t bufferLen, bool value)
{
return CopyTextRecordValue(buffer, bufferLen, 1, "%d", value);
}
CHIP_ERROR CopyTextRecordValue(char * buffer, size_t bufferLen, uint16_t value)
{
return CopyTextRecordValue(buffer, bufferLen, 1, "%u", value);
}
CHIP_ERROR CopyTextRecordValue(char * buffer, size_t bufferLen, uint32_t value)
{
return CopyTextRecordValue(buffer, bufferLen, 1, "%" PRIu32, value);
}
CHIP_ERROR CopyTextRecordValue(char * buffer, size_t bufferLen, uint16_t value1, uint16_t value2)
{
return CopyTextRecordValue(buffer, bufferLen, 3, "%u+%u", value1, value2);
}
CHIP_ERROR CopyTextRecordValue(char * buffer, size_t bufferLen, const char * value)
{
return CopyTextRecordValue(buffer, bufferLen, 0, "%s", value);
}
CHIP_ERROR CopyTextRecordValue(char * buffer, size_t bufferLen, CommissioningMode value)
{
return CopyTextRecordValue(buffer, bufferLen, static_cast<uint16_t>(value));
}
template <class T>
CHIP_ERROR CopyTextRecordValue(char * buffer, size_t bufferLen, chip::Optional<T> value)
{
VerifyOrReturnError(value.HasValue(), CHIP_ERROR_WELL_UNINITIALIZED);
return CopyTextRecordValue(buffer, bufferLen, value.Value());
}
CHIP_ERROR CopyTextRecordValue(char * buffer, size_t bufferLen, chip::Optional<uint16_t> value1, chip::Optional<uint16_t> value2)
{
VerifyOrReturnError(value1.HasValue(), CHIP_ERROR_WELL_UNINITIALIZED);
return value2.HasValue() ? CopyTextRecordValue(buffer, bufferLen, value1.Value(), value2.Value())
: CopyTextRecordValue(buffer, bufferLen, value1.Value());
}
CHIP_ERROR CopyTextRecordValue(char * buffer, size_t bufferLen, const chip::Optional<ReliableMessageProtocolConfig> optional,
bool isIdle)
{
VerifyOrReturnError(optional.HasValue(), CHIP_ERROR_WELL_UNINITIALIZED);
auto retryInterval = isIdle ? optional.Value().mIdleRetransTimeout : optional.Value().mActiveRetransTimeout;
if (retryInterval > kMaxRetryInterval)
{
ChipLogProgress(Discovery, "MRP retry interval %s value exceeds allowed range of 1 hour, using maximum available",
isIdle ? "idle" : "active");
retryInterval = kMaxRetryInterval;
}
return CopyTextRecordValue(buffer, bufferLen, retryInterval.count());
}
template <class T>
CHIP_ERROR CopyTxtRecord(TxtFieldKey key, char * buffer, size_t bufferLen, const T & params)
{
switch (key)
{
case TxtFieldKey::kTcpSupported:
return CopyTextRecordValue(buffer, bufferLen, params.GetTcpSupported());
case TxtFieldKey::kMrpRetryIntervalIdle:
case TxtFieldKey::kMrpRetryIntervalActive:
return CopyTextRecordValue(buffer, bufferLen, params.GetMRPConfig(), key == TxtFieldKey::kMrpRetryIntervalIdle);
default:
return CHIP_ERROR_INVALID_ARGUMENT;
}
}
CHIP_ERROR CopyTxtRecord(TxtFieldKey key, char * buffer, size_t bufferLen, const CommissionAdvertisingParameters & params)
{
switch (key)
{
case TxtFieldKey::kVendorProduct:
return CopyTextRecordValue(buffer, bufferLen, params.GetVendorId(), params.GetProductId());
case TxtFieldKey::kDeviceType:
return CopyTextRecordValue(buffer, bufferLen, params.GetDeviceType());
case TxtFieldKey::kDeviceName:
return CopyTextRecordValue(buffer, bufferLen, params.GetDeviceName());
case TxtFieldKey::kLongDiscriminator:
return CopyTextRecordValue(buffer, bufferLen, params.GetLongDiscriminator());
case TxtFieldKey::kRotatingDeviceId:
return CopyTextRecordValue(buffer, bufferLen, params.GetRotatingDeviceId());
case TxtFieldKey::kPairingInstruction:
return CopyTextRecordValue(buffer, bufferLen, params.GetPairingInstruction());
case TxtFieldKey::kPairingHint:
return CopyTextRecordValue(buffer, bufferLen, params.GetPairingHint());
case TxtFieldKey::kCommissioningMode:
return CopyTextRecordValue(buffer, bufferLen, params.GetCommissioningMode());
default:
return CopyTxtRecord(key, buffer, bufferLen, static_cast<BaseAdvertisingParams<CommissionAdvertisingParameters>>(params));
}
}
template <class T>
CHIP_ERROR AddTxtRecord(TxtFieldKey key, TextEntry * entries, size_t & entriesCount, char * buffer, size_t bufferLen,
const T & params)
{
CHIP_ERROR error = CopyTxtRecord(key, buffer, bufferLen, params);
VerifyOrReturnError(CHIP_ERROR_WELL_UNINITIALIZED != error, CHIP_NO_ERROR);
VerifyOrReturnError(CHIP_NO_ERROR == error, error);
entries[entriesCount++] = { Internal::txtFieldInfo[static_cast<int>(key)].keyStr, reinterpret_cast<const uint8_t *>(buffer),
strnlen(buffer, bufferLen) };
return CHIP_NO_ERROR;
}
} // namespace
DiscoveryImplPlatform DiscoveryImplPlatform::sManager;
DiscoveryImplPlatform::DiscoveryImplPlatform() = default;
CHIP_ERROR DiscoveryImplPlatform::InitImpl()
{
ReturnErrorCodeIf(mDnssdInitialized, CHIP_NO_ERROR);
ReturnErrorOnFailure(ChipDnssdInit(HandleDnssdInit, HandleDnssdError, this));
uint64_t random_instance_name = chip::Crypto::GetRandU64();
memcpy(&mCommissionableInstanceName[0], &random_instance_name, sizeof(mCommissionableInstanceName));
return CHIP_NO_ERROR;
}
void DiscoveryImplPlatform::Shutdown()
{
VerifyOrReturn(mDnssdInitialized);
ChipDnssdShutdown();
}
void DiscoveryImplPlatform::HandleDnssdInit(void * context, CHIP_ERROR initError)
{
DiscoveryImplPlatform * publisher = static_cast<DiscoveryImplPlatform *>(context);
if (initError == CHIP_NO_ERROR)
{
publisher->mDnssdInitialized = true;
// TODO: this is wrong, however we need resolverproxy initialized
// otherwise DiscoveryImplPlatform is not usable.
//
// We rely on the fact that resolverproxy does not use the endpoint
// nor does DiscoveryImplPlatform use it (since init will be called
// twice now)
//
// The problem is that:
// - DiscoveryImplPlatform contains a ResolverProxy
// - ResolverProxy::Init calls Dnssd::Resolver::Instance().Init
// which results in a recursive dependency (proxy initializes the
// class that it is contained in).
publisher->mResolverProxy.Init(nullptr);
#if !CHIP_DEVICE_LAYER_NONE
// Post an event that will start advertising
chip::DeviceLayer::ChipDeviceEvent event;
event.Type = chip::DeviceLayer::DeviceEventType::kDnssdPlatformInitialized;
CHIP_ERROR error = chip::DeviceLayer::PlatformMgr().PostEvent(&event);
if (error != CHIP_NO_ERROR)
{
ChipLogError(Discovery, "Posting DNS-SD platform initialized event failed with %s", chip::ErrorStr(error));
}
#endif
}
else
{
ChipLogError(Discovery, "DNS-SD initialization failed with %s", chip::ErrorStr(initError));
publisher->mDnssdInitialized = false;
}
}
void DiscoveryImplPlatform::HandleDnssdError(void * context, CHIP_ERROR error)
{
DiscoveryImplPlatform * publisher = static_cast<DiscoveryImplPlatform *>(context);
if (error == CHIP_ERROR_FORCED_RESET)
{
if (publisher->mIsOperationalNodePublishing)
{
publisher->Advertise(publisher->mOperationalNodeAdvertisingParams);
}
if (publisher->mIsCommissionableNodePublishing)
{
publisher->Advertise(publisher->mCommissionableNodeAdvertisingParams);
}
if (publisher->mIsCommissionerNodePublishing)
{
publisher->Advertise(publisher->mCommissionerNodeAdvertisingParams);
}
publisher->FinalizeServiceUpdate();
}
else
{
ChipLogError(Discovery, "DNS-SD error: %s", chip::ErrorStr(error));
}
}
CHIP_ERROR DiscoveryImplPlatform::GetCommissionableInstanceName(char * instanceName, size_t maxLength)
{
if (maxLength < (chip::Dnssd::Commission::kInstanceNameMaxLength + 1))
{
return CHIP_ERROR_NO_MEMORY;
}
return chip::Encoding::BytesToUppercaseHexString(&mCommissionableInstanceName[0], sizeof(mCommissionableInstanceName),
instanceName, maxLength);
}
void DiscoveryImplPlatform::HandleDnssdPublish(void * context, const char * type, CHIP_ERROR error)
{
if (CHIP_NO_ERROR == error)
{
ChipLogProgress(Discovery, "mDNS service published: %s", type);
}
else
{
ChipLogError(Discovery, "mDNS service published error: %s", chip::ErrorStr(error));
}
}
CHIP_ERROR DiscoveryImplPlatform::PublishService(const char * serviceType, TextEntry * textEntries, size_t textEntrySize,
const char ** subTypes, size_t subTypeSize,
const OperationalAdvertisingParameters & params)
{
return PublishService(serviceType, textEntries, textEntrySize, subTypes, subTypeSize, params.GetPort(), params.GetInterfaceId(),
params.GetMac(), DnssdServiceProtocol::kDnssdProtocolTcp, params.GetPeerId());
}
CHIP_ERROR DiscoveryImplPlatform::PublishService(const char * serviceType, TextEntry * textEntries, size_t textEntrySize,
const char ** subTypes, size_t subTypeSize,
const CommissionAdvertisingParameters & params)
{
return PublishService(serviceType, textEntries, textEntrySize, subTypes, subTypeSize, params.GetPort(), params.GetInterfaceId(),
params.GetMac(), DnssdServiceProtocol::kDnssdProtocolUdp, PeerId());
}
CHIP_ERROR DiscoveryImplPlatform::PublishService(const char * serviceType, TextEntry * textEntries, size_t textEntrySize,
const char ** subTypes, size_t subTypeSize, uint16_t port,
Inet::InterfaceId interfaceId, const chip::ByteSpan & mac,
DnssdServiceProtocol protocol, PeerId peerId)
{
ReturnErrorCodeIf(mDnssdInitialized == false, CHIP_ERROR_INCORRECT_STATE);
DnssdService service;
ReturnErrorOnFailure(MakeHostName(service.mHostName, sizeof(service.mHostName), mac));
ReturnErrorOnFailure(protocol == DnssdServiceProtocol::kDnssdProtocolTcp
? MakeInstanceName(service.mName, sizeof(service.mName), peerId)
: GetCommissionableInstanceName(service.mName, sizeof(service.mName)));
strncpy(service.mType, serviceType, sizeof(service.mType));
service.mAddressType = Inet::IPAddressType::kAny;
service.mInterface = interfaceId;
service.mProtocol = protocol;
service.mPort = port;
service.mTextEntries = textEntries;
service.mTextEntrySize = textEntrySize;
service.mSubTypes = subTypes;
service.mSubTypeSize = subTypeSize;
ReturnErrorOnFailure(ChipDnssdPublishService(&service, HandleDnssdPublish, this));
#ifdef DETAIL_LOGGING
printf("printEntries port=%u, mTextEntrySize=%zu, mSubTypeSize=%zu\n", port, textEntrySize, subTypeSize);
for (size_t i = 0; i < textEntrySize; i++)
{
printf(" entry [%zu] : %s %s\n", i, textEntries[i].mKey, (char *) (textEntries[i].mData));
}
for (size_t i = 0; i < subTypeSize; i++)
{
printf(" type [%zu] : %s\n", i, subTypes[i]);
}
#endif
return CHIP_NO_ERROR;
}
#define PREPARE_RECORDS(Type) \
TextEntry textEntries[Type##AdvertisingParameters::kTxtMaxNumber]; \
size_t textEntrySize = 0; \
const char * subTypes[Type::kSubTypeMaxNumber]; \
size_t subTypeSize = 0;
#define ADD_TXT_RECORD(Name) \
char Name##Buf[kKey##Name##MaxLength + 1]; \
ReturnErrorOnFailure(AddTxtRecord(TxtFieldKey::k##Name, textEntries, textEntrySize, Name##Buf, sizeof(Name##Buf), params));
#define ADD_PTR_RECORD(Name) \
char Name##SubTypeBuf[kSubType##Name##MaxLength + 1]; \
ReturnErrorOnFailure(AddPtrRecord(DiscoveryFilterType::k##Name, subTypes, subTypeSize, Name##SubTypeBuf, \
sizeof(Name##SubTypeBuf), params.Get##Name()));
#define PUBLISH_RECORDS(Type) \
ReturnErrorOnFailure(PublishService(k##Type##ServiceName, textEntries, textEntrySize, subTypes, subTypeSize, params)); \
m##Type##NodeAdvertisingParams = params; \
mIs##Type##NodePublishing = true; \
return CHIP_NO_ERROR;
CHIP_ERROR DiscoveryImplPlatform::Advertise(const OperationalAdvertisingParameters & params)
{
PREPARE_RECORDS(Operational);
ADD_TXT_RECORD(MrpRetryIntervalIdle);
ADD_TXT_RECORD(MrpRetryIntervalActive);
ADD_TXT_RECORD(TcpSupported);
ADD_PTR_RECORD(CompressedFabricId);
PUBLISH_RECORDS(Operational);
}
CHIP_ERROR DiscoveryImplPlatform::Advertise(const CommissionAdvertisingParameters & params)
{
PREPARE_RECORDS(Commission);
ADD_TXT_RECORD(VendorProduct);
ADD_TXT_RECORD(DeviceType);
ADD_TXT_RECORD(DeviceName);
ADD_TXT_RECORD(MrpRetryIntervalIdle);
ADD_TXT_RECORD(MrpRetryIntervalActive);
ADD_TXT_RECORD(TcpSupported);
ADD_PTR_RECORD(VendorId);
ADD_PTR_RECORD(DeviceType);
if (params.GetCommissionAdvertiseMode() == CommssionAdvertiseMode::kCommissioner)
{
PUBLISH_RECORDS(Commissioner);
}
else
{
ADD_TXT_RECORD(LongDiscriminator);
ADD_TXT_RECORD(CommissioningMode);
ADD_TXT_RECORD(RotatingDeviceId);
ADD_TXT_RECORD(PairingHint);
ADD_TXT_RECORD(PairingInstruction);
ADD_PTR_RECORD(ShortDiscriminator);
ADD_PTR_RECORD(LongDiscriminator);
ADD_PTR_RECORD(CommissioningMode);
PUBLISH_RECORDS(Commissionable);
}
}
CHIP_ERROR DiscoveryImplPlatform::RemoveServices()
{
ReturnErrorOnFailure(ChipDnssdRemoveServices());
mIsOperationalNodePublishing = false;
mIsCommissionableNodePublishing = false;
mIsCommissionerNodePublishing = false;
return CHIP_NO_ERROR;
}
CHIP_ERROR DiscoveryImplPlatform::FinalizeServiceUpdate()
{
return ChipDnssdFinalizeServiceUpdate();
}
CHIP_ERROR DiscoveryImplPlatform::ResolveNodeId(const PeerId & peerId, Inet::IPAddressType type)
{
ReturnErrorOnFailure(InitImpl());
return mResolverProxy.ResolveNodeId(peerId, type);
}
CHIP_ERROR DiscoveryImplPlatform::FindCommissionableNodes(DiscoveryFilter filter)
{
ReturnErrorOnFailure(InitImpl());
return mResolverProxy.FindCommissionableNodes(filter);
}
CHIP_ERROR DiscoveryImplPlatform::FindCommissioners(DiscoveryFilter filter)
{
ReturnErrorOnFailure(InitImpl());
return mResolverProxy.FindCommissioners(filter);
}
DiscoveryImplPlatform & DiscoveryImplPlatform::GetInstance()
{
return sManager;
}
ServiceAdvertiser & chip::Dnssd::ServiceAdvertiser::Instance()
{
return DiscoveryImplPlatform::GetInstance();
}
Resolver & chip::Dnssd::Resolver::Instance()
{
return DiscoveryImplPlatform::GetInstance();
}
CHIP_ERROR ResolverProxy::ResolveNodeId(const PeerId & peerId, Inet::IPAddressType type)
{
VerifyOrReturnError(mDelegate != nullptr, CHIP_ERROR_INCORRECT_STATE);
ChipLogProgress(Discovery, "Resolving " ChipLogFormatX64 ":" ChipLogFormatX64 " ...",
ChipLogValueX64(peerId.GetCompressedFabricId()), ChipLogValueX64(peerId.GetNodeId()));
mDelegate->Retain();
DnssdService service;
ReturnErrorOnFailure(MakeInstanceName(service.mName, sizeof(service.mName), peerId));
strncpy(service.mType, kOperationalServiceName, sizeof(service.mType));
service.mProtocol = DnssdServiceProtocol::kDnssdProtocolTcp;
service.mAddressType = type;
return ChipDnssdResolve(&service, Inet::InterfaceId::Null(), HandleNodeIdResolve, mDelegate);
}
CHIP_ERROR ResolverProxy::FindCommissionableNodes(DiscoveryFilter filter)
{
VerifyOrReturnError(mDelegate != nullptr, CHIP_ERROR_INCORRECT_STATE);
mDelegate->Retain();
char serviceName[kMaxCommissionableServiceNameSize];
ReturnErrorOnFailure(MakeServiceTypeName(serviceName, sizeof(serviceName), filter, DiscoveryType::kCommissionableNode));
return ChipDnssdBrowse(serviceName, DnssdServiceProtocol::kDnssdProtocolUdp, Inet::IPAddressType::kAny,
Inet::InterfaceId::Null(), HandleNodeBrowse, mDelegate);
}
CHIP_ERROR ResolverProxy::FindCommissioners(DiscoveryFilter filter)
{
VerifyOrReturnError(mDelegate != nullptr, CHIP_ERROR_INCORRECT_STATE);
mDelegate->Retain();
char serviceName[kMaxCommissionerServiceNameSize];
ReturnErrorOnFailure(MakeServiceTypeName(serviceName, sizeof(serviceName), filter, DiscoveryType::kCommissionerNode));
return ChipDnssdBrowse(serviceName, DnssdServiceProtocol::kDnssdProtocolUdp, Inet::IPAddressType::kAny,
Inet::InterfaceId::Null(), HandleNodeBrowse, mDelegate);
}
} // namespace Dnssd
} // namespace chip