/src/connectedhomeip/src/lib/dnssd/Advertiser_ImplMinimalMdnsAllocator.h
Line | Count | Source |
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 <inttypes.h> |
21 | | |
22 | | #include <lib/core/CHIPError.h> |
23 | | #include <lib/dnssd/minimal_mdns/core/FlatAllocatedQName.h> |
24 | | #include <lib/dnssd/minimal_mdns/core/QName.h> |
25 | | #include <lib/dnssd/minimal_mdns/responders/IP.h> |
26 | | #include <lib/dnssd/minimal_mdns/responders/Ptr.h> |
27 | | #include <lib/dnssd/minimal_mdns/responders/QueryResponder.h> |
28 | | #include <lib/dnssd/minimal_mdns/responders/RecordResponder.h> |
29 | | #include <lib/dnssd/minimal_mdns/responders/Srv.h> |
30 | | #include <lib/dnssd/minimal_mdns/responders/Txt.h> |
31 | | #include <lib/support/CHIPMem.h> |
32 | | #include <lib/support/logging/CHIPLogging.h> |
33 | | |
34 | | namespace chip { |
35 | | namespace Dnssd { |
36 | | |
37 | | template <size_t kMaxRecords> |
38 | | class QueryResponderAllocator |
39 | | { |
40 | | public: |
41 | | QueryResponderAllocator() |
42 | 0 | { |
43 | 0 | for (auto & responder : mAllocatedResponders) |
44 | 0 | { |
45 | 0 | responder = nullptr; |
46 | 0 | } |
47 | 0 | for (auto & name : mAllocatedQNameParts) |
48 | 0 | { |
49 | 0 | name = nullptr; |
50 | 0 | } |
51 | 0 | } Unexecuted instantiation: chip::Dnssd::QueryResponderAllocator<11ul>::QueryResponderAllocator() Unexecuted instantiation: chip::Dnssd::QueryResponderAllocator<6ul>::QueryResponderAllocator() |
52 | 0 | ~QueryResponderAllocator() { Clear(); }Unexecuted instantiation: chip::Dnssd::QueryResponderAllocator<6ul>::~QueryResponderAllocator() Unexecuted instantiation: chip::Dnssd::QueryResponderAllocator<11ul>::~QueryResponderAllocator() |
53 | | |
54 | | /// Appends another responder to the internal replies. |
55 | | template <typename ResponderType, typename... Args> |
56 | | mdns::Minimal::QueryResponderSettings AddResponder(Args &&... args) |
57 | 0 | { |
58 | 0 | return AddAllocatedResponder(chip::Platform::New<ResponderType>(std::forward<Args>(args)...)); |
59 | 0 | } Unexecuted instantiation: mdns::Minimal::QueryResponderSettings chip::Dnssd::QueryResponderAllocator<6ul>::AddResponder<mdns::Minimal::PtrResponder, mdns::Minimal::FullQName&, mdns::Minimal::FullQName&>(mdns::Minimal::FullQName&, mdns::Minimal::FullQName&) Unexecuted instantiation: mdns::Minimal::QueryResponderSettings chip::Dnssd::QueryResponderAllocator<6ul>::AddResponder<mdns::Minimal::SrvResponder, mdns::Minimal::SrvResourceRecord&>(mdns::Minimal::SrvResourceRecord&) Unexecuted instantiation: mdns::Minimal::QueryResponderSettings chip::Dnssd::QueryResponderAllocator<6ul>::AddResponder<mdns::Minimal::TxtResponder, mdns::Minimal::TxtResourceRecord&>(mdns::Minimal::TxtResourceRecord&) Unexecuted instantiation: mdns::Minimal::QueryResponderSettings chip::Dnssd::QueryResponderAllocator<6ul>::AddResponder<mdns::Minimal::IPv6Responder, mdns::Minimal::FullQName&>(mdns::Minimal::FullQName&) Unexecuted instantiation: mdns::Minimal::QueryResponderSettings chip::Dnssd::QueryResponderAllocator<6ul>::AddResponder<mdns::Minimal::IPv4Responder, mdns::Minimal::FullQName&>(mdns::Minimal::FullQName&) Unexecuted instantiation: mdns::Minimal::QueryResponderSettings chip::Dnssd::QueryResponderAllocator<11ul>::AddResponder<mdns::Minimal::PtrResponder, mdns::Minimal::FullQName&, mdns::Minimal::FullQName&>(mdns::Minimal::FullQName&, mdns::Minimal::FullQName&) Unexecuted instantiation: mdns::Minimal::QueryResponderSettings chip::Dnssd::QueryResponderAllocator<11ul>::AddResponder<mdns::Minimal::SrvResponder, mdns::Minimal::SrvResourceRecord&>(mdns::Minimal::SrvResourceRecord&) Unexecuted instantiation: mdns::Minimal::QueryResponderSettings chip::Dnssd::QueryResponderAllocator<11ul>::AddResponder<mdns::Minimal::IPv6Responder, mdns::Minimal::FullQName&>(mdns::Minimal::FullQName&) Unexecuted instantiation: mdns::Minimal::QueryResponderSettings chip::Dnssd::QueryResponderAllocator<11ul>::AddResponder<mdns::Minimal::IPv4Responder, mdns::Minimal::FullQName&>(mdns::Minimal::FullQName&) Unexecuted instantiation: mdns::Minimal::QueryResponderSettings chip::Dnssd::QueryResponderAllocator<11ul>::AddResponder<mdns::Minimal::TxtResponder, mdns::Minimal::TxtResourceRecord&>(mdns::Minimal::TxtResourceRecord&) |
60 | | |
61 | | template <typename... Args> |
62 | | mdns::Minimal::FullQName AllocateQName(Args &&... names) |
63 | 0 | { |
64 | 0 | void * storage = AllocateQNameSpace(mdns::Minimal::FlatAllocatedQName::RequiredStorageSize(std::forward<Args>(names)...)); |
65 | 0 | if (storage == nullptr) |
66 | 0 | { |
67 | 0 | return mdns::Minimal::FullQName(); |
68 | 0 | } |
69 | 0 | return mdns::Minimal::FlatAllocatedQName::Build(storage, std::forward<Args>(names)...); |
70 | 0 | } Unexecuted instantiation: mdns::Minimal::FullQName chip::Dnssd::QueryResponderAllocator<6ul>::AllocateQName<char const (&) [8], char const (&) [5], char const (&) [6]>(char const (&) [8], char const (&) [5], char const (&) [6]) Unexecuted instantiation: mdns::Minimal::FullQName chip::Dnssd::QueryResponderAllocator<6ul>::AllocateQName<char (&) [34], char const (&) [8], char const (&) [5], char const (&) [6]>(char (&) [34], char const (&) [8], char const (&) [5], char const (&) [6]) Unexecuted instantiation: mdns::Minimal::FullQName chip::Dnssd::QueryResponderAllocator<6ul>::AllocateQName<char (&) [34], char const (&) [6]>(char (&) [34], char const (&) [6]) Unexecuted instantiation: mdns::Minimal::FullQName chip::Dnssd::QueryResponderAllocator<6ul>::AllocateQName<char (&) [34], char const (&) [5], char const (&) [8], char const (&) [5], char const (&) [6]>(char (&) [34], char const (&) [5], char const (&) [8], char const (&) [5], char const (&) [6]) Unexecuted instantiation: mdns::Minimal::FullQName chip::Dnssd::QueryResponderAllocator<11ul>::AllocateQName<char const*&, char const (&) [5], char const (&) [6]>(char const*&, char const (&) [5], char const (&) [6]) Unexecuted instantiation: mdns::Minimal::FullQName chip::Dnssd::QueryResponderAllocator<11ul>::AllocateQName<char (&) [64], char const*&, char const (&) [5], char const (&) [6]>(char (&) [64], char const*&, char const (&) [5], char const (&) [6]) Unexecuted instantiation: mdns::Minimal::FullQName chip::Dnssd::QueryResponderAllocator<11ul>::AllocateQName<char (&) [64], char const (&) [6]>(char (&) [64], char const (&) [6]) Unexecuted instantiation: mdns::Minimal::FullQName chip::Dnssd::QueryResponderAllocator<11ul>::AllocateQName<char (&) [64], char const (&) [5], char const*&, char const (&) [5], char const (&) [6]>(char (&) [64], char const (&) [5], char const*&, char const (&) [5], char const (&) [6]) |
71 | | |
72 | | mdns::Minimal::FullQName AllocateQNameFromArray(char const * const * names, size_t num) |
73 | 0 | { |
74 | 0 | void * storage = AllocateQNameSpace(mdns::Minimal::FlatAllocatedQName::RequiredStorageSizeFromArray(names, num)); |
75 | 0 | if (storage == nullptr) |
76 | 0 | { |
77 | 0 | return mdns::Minimal::FullQName(); |
78 | 0 | } |
79 | 0 | return mdns::Minimal::FlatAllocatedQName::BuildFromArray(storage, names, num); |
80 | 0 | } Unexecuted instantiation: chip::Dnssd::QueryResponderAllocator<6ul>::AllocateQNameFromArray(char const* const*, unsigned long) Unexecuted instantiation: chip::Dnssd::QueryResponderAllocator<11ul>::AllocateQNameFromArray(char const* const*, unsigned long) |
81 | | |
82 | | /// Sets the query responder to a blank state and frees up any |
83 | | /// allocated memory. |
84 | | void Clear() |
85 | 0 | { |
86 | | // Init clears all responders, so that data can be freed |
87 | 0 | mQueryResponder.Init(); |
88 | | |
89 | | // Free all allocated data |
90 | 0 | for (auto & responder : mAllocatedResponders) |
91 | 0 | { |
92 | 0 | if (responder != nullptr) |
93 | 0 | { |
94 | 0 | chip::Platform::Delete(responder); |
95 | 0 | responder = nullptr; |
96 | 0 | } |
97 | 0 | } |
98 | |
|
99 | 0 | for (auto & name : mAllocatedQNameParts) |
100 | 0 | { |
101 | 0 | if (name != nullptr) |
102 | 0 | { |
103 | 0 | chip::Platform::MemoryFree(name); |
104 | 0 | name = nullptr; |
105 | 0 | } |
106 | 0 | } |
107 | 0 | } Unexecuted instantiation: chip::Dnssd::QueryResponderAllocator<6ul>::Clear() Unexecuted instantiation: chip::Dnssd::QueryResponderAllocator<11ul>::Clear() |
108 | 0 | mdns::Minimal::QueryResponder<kMaxRecords + 1> * GetQueryResponder() { return &mQueryResponder; }Unexecuted instantiation: chip::Dnssd::QueryResponderAllocator<11ul>::GetQueryResponder() Unexecuted instantiation: chip::Dnssd::QueryResponderAllocator<6ul>::GetQueryResponder() |
109 | | const mdns::Minimal::RecordResponder * GetResponder(const mdns::Minimal::QType & qtype, |
110 | | const mdns::Minimal::FullQName & qname) const |
111 | 0 | { |
112 | 0 | for (auto & responder : mAllocatedResponders) |
113 | 0 | { |
114 | 0 | if (responder != nullptr && responder->GetQType() == qtype && responder->GetQName() == qname) |
115 | 0 | { |
116 | 0 | return responder; |
117 | 0 | } |
118 | 0 | } |
119 | 0 | return nullptr; |
120 | 0 | } |
121 | | bool IsEmpty() const |
122 | | { |
123 | | for (auto & responder : mAllocatedResponders) |
124 | | { |
125 | | if (responder != nullptr) |
126 | | { |
127 | | return false; |
128 | | } |
129 | | } |
130 | | for (auto & name : mAllocatedQNameParts) |
131 | | { |
132 | | if (name != nullptr) |
133 | | { |
134 | | return false; |
135 | | } |
136 | | } |
137 | | return true; |
138 | | } |
139 | | |
140 | | protected: |
141 | | // For testing. |
142 | | size_t GetMaxAllocatedQNames() { return kMaxAllocatedQNameData; } |
143 | | void * GetQNamePart(size_t idx) { return mAllocatedQNameParts[idx]; } |
144 | | mdns::Minimal::RecordResponder * GetRecordResponder(size_t idx) { return mAllocatedResponders[idx]; } |
145 | | |
146 | | private: |
147 | | static constexpr size_t kMaxAllocatedQNameData = 32; |
148 | | // dynamically allocated items |
149 | | mdns::Minimal::RecordResponder * mAllocatedResponders[kMaxRecords]; |
150 | | void * mAllocatedQNameParts[kMaxAllocatedQNameData]; |
151 | | // The QueryResponder needs 1 extra space to hold the record for itself. |
152 | | mdns::Minimal::QueryResponder<kMaxRecords + 1> mQueryResponder; |
153 | | |
154 | | mdns::Minimal::QueryResponderSettings AddAllocatedResponder(mdns::Minimal::RecordResponder * newResponder) |
155 | 0 | { |
156 | 0 | if (newResponder == nullptr) |
157 | 0 | { |
158 | 0 | ChipLogError(Discovery, "Responder memory allocation failed"); |
159 | 0 | return mdns::Minimal::QueryResponderSettings(); // failed |
160 | 0 | } |
161 | | |
162 | 0 | for (auto & responder : mAllocatedResponders) |
163 | 0 | { |
164 | 0 | if (responder != nullptr) |
165 | 0 | { |
166 | 0 | continue; |
167 | 0 | } |
168 | | |
169 | 0 | responder = newResponder; |
170 | 0 | return mQueryResponder.AddResponder(responder); |
171 | 0 | } |
172 | | |
173 | 0 | Platform::Delete(newResponder); |
174 | 0 | ChipLogError(Discovery, "Failed to find free slot for adding a responder"); |
175 | 0 | return mdns::Minimal::QueryResponderSettings(); |
176 | 0 | } Unexecuted instantiation: chip::Dnssd::QueryResponderAllocator<6ul>::AddAllocatedResponder(mdns::Minimal::RecordResponder*) Unexecuted instantiation: chip::Dnssd::QueryResponderAllocator<11ul>::AddAllocatedResponder(mdns::Minimal::RecordResponder*) |
177 | | |
178 | | void * AllocateQNameSpace(size_t size) |
179 | 0 | { |
180 | 0 | for (auto & name : mAllocatedQNameParts) |
181 | 0 | { |
182 | 0 | if (name != nullptr) |
183 | 0 | { |
184 | 0 | continue; |
185 | 0 | } |
186 | | |
187 | 0 | name = chip::Platform::MemoryAlloc(size); |
188 | 0 | if (name == nullptr) |
189 | 0 | { |
190 | 0 | ChipLogError(Discovery, "QName memory allocation failed"); |
191 | 0 | } |
192 | 0 | return name; |
193 | 0 | } |
194 | 0 | ChipLogError(Discovery, "Failed to find free slot for adding a qname"); |
195 | 0 | return nullptr; |
196 | 0 | } Unexecuted instantiation: chip::Dnssd::QueryResponderAllocator<6ul>::AllocateQNameSpace(unsigned long) Unexecuted instantiation: chip::Dnssd::QueryResponderAllocator<11ul>::AllocateQNameSpace(unsigned long) |
197 | | }; |
198 | | |
199 | | } // namespace Dnssd |
200 | | } // namespace chip |