Skip to content

Commit

Permalink
[chip-tool] Update chip-tool such that the device scanner is able to …
Browse files Browse the repository at this point in the history
…directly gives the discovered CommissionNodeData to the SetUpCodePairer (#26164)

* [dnssd] Add ChipDnssdBrowse method that accepts a delegate

* [dnssd] Add ChipDnssdResolve method that accepts a delegate

* [darwin] Add ChipDnssdBrowse that accepts a delegate implementation on darwin

* [darwin] Add ChipDnssdResolve that accepts a delegate implementation on darwin

* Add an optional Dnssd::CommonResolutionData parameters when pairing a device using a setup code

* [chip-tool] Update chip-tool such that the device scanner is using the whole discovered node data addresses
  • Loading branch information
vivien-apple authored and pull[bot] committed May 22, 2024
1 parent 54256f3 commit 3030061
Show file tree
Hide file tree
Showing 20 changed files with 882 additions and 243 deletions.
5 changes: 4 additions & 1 deletion examples/chip-tool/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,6 @@ static_library("chip-tool-utils") {
"commands/common/Commands.cpp",
"commands/common/Commands.h",
"commands/common/CredentialIssuerCommands.h",
"commands/common/DeviceScanner.cpp",
"commands/common/HexConversion.h",
"commands/common/RemoteDataModelLogger.cpp",
"commands/common/RemoteDataModelLogger.h",
Expand Down Expand Up @@ -97,6 +96,10 @@ static_library("chip-tool-utils") {
sources += [ "commands/tests/TestCommand.cpp" ]
}

if (chip_device_platform == "darwin") {
sources += [ "commands/common/DeviceScanner.cpp" ]
}

public_deps = [
"${chip_root}/src/app/server",
"${chip_root}/src/app/tests/suites/commands/commissioner",
Expand Down
186 changes: 154 additions & 32 deletions examples/chip-tool/commands/common/DeviceScanner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,34 +19,38 @@
#include "DeviceScanner.h"

using namespace chip;
using namespace chip::Ble;
using namespace chip::Dnssd;

#if CONFIG_NETWORK_LAYER_BLE
using namespace chip::Ble;
constexpr const char * kBleKey = "BLE";
#endif // CONFIG_NETWORK_LAYER_BLE

CHIP_ERROR DeviceScanner::Start()
{
mDiscoveredResults.clear();

#if CHIP_TOOL_DEVICE_SCANNER_USE_BLE
#if CONFIG_NETWORK_LAYER_BLE
ReturnErrorOnFailure(DeviceLayer::PlatformMgrImpl().StartBleScan(this));
#endif // CHIP_TOOL_DEVICE_SCANNER_USE_BLE
#endif // CONFIG_NETWORK_LAYER_BLE

ReturnErrorOnFailure(mDNSResolver.Init(DeviceLayer::UDPEndPointManager()));
mDNSResolver.SetCommissioningDelegate(this);
ReturnErrorOnFailure(chip::Dnssd::Resolver::Instance().Init(DeviceLayer::UDPEndPointManager()));

DiscoveryFilter filter(DiscoveryFilterType::kNone, (uint64_t) 0);
return mDNSResolver.DiscoverCommissionableNodes(filter);
char serviceName[kMaxCommissionableServiceNameSize];
auto filter = DiscoveryFilterType::kNone;
ReturnErrorOnFailure(MakeServiceTypeName(serviceName, sizeof(serviceName), filter, DiscoveryType::kCommissionableNode));

return ChipDnssdBrowse(serviceName, DnssdServiceProtocol::kDnssdProtocolUdp, Inet::IPAddressType::kAny,
Inet::InterfaceId::Null(), this);
}

CHIP_ERROR DeviceScanner::Stop()
{
#if CHIP_TOOL_DEVICE_SCANNER_USE_BLE
#if CONFIG_NETWORK_LAYER_BLE
ReturnErrorOnFailure(DeviceLayer::PlatformMgrImpl().StopBleScan());
#endif // CHIP_TOOL_DEVICE_SCANNER_USE_BLE
#endif // CONFIG_NETWORK_LAYER_BLE

mDNSResolver.SetCommissioningDelegate(nullptr);
ReturnErrorOnFailure(mDNSResolver.StopDiscovery());
mDNSResolver.Shutdown();
return CHIP_NO_ERROR;
return ChipDnssdStopBrowse(this);
}

void DeviceScanner::OnNodeDiscovered(const DiscoveredNodeData & nodeData)
Expand All @@ -61,41 +65,152 @@ void DeviceScanner::OnNodeDiscovered(const DiscoveredNodeData & nodeData)
productId);

auto & resolutionData = nodeData.resolutionData;

auto & instanceData = mDiscoveredResults[commissionData.instanceName];
auto & interfaceData = instanceData[resolutionData.interfaceId.GetPlatformInterface()];

for (size_t i = 0; i < resolutionData.numIPs; i++)
{
auto params = Controller::SetUpCodePairerParameters(resolutionData, i);
DeviceScannerResult result = { params, vendorId, productId, discriminator };
mDiscoveredResults.push_back(result);
DeviceScannerResult result = { params, vendorId, productId, discriminator, chip::MakeOptional(resolutionData) };
interfaceData.push_back(result);
}

nodeData.LogDetail();
}

#if CHIP_TOOL_DEVICE_SCANNER_USE_BLE
void DeviceScanner::OnBrowseAdd(chip::Dnssd::DnssdService service)
{
ChipLogProgress(chipTool, "OnBrowseAdd: %s", service.mName);
LogErrorOnFailure(ChipDnssdResolve(&service, service.mInterface, this));

auto & instanceData = mDiscoveredResults[service.mName];
auto & interfaceData = instanceData[service.mInterface.GetPlatformInterface()];
(void) interfaceData;
}

void DeviceScanner::OnBrowseRemove(chip::Dnssd::DnssdService service)
{
ChipLogProgress(chipTool, "OnBrowseRemove: %s", service.mName);
auto & instanceData = mDiscoveredResults[service.mName];
auto & interfaceData = instanceData[service.mInterface.GetPlatformInterface()];

// Check if the interface data has been resolved already, otherwise, just inform the
// back end that we may not need it anymore.
if (interfaceData.size() == 0)
{
ChipDnssdResolveNoLongerNeeded(service.mName);
}

// Delete the interface placeholder.
instanceData.erase(service.mInterface.GetPlatformInterface());

// If there is nothing else to resolve for the given instance name, just remove it
// too.
if (instanceData.size() == 0)
{
mDiscoveredResults.erase(service.mName);
}
}

void DeviceScanner::OnBrowseStop(CHIP_ERROR error)
{
ChipLogProgress(chipTool, "OnBrowseStop: %" CHIP_ERROR_FORMAT, error.Format());

for (auto & instance : mDiscoveredResults)
{
for (auto & interface : instance.second)
{
if (interface.second.size() == 0)
{
ChipDnssdResolveNoLongerNeeded(instance.first.c_str());
}
}
}
}

#if CONFIG_NETWORK_LAYER_BLE
void DeviceScanner::OnBleScanAdd(BLE_CONNECTION_OBJECT connObj, const ChipBLEDeviceIdentificationInfo & info)
{
auto discriminator = info.GetDeviceDiscriminator();
auto vendorId = static_cast<VendorId>(info.GetVendorId());
auto productId = info.GetProductId();

ChipLogProgress(chipTool, "OnNodeDiscovered (BLE): discriminator: %u, vendorId: %u, productId: %u", discriminator, vendorId,
productId);
ChipLogProgress(chipTool, "OnBleScanAdd (BLE): %p, discriminator: %u, vendorId: %u, productId: %u", connObj, discriminator,
vendorId, productId);

auto params = Controller::SetUpCodePairerParameters(connObj, false /* connected */);
DeviceScannerResult result = { params, vendorId, productId, discriminator };
mDiscoveredResults.push_back(result);

auto & instanceData = mDiscoveredResults[kBleKey];
auto & interfaceData = instanceData[chip::Inet::InterfaceId::Null().GetPlatformInterface()];
interfaceData.push_back(result);
}

void DeviceScanner::OnBleScanRemove(BLE_CONNECTION_OBJECT connObj) {}
#endif // CHIP_TOOL_DEVICE_SCANNER_USE_BLE
void DeviceScanner::OnBleScanRemove(BLE_CONNECTION_OBJECT connObj)
{
ChipLogProgress(chipTool, "OnBleScanRemove: %p", connObj);

auto & instanceData = mDiscoveredResults[kBleKey];
auto & interfaceData = instanceData[chip::Inet::InterfaceId::Null().GetPlatformInterface()];

interfaceData.erase(std::remove_if(interfaceData.begin(), interfaceData.end(),
[connObj](const DeviceScannerResult & result) {
return result.mParams.HasDiscoveredObject() &&
result.mParams.GetDiscoveredObject() == connObj;
}),
interfaceData.end());

if (interfaceData.size() == 0)
{
instanceData.clear();
mDiscoveredResults.erase(kBleKey);
}
}
#endif // CONFIG_NETWORK_LAYER_BLE

CHIP_ERROR DeviceScanner::Get(uint16_t index, RendezvousParameters & params)
{
VerifyOrReturnError(index < mDiscoveredResults.size(), CHIP_ERROR_NOT_FOUND);
uint16_t currentIndex = 0;
for (auto & instance : mDiscoveredResults)
{
for (auto & interface : instance.second)
{
for (auto & result : interface.second)
{
if (currentIndex == index)
{
params = result.mParams;
return CHIP_NO_ERROR;
}
currentIndex++;
}
}
}

auto & result = mDiscoveredResults.at(index);
params = result.mParams;
return CHIP_NO_ERROR;
return CHIP_ERROR_NOT_FOUND;
}

CHIP_ERROR DeviceScanner::Get(uint16_t index, Dnssd::CommonResolutionData & resolutionData)
{
uint16_t currentIndex = 0;
for (auto & instance : mDiscoveredResults)
{
for (auto & interface : instance.second)
{
for (auto & result : interface.second)
{
if (currentIndex == index && result.mResolutionData.HasValue())
{
resolutionData = result.mResolutionData.Value();
return CHIP_NO_ERROR;
}
currentIndex++;
}
}
}

return CHIP_ERROR_NOT_FOUND;
}

void DeviceScanner::Log() const
Expand All @@ -104,14 +219,21 @@ void DeviceScanner::Log() const
VerifyOrReturn(resultsCount > 0, ChipLogProgress(chipTool, "No device discovered."));

uint16_t index = 0;
for (auto & result : mDiscoveredResults)
for (auto & instance : mDiscoveredResults)
{
char addr[Transport::PeerAddress::kMaxToStringSize];
result.mParams.GetPeerAddress().ToString(addr);

ChipLogProgress(chipTool, "\t %u - Discriminator: %u - Vendor: %u - Product: %u - %s", index, result.mDiscriminator,
result.mVendorId, result.mProductId, addr);
index++;
ChipLogProgress(chipTool, "Instance Name: %s ", instance.first.c_str());
for (auto & interface : instance.second)
{
for (auto & result : interface.second)
{
char addr[Transport::PeerAddress::kMaxToStringSize];
result.mParams.GetPeerAddress().ToString(addr);

ChipLogProgress(chipTool, "\t %u - Discriminator: %u - Vendor: %u - Product: %u - %s", index, result.mDiscriminator,
result.mVendorId, result.mProductId, addr);
index++;
}
}
}
}

