| /* |
| * |
| * 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. |
| */ |
| |
| #pragma once |
| |
| #include <cstdint> |
| #include <limits> |
| #include <utility> |
| |
| #include <inet/IPAddress.h> |
| #include <inet/InetInterface.h> |
| #include <inet/UDPEndPoint.h> |
| #include <lib/core/CHIPError.h> |
| #include <lib/core/Optional.h> |
| #include <lib/core/PeerId.h> |
| #include <lib/core/ReferenceCounted.h> |
| #include <lib/dnssd/Constants.h> |
| #include <lib/dnssd/Types.h> |
| #include <lib/support/logging/CHIPLogging.h> |
| |
| namespace chip { |
| namespace Dnssd { |
| |
| /// Node resolution data common to both operational and commissionable discovery |
| |
| /// Callbacks for resolving operational node resolution |
| class OperationalResolveDelegate |
| { |
| public: |
| virtual ~OperationalResolveDelegate() = default; |
| |
| /// Called within the CHIP event loop after a successful node resolution. |
| /// |
| /// May be called multiple times: implementations may call this once per |
| /// received packet and MDNS packets may arrive over different interfaces |
| /// which will make nodeData have different content. |
| virtual void OnOperationalNodeResolved(const ResolvedNodeData & nodeData) = 0; |
| |
| /// Notify a final failure for a node operational resolution. |
| /// |
| /// Called within the chip event loop if node resolution could not be performed. |
| /// This may be due to internal errors or timeouts. |
| /// |
| /// This will be called only if 'OnOperationalNodeResolved' is never called. |
| virtual void OnOperationalNodeResolutionFailed(const PeerId & peerId, CHIP_ERROR error) = 0; |
| }; |
| |
| /** |
| * Node discovery context class. |
| * |
| * This class enables multiple clients of the global DNS-SD resolver to start simultaneous |
| * discovery operations. |
| * |
| * An object of this class is shared between a resolver client and the concrete resolver |
| * implementation. The client is responsible for allocating the context and passing it to |
| * the resolver when initiating a discovery operation. The resolver, in turn, is supposed to retain |
| * the context until the operation is finished. This allows the client to release the ownership of |
| * the context at any time without putting the resolver at risk of using a deleted object. |
| */ |
| class DiscoveryContext : public ReferenceCounted<DiscoveryContext> |
| { |
| public: |
| void SetBrowseIdentifier(intptr_t identifier) { mBrowseIdentifier.Emplace(identifier); } |
| void ClearBrowseIdentifier() { mBrowseIdentifier.ClearValue(); } |
| const Optional<intptr_t> & GetBrowseIdentifier() const { return mBrowseIdentifier; } |
| |
| void SetCommissioningDelegate(CommissioningResolveDelegate * delegate) { mCommissioningDelegate = delegate; } |
| void OnNodeDiscovered(const DiscoveredNodeData & nodeData) |
| { |
| if (mCommissioningDelegate != nullptr) |
| { |
| mCommissioningDelegate->OnNodeDiscovered(nodeData); |
| } |
| else |
| { |
| ChipLogError(Discovery, "Missing commissioning delegate. Data discarded"); |
| } |
| } |
| |
| private: |
| CommissioningResolveDelegate * mCommissioningDelegate = nullptr; |
| Optional<intptr_t> mBrowseIdentifier; |
| }; |
| |
| /** |
| * Interface for resolving CHIP DNS-SD services |
| */ |
| class Resolver |
| { |
| public: |
| virtual ~Resolver() {} |
| |
| /** |
| * Initializes the resolver. |
| * |
| * The method must be called before other methods of this class. |
| * If the resolver has already been initialized, the method exits immediately with no error. |
| */ |
| virtual CHIP_ERROR Init(Inet::EndPointManager<Inet::UDPEndPoint> * endPointManager) = 0; |
| |
| /** |
| * Returns whether the resolver has completed the initialization. |
| * |
| * Returns true if the resolver is ready to take node resolution and discovery requests. |
| */ |
| virtual bool IsInitialized() = 0; |
| |
| /** |
| * Shuts down the resolver if it has been initialized before. |
| */ |
| virtual void Shutdown() = 0; |
| |
| /** |
| * If nullptr is passed, the previously registered delegate is unregistered. |
| */ |
| virtual void SetOperationalDelegate(OperationalResolveDelegate * delegate) = 0; |
| |
| /** |
| * Requests resolution of the given operational node service. |
| * |
| * This will trigger a DNSSD query. |
| * |
| * When the operation succeeds or fails, and a resolver delegate has been registered, |
| * the result of the operation is passed to the delegate's `OnOperationalNodeResolved` or |
| * `OnOperationalNodeResolutionFailed` method, respectively. |
| * |
| * Multiple calls to ResolveNodeId may be coalesced by the implementation |
| * and lead to just one call to |
| * OnOperationalNodeResolved/OnOperationalNodeResolutionFailed, as long as |
| * the later calls cause the underlying querying mechanism to re-query as if |
| * there were no coalescing. |
| * |
| * A single call to ResolveNodeId may lead to multiple calls to |
| * OnOperationalNodeResolved with different IP addresses. |
| * |
| * @see NodeIdResolutionNoLongerNeeded. |
| */ |
| virtual CHIP_ERROR ResolveNodeId(const PeerId & peerId) = 0; |
| |
| /* |
| * Notify the resolver that one of the consumers that called ResolveNodeId |
| * successfully no longer needs the resolution result (e.g. because it got |
| * the result via OnOperationalNodeResolved, or got an via |
| * OnOperationalNodeResolutionFailed, or no longer cares about future |
| * updates). |
| * |
| * There must be a NodeIdResolutionNoLongerNeeded call that matches every |
| * successful ResolveNodeId call. In particular, implementations of |
| * OnOperationalNodeResolved and OnOperationalNodeResolutionFailed must call |
| * NodeIdResolutionNoLongerNeeded once for each prior successful call to |
| * ResolveNodeId for the relevant PeerId that has not yet had a matching |
| * NodeIdResolutionNoLongerNeeded call made. |
| */ |
| virtual void NodeIdResolutionNoLongerNeeded(const PeerId & peerId) = 0; |
| |
| /** |
| * Finds all commissionable nodes matching the given filter. |
| * |
| * Whenever a new matching node is found, the node information is passed to |
| * the `OnNodeDiscovered` method of the commissioning delegate configured |
| * in the context object. |
| * |
| * This method is expected to increase the reference count of the context |
| * object for as long as it takes to complete the discovery request. |
| */ |
| virtual CHIP_ERROR DiscoverCommissionableNodes(DiscoveryFilter filter, DiscoveryContext & context) = 0; |
| |
| /** |
| * Finds all commissioner nodes matching the given filter. |
| * |
| * Whenever a new matching node is found, the node information is passed to |
| * the `OnNodeDiscovered` method of the commissioning delegate configured |
| * in the context object. |
| * |
| * This method is expected to increase the reference count of the context |
| * object for as long as it takes to complete the discovery request. |
| */ |
| virtual CHIP_ERROR DiscoverCommissioners(DiscoveryFilter filter, DiscoveryContext & context) = 0; |
| |
| /** |
| * Stop discovery (of commissionable or commissioner nodes). |
| * |
| * Some back ends may not support stopping discovery, so consumers should |
| * not assume they will stop getting callbacks after calling this. |
| */ |
| virtual CHIP_ERROR StopDiscovery(DiscoveryContext & context) = 0; |
| |
| /** |
| * Verify the validity of an address that appears to be out of date (for example |
| * because establishing a connection to it has failed). |
| */ |
| virtual CHIP_ERROR ReconfirmRecord(const char * hostname, Inet::IPAddress address, Inet::InterfaceId interfaceId) = 0; |
| |
| /** |
| * Provides the system-wide implementation of the service resolver |
| */ |
| static Resolver & Instance(); |
| }; |
| |
| } // namespace Dnssd |
| } // namespace chip |