diff --git a/examples/tv-casting-app/linux/BUILD.gn b/examples/tv-casting-app/linux/BUILD.gn index 8ca2d722a329c7..a48f121ab0109a 100644 --- a/examples/tv-casting-app/linux/BUILD.gn +++ b/examples/tv-casting-app/linux/BUILD.gn @@ -14,6 +14,7 @@ import("//build_overrides/build.gni") import("//build_overrides/chip.gni") +import("args.gni") import("${chip_root}/build/chip/tools.gni") @@ -22,6 +23,9 @@ assert(chip_build_tools) executable("chip-tv-casting-app") { sources = [ "${chip_root}/examples/tv-casting-app/tv-casting-common/include/CHIPProjectAppConfig.h", + "Casting.h", + "CastingShellCommands.cpp", + "CastingShellCommands.h", "main.cpp", ] @@ -35,6 +39,10 @@ executable("chip-tv-casting-app") { cflags = [ "-Wconversion" ] + if (chip_build_libshell) { + cflags += [ "-DENABLE_CHIP_SHELL" ] + } + output_dir = root_out_dir } diff --git a/examples/tv-casting-app/linux/Casting.h b/examples/tv-casting-app/linux/Casting.h new file mode 100644 index 00000000000000..bb48763acb8fba --- /dev/null +++ b/examples/tv-casting-app/linux/Casting.h @@ -0,0 +1,32 @@ +/* + * + * Copyright (c) 2021 Project CHIP Authors + * All rights reserved. + * + * 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. + */ + +#pragma once + +#include +#include +#include +#include + +CHIP_ERROR DiscoverCommissioners(); +CHIP_ERROR RequestCommissioning(int index); +void ReadServerClustersForNode(chip::NodeId nodeId); +CHIP_ERROR ContentLauncherLaunchURL(const char * contentUrl, const char * contentDisplayStr); +#if CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY_CLIENT +CHIP_ERROR SendUDC(chip::Transport::PeerAddress commissioner); +#endif // CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY_CLIENT diff --git a/examples/tv-casting-app/linux/CastingShellCommands.cpp b/examples/tv-casting-app/linux/CastingShellCommands.cpp new file mode 100644 index 00000000000000..5e61dae4a845eb --- /dev/null +++ b/examples/tv-casting-app/linux/CastingShellCommands.cpp @@ -0,0 +1,123 @@ +/* + * + * Copyright (c) 2021 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. + */ + +/** + * @file Contains shell commands for a ContentApp relating to Content App platform of the Video Player. + */ + +#include "CastingShellCommands.h" +#include "Casting.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace chip { +namespace Shell { + +static CHIP_ERROR PrintAllCommands() +{ + streamer_t * sout = streamer_get(); + streamer_printf(sout, " help Usage: app \r\n"); + streamer_printf(sout, " discover Discover commissioners. Usage: cast discover\r\n"); + streamer_printf( + sout, " request Request commissioning from discovered commissioner with [index]. Usage: cast request 0\r\n"); + streamer_printf(sout, " launch Launch content. Usage: cast launc https://www.yahoo.com Hello\r\n"); + streamer_printf( + sout, + " access Read and display clusters on each endpoint for . Usage: cast access 0xFFFFFFEFFFFFFFFF\r\n"); + streamer_printf(sout, " sendudc
Send UDC message to address. Usage: cast sendudc ::1 5543\r\n"); + streamer_printf(sout, "\r\n"); + + return CHIP_NO_ERROR; +} + +static CHIP_ERROR CastingHandler(int argc, char ** argv) +{ + if (argc == 0 || strcmp(argv[0], "help") == 0) + { + return PrintAllCommands(); + } + if (strcmp(argv[0], "discover") == 0) + { + ChipLogProgress(DeviceLayer, "discover"); + + return DiscoverCommissioners(); + } + if (strcmp(argv[0], "request") == 0) + { + ChipLogProgress(DeviceLayer, "request"); + if (argc < 2) + { + return PrintAllCommands(); + } + char * eptr; + int index = (int) strtol(argv[1], &eptr, 10); + return RequestCommissioning(index); + } + if (strcmp(argv[0], "launch") == 0) + { + ChipLogProgress(DeviceLayer, "launch"); + if (argc < 3) + { + return PrintAllCommands(); + } + char * url = argv[1]; + char * display = argv[2]; + return ContentLauncherLaunchURL(url, display); + } + if (strcmp(argv[0], "access") == 0) + { + ChipLogProgress(DeviceLayer, "access"); + if (argc < 2) + { + return PrintAllCommands(); + } + char * eptr; + chip::NodeId node = (chip::NodeId) strtoull(argv[1], &eptr, 0); + ReadServerClustersForNode(node); + return CHIP_NO_ERROR; + } +#if CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY_CLIENT + if (strcmp(argv[0], "sendudc") == 0) + { + char * eptr; + chip::Inet::IPAddress commissioner; + chip::Inet::IPAddress::FromString(argv[1], commissioner); + uint16_t port = (uint16_t) strtol(argv[2], &eptr, 10); + return SendUDC(chip::Transport::PeerAddress::UDP(commissioner, port)); + } +#endif // CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY_CLIENT + return CHIP_ERROR_INVALID_ARGUMENT; +} + +void RegisterCastingCommands() +{ + + static const shell_command_t sDeviceComand = { &CastingHandler, "cast", "Casting commands. Usage: cast [command_name]" }; + + // Register the root `device` command with the top-level shell. + Engine::Root().RegisterCommands(&sDeviceComand, 1); +} + +} // namespace Shell +} // namespace chip diff --git a/examples/tv-casting-app/linux/CastingShellCommands.h b/examples/tv-casting-app/linux/CastingShellCommands.h new file mode 100644 index 00000000000000..f3d7d0ae666c9a --- /dev/null +++ b/examples/tv-casting-app/linux/CastingShellCommands.h @@ -0,0 +1,31 @@ +/* + * + * Copyright (c) 2021 Project CHIP Authors + * All rights reserved. + * + * 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. + */ + +/** + * @brief Contains shell commands for a Casting App. + */ + +#include + +namespace chip { +namespace Shell { + +void RegisterCastingCommands(); + +} // namespace Shell +} // namespace chip diff --git a/examples/tv-casting-app/linux/main.cpp b/examples/tv-casting-app/linux/main.cpp index d7957cd1e22f23..c305746333e07f 100644 --- a/examples/tv-casting-app/linux/main.cpp +++ b/examples/tv-casting-app/linux/main.cpp @@ -40,6 +40,12 @@ #include #include +#if defined(ENABLE_CHIP_SHELL) +#include "CastingShellCommands.h" +#include +#include +#endif + #include #include @@ -51,6 +57,10 @@ using chip::ArgParser::OptionDef; using chip::ArgParser::OptionSet; using namespace chip::app::Clusters::ContentLauncher::Commands; +#if defined(ENABLE_CHIP_SHELL) +using chip::Shell::Engine; +#endif + struct TVExampleDeviceType { const char * name; @@ -129,6 +139,17 @@ CHIP_ERROR InitBindingHandlers() return CHIP_NO_ERROR; } +#if CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY_CLIENT +void HandleUDCSendExpiration(System::Layer * aSystemLayer, void * context) +{ + Dnssd::DiscoveredNodeData * selectedCommissioner = (Dnssd::DiscoveredNodeData *) context; + + // Send User Directed commissioning request + ReturnOnFailure(Server::GetInstance().SendUserDirectedCommissioningRequest(chip::Transport::PeerAddress::UDP( + selectedCommissioner->ipAddress[0], selectedCommissioner->port, selectedCommissioner->interfaceId))); +} +#endif // CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY_CLIENT + /** * Enters commissioning mode, opens commissioning window, logs onboarding payload. * If non-null selectedCommissioner is provided, sends user directed commissioning @@ -158,31 +179,25 @@ void PrepareForCommissioning(const Dnssd::DiscoveredNodeData * selectedCommissio if (selectedCommissioner != nullptr) { // Send User Directed commissioning request - ReturnOnFailure(Server::GetInstance().SendUserDirectedCommissioningRequest(chip::Transport::PeerAddress::UDP( - selectedCommissioner->ipAddress[0], selectedCommissioner->port, selectedCommissioner->interfaceId))); + // Wait 1 second to allow our commissionee DNS records to publish (needed on Mac) + int32_t expiration = 1; + ReturnOnFailure(DeviceLayer::SystemLayer().StartTimer(System::Clock::Seconds32(expiration), HandleUDCSendExpiration, + (void *) selectedCommissioner)); + } + else + { + ChipLogProgress(AppServer, "To run discovery again, enter: cast discover"); } #endif // CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY_CLIENT } -/** - * Accepts user input of selected commissioner and calls PrepareForCommissioning with - * the selected commissioner - */ -void RequestUserDirectedCommissioning(System::SocketEvents events, intptr_t data) +#if CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY_CLIENT +CHIP_ERROR SendUDC(chip::Transport::PeerAddress commissioner) { - // Accept user selection for commissioner to request commissioning from. - // Assuming kernel has line buffering, this will unblock on '\n' character - // on stdin i.e. when user hits 'Enter' - int selectedCommissionerNumber = CHIP_DEVICE_CONFIG_MAX_DISCOVERED_NODES; - scanf("%d", &selectedCommissionerNumber); - printf("%d\n", selectedCommissionerNumber); - chip::DeviceLayer::SystemLayerSockets().StopWatchingSocket(&gToken); - - const Dnssd::DiscoveredNodeData * selectedCommissioner = - gCommissionableNodeController.GetDiscoveredCommissioner(selectedCommissionerNumber - 1); - VerifyOrReturn(selectedCommissioner != nullptr, ChipLogError(AppServer, "No such commissioner!")); - PrepareForCommissioning(selectedCommissioner); + PrepareForCommissioning(); + return Server::GetInstance().SendUserDirectedCommissioningRequest(commissioner); } +#endif // CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY_CLIENT void InitCommissioningFlow(intptr_t commandArg) { @@ -194,7 +209,7 @@ void InitCommissioningFlow(intptr_t commandArg) const Dnssd::DiscoveredNodeData * commissioner = gCommissionableNodeController.GetDiscoveredCommissioner(i); if (commissioner != nullptr) { - ChipLogProgress(AppServer, "Discovered Commissioner #%d", ++commissionerCount); + ChipLogProgress(AppServer, "Discovered Commissioner #%d", commissionerCount++); commissioner->LogDetail(); } } @@ -204,14 +219,7 @@ void InitCommissioningFlow(intptr_t commandArg) ChipLogProgress(AppServer, "%d commissioner(s) discovered. Select one (by number# above) to request commissioning from: ", commissionerCount); - // Setup for async/non-blocking user input from stdin - int flags = fcntl(STDIN_FILENO, F_GETFL, 0); - VerifyOrReturn(fcntl(0, F_SETFL, flags | O_NONBLOCK) == 0, - ChipLogError(AppServer, "Could not set non-blocking mode for user input!")); - ReturnOnFailure(chip::DeviceLayer::SystemLayerSockets().StartWatchingSocket(STDIN_FILENO, &gToken)); - ReturnOnFailure( - chip::DeviceLayer::SystemLayerSockets().SetCallback(gToken, RequestUserDirectedCommissioning, (intptr_t) NULL)); - ReturnOnFailure(chip::DeviceLayer::SystemLayerSockets().RequestCallbackOnPendingRead(gToken)); + ChipLogProgress(AppServer, "Example: cast request 0"); } else { @@ -220,6 +228,29 @@ void InitCommissioningFlow(intptr_t commandArg) } } +CHIP_ERROR DiscoverCommissioners() +{ + // Send discover commissioners request + ReturnErrorOnFailure(gCommissionableNodeController.DiscoverCommissioners(gDiscoveryFilter)); + + // Give commissioners some time to respond and then ScheduleWork to initiate commissioning + return DeviceLayer::SystemLayer().StartTimer( + chip::System::Clock::Milliseconds32(kCommissionerDiscoveryTimeoutInMs), + [](System::Layer *, void *) { chip::DeviceLayer::PlatformMgr().ScheduleWork(InitCommissioningFlow); }, nullptr); +} + +CHIP_ERROR RequestCommissioning(int index) +{ + const Dnssd::DiscoveredNodeData * selectedCommissioner = gCommissionableNodeController.GetDiscoveredCommissioner(index); + if (selectedCommissioner == nullptr) + { + ChipLogError(AppServer, "No such commissioner with index %d exists", index); + return CHIP_ERROR_INVALID_ARGUMENT; + } + PrepareForCommissioning(selectedCommissioner); + return CHIP_NO_ERROR; +} + void OnContentLauncherSuccessResponse(void * context, const LaunchResponse::DecodableType & response) { ChipLogProgress(AppServer, "ContentLauncher: Default Success Response"); @@ -482,6 +513,7 @@ void ReadServerClusters(EndpointId endpointId) void ReadServerClustersForNode(NodeId nodeId) { + ChipLogProgress(NotSpecified, "ReadServerClustersForNode nodeId=0x" ChipLogFormatX64, ChipLogValueX64(nodeId)); for (const auto & binding : BindingTable::GetInstance()) { ChipLogProgress(NotSpecified, @@ -495,10 +527,42 @@ void ReadServerClustersForNode(NodeId nodeId) { ReadServerClusters(binding.remote); } + else + { + TargetEndpointInfo * endpointInfo = gTargetVideoPlayerInfo.GetEndpoint(binding.remote); + if (endpointInfo != nullptr && endpointInfo->IsInitialized()) + { + endpointInfo->PrintInfo(); + } + } } } } +CHIP_ERROR ContentLauncherLaunchURL(const char * contentUrl, const char * contentDisplayStr) +{ + OperationalDeviceProxy * operationalDeviceProxy = gTargetVideoPlayerInfo.GetOperationalDeviceProxy(); + if (operationalDeviceProxy == nullptr) + { + ChipLogError(AppServer, "Failed in getting an instance of OperationalDeviceProxy"); + return CHIP_ERROR_PEER_NODE_NOT_FOUND; + } + + ContentLauncherCluster cluster; + CHIP_ERROR err = cluster.Associate(operationalDeviceProxy, kTvEndpoint); + if (err != CHIP_NO_ERROR) + { + ChipLogError(AppServer, "Associate() failed: %" CHIP_ERROR_FORMAT, err.Format()); + return err; + } + LaunchURL::Type request; + request.contentURL = chip::CharSpan::fromCharString(contentUrl); + request.displayString = Optional(chip::CharSpan::fromCharString(contentDisplayStr)); + request.brandingInformation = MakeOptional(chip::app::Clusters::ContentLauncher::Structs::BrandingInformation::Type()); + cluster.InvokeCommand(request, nullptr, OnContentLauncherSuccessResponse, OnContentLauncherFailureResponse); + return CHIP_NO_ERROR; +} + void DeviceEventCallback(const DeviceLayer::ChipDeviceEvent * event, intptr_t arg) { if (event->Type == DeviceLayer::DeviceEventType::kBindingsChangedViaCluster) @@ -513,26 +577,7 @@ void DeviceEventCallback(const DeviceLayer::ChipDeviceEvent * event, intptr_t ar ReturnOnFailure(gTargetVideoPlayerInfo.Initialize(event->CommissioningComplete.PeerNodeId, event->CommissioningComplete.PeerFabricIndex)); - OperationalDeviceProxy * operationalDeviceProxy = gTargetVideoPlayerInfo.GetOperationalDeviceProxy(); - if (operationalDeviceProxy == nullptr) - { - ChipLogError(AppServer, "Failed in getting an instance of OperationalDeviceProxy"); - return; - } - - ContentLauncherCluster cluster; - CHIP_ERROR err = cluster.Associate(operationalDeviceProxy, kTvEndpoint); - if (err != CHIP_NO_ERROR) - { - ChipLogError(AppServer, "Associate() failed: %" CHIP_ERROR_FORMAT, err.Format()); - return; - } - LaunchURL::Type request; - request.contentURL = chip::CharSpan::fromCharString(kContentUrl); - request.displayString = Optional(chip::CharSpan::fromCharString(kContentDisplayStr)); - request.brandingInformation = Optional( - chip::app::Clusters::ContentLauncher::Structs::BrandingInformation::Type()); - cluster.InvokeCommand(request, nullptr, OnContentLauncherSuccessResponse, OnContentLauncherFailureResponse); + ContentLauncherLaunchURL(kContentUrl, kContentDisplayStr); } } @@ -582,6 +627,12 @@ LinuxCommissionableDataProvider gCommissionableDataProvider; int main(int argc, char * argv[]) { +#if defined(ENABLE_CHIP_SHELL) + Engine::Root().Init(); + std::thread shellThread([]() { Engine::Root().RunMainLoop(); }); + Shell::RegisterCastingCommands(); +#endif + CHIP_ERROR err = CHIP_NO_ERROR; SuccessOrExit(err = chip::Platform::MemoryInit()); @@ -621,6 +672,9 @@ int main(int argc, char * argv[]) DeviceLayer::PlatformMgr().RunEventLoop(); exit: +#if defined(ENABLE_CHIP_SHELL) + shellThread.join(); +#endif if (err != CHIP_NO_ERROR) { ChipLogError(AppServer, "Failed to run TV Casting App: %s", ErrorStr(err)); diff --git a/examples/tv-casting-app/tv-casting-common/include/CHIPProjectAppConfig.h b/examples/tv-casting-app/tv-casting-common/include/CHIPProjectAppConfig.h index 849344c80a4392..a63471244806fc 100644 --- a/examples/tv-casting-app/tv-casting-common/include/CHIPProjectAppConfig.h +++ b/examples/tv-casting-app/tv-casting-common/include/CHIPProjectAppConfig.h @@ -28,6 +28,9 @@ #pragma once // include the CHIPProjectConfig from config/standalone + +#define CHIP_CONFIG_KVS_PATH "/tmp/chip_casting_kvs" + #include #define CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY 0 diff --git a/src/app/server/CommissioningWindowManager.cpp b/src/app/server/CommissioningWindowManager.cpp index f2169f37835a21..339935c94f228e 100644 --- a/src/app/server/CommissioningWindowManager.cpp +++ b/src/app/server/CommissioningWindowManager.cpp @@ -348,10 +348,12 @@ CHIP_ERROR CommissioningWindowManager::StartAdvertisement() } #endif +#if CONFIG_NETWORK_LAYER_BLE if (mIsBLE) { ReturnErrorOnFailure(chip::DeviceLayer::ConnectivityMgr().SetBLEAdvertisingEnabled(true)); } +#endif // CONFIG_NETWORK_LAYER_BLE if (mAppDelegate != nullptr) { @@ -397,10 +399,12 @@ CHIP_ERROR CommissioningWindowManager::StopAdvertisement(bool aShuttingDown) app::DnssdServer::Instance().StartServer(); } +#if CONFIG_NETWORK_LAYER_BLE if (mIsBLE) { ReturnErrorOnFailure(chip::DeviceLayer::ConnectivityMgr().SetBLEAdvertisingEnabled(false)); } +#endif // CONFIG_NETWORK_LAYER_BLE if (mAppDelegate != nullptr) { diff --git a/src/controller/CHIPCommissionableNodeController.cpp b/src/controller/CHIPCommissionableNodeController.cpp index 59b8ecc559fa03..47f1299c07ac6f 100644 --- a/src/controller/CHIPCommissionableNodeController.cpp +++ b/src/controller/CHIPCommissionableNodeController.cpp @@ -35,6 +35,7 @@ CHIP_ERROR CommissionableNodeController::DiscoverCommissioners(Dnssd::DiscoveryF if (mResolver == nullptr) { #if CONFIG_DEVICE_LAYER + mDNSResolver.Shutdown(); // reset if already inited ReturnErrorOnFailure(mDNSResolver.Init(DeviceLayer::UDPEndPointManager())); #endif mDNSResolver.SetCommissioningDelegate(this); diff --git a/src/lib/dnssd/Discovery_ImplPlatform.cpp b/src/lib/dnssd/Discovery_ImplPlatform.cpp index e8eb283e5a368c..194c216d3d4df8 100644 --- a/src/lib/dnssd/Discovery_ImplPlatform.cpp +++ b/src/lib/dnssd/Discovery_ImplPlatform.cpp @@ -646,6 +646,18 @@ CHIP_ERROR ResolverProxy::FindCommissionableNodes(DiscoveryFilter filter) VerifyOrReturnError(mDelegate != nullptr, CHIP_ERROR_INCORRECT_STATE); mDelegate->Retain(); + if (filter.type == DiscoveryFilterType::kInstanceName) + { + // when we have the instance name, no need to browse, only need to resolve + DnssdService service; + + ReturnErrorOnFailure(MakeServiceSubtype(service.mName, sizeof(service.mName), filter)); + strncpy(service.mType, kCommissionableServiceName, sizeof(service.mType)); + service.mProtocol = DnssdServiceProtocol::kDnssdProtocolUdp; + service.mAddressType = Inet::IPAddressType::kAny; + return ChipDnssdResolve(&service, Inet::InterfaceId::Null(), HandleNodeResolve, mDelegate); + } + char serviceName[kMaxCommissionableServiceNameSize]; ReturnErrorOnFailure(MakeServiceTypeName(serviceName, sizeof(serviceName), filter, DiscoveryType::kCommissionableNode)); @@ -658,6 +670,18 @@ CHIP_ERROR ResolverProxy::FindCommissioners(DiscoveryFilter filter) VerifyOrReturnError(mDelegate != nullptr, CHIP_ERROR_INCORRECT_STATE); mDelegate->Retain(); + if (filter.type == DiscoveryFilterType::kInstanceName) + { + // when we have the instance name, no need to browse, only need to resolve + DnssdService service; + + ReturnErrorOnFailure(MakeServiceSubtype(service.mName, sizeof(service.mName), filter)); + strncpy(service.mType, kCommissionerServiceName, sizeof(service.mType)); + service.mProtocol = DnssdServiceProtocol::kDnssdProtocolUdp; + service.mAddressType = Inet::IPAddressType::kAny; + return ChipDnssdResolve(&service, Inet::InterfaceId::Null(), HandleNodeResolve, mDelegate); + } + char serviceName[kMaxCommissionerServiceNameSize]; ReturnErrorOnFailure(MakeServiceTypeName(serviceName, sizeof(serviceName), filter, DiscoveryType::kCommissionerNode)); diff --git a/src/platform/Darwin/DnssdImpl.cpp b/src/platform/Darwin/DnssdImpl.cpp index 07d7bf2fca0ee4..a520c4baf0e6d5 100644 --- a/src/platform/Darwin/DnssdImpl.cpp +++ b/src/platform/Darwin/DnssdImpl.cpp @@ -544,6 +544,8 @@ static CHIP_ERROR Resolve(void * context, DnssdResolveCallback callback, uint32_ DNSServiceRef sdRef; ResolveContext * sdCtx; + ChipLogProgress(Controller, "Resolve type=%s name=%s", type, name); + sdCtx = chip::Platform::New(context, callback, name, addressType); err = DNSServiceResolve(&sdRef, 0 /* flags */, interfaceId, name, type, kLocalDot, OnResolve, sdCtx); VerifyOrReturnError(CheckForSuccess(sdCtx, __func__, err), CHIP_ERROR_INTERNAL);