Expand Down
38 changes: 23 additions & 15 deletions examples/chip-tool/commands/common/DeviceScanner.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,54 +18,62 @@

#pragma once

#include <platform/CHIPDeviceBuildConfig.h>

#if CHIP_DEVICE_LAYER_TARGET_DARWIN

#include <controller/CHIPDeviceController.h>
#include <lib/dnssd/ResolverProxy.h>
#include <lib/dnssd/platform/Dnssd.h>

#include <unordered_map>
#include <vector>

#if CONFIG_NETWORK_LAYER_BLE
#if CHIP_DEVICE_LAYER_TARGET_DARWIN
#include <platform/Darwin/BleScannerDelegate.h>
#define CHIP_TOOL_DEVICE_SCANNER_USE_BLE 1
#endif // CHIP_DEVICE_LAYER_TARGET_DARWIN
#endif // CONFIG_NETWORK_LAYER_BLE

#ifndef CHIP_TOOL_DEVICE_SCANNER_USE_BLE
#define CHIP_TOOL_DEVICE_SCANNER_USE_BLE 0
#endif // CHIP_TOOL_DEVICE_SCANNER_USE_BLE

struct DeviceScannerResult
{
chip::Controller::SetUpCodePairerParameters mParams;
chip::VendorId mVendorId;
uint16_t mProductId;
uint16_t mDiscriminator;
chip::Optional<chip::Dnssd::CommonResolutionData> mResolutionData;
};

