Skip to content

Commit 6538809

Browse files
committed
Allow null BuiltIn field when saving Presets
1 parent 0c395c1 commit 6538809

File tree

5 files changed

+44
-22
lines changed

5 files changed

+44
-22
lines changed

examples/thermostat/thermostat-common/include/thermostat-delegate-impl.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ class ThermostatDelegate : public Delegate
5858

5959
void InitializePendingPresets() override;
6060

61-
CHIP_ERROR AppendToPendingPresetList(const Structs::PresetStruct::Type & preset) override;
61+
CHIP_ERROR AppendToPendingPresetList(const PresetStructWithOwnedMembers & preset) override;
6262

6363
CHIP_ERROR GetPendingPresetAtIndex(size_t index, PresetStructWithOwnedMembers & preset) override;
6464

examples/thermostat/thermostat-common/src/thermostat-delegate-impl.cpp

+3-3
Original file line numberDiff line numberDiff line change
@@ -177,17 +177,17 @@ void ThermostatDelegate::InitializePendingPresets()
177177
}
178178
}
179179

180-
CHIP_ERROR ThermostatDelegate::AppendToPendingPresetList(const PresetStruct::Type & preset)
180+
CHIP_ERROR ThermostatDelegate::AppendToPendingPresetList(const PresetStructWithOwnedMembers & preset)
181181
{
182182
if (mNextFreeIndexInPendingPresetsList < ArraySize(mPendingPresets))
183183
{
184184
mPendingPresets[mNextFreeIndexInPendingPresetsList] = preset;
185-
if (preset.presetHandle.IsNull())
185+
if (preset.GetPresetHandle().IsNull())
186186
{
187187
// TODO: #34556 Since we support only one preset of each type, using the octet string containing the preset scenario
188188
// suffices as the unique preset handle. Need to fix this to actually provide unique handles once multiple presets of
189189
// each type are supported.
190-
const uint8_t handle[] = { static_cast<uint8_t>(preset.presetScenario) };
190+
const uint8_t handle[] = { static_cast<uint8_t>(preset.GetPresetScenario()) };
191191
mPendingPresets[mNextFreeIndexInPendingPresetsList].SetPresetHandle(DataModel::MakeNullable(ByteSpan(handle)));
192192
}
193193
mNextFreeIndexInPendingPresetsList++;

src/app/clusters/thermostat-server/thermostat-delegate.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ class Delegate
103103
* @return CHIP_NO_ERROR if the preset was appended to the list successfully.
104104
* @return CHIP_ERROR if there was an error adding the preset to the list.
105105
*/
106-
virtual CHIP_ERROR AppendToPendingPresetList(const Structs::PresetStruct::Type & preset) = 0;
106+
virtual CHIP_ERROR AppendToPendingPresetList(const PresetStructWithOwnedMembers & preset) = 0;
107107

108108
/**
109109
* @brief Get the Preset at a given index in the pending presets list.

src/app/clusters/thermostat-server/thermostat-server-presets.cpp

+36-16
Original file line numberDiff line numberDiff line change
@@ -38,16 +38,16 @@ namespace {
3838
* @return true If the preset is valid i.e the PresetHandle (if not null) fits within size constraints and the presetScenario enum
3939
* value is valid. Otherwise, return false.
4040
*/
41-
bool IsValidPresetEntry(const PresetStruct::Type & preset)
41+
bool IsValidPresetEntry(const PresetStructWithOwnedMembers & preset)
4242
{
4343
// Check that the preset handle is not too long.
44-
if (!preset.presetHandle.IsNull() && preset.presetHandle.Value().size() > kPresetHandleSize)
44+
if (!preset.GetPresetHandle().IsNull() && preset.GetPresetHandle().Value().size() > kPresetHandleSize)
4545
{
4646
return false;
4747
}
4848

4949
// Ensure we have a valid PresetScenario.
50-
return (preset.presetScenario != PresetScenarioEnum::kUnknownEnumValue);
50+
return (preset.GetPresetScenario() != PresetScenarioEnum::kUnknownEnumValue);
5151
}
5252

5353
/**
@@ -123,7 +123,7 @@ bool MatchingPendingPresetExists(Delegate * delegate, const PresetStructWithOwne
123123
*
124124
* @return true if a matching entry was found in the presets attribute list, false otherwise.
125125
*/
126-
bool GetMatchingPresetInPresets(Delegate * delegate, const PresetStruct::Type & presetToMatch,
126+
bool GetMatchingPresetInPresets(Delegate * delegate, const DataModel::Nullable<ByteSpan> & presetHandle,
127127
PresetStructWithOwnedMembers & matchingPreset)
128128
{
129129
VerifyOrReturnValue(delegate != nullptr, false);
@@ -143,7 +143,7 @@ bool GetMatchingPresetInPresets(Delegate * delegate, const PresetStruct::Type &
143143
}
144144

145145
// Note: presets coming from our delegate always have a handle.
146-
if (presetToMatch.presetHandle.Value().data_equal(matchingPreset.GetPresetHandle().Value()))
146+
if (presetHandle.Value().data_equal(matchingPreset.GetPresetHandle().Value()))
147147
{
148148
return true;
149149
}
@@ -351,14 +351,15 @@ Status ThermostatAttrAccess::SetActivePreset(EndpointId endpoint, DataModel::Nul
351351
return Status::Success;
352352
}
353353

354-
CHIP_ERROR ThermostatAttrAccess::AppendPendingPreset(Thermostat::Delegate * delegate, const PresetStruct::Type & preset)
354+
CHIP_ERROR ThermostatAttrAccess::AppendPendingPreset(Thermostat::Delegate * delegate, const PresetStruct::Type & newPreset)
355355
{
356+
PresetStructWithOwnedMembers preset = newPreset;
356357
if (!IsValidPresetEntry(preset))
357358
{
358359
return CHIP_IM_GLOBAL_STATUS(ConstraintError);
359360
}
360361

361-
if (preset.presetHandle.IsNull())
362+
if (preset.GetPresetHandle().IsNull())
362363
{
363364
if (IsBuiltIn(preset))
364365
{
@@ -367,37 +368,56 @@ CHIP_ERROR ThermostatAttrAccess::AppendPendingPreset(Thermostat::Delegate * dele
367368
}
368369
else
369370
{
370-
auto & presetHandle = preset.presetHandle.Value();
371371

372372
// Per spec we need to check that:
373373
// (a) There is an existing non-pending preset with this handle.
374374
PresetStructWithOwnedMembers matchingPreset;
375-
if (!GetMatchingPresetInPresets(delegate, preset, matchingPreset))
375+
if (!GetMatchingPresetInPresets(delegate, preset.GetPresetHandle().Value(), matchingPreset))
376376
{
377377
return CHIP_IM_GLOBAL_STATUS(NotFound);
378378
}
379379

380380
// (b) There is no existing pending preset with this handle.
381-
if (CountPresetsInPendingListWithPresetHandle(delegate, presetHandle) > 0)
381+
if (CountPresetsInPendingListWithPresetHandle(delegate, preset.GetPresetHandle().Value()) > 0)
382382
{
383383
return CHIP_IM_GLOBAL_STATUS(ConstraintError);
384384
}
385385

386+
const auto & presetBuiltIn = preset.GetBuiltIn();
387+
const auto & matchingPresetBuiltIn = matchingPreset.GetBuiltIn();
386388
// (c)/(d) The built-in fields do not have a mismatch.
387-
// TODO: What's the story with nullability on the BuiltIn field?
388-
if (!preset.builtIn.IsNull() && !matchingPreset.GetBuiltIn().IsNull() &&
389-
preset.builtIn.Value() != matchingPreset.GetBuiltIn().Value())
389+
if (presetBuiltIn.IsNull())
390390
{
391-
return CHIP_IM_GLOBAL_STATUS(ConstraintError);
391+
if (matchingPresetBuiltIn.IsNull())
392+
{
393+
// This really shouldn't happen; internal presets should alway have built-in set
394+
return CHIP_IM_GLOBAL_STATUS(InvalidInState);
395+
}
396+
else
397+
{
398+
preset.SetBuiltIn(matchingPresetBuiltIn.Value());
399+
}
400+
}
401+
else
402+
{
403+
if (matchingPresetBuiltIn.IsNull())
404+
{
405+
// This really shouldn't happen; internal presets should alway have built-in set
406+
return CHIP_IM_GLOBAL_STATUS(InvalidInState);
407+
}
408+
if (presetBuiltIn.Value() != matchingPresetBuiltIn.Value())
409+
{
410+
return CHIP_IM_GLOBAL_STATUS(ConstraintError);
411+
}
392412
}
393413
}
394414

395-
if (!PresetScenarioExistsInPresetTypes(delegate, preset.presetScenario))
415+
if (!PresetScenarioExistsInPresetTypes(delegate, preset.GetPresetScenario()))
396416
{
397417
return CHIP_IM_GLOBAL_STATUS(ConstraintError);
398418
}
399419

400-
if (preset.name.HasValue() && !PresetTypeSupportsNames(delegate, preset.presetScenario))
420+
if (preset.GetName().HasValue() && !PresetTypeSupportsNames(delegate, preset.GetPresetScenario()))
401421
{
402422
return CHIP_IM_GLOBAL_STATUS(ConstraintError);
403423
}

src/python_testing/TC_TSTAT_4_2.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -269,7 +269,9 @@ async def test_TC_TSTAT_4_2(self):
269269
await self.send_atomic_request_begin_command()
270270

271271
# Write to the presets attribute after calling AtomicRequest command
272-
await self.write_presets(endpoint=endpoint, presets=new_presets)
272+
test_presets = copy.deepcopy(new_presets)
273+
test_presets[0].builtIn = NullValue
274+
await self.write_presets(endpoint=endpoint, presets=test_presets)
273275

274276
# Send the AtomicRequest commit command
275277
await self.send_atomic_request_commit_command()

0 commit comments

Comments
 (0)