Line data Source code
1 : /* 2 : * 3 : * Copyright (c) 2021 Project CHIP Authors 4 : * 5 : * Licensed under the Apache License, Version 2.0 (the "License"); 6 : * you may not use this file except in compliance with the License. 7 : * You may obtain a copy of the License at 8 : * 9 : * http://www.apache.org/licenses/LICENSE-2.0 10 : * 11 : * Unless required by applicable law or agreed to in writing, software 12 : * distributed under the License is distributed on an "AS IS" BASIS, 13 : * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 : * See the License for the specific language governing permissions and 15 : * limitations under the License. 16 : */ 17 : 18 : #pragma once 19 : 20 : #include <cstdint> 21 : #include <limits> 22 : #include <utility> 23 : 24 : #include <inet/IPAddress.h> 25 : #include <inet/InetInterface.h> 26 : #include <inet/UDPEndPoint.h> 27 : #include <lib/core/CHIPError.h> 28 : #include <lib/core/Optional.h> 29 : #include <lib/core/PeerId.h> 30 : #include <lib/core/ReferenceCounted.h> 31 : #include <lib/dnssd/Constants.h> 32 : #include <lib/dnssd/Types.h> 33 : #include <lib/support/logging/CHIPLogging.h> 34 : 35 : namespace chip { 36 : namespace Dnssd { 37 : 38 : /// Node resolution data common to both operational and commissionable discovery 39 : 40 : /// Callbacks for resolving operational node resolution 41 : class OperationalResolveDelegate 42 : { 43 : public: 44 1 : virtual ~OperationalResolveDelegate() = default; 45 : 46 : /// Called within the CHIP event loop after a successful node resolution. 47 : /// 48 : /// May be called multiple times: implementations may call this once per 49 : /// received packet and MDNS packets may arrive over different interfaces 50 : /// which will make nodeData have different content. 51 : virtual void OnOperationalNodeResolved(const ResolvedNodeData & nodeData) = 0; 52 : 53 : /// Notify a final failure for a node operational resolution. 54 : /// 55 : /// Called within the chip event loop if node resolution could not be performed. 56 : /// This may be due to internal errors or timeouts. 57 : /// 58 : /// This will be called only if 'OnOperationalNodeResolved' is never called. 59 : virtual void OnOperationalNodeResolutionFailed(const PeerId & peerId, CHIP_ERROR error) = 0; 60 : }; 61 : 62 : /** 63 : * Node discovery context class. 64 : * 65 : * This class enables multiple clients of the global DNS-SD resolver to start simultaneous 66 : * discovery operations. 67 : * 68 : * An object of this class is shared between a resolver client and the concrete resolver 69 : * implementation. The client is responsible for allocating the context and passing it to 70 : * the resolver when initiating a discovery operation. The resolver, in turn, is supposed to retain 71 : * the context until the operation is finished. This allows the client to release the ownership of 72 : * the context at any time without putting the resolver at risk of using a deleted object. 73 : */ 74 : class DiscoveryContext : public ReferenceCounted<DiscoveryContext> 75 : { 76 : public: 77 : void SetBrowseIdentifier(intptr_t identifier) { mBrowseIdentifier.Emplace(identifier); } 78 : void ClearBrowseIdentifier() { mBrowseIdentifier.ClearValue(); } 79 : const Optional<intptr_t> & GetBrowseIdentifier() const { return mBrowseIdentifier; } 80 : 81 9 : void SetCommissioningDelegate(CommissioningResolveDelegate * delegate) { mCommissioningDelegate = delegate; } 82 0 : void OnNodeDiscovered(const DiscoveredNodeData & nodeData) 83 : { 84 0 : if (mCommissioningDelegate != nullptr) 85 : { 86 0 : mCommissioningDelegate->OnNodeDiscovered(nodeData); 87 : } 88 : else 89 : { 90 0 : ChipLogError(Discovery, "Missing commissioning delegate. Data discarded"); 91 : } 92 0 : } 93 : 94 : private: 95 : CommissioningResolveDelegate * mCommissioningDelegate = nullptr; 96 : Optional<intptr_t> mBrowseIdentifier; 97 : }; 98 : 99 : /** 100 : * Interface for resolving CHIP DNS-SD services 101 : */ 102 : class Resolver 103 : { 104 : public: 105 28 : virtual ~Resolver() {} 106 : 107 : /** 108 : * Initializes the resolver. 109 : * 110 : * The method must be called before other methods of this class. 111 : * If the resolver has already been initialized, the method exits immediately with no error. 112 : */ 113 : virtual CHIP_ERROR Init(Inet::EndPointManager<Inet::UDPEndPoint> * endPointManager) = 0; 114 : 115 : /** 116 : * Returns whether the resolver has completed the initialization. 117 : * 118 : * Returns true if the resolver is ready to take node resolution and discovery requests. 119 : */ 120 : virtual bool IsInitialized() = 0; 121 : 122 : /** 123 : * Shuts down the resolver if it has been initialized before. 124 : */ 125 : virtual void Shutdown() = 0; 126 : 127 : /** 128 : * If nullptr is passed, the previously registered delegate is unregistered. 129 : */ 130 : virtual void SetOperationalDelegate(OperationalResolveDelegate * delegate) = 0; 131 : 132 : /** 133 : * Requests resolution of the given operational node service. 134 : * 135 : * This will trigger a DNSSD query. 136 : * 137 : * When the operation succeeds or fails, and a resolver delegate has been registered, 138 : * the result of the operation is passed to the delegate's `OnOperationalNodeResolved` or 139 : * `OnOperationalNodeResolutionFailed` method, respectively. 140 : * 141 : * Multiple calls to ResolveNodeId may be coalesced by the implementation 142 : * and lead to just one call to 143 : * OnOperationalNodeResolved/OnOperationalNodeResolutionFailed, as long as 144 : * the later calls cause the underlying querying mechanism to re-query as if 145 : * there were no coalescing. 146 : * 147 : * A single call to ResolveNodeId may lead to multiple calls to 148 : * OnOperationalNodeResolved with different IP addresses. 149 : * 150 : * @see NodeIdResolutionNoLongerNeeded. 151 : */ 152 : virtual CHIP_ERROR ResolveNodeId(const PeerId & peerId) = 0; 153 : 154 : /* 155 : * Notify the resolver that one of the consumers that called ResolveNodeId 156 : * successfully no longer needs the resolution result (e.g. because it got 157 : * the result via OnOperationalNodeResolved, or got an via 158 : * OnOperationalNodeResolutionFailed, or no longer cares about future 159 : * updates). 160 : * 161 : * There must be a NodeIdResolutionNoLongerNeeded call that matches every 162 : * successful ResolveNodeId call. In particular, implementations of 163 : * OnOperationalNodeResolved and OnOperationalNodeResolutionFailed must call 164 : * NodeIdResolutionNoLongerNeeded once for each prior successful call to 165 : * ResolveNodeId for the relevant PeerId that has not yet had a matching 166 : * NodeIdResolutionNoLongerNeeded call made. 167 : */ 168 : virtual void NodeIdResolutionNoLongerNeeded(const PeerId & peerId) = 0; 169 : 170 : /** 171 : * Finds all commissionable nodes matching the given filter. 172 : * 173 : * Whenever a new matching node is found, the node information is passed to 174 : * the `OnNodeDiscovered` method of the commissioning delegate configured 175 : * in the context object. 176 : * 177 : * This method is expected to increase the reference count of the context 178 : * object for as long as it takes to complete the discovery request. 179 : */ 180 : virtual CHIP_ERROR DiscoverCommissionableNodes(DiscoveryFilter filter, DiscoveryContext & context) = 0; 181 : 182 : /** 183 : * Finds all commissioner nodes matching the given filter. 184 : * 185 : * Whenever a new matching node is found, the node information is passed to 186 : * the `OnNodeDiscovered` method of the commissioning delegate configured 187 : * in the context object. 188 : * 189 : * This method is expected to increase the reference count of the context 190 : * object for as long as it takes to complete the discovery request. 191 : */ 192 : virtual CHIP_ERROR DiscoverCommissioners(DiscoveryFilter filter, DiscoveryContext & context) = 0; 193 : 194 : /** 195 : * Stop discovery (of commissionable or commissioner nodes). 196 : * 197 : * Some back ends may not support stopping discovery, so consumers should 198 : * not assume they will stop getting callbacks after calling this. 199 : */ 200 : virtual CHIP_ERROR StopDiscovery(DiscoveryContext & context) = 0; 201 : 202 : /** 203 : * Verify the validity of an address that appears to be out of date (for example 204 : * because establishing a connection to it has failed). 205 : */ 206 : virtual CHIP_ERROR ReconfirmRecord(const char * hostname, Inet::IPAddress address, Inet::InterfaceId interfaceId) = 0; 207 : 208 : /** 209 : * Provides the system-wide implementation of the service resolver 210 : */ 211 : static Resolver & Instance(); 212 : }; 213 : 214 : } // namespace Dnssd 215 : } // namespace chip