LCOV - code coverage report
Current view: top level - lib/address_resolve - AddressResolve_DefaultImpl.h (source / functions) Hit Total Coverage
Test: lcov_final.info Lines: 1 22 4.5 %
Date: 2024-02-15 08:20:41 Functions: 1 15 6.7 %

          Line data    Source code
       1             : /*
       2             :  *
       3             :  *    Copyright (c) 2022 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             : #pragma once
      18             : 
      19             : #include <lib/address_resolve/AddressResolve.h>
      20             : #include <lib/dnssd/IPAddressSorter.h>
      21             : #include <lib/dnssd/Resolver.h>
      22             : #include <system/TimeSource.h>
      23             : #include <transport/raw/PeerAddress.h>
      24             : 
      25             : namespace chip {
      26             : namespace AddressResolve {
      27             : namespace Impl {
      28             : 
      29             : inline constexpr uint8_t kNodeLookupResultsLen = CHIP_CONFIG_MDNS_RESOLVE_LOOKUP_RESULTS;
      30             : 
      31             : enum class NodeLookupResult
      32             : {
      33             :     kKeepSearching, // keep the current search active
      34             :     kLookupError,   // final status: error
      35             :     kLookupSuccess, // final status: success
      36             : };
      37             : 
      38             : struct NodeLookupResults
      39             : {
      40             :     ResolveResult results[kNodeLookupResultsLen] = {};
      41             :     uint8_t count                                = 0; // number of valid ResolveResult
      42             :     uint8_t consumed                             = 0; // number of already read ResolveResult
      43             : 
      44             :     bool UpdateResults(const ResolveResult & result, Dnssd::IPAddressSorter::IpScore score);
      45             : 
      46           0 :     bool HasValidResult() const { return count > consumed; }
      47             : 
      48           0 :     ResolveResult ConsumeResult()
      49             :     {
      50           0 :         VerifyOrDie(HasValidResult());
      51           0 :         return results[consumed++];
      52             :     }
      53             : 
      54             : #if CHIP_DETAIL_LOGGING
      55             :     void LogDetail() const
      56             :     {
      57             :         for (unsigned i = 0; i < count; i++)
      58             :         {
      59             :             char addr_string[Transport::PeerAddress::kMaxToStringSize];
      60             :             results[i].address.ToString(addr_string);
      61             :             ChipLogDetail(Discovery, "\t#%d: %s", i + 1, addr_string);
      62             :         }
      63             :     }
      64             : #endif // CHIP_DETAIL_LOGGING
      65             : };
      66             : 
      67             : /// Action to take when some resolve data
      68             : /// has been received by an active lookup
      69             : class NodeLookupAction
      70             : {
      71             : public:
      72             :     NodeLookupAction(const NodeLookupAction & other) { *this = other; }
      73             : 
      74             :     NodeLookupAction & operator=(const NodeLookupAction & other)
      75             :     {
      76             :         mResultType = other.mResultType;
      77             :         switch (mResultType)
      78             :         {
      79             :         case NodeLookupResult::kLookupError:
      80             :             mResult.error = other.mResult.error;
      81             :             break;
      82             :         case NodeLookupResult::kLookupSuccess:
      83             :             mResult.result = other.mResult.result;
      84             :             break;
      85             :         case NodeLookupResult::kKeepSearching:
      86             :             // no data is important here
      87             :             break;
      88             :         }
      89             :         return *this;
      90             :     }
      91             : 
      92           0 :     static NodeLookupAction KeepSearching() { return NodeLookupAction(NodeLookupResult::kKeepSearching); }
      93             : 
      94           0 :     static NodeLookupAction Error(CHIP_ERROR err)
      95             :     {
      96           0 :         NodeLookupAction value(NodeLookupResult::kLookupError);
      97           0 :         value.mResult.error = err;
      98           0 :         return value;
      99             :     }
     100             : 
     101           0 :     static NodeLookupAction Success(const AddressResolve::ResolveResult & result)
     102             :     {
     103           0 :         NodeLookupAction value(NodeLookupResult::kLookupSuccess);
     104           0 :         value.mResult.result = result;
     105           0 :         return value;
     106             :     }
     107             : 
     108           0 :     NodeLookupResult Type() const { return mResultType; }
     109           0 :     CHIP_ERROR ErrorResult() const { return mResult.error; }
     110           0 :     const AddressResolve::ResolveResult & ResolveResult() const { return mResult.result; }
     111             : 
     112             : private:
     113           0 :     NodeLookupAction(NodeLookupResult result) : mResultType(result) {}
     114             : 
     115             :     union
     116             :     {
     117             :         CHIP_ERROR error;
     118             :         AddressResolve::ResolveResult result;
     119             :     } mResult = {};
     120             :     NodeLookupResult mResultType;
     121             : };
     122             : 
     123             : /// An implementation of a node lookup handle
     124             : ///
     125             : /// Keeps track of time requests as well as the current
     126             : /// "best" IPs addresses found.
     127             : class NodeLookupHandle : public NodeLookupHandleBase
     128             : {
     129             : public:
     130           0 :     const NodeLookupRequest & GetRequest() const { return mRequest; }
     131             : 
     132             :     /// Sets up a request for a new lookup.
     133             :     /// Resets internal state (i.e. best address so far)
     134             :     void ResetForLookup(System::Clock::Timestamp now, const NodeLookupRequest & request);
     135             : 
     136             :     /// Mark that a specific IP address has been found
     137             :     void LookupResult(const ResolveResult & result);
     138             : 
     139             :     /// Called after timeouts or after a series of IP addresses have been
     140             :     /// marked as found.
     141             :     ///
     142             :     /// If sufficient data for a complete address resolution has been gathered,
     143             :     /// calls the underlying listener `OnNodeAddressResolved` and returns
     144             :     /// kStopSearching.
     145             :     ///
     146             :     /// Returns kKeepSearching if more data is acceptable (keep timeouts and
     147             :     /// any active searches)
     148             :     NodeLookupAction NextAction(System::Clock::Timestamp now);
     149             : 
     150             :     /// Does the node have any valid lookup result?
     151           0 :     bool HasLookupResult() const { return mResults.HasValidResult(); }
     152             : 
     153             :     /// Return the next valid lookup result.
     154           0 :     ResolveResult TakeLookupResult() { return mResults.ConsumeResult(); }
     155             : 
     156             :     /// Return when the next timer (min or max lookup time) is required to
     157             :     /// be triggered for this lookup handle
     158             :     System::Clock::Timeout NextEventTimeout(System::Clock::Timestamp now);
     159             : 
     160             : private:
     161             :     NodeLookupResults mResults;
     162             :     NodeLookupRequest mRequest; // active request to process
     163             :     System::Clock::Timestamp mRequestStartTime;
     164             : };
     165             : 
     166             : class Resolver : public ::chip::AddressResolve::Resolver, public Dnssd::OperationalResolveDelegate
     167             : {
     168             : public:
     169           1 :     ~Resolver() override = default;
     170             : 
     171             :     // AddressResolve::Resolver
     172             : 
     173             :     CHIP_ERROR Init(System::Layer * systemLayer) override;
     174             :     CHIP_ERROR LookupNode(const NodeLookupRequest & request, Impl::NodeLookupHandle & handle) override;
     175             :     CHIP_ERROR TryNextResult(Impl::NodeLookupHandle & handle) override;
     176             :     CHIP_ERROR CancelLookup(Impl::NodeLookupHandle & handle, FailureCallback cancel_method) override;
     177             :     void Shutdown() override;
     178             : 
     179             :     // Dnssd::OperationalResolveDelegate
     180             : 
     181             :     void OnOperationalNodeResolved(const Dnssd::ResolvedNodeData & nodeData) override;
     182             :     void OnOperationalNodeResolutionFailed(const PeerId & peerId, CHIP_ERROR error) override;
     183             : 
     184             : private:
     185           0 :     static void OnResolveTimer(System::Layer * layer, void * context) { static_cast<Resolver *>(context)->HandleTimer(); }
     186             : 
     187             :     /// Timer on lookup node events: min and max search times.
     188             :     void HandleTimer();
     189             : 
     190             :     /// Sets up a system timer to the next closest timeout on one of the active
     191             :     /// lookup operations.
     192             :     ///
     193             :     /// Any existing timer is cancelled and then OnResolveTimer will be called
     194             :     /// on the closest event required for an active resolve.
     195             :     void ReArmTimer();
     196             : 
     197             :     /// Handles the 'NextAction' on the given iterator
     198             :     ///
     199             :     /// NOTE: may remove `current` from the internal list. Current MUST NOT
     200             :     /// be used after calling this method.
     201             :     void HandleAction(IntrusiveList<NodeLookupHandle>::Iterator & current);
     202             : 
     203             :     System::Layer * mSystemLayer = nullptr;
     204             :     Time::TimeSource<Time::Source::kSystem> mTimeSource;
     205             :     IntrusiveList<NodeLookupHandle> mActiveLookups;
     206             : };
     207             : 
     208             : } // namespace Impl
     209             : } // namespace AddressResolve
     210             : } // namespace chip

Generated by: LCOV version 1.14