LCOV - code coverage report
Current view: top level - lib/dnssd/minimal_mdns - ResponseBuilder.h (source / functions) Hit Total Coverage
Test: lcov_final.info Lines: 35 39 89.7 %
Date: 2024-02-15 08:20:41 Functions: 9 9 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             : #pragma once
      19             : 
      20             : #include <system/SystemPacketBuffer.h>
      21             : 
      22             : #include <lib/dnssd/minimal_mdns/Parser.h>
      23             : #include <lib/dnssd/minimal_mdns/core/DnsHeader.h>
      24             : #include <lib/dnssd/minimal_mdns/records/ResourceRecord.h>
      25             : 
      26             : namespace mdns {
      27             : namespace Minimal {
      28             : 
      29             : /// Writes a MDNS reply into a given packet buffer.
      30             : class ResponseBuilder
      31             : {
      32             : public:
      33           2 :     ResponseBuilder() : mHeader(nullptr), mEndianOutput(nullptr, 0), mWriter(&mEndianOutput) {}
      34             :     ResponseBuilder(chip::System::PacketBufferHandle && packet) :
      35             :         mHeader(nullptr), mEndianOutput(nullptr, 0), mWriter(&mEndianOutput)
      36             :     {
      37             :         Reset(std::move(packet));
      38             :     }
      39             : 
      40         110 :     ResponseBuilder & Reset(chip::System::PacketBufferHandle && packet)
      41             :     {
      42         110 :         mPacket = std::move(packet);
      43         110 :         mHeader = HeaderRef(mPacket->Start());
      44             : 
      45         110 :         if (mPacket->AvailableDataLength() >= HeaderRef::kSizeBytes)
      46             :         {
      47         110 :             mPacket->SetDataLength(HeaderRef::kSizeBytes);
      48         110 :             mHeader.Clear();
      49         110 :             mBuildOk = true;
      50             :         }
      51             :         else
      52             :         {
      53           0 :             mBuildOk = false;
      54             :         }
      55             : 
      56         110 :         mHeader.SetFlags(mHeader.GetFlags().SetResponse().SetAuthoritative());
      57             : 
      58         110 :         mEndianOutput =
      59         110 :             chip::Encoding::BigEndian::BufferWriter(mPacket->Start(), mPacket->DataLength() + mPacket->AvailableDataLength());
      60         110 :         mEndianOutput.Skip(mPacket->DataLength());
      61             : 
      62         110 :         mWriter.Reset();
      63             : 
      64         110 :         return *this;
      65             :     }
      66             : 
      67             :     CHECK_RETURN_VALUE
      68         110 :     chip::System::PacketBufferHandle ReleasePacket()
      69             :     {
      70         110 :         mHeader  = HeaderRef(nullptr);
      71         110 :         mBuildOk = false;
      72         110 :         return std::move(mPacket);
      73             :     }
      74             : 
      75         110 :     bool HasResponseRecords() const
      76             :     {
      77         110 :         return (mHeader.GetAnswerCount() != 0) || (mHeader.GetAuthorityCount() != 0) || (mHeader.GetAdditionalCount() != 0);
      78             :     }
      79             : 
      80         130 :     HeaderRef & Header() { return mHeader; }
      81             : 
      82             :     /// Attempts to add a record to the currentsystem packet buffer.
      83             :     /// On success, the packet buffer data length is updated.
      84             :     /// On failure, the packet buffer data length is NOT updated and header is unchanged.
      85         831 :     ResponseBuilder & AddRecord(ResourceType type, const ResourceRecord & record)
      86             :     {
      87         831 :         if (!mBuildOk)
      88             :         {
      89           0 :             return *this;
      90             :         }
      91             : 
      92         831 :         if (!record.Append(mHeader, type, mWriter))
      93             :         {
      94          10 :             mBuildOk = false;
      95             :         }
      96             :         else
      97             :         {
      98         821 :             VerifyOrDie(mEndianOutput.Fit()); // should be guaranteed because record Append succeeded
      99         821 :             mPacket->SetDataLength(static_cast<uint16_t>(mEndianOutput.Needed()));
     100             :         }
     101             : 
     102         831 :         return *this;
     103             :     }
     104             : 
     105          32 :     ResponseBuilder & AddQuery(const QueryData & query)
     106             :     {
     107          32 :         if (!mBuildOk)
     108             :         {
     109           0 :             return *this;
     110             :         }
     111             : 
     112          32 :         if (!query.Append(mHeader, mWriter))
     113             :         {
     114           0 :             mBuildOk = false;
     115             :         }
     116             :         else
     117             :         {
     118          32 :             mPacket->SetDataLength(static_cast<uint16_t>(mEndianOutput.Needed()));
     119             :         }
     120          32 :         return *this;
     121             :     }
     122             : 
     123        1662 :     bool Ok() const { return mBuildOk; }
     124         980 :     bool HasPacketBuffer() const { return !mPacket.IsNull(); }
     125             : 
     126             : private:
     127             :     chip::System::PacketBufferHandle mPacket;
     128             :     HeaderRef mHeader;
     129             :     chip::Encoding::BigEndian::BufferWriter mEndianOutput;
     130             :     RecordWriter mWriter;
     131             :     bool mBuildOk = false;
     132             : };
     133             : 
     134             : } // namespace Minimal
     135             : } // namespace mdns

Generated by: LCOV version 1.14