diff --git a/examples/chip-tool/BUILD.gn b/examples/chip-tool/BUILD.gn index f07921eab6bf00..91b4c1240e2bc9 100644 --- a/examples/chip-tool/BUILD.gn +++ b/examples/chip-tool/BUILD.gn @@ -33,6 +33,7 @@ executable("chip-tool") { "commands/clusters/ModelCommand.cpp", "commands/common/Command.cpp", "commands/common/Commands.cpp", + "commands/discover/DiscoverCommand.cpp", "commands/pairing/PairingCommand.cpp", "commands/payload/AdditionalDataParseCommand.cpp", "commands/payload/SetupPayloadParseCommand.cpp", diff --git a/examples/chip-tool/commands/discover/Commands.h b/examples/chip-tool/commands/discover/Commands.h index f9f3f41df7ebf8..30ef4a12a7dc9c 100644 --- a/examples/chip-tool/commands/discover/Commands.h +++ b/examples/chip-tool/commands/discover/Commands.h @@ -18,38 +18,23 @@ #pragma once -#include "Command.h" +#include "DiscoverCommand.h" +#include #include -class Discover : public Command, public chip::Mdns::ResolverDelegate +class Resolve : public DiscoverCommand, public chip::Mdns::ResolverDelegate { public: - Discover() : Command("resolve-node-id") - { - AddArgument("nodeid", 0, UINT64_MAX, &mNodeId); - AddArgument("fabricid", 0, UINT64_MAX, &mFabricId); - } + Resolve() : DiscoverCommand("resolve") {} - CHIP_ERROR Run(PersistentStorage & storage, NodeId localId, NodeId remoteId) override + /////////// DiscoverCommand Interface ///////// + CHIP_ERROR RunCommand(NodeId remoteId, uint64_t fabricId) override { - ReturnErrorOnFailure(mCommissioner.SetUdpListenPort(storage.GetListenPort())); - ReturnErrorOnFailure(mCommissioner.Init(localId, &storage)); - ReturnErrorOnFailure(mCommissioner.ServiceEvents()); - ReturnErrorOnFailure(chip::Mdns::Resolver::Instance().SetResolverDelegate(this)); - ReturnErrorOnFailure(chip::Mdns::Resolver::Instance().ResolveNodeId(mNodeId, mFabricId, chip::Inet::kIPAddressType_Any)); - - UpdateWaitForResponse(true); - WaitForResponse(mWaitDurationInSeconds); - - mCommissioner.ServiceEventSignal(); - mCommissioner.Shutdown(); - - VerifyOrReturnError(GetCommandExitStatus(), CHIP_ERROR_INTERNAL); - - return CHIP_NO_ERROR; + return chip::Mdns::Resolver::Instance().ResolveNodeId(remoteId, fabricId, chip::Inet::kIPAddressType_Any); } + /////////// ResolverDelegate Interface ///////// void OnNodeIdResolved(NodeId nodeId, const chip::Mdns::ResolvedNodeData & nodeData) override { char addrBuffer[chip::Transport::PeerAddress::kMaxToStringSize]; @@ -63,12 +48,35 @@ class Discover : public Command, public chip::Mdns::ResolverDelegate ChipLogProgress(chipTool, "NodeId Resolution: failed!"); SetCommandExitStatus(false); }; +}; -private: - uint16_t mWaitDurationInSeconds = 30; - ChipDeviceCommissioner mCommissioner; - chip::NodeId mNodeId; - uint64_t mFabricId; +class Update : public DiscoverCommand +{ +public: + Update() : DiscoverCommand("update") {} + + /////////// DiscoverCommand Interface ///////// + CHIP_ERROR RunCommand(NodeId remoteId, uint64_t fabricId) override + { + ChipDevice * device; + ReturnErrorOnFailure(mCommissioner.GetDevice(remoteId, &device)); + return mCommissioner.UpdateDevice(device, fabricId); + } + + /////////// DeviceAddressUpdateDelegate Interface ///////// + void OnAddressUpdateComplete(NodeId nodeId, CHIP_ERROR error) override + { + if (CHIP_NO_ERROR == error) + { + ChipLogProgress(chipTool, "Device address updated successfully"); + } + else + { + ChipLogError(chipTool, "Failed to update the device address: %s", chip::ErrorStr(error)); + } + + SetCommandExitStatus(CHIP_NO_ERROR == error); + } }; void registerCommandsDiscover(Commands & commands) @@ -76,7 +84,8 @@ void registerCommandsDiscover(Commands & commands) const char * clusterName = "Discover"; commands_list clusterCommands = { - make_unique(), + make_unique(), + make_unique(), }; commands.Register(clusterName, clusterCommands); diff --git a/examples/chip-tool/commands/discover/DiscoverCommand.cpp b/examples/chip-tool/commands/discover/DiscoverCommand.cpp new file mode 100644 index 00000000000000..3e75dbf07cdc46 --- /dev/null +++ b/examples/chip-tool/commands/discover/DiscoverCommand.cpp @@ -0,0 +1,45 @@ +/* + * 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. + * + */ + +#include "DiscoverCommand.h" + +constexpr uint16_t kWaitDurationInSeconds = 30; + +CHIP_ERROR DiscoverCommand::Run(PersistentStorage & storage, NodeId localId, NodeId remoteId) +{ + chip::Controller::ControllerInitParams params{ + .storageDelegate = &storage, + .mDeviceAddressUpdateDelegate = this, + }; + + ReturnErrorOnFailure(mCommissioner.SetUdpListenPort(storage.GetListenPort())); + ReturnErrorOnFailure(mCommissioner.Init(localId, params)); + ReturnErrorOnFailure(mCommissioner.ServiceEvents()); + + ReturnErrorOnFailure(RunCommand(mNodeId, mFabricId)); + + UpdateWaitForResponse(true); + WaitForResponse(kWaitDurationInSeconds); + + mCommissioner.ServiceEventSignal(); + mCommissioner.Shutdown(); + + VerifyOrReturnError(GetCommandExitStatus(), CHIP_ERROR_INTERNAL); + + return CHIP_NO_ERROR; +} diff --git a/examples/chip-tool/commands/discover/DiscoverCommand.h b/examples/chip-tool/commands/discover/DiscoverCommand.h new file mode 100644 index 00000000000000..724fc55b311e12 --- /dev/null +++ b/examples/chip-tool/commands/discover/DiscoverCommand.h @@ -0,0 +1,47 @@ +/* + * 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 "../../config/PersistentStorage.h" +#include "../common/Command.h" + +class DiscoverCommand : public Command, public chip::Controller::DeviceAddressUpdateDelegate +{ +public: + DiscoverCommand(const char * commandName) : Command(commandName) + { + AddArgument("nodeid", 0, UINT64_MAX, &mNodeId); + AddArgument("fabricid", 0, UINT64_MAX, &mFabricId); + } + + /////////// DeviceAddressUpdateDelegate Interface ///////// + void OnAddressUpdateComplete(NodeId nodeId, CHIP_ERROR error) override{}; + + /////////// Command Interface ///////// + CHIP_ERROR Run(PersistentStorage & storage, NodeId localId, NodeId remoteId) override; + + virtual CHIP_ERROR RunCommand(NodeId remoteId, uint64_t fabricId) = 0; + +protected: + ChipDeviceCommissioner mCommissioner; + +private: + chip::NodeId mNodeId; + uint64_t mFabricId; +}; diff --git a/src/controller/CHIPDeviceController.cpp b/src/controller/CHIPDeviceController.cpp index 65ca2255d6e424..dd7f5e47ef1612 100644 --- a/src/controller/CHIPDeviceController.cpp +++ b/src/controller/CHIPDeviceController.cpp @@ -174,6 +174,16 @@ CHIP_ERROR DeviceController::Init(NodeId localDeviceId, ControllerInitParams par mExchangeMgr->SetDelegate(this); +#if CHIP_DEVICE_CONFIG_ENABLE_MDNS + err = Mdns::Resolver::Instance().SetResolverDelegate(this); + SuccessOrExit(err); + + if (params.mDeviceAddressUpdateDelegate != nullptr) + { + mDeviceAddressUpdateDelegate = params.mDeviceAddressUpdateDelegate; + } +#endif // CHIP_DEVICE_CONFIG_ENABLE_MDNS + InitDataModelHandler(); mState = State::Initialized; @@ -329,6 +339,15 @@ CHIP_ERROR DeviceController::GetDevice(NodeId deviceId, Device ** out_device) return err; } +CHIP_ERROR DeviceController::UpdateDevice(Device * device, uint64_t fabricId) +{ +#if CHIP_DEVICE_CONFIG_ENABLE_MDNS + return Mdns::Resolver::Instance().ResolveNodeId(device->GetDeviceId(), fabricId, chip::Inet::kIPAddressType_Any); +#else + return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; +#endif // CHIP_DEVICE_CONFIG_ENABLE_MDNS +} + void DeviceController::PersistDevice(Device * device) { // mStorageDelegate would not be null for a typical pairing scenario, as Pair() @@ -548,6 +567,34 @@ CHIP_ERROR DeviceController::SetPairedDeviceList(const char * serialized) void DeviceController::OnPersistentStorageStatus(const char * key, Operation op, CHIP_ERROR err) {} +#if CHIP_DEVICE_CONFIG_ENABLE_MDNS +void DeviceController::OnNodeIdResolved(NodeId nodeId, const chip::Mdns::ResolvedNodeData & nodeData) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + Device * device = nullptr; + + err = GetDevice(nodeId, &device); + SuccessOrExit(err); + + err = device->UpdateAddress(Transport::PeerAddress::UDP(nodeData.mAddress, nodeData.mPort, nodeData.mInterfaceId)); + SuccessOrExit(err); + + PersistDevice(device); + +exit: + if (mDeviceAddressUpdateDelegate != nullptr) + { + mDeviceAddressUpdateDelegate->OnAddressUpdateComplete(nodeId, err); + } + return; +}; + +void DeviceController::OnNodeIdResolutionFailed(NodeId nodeId, CHIP_ERROR error) +{ + ChipLogError(Controller, "Error resolving node %" PRIu64 ": %s", ErrorStr(error)); +}; +#endif // CHIP_DEVICE_CONFIG_ENABLE_MDNS + ControllerDeviceInitParams DeviceController::GetControllerDeviceInitParams() { return ControllerDeviceInitParams{ diff --git a/src/controller/CHIPDeviceController.h b/src/controller/CHIPDeviceController.h index 4cda9ccdc56373..2032813dc3875c 100644 --- a/src/controller/CHIPDeviceController.h +++ b/src/controller/CHIPDeviceController.h @@ -44,6 +44,10 @@ #include #include +#if CHIP_DEVICE_CONFIG_ENABLE_MDNS +#include +#endif + namespace chip { namespace Controller { @@ -59,6 +63,9 @@ struct ControllerInitParams #if CHIP_ENABLE_INTERACTION_MODEL app::InteractionModelDelegate * imDelegate = nullptr; #endif +#if CHIP_DEVICE_CONFIG_ENABLE_MDNS + DeviceAddressUpdateDelegate * mDeviceAddressUpdateDelegate = nullptr; +#endif }; class DLL_EXPORT DevicePairingDelegate @@ -121,6 +128,9 @@ class DLL_EXPORT DevicePairingDelegate class DLL_EXPORT DeviceController : public Messaging::ExchangeDelegate, public Messaging::ExchangeMgrDelegate, public PersistentStorageResultDelegate, +#if CHIP_DEVICE_CONFIG_ENABLE_MDNS + public Mdns::ResolverDelegate, +#endif public app::InteractionModelDelegate { public: @@ -166,6 +176,18 @@ class DLL_EXPORT DeviceController : public Messaging::ExchangeDelegate, */ CHIP_ERROR GetDevice(NodeId deviceId, Device ** device); + /** + * @brief + * This function update the device informations asynchronously using mdns. + * If new device informations has been found, it will be persisted. + * + * @param[in] device The input device object to update + * @param[in] fabricId The fabricId used for mdns resolution + * + * @return CHIP_ERROR CHIP_NO_ERROR on success, or corresponding error code. + */ + CHIP_ERROR UpdateDevice(Device * device, uint64_t fabricId); + void PersistDevice(Device * device); CHIP_ERROR SetUdpListenPort(uint16_t listenPort); @@ -211,6 +233,9 @@ class DLL_EXPORT DeviceController : public Messaging::ExchangeDelegate, SecureSessionMgr * mSessionMgr; Messaging::ExchangeManager * mExchangeMgr; PersistentStorageDelegate * mStorageDelegate; +#if CHIP_DEVICE_CONFIG_ENABLE_MDNS + DeviceAddressUpdateDelegate * mDeviceAddressUpdateDelegate = nullptr; +#endif Inet::InetLayer * mInetLayer; System::Layer * mSystemLayer; @@ -240,6 +265,12 @@ class DLL_EXPORT DeviceController : public Messaging::ExchangeDelegate, //////////// PersistentStorageResultDelegate Implementation /////////////// void OnPersistentStorageStatus(const char * key, Operation op, CHIP_ERROR err) override; +#if CHIP_DEVICE_CONFIG_ENABLE_MDNS + //////////// ResolverDelegate Implementation /////////////// + void OnNodeIdResolved(NodeId nodeId, const chip::Mdns::ResolvedNodeData & nodeData) override; + void OnNodeIdResolutionFailed(NodeId nodeId, CHIP_ERROR error) override; +#endif // CHIP_DEVICE_CONFIG_ENABLE_MDNS + void ReleaseAllDevices(); };