Coverage Report

Created: 2025-06-20 06:55

/src/connectedhomeip/examples/providers/DeviceInfoProviderImpl.cpp
Line
Count
Source (jump to first uncovered line)
1
/*
2
 *
3
 *    Copyright (c) 2022 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
#include <DeviceInfoProviderImpl.h>
18
19
#include <lib/core/TLV.h>
20
#include <lib/support/CHIPMemString.h>
21
#include <lib/support/CodeUtils.h>
22
#include <lib/support/DefaultStorageKeyAllocator.h>
23
#include <lib/support/SafeInt.h>
24
#include <lib/support/Span.h>
25
#include <platform/internal/CHIPDeviceLayerInternal.h>
26
27
#include <stdlib.h>
28
#include <string.h>
29
30
#include <cstring>
31
32
namespace chip {
33
namespace DeviceLayer {
34
35
namespace {
36
constexpr TLV::Tag kLabelNameTag  = TLV::ContextTag(0);
37
constexpr TLV::Tag kLabelValueTag = TLV::ContextTag(1);
38
} // anonymous namespace
39
40
DeviceInfoProviderImpl & DeviceInfoProviderImpl::GetDefaultInstance()
41
0
{
42
0
    static DeviceInfoProviderImpl sInstance;
43
0
    return sInstance;
44
0
}
45
46
// !!!!!!!!!!!!!!!!!!!!!!!! WARNING WARNING WARNING !!!!!!!!!!!!!!!!!!!!
47
// WARNING: DO NOT USE THESE DEFAULT IMPLEMENTATIONS WITH DEFAULT VALUES
48
// IN PRODUCTION PRODUCTS WITHOUT AUDITING THEM! See
49
// `AllClustersExampleDeviceInforProviderImpl.cpp` for an example provider
50
// that has constant values. Here, all providers have empty implementations
51
// to force empty lists which prevent bad values from leaking into products
52
// like happened before Matter 1.5. If you really are using these clusters,
53
// then please re-implement the provider as needed.
54
//
55
// The FixedLabel, LocalizationConfigurationand and Time Format localization
56
// clusters, if used, should have values that have been vetted
57
// for correctness in the product !!! DO NOT USE SAMPLE DEFAULTS IN PRODUCTS.
58
// !!!!!!!!!!!!!!!!!!!!!!!! WARNING WARNING WARNING !!!!!!!!!!!!!!!!!!!!
59
60
DeviceInfoProvider::FixedLabelIterator * DeviceInfoProviderImpl::IterateFixedLabel(EndpointId endpoint)
61
0
{
62
    // We don't include fixed label data in this sample one. Returning nullptr returns empty list.
63
0
    (void) endpoint;
64
0
    return nullptr;
65
0
}
66
67
CHIP_ERROR DeviceInfoProviderImpl::SetUserLabelLength(EndpointId endpoint, size_t val)
68
0
{
69
0
    return mStorage->SyncSetKeyValue(DefaultStorageKeyAllocator::UserLabelLengthKey(endpoint).KeyName(), &val,
70
0
                                     static_cast<uint16_t>(sizeof(val)));
71
0
}
72
73
CHIP_ERROR DeviceInfoProviderImpl::GetUserLabelLength(EndpointId endpoint, size_t & val)
74
0
{
75
0
    uint16_t len = static_cast<uint16_t>(sizeof(val));
76
77
0
    return mStorage->SyncGetKeyValue(DefaultStorageKeyAllocator::UserLabelLengthKey(endpoint).KeyName(), &val, len);
78
0
}
79
80
CHIP_ERROR DeviceInfoProviderImpl::SetUserLabelAt(EndpointId endpoint, size_t index, const UserLabelType & userLabel)
81
0
{
82
0
    VerifyOrReturnError(CanCastTo<uint32_t>(index), CHIP_ERROR_INVALID_ARGUMENT);
83
84
0
    uint8_t buf[UserLabelTLVMaxSize()];
85
0
    TLV::TLVWriter writer;
86
0
    writer.Init(buf);
87
88
0
    TLV::TLVType outerType;
89
0
    ReturnErrorOnFailure(writer.StartContainer(TLV::AnonymousTag(), TLV::kTLVType_Structure, outerType));
90
0
    ReturnErrorOnFailure(writer.PutString(kLabelNameTag, userLabel.label));
91
0
    ReturnErrorOnFailure(writer.PutString(kLabelValueTag, userLabel.value));
92
0
    ReturnErrorOnFailure(writer.EndContainer(outerType));
93
94
0
    return mStorage->SyncSetKeyValue(
95
0
        DefaultStorageKeyAllocator::UserLabelIndexKey(endpoint, static_cast<uint32_t>(index)).KeyName(), buf,
96
0
        static_cast<uint16_t>(writer.GetLengthWritten()));
97
0
}
98
99
CHIP_ERROR DeviceInfoProviderImpl::DeleteUserLabelAt(EndpointId endpoint, size_t index)
100
0
{
101
0
    return mStorage->SyncDeleteKeyValue(
102
0
        DefaultStorageKeyAllocator::UserLabelIndexKey(endpoint, static_cast<uint32_t>(index)).KeyName());
103
0
}
104
105
DeviceInfoProvider::UserLabelIterator * DeviceInfoProviderImpl::IterateUserLabel(EndpointId endpoint)
106
0
{
107
0
    return chip::Platform::New<UserLabelIteratorImpl>(*this, endpoint);
108
0
}
109
110
DeviceInfoProviderImpl::UserLabelIteratorImpl::UserLabelIteratorImpl(DeviceInfoProviderImpl & provider, EndpointId endpoint) :
111
0
    mProvider(provider), mEndpoint(endpoint)
112
0
{
113
0
    size_t total = 0;
114
115
0
    ReturnOnFailure(mProvider.GetUserLabelLength(mEndpoint, total));
116
0
    mTotal = total;
117
0
    mIndex = 0;
118
0
}
119
120
bool DeviceInfoProviderImpl::UserLabelIteratorImpl::Next(UserLabelType & output)
121
0
{
122
0
    CHIP_ERROR err = CHIP_NO_ERROR;
123
124
0
    VerifyOrReturnError(mIndex < mTotal, false);
125
0
    VerifyOrReturnError(CanCastTo<uint32_t>(mIndex), false);
126
127
0
    uint8_t buf[UserLabelTLVMaxSize()];
128
0
    uint16_t len = static_cast<uint16_t>(sizeof(buf));
129
130
0
    err = mProvider.mStorage->SyncGetKeyValue(
131
0
        DefaultStorageKeyAllocator::UserLabelIndexKey(mEndpoint, static_cast<uint32_t>(mIndex)).KeyName(), buf, len);
132
0
    VerifyOrReturnError(err == CHIP_NO_ERROR, false);
133
134
0
    TLV::ContiguousBufferTLVReader reader;
135
0
    reader.Init(buf);
136
0
    err = reader.Next(TLV::kTLVType_Structure, TLV::AnonymousTag());
137
0
    VerifyOrReturnError(err == CHIP_NO_ERROR, false);
138
139
0
    TLV::TLVType containerType;
140
0
    VerifyOrReturnError(reader.EnterContainer(containerType) == CHIP_NO_ERROR, false);
141
142
0
    chip::CharSpan label;
143
0
    chip::CharSpan value;
144
145
0
    VerifyOrReturnError(reader.Next(kLabelNameTag) == CHIP_NO_ERROR, false);
146
0
    VerifyOrReturnError(reader.Get(label) == CHIP_NO_ERROR, false);
147
148
0
    VerifyOrReturnError(reader.Next(kLabelValueTag) == CHIP_NO_ERROR, false);
149
0
    VerifyOrReturnError(reader.Get(value) == CHIP_NO_ERROR, false);
150
151
0
    VerifyOrReturnError(reader.VerifyEndOfContainer() == CHIP_NO_ERROR, false);
152
0
    VerifyOrReturnError(reader.ExitContainer(containerType) == CHIP_NO_ERROR, false);
153
154
0
    Platform::CopyString(mUserLabelNameBuf, label);
155
0
    Platform::CopyString(mUserLabelValueBuf, value);
156
157
0
    output.label = CharSpan::fromCharString(mUserLabelNameBuf);
158
0
    output.value = CharSpan::fromCharString(mUserLabelValueBuf);
159
160
0
    mIndex++;
161
162
0
    return true;
163
0
}
164
165
DeviceInfoProvider::SupportedLocalesIterator * DeviceInfoProviderImpl::IterateSupportedLocales()
166
0
{
167
0
    return chip::Platform::New<SupportedLocalesIteratorImpl>();
168
0
}
169
170
size_t DeviceInfoProviderImpl::SupportedLocalesIteratorImpl::Count()
171
0
{
172
    // Hardcoded list of locales
173
    // {("en-US")}
174
175
0
    return kNumSupportedLocales;
176
0
}
177
178
bool DeviceInfoProviderImpl::SupportedLocalesIteratorImpl::Next(CharSpan & output)
179
0
{
180
    // Hardcoded list of locales
181
0
    static const char * kAllSupportedLocales[kNumSupportedLocales] = { "en-US" };
182
183
0
    VerifyOrReturnError(mIndex < kNumSupportedLocales, false);
184
0
    output = CharSpan::fromCharString(kAllSupportedLocales[mIndex]);
185
0
    mIndex++;
186
187
0
    return true;
188
0
}
189
190
DeviceInfoProvider::SupportedCalendarTypesIterator * DeviceInfoProviderImpl::IterateSupportedCalendarTypes()
191
0
{
192
0
    return chip::Platform::New<SupportedCalendarTypesIteratorImpl>();
193
0
}
194
195
size_t DeviceInfoProviderImpl::SupportedCalendarTypesIteratorImpl::Count()
196
0
{
197
    // Hardcoded list of strings
198
    // {("kGregorian")}
199
200
0
    return kNumSupportedCalendarTypes;
201
0
}
202
203
bool DeviceInfoProviderImpl::SupportedCalendarTypesIteratorImpl::Next(CalendarType & output)
204
0
{
205
0
    static const CalendarType kAllSupportedCalendarTypes[kNumSupportedCalendarTypes] = {
206
0
        app::Clusters::TimeFormatLocalization::CalendarTypeEnum::kGregorian
207
0
    };
208
209
0
    VerifyOrReturnError(mIndex < kNumSupportedCalendarTypes, false);
210
0
    output = kAllSupportedCalendarTypes[mIndex];
211
0
    mIndex++;
212
0
    return true;
213
0
}
214
215
} // namespace DeviceLayer
216
} // namespace chip