Skip to content

Commit

Permalink
Commissioner discovery based on DNS-SD using ChipTool (project-chip#7193
Browse files Browse the repository at this point in the history
)
  • Loading branch information
sharadb-amazon authored Jun 17, 2021
1 parent c3443e0 commit f78d60e
Show file tree
Hide file tree
Showing 23 changed files with 482 additions and 83 deletions.
1 change: 1 addition & 0 deletions examples/chip-tool/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ executable("chip-tool") {
"commands/common/Command.cpp",
"commands/common/Commands.cpp",
"commands/discover/DiscoverCommand.cpp",
"commands/discover/DiscoverCommissionersCommand.cpp",
"commands/pairing/PairingCommand.cpp",
"commands/payload/AdditionalDataParseCommand.cpp",
"commands/payload/SetupPayloadParseCommand.cpp",
Expand Down
4 changes: 3 additions & 1 deletion examples/chip-tool/commands/discover/Commands.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#pragma once

#include "DiscoverCommand.h"
#include "DiscoverCommissionersCommand.h"
#include <controller/DeviceAddressUpdateDelegate.h>
#include <mdns/Resolver.h>

Expand Down Expand Up @@ -54,7 +55,7 @@ class Resolve : public DiscoverCommand, public chip::Mdns::ResolverDelegate
ChipLogProgress(chipTool, "NodeId Resolution: failed!");
SetCommandExitStatus(false);
}
void OnCommissionableNodeFound(const chip::Mdns::CommissionableNodeData & nodeData) override {}
void OnNodeDiscoveryComplete(const chip::Mdns::DiscoveredNodeData & nodeData) override {}
};

class Update : public DiscoverCommand
Expand Down Expand Up @@ -94,6 +95,7 @@ void registerCommandsDiscover(Commands & commands)
commands_list clusterCommands = {
make_unique<Resolve>(),
make_unique<Update>(),
make_unique<DiscoverCommissionersCommand>(),
};

commands.Register(clusterName, clusterCommands);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
/*
* Copyright (c) 2020 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.
*
*/

#include "DiscoverCommissionersCommand.h"
#include <arpa/inet.h>

using namespace ::chip;

constexpr uint16_t kWaitDurationInSeconds = 3;

