Coverage Report

Created: 2026-07-10 06:38

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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