class DeviceScanner : public chip::Dnssd::CommissioningResolveDelegate
#if CHIP_TOOL_DEVICE_SCANNER_USE_BLE
class DeviceScanner : public chip::Dnssd::CommissioningResolveDelegate,
public chip::Dnssd::DnssdBrowseDelegate
#if CONFIG_NETWORK_LAYER_BLE
,
public chip::DeviceLayer::BleScannerDelegate
#endif // CHIP_TOOL_DEVICE_SCANNER_USE_BLE
#endif // CONFIG_NETWORK_LAYER_BLE
{
public:
CHIP_ERROR Start();
CHIP_ERROR Stop();
CHIP_ERROR Get(uint16_t index, chip::RendezvousParameters & params);
CHIP_ERROR Get(uint16_t index, chip::Dnssd::CommonResolutionData & resolutionData);
void Log() const;

/////////// CommissioningResolveDelegate Interface /////////
void OnNodeDiscovered(const chip::Dnssd::DiscoveredNodeData & nodeData) override;

#if CHIP_TOOL_DEVICE_SCANNER_USE_BLE
/////////// DnssdBrowseDelegate Interface /////////
void OnBrowseAdd(chip::Dnssd::DnssdService service) override;
void OnBrowseRemove(chip::Dnssd::DnssdService service) override;
void OnBrowseStop(CHIP_ERROR error) override;

#if CONFIG_NETWORK_LAYER_BLE
/////////// BleScannerDelegate Interface /////////
void OnBleScanAdd(BLE_CONNECTION_OBJECT connObj, const chip::Ble::ChipBLEDeviceIdentificationInfo & info) override;
void OnBleScanRemove(BLE_CONNECTION_OBJECT connObj) override;
#endif // CHIP_TOOL_DEVICE_SCANNER_USE_BLE
#endif // CONFIG_NETWORK_LAYER_BLE

private:
std::vector<DeviceScannerResult> mDiscoveredResults;
chip::Dnssd::ResolverProxy mDNSResolver;
std::unordered_map<std::string, std::map<chip::Inet::InterfaceId::PlatformType, std::vector<DeviceScannerResult>>>
mDiscoveredResults;
};

DeviceScanner & GetDeviceScanner();

#endif // CHIP_DEVICE_LAYER_TARGET_DARWIN
Original file line number Diff line number Diff line change
Expand Up @@ -38,29 +38,41 @@ void DiscoverCommissionablesCommandBase::OnDiscoveredDevice(const chip::Dnssd::D

CHIP_ERROR DiscoverCommissionablesStartCommand::RunCommand()
{
#if CHIP_DEVICE_LAYER_TARGET_DARWIN
VerifyOrReturnError(IsInteractive(), CHIP_ERROR_INCORRECT_STATE);
ReturnErrorOnFailure(GetDeviceScanner().Start());

SetCommandExitStatus(CHIP_NO_ERROR);
return CHIP_NO_ERROR;
#else
return CHIP_ERROR_NOT_IMPLEMENTED;
#endif // CHIP_DEVICE_LAYER_TARGET_DARWIN
}

CHIP_ERROR DiscoverCommissionablesStopCommand::RunCommand()
{
#if CHIP_DEVICE_LAYER_TARGET_DARWIN
VerifyOrReturnError(IsInteractive(), CHIP_ERROR_INCORRECT_STATE);
ReturnErrorOnFailure(GetDeviceScanner().Stop());

SetCommandExitStatus(CHIP_NO_ERROR);
return CHIP_NO_ERROR;
#else
return CHIP_ERROR_NOT_IMPLEMENTED;
#endif // CHIP_DEVICE_LAYER_TARGET_DARWIN
}

CHIP_ERROR DiscoverCommissionablesListCommand::RunCommand()
{
#if CHIP_DEVICE_LAYER_TARGET_DARWIN
VerifyOrReturnError(IsInteractive(), CHIP_ERROR_INCORRECT_STATE);
GetDeviceScanner().Log();

SetCommandExitStatus(CHIP_NO_ERROR);
return CHIP_NO_ERROR;
#else
return CHIP_ERROR_NOT_IMPLEMENTED;
#endif // CHIP_DEVICE_LAYER_TARGET_DARWIN
}

CHIP_ERROR DiscoverCommissionablesCommand::RunCommand()
Expand Down
Loading

0 comments on commit 3030061

Please sign in to comment.