CHIP_ERROR DiscoverCommissionersCommand::Run(NodeId localId, NodeId remoteId)
{
//
// Set this to true first BEFORE we send commands to ensure we don't
// end up in a situation where the response comes back faster than we can
// set the variable to true, which will cause it to block indefinitely.
//
UpdateWaitForResponse(true);

{
chip::DeviceLayer::StackLock lock;

ReturnErrorOnFailure(mCommissionableNodeController.DiscoverCommissioners());
}

WaitForResponse(kWaitDurationInSeconds);

int commissionerCount = 0;
for (int i = 0; i < CHIP_DEVICE_CONFIG_MAX_DISCOVERED_NODES; i++)
{
const Mdns::DiscoveredNodeData * commissioner = mCommissionableNodeController.GetDiscoveredCommissioner(i);
if (commissioner != nullptr)
{
printf("Discovered Commisioner #%d\n", ++commissionerCount);
if (strcmp(commissioner->deviceName, "") != 0)
{
printf("Device Name: %s\n", commissioner->deviceName);
}
if (commissioner->vendorId > 0)
{
printf("Vendor ID: %d\n", commissioner->vendorId);
}
if (commissioner->productId > 0)
{
printf("Product ID: %d\n", commissioner->productId);
}
if (commissioner->deviceType > 0)
{
printf("Device Type: %d\n", commissioner->deviceType);
}
if (commissioner->longDiscriminator > 0)
{
printf("Long Discriminator: %d\n", commissioner->longDiscriminator);
}
if (!commissioner->IsHost(""))
{
printf("Hostname: %s\n", commissioner->hostName);
}
if (commissioner->numIPs > 0)
{
printf("Number of IP addresses: %d. IP Adddress(es): ", commissioner->numIPs);
for (int j = 0; j < commissioner->numIPs; j++)
{
char ipAddress[Inet::kMaxIPAddressStringLength];
printf("%s, ", commissioner->ipAddress[j].ToString(ipAddress, sizeof(ipAddress)));
}
printf("\n");
}

printf("\n");
}
}

printf("Total of %d commissioner(s) discovered in %d sec\n", commissionerCount, kWaitDurationInSeconds);
return CHIP_NO_ERROR;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*
* Copyright (c) 2020 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 "../common/Command.h"
#include <controller/CHIPCommissionableNodeController.h>

class DiscoverCommissionersCommand : public Command
{
public:
DiscoverCommissionersCommand() : Command("discover-commissioners") {}
CHIP_ERROR Run(NodeId localId, NodeId remoteId) override;

private:
chip::Controller::CommissionableNodeController mCommissionableNodeController;
};
92 changes: 92 additions & 0 deletions src/controller/AbstractMdnsDiscoveryController.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
/*
*
* Copyright (c) 2020 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.
*/

// module header, comes first
#include <controller/AbstractMdnsDiscoveryController.h>

#if CONFIG_DEVICE_LAYER
#include <platform/CHIPDeviceLayer.h>
#endif

#include <core/CHIPEncoding.h>
#include <support/logging/CHIPLogging.h>

namespace chip {
namespace Controller {

void AbstractMdnsDiscoveryController::OnNodeDiscoveryComplete(const chip::Mdns::DiscoveredNodeData & nodeData)
{
Mdns::DiscoveredNodeData * mDiscoveredNodes = GetDiscoveredNodes();
for (int i = 0; i < CHIP_DEVICE_CONFIG_MAX_DISCOVERED_NODES; ++i)
{
if (!mDiscoveredNodes[i].IsValid())
{
continue;
}
if (strcmp(mDiscoveredNodes[i].hostName, nodeData.hostName) == 0)
{
mDiscoveredNodes[i] = nodeData;
return;
}
}
// Node not yet in the list
for (int i = 0; i < CHIP_DEVICE_CONFIG_MAX_DISCOVERED_NODES; ++i)
{
if (!mDiscoveredNodes[i].IsValid())
{
mDiscoveredNodes[i] = nodeData;
return;
}
}
ChipLogError(Discovery, "Failed to add discovered node with hostname %s- Insufficient space", nodeData.hostName);
}

CHIP_ERROR AbstractMdnsDiscoveryController::SetUpNodeDiscovery()
{
chip::Mdns::Resolver::Instance().SetResolverDelegate(this);
#if CONFIG_DEVICE_LAYER
ReturnErrorOnFailure(chip::Mdns::Resolver::Instance().StartResolver(&DeviceLayer::InetLayer, kMdnsPort));
#endif

Mdns::DiscoveredNodeData * mDiscoveredNodes = GetDiscoveredNodes();
for (int i = 0; i < CHIP_DEVICE_CONFIG_MAX_DISCOVERED_NODES; ++i)
{
mDiscoveredNodes[i].Reset();
}
return CHIP_NO_ERROR;
}

CHIP_ERROR AbstractMdnsDiscoveryController::SetUpNodeDiscoveryLongDiscriminator(uint16_t long_discriminator)
{
filter = Mdns::DiscoveryFilter(Mdns::DiscoveryFilterType::kLong, long_discriminator);
return SetUpNodeDiscovery();
}

const Mdns::DiscoveredNodeData * AbstractMdnsDiscoveryController::GetDiscoveredNode(int idx)
{
// TODO(cecille): Add assertion about main loop.
Mdns::DiscoveredNodeData * mDiscoveredNodes = GetDiscoveredNodes();
if (mDiscoveredNodes[idx].IsValid())
{
return &mDiscoveredNodes[idx];
}
return nullptr;
}

} // namespace Controller
} // namespace chip
57 changes: 57 additions & 0 deletions src/controller/AbstractMdnsDiscoveryController.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/*
*
* Copyright (c) 2020 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 <mdns/Resolver.h>
#include <platform/CHIPDeviceConfig.h>

namespace chip {

namespace Controller {

constexpr uint16_t kMdnsPort = 5353;

/**
* @brief
* Convenient superclass for controller implementations that need to discover
* Commissioners or CommissionableNodes using mDNS. This Abstract class
* provides base implementations for logic to setup mDNS discovery requests,
* handling of received DiscoveredNodeData, etc. while expecting child classes
* to maintain a list of DiscoveredNodes and providing the implementation
* of the template GetDiscoveredNodes() function.
*/
class DLL_EXPORT AbstractMdnsDiscoveryController : public Mdns::ResolverDelegate
{
public:
AbstractMdnsDiscoveryController(){};
virtual ~AbstractMdnsDiscoveryController() {}

void OnNodeDiscoveryComplete(const chip::Mdns::DiscoveredNodeData & nodeData) override;

protected:
CHIP_ERROR SetUpNodeDiscovery();
CHIP_ERROR SetUpNodeDiscoveryLongDiscriminator(uint16_t long_discriminator);
const Mdns::DiscoveredNodeData * GetDiscoveredNode(int idx);
virtual Mdns::DiscoveredNodeData * GetDiscoveredNodes() = 0;

Mdns::DiscoveryFilter filter;
};

} // namespace Controller
} // namespace chip
2 changes: 2 additions & 0 deletions src/controller/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,10 @@ static_library("controller") {

sources = [
"${chip_root}/src/app/util/CHIPDeviceCallbacksMgr.cpp",
"AbstractMdnsDiscoveryController.cpp",
"CHIPCluster.cpp",
"CHIPCluster.h",
"CHIPCommissionableNodeController.cpp",
"CHIPDevice.cpp",
"CHIPDevice.h",
"CHIPDeviceController.cpp",
Expand Down
45 changes: 45 additions & 0 deletions src/controller/CHIPCommissionableNodeController.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/*
*
* Copyright (c) 2020 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.
*/

// module header, comes first
#include <controller/CHIPCommissionableNodeController.h>

#include <support/CodeUtils.h>

namespace chip {
namespace Controller {

CHIP_ERROR CommissionableNodeController::DiscoverCommissioners()
{
ReturnErrorOnFailure(SetUpNodeDiscovery());
return chip::Mdns::Resolver::Instance().FindCommissioners();
}

CHIP_ERROR CommissionableNodeController::DiscoverCommissionersLongDiscriminator(uint16_t long_discriminator)
{
ReturnErrorOnFailure(SetUpNodeDiscoveryLongDiscriminator(long_discriminator));
return chip::Mdns::Resolver::Instance().FindCommissioners(filter);
}

const Mdns::DiscoveredNodeData * CommissionableNodeController::GetDiscoveredCommissioner(int idx)
{
return GetDiscoveredNode(idx);
}

} // namespace Controller
} // namespace chip
Loading

0 comments on commit f78d60e

Please sign in to comment.