LCOV - code coverage report
Current view: top level - lib/dnssd/minimal_mdns/responders - QueryResponder.cpp (source / functions) Hit Total Coverage
Test: lcov_final.info Lines: 65 67 97.0 %
Date: 2024-02-15 08:20:41 Functions: 8 8 100.0 %

          Line data    Source code
       1             : /*
       2             :  *
       3             :  *    Copyright (c) 2020 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             : #include "QueryResponder.h"
      19             : 
      20             : #include <lib/dnssd/minimal_mdns/core/QNameString.h>
      21             : #include <lib/dnssd/minimal_mdns/records/Ptr.h>
      22             : 
      23             : #include <lib/support/logging/CHIPLogging.h>
      24             : 
      25             : namespace mdns {
      26             : namespace Minimal {
      27             : 
      28             : const QNamePart kDnsSdQueryPath[] = { "_services", "_dns-sd", "_udp", "local" };
      29             : 
      30          38 : QueryResponderBase::QueryResponderBase(Internal::QueryResponderInfo * infos, size_t infoSizes) :
      31          38 :     Responder(QType::PTR, FullQName(kDnsSdQueryPath)), mResponderInfos(infos), mResponderInfoSize(infoSizes)
      32          38 : {}
      33             : 
      34         132 : void QueryResponderBase::Init()
      35             : {
      36        1448 :     for (size_t i = 0; i < mResponderInfoSize; i++)
      37             :     {
      38        1316 :         mResponderInfos[i].Clear();
      39             :     }
      40             : 
      41         132 :     if (mResponderInfoSize > 0)
      42             :     {
      43             :         // reply to queries about services available
      44         132 :         mResponderInfos[0].responder = this;
      45             :     }
      46             : 
      47         132 :     if (mResponderInfoSize < 2)
      48             :     {
      49             :         // Nothing useful really
      50           7 :         ChipLogError(Discovery, "Query responder storage size too small");
      51             :     }
      52         132 : }
      53             : 
      54         315 : QueryResponderSettings QueryResponderBase::AddResponder(RecordResponder * responder)
      55             : {
      56         315 :     if (responder == nullptr)
      57             :     {
      58           0 :         return QueryResponderSettings();
      59             :     }
      60         315 :     ChipLogDetail(Discovery, "Responding with %s", QNameString(responder->GetQName()).c_str());
      61             : 
      62        1495 :     for (size_t i = 0; i < mResponderInfoSize; i++)
      63             :     {
      64        1395 :         if (mResponderInfos[i].responder == nullptr)
      65             :         {
      66         215 :             mResponderInfos[i].Clear();
      67         215 :             mResponderInfos[i].responder = responder;
      68             : 
      69         215 :             return QueryResponderSettings(&mResponderInfos[i]);
      70             :         }
      71             :     }
      72         100 :     return QueryResponderSettings();
      73             : }
      74             : 
      75         367 : void QueryResponderBase::ResetAdditionals()
      76             : {
      77             : 
      78        4346 :     for (size_t i = 0; i < mResponderInfoSize; i++)
      79             :     {
      80        3979 :         mResponderInfos[i].reportNowAsAdditional = false;
      81             :     }
      82         367 : }
      83             : 
      84         825 : size_t QueryResponderBase::MarkAdditional(const FullQName & qname)
      85             : {
      86         825 :     size_t count = 0;
      87        9153 :     for (size_t i = 0; i < mResponderInfoSize; i++)
      88             :     {
      89        8328 :         if (mResponderInfos[i].responder == nullptr)
      90             :         {
      91         954 :             continue; // not a valid entry
      92             :         }
      93             : 
      94        7374 :         if (mResponderInfos[i].reportNowAsAdditional)
      95             :         {
      96        2486 :             continue; // already marked
      97             :         }
      98             : 
      99        4888 :         if (mResponderInfos[i].responder->GetQName() == qname)
     100             :         {
     101         524 :             mResponderInfos[i].reportNowAsAdditional = true;
     102         524 :             count++;
     103             :         }
     104             :     }
     105             : 
     106         825 :     return count;
     107             : }
     108             : 
     109         762 : void QueryResponderBase::MarkAdditionalRepliesFor(QueryResponderIterator it)
     110             : {
     111         762 :     Internal::QueryResponderInfo * info = it.GetInternal();
     112             : 
     113         762 :     if (!info->alsoReportAdditionalQName)
     114             :     {
     115         315 :         return; // nothing additional to report
     116             :     }
     117             : 
     118         447 :     if (MarkAdditional(info->additionalQName) == 0)
     119             :     {
     120         311 :         return; // nothing additional added
     121             :     }
     122             : 
     123             :     // something additionally added. Iterate and re-add until no more additional items were added
     124         136 :     bool keepAdding = true;
     125         398 :     while (keepAdding)
     126             :     {
     127         262 :         keepAdding = false;
     128             : 
     129         262 :         QueryResponderRecordFilter filter;
     130         262 :         filter.SetIncludeAdditionalRepliesOnly(true);
     131             : 
     132        1290 :         for (auto ait = begin(&filter); ait != end(); ait++)
     133             :         {
     134        1028 :             if (ait.GetInternal()->alsoReportAdditionalQName)
     135             :             {
     136         504 :                 keepAdding = keepAdding || (MarkAdditional(ait.GetInternal()->additionalQName) != 0);
     137             :             }
     138             :         }
     139             :     }
     140             : }
     141             : 
     142         309 : void QueryResponderBase::AddAllResponses(const chip::Inet::IPPacketInfo * source, ResponderDelegate * delegate,
     143             :                                          const ResponseConfiguration & configuration)
     144             : {
     145         309 :     if (!delegate->ShouldSend(*this))
     146             :     {
     147         284 :         return;
     148             :     }
     149             : 
     150             :     // reply to dns-sd service list request
     151         278 :     for (size_t i = 0; i < mResponderInfoSize; i++)
     152             :     {
     153         253 :         if (!mResponderInfos[i].reportService)
     154             :         {
     155         214 :             continue;
     156             :         }
     157             : 
     158          39 :         if (mResponderInfos[i].responder == nullptr)
     159             :         {
     160           0 :             continue;
     161             :         }
     162             : 
     163          39 :         PtrResourceRecord record(GetQName(), mResponderInfos[i].responder->GetQName());
     164          39 :         configuration.Adjust(record);
     165          39 :         delegate->AddResponse(record);
     166          39 :     }
     167             : 
     168          25 :     delegate->ResponsesAdded(*this);
     169             : }
     170             : 
     171         426 : void QueryResponderBase::ClearBroadcastThrottle()
     172             : {
     173        5118 :     for (size_t i = 0; i < mResponderInfoSize; i++)
     174             :     {
     175        4692 :         mResponderInfos[i].lastMulticastTime = chip::System::Clock::kZero;
     176             :     }
     177         426 : }
     178             : 
     179             : } // namespace Minimal
     180             : } // namespace mdns

Generated by: LCOV version 1.14