LCOV - code coverage report
Current view: top level - lib/dnssd - IncrementalResolve.h (source / functions) Hit Total Coverage
Test: lcov_final.info Lines: 10 13 76.9 %
Date: 2024-02-15 08:20:41 Functions: 7 10 70.0 %

          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/dnssd/Resolver.h>
      20             : #include <lib/dnssd/minimal_mdns/Parser.h>
      21             : #include <lib/dnssd/minimal_mdns/RecordData.h>
      22             : #include <lib/dnssd/minimal_mdns/core/QName.h>
      23             : #include <lib/support/BitFlags.h>
      24             : #include <lib/support/Variant.h>
      25             : 
      26             : namespace chip {
      27             : namespace Dnssd {
      28             : 
      29             : /// Allows storing and retrieving of a SerializedQName for later recall.
      30             : ///
      31             : /// This is a convenience storage as MDNS generally provides data as QNames
      32             : /// and comparisons between QNames is more convenient than replacing them with
      33             : /// null-terminated character strings.
      34             : class StoredServerName
      35             : {
      36             : public:
      37         116 :     StoredServerName() {}
      38             : 
      39          25 :     void Clear() { memset(mNameBuffer, 0, sizeof(mNameBuffer)); }
      40             : 
      41             :     /// Set the underlying value. Will return CHIP_ERROR_NO_MEMORY
      42             :     /// on insufficient storage space.
      43             :     ///
      44             :     /// If insufficient space, buffer will be cleared.
      45             :     CHIP_ERROR Set(mdns::Minimal::SerializedQNameIterator value);
      46             : 
      47             :     /// Return the underlying value in this object.
      48             :     ///
      49             :     /// Value valid as long as this object is valid and underlying Set() is
      50             :     /// not called.
      51             :     mdns::Minimal::SerializedQNameIterator Get() const;
      52             : 
      53             : private:
      54             :     // Try to have space for at least:
      55             :     //  L1234._sub._matterc._udp.local      => 30 chars
      56             :     //  <fabric>-<node>._matter._tcp.local  => 52 chars
      57             :     //  <hostname>.local (where hostname is kHostNameMaxLength == 16)
      58             :     //
      59             :     // This does not try to optimize out ".local" suffix which is always expected
      60             :     // since comparisons are easier when suffix is still present.
      61             :     static constexpr size_t kMaxStoredNameLength = 64;
      62             : 
      63             :     uint8_t mNameBuffer[kMaxStoredNameLength] = {};
      64             : };
      65             : 
      66             : /// Incrementally accumulates data from DNSSD packets. It is geared twoards
      67             : /// resource-constrained dns-sd querier implementations.
      68             : ///
      69             : /// It all starts with processing SRV records which define the type of record
      70             : /// (could be operational, commissionable or commissioner), after which the
      71             : /// additional data is accumulated, specifically TXT information and A/AAAA
      72             : ///
      73             : /// Class can also be used to determine what additional data is missing from a
      74             : /// record so that additional DNSSD queries can be made recursively (e.g. if
      75             : /// only a SRV/TXT records are available, ask for AAAA records).
      76             : class IncrementalResolver
      77             : {
      78             : public:
      79             :     // Elements that the incremental resolve still needs
      80             :     enum class RequiredInformationBitFlags : uint8_t
      81             :     {
      82             :         kSrvInitialization = (1 << 0), // server being initialized
      83             :         kIpAddress         = (1 << 1), // IP address missing
      84             :     };
      85             :     using RequiredInformationFlags = BitFlags<RequiredInformationBitFlags>;
      86             : 
      87             :     // Type of service name that is contained in this resolver
      88             :     enum class ServiceNameType
      89             :     {
      90             :         kInvalid, // not a matter service name
      91             :         kOperational,
      92             :         kCommissioner,
      93             :         kCommissionable,
      94             :     };
      95             : 
      96          58 :     IncrementalResolver() = default;
      97             : 
      98             :     /// Checks if object has been initialized using the `InitializeParsing`
      99             :     /// method.
     100        1024 :     bool IsActive() const { return mSpecificResolutionData.Valid(); }
     101             : 
     102          96 :     bool IsActiveCommissionParse() const { return mSpecificResolutionData.Is<CommissionNodeData>(); }
     103           0 :     bool IsActiveOperationalParse() const { return mSpecificResolutionData.Is<OperationalNodeData>(); }
     104             : 
     105          32 :     ServiceNameType GetCurrentType() const { return mServiceNameType; }
     106             : 
     107             :     /// Start parsing a new record. SRV records are the records we are mainly
     108             :     /// interested on, after which TXT and A/AAAA are looked for.
     109             :     ///
     110             :     /// If this function returns with error, the object will be in an inactive state.
     111             :     CHIP_ERROR InitializeParsing(mdns::Minimal::SerializedQNameIterator name, const mdns::Minimal::SrvRecord & srv);
     112             : 
     113             :     /// Notify that a new record is being processed.
     114             :     /// Will handle filtering and processing of data to determine if the entry is relevant for
     115             :     /// the current resolver.
     116             :     ///
     117             :     /// Providing a data that is not relevant to the current parser is not considered and error,
     118             :     /// however if the resource fails parsing completely an error will be returned.
     119             :     ///
     120             :     ///
     121             :     /// [data] represents the record received via [interface] and [packetRange] represents the range
     122             :     /// of valid bytes within the packet for the purpose of QName parsing
     123             :     CHIP_ERROR OnRecord(Inet::InterfaceId interface, const mdns::Minimal::ResourceData & data,
     124             :                         mdns::Minimal::BytesRange packetRange);
     125             : 
     126             :     /// Return what additional data is required until the object can be extracted
     127             :     ///
     128             :     /// If `!GetREquiredInformation().HasAny()` the parsed information is ready
     129             :     /// to be processed.
     130             :     RequiredInformationFlags GetMissingRequiredInformation() const;
     131             : 
     132             :     /// Fetch the target host name set by `InitializeParsing`
     133             :     ///
     134             :     /// VALIDITY: Data references internal storage of this object and is valid as long
     135             :     ///           as this object is valid and InitializeParsing is not called again.
     136           0 :     mdns::Minimal::SerializedQNameIterator GetTargetHostName() const { return mTargetHostName.Get(); }
     137             : 
     138             :     /// Fetch the record name set by `InitializeParsing`.
     139             :     ///
     140             :     /// VALIDITY: Data references internal storage of this object and is valid as long
     141             :     ///           as this object is valid and InitializeParsing is not called again.
     142           0 :     mdns::Minimal::SerializedQNameIterator GetRecordName() const { return mRecordName.Get(); }
     143             : 
     144             :     /// Take the current value of the object and clear it once returned.
     145             :     ///
     146             :     /// Object must be in `IsActiveCommissionParse()` for this to succeed.
     147             :     /// Data will be returned (and cleared) even if not yet complete based
     148             :     /// on `GetMissingRequiredInformation()`. This method takes as much data as
     149             :     /// it was parsed so far.
     150             :     CHIP_ERROR Take(DiscoveredNodeData & outputData);
     151             : 
     152             :     /// Take the current value of the object and clear it once returned.
     153             :     ///
     154             :     /// Object must be in `IsActiveOperationalParse()` for this to succeed.
     155             :     /// Data will be returned (and cleared) even if not yet complete based
     156             :     /// on `GetMissingRequiredInformation()`. This method takes as much data as
     157             :     /// it was parsed so far.
     158             :     CHIP_ERROR Take(ResolvedNodeData & outputData);
     159             : 
     160             :     /// Clears current state, setting as inactive
     161          35 :     void ResetToInactive()
     162             :     {
     163          35 :         mCommonResolutionData.Reset();
     164          35 :         mSpecificResolutionData = ParsedRecordSpecificData();
     165          35 :     }
     166             : 
     167             : private:
     168             :     /// Notify that a PTR record can be parsed.
     169             :     ///
     170             :     /// Input data MUST have GetType() == QType::TXT
     171             :     CHIP_ERROR OnTxtRecord(const mdns::Minimal::ResourceData & data, mdns::Minimal::BytesRange packetRange);
     172             : 
     173             :     /// Notify that a new IP addres has been found.
     174             :     ///
     175             :     /// This is to be called on both A (if IPv4 support is enabled) and AAAA
     176             :     /// addresses.
     177             :     ///
     178             :     /// Prerequisite: IP address belongs to the right nost name
     179             :     CHIP_ERROR OnIpAddress(Inet::InterfaceId interface, const Inet::IPAddress & addr);
     180             : 
     181             :     using ParsedRecordSpecificData = Variant<OperationalNodeData, CommissionNodeData>;
     182             : 
     183             :     StoredServerName mRecordName;     // Record name for what is parsed (SRV/PTR/TXT)
     184             :     StoredServerName mTargetHostName; // `Target` for the SRV record
     185             :     ServiceNameType mServiceNameType = ServiceNameType::kInvalid;
     186             :     CommonResolutionData mCommonResolutionData;
     187             :     ParsedRecordSpecificData mSpecificResolutionData;
     188             : };
     189             : 
     190             : } // namespace Dnssd
     191             : } // namespace chip

Generated by: LCOV version 1.14