e7ee74942cd10465e45a88c8ff47b81140a5572b
[platform/upstream/connectedhomeip.git] / src / lib / mdns / minimal / ResourceRecord.cpp
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 "ResourceRecord.h"
19
20 namespace mdns {
21 namespace Minimal {
22
23 bool ResourceRecord::Append(HeaderRef & hdr, ResourceType asType, chip::BufBound & out) const
24 {
25     // order is important based on resource type. First come answers, then authorityAnswers
26     // and then additional:
27     if ((asType == ResourceType::kAuthority) && (hdr.GetAdditionalCount() != 0))
28     {
29         return false;
30     }
31     if ((asType == ResourceType::kAnswer) && ((hdr.GetAdditionalCount() != 0) || (hdr.GetAuthorityCount() != 0)))
32     {
33         return false;
34     }
35
36     // Write all QName parts
37     for (uint16_t i = 0; i < mQNameCount; i++)
38     {
39
40         out.Put8(strlen(mQName[i]));
41         out.Put(mQName[i]);
42     }
43     out.Put8(0); // end of qnames
44
45     out                                             //
46         .PutBE16(static_cast<uint16_t>(GetClass())) //
47         .PutBE16(static_cast<uint16_t>(GetType()))  //
48         .PutBE32(static_cast<uint32_t>(GetTtl()))   //
49         ;
50
51     chip::BufBound sizeOutput(out);        // copy to re-output size
52     out.PutBE16(static_cast<uint32_t>(0)); // dummy, will be replaced later
53
54     if (!WriteData(out))
55     {
56         return false;
57     }
58     sizeOutput.PutBE16(static_cast<uint16_t>(out.Needed() - sizeOutput.Needed() - 2));
59
60     // This MUST be final and separated out: record count is only updated on success.
61     if (out.Fit())
62     {
63         switch (asType)
64         {
65         case ResourceType::kAdditional:
66             hdr.SetAdditionalCount(hdr.GetAdditionalCount() + 1);
67             break;
68         case ResourceType::kAuthority:
69             hdr.SetAuthorityCount(hdr.GetAuthorityCount() + 1);
70             break;
71         case ResourceType::kAnswer:
72             hdr.SetAnswerCount(hdr.GetAnswerCount() + 1);
73             break;
74         }
75     }
76
77     return out.Fit();
78 }
79
80 } // namespace Minimal
81 } // namespace mdns