Skip to content

Commit a696416

Browse files
hastynivi-applerestyled-commitsbzbarsky-appletehampson
authored andcommitted
[HVAC] Handle null BuiltIn field on Preset write according to spec (project-chip#35161)
* Add support for Presets attributes and commands to the Thermostat cluster Clean up the Thermostat cluster and remove the TemperatureSetpointHoldPolicy attribute and SetTemperatureSetpointHoldPolicy command * Restyled by whitespace * Restyled by clang-format * Restyled by gn. * Fix build error for Linux configure build of all-clusters-app * Fix Darwin CI issues Editorial fixes * Restyled by clang-format * More fixes * Restyled by clang-format * BUILD.gn fixes for CI * Apply suggestions from code review Co-authored-by: Boris Zbarsky <bzbarsky@apple.com> * Address review comments. * Restyled by clang-format * Regenerate Thermostat XML from spec * Move atomic enum to global-enums.xml, actually # Conflicts: # src/app/zap-templates/zcl/data-model/chip/global-structs.xml * Regenerate XML and convert thermostat-server to atomic writes * Pull in ACCapacityFormat typo un-fix * Update Test_TC_TSTAT_1_1 to know about AtomicResponse command. * Restyled patch * Fix weird merge with upstream * Fix emberAfIsTypeSigned not understanding temperature type * Merge fixes from atomic write branch * Relocate thermostat-manager sample code to all-clusters-common * Fix g++ build error on linux * Fix C formatter for long int, cast whole expression * Sync cast fix with master * Add thermostat-common dependency to thermostat app under linux * Remove MatterPostAttributeChangeCallback from thermostat-manager, as it conflicts with other implementations * Convert Atomic enums and structs to global * Restyled patch * Apply suggestions from code review Co-authored-by: Boris Zbarsky <bzbarsky@apple.com> * Regen with alchemy 0.6.1 * Updates based on comments * Add TC_MCORE_FS_1_3.py test implementation (project-chip#34650) * Fix most TC-SWTCH-2.4 remaining issues (project-chip#34677) - Move 2.4 in a better place in the file - Add test steps properly - Allow default button press position override Issue project-chip#34656 Testing done: - Test still passes on DUT with automation * Initial test script for Fabric Sync TC_MCORE_FS_1_2 (project-chip#34675) * Initial test script for Fabric Sync TC_MCORE_FS_1_2 * Apply suggestions from code review Co-authored-by: C Freeman <cecille@google.com> * Address Review Comments * Address review comments * Fix default timeout after other timeouts changed * Restyled by autopep8 * Fix linter error --------- Co-authored-by: C Freeman <cecille@google.com> Co-authored-by: Restyled.io <commits@restyled.io> * Test automation for FabricSync ICD BridgedDeviceBasicInfoCluster (project-chip#34628) * WIP Bridged ICD, commissioning to both fabrics * wip testing sending KeepActive * wip most steps implemented * using SIGSTOP and SIGCONT to control ICD server pausing * Update src/python_testing/TC_BRBINFO_4_1.py Co-authored-by: Terence Hampson <thampson@google.com> * comments addressed * more comments addressed * lint pass * Update src/python_testing/TC_BRBINFO_4_1.py Co-authored-by: C Freeman <cecille@google.com> * comments addressed, incl TH_SERVER configurable * added setupQRCode and setupManualCode as options for DUT commissioning * Restyled by autopep8 * Restyled by isort * Update src/python_testing/TC_BRBINFO_4_1.py Co-authored-by: Terence Hampson <thampson@google.com> * Update src/python_testing/TC_BRBINFO_4_1.py Co-authored-by: Terence Hampson <thampson@google.com> * Update src/python_testing/TC_BRBINFO_4_1.py Co-authored-by: Terence Hampson <thampson@google.com> * comments addressed * Restyled by autopep8 --------- Co-authored-by: Terence Hampson <thampson@google.com> Co-authored-by: C Freeman <cecille@google.com> Co-authored-by: Restyled.io <commits@restyled.io> * ServiceArea test scripts (project-chip#34548) * initial commit * fix bugs * fix issues reported by the linter * fix bug in checking for unique areaDesc * add TC 1.5 * Update src/python_testing/TC_SEAR_1_2.py Co-authored-by: William <hicklin@users.noreply.github.com> * Update src/python_testing/TC_SEAR_1_2.py Co-authored-by: William <hicklin@users.noreply.github.com> * address code review comments * fix issue introduced by the previous commit * address code review feedback * Update src/python_testing/TC_SEAR_1_2.py Co-authored-by: Kiel Oleson <kielo@apple.com> * address code review feedback * remove PICS checked by the TC_SEAR_1.6 * more code review updates * Restyled by autopep8 --------- Co-authored-by: William <hicklin@users.noreply.github.com> Co-authored-by: Kiel Oleson <kielo@apple.com> Co-authored-by: Restyled.io <commits@restyled.io> * Remove manual tests for Thermostat presets (project-chip#34679) * Dump details about leaked ExchangeContexts before aborting (project-chip#34617) * Dump details about leaked ExchangeContexts before aborting This is implemented via a VerifyOrDieWithObject() variant of the existing VerifyOrDie() macro that calls a DumpToLog() method on the provided object if it exists (otherwise this is simply a no-op). If CHIP_CONFIG_VERBOSE_VERIFY_OR_DIE is not enabled, VerifyOrDieWithObject() simply behaves like a plain VerifyOrDie(). DumpToLog() implementations can use ChipLogFormatRtti to log type information about an object (usually a delegate); if RTTI is disabled this simply outputs whether the object was null or not. * Address review comments * Make gcc happy and improve documentation * Remove unused include * Fix compile error without CHIP_CONFIG_VERBOSE_VERIFY_OR_DIE * Avoid unused parameter warning * [TI] CC13x4_26x4 build fixes (project-chip#34682) * lwip pbuf, map file, and hex creation when OTA is disabled * added cc13x4 family define around the non OTA hex creation * whitespace fix * reversed custom factoy data flash with cc13x4 check * more whitespace fixes * [ICD] Add missing polling function to NoWifi connectivity manager (project-chip#34684) * Add missing polling function to NoWifi connectivity manager * Update GenericConnectivityManagerImpl_NoWiFi.h Co-authored-by: Boris Zbarsky <bzbarsky@apple.com> --------- Co-authored-by: Boris Zbarsky <bzbarsky@apple.com> * [OPSTATE] Add Q test script for CountdownTime (project-chip#34632) * Add Q test * Added test to test set * Remove unused var * Restyled by autopep8 * Restyled by isort * Fix name * Use pics over other method * Removed unused stuff * Added pipe commands * Fix reset * Get example to report appropriate changes. * WiP * Added some comments * Changes to make things work * Removed dev msgs * Missed some * Removed dev msgs * Straggler * Restyled by clang-format * Restyled by autopep8 * Restyled by isort * Commented unused var * Update examples/all-clusters-app/linux/AllClustersCommandDelegate.cpp * Fix bug --------- Co-authored-by: Restyled.io <commits@restyled.io> * YAML update to BRBINFO, ProductId (project-chip#34513) * Bridged Device Information Cluster, Attribute ProductID test reflects marking as O, not X * Update src/app/tests/suites/certification/Test_TC_BRBINFO_2_1.yaml Co-authored-by: Terence Hampson <thampson@google.com> * corrected pics * corrected pics * WIP Bridged ICD, commissioning to both fabrics * wip testing sending KeepActive * update to bridged-device-basic-information.xml and zap generated files * removed unrelated file --------- Co-authored-by: Terence Hampson <thampson@google.com> Co-authored-by: Andrei Litvin <andy314@gmail.com> * Fix simplified Linux tv-casting-app gn build error. (project-chip#34692) * adding parallel execution to restyle-diff (project-chip#34663) * adding parallel execution to restyle-diff * using xargs to call restyle-paths * fixing Copyright year * restyle the restyler * Add some bits to exercise global structs/enums to Unit Testing cluster. (project-chip#34540) * Adds things to the Unit Testing cluster XML. * This requires those things to be enabled in all-clusters-app, all-clusters-minimal-app, and one of the chef contact sensors to pass CI. * That requires an implementation in test-cluster-server * At which point might as well add a YAML test to exercise it all. * [Silabs] Port platform specific Multi-Chip OTA work (project-chip#34440) * Pull request project-chip#1836: Cherry multi ota Merge in WMN_TOOLS/matter from cherry-multi-ota to silabs_slc_1.3 Squashed commit of the following: commit 4320bb46571658bc44fb82345348265def394991 Author: Michael Rupp <michael.rupp@silabs.com> Date: Fri May 10 14:26:07 2024 -0400 remove some unwanted diffs in provision files commit be160931dc600de7e7ead378b70d6a43c3945e46 Author: Michael Rupp <michael.rupp@silabs.com> Date: Fri May 10 14:24:25 2024 -0400 revert changes to generator.project.mak commit 14b6605887166e6d5284a61feb2bf407d850bdcf Author: Michael Rupp <michael.rupp@silabs.com> Date: Fri May 10 13:06:12 2024 -0400 revert NVM key changes and script changes ... and 8 more commits * Restyled by whitespace * Restyled by clang-format * Restyled by gn * Restyled by autopep8 * remove unused libs caught by linter * update doctree with new readmes * rerun CI, cirque failing for unknown reasons * fix include guards in provision examples * Restyled by clang-format --------- Co-authored-by: Restyled.io <commits@restyled.io> * Add python tests for Thermostat presets feature (project-chip#34693) * Add python tests for Thermostat presets feature * Restyled by autopep8 * Restyled by isort * Update the PICS code for presets attribute --------- Co-authored-by: Restyled.io <commits@restyled.io> * removing unneccessary git fetch (project-chip#34698) * Restyle patch * Regen to fix ordering of global structs * Apply suggestions from code review Co-authored-by: Boris Zbarsky <bzbarsky@apple.com> * Return correct AtomicResponse when committing or rolling back * Patch tests for atomic write of presets * Fix tests to work with the new setup. Specific changes: * Enable SetActivePresetRequest command in all-clusters-app. * Fix assignment of a PresetStructWithOwnedMembers to another PresetStructWithOwnedMembers to actually work correctly. * Move constraint checks that happen on write from commit to write. * Fix sending of atomic responses to not have use-stack-after-return. * Fix PICS for the tests involved. * Fix PICS values for atomic requests * Remove PresetsSchedulesEditable and QueuedPreset from various places * Restyled patch * Restyled patch, again * Remove PICS value for PresetsSchedulesEditable * clang-tidy fixes * clang-tidy fixes * Clear associated atomic writes when fabric is removed * Add tests for fabric removal and lockout of clients outside of atomic write * Python linter * Restyled patch * Clear timer when fabric is removed * Check for open atomic write before resetting * Revert auto delegate declaration on lines where there's no collision * Allow Thermostat delegate to provide timeout for atomic requests * Relocate thermostat example code to thermostat-common * Remove thermostat-manager code, replace with thermostat delegate * Sync atomic write error order with spec * Restyle patch * Drop memset of atomic write sessions * Add PreCommit stage to allow rollback of multiple attributes when only one fails * Separate OnTimerExpired method, vs ResetWrite * Method documentation * Apply suggestions from code review Co-authored-by: Nivi Sarkar <55898241+nivi-apple@users.noreply.github.com> * Remove unused InWrite check * Drop imcode alias * Switch AtomicWriteState to enum class * DRY up atomic write manager * Apply suggestions from code review Co-authored-by: Nivi Sarkar <55898241+nivi-apple@users.noreply.github.com> * Drop duplicate doc comments * Rename GetAtomicWriteScopedNodeId to GetAtomicWriteOriginatorScopedNodeId * Updates based on comments * Add MatterReportingAttributeChangeCallback calls for updated attributes * Relocate thermostat example code to thermostat-common, and remove thermostat-manager * Merge atomic write code back into thermostat-server * Apply suggestions from code review Co-authored-by: Boris Zbarsky <bzbarsky@apple.com> * Fix build after suggestions * Actually track attribute IDs associated with atomic write * Only commit presets if all attribute precommits were successful * Fix scope on err * Add documentation to methods * Remove duplicate preset check. * Move various functions into anonymous namespaces, or Thermostat namespace * Drop impossible non-atomic attribute status after rollback * Allow null BuiltIn field when saving Presets * Namespace workaround for compilers on other platforms * Fix bad merge * Fix readability issue * Force built-in to false on new presets --------- Co-authored-by: Nivedita Sarkar <nivedita_sarkar@apple.com> Co-authored-by: Restyled.io <commits@restyled.io> Co-authored-by: Nivi Sarkar <55898241+nivi-apple@users.noreply.github.com> Co-authored-by: Boris Zbarsky <bzbarsky@apple.com> Co-authored-by: Terence Hampson <thampson@google.com> Co-authored-by: Tennessee Carmel-Veilleux <tennessee.carmelveilleux@gmail.com> Co-authored-by: Chris Letnick <cletnick@google.com> Co-authored-by: C Freeman <cecille@google.com> Co-authored-by: Douglas Rocha Ferraz <rochaferraz@google.com> Co-authored-by: Petru Lauric <81822411+plauric@users.noreply.github.com> Co-authored-by: William <hicklin@users.noreply.github.com> Co-authored-by: Kiel Oleson <kielo@apple.com> Co-authored-by: Karsten Sperling <113487422+ksperling-apple@users.noreply.github.com> Co-authored-by: Anu Biradar <104591549+abiradarti@users.noreply.github.com> Co-authored-by: mkardous-silabs <84793247+mkardous-silabs@users.noreply.github.com> Co-authored-by: Rob Bultman <rob.Bultman@gmail.com> Co-authored-by: Andrei Litvin <andy314@gmail.com> Co-authored-by: Shao Ling Tan <161761051+shaoltan-amazon@users.noreply.github.com> Co-authored-by: Amine Alami <43780877+Alami-Amine@users.noreply.github.com> Co-authored-by: Michael Rupp <95718139+mykrupp@users.noreply.github.com>
1 parent ee03924 commit a696416

File tree

5 files changed

+50
-24
lines changed

5 files changed

+50
-24
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

+35-17
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,53 +351,71 @@ 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
{
365366
return CHIP_IM_GLOBAL_STATUS(ConstraintError);
366367
}
368+
// Force to be false, if passed as null
369+
preset.SetBuiltIn(false);
367370
}
368371
else
369372
{
370-
auto & presetHandle = preset.presetHandle.Value();
371-
372373
// Per spec we need to check that:
373374
// (a) There is an existing non-pending preset with this handle.
374375
PresetStructWithOwnedMembers matchingPreset;
375-
if (!GetMatchingPresetInPresets(delegate, preset, matchingPreset))
376+
if (!GetMatchingPresetInPresets(delegate, preset.GetPresetHandle().Value(), matchingPreset))
376377
{
377378
return CHIP_IM_GLOBAL_STATUS(NotFound);
378379
}
379380

380381
// (b) There is no existing pending preset with this handle.
381-
if (CountPresetsInPendingListWithPresetHandle(delegate, presetHandle) > 0)
382+
if (CountPresetsInPendingListWithPresetHandle(delegate, preset.GetPresetHandle().Value()) > 0)
382383
{
383384
return CHIP_IM_GLOBAL_STATUS(ConstraintError);
384385
}
385386

387+
const auto & presetBuiltIn = preset.GetBuiltIn();
388+
const auto & matchingPresetBuiltIn = matchingPreset.GetBuiltIn();
386389
// (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())
390+
if (presetBuiltIn.IsNull())
390391
{
391-
return CHIP_IM_GLOBAL_STATUS(ConstraintError);
392+
if (matchingPresetBuiltIn.IsNull())
393+
{
394+
// This really shouldn't happen; internal presets should alway have built-in set
395+
return CHIP_IM_GLOBAL_STATUS(InvalidInState);
396+
}
397+
preset.SetBuiltIn(matchingPresetBuiltIn.Value());
398+
}
399+
else
400+
{
401+
if (matchingPresetBuiltIn.IsNull())
402+
{
403+
// This really shouldn't happen; internal presets should alway have built-in set
404+
return CHIP_IM_GLOBAL_STATUS(InvalidInState);
405+
}
406+
if (presetBuiltIn.Value() != matchingPresetBuiltIn.Value())
407+
{
408+
return CHIP_IM_GLOBAL_STATUS(ConstraintError);
409+
}
392410
}
393411
}
394412

395-
if (!PresetScenarioExistsInPresetTypes(delegate, preset.presetScenario))
413+
if (!PresetScenarioExistsInPresetTypes(delegate, preset.GetPresetScenario()))
396414
{
397415
return CHIP_IM_GLOBAL_STATUS(ConstraintError);
398416
}
399417

400-
if (preset.name.HasValue() && !PresetTypeSupportsNames(delegate, preset.presetScenario))
418+
if (preset.GetName().HasValue() && !PresetTypeSupportsNames(delegate, preset.GetPresetScenario()))
401419
{
402420
return CHIP_IM_GLOBAL_STATUS(ConstraintError);
403421
}

src/python_testing/TC_TSTAT_4_2.py

+10-2
Original file line numberDiff line numberDiff line change
@@ -246,8 +246,12 @@ async def test_TC_TSTAT_4_2(self):
246246
if self.pics_guard(self.check_pics("TSTAT.S.F08") and self.check_pics("TSTAT.S.A0050") and self.check_pics("TSTAT.S.Cfe.Rsp")):
247247
await self.send_atomic_request_begin_command()
248248

249+
# Set the new preset to a null built-in value; will be replaced with false on reading
250+
test_presets = copy.deepcopy(new_presets)
251+
test_presets[2].builtIn = NullValue
252+
249253
# Write to the presets attribute after calling AtomicRequest command
250-
status = await self.write_presets(endpoint=endpoint, presets=new_presets)
254+
status = await self.write_presets(endpoint=endpoint, presets=test_presets)
251255
status_ok = (status == Status.Success)
252256
asserts.assert_true(status_ok, "Presets write did not return Success as expected")
253257

@@ -268,8 +272,12 @@ async def test_TC_TSTAT_4_2(self):
268272
# Send the AtomicRequest begin command
269273
await self.send_atomic_request_begin_command()
270274

275+
# Set the existing preset to a null built-in value; will be replaced with true on reading
276+
test_presets = copy.deepcopy(new_presets)
277+
test_presets[0].builtIn = NullValue
278+
271279
# Write to the presets attribute after calling AtomicRequest command
272-
await self.write_presets(endpoint=endpoint, presets=new_presets)
280+
await self.write_presets(endpoint=endpoint, presets=test_presets)
273281

274282
# Send the AtomicRequest commit command
275283
await self.send_atomic_request_commit_command()

0 commit comments

Comments
 (0)