From 9a2f19d2249f3000aa76ac7c37f244fdc42492f4 Mon Sep 17 00:00:00 2001 From: Erwin Pan Date: Fri, 16 Feb 2024 21:45:28 +0800 Subject: [PATCH 01/33] [Chef] Fix basicvideoplayer device type (#32091) * [Chef] Fix basicvideoplayer device type This was actually a squashed and rebased commit for PR #31987 since it mixed with unwanted commit from other people due to conflicts during rebasing * Rename Data() function to GetXxxxName() function * Use `StringBuilder` instead of std::stringstream * Simplify codes without unnecessary return variables * Remove unused static_cast * Simplify the keypad keycode handling * Restyled by clang-format * Enable Chef BasicVideoPlayer in cloud build * Remove unused GetInputName & GetOutputName function * Using struct InputData&OuptutData to refine logics in Chef common/clusters/audio-output/AudioOutputManager.* and common/clusters/media-input/MediaInputManager.* * Add break in default section * Fix recordingFlag type and remove EMBER_ZCL_STATUS_SUCCESS * Use std::numeric_limits::max() as endTime default * Remove some unneeded namespace declaration * Restyled by clang-format * Restyled by clang-format --------- Co-authored-by: Restyled.io --- examples/chef/chef.py | 1 + examples/chef/common/chef-channel-manager.cpp | 226 ---- examples/chef/common/chef-channel-manager.h | 55 - .../audio-output/AudioOutputManager.cpp | 83 ++ .../audio-output/AudioOutputManager.h | 58 + .../clusters/channel/ChannelManager.cpp | 352 +++++ .../common/clusters/channel/ChannelManager.h | 78 ++ .../keypad-input/KeypadInputManager.cpp | 78 ++ .../keypad-input/KeypadInputManager.h | 37 + .../clusters/low-power/LowPowerManager.cpp | 28 + .../clusters/low-power/LowPowerManager.h | 27 + .../media-input/MediaInputManager.cpp | 102 ++ .../clusters/media-input/MediaInputManager.h | 68 + .../media-playback/MediaPlaybackManager.cpp | 339 +++++ .../media-playback/MediaPlaybackManager.h | 117 ++ .../TargetNavigatorManager.cpp | 94 ++ .../target-navigator/TargetNavigatorManager.h | 45 + .../clusters/wake-on-lan/WakeOnLanManager.cpp | 68 + .../clusters/wake-on-lan/WakeOnLanManager.h | 27 + examples/chef/common/stubs.cpp | 125 +- ...ootnode_basicvideoplayer_0ff86e943b.matter | 327 ++++- .../rootnode_basicvideoplayer_0ff86e943b.zap | 1202 ++++++++++++++--- examples/chef/esp32/main/CMakeLists.txt | 9 + examples/chef/linux/BUILD.gn | 10 +- examples/chef/nrfconnect/CMakeLists.txt | 10 +- integrations/cloudbuild/chef.yaml | 2 +- 26 files changed, 3069 insertions(+), 499 deletions(-) delete mode 100644 examples/chef/common/chef-channel-manager.cpp delete mode 100644 examples/chef/common/chef-channel-manager.h create mode 100644 examples/chef/common/clusters/audio-output/AudioOutputManager.cpp create mode 100644 examples/chef/common/clusters/audio-output/AudioOutputManager.h create mode 100644 examples/chef/common/clusters/channel/ChannelManager.cpp create mode 100644 examples/chef/common/clusters/channel/ChannelManager.h create mode 100644 examples/chef/common/clusters/keypad-input/KeypadInputManager.cpp create mode 100644 examples/chef/common/clusters/keypad-input/KeypadInputManager.h create mode 100644 examples/chef/common/clusters/low-power/LowPowerManager.cpp create mode 100644 examples/chef/common/clusters/low-power/LowPowerManager.h create mode 100644 examples/chef/common/clusters/media-input/MediaInputManager.cpp create mode 100644 examples/chef/common/clusters/media-input/MediaInputManager.h create mode 100644 examples/chef/common/clusters/media-playback/MediaPlaybackManager.cpp create mode 100644 examples/chef/common/clusters/media-playback/MediaPlaybackManager.h create mode 100644 examples/chef/common/clusters/target-navigator/TargetNavigatorManager.cpp create mode 100644 examples/chef/common/clusters/target-navigator/TargetNavigatorManager.h create mode 100644 examples/chef/common/clusters/wake-on-lan/WakeOnLanManager.cpp create mode 100644 examples/chef/common/clusters/wake-on-lan/WakeOnLanManager.h diff --git a/examples/chef/chef.py b/examples/chef/chef.py index 688bdfef490761..816840f8584a45 100755 --- a/examples/chef/chef.py +++ b/examples/chef/chef.py @@ -801,6 +801,7 @@ def main() -> int: 'import("${chip_root}/config/standalone/args.gni")', 'chip_shell_cmd_server = false', 'chip_build_libshell = true', + 'chip_enable_openthread = false', 'chip_config_network_layer_ble = false', 'chip_device_project_config_include = ""', 'chip_project_config_include = ""', diff --git a/examples/chef/common/chef-channel-manager.cpp b/examples/chef/common/chef-channel-manager.cpp deleted file mode 100644 index 4a8d6de466d746..00000000000000 --- a/examples/chef/common/chef-channel-manager.cpp +++ /dev/null @@ -1,226 +0,0 @@ -/** - * - * Copyright (c) 2021 Project CHIP Authors - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#include -#include -#include - -using ChangeChannelResponseType = chip::app::Clusters::Channel::Commands::ChangeChannelResponse::Type; -using ChannelInfoType = chip::app::Clusters::Channel::Structs::ChannelInfoStruct::Type; -using LineupInfoType = chip::app::Clusters::Channel::Structs::LineupInfoStruct::Type; -// Include Channel Cluster Server callbacks only when the server is enabled -#ifdef MATTER_DM_PLUGIN_CHANNEL_SERVER -#include - -using namespace chip; -using namespace chip::app; -using namespace chip::app::Clusters::Channel; -using namespace chip::Uint8; - -ChefChannelManager::ChefChannelManager() -{ - ChannelInfoType abc; - abc.affiliateCallSign = MakeOptional(chip::CharSpan::fromCharString("KAAL")); - abc.callSign = MakeOptional(chip::CharSpan::fromCharString("KAAL-TV")); - abc.name = MakeOptional(chip::CharSpan::fromCharString("ABC")); - abc.majorNumber = static_cast(6); - abc.minorNumber = static_cast(0); - mChannels[mTotalChannels++] = abc; - - ChannelInfoType pbs; - pbs.affiliateCallSign = MakeOptional(chip::CharSpan::fromCharString("KCTS")); - pbs.callSign = MakeOptional(chip::CharSpan::fromCharString("KCTS-TV")); - pbs.name = MakeOptional(chip::CharSpan::fromCharString("PBS")); - pbs.majorNumber = static_cast(9); - pbs.minorNumber = static_cast(1); - mChannels[mTotalChannels++] = pbs; - - ChannelInfoType pbsKids; - pbsKids.affiliateCallSign = MakeOptional(chip::CharSpan::fromCharString("KCTS")); - pbsKids.callSign = MakeOptional(chip::CharSpan::fromCharString("KCTS-TV")); - pbsKids.name = MakeOptional(chip::CharSpan::fromCharString("PBS Kids")); - pbsKids.majorNumber = static_cast(9); - pbsKids.minorNumber = static_cast(2); - mChannels[mTotalChannels++] = pbsKids; - - ChannelInfoType worldChannel; - worldChannel.affiliateCallSign = MakeOptional(chip::CharSpan::fromCharString("KCTS")); - worldChannel.callSign = MakeOptional(chip::CharSpan::fromCharString("KCTS-TV")); - worldChannel.name = MakeOptional(chip::CharSpan::fromCharString("World Channel")); - worldChannel.majorNumber = static_cast(9); - worldChannel.minorNumber = static_cast(3); - mChannels[mTotalChannels++] = worldChannel; -} - -static bool isChannelMatched(const ChannelInfoType & channel, const CharSpan & match) -{ - if (channel.name.HasValue() && channel.name.Value().data_equal(match)) - { - return true; - } - - if (channel.affiliateCallSign.HasValue() && channel.affiliateCallSign.Value().data_equal(match)) - { - return true; - } - - if (channel.callSign.HasValue() && channel.callSign.Value().data_equal(match)) - { - return true; - } - - StringBuilder<32> nr; - nr.AddFormat("%d.%d", channel.majorNumber, channel.minorNumber); - return match.data_equal(CharSpan::fromCharString(nr.c_str())); -} - -CHIP_ERROR ChefChannelManager::HandleGetChannelList(app::AttributeValueEncoder & aEncoder) -{ - return aEncoder.EncodeList([](const auto & encoder) -> CHIP_ERROR { - int index = 0; - for (auto const & channel : ChefChannelManager().mChannels) - { - ReturnErrorOnFailure(encoder.Encode(channel)); - index++; - if (index >= ChefChannelManager().mTotalChannels) - break; - } - return CHIP_NO_ERROR; - }); -} - -CHIP_ERROR ChefChannelManager::HandleGetLineup(app::AttributeValueEncoder & aEncoder) -{ - LineupInfoType lineup; - lineup.operatorName = chip::CharSpan::fromCharString("Comcast"); - lineup.lineupName = MakeOptional(chip::CharSpan::fromCharString("Comcast King County")); - lineup.postalCode = MakeOptional(chip::CharSpan::fromCharString("98052")); - lineup.lineupInfoType = chip::app::Clusters::Channel::LineupInfoTypeEnum::kMso; - - return aEncoder.Encode(lineup); -} - -CHIP_ERROR ChefChannelManager::HandleGetCurrentChannel(app::AttributeValueEncoder & aEncoder) -{ - return aEncoder.Encode(mChannels[mCurrentChannelIndex]); -} - -void ChefChannelManager::HandleChangeChannel(CommandResponseHelper & helper, - const chip::CharSpan & match) -{ - std::array matchedChannels; - - uint16_t index = 0; - uint16_t totalMatchedChannels = 0; - for (auto const & channel : mChannels) - { - // verify if CharSpan matches channel name - // or callSign or affiliateCallSign or majorNumber.minorNumber - if (isChannelMatched(channel, match)) - { - matchedChannels[totalMatchedChannels++] = (channel); - } - else if (totalMatchedChannels == 0) - { - // "index" is only used when we end up with totalMatchedChannels == 1. - // In that case, we want it to be the number of non-matching channels we saw before - // the matching one. - index++; - } - } - - ChangeChannelResponseType response; - - // Error: Found multiple matches - if (totalMatchedChannels > 1) - { - response.status = chip::app::Clusters::Channel::StatusEnum::kMultipleMatches; - helper.Success(response); - } - else if (totalMatchedChannels == 0) - { - // Error: Found no match - response.status = chip::app::Clusters::Channel::StatusEnum::kNoMatches; - helper.Success(response); - } - else - { - response.status = chip::app::Clusters::Channel::StatusEnum::kSuccess; - response.data = chip::MakeOptional(CharSpan::fromCharString("data response")); - mCurrentChannelIndex = index; - helper.Success(response); - } -} - -bool ChefChannelManager::HandleChangeChannelByNumber(const uint16_t & majorNumber, const uint16_t & minorNumber) -{ - bool channelChanged = false; - uint16_t index = 0; - for (auto const & channel : mChannels) - { - - // verify if major & minor matches one of the channel from the list - if (channel.minorNumber == minorNumber && channel.majorNumber == majorNumber) - { - // verify if channel changed by comparing values of current channel with the requested channel - if (channel.minorNumber != mChannels[mCurrentChannelIndex].minorNumber || - channel.majorNumber != mChannels[mCurrentChannelIndex].majorNumber) - { - channelChanged = true; - mCurrentChannelIndex = index; - } - - // return since we've already found the unique matched channel - return channelChanged; - } - index++; - if (index >= mTotalChannels) - break; - } - return channelChanged; -} - -bool ChefChannelManager::HandleSkipChannel(const int16_t & count) -{ - int32_t newChannelIndex = static_cast(count) + static_cast(mCurrentChannelIndex); - uint16_t channelsSize = static_cast(mChannels.size()); - - // handle newChannelIndex out of range. - newChannelIndex = newChannelIndex % channelsSize; - - if (newChannelIndex < 0) - { - newChannelIndex = newChannelIndex + channelsSize; - } - - mCurrentChannelIndex = static_cast(newChannelIndex); - return true; -} - -uint32_t ChefChannelManager::GetFeatureMap(chip::EndpointId endpoint) -{ - if (endpoint > MATTER_DM_CHANNEL_CLUSTER_SERVER_ENDPOINT_COUNT) - { - return 0; - } - - uint32_t featureMap = 0; - Attributes::FeatureMap::Get(endpoint, &featureMap); - return featureMap; -} - -#endif /* MATTER_DM_PLUGIN_CHANNEL_SERVER */ diff --git a/examples/chef/common/chef-channel-manager.h b/examples/chef/common/chef-channel-manager.h deleted file mode 100644 index 53a1db529a9a4a..00000000000000 --- a/examples/chef/common/chef-channel-manager.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * - * Copyright (c) 2021 Project CHIP Authors - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include - -class ChefChannelManager : public chip::app::Clusters::Channel::Delegate -{ - -public: - ChefChannelManager(); - - CHIP_ERROR HandleGetChannelList(chip::app::AttributeValueEncoder & aEncoder); - CHIP_ERROR HandleGetLineup(chip::app::AttributeValueEncoder & aEncoder); - CHIP_ERROR HandleGetCurrentChannel(chip::app::AttributeValueEncoder & aEncoder); - - void HandleChangeChannel( - chip::app::CommandResponseHelper & helper, - const chip::CharSpan & match); - bool HandleChangeChannelByNumber(const uint16_t & majorNumber, const uint16_t & minorNumber); - bool HandleSkipChannel(const int16_t & count); - - static ChefChannelManager & Instance() - { - static ChefChannelManager instance; - return instance; - } - - // bool HasFeature(chip::EndpointId endpoint, Feature feature); - uint32_t GetFeatureMap(chip::EndpointId endpoint); - - ~ChefChannelManager() = default; - -protected: - static constexpr size_t kMaxChannels = 10; - uint16_t mCurrentChannelIndex{ 0 }; - uint16_t mTotalChannels{ 0 }; - std::array mChannels; -}; diff --git a/examples/chef/common/clusters/audio-output/AudioOutputManager.cpp b/examples/chef/common/clusters/audio-output/AudioOutputManager.cpp new file mode 100644 index 00000000000000..06a123a6549679 --- /dev/null +++ b/examples/chef/common/clusters/audio-output/AudioOutputManager.cpp @@ -0,0 +1,83 @@ +/* + * + * Copyright (c) 2021 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#ifdef MATTER_DM_PLUGIN_AUDIO_OUTPUT_SERVER +#include "AudioOutputManager.h" + +using namespace std; +using namespace chip::app; +using namespace chip::app::Clusters::AudioOutput; +using chip::app::AttributeValueEncoder; + +AudioOutputManager::AudioOutputManager() +{ + struct OutputData outputData1(1, chip::app::Clusters::AudioOutput::OutputTypeEnum::kHdmi, "HDMI 1"); + mOutputs.push_back(outputData1); + struct OutputData outputData2(2, chip::app::Clusters::AudioOutput::OutputTypeEnum::kHdmi, "HDMI 2"); + mOutputs.push_back(outputData2); + struct OutputData outputData3(3, chip::app::Clusters::AudioOutput::OutputTypeEnum::kHdmi, "HDMI 3"); + mOutputs.push_back(outputData3); + + mCurrentOutput = 1; +} + +uint8_t AudioOutputManager::HandleGetCurrentOutput() +{ + return mCurrentOutput; +} + +CHIP_ERROR AudioOutputManager::HandleGetOutputList(AttributeValueEncoder & aEncoder) +{ + return aEncoder.EncodeList([this](const auto & encoder) -> CHIP_ERROR { + for (auto const & outputData : mOutputs) + { + ReturnErrorOnFailure(encoder.Encode(outputData.GetEncodable())); + } + return CHIP_NO_ERROR; + }); +} + +bool AudioOutputManager::HandleRenameOutput(const uint8_t & index, const chip::CharSpan & newName) +{ + for (auto & outputData : mOutputs) + { + if (outputData.index == index) + { + outputData.Rename(newName); + return true; + } + } + + return false; +} + +bool AudioOutputManager::HandleSelectOutput(const uint8_t & index) +{ + for (auto & outputData : mOutputs) + { + if (outputData.index == index) + { + mCurrentOutput = index; + return true; + } + } + + return false; +} +#endif // MATTER_DM_PLUGIN_AUDIO_OUTPUT_SERVER diff --git a/examples/chef/common/clusters/audio-output/AudioOutputManager.h b/examples/chef/common/clusters/audio-output/AudioOutputManager.h new file mode 100644 index 00000000000000..5f9157de773ee7 --- /dev/null +++ b/examples/chef/common/clusters/audio-output/AudioOutputManager.h @@ -0,0 +1,58 @@ +/* + * + * Copyright (c) 2021 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include +#include + +class AudioOutputManager : public chip::app::Clusters::AudioOutput::Delegate +{ + using OutputInfoType = chip::app::Clusters::AudioOutput::Structs::OutputInfoStruct::Type; + +public: + AudioOutputManager(); + + uint8_t HandleGetCurrentOutput() override; + CHIP_ERROR HandleGetOutputList(chip::app::AttributeValueEncoder & aEncoder) override; + bool HandleRenameOutput(const uint8_t & index, const chip::CharSpan & name) override; + bool HandleSelectOutput(const uint8_t & index) override; + + struct OutputData + { + uint8_t index; + chip::app::Clusters::AudioOutput::OutputTypeEnum outputType; + std::string name; + + OutputData(uint8_t i, chip::app::Clusters::AudioOutput::OutputTypeEnum t, const char * n) : index(i), outputType(t), name(n) + {} + void Rename(const chip::CharSpan & newName) { name.assign(newName.data(), newName.size()); } + OutputInfoType GetEncodable() const + { + OutputInfoType result; + result.index = index; + result.outputType = outputType; + result.name = chip::CharSpan::fromCharString(name.c_str()); + return result; + } + }; + +protected: + uint8_t mCurrentOutput = 1; + std::vector mOutputs; +}; diff --git a/examples/chef/common/clusters/channel/ChannelManager.cpp b/examples/chef/common/clusters/channel/ChannelManager.cpp new file mode 100644 index 00000000000000..36df31af6de280 --- /dev/null +++ b/examples/chef/common/clusters/channel/ChannelManager.cpp @@ -0,0 +1,352 @@ +/** + * + * Copyright (c) 2021 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#ifdef MATTER_DM_PLUGIN_CHANNEL_SERVER +#include "ChannelManager.h" +#include +#include + +#include +#include +#include + +using namespace chip; +using namespace chip::app; +using namespace chip::app::Clusters::Channel; +using namespace chip::Uint8; + +ChannelManager::ChannelManager() +{ + ChannelInfoType abc; + abc.affiliateCallSign = MakeOptional(chip::CharSpan::fromCharString("KAAL")); + abc.callSign = MakeOptional(chip::CharSpan::fromCharString("KAAL-TV")); + abc.name = MakeOptional(chip::CharSpan::fromCharString("ABC")); + abc.majorNumber = static_cast(6); + abc.minorNumber = static_cast(0); + mChannels.push_back(abc); + + ChannelInfoType pbs; + pbs.affiliateCallSign = MakeOptional(chip::CharSpan::fromCharString("KCTS")); + pbs.callSign = MakeOptional(chip::CharSpan::fromCharString("KCTS-TV")); + pbs.name = MakeOptional(chip::CharSpan::fromCharString("PBS")); + pbs.majorNumber = static_cast(9); + pbs.minorNumber = static_cast(1); + mChannels.push_back(pbs); + + ChannelInfoType pbsKids; + pbsKids.affiliateCallSign = MakeOptional(chip::CharSpan::fromCharString("KCTS")); + pbsKids.callSign = MakeOptional(chip::CharSpan::fromCharString("KCTS-TV")); + pbsKids.name = MakeOptional(chip::CharSpan::fromCharString("PBS Kids")); + pbsKids.majorNumber = static_cast(9); + pbsKids.minorNumber = static_cast(2); + mChannels.push_back(pbsKids); + + ChannelInfoType worldChannel; + worldChannel.affiliateCallSign = MakeOptional(chip::CharSpan::fromCharString("KCTS")); + worldChannel.callSign = MakeOptional(chip::CharSpan::fromCharString("KCTS-TV")); + worldChannel.name = MakeOptional(chip::CharSpan::fromCharString("World Channel")); + worldChannel.majorNumber = static_cast(9); + worldChannel.minorNumber = static_cast(3); + mChannels.push_back(worldChannel); + + mCurrentChannelIndex = 0; + mCurrentChannel = mChannels[mCurrentChannelIndex]; + + ProgramType program1; + program1.identifier = chip::CharSpan::fromCharString("progid-abc1"); + program1.channel = abc; + program1.title = chip::CharSpan::fromCharString("ABC Title1"); + program1.subtitle = MakeOptional(chip::CharSpan::fromCharString("My Program Subtitle1")); + program1.startTime = 0; + program1.endTime = 30 * 60; + + mPrograms.push_back(program1); + + ProgramType program_pbs1; + program_pbs1.identifier = chip::CharSpan::fromCharString("progid-pbs1"); + program_pbs1.channel = pbs; + program_pbs1.title = chip::CharSpan::fromCharString("PBS Title1"); + program_pbs1.subtitle = MakeOptional(chip::CharSpan::fromCharString("My Program Subtitle1")); + program_pbs1.startTime = 0; + program_pbs1.endTime = 30 * 60; + + mPrograms.push_back(program_pbs1); + + ProgramType program2; + program2.identifier = chip::CharSpan::fromCharString("progid-abc2"); + program2.channel = abc; + program2.title = chip::CharSpan::fromCharString("My Program Title2"); + program2.subtitle = MakeOptional(chip::CharSpan::fromCharString("My Program Subtitle2")); + program2.startTime = 30 * 60; + program2.endTime = 60 * 60; + + mPrograms.push_back(program2); + + ProgramType program3; + program3.identifier = chip::CharSpan::fromCharString("progid-abc3"); + program3.channel = abc; + program3.title = chip::CharSpan::fromCharString("My Program Title3"); + program3.subtitle = MakeOptional(chip::CharSpan::fromCharString("My Program Subtitle3")); + program3.startTime = 0; + program3.endTime = 60 * 60; + + mPrograms.push_back(program3); +} + +CHIP_ERROR ChannelManager::HandleGetChannelList(AttributeValueEncoder & aEncoder) +{ + return aEncoder.EncodeList([](const auto & encoder) -> CHIP_ERROR { + for (auto const & channel : ChannelManager().mChannels) + { + ReturnErrorOnFailure(encoder.Encode(channel)); + } + return CHIP_NO_ERROR; + }); +} + +CHIP_ERROR ChannelManager::HandleGetLineup(AttributeValueEncoder & aEncoder) +{ + LineupInfoType lineup; + lineup.operatorName = chip::CharSpan::fromCharString("Comcast"); + lineup.lineupName = MakeOptional(chip::CharSpan::fromCharString("Comcast King County")); + lineup.postalCode = MakeOptional(chip::CharSpan::fromCharString("98052")); + lineup.lineupInfoType = LineupInfoTypeEnum::kMso; + + return aEncoder.Encode(lineup); +} + +CHIP_ERROR ChannelManager::HandleGetCurrentChannel(AttributeValueEncoder & aEncoder) +{ + return aEncoder.Encode(mCurrentChannel); +} + +bool ChannelManager::isChannelMatched(const ChannelInfoType & channel, const chip::CharSpan & match) +{ + StringBuilder<16> channelNum; + channelNum.AddFormat("%d.%d", channel.majorNumber, channel.minorNumber); + + auto isMatch = [&match](const Optional & a) { return a.HasValue() && a.Value().data_equal(match); }; + + return isMatch(channel.name) || isMatch(channel.affiliateCallSign) || isMatch(channel.callSign) || + match.data_equal(chip::CharSpan::fromCharString(channelNum.c_str())); +} + +void ChannelManager::HandleChangeChannel(CommandResponseHelper & helper, const CharSpan & match) +{ + int iMatchedChannel = -1; + ChangeChannelResponseType response; + + for (uint16_t i = 0; i < mChannels.size(); i++) + { + // verify if CharSpan matches channel name + // or callSign or affiliateCallSign or majorNumber.minorNumber + if (isChannelMatched(mChannels[i], match)) + { + if (iMatchedChannel != -1) + { + // Error: Found multiple matches + response.status = StatusEnum::kMultipleMatches; + helper.Success(response); + return; + } + iMatchedChannel = i; + } + } + + if (iMatchedChannel == -1) + { + // Error: Found no match + response.status = StatusEnum::kNoMatches; + helper.Success(response); + } + else + { + response.status = StatusEnum::kSuccess; + response.data = chip::MakeOptional(CharSpan::fromCharString("data response")); + mCurrentChannel = mChannels[iMatchedChannel]; + mCurrentChannelIndex = iMatchedChannel; + helper.Success(response); + } +} + +bool ChannelManager::HandleChangeChannelByNumber(const uint16_t & majorNumber, const uint16_t & minorNumber) +{ + uint16_t index = 0; + for (auto const & channel : mChannels) + { + // verify if major & minor matches one of the channel from the list + if (channel.minorNumber == minorNumber && channel.majorNumber == majorNumber) + { + // verify if channel changed by comparing values of current channel with the requested channel + if (channel.minorNumber != mCurrentChannel.minorNumber || channel.majorNumber != mCurrentChannel.majorNumber) + { + mCurrentChannelIndex = index; + mCurrentChannel = channel; + return true; + } + } + index++; + } + return false; +} + +bool ChannelManager::HandleSkipChannel(const int16_t & count) +{ + int32_t newChannelIndex = static_cast(count) + static_cast(mCurrentChannelIndex); + uint16_t channelsSize = static_cast(mChannels.size()); + + // handle newChannelIndex out of range. + newChannelIndex = newChannelIndex % channelsSize; + + if (newChannelIndex < 0) + { + newChannelIndex = newChannelIndex + channelsSize; + } + + mCurrentChannelIndex = static_cast(newChannelIndex); + mCurrentChannel = mChannels[mCurrentChannelIndex]; + return true; +} + +void ChannelManager::HandleGetProgramGuide(CommandResponseHelper & helper, + const chip::Optional & startTime, const chip::Optional & endTime, + const chip::Optional> & channelList, + const chip::Optional & pageToken, + const chip::Optional> & recordingFlag, + const chip::Optional> & externalIdList, + const chip::Optional & data) +{ + + // 1. Decode received parameters + // 2. Perform search + // 3. Return results + + // PageTokenType paging; + // paging.limit = MakeOptional(static_cast(10)); + // paging.after = MakeOptional(chip::CharSpan::fromCharString("after-token")); + // paging.before = MakeOptional(chip::CharSpan::fromCharString("before-token")); + + // ChannelPagingStructType channelPaging; + // channelPaging.nextToken = MakeOptional>(paging); + + std::vector matches; + for (auto const & program : mPrograms) + { + if (startTime.ValueOr(0) > program.startTime) + { + continue; + } + if (endTime.ValueOr(std::numeric_limits::max()) < program.endTime) + { + continue; + } + if (channelList.HasValue()) + { + auto iter = channelList.Value().begin(); + bool match = false; + int listCount = 0; + while (iter.Next() && !match) + { + listCount++; + auto & channel = iter.GetValue(); + if (channel.minorNumber != program.channel.minorNumber || channel.majorNumber != program.channel.majorNumber) + { + continue; + } + // this sample code does not currently check OTT + match = true; + } + if (!match && listCount > 0) + { + continue; + } + } + // this sample code does not currently filter on external id list + matches.push_back(program); + } + + ProgramGuideResponseType response; + response.programList = DataModel::List(matches.data(), matches.size()); + helper.Success(response); +} + +bool ChannelManager::HandleRecordProgram(const chip::CharSpan & programIdentifier, bool shouldRecordSeries, + const DataModel::DecodableList & externalIdList, + const chip::ByteSpan & data) +{ + // Start recording + std::string idString(programIdentifier.data(), programIdentifier.size()); + for (auto & program : mPrograms) + { + std::string nextIdString(program.identifier.data(), program.identifier.size()); + if (nextIdString == idString) + { + program.recordingFlag = MakeOptional(chip::BitMask( + shouldRecordSeries ? RecordingFlagBitmap::kRecordSeries : RecordingFlagBitmap::kScheduled)); + } + } + + return true; +} + +bool ChannelManager::HandleCancelRecordProgram(const chip::CharSpan & programIdentifier, bool shouldRecordSeries, + const DataModel::DecodableList & externalIdList, + const chip::ByteSpan & data) +{ + // Cancel recording + std::string idString(programIdentifier.data(), programIdentifier.size()); + for (auto & program : mPrograms) + { + std::string nextIdString(program.identifier.data(), program.identifier.size()); + if (nextIdString == idString) + { + program.recordingFlag = MakeOptional>(0); + } + } + return true; +} + +uint32_t ChannelManager::GetFeatureMap(chip::EndpointId endpoint) +{ + if (endpoint >= MATTER_DM_CHANNEL_CLUSTER_SERVER_ENDPOINT_COUNT) + { + return mDynamicEndpointFeatureMap; + } + + uint32_t featureMap = 0; + Attributes::FeatureMap::Get(endpoint, &featureMap); + return featureMap; +} + +uint16_t ChannelManager::GetClusterRevision(chip::EndpointId endpoint) +{ + if (endpoint >= MATTER_DM_CHANNEL_CLUSTER_SERVER_ENDPOINT_COUNT) + { + return kClusterRevision; + } + + uint16_t clusterRevision = 0; + bool success = + (Attributes::ClusterRevision::Get(endpoint, &clusterRevision) == chip::Protocols::InteractionModel::Status::Success); + if (!success) + { + ChipLogError(Zcl, "ChannelManager::GetClusterRevision error reading cluster revision"); + } + return clusterRevision; +} +#endif // MATTER_DM_PLUGIN_CHANNEL_SERVER diff --git a/examples/chef/common/clusters/channel/ChannelManager.h b/examples/chef/common/clusters/channel/ChannelManager.h new file mode 100644 index 00000000000000..54006c67caf031 --- /dev/null +++ b/examples/chef/common/clusters/channel/ChannelManager.h @@ -0,0 +1,78 @@ +/** + * + * Copyright (c) 2021 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include +#include +#include + +class ChannelManager : public chip::app::Clusters::Channel::Delegate +{ + using RecordingFlagBitmap = chip::app::Clusters::Channel::RecordingFlagBitmap; + using ChangeChannelResponseType = chip::app::Clusters::Channel::Commands::ChangeChannelResponse::Type; + using ProgramGuideResponseType = chip::app::Clusters::Channel::Commands::ProgramGuideResponse::Type; + using ChannelInfoType = chip::app::Clusters::Channel::Structs::ChannelInfoStruct::Type; + using AdditionalInfoType = chip::app::Clusters::Channel::Structs::AdditionalInfoStruct::Type; + using LineupInfoType = chip::app::Clusters::Channel::Structs::LineupInfoStruct::Type; + using PageTokenType = chip::app::Clusters::Channel::Structs::PageTokenStruct::Type; + using ProgramType = chip::app::Clusters::Channel::Structs::ProgramStruct::Type; + using ChannelPagingType = chip::app::Clusters::Channel::Structs::ChannelPagingStruct::Type; + using Feature = chip::app::Clusters::Channel::Feature; + +public: + ChannelManager(); + + CHIP_ERROR HandleGetChannelList(chip::app::AttributeValueEncoder & aEncoder) override; + CHIP_ERROR HandleGetLineup(chip::app::AttributeValueEncoder & aEncoder) override; + CHIP_ERROR HandleGetCurrentChannel(chip::app::AttributeValueEncoder & aEncoder) override; + + void HandleChangeChannel(chip::app::CommandResponseHelper & helper, + const chip::CharSpan & match) override; + bool HandleChangeChannelByNumber(const uint16_t & majorNumber, const uint16_t & minorNumber) override; + bool HandleSkipChannel(const int16_t & count) override; + void HandleGetProgramGuide(chip::app::CommandResponseHelper & helper, + const chip::Optional & startTime, const chip::Optional & endTime, + const chip::Optional> & channelList, + const chip::Optional & pageToken, + const chip::Optional> & recordingFlag, + const chip::Optional> & externalIdList, + const chip::Optional & data) override; + + bool HandleRecordProgram(const chip::CharSpan & programIdentifier, bool shouldRecordSeries, + const chip::app::DataModel::DecodableList & externalIdList, + const chip::ByteSpan & data) override; + + bool HandleCancelRecordProgram(const chip::CharSpan & programIdentifier, bool shouldRecordSeries, + const chip::app::DataModel::DecodableList & externalIdList, + const chip::ByteSpan & data) override; + + uint32_t GetFeatureMap(chip::EndpointId endpoint) override; + uint16_t GetClusterRevision(chip::EndpointId endpoint) override; + +protected: + uint16_t mCurrentChannelIndex; + ChannelInfoType mCurrentChannel; + std::vector mChannels; + std::vector mPrograms; + +private: + bool isChannelMatched(const ChannelInfoType & channel, const chip::CharSpan & match); + static constexpr uint32_t mDynamicEndpointFeatureMap = + chip::BitMask(Feature::kChannelList, Feature::kLineupInfo).Raw(); + static constexpr uint16_t kClusterRevision = 2; +}; diff --git a/examples/chef/common/clusters/keypad-input/KeypadInputManager.cpp b/examples/chef/common/clusters/keypad-input/KeypadInputManager.cpp new file mode 100644 index 00000000000000..bbae2b399b4c0f --- /dev/null +++ b/examples/chef/common/clusters/keypad-input/KeypadInputManager.cpp @@ -0,0 +1,78 @@ +/* + * + * Copyright (c) 2021 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#ifdef MATTER_DM_PLUGIN_KEYPAD_INPUT_SERVER +#include "KeypadInputManager.h" +#include +#include + +using namespace chip; +using namespace chip::app; +using namespace chip::app::Clusters::KeypadInput; + +using chip::app::CommandResponseHelper; + +void KeypadInputManager::HandleSendKey(CommandResponseHelper & helper, const CecKeyCodeType & keycCode) +{ + Commands::SendKeyResponse::Type response; + + switch (keycCode) + { + case CecKeyCodeType::kUp: + case CecKeyCodeType::kDown: + case CecKeyCodeType::kLeft: + case CecKeyCodeType::kRight: + case CecKeyCodeType::kSelect: + case CecKeyCodeType::kBackward: + case CecKeyCodeType::kExit: + case CecKeyCodeType::kRootMenu: + case CecKeyCodeType::kSetupMenu: + case CecKeyCodeType::kEnter: + case CecKeyCodeType::kNumber0OrNumber10: + case CecKeyCodeType::kNumbers1: + case CecKeyCodeType::kNumbers2: + case CecKeyCodeType::kNumbers3: + case CecKeyCodeType::kNumbers4: + case CecKeyCodeType::kNumbers5: + case CecKeyCodeType::kNumbers6: + case CecKeyCodeType::kNumbers7: + case CecKeyCodeType::kNumbers8: + case CecKeyCodeType::kNumbers9: + response.status = chip::app::Clusters::KeypadInput::StatusEnum::kSuccess; + break; + default: + response.status = chip::app::Clusters::KeypadInput::StatusEnum::kUnsupportedKey; + break; + } + + helper.Success(response); +} + +uint32_t KeypadInputManager::GetFeatureMap(chip::EndpointId endpoint) +{ + if (endpoint >= MATTER_DM_KEYPAD_INPUT_CLUSTER_SERVER_ENDPOINT_COUNT) + { + return mDynamicEndpointFeatureMap; + } + + uint32_t featureMap = 0; + Attributes::FeatureMap::Get(endpoint, &featureMap); + return featureMap; +} +#endif // MATTER_DM_PLUGIN_KEYPAD_INPUT_SERVER diff --git a/examples/chef/common/clusters/keypad-input/KeypadInputManager.h b/examples/chef/common/clusters/keypad-input/KeypadInputManager.h new file mode 100644 index 00000000000000..a3c6634166d683 --- /dev/null +++ b/examples/chef/common/clusters/keypad-input/KeypadInputManager.h @@ -0,0 +1,37 @@ +/* + * + * Copyright (c) 2021 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include + +class KeypadInputManager : public chip::app::Clusters::KeypadInput::Delegate +{ + using SendKeyResponseType = chip::app::Clusters::KeypadInput::Commands::SendKeyResponse::Type; + using CecKeyCodeType = chip::app::Clusters::KeypadInput::CECKeyCodeEnum; + using Feature = chip::app::Clusters::KeypadInput::Feature; + +public: + void HandleSendKey(chip::app::CommandResponseHelper & helper, const CecKeyCodeType & keyCode) override; + + uint32_t GetFeatureMap(chip::EndpointId endpoint) override; + +private: + static constexpr uint32_t mDynamicEndpointFeatureMap = + chip::BitMask(Feature::kNavigationKeyCodes, Feature::kLocationKeys, Feature::kNumberKeys).Raw(); +}; diff --git a/examples/chef/common/clusters/low-power/LowPowerManager.cpp b/examples/chef/common/clusters/low-power/LowPowerManager.cpp new file mode 100644 index 00000000000000..1926d0c7150ddd --- /dev/null +++ b/examples/chef/common/clusters/low-power/LowPowerManager.cpp @@ -0,0 +1,28 @@ +/* + * + * Copyright (c) 2021 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#ifdef MATTER_DM_PLUGIN_LOW_POWER_SERVER +#include "LowPowerManager.h" + +bool LowPowerManager::HandleSleep() +{ + ChipLogProgress(Zcl, "LowPowerManager::HandleSleep"); + return true; +} +#endif // MATTER_DM_PLUGIN_LOW_POWER_SERVER diff --git a/examples/chef/common/clusters/low-power/LowPowerManager.h b/examples/chef/common/clusters/low-power/LowPowerManager.h new file mode 100644 index 00000000000000..92bb1417be514d --- /dev/null +++ b/examples/chef/common/clusters/low-power/LowPowerManager.h @@ -0,0 +1,27 @@ +/* + * + * Copyright (c) 2021 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include + +class LowPowerManager : public chip::app::Clusters::LowPower::Delegate +{ +public: + bool HandleSleep() override; +}; diff --git a/examples/chef/common/clusters/media-input/MediaInputManager.cpp b/examples/chef/common/clusters/media-input/MediaInputManager.cpp new file mode 100644 index 00000000000000..f7e853cc46a40b --- /dev/null +++ b/examples/chef/common/clusters/media-input/MediaInputManager.cpp @@ -0,0 +1,102 @@ +/** + * + * Copyright (c) 2021 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#ifdef MATTER_DM_PLUGIN_MEDIA_INPUT_SERVER +#include "MediaInputManager.h" + +using namespace std; +using namespace chip; +using namespace chip::app::Clusters::MediaInput; + +MediaInputManager::MediaInputManager() +{ + struct InputData inputData1(1, chip::app::Clusters::MediaInput::InputTypeEnum::kHdmi, "HDMI 1", + "High-Definition Multimedia Interface"); + mInputs.push_back(inputData1); + struct InputData inputData2(2, chip::app::Clusters::MediaInput::InputTypeEnum::kHdmi, "HDMI 2", + "High-Definition Multimedia Interface"); + mInputs.push_back(inputData2); + struct InputData inputData3(3, chip::app::Clusters::MediaInput::InputTypeEnum::kHdmi, "HDMI 3", + "High-Definition Multimedia Interface"); + mInputs.push_back(inputData3); + + mCurrentInput = 1; +} + +CHIP_ERROR MediaInputManager::HandleGetInputList(chip::app::AttributeValueEncoder & aEncoder) +{ + return aEncoder.EncodeList([this](const auto & encoder) -> CHIP_ERROR { + for (auto const & inputData : this->mInputs) + { + ReturnErrorOnFailure(encoder.Encode(inputData.GetEncodable())); + } + return CHIP_NO_ERROR; + }); +} + +uint8_t MediaInputManager::HandleGetCurrentInput() +{ + return mCurrentInput; +} + +bool MediaInputManager::HandleSelectInput(const uint8_t index) +{ + for (auto const & inputData : mInputs) + { + if (inputData.index == index) + { + mCurrentInput = index; + return true; + } + } + + return false; +} + +bool MediaInputManager::HandleShowInputStatus() +{ + ChipLogProgress(Zcl, " MediaInputManager::HandleShowInputStatus()"); + for (auto const & inputData : mInputs) + { + ChipLogProgress(Zcl, " [%d] type=%d selected=%d name=%s desc=%s", inputData.index, + static_cast(inputData.inputType), (mCurrentInput == inputData.index ? 1 : 0), + inputData.name.c_str(), inputData.description.c_str()); + } + return true; +} + +bool MediaInputManager::HandleHideInputStatus() +{ + ChipLogProgress(Zcl, " MediaInputManager::HandleHideInputStatus()"); + return true; +} + +bool MediaInputManager::HandleRenameInput(const uint8_t index, const chip::CharSpan & newName) +{ + for (auto & inputData : mInputs) + { + if (inputData.index == index) + { + inputData.Rename(newName); + return true; + } + } + + return false; +} +#endif // MATTER_DM_PLUGIN_MEDIA_INPUT_SERVER diff --git a/examples/chef/common/clusters/media-input/MediaInputManager.h b/examples/chef/common/clusters/media-input/MediaInputManager.h new file mode 100644 index 00000000000000..104db65e2bbe97 --- /dev/null +++ b/examples/chef/common/clusters/media-input/MediaInputManager.h @@ -0,0 +1,68 @@ +/* + * + * Copyright (c) 2021 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include +#include +#include + +class MediaInputManager : public chip::app::Clusters::MediaInput::Delegate +{ + using InputInfoType = chip::app::Clusters::MediaInput::Structs::InputInfoStruct::Type; + +public: + MediaInputManager(); + + CHIP_ERROR HandleGetInputList(chip::app::AttributeValueEncoder & aEncoder) override; + uint8_t HandleGetCurrentInput() override; + bool HandleSelectInput(const uint8_t index) override; + bool HandleShowInputStatus() override; + bool HandleHideInputStatus() override; + bool HandleRenameInput(const uint8_t index, const chip::CharSpan & name) override; + + struct InputData + { + uint8_t index; + chip::app::Clusters::MediaInput::InputTypeEnum inputType; + std::string name; + std::string description; + + InputData(uint8_t i, chip::app::Clusters::MediaInput::InputTypeEnum t, const char * n, const char * d) : + index(i), inputType(t), name(n), description(d) + {} + + void Rename(const chip::CharSpan & newName) { name.assign(newName.data(), newName.size()); } + + InputInfoType GetEncodable() const + { + InputInfoType result; + result.index = index; + result.inputType = inputType; + result.name = chip::CharSpan::fromCharString(name.c_str()); + result.description = chip::CharSpan::fromCharString(description.c_str()); + return result; + } + }; + +protected: + uint8_t mCurrentInput; + std::vector mInputs; + +private: +}; diff --git a/examples/chef/common/clusters/media-playback/MediaPlaybackManager.cpp b/examples/chef/common/clusters/media-playback/MediaPlaybackManager.cpp new file mode 100644 index 00000000000000..512da2966d68b6 --- /dev/null +++ b/examples/chef/common/clusters/media-playback/MediaPlaybackManager.cpp @@ -0,0 +1,339 @@ +/** + * + * Copyright (c) 2021 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#ifdef MATTER_DM_PLUGIN_MEDIA_PLAYBACK_SERVER +#include "MediaPlaybackManager.h" +#include +#include + +using namespace std; +using namespace chip::app::DataModel; +using namespace chip::app::Clusters::MediaPlayback; +using namespace chip::Uint8; + +using chip::CharSpan; +using chip::app::AttributeValueEncoder; +using chip::app::CommandResponseHelper; + +PlaybackStateEnum MediaPlaybackManager::HandleGetCurrentState() +{ + return mCurrentState; +} + +uint64_t MediaPlaybackManager::HandleGetStartTime() +{ + return mStartTime; +} + +uint64_t MediaPlaybackManager::HandleGetDuration() +{ + return mDuration; +} + +CHIP_ERROR MediaPlaybackManager::HandleGetSampledPosition(AttributeValueEncoder & aEncoder) +{ + return aEncoder.Encode(mPlaybackPosition); +} + +float MediaPlaybackManager::HandleGetPlaybackSpeed() +{ + return mPlaybackSpeed; +} + +uint64_t MediaPlaybackManager::HandleGetSeekRangeStart() +{ + return mStartTime; +} + +uint64_t MediaPlaybackManager::HandleGetSeekRangeEnd() +{ + return mDuration; +} + +CHIP_ERROR MediaPlaybackManager::HandleGetActiveAudioTrack(AttributeValueEncoder & aEncoder) +{ + return aEncoder.Encode(mActiveAudioTrack); +} + +CHIP_ERROR MediaPlaybackManager::HandleGetAvailableAudioTracks(AttributeValueEncoder & aEncoder) +{ + return aEncoder.EncodeList([this](const auto & encoder) -> CHIP_ERROR { + for (auto const & audioTrack : mAvailableAudioTracks) + { + ReturnErrorOnFailure(encoder.Encode(audioTrack)); + } + return CHIP_NO_ERROR; + }); +} + +CHIP_ERROR MediaPlaybackManager::HandleGetActiveTextTrack(AttributeValueEncoder & aEncoder) +{ + return aEncoder.Encode(mActiveTextTrack); +} + +CHIP_ERROR MediaPlaybackManager::HandleGetAvailableTextTracks(AttributeValueEncoder & aEncoder) +{ + return aEncoder.EncodeList([this](const auto & encoder) -> CHIP_ERROR { + for (auto const & textTrack : mAvailableTextTracks) + { + ReturnErrorOnFailure(encoder.Encode(textTrack)); + } + return CHIP_NO_ERROR; + }); +} + +void MediaPlaybackManager::HandlePlay(CommandResponseHelper & helper) +{ + mCurrentState = PlaybackStateEnum::kPlaying; + mPlaybackSpeed = 1; + + Commands::PlaybackResponse::Type response; + response.data = chip::MakeOptional(CharSpan::fromCharString("data response")); + response.status = StatusEnum::kSuccess; + helper.Success(response); +} + +void MediaPlaybackManager::HandlePause(CommandResponseHelper & helper) +{ + mCurrentState = PlaybackStateEnum::kPaused; + mPlaybackSpeed = 0; + + Commands::PlaybackResponse::Type response; + response.data = chip::MakeOptional(CharSpan::fromCharString("data response")); + response.status = StatusEnum::kSuccess; + helper.Success(response); +} + +void MediaPlaybackManager::HandleStop(CommandResponseHelper & helper) +{ + mCurrentState = PlaybackStateEnum::kNotPlaying; + mPlaybackSpeed = 0; + mPlaybackPosition = { 0, chip::app::DataModel::Nullable(0) }; + + Commands::PlaybackResponse::Type response; + response.data = chip::MakeOptional(CharSpan::fromCharString("data response")); + response.status = StatusEnum::kSuccess; + helper.Success(response); +} + +void MediaPlaybackManager::HandleFastForward(CommandResponseHelper & helper, + const chip::Optional & audioAdvanceUnmuted) +{ + if (mPlaybackSpeed == kPlaybackMaxForwardSpeed) + { + // if already at max speed, return error + Commands::PlaybackResponse::Type response; + response.data = chip::MakeOptional(CharSpan::fromCharString("data response")); + response.status = StatusEnum::kSpeedOutOfRange; + helper.Success(response); + return; + } + + mCurrentState = PlaybackStateEnum::kPlaying; + mPlaybackSpeed = (mPlaybackSpeed <= 0 ? 1 : mPlaybackSpeed * 2); + if (mPlaybackSpeed > kPlaybackMaxForwardSpeed) + { + // don't exceed max speed + mPlaybackSpeed = kPlaybackMaxForwardSpeed; + } + + Commands::PlaybackResponse::Type response; + response.data = chip::MakeOptional(CharSpan::fromCharString("data response")); + response.status = StatusEnum::kSuccess; + helper.Success(response); +} + +void MediaPlaybackManager::HandlePrevious(CommandResponseHelper & helper) +{ + mCurrentState = PlaybackStateEnum::kPlaying; + mPlaybackSpeed = 1; + mPlaybackPosition = { 0, chip::app::DataModel::Nullable(0) }; + + Commands::PlaybackResponse::Type response; + response.data = chip::MakeOptional(CharSpan::fromCharString("data response")); + response.status = StatusEnum::kSuccess; + helper.Success(response); +} + +void MediaPlaybackManager::HandleRewind(CommandResponseHelper & helper, + const chip::Optional & audioAdvanceUnmuted) +{ + if (mPlaybackSpeed == kPlaybackMaxRewindSpeed) + { + // if already at max speed in reverse, return error + Commands::PlaybackResponse::Type response; + response.data = chip::MakeOptional(CharSpan::fromCharString("data response")); + response.status = StatusEnum::kSpeedOutOfRange; + helper.Success(response); + return; + } + + mCurrentState = PlaybackStateEnum::kPlaying; + mPlaybackSpeed = (mPlaybackSpeed >= 0 ? -1 : mPlaybackSpeed * 2); + if (mPlaybackSpeed < kPlaybackMaxRewindSpeed) + { + // don't exceed max rewind speed + mPlaybackSpeed = kPlaybackMaxRewindSpeed; + } + + Commands::PlaybackResponse::Type response; + response.data = chip::MakeOptional(CharSpan::fromCharString("data response")); + response.status = StatusEnum::kSuccess; + helper.Success(response); +} + +void MediaPlaybackManager::HandleSkipBackward(CommandResponseHelper & helper, + const uint64_t & deltaPositionMilliseconds) +{ + uint64_t newPosition = (mPlaybackPosition.position.Value() > deltaPositionMilliseconds + ? mPlaybackPosition.position.Value() - deltaPositionMilliseconds + : 0); + mPlaybackPosition = { 0, chip::app::DataModel::Nullable(newPosition) }; + + Commands::PlaybackResponse::Type response; + response.data = chip::MakeOptional(CharSpan::fromCharString("data response")); + response.status = StatusEnum::kSuccess; + helper.Success(response); +} + +void MediaPlaybackManager::HandleSkipForward(CommandResponseHelper & helper, + const uint64_t & deltaPositionMilliseconds) +{ + uint64_t newPosition = mPlaybackPosition.position.Value() + deltaPositionMilliseconds; + newPosition = newPosition > mDuration ? mDuration : newPosition; + mPlaybackPosition = { 0, chip::app::DataModel::Nullable(newPosition) }; + + Commands::PlaybackResponse::Type response; + response.data = chip::MakeOptional(CharSpan::fromCharString("data response")); + response.status = StatusEnum::kSuccess; + helper.Success(response); +} + +void MediaPlaybackManager::HandleSeek(CommandResponseHelper & helper, + const uint64_t & positionMilliseconds) +{ + if (positionMilliseconds > mDuration) + { + Commands::PlaybackResponse::Type response; + response.data = chip::MakeOptional(CharSpan::fromCharString("data response")); + response.status = StatusEnum::kSeekOutOfRange; + helper.Success(response); + } + else + { + mPlaybackPosition = { 0, chip::app::DataModel::Nullable(positionMilliseconds) }; + + Commands::PlaybackResponse::Type response; + response.data = chip::MakeOptional(CharSpan::fromCharString("data response")); + response.status = StatusEnum::kSuccess; + helper.Success(response); + } +} + +void MediaPlaybackManager::HandleNext(CommandResponseHelper & helper) +{ + mCurrentState = PlaybackStateEnum::kPlaying; + mPlaybackSpeed = 1; + mPlaybackPosition = { 0, chip::app::DataModel::Nullable(0) }; + + Commands::PlaybackResponse::Type response; + response.data = chip::MakeOptional(CharSpan::fromCharString("data response")); + response.status = StatusEnum::kSuccess; + helper.Success(response); +} + +void MediaPlaybackManager::HandleStartOver(CommandResponseHelper & helper) +{ + mPlaybackPosition = { 0, chip::app::DataModel::Nullable(0) }; + + Commands::PlaybackResponse::Type response; + response.data = chip::MakeOptional(CharSpan::fromCharString("data response")); + response.status = StatusEnum::kSuccess; + helper.Success(response); +} + +bool MediaPlaybackManager::HandleActivateAudioTrack(const chip::CharSpan & trackId, const uint8_t & audioOutputIndex) +{ + std::string idString(trackId.data(), trackId.size()); + for (auto const & availableAudioTrack : mAvailableAudioTracks) + { + std::string nextIdString(availableAudioTrack.id.data(), availableAudioTrack.id.size()); + if (nextIdString == idString) + { + mActiveAudioTrack = availableAudioTrack; + return true; + } + } + return false; +} + +bool MediaPlaybackManager::HandleActivateTextTrack(const chip::CharSpan & trackId) +{ + std::string idString(trackId.data(), trackId.size()); + for (auto const & availableTextTrack : mAvailableTextTracks) + { + std::string nextIdString(availableTextTrack.id.data(), availableTextTrack.id.size()); + if (nextIdString == idString) + { + mActiveTextTrack = availableTextTrack; + return true; + } + } + return false; +} + +bool MediaPlaybackManager::HandleDeactivateTextTrack() +{ + // Handle Deactivate Text Track + if (mActiveTextTrack.id.data() != nullptr) + { + mActiveTextTrack = {}; + } + return true; +} + +uint32_t MediaPlaybackManager::GetFeatureMap(chip::EndpointId endpoint) +{ + if (endpoint >= MATTER_DM_MEDIA_PLAYBACK_CLUSTER_SERVER_ENDPOINT_COUNT) + { + return mDynamicEndpointFeatureMap; + } + + uint32_t featureMap = 0; + Attributes::FeatureMap::Get(endpoint, &featureMap); + return featureMap; +} + +uint16_t MediaPlaybackManager::GetClusterRevision(chip::EndpointId endpoint) +{ + if (endpoint >= MATTER_DM_MEDIA_PLAYBACK_CLUSTER_SERVER_ENDPOINT_COUNT) + { + return kClusterRevision; + } + + uint16_t clusterRevision = 0; + bool success = + (Attributes::ClusterRevision::Get(endpoint, &clusterRevision) == chip::Protocols::InteractionModel::Status::Success); + if (!success) + { + ChipLogError(Zcl, "MediaPlaybackManager::GetClusterRevision error reading cluster revision"); + } + return clusterRevision; +} + +#endif /// MATTER_DM_PLUGIN_MEDIA_PLAYBACK_SERVER diff --git a/examples/chef/common/clusters/media-playback/MediaPlaybackManager.h b/examples/chef/common/clusters/media-playback/MediaPlaybackManager.h new file mode 100644 index 00000000000000..79bca10a3c8fb6 --- /dev/null +++ b/examples/chef/common/clusters/media-playback/MediaPlaybackManager.h @@ -0,0 +1,117 @@ +/* + * + * Copyright (c) 2021 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include +#include + +class MediaPlaybackManager : public chip::app::Clusters::MediaPlayback::Delegate +{ + using PlaybackResponseType = chip::app::Clusters::MediaPlayback::Commands::PlaybackResponse::Type; + using PlaybackPositionType = chip::app::Clusters::MediaPlayback::Structs::PlaybackPositionStruct::Type; + using TrackType = chip::app::Clusters::MediaPlayback::Structs::TrackStruct::Type; + using TrackAttributesType = chip::app::Clusters::MediaPlayback::Structs::TrackAttributesStruct::Type; + using Feature = chip::app::Clusters::MediaPlayback::Feature; + +public: + chip::app::Clusters::MediaPlayback::PlaybackStateEnum HandleGetCurrentState() override; + uint64_t HandleGetStartTime() override; + uint64_t HandleGetDuration() override; + CHIP_ERROR HandleGetSampledPosition(chip::app::AttributeValueEncoder & aEncoder) override; + float HandleGetPlaybackSpeed() override; + uint64_t HandleGetSeekRangeStart() override; + uint64_t HandleGetSeekRangeEnd() override; + CHIP_ERROR HandleGetActiveAudioTrack(chip::app::AttributeValueEncoder & aEncoder) override; + CHIP_ERROR HandleGetAvailableAudioTracks(chip::app::AttributeValueEncoder & aEncoder) override; + CHIP_ERROR HandleGetActiveTextTrack(chip::app::AttributeValueEncoder & aEncoder) override; + CHIP_ERROR HandleGetAvailableTextTracks(chip::app::AttributeValueEncoder & aEncoder) override; + + void HandlePlay(chip::app::CommandResponseHelper & helper) override; + void HandlePause(chip::app::CommandResponseHelper & helper) override; + void HandleStop(chip::app::CommandResponseHelper & helper) override; + void HandleFastForward(chip::app::CommandResponseHelper & helper, + const chip::Optional & audioAdvanceUnmuted) override; + void HandlePrevious(chip::app::CommandResponseHelper & helper) override; + void HandleRewind(chip::app::CommandResponseHelper & helper, + const chip::Optional & audioAdvanceUnmuted) override; + void HandleSkipBackward(chip::app::CommandResponseHelper & helper, + const uint64_t & deltaPositionMilliseconds) override; + void HandleSkipForward(chip::app::CommandResponseHelper & helper, + const uint64_t & deltaPositionMilliseconds) override; + void HandleSeek(chip::app::CommandResponseHelper & helper, + const uint64_t & positionMilliseconds) override; + void HandleNext(chip::app::CommandResponseHelper & helper) override; + void HandleStartOver(chip::app::CommandResponseHelper & helper) override; + bool HandleActivateAudioTrack(const chip::CharSpan & trackId, const uint8_t & audioOutputIndex) override; + bool HandleActivateTextTrack(const chip::CharSpan & trackId) override; + bool HandleDeactivateTextTrack() override; + + uint32_t GetFeatureMap(chip::EndpointId endpoint) override; + uint16_t GetClusterRevision(chip::EndpointId endpoint) override; + +protected: + // NOTE: it does not make sense to have default state of playing with a speed of 0, but + // the CI test cases expect these values, and need to be fixed. + chip::app::Clusters::MediaPlayback::PlaybackStateEnum mCurrentState = + chip::app::Clusters::MediaPlayback::PlaybackStateEnum::kPlaying; + PlaybackPositionType mPlaybackPosition = { 0, chip::app::DataModel::Nullable(0) }; + TrackType mActiveAudioTrack = { chip::CharSpan("activeAudioTrackId_0", 20), + chip::app::DataModel::Nullable( + { chip::CharSpan("languageCode1", 13), + chip::Optional>( + { chip::app::DataModel::MakeNullable(chip::CharSpan("displayName1", 12)) }) }) }; + std::vector mAvailableAudioTracks = { + { chip::CharSpan("activeAudioTrackId_0", 20), + chip::app::DataModel::Nullable( + { chip::CharSpan("languageCode1", 13), + chip::Optional>( + { chip::app::DataModel::MakeNullable(chip::CharSpan("displayName1", 12)) }) }) }, + { chip::CharSpan("activeAudioTrackId_1", 20), + chip::app::DataModel::Nullable( + { chip::CharSpan("languageCode2", 13), + chip::Optional>( + { chip::app::DataModel::MakeNullable(chip::CharSpan("displayName2", 12)) }) }) } + }; + TrackType mActiveTextTrack = {}; + std::vector mAvailableTextTracks = { + { chip::CharSpan("activeTextTrackId_0", 19), + chip::app::DataModel::Nullable( + { chip::CharSpan("languageCode1", 13), + chip::Optional>( + { chip::app::DataModel::MakeNullable(chip::CharSpan("displayName1", 12)) }) }) }, + { chip::CharSpan("activeTextTrackId_1", 19), + chip::app::DataModel::Nullable( + { chip::CharSpan("languageCode2", 13), + chip::Optional>( + { chip::app::DataModel::MakeNullable(chip::CharSpan("displayName2", 12)) }) }) } + }; + float mPlaybackSpeed = 1.0; + uint64_t mStartTime = 0; + // Magic number for testing. + uint64_t mDuration = 80000; + bool mAudioAdvanceMuted = false; + + static const int kPlaybackMaxForwardSpeed = 10; + static const int kPlaybackMaxRewindSpeed = -10; + +private: + static constexpr uint32_t mDynamicEndpointFeatureMap = + chip::BitMask(Feature::kAdvancedSeek, Feature::kVariableSpeed).Raw(); + static constexpr uint16_t kClusterRevision = 2; +}; diff --git a/examples/chef/common/clusters/target-navigator/TargetNavigatorManager.cpp b/examples/chef/common/clusters/target-navigator/TargetNavigatorManager.cpp new file mode 100644 index 00000000000000..17acf11b39bf23 --- /dev/null +++ b/examples/chef/common/clusters/target-navigator/TargetNavigatorManager.cpp @@ -0,0 +1,94 @@ +/** + * + * Copyright (c) 2021 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#ifdef MATTER_DM_PLUGIN_TARGET_NAVIGATOR_SERVER +#include "TargetNavigatorManager.h" +#include + +using namespace std; +using namespace chip::app; +using namespace chip::app::Clusters::TargetNavigator; + +using chip::CharSpan; +using chip::app::AttributeValueEncoder; +using chip::app::CommandResponseHelper; + +TargetNavigatorManager::TargetNavigatorManager(std::list targets, uint8_t currentTarget) +{ + mTargets = targets; + mCurrentTarget = currentTarget; +} + +CHIP_ERROR TargetNavigatorManager::HandleGetTargetList(AttributeValueEncoder & aEncoder) +{ + // NOTE: the ids for each target start at 1 so that we can reserve 0 as "no current target" + return aEncoder.EncodeList([this](const auto & encoder) -> CHIP_ERROR { + int i = 0; + for (std::string & entry : mTargets) + { + Structs::TargetInfoStruct::Type outputInfo; + outputInfo.identifier = static_cast(i + 1); + outputInfo.name = CharSpan::fromCharString(entry.c_str()); + ReturnErrorOnFailure(encoder.Encode(outputInfo)); + i++; + } + return CHIP_NO_ERROR; + }); +} + +uint8_t TargetNavigatorManager::HandleGetCurrentTarget() +{ + return mCurrentTarget; +} + +void TargetNavigatorManager::HandleNavigateTarget(CommandResponseHelper & helper, + const uint64_t & target, const CharSpan & data) +{ + NavigateTargetResponseType response; + if (target == kNoCurrentTarget || target > mTargets.size()) + { + response.data = chip::MakeOptional(CharSpan::fromCharString("error")); + response.status = StatusEnum::kTargetNotFound; + helper.Success(response); + return; + } + mCurrentTarget = static_cast(target); + + response.data = chip::MakeOptional(CharSpan::fromCharString("data response")); + response.status = StatusEnum::kSuccess; + helper.Success(response); +} + +uint16_t TargetNavigatorManager::GetClusterRevision(chip::EndpointId endpoint) +{ + if (endpoint >= MATTER_DM_TARGET_NAVIGATOR_CLUSTER_SERVER_ENDPOINT_COUNT) + { + return kClusterRevision; + } + + uint16_t clusterRevision = 0; + bool success = + (Attributes::ClusterRevision::Get(endpoint, &clusterRevision) == chip::Protocols::InteractionModel::Status::Success); + if (!success) + { + ChipLogError(Zcl, "TargetNavigatorManager::GetClusterRevision error reading cluster revision"); + } + + return clusterRevision; +} +#endif // MATTER_DM_PLUGIN_TARGET_NAVIGATOR_SERVER diff --git a/examples/chef/common/clusters/target-navigator/TargetNavigatorManager.h b/examples/chef/common/clusters/target-navigator/TargetNavigatorManager.h new file mode 100644 index 00000000000000..21a08b9595cd82 --- /dev/null +++ b/examples/chef/common/clusters/target-navigator/TargetNavigatorManager.h @@ -0,0 +1,45 @@ +/** + * + * Copyright (c) 2021 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include + +class TargetNavigatorManager : public chip::app::Clusters::TargetNavigator::Delegate +{ + using TargetInfoType = chip::app::Clusters::TargetNavigator::Structs::TargetInfoStruct::Type; + using NavigateTargetResponseType = chip::app::Clusters::TargetNavigator::Commands::NavigateTargetResponse::Type; + +public: + TargetNavigatorManager() : TargetNavigatorManager({ "exampleName", "exampleName" }, kNoCurrentTarget){}; + TargetNavigatorManager(std::list targets, uint8_t currentTarget); + + CHIP_ERROR HandleGetTargetList(chip::app::AttributeValueEncoder & aEncoder) override; + uint8_t HandleGetCurrentTarget() override; + void HandleNavigateTarget(chip::app::CommandResponseHelper & responser, const uint64_t & target, + const chip::CharSpan & data) override; + uint16_t GetClusterRevision(chip::EndpointId endpoint) override; + +protected: + // NOTE: the ids for each target start at 1 so that we can reserve 0 as "no current target" + static const uint8_t kNoCurrentTarget = 0; + std::list mTargets; + uint8_t mCurrentTarget; + +private: + static constexpr uint16_t kClusterRevision = 2; +}; diff --git a/examples/chef/common/clusters/wake-on-lan/WakeOnLanManager.cpp b/examples/chef/common/clusters/wake-on-lan/WakeOnLanManager.cpp new file mode 100644 index 00000000000000..5f4e2e1ec7b6e2 --- /dev/null +++ b/examples/chef/common/clusters/wake-on-lan/WakeOnLanManager.cpp @@ -0,0 +1,68 @@ +/* + * + * Copyright (c) 2021 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#ifdef MATTER_DM_PLUGIN_WAKE_ON_LAN_SERVER +#include "WakeOnLanManager.h" +#include +#include +#include +#include +#include + +constexpr char kNullHexMACAddress[] = "000000000000"; + +using namespace chip; +using namespace chip::app::Clusters::WakeOnLan; + +std::string getMacAddress() +{ + uint8_t macBuffer[chip::DeviceLayer::ConfigurationManager::kPrimaryMACAddressLength]; + MutableByteSpan mac(macBuffer); + if (chip::DeviceLayer::ConfigurationMgr().GetPrimaryMACAddress(mac) != CHIP_NO_ERROR) + { + ChipLogProgress(Zcl, "WakeOnLanManager::getMacAddress no primary MAC configured by DeviceLayer"); + return kNullHexMACAddress; + } + + char macStr[chip::DeviceLayer::ConfigurationManager::kPrimaryMACAddressLength * 2 + 1] = { 0 }; // added null char + if (BytesToHex(&macBuffer[0], sizeof(macBuffer), &macStr[0], sizeof(macBuffer) * 2u, chip::Encoding::HexFlags::kUppercase) != + CHIP_NO_ERROR) + { + ChipLogProgress(Zcl, "WakeOnLanManager::getMacAddress hex conversion failed"); + return kNullHexMACAddress; + } + + return std::string(macStr); +} + +CHIP_ERROR WakeOnLanManager::HandleGetMacAddress(chip::app::AttributeValueEncoder & aEncoder) +{ + ChipLogProgress(Zcl, "WakeOnLanManager::HandleGetMacAddress"); + + // Spec REQUIRES 48-bit mac addresses. This means at least Thread devices will + // fail here. + if (chip::DeviceLayer::ConfigurationManager::kPrimaryMACAddressLength != 6) + { + ChipLogError(Zcl, "WakeOnLanManager: primary MAC address is not 48-bit"); + return CHIP_ERROR_BUFFER_TOO_SMALL; + } + + return aEncoder.Encode(CharSpan::fromCharString(getMacAddress().c_str())); +} +#endif // MATTER_DM_PLUGIN_WAKE_ON_LAN_SERVER diff --git a/examples/chef/common/clusters/wake-on-lan/WakeOnLanManager.h b/examples/chef/common/clusters/wake-on-lan/WakeOnLanManager.h new file mode 100644 index 00000000000000..63217020e9ab11 --- /dev/null +++ b/examples/chef/common/clusters/wake-on-lan/WakeOnLanManager.h @@ -0,0 +1,27 @@ +/* + * + * Copyright (c) 2021 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include + +class WakeOnLanManager : public chip::app::Clusters::WakeOnLan::Delegate +{ +public: + CHIP_ERROR HandleGetMacAddress(chip::app::AttributeValueEncoder & aEncoder) override; +}; diff --git a/examples/chef/common/stubs.cpp b/examples/chef/common/stubs.cpp index cff7ffdee4679f..48c48620c98fb0 100644 --- a/examples/chef/common/stubs.cpp +++ b/examples/chef/common/stubs.cpp @@ -22,6 +22,8 @@ using chip::app::DataModel::Nullable; using namespace chip; +using namespace chip::app; +using namespace chip::app::Clusters; Protocols::InteractionModel::Status emberAfExternalAttributeReadCallback(EndpointId endpoint, ClusterId clusterId, const EmberAfAttributeMetadata * attributeMetadata, @@ -341,14 +343,127 @@ bool emberAfPluginDoorLockSetCredential(chip::EndpointId endpointId, uint16_t cr #endif /* MATTER_DM_PLUGIN_DOOR_LOCK_SERVER */ +void emberAfPluginSmokeCoAlarmSelfTestRequestCommand(EndpointId endpointId) {} + +void MatterPostAttributeChangeCallback(const chip::app::ConcreteAttributePath & attributePath, uint8_t type, uint16_t size, + uint8_t * value) +{ + ClusterId clusterId = attributePath.mClusterId; + AttributeId attributeId = attributePath.mAttributeId; + ChipLogProgress(Zcl, "Cluster callback: " ChipLogFormatMEI, ChipLogValueMEI(clusterId)); + + if (clusterId == OnOff::Id && attributeId == OnOff::Attributes::OnOff::Id) + { + ChipLogProgress(Zcl, "OnOff attribute ID: " ChipLogFormatMEI " Type: %u Value: %u, length %u", ChipLogValueMEI(attributeId), + type, *value, size); + } + else if (clusterId == LevelControl::Id) + { + ChipLogProgress(Zcl, "Level Control attribute ID: " ChipLogFormatMEI " Type: %u Value: %u, length %u", + ChipLogValueMEI(attributeId), type, *value, size); + + // WIP Apply attribute change to Light + } +} + +/** @brief OnOff Cluster Init + * + * This function is called when a specific cluster is initialized. It gives the + * application an opportunity to take care of cluster initialization procedures. + * It is called exactly once for each endpoint where cluster is present. + * + * TODO Issue #3841 + * emberAfOnOffClusterInitCallback happens before the stack initialize the cluster + * attributes to the default value. + * The logic here expects something similar to the deprecated Plugins callback + * emberAfPluginOnOffClusterServerPostInitCallback. + * + */ +void emberAfOnOffClusterInitCallback(EndpointId endpoint) {} + +#ifdef MATTER_DM_PLUGIN_AUDIO_OUTPUT_SERVER +#include "audio-output/AudioOutputManager.h" +static AudioOutputManager audioOutputManager; + +void emberAfAudioOutputClusterInitCallback(EndpointId endpoint) +{ + ChipLogProgress(Zcl, "TV Linux App: AudioOutput::SetDefaultDelegate"); + AudioOutput::SetDefaultDelegate(endpoint, &audioOutputManager); +} +#endif + #ifdef MATTER_DM_PLUGIN_CHANNEL_SERVER -#include +#include "channel/ChannelManager.h" +static ChannelManager channelManager; void emberAfChannelClusterInitCallback(EndpointId endpoint) { - app::Clusters::Channel::SetDefaultDelegate(endpoint, - static_cast(&(ChefChannelManager::Instance()))); + ChipLogProgress(Zcl, "TV Linux App: Channel::SetDefaultDelegate"); + Channel::SetDefaultDelegate(endpoint, &channelManager); } -#endif // MATTER_DM_PLUGIN_CHANNEL_SERVER +#endif -void emberAfPluginSmokeCoAlarmSelfTestRequestCommand(EndpointId endpointId) {} +#ifdef MATTER_DM_PLUGIN_KEYPAD_INPUT_SERVER +#include "keypad-input/KeypadInputManager.h" +static KeypadInputManager keypadInputManager; + +void emberAfKeypadInputClusterInitCallback(EndpointId endpoint) +{ + ChipLogProgress(Zcl, "TV Linux App: KeypadInput::SetDefaultDelegate"); + KeypadInput::SetDefaultDelegate(endpoint, &keypadInputManager); +} +#endif + +#ifdef MATTER_DM_PLUGIN_LOW_POWER_SERVER +#include "low-power/LowPowerManager.h" +static LowPowerManager lowPowerManager; + +void emberAfLowPowerClusterInitCallback(EndpointId endpoint) +{ + ChipLogProgress(Zcl, "TV Linux App: LowPower::SetDefaultDelegate"); + LowPower::SetDefaultDelegate(endpoint, &lowPowerManager); +} +#endif + +#ifdef MATTER_DM_PLUGIN_MEDIA_INPUT_SERVER +#include "media-input/MediaInputManager.h" +static MediaInputManager mediaInputManager; +void emberAfMediaInputClusterInitCallback(EndpointId endpoint) +{ + ChipLogProgress(Zcl, "TV Linux App: MediaInput::SetDefaultDelegate"); + MediaInput::SetDefaultDelegate(endpoint, &mediaInputManager); +} +#endif + +#ifdef MATTER_DM_PLUGIN_MEDIA_PLAYBACK_SERVER +#include "media-playback/MediaPlaybackManager.h" +static MediaPlaybackManager mediaPlaybackManager; + +void emberAfMediaPlaybackClusterInitCallback(EndpointId endpoint) +{ + ChipLogProgress(Zcl, "TV Linux App: MediaPlayback::SetDefaultDelegate"); + MediaPlayback::SetDefaultDelegate(endpoint, &mediaPlaybackManager); +} +#endif + +#ifdef MATTER_DM_PLUGIN_TARGET_NAVIGATOR_SERVER +#include "target-navigator/TargetNavigatorManager.h" +static TargetNavigatorManager targetNavigatorManager; + +void emberAfTargetNavigatorClusterInitCallback(EndpointId endpoint) +{ + ChipLogProgress(Zcl, "TV Linux App: TargetNavigator::SetDefaultDelegate"); + TargetNavigator::SetDefaultDelegate(endpoint, &targetNavigatorManager); +} +#endif + +#ifdef MATTER_DM_PLUGIN_WAKE_ON_LAN_SERVER +#include "wake-on-lan/WakeOnLanManager.h" +static WakeOnLanManager wakeOnLanManager; + +void emberAfWakeOnLanClusterInitCallback(EndpointId endpoint) +{ + ChipLogProgress(Zcl, "TV Linux App: WakeOnLanManager::SetDefaultDelegate"); + WakeOnLan::SetDefaultDelegate(endpoint, &wakeOnLanManager); +} +#endif diff --git a/examples/chef/devices/rootnode_basicvideoplayer_0ff86e943b.matter b/examples/chef/devices/rootnode_basicvideoplayer_0ff86e943b.matter index c5c71d597ebe74..d8fb307e9d8579 100644 --- a/examples/chef/devices/rootnode_basicvideoplayer_0ff86e943b.matter +++ b/examples/chef/devices/rootnode_basicvideoplayer_0ff86e943b.matter @@ -1,6 +1,56 @@ // This IDL was generated automatically by ZAP. // It is for view/code review purposes only. +/** Attributes and commands for putting a device into Identification mode (e.g. flashing a light). */ +cluster Identify = 3 { + revision 4; + + enum EffectIdentifierEnum : enum8 { + kBlink = 0; + kBreathe = 1; + kOkay = 2; + kChannelChange = 11; + kFinishEffect = 254; + kStopEffect = 255; + } + + enum EffectVariantEnum : enum8 { + kDefault = 0; + } + + enum IdentifyTypeEnum : enum8 { + kNone = 0; + kLightOutput = 1; + kVisibleIndicator = 2; + kAudibleBeep = 3; + kDisplay = 4; + kActuator = 5; + } + + attribute int16u identifyTime = 0; + readonly attribute IdentifyTypeEnum identifyType = 1; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + request struct IdentifyRequest { + int16u identifyTime = 0; + } + + request struct TriggerEffectRequest { + EffectIdentifierEnum effectIdentifier = 0; + EffectVariantEnum effectVariant = 1; + } + + /** Command description for Identify */ + command access(invoke: manage) Identify(IdentifyRequest): DefaultSuccess = 0; + /** Command description for TriggerEffect */ + command access(invoke: manage) TriggerEffect(TriggerEffectRequest): DefaultSuccess = 64; +} + /** Attributes and commands for switching devices between 'On' and 'Off' states. */ cluster OnOff = 6 { revision 6; @@ -73,6 +123,131 @@ cluster OnOff = 6 { command OnWithTimedOff(OnWithTimedOffRequest): DefaultSuccess = 66; } +/** Attributes and commands for controlling devices that can be set to a level between fully 'On' and fully 'Off.' */ +cluster LevelControl = 8 { + revision 5; + + enum MoveModeEnum : enum8 { + kUp = 0; + kDown = 1; + } + + enum StepModeEnum : enum8 { + kUp = 0; + kDown = 1; + } + + bitmap Feature : bitmap32 { + kOnOff = 0x1; + kLighting = 0x2; + kFrequency = 0x4; + } + + bitmap OptionsBitmap : bitmap8 { + kExecuteIfOff = 0x1; + kCoupleColorTempToLevel = 0x2; + } + + readonly attribute nullable int8u currentLevel = 0; + readonly attribute optional int16u remainingTime = 1; + readonly attribute optional int8u minLevel = 2; + readonly attribute optional int8u maxLevel = 3; + readonly attribute optional int16u currentFrequency = 4; + readonly attribute optional int16u minFrequency = 5; + readonly attribute optional int16u maxFrequency = 6; + attribute OptionsBitmap options = 15; + attribute optional int16u onOffTransitionTime = 16; + attribute nullable int8u onLevel = 17; + attribute optional nullable int16u onTransitionTime = 18; + attribute optional nullable int16u offTransitionTime = 19; + attribute optional nullable int8u defaultMoveRate = 20; + attribute access(write: manage) optional nullable int8u startUpCurrentLevel = 16384; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + request struct MoveToLevelRequest { + int8u level = 0; + nullable int16u transitionTime = 1; + OptionsBitmap optionsMask = 2; + OptionsBitmap optionsOverride = 3; + } + + request struct MoveRequest { + MoveModeEnum moveMode = 0; + nullable int8u rate = 1; + OptionsBitmap optionsMask = 2; + OptionsBitmap optionsOverride = 3; + } + + request struct StepRequest { + StepModeEnum stepMode = 0; + int8u stepSize = 1; + nullable int16u transitionTime = 2; + OptionsBitmap optionsMask = 3; + OptionsBitmap optionsOverride = 4; + } + + request struct StopRequest { + OptionsBitmap optionsMask = 0; + OptionsBitmap optionsOverride = 1; + } + + request struct MoveToLevelWithOnOffRequest { + int8u level = 0; + nullable int16u transitionTime = 1; + OptionsBitmap optionsMask = 2; + OptionsBitmap optionsOverride = 3; + } + + request struct MoveWithOnOffRequest { + MoveModeEnum moveMode = 0; + nullable int8u rate = 1; + OptionsBitmap optionsMask = 2; + OptionsBitmap optionsOverride = 3; + } + + request struct StepWithOnOffRequest { + StepModeEnum stepMode = 0; + int8u stepSize = 1; + nullable int16u transitionTime = 2; + OptionsBitmap optionsMask = 3; + OptionsBitmap optionsOverride = 4; + } + + request struct StopWithOnOffRequest { + OptionsBitmap optionsMask = 0; + OptionsBitmap optionsOverride = 1; + } + + request struct MoveToClosestFrequencyRequest { + int16u frequency = 0; + } + + /** Command description for MoveToLevel */ + command MoveToLevel(MoveToLevelRequest): DefaultSuccess = 0; + /** Command description for Move */ + command Move(MoveRequest): DefaultSuccess = 1; + /** Command description for Step */ + command Step(StepRequest): DefaultSuccess = 2; + /** Command description for Stop */ + command Stop(StopRequest): DefaultSuccess = 3; + /** Command description for MoveToLevelWithOnOff */ + command MoveToLevelWithOnOff(MoveToLevelWithOnOffRequest): DefaultSuccess = 4; + /** Command description for MoveWithOnOff */ + command MoveWithOnOff(MoveWithOnOffRequest): DefaultSuccess = 5; + /** Command description for StepWithOnOff */ + command StepWithOnOff(StepWithOnOffRequest): DefaultSuccess = 6; + /** Command description for StopWithOnOff */ + command StopWithOnOff(StopWithOnOffRequest): DefaultSuccess = 7; + /** Change the currrent frequency to the provided one, or a close + approximation if the exact provided one is not possible. */ + command MoveToClosestFrequency(MoveToClosestFrequencyRequest): DefaultSuccess = 8; +} + /** The Descriptor Cluster is meant to replace the support from the Zigbee Device Object (ZDO) for describing a node, its endpoints and clusters. */ cluster Descriptor = 29 { revision 2; @@ -449,50 +624,6 @@ cluster LocalizationConfiguration = 43 { readonly attribute int16u clusterRevision = 65533; } -/** Nodes should be expected to be deployed to any and all regions of the world. These global regions - may have differing preferences for how dates and times are conveyed. As such, Nodes that visually - or audibly convey time information need a mechanism by which they can be configured to use a - user’s preferred format. */ -cluster TimeFormatLocalization = 44 { - revision 1; // NOTE: Default/not specifically set - - enum CalendarTypeEnum : enum8 { - kBuddhist = 0; - kChinese = 1; - kCoptic = 2; - kEthiopian = 3; - kGregorian = 4; - kHebrew = 5; - kIndian = 6; - kIslamic = 7; - kJapanese = 8; - kKorean = 9; - kPersian = 10; - kTaiwanese = 11; - kUseActiveLocale = 255; - } - - enum HourFormatEnum : enum8 { - k12hr = 0; - k24hr = 1; - kUseActiveLocale = 255; - } - - bitmap Feature : bitmap32 { - kCalendarFormat = 0x1; - } - - attribute access(write: manage) HourFormatEnum hourFormat = 0; - attribute access(write: manage) optional CalendarTypeEnum activeCalendarType = 1; - readonly attribute optional CalendarTypeEnum supportedCalendarTypes[] = 2; - readonly attribute command_id generatedCommandList[] = 65528; - readonly attribute command_id acceptedCommandList[] = 65529; - readonly attribute event_id eventList[] = 65530; - readonly attribute attrib_id attributeList[] = 65531; - readonly attribute bitmap32 featureMap = 65532; - readonly attribute int16u clusterRevision = 65533; -} - /** This cluster is used to manage global aspects of the Commissioning flow. */ cluster GeneralCommissioning = 48 { revision 1; // NOTE: Default/not specifically set @@ -1942,14 +2073,6 @@ endpoint 0 { ram attribute clusterRevision default = 1; } - server cluster TimeFormatLocalization { - persist attribute hourFormat default = 0; - persist attribute activeCalendarType default = 0; - callback attribute supportedCalendarTypes; - ram attribute featureMap default = 0; - ram attribute clusterRevision default = 1; - } - server cluster GeneralCommissioning { ram attribute breadcrumb default = 0x0000000000000000; callback attribute basicCommissioningInfo; @@ -2031,7 +2154,7 @@ endpoint 0 { callback attribute windowStatus; callback attribute adminFabricIndex; callback attribute adminVendorId; - ram attribute featureMap default = 0; + ram attribute featureMap default = 1; ram attribute clusterRevision default = 0x0001; handle command OpenCommissioningWindow; @@ -2096,7 +2219,7 @@ endpoint 1 { callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; - ram attribute clusterRevision default = 4; + ram attribute clusterRevision default = 6; handle command Off; handle command On; @@ -2117,6 +2240,7 @@ endpoint 1 { } server cluster WakeOnLan { + ram attribute MACAddress; callback attribute generatedCommandList; callback attribute acceptedCommandList; callback attribute eventList; @@ -2143,7 +2267,9 @@ endpoint 1 { } server cluster TargetNavigator { + emits event TargetUpdated; callback attribute targetList; + ram attribute currentTarget default = 0; callback attribute generatedCommandList; callback attribute acceptedCommandList; callback attribute eventList; @@ -2156,18 +2282,33 @@ endpoint 1 { } server cluster MediaPlayback { + emits event StateChanged; ram attribute currentState default = 0x00; + ram attribute startTime default = 0x00; + ram attribute duration default = 0; + callback attribute sampledPosition; + ram attribute playbackSpeed default = 0; + ram attribute seekRangeEnd; + ram attribute seekRangeStart; callback attribute generatedCommandList; callback attribute acceptedCommandList; callback attribute eventList; callback attribute attributeList; - ram attribute featureMap default = 0; + ram attribute featureMap default = 3; ram attribute clusterRevision default = 1; handle command Play; handle command Pause; handle command Stop; + handle command StartOver; + handle command Previous; + handle command Next; + handle command Rewind; + handle command FastForward; + handle command SkipForward; + handle command SkipBackward; handle command PlaybackResponse; + handle command Seek; } server cluster MediaInput { @@ -2177,12 +2318,13 @@ endpoint 1 { callback attribute acceptedCommandList; callback attribute eventList; callback attribute attributeList; - ram attribute featureMap default = 0; + ram attribute featureMap default = 1; ram attribute clusterRevision default = 1; handle command SelectInput; handle command ShowInputStatus; handle command HideInputStatus; + handle command RenameInput; } server cluster LowPower { @@ -2201,7 +2343,7 @@ endpoint 1 { callback attribute acceptedCommandList; callback attribute eventList; callback attribute attributeList; - ram attribute featureMap default = 0; + ram attribute featureMap default = 7; ram attribute clusterRevision default = 1; handle command SendKey; @@ -2215,10 +2357,79 @@ endpoint 1 { callback attribute acceptedCommandList; callback attribute eventList; callback attribute attributeList; - ram attribute featureMap default = 0; + ram attribute featureMap default = 1; ram attribute clusterRevision default = 1; handle command SelectOutput; + handle command RenameOutput; + } +} +endpoint 2 { + device type ma_speaker = 34, version 1; + + + server cluster Identify { + ram attribute identifyTime default = 0x0; + ram attribute identifyType default = 0x00; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; + ram attribute featureMap default = 0; + ram attribute clusterRevision default = 4; + + handle command Identify; + handle command TriggerEffect; + } + + server cluster OnOff { + ram attribute onOff default = 0; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; + ram attribute featureMap default = 0; + ram attribute clusterRevision default = 6; + + handle command Off; + handle command On; + handle command Toggle; + } + + server cluster LevelControl { + ram attribute currentLevel default = 0x00; + ram attribute minLevel default = 0x00; + ram attribute maxLevel default = 0xFE; + ram attribute options default = 0x00; + ram attribute onLevel default = 0xFE; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; + ram attribute featureMap default = 0; + ram attribute clusterRevision default = 5; + + handle command MoveToLevel; + handle command Move; + handle command Step; + handle command Stop; + handle command MoveToLevelWithOnOff; + handle command MoveWithOnOff; + handle command StepWithOnOff; + handle command StopWithOnOff; + } + + server cluster Descriptor { + callback attribute deviceTypeList; + callback attribute serverList; + callback attribute clientList; + callback attribute partsList; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; + callback attribute featureMap; + callback attribute clusterRevision; } } diff --git a/examples/chef/devices/rootnode_basicvideoplayer_0ff86e943b.zap b/examples/chef/devices/rootnode_basicvideoplayer_0ff86e943b.zap index 245f7ee38016e5..92cb592ebd3407 100644 --- a/examples/chef/devices/rootnode_basicvideoplayer_0ff86e943b.zap +++ b/examples/chef/devices/rootnode_basicvideoplayer_0ff86e943b.zap @@ -1002,96 +1002,6 @@ } ] }, - { - "name": "Time Format Localization", - "code": 44, - "mfgCode": null, - "define": "TIME_FORMAT_LOCALIZATION_CLUSTER", - "side": "server", - "enabled": 1, - "attributes": [ - { - "name": "HourFormat", - "code": 0, - "mfgCode": null, - "side": "server", - "type": "HourFormatEnum", - "included": 1, - "storageOption": "NVM", - "singleton": 0, - "bounded": 0, - "defaultValue": "0", - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, - { - "name": "ActiveCalendarType", - "code": 1, - "mfgCode": null, - "side": "server", - "type": "CalendarTypeEnum", - "included": 1, - "storageOption": "NVM", - "singleton": 0, - "bounded": 0, - "defaultValue": "0", - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, - { - "name": "SupportedCalendarTypes", - "code": 2, - "mfgCode": null, - "side": "server", - "type": "array", - "included": 1, - "storageOption": "External", - "singleton": 0, - "bounded": 0, - "defaultValue": null, - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, - { - "name": "FeatureMap", - "code": 65532, - "mfgCode": null, - "side": "server", - "type": "bitmap32", - "included": 1, - "storageOption": "RAM", - "singleton": 0, - "bounded": 0, - "defaultValue": "0", - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, - { - "name": "ClusterRevision", - "code": 65533, - "mfgCode": null, - "side": "server", - "type": "int16u", - "included": 1, - "storageOption": "RAM", - "singleton": 0, - "bounded": 0, - "defaultValue": "1", - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - } - ] - }, { "name": "General Commissioning", "code": 48, @@ -1989,7 +1899,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "0", + "defaultValue": "1", "reportable": 1, "minInterval": 1, "maxInterval": 65534, @@ -2632,7 +2542,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "4", + "defaultValue": "6", "reportable": 1, "minInterval": 1, "maxInterval": 65534, @@ -2818,6 +2728,22 @@ "side": "server", "enabled": 1, "attributes": [ + { + "name": "MACAddress", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, { "name": "GeneratedCommandList", "code": 65528, @@ -3146,6 +3072,22 @@ "maxInterval": 65534, "reportableChange": 0 }, + { + "name": "CurrentTarget", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, { "name": "GeneratedCommandList", "code": 65528, @@ -3242,6 +3184,15 @@ "maxInterval": 65534, "reportableChange": 0 } + ], + "events": [ + { + "name": "TargetUpdated", + "code": 0, + "mfgCode": null, + "side": "server", + "included": 1 + } ] }, { @@ -3276,6 +3227,62 @@ "isIncoming": 1, "isEnabled": 1 }, + { + "name": "StartOver", + "code": 3, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "Previous", + "code": 4, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "Next", + "code": 5, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "Rewind", + "code": 6, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "FastForward", + "code": 7, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "SkipForward", + "code": 8, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "SkipBackward", + "code": 9, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, { "name": "PlaybackResponse", "code": 10, @@ -3283,6 +3290,14 @@ "source": "server", "isIncoming": 0, "isEnabled": 1 + }, + { + "name": "Seek", + "code": 11, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 } ], "attributes": [ @@ -3303,43 +3318,43 @@ "reportableChange": 0 }, { - "name": "GeneratedCommandList", - "code": 65528, + "name": "StartTime", + "code": 1, "mfgCode": null, "side": "server", - "type": "array", + "type": "epoch_us", "included": 1, - "storageOption": "External", + "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": null, + "defaultValue": "0x00", "reportable": 1, "minInterval": 1, "maxInterval": 65534, "reportableChange": 0 }, { - "name": "AcceptedCommandList", - "code": 65529, + "name": "Duration", + "code": 2, "mfgCode": null, "side": "server", - "type": "array", + "type": "int64u", "included": 1, - "storageOption": "External", + "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": null, + "defaultValue": "0", "reportable": 1, "minInterval": 1, "maxInterval": 65534, "reportableChange": 0 }, { - "name": "EventList", - "code": 65530, + "name": "SampledPosition", + "code": 3, "mfgCode": null, "side": "server", - "type": "array", + "type": "PlaybackPositionStruct", "included": 1, "storageOption": "External", "singleton": 0, @@ -3351,74 +3366,179 @@ "reportableChange": 0 }, { - "name": "AttributeList", - "code": 65531, + "name": "PlaybackSpeed", + "code": 4, "mfgCode": null, "side": "server", - "type": "array", + "type": "single", "included": 1, - "storageOption": "External", + "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": null, + "defaultValue": "0", "reportable": 1, "minInterval": 1, "maxInterval": 65534, "reportableChange": 0 }, { - "name": "FeatureMap", - "code": 65532, + "name": "SeekRangeEnd", + "code": 5, "mfgCode": null, "side": "server", - "type": "bitmap32", + "type": "int64u", "included": 1, "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "0", + "defaultValue": "", "reportable": 1, "minInterval": 1, "maxInterval": 65534, "reportableChange": 0 }, { - "name": "ClusterRevision", - "code": 65533, + "name": "SeekRangeStart", + "code": 6, "mfgCode": null, "side": "server", - "type": "int16u", + "type": "int64u", "included": 1, "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "1", + "defaultValue": "", "reportable": 1, "minInterval": 1, "maxInterval": 65534, "reportableChange": 0 - } - ] - }, - { - "name": "Media Input", - "code": 1287, - "mfgCode": null, - "define": "MEDIA_INPUT_CLUSTER", - "side": "server", - "enabled": 1, - "commands": [ + }, { - "name": "SelectInput", - "code": 0, + "name": "GeneratedCommandList", + "code": 65528, "mfgCode": null, - "source": "client", - "isIncoming": 1, - "isEnabled": 1 + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 }, { - "name": "ShowInputStatus", - "code": 1, + "name": "AcceptedCommandList", + "code": 65529, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "EventList", + "code": 65530, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AttributeList", + "code": 65531, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "3", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + } + ], + "events": [ + { + "name": "StateChanged", + "code": 0, + "mfgCode": null, + "side": "server", + "included": 1 + } + ] + }, + { + "name": "Media Input", + "code": 1287, + "mfgCode": null, + "define": "MEDIA_INPUT_CLUSTER", + "side": "server", + "enabled": 1, + "commands": [ + { + "name": "SelectInput", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "ShowInputStatus", + "code": 1, "mfgCode": null, "source": "client", "isIncoming": 1, @@ -3431,6 +3551,14 @@ "source": "client", "isIncoming": 1, "isEnabled": 1 + }, + { + "name": "RenameInput", + "code": 3, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 } ], "attributes": [ @@ -3540,7 +3668,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "0", + "defaultValue": "1", "reportable": 1, "minInterval": 1, "maxInterval": 65534, @@ -3780,7 +3908,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "0", + "defaultValue": "7", "reportable": 1, "minInterval": 1, "maxInterval": 65534, @@ -3819,6 +3947,14 @@ "source": "client", "isIncoming": 1, "isEnabled": 1 + }, + { + "name": "RenameOutput", + "code": 1, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 } ], "attributes": [ @@ -3928,7 +4064,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "0", + "defaultValue": "1", "reportable": 1, "minInterval": 1, "maxInterval": 65534, @@ -3953,21 +4089,783 @@ ] } ] - } - ], - "endpoints": [ - { - "endpointTypeName": "MA-rootdevice", - "endpointTypeIndex": 0, - "profileId": 259, - "endpointId": 0, - "networkId": 0 }, { - "endpointTypeName": "Anonymous Endpoint Type", - "endpointTypeIndex": 1, - "profileId": 259, - "endpointId": 1, + "id": 3, + "name": "Anonymous Endpoint Type", + "deviceTypeRef": { + "code": 34, + "profileId": 259, + "label": "MA-speaker", + "name": "MA-speaker" + }, + "deviceTypes": [ + { + "code": 34, + "profileId": 259, + "label": "MA-speaker", + "name": "MA-speaker" + } + ], + "deviceVersions": [ + 1 + ], + "deviceIdentifiers": [ + 34 + ], + "deviceTypeName": "MA-speaker", + "deviceTypeCode": 34, + "deviceTypeProfileId": 259, + "clusters": [ + { + "name": "Identify", + "code": 3, + "mfgCode": null, + "define": "IDENTIFY_CLUSTER", + "side": "server", + "enabled": 1, + "commands": [ + { + "name": "Identify", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "TriggerEffect", + "code": 64, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + } + ], + "attributes": [ + { + "name": "IdentifyTime", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "IdentifyType", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "IdentifyTypeEnum", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x00", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "GeneratedCommandList", + "code": 65528, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AcceptedCommandList", + "code": 65529, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "EventList", + "code": 65530, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AttributeList", + "code": 65531, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "4", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + } + ] + }, + { + "name": "On/Off", + "code": 6, + "mfgCode": null, + "define": "ON_OFF_CLUSTER", + "side": "server", + "enabled": 1, + "commands": [ + { + "name": "Off", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "On", + "code": 1, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "Toggle", + "code": 2, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + } + ], + "attributes": [ + { + "name": "OnOff", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "boolean", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "GeneratedCommandList", + "code": 65528, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AcceptedCommandList", + "code": 65529, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "EventList", + "code": 65530, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AttributeList", + "code": 65531, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "6", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + } + ] + }, + { + "name": "Level Control", + "code": 8, + "mfgCode": null, + "define": "LEVEL_CONTROL_CLUSTER", + "side": "server", + "enabled": 1, + "commands": [ + { + "name": "MoveToLevel", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "Move", + "code": 1, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "Step", + "code": 2, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "Stop", + "code": 3, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "MoveToLevelWithOnOff", + "code": 4, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "MoveWithOnOff", + "code": 5, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "StepWithOnOff", + "code": 6, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "StopWithOnOff", + "code": 7, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + } + ], + "attributes": [ + { + "name": "CurrentLevel", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x00", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "MinLevel", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x00", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "MaxLevel", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0xFE", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "Options", + "code": 15, + "mfgCode": null, + "side": "server", + "type": "OptionsBitmap", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x00", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "OnLevel", + "code": 17, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0xFE", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "GeneratedCommandList", + "code": 65528, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AcceptedCommandList", + "code": 65529, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "EventList", + "code": 65530, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AttributeList", + "code": 65531, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "5", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + } + ] + }, + { + "name": "Descriptor", + "code": 29, + "mfgCode": null, + "define": "DESCRIPTOR_CLUSTER", + "side": "server", + "enabled": 1, + "attributes": [ + { + "name": "DeviceTypeList", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ServerList", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClientList", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "PartsList", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "GeneratedCommandList", + "code": 65528, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AcceptedCommandList", + "code": 65529, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "EventList", + "code": 65530, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AttributeList", + "code": 65531, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + } + ] + } + ] + } + ], + "endpoints": [ + { + "endpointTypeName": "MA-rootdevice", + "endpointTypeIndex": 0, + "profileId": 259, + "endpointId": 0, + "networkId": 0 + }, + { + "endpointTypeName": "Anonymous Endpoint Type", + "endpointTypeIndex": 1, + "profileId": 259, + "endpointId": 1, + "networkId": 0 + }, + { + "endpointTypeName": "Anonymous Endpoint Type", + "endpointTypeIndex": 2, + "profileId": 259, + "endpointId": 2, "networkId": 0 } ] diff --git a/examples/chef/esp32/main/CMakeLists.txt b/examples/chef/esp32/main/CMakeLists.txt index e6ab518f3494a9..8278cf9a735675 100644 --- a/examples/chef/esp32/main/CMakeLists.txt +++ b/examples/chef/esp32/main/CMakeLists.txt @@ -33,6 +33,7 @@ set(PRIV_INCLUDE_DIRS_LIST "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/third_party/nlio/repo/include" "${CMAKE_SOURCE_DIR}/../" "${CMAKE_SOURCE_DIR}/../common" + "${CMAKE_SOURCE_DIR}/../common/clusters" "${CMAKE_SOURCE_DIR}/main/include/" ) @@ -62,6 +63,14 @@ set(SRC_DIRS_LIST ${SRC_DIRS_LIST} "${CMAKE_CURRENT_LIST_DIR}" "${CMAKE_SOURCE_DIR}/../common" + "${CMAKE_SOURCE_DIR}/../common/clusters/media-input/" + "${CMAKE_SOURCE_DIR}/../common/clusters/low-power/" + "${CMAKE_SOURCE_DIR}/../common/clusters/media-playback/" + "${CMAKE_SOURCE_DIR}/../common/clusters/target-navigator/" + "${CMAKE_SOURCE_DIR}/../common/clusters/wake-on-lan/" + "${CMAKE_SOURCE_DIR}/../common/clusters/channel/" + "${CMAKE_SOURCE_DIR}/../common/clusters/keypad-input/" + "${CMAKE_SOURCE_DIR}/../common/clusters/audio-output/" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/zzz_generated/app-common/app-common/zap-generated/attributes" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/server" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/util" diff --git a/examples/chef/linux/BUILD.gn b/examples/chef/linux/BUILD.gn index a25c1f5ffa11ce..a119f832e051db 100644 --- a/examples/chef/linux/BUILD.gn +++ b/examples/chef/linux/BUILD.gn @@ -43,12 +43,19 @@ chip_data_model("chef-data-model") { executable("${sample_name}") { sources = [ "${project_dir}/common/chef-air-quality.cpp", - "${project_dir}/common/chef-channel-manager.cpp", "${project_dir}/common/chef-concentration-measurement.cpp", "${project_dir}/common/chef-fan-control-manager.cpp", "${project_dir}/common/chef-resource-monitoring-delegates.cpp", "${project_dir}/common/chef-rvc-mode-delegate.cpp", "${project_dir}/common/chef-rvc-operational-state-delegate.cpp", + "${project_dir}/common/clusters/audio-output/AudioOutputManager.cpp", + "${project_dir}/common/clusters/channel/ChannelManager.cpp", + "${project_dir}/common/clusters/keypad-input/KeypadInputManager.cpp", + "${project_dir}/common/clusters/low-power/LowPowerManager.cpp", + "${project_dir}/common/clusters/media-input/MediaInputManager.cpp", + "${project_dir}/common/clusters/media-playback/MediaPlaybackManager.cpp", + "${project_dir}/common/clusters/target-navigator/TargetNavigatorManager.cpp", + "${project_dir}/common/clusters/wake-on-lan/WakeOnLanManager.cpp", "${project_dir}/common/stubs.cpp", "${project_dir}/linux/main.cpp", ] @@ -63,6 +70,7 @@ executable("${sample_name}") { include_dirs = [ "include", "${project_dir}/common", + "${project_dir}/common/clusters", ] if (chip_enable_pw_rpc) { diff --git a/examples/chef/nrfconnect/CMakeLists.txt b/examples/chef/nrfconnect/CMakeLists.txt index 17556ef398b27a..0a408e829dd04f 100644 --- a/examples/chef/nrfconnect/CMakeLists.txt +++ b/examples/chef/nrfconnect/CMakeLists.txt @@ -60,6 +60,7 @@ target_include_directories(app PRIVATE ${GEN_DIR} ${CHEF} ${CHEF}/common + ${CHEF}/common/clusters/ ${GEN_DIR}/../ ${CHIP_ROOT}/src ${CHIP_ROOT}/examples/shell/shell_common/include @@ -81,12 +82,19 @@ endif() target_sources(app PRIVATE ${CHEF}/common/chef-air-quality.cpp - ${CHEF}/common/chef-channel-manager.cpp ${CHEF}/common/chef-concentration-measurement.cpp ${CHEF}/common/chef-fan-control-manager.cpp ${CHEF}/common/chef-resource-monitoring-delegates.cpp ${CHEF}/common/chef-rvc-mode-delegate.cpp ${CHEF}/common/chef-rvc-operational-state-delegate.cpp + ${CHEF}/common/clusters/media-input/MediaInputManager.cpp + ${CHEF}/common/clusters/low-power/LowPowerManager.cpp + ${CHEF}/common/clusters/media-playback/MediaPlaybackManager.cpp + ${CHEF}/common/clusters/target-navigator/TargetNavigatorManager.cpp + ${CHEF}/common/clusters/wake-on-lan/WakeOnLanManager.cpp + ${CHEF}/common/clusters/channel/ChannelManager.cpp + ${CHEF}/common/clusters/keypad-input/KeypadInputManager.cpp + ${CHEF}/common/clusters/audio-output/AudioOutputManager.cpp ${CHEF}/common/stubs.cpp ${CHEF}/nrfconnect/main.cpp ) diff --git a/integrations/cloudbuild/chef.yaml b/integrations/cloudbuild/chef.yaml index 432308a8bd695f..8dcf827d7e56aa 100644 --- a/integrations/cloudbuild/chef.yaml +++ b/integrations/cloudbuild/chef.yaml @@ -18,7 +18,7 @@ steps: args: - >- perl -i -pe 's/^gdbgui==/# gdbgui==/' /opt/espressif/esp-idf/requirements.txt && - ./examples/chef/chef.py --build_all --build_exclude noip\|basicvideo\|roboticvacuumcleaner + ./examples/chef/chef.py --build_all --build_exclude noip\|roboticvacuumcleaner id: CompileAll waitFor: - Bootstrap From 1dd67c3d7a2cd690db7d802ef41270eb9353fce7 Mon Sep 17 00:00:00 2001 From: Junior Martinez <67972863+jmartinez-silabs@users.noreply.github.com> Date: Fri, 16 Feb 2024 08:58:17 -0500 Subject: [PATCH 02/33] docker image 36 : Update GeckoSDK and WIFI SDK (#32146) --- integrations/docker/images/base/chip-build/version | 2 +- .../docker/images/stage-2/chip-build-efr32/Dockerfile | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/integrations/docker/images/base/chip-build/version b/integrations/docker/images/base/chip-build/version index 4a62ddb7795a85..3f8f2543a19424 100644 --- a/integrations/docker/images/base/chip-build/version +++ b/integrations/docker/images/base/chip-build/version @@ -1 +1 @@ -35 : [Telink] Update Docker image (Zephyr update) +36 : [Silabs] Update GeckoSDK and WIFI SDK diff --git a/integrations/docker/images/stage-2/chip-build-efr32/Dockerfile b/integrations/docker/images/stage-2/chip-build-efr32/Dockerfile index 9f3a218dbdb2bb..8dd4ca6b1444fd 100644 --- a/integrations/docker/images/stage-2/chip-build-efr32/Dockerfile +++ b/integrations/docker/images/stage-2/chip-build-efr32/Dockerfile @@ -13,8 +13,8 @@ RUN set -x \ && : # last line -# Clone Gecko SDK 4.4.0 (124fa19) -RUN wget https://github.com/SiliconLabs/gecko_sdk/releases/download/v4.4.0/gecko-sdk.zip -O /tmp/gecko_sdk.zip \ +# Clone Gecko SDK 4.4.1 (911f6cd) +RUN wget https://github.com/SiliconLabs/gecko_sdk/releases/download/v4.4.1/gecko-sdk.zip -O /tmp/gecko_sdk.zip \ && unzip /tmp/gecko_sdk.zip -d /tmp/gecko_sdk \ && rm -rf /tmp/gecko_sdk.zip \ # Deleting files that are not needed to save space @@ -30,8 +30,8 @@ RUN git clone --depth=1 --single-branch --branch=2.8.2 https://github.com/Silico rm -rf .git \ && : # last line -# Clone WiSeConnect SDK 3.1.1 (b2c1cd0) -RUN git clone --depth=1 --single-branch --branch=v3.1.1 https://github.com/SiliconLabs/wiseconnect.git /tmp/wifi_sdk && \ +# Clone WiSeConnect SDK 3.1.3 (00dd57a) +RUN git clone --depth=1 --single-branch --branch=v3.1.3 https://github.com/SiliconLabs/wiseconnect.git /tmp/wifi_sdk && \ cd /tmp/wifi_sdk && \ rm -rf .git \ && : # last line From 2feb5d771a3a904360f7ac60a985594bc2b280c9 Mon Sep 17 00:00:00 2001 From: yunhanw-google Date: Fri, 16 Feb 2024 07:03:18 -0800 Subject: [PATCH 03/33] [Android]remove unused status newInstance (#32160) --- .../java/src/chip/devicecontroller/model/Status.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/controller/java/src/chip/devicecontroller/model/Status.java b/src/controller/java/src/chip/devicecontroller/model/Status.java index af97d84d9a099a..c367535f5e8578 100644 --- a/src/controller/java/src/chip/devicecontroller/model/Status.java +++ b/src/controller/java/src/chip/devicecontroller/model/Status.java @@ -47,10 +47,6 @@ public String toString() { clusterStatus.isPresent() ? String.valueOf(clusterStatus.get()) : "None"); } - public static Status newInstance(int status, int clusterStatus) { - return new Status(status, Optional.of(clusterStatus)); - } - public static Status newInstance(int status) { return new Status(status, Optional.empty()); } From 7a29610cc6c243e329238edc980d7556a6c68192 Mon Sep 17 00:00:00 2001 From: C Freeman Date: Fri, 16 Feb 2024 10:07:19 -0500 Subject: [PATCH 04/33] Remove IP commissioning guide. (#32145) * Remove IP commissioning guide. This is horrendously outdated. Chip tool and chip repl cover this fully now, and are actually correct. * missed one --- docs/guides/README.md | 1 - docs/guides/index.md | 1 - docs/guides/ip_commissioning.md | 82 --------------------------------- 3 files changed, 84 deletions(-) delete mode 100644 docs/guides/ip_commissioning.md diff --git a/docs/guides/README.md b/docs/guides/README.md index 30356c72273747..4f4ddb231f577b 100644 --- a/docs/guides/README.md +++ b/docs/guides/README.md @@ -34,7 +34,6 @@ ## Development Guides - [Access Control](./access-control-guide.md) -- [IP Commissioning](./ip_commissioning.md) ## Setup Guides diff --git a/docs/guides/index.md b/docs/guides/index.md index 8813376f7e3e81..2a5d3a64f5afe7 100644 --- a/docs/guides/index.md +++ b/docs/guides/index.md @@ -55,7 +55,6 @@ ti/ti_platform_overview ## Development Guides - [Access Control](./access-control-guide.md) -- [IP Commissioning](./ip_commissioning.md) - [Matter IDL tooling and validation](./matter_idl_tooling.md) ## Setup Guides diff --git a/docs/guides/ip_commissioning.md b/docs/guides/ip_commissioning.md deleted file mode 100644 index d1e44d087be435..00000000000000 --- a/docs/guides/ip_commissioning.md +++ /dev/null @@ -1,82 +0,0 @@ -# IP commissioning - -## Devices - -### ESP32 (M5 stack) - all-clusters-app - -The M5 doesn’t have an ethernet port, but we can simulate IP connection by -giving the device wifi credentials. The device will start up advertising as a -commissionable device. - -Compile the device image as follows - -``` -Demo->Device Type = -Component config-> Chip Device Layer -> WiFi Station Options - set up ssid and password -``` - -### linux builds - -```bash -gn gen out/debug -ninja -C out/debug -``` - -These devices start in commissioning mode if they do not have stored Matter -credentials. Linux devices store credentials in the /tmp directory, so to -re-commission the device from scratch, remove the chip\_\* files from /tmp. - -## Controller - -### chip-device-ctrl - -There are two ways to connect via IP: - -**Discover then connect ip** - -``` -discover -all -``` - -or - -``` -discover -qr “[qrcode]” -``` - -then - -``` -connect -ip
[] -``` - -It is no longer necessary to run resolve after connect - this is done as part of -the commissioning process - -**Connect using the QR code** - -``` -connect -qr “[qr code]” -``` - -This will discover, connect over IP with the code from the QR and resolve. - -### chip-tool - -You can connect using chip-tool either using the setup codes or by discovering -the device on the network using one of the mDNS sub types. To get a list of the -available options run - -``` -chip-tool pairing -``` - -For example, to discover, connect and commission using the long discriminator - -``` -chip-tool pairing onnetwork-long -``` - -where the node id is set to a value of your choice (used to id devices for -future communication), and the setup pin code and long discriminator are set by -the device and are normally logged at startup. From d4a89c9eb2417bf96a58c77b4dfc715ed9d21e13 Mon Sep 17 00:00:00 2001 From: Terence Hampson Date: Fri, 16 Feb 2024 10:30:22 -0500 Subject: [PATCH 05/33] Update IDM_1_3 yaml to latest testplan spec which uses fault injection (#32149) * Update IDM_1_3 yaml to latest testplan spec which used fault injection * Restyled by whitespace * Restyled by prettier-yaml * Quick fix --------- Co-authored-by: Restyled.io --- .../suites/certification/Test_TC_IDM_1_3.yaml | 198 +++++++++++++++++- 1 file changed, 195 insertions(+), 3 deletions(-) diff --git a/src/app/tests/suites/certification/Test_TC_IDM_1_3.yaml b/src/app/tests/suites/certification/Test_TC_IDM_1_3.yaml index 4c2d250ca17de1..7e25cef6c174e1 100644 --- a/src/app/tests/suites/certification/Test_TC_IDM_1_3.yaml +++ b/src/app/tests/suites/certification/Test_TC_IDM_1_3.yaml @@ -31,6 +31,189 @@ tests: Chip-repl commands used below are an example to verify the DUT as client test cases. For certification test, we expect DUT should have a capability or way to run the equivalent command. disabled: true + - label: + "Step 0 (Pre-Condition 1): Commission TH Client to TH device (Server), + if not done so already." + verification: | + Ensure DUT is commissioned to TH device (Server). + disabled: true + + - label: + "Step 0 (Pre-Condition 2): Commission DUT to TH device (Server), if + not done so already." + verification: | + Ensure DUT is commissioned to TH device (Server). + This likely requires opening the commissioning window with TH Client." + disabled: true + + - label: + "Step 0 (Pre-Condition 3): TH Client send `FailAtFault` command to + `FaultInjection` cluster to TH device (Server)." + cluster: "FaultInjection" + command: "FailAtFault" + arguments: + values: + - name: "Type" + value: 3 + - name: "Id" + value: 12 + - name: "NumCallsToSkip" + value: 3 + - name: "NumCallsToFail" + value: 1 + - name: "TakeMutex" + value: false + verification: | + Equivalent TH Client command to run `chip-tool faultinjection fail-at-fault 3 12 3 1 false 1 0` + On TH(all-clusters-app), Verify command is successfully: + + CHIP:DMG: InvokeRequestMessage = + CHIP:DMG: { + CHIP:DMG: suppressResponse = false, + CHIP:DMG: timedRequest = false, + CHIP:DMG: InvokeRequests = + CHIP:DMG: [ + CHIP:DMG: CommandDataIB = + CHIP:DMG: { + CHIP:DMG: CommandPathIB = + CHIP:DMG: { + CHIP:DMG: EndpointId = 0x0, + CHIP:DMG: ClusterId = 0xfff1fc06, + CHIP:DMG: CommandId = 0x0, + CHIP:DMG: }, + CHIP:DMG: + CHIP:DMG: CommandFields = + CHIP:DMG: { + CHIP:DMG: 0x0 = 3, + CHIP:DMG: 0x1 = 12, + CHIP:DMG: 0x2 = 3, + CHIP:DMG: 0x3 = 1, + CHIP:DMG: 0x4 = false, + CHIP:DMG: }, + CHIP:DMG: }, + CHIP:DMG: + CHIP:DMG: ], + CHIP:DMG: + CHIP:DMG: InteractionModelRevision = 11 + CHIP:DMG: }, + CHIP:DMG: AccessControl: checking f=1 a=c s=0x000000000001B669 t= c=0xFFF1_FC06 e=0 p=m + CHIP:DMG: AccessControl: allowed + CHIP:DMG: Received command for Endpoint=0 Cluster=0xFFF1_FC06 Command=0x0000_0000 + CHIP:ZCL: FaultInjection: Configure a fault of type: 3 and Id: 12 to be triggered deterministically <--------- Verify success with this message. + disabled: true + + - label: + "Step 0 (Pre-Condition 4): TH Client send `FailAtFault` command to + `FaultInjection` cluster to TH device (Server)." + cluster: "FaultInjection" + command: "FailAtFault" + arguments: + values: + - name: "Type" + value: 3 + - name: "Id" + value: 13 + - name: "NumCallsToSkip" + value: 2 + - name: "NumCallsToFail" + value: 1 + - name: "TakeMutex" + value: false + verification: | + Equivalent TH Client command to run `chip-tool faultinjection fail-at-fault 3 13 2 1 false 1 0` + On TH(all-clusters-app), Verify command is successfully: + + CHIP:DMG: InvokeRequestMessage = + CHIP:DMG: { + CHIP:DMG: suppressResponse = false, + CHIP:DMG: timedRequest = false, + CHIP:DMG: InvokeRequests = + CHIP:DMG: [ + CHIP:DMG: CommandDataIB = + CHIP:DMG: { + CHIP:DMG: CommandPathIB = + CHIP:DMG: { + CHIP:DMG: EndpointId = 0x0, + CHIP:DMG: ClusterId = 0xfff1fc06, + CHIP:DMG: CommandId = 0x0, + CHIP:DMG: }, + CHIP:DMG: + CHIP:DMG: CommandFields = + CHIP:DMG: { + CHIP:DMG: 0x0 = 3, + CHIP:DMG: 0x1 = 13, + CHIP:DMG: 0x2 = 2, + CHIP:DMG: 0x3 = 1, + CHIP:DMG: 0x4 = false, + CHIP:DMG: }, + CHIP:DMG: }, + CHIP:DMG: + CHIP:DMG: ], + CHIP:DMG: + CHIP:DMG: InteractionModelRevision = 11 + CHIP:DMG: }, + CHIP:DMG: AccessControl: checking f=1 a=c s=0x000000000001B669 t= c=0xFFF1_FC06 e=0 p=m + CHIP:DMG: AccessControl: allowed + CHIP:DMG: Received command for Endpoint=0 Cluster=0xFFF1_FC06 Command=0x0000_0000 + CHIP:ZCL: FaultInjection: Configure a fault of type: 3 and Id: 13 to be triggered deterministically <--------- Verify success with this message. + disabled: true + + - label: + "Step 0 (Pre-Condition 5): TH Client send `FailAtFault` command to + `FaultInjection` cluster to TH device (Server)." + cluster: "FaultInjection" + command: "FailAtFault" + arguments: + values: + - name: "Type" + value: 3 + - name: "Id" + value: 14 + - name: "NumCallsToSkip" + value: 1 + - name: "NumCallsToFail" + value: 1 + - name: "TakeMutex" + value: false + verification: | + Equivalent TH Client command to run `chip-tool faultinjection fail-at-fault 3 14 1 1 false 1 0` + On TH(all-clusters-app), Verify command is successfully: + + CHIP:DMG: InvokeRequestMessage = + CHIP:DMG: { + CHIP:DMG: suppressResponse = false, + CHIP:DMG: timedRequest = false, + CHIP:DMG: InvokeRequests = + CHIP:DMG: [ + CHIP:DMG: CommandDataIB = + CHIP:DMG: { + CHIP:DMG: CommandPathIB = + CHIP:DMG: { + CHIP:DMG: EndpointId = 0x0, + CHIP:DMG: ClusterId = 0xfff1fc06, + CHIP:DMG: CommandId = 0x0, + CHIP:DMG: }, + CHIP:DMG: + CHIP:DMG: CommandFields = + CHIP:DMG: { + CHIP:DMG: 0x0 = 3, + CHIP:DMG: 0x1 = 14, + CHIP:DMG: 0x2 = 1, + CHIP:DMG: 0x3 = 1, + CHIP:DMG: 0x4 = false, + CHIP:DMG: }, + CHIP:DMG: }, + CHIP:DMG: + CHIP:DMG: ], + CHIP:DMG: + CHIP:DMG: InteractionModelRevision = 11 + CHIP:DMG: }, + CHIP:DMG: AccessControl: checking f=1 a=c s=0x000000000001B669 t= c=0xFFF1_FC06 e=0 p=m + CHIP:DMG: AccessControl: allowed + CHIP:DMG: Received command for Endpoint=0 Cluster=0xFFF1_FC06 Command=0x0000_0000 + CHIP:ZCL: FaultInjection: Configure a fault of type: 3 and Id: 14 to be triggered deterministically <--------- Verify success with this message. + disabled: true + - label: "Step 1: DUT sends the Invoke Request Message to the TH. The Message should contain two valid and unique paths in the CommandDataIBs, which has the specific Endpoints, specific Clusters @@ -110,7 +293,10 @@ tests: `await devCtrl.SendBatchCommands(0x12344321, [chip.clusters.Command.InvokeRequestInfo(1, chip.clusters.OnOff.Commands.Toggle()), chip.clusters.Command.InvokeRequestInfo(2, chip.clusters.OnOff.Commands.Toggle())])` - Verify DUT doesn't crash by seeing next step execute. + * Verify DUT doesn't crash by seeing next step execute. + * On TH(all-clusters-app), Verify following logs are seen: + CHIP:DMG: Response to InvokeRequestMessage overridden by fault injection + CHIP:DMG: Injecting the following response:Each response will be sent in a separate InvokeResponseMessage. The order of responses will be the same as the original request. disabled: true - label: "Step 3: DUT sends the Invoke Request Message to the TH. The @@ -130,7 +316,10 @@ tests: `await devCtrl.SendBatchCommands(0x12344321, [chip.clusters.Command.InvokeRequestInfo(1, chip.clusters.OnOff.Commands.Toggle()), chip.clusters.Command.InvokeRequestInfo(2, chip.clusters.OnOff.Commands.Toggle())])` - Verify DUT doesn't crash by seeing next step execute. + * Verify DUT doesn't crash by seeing next step execute. + * On TH(all-clusters-app), Verify following logs are seen: + CHIP:DMG: Response to InvokeRequestMessage overridden by fault injection + CHIP:DMG: Injecting the following response:Each response will be sent in a separate InvokeResponseMessage. The order of responses will be reversed from the original request. disabled: true - label: "Step 4: DUT sends the Invoke Request Message to the TH. The @@ -150,7 +339,10 @@ tests: `await devCtrl.SendBatchCommands(0x12344321, [chip.clusters.Command.InvokeRequestInfo(1, chip.clusters.OnOff.Commands.Toggle()), chip.clusters.Command.InvokeRequestInfo(2, chip.clusters.OnOff.Commands.Toggle())])` - Verify DUT doesn't crash by seeing next step execute. + * Verify DUT doesn't crash by seeing next step execute. + * On TH(all-clusters-app), Verify following logs are seen: + CHIP:DMG: Response to InvokeRequestMessage overridden by fault injection + CHIP:DMG: Injecting the following response:Single InvokeResponseMessages. Dropping response to second request disabled: true - label: "Step 5: DUT sends the Invoke Request Message to the TH. The From d116c7cc1203a0c2e8395e6c6c5a97ef15399771 Mon Sep 17 00:00:00 2001 From: Rob Bultman Date: Fri, 16 Feb 2024 11:11:16 -0500 Subject: [PATCH 06/33] [MWOCTRL] Add constraint error checks (#32118) * Add constraint error checks * Apply suggestions from code review Co-authored-by: Andrei Litvin * Added check for exception expected --------- Co-authored-by: Andrei Litvin --- src/python_testing/TC_MWOCTRL_2_2.py | 9 +++++++++ src/python_testing/TC_MWOCTRL_2_3.py | 9 +++++++++ 2 files changed, 18 insertions(+) diff --git a/src/python_testing/TC_MWOCTRL_2_2.py b/src/python_testing/TC_MWOCTRL_2_2.py index abe02d8237a8db..a5484c586067c6 100644 --- a/src/python_testing/TC_MWOCTRL_2_2.py +++ b/src/python_testing/TC_MWOCTRL_2_2.py @@ -42,6 +42,7 @@ def steps_TC_MWOCTRL_2_2(self) -> list[TestStep]: TestStep(2, "Read the PowerSetting attribute"), TestStep(3, "Send the SetCookingParameters command"), TestStep(4, "Read and verify the PowerSetting attribute"), + TestStep(5, "Cause constraint error response"), ] return steps @@ -89,6 +90,14 @@ async def test_TC_MWOCTRL_2_2(self): powerValue = await self.read_mwoctrl_attribute_expect_success(endpoint=endpoint, attribute=attributes.PowerSetting) asserts.assert_true(powerValue == newPowerValue, "PowerSetting was not correctly set") + self.step(5) + newPowerValue = 125 + try: + await self.send_single_cmd(cmd=commands.SetCookingParameters(powerSetting=newPowerValue), endpoint=endpoint) + asserts.assert_fail("Expected an exception but received none.") + except InteractionModelError as e: + asserts.assert_equal(e.status, Status.ConstraintError, "Expected ConstraintError but received a different error.") + if __name__ == "__main__": default_matter_test_main() diff --git a/src/python_testing/TC_MWOCTRL_2_3.py b/src/python_testing/TC_MWOCTRL_2_3.py index 0d34c5b3ee8fde..20a1e730ab620a 100644 --- a/src/python_testing/TC_MWOCTRL_2_3.py +++ b/src/python_testing/TC_MWOCTRL_2_3.py @@ -45,6 +45,7 @@ def steps_TC_MWOCTRL_2_3(self) -> list[TestStep]: TestStep(5, "Read the PowerSetting attribute"), TestStep(6, "Send the SetCookingParameters command"), TestStep(7, "Read and verify the PowerSetting attribute"), + TestStep(8, "Cause constraint error response"), ] return steps @@ -109,6 +110,14 @@ async def test_TC_MWOCTRL_2_3(self): powerValue = await self.read_mwoctrl_attribute_expect_success(endpoint=endpoint, attribute=attributes.PowerSetting) asserts.assert_true(powerValue == newPowerValue, "PowerSetting was not correctly set") + self.step(8) + newPowerValue = maxPowerValue+1 + try: + await self.send_single_cmd(cmd=commands.SetCookingParameters(powerSetting=newPowerValue), endpoint=endpoint) + asserts.assert_fail("Expected an exception but received none.") + except InteractionModelError as e: + asserts.assert_equal(e.status, Status.ConstraintError, "Expected ConstraintError but received a different response.") + if __name__ == "__main__": default_matter_test_main() From 5dfaed47fd509043bb2eb9097b799ea9daeca3f1 Mon Sep 17 00:00:00 2001 From: jamesharrow <93921463+jamesharrow@users.noreply.github.com> Date: Fri, 16 Feb 2024 17:32:05 +0000 Subject: [PATCH 07/33] =?UTF-8?q?Fixes:=20#31672=20avoids=20a=20deliberate?= =?UTF-8?q?=20crash=20on=20targets=20which=20don't=20suppor=E2=80=A6=20(#3?= =?UTF-8?q?2058)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Fixes: #31672 avoids a deliberate crash on targets which don't support real-time clock * Added clearer error message about checking EVSE certification requirements. --- .../energy-management-common/src/EnergyEvseDelegateImpl.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/examples/energy-management-app/energy-management-common/src/EnergyEvseDelegateImpl.cpp b/examples/energy-management-app/energy-management-common/src/EnergyEvseDelegateImpl.cpp index dc60d748958894..99619fc95b5fb0 100644 --- a/examples/energy-management-app/energy-management-common/src/EnergyEvseDelegateImpl.cpp +++ b/examples/energy-management-app/energy-management-common/src/EnergyEvseDelegateImpl.cpp @@ -1474,7 +1474,11 @@ CHIP_ERROR GetEpochTS(uint32_t & chipEpoch) * This should not be certifiable since getting time is a Mandatory * feature of EVSE Cluster */ - VerifyOrDie(err != CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE); + if (err == CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE) + { + ChipLogError(Zcl, "Platform does not support GetClock_RealTimeMS. Check EVSE certification requirements!"); + return err; + } if (err != CHIP_NO_ERROR) { From fd92b3edc4e3ee903d9215fb7daf1b128e9f0a08 Mon Sep 17 00:00:00 2001 From: Junior Martinez <67972863+jmartinez-silabs@users.noreply.github.com> Date: Fri, 16 Feb 2024 13:25:20 -0500 Subject: [PATCH 08/33] Bump gecko-sdk, wifi-sdk and matter support submodules. Small changes to silabs platform code inline with sdk updates. Use latest Docker image version for CI (#32171) --- .github/workflows/examples-efr32.yaml | 2 +- .github/workflows/release_artifacts.yaml | 2 +- .gitmodules | 4 +- .../silabs/efr32/rs911x/hal/efx32_ncp_host.c | 107 ++++++++++-------- .../platform/silabs/efr32/rs911x/rs9117.gni | 3 +- .../platform/silabs/efr32/wf200/host_if.cpp | 2 +- src/platform/silabs/SilabsConfig.cpp | 6 +- third_party/silabs/efr32_sdk.gni | 2 +- third_party/silabs/gecko_sdk | 2 +- third_party/silabs/matter_support | 2 +- third_party/silabs/wifi_sdk | 2 +- 11 files changed, 75 insertions(+), 59 deletions(-) diff --git a/.github/workflows/examples-efr32.yaml b/.github/workflows/examples-efr32.yaml index 36c490956d9ae8..1dae68ced0f4a7 100644 --- a/.github/workflows/examples-efr32.yaml +++ b/.github/workflows/examples-efr32.yaml @@ -38,7 +38,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: ghcr.io/project-chip/chip-build-efr32:35 + image: ghcr.io/project-chip/chip-build-efr32:36 volumes: - "/tmp/bloat_reports:/tmp/bloat_reports" steps: diff --git a/.github/workflows/release_artifacts.yaml b/.github/workflows/release_artifacts.yaml index c82e9f59a27674..65896c73b3faca 100644 --- a/.github/workflows/release_artifacts.yaml +++ b/.github/workflows/release_artifacts.yaml @@ -68,7 +68,7 @@ jobs: runs-on: ubuntu-latest container: - image: ghcr.io/project-chip/chip-build-efr32:35 + image: ghcr.io/project-chip/chip-build-efr32:36 steps: - name: Checkout uses: actions/checkout@v4 diff --git a/.gitmodules b/.gitmodules index 61e34cfafd6e94..06fb7f0e347951 100644 --- a/.gitmodules +++ b/.gitmodules @@ -239,7 +239,7 @@ [submodule "third_party/silabs/gecko_sdk"] path = third_party/silabs/gecko_sdk url = https://github.com/SiliconLabs/gecko_sdk.git - branch = v4.4.0 + branch = v4.4.1 platforms = silabs [submodule "third_party/silabs/wiseconnect-wifi-bt-sdk"] path = third_party/silabs/wiseconnect-wifi-bt-sdk @@ -249,7 +249,7 @@ [submodule "third_party/silabs/wifi_sdk"] path = third_party/silabs/wifi_sdk url = https://github.com/SiliconLabs/wiseconnect.git - branch = v3.1.1 + branch = v3.1.3 platforms = silabs [submodule "editline"] path = third_party/editline/repo diff --git a/examples/platform/silabs/efr32/rs911x/hal/efx32_ncp_host.c b/examples/platform/silabs/efr32/rs911x/hal/efx32_ncp_host.c index 414153ecd0164c..82976deb6a3b09 100644 --- a/examples/platform/silabs/efr32/rs911x/hal/efx32_ncp_host.c +++ b/examples/platform/silabs/efr32/rs911x/hal/efx32_ncp_host.c @@ -15,7 +15,6 @@ * ******************************************************************************/ -#include "FreeRTOS.h" #include "cmsis_os2.h" #include "dmadrv.h" #include "em_cmu.h" @@ -37,13 +36,16 @@ #include "sl_power_manager.h" #endif +#define USART_INITSYNC_BAUDRATE 12500000 + static bool dma_callback(unsigned int channel, unsigned int sequenceNo, void * userParam); unsigned int rx_ldma_channel; unsigned int tx_ldma_channel; -osMutexId_t spi_transfer_mutex = 0; +osMutexId_t ncp_transfer_mutex = 0; static uint32_t dummy_buffer; +static sl_si91x_host_init_configuration init_config = { 0 }; // LDMA descriptor and transfer configuration structures for USART TX channel LDMA_Descriptor_t ldmaTXDescriptor; @@ -70,33 +72,22 @@ static bool dma_callback(unsigned int channel, unsigned int sequenceNo, void * u static void gpio_interrupt(uint8_t interrupt_number) { UNUSED_PARAMETER(interrupt_number); - sl_si91x_host_set_bus_event(NCP_HOST_BUS_RX_EVENT); - // GPIO_IntClear(0xAAAA); -} - -void sl_si91x_host_set_sleep_indicator(void) -{ - GPIO_PinOutSet(SLEEP_CONFIRM_PIN.port, SLEEP_CONFIRM_PIN.pin); -} -void sl_si91x_host_clear_sleep_indicator(void) -{ - GPIO_PinOutClear(SLEEP_CONFIRM_PIN.port, SLEEP_CONFIRM_PIN.pin); + if (NULL != init_config.rx_irq) + { + init_config.rx_irq(); + } } -uint32_t sl_si91x_host_get_wake_indicator(void) +static void efx32_spi_init(void) { - return GPIO_PinInGet(WAKE_INDICATOR_PIN.port, WAKE_INDICATOR_PIN.pin); -} + // Default asynchronous initializer (master mode, 1 Mbps, 8-bit data) + USART_InitSync_TypeDef init = USART_INITSYNC_DEFAULT; -sl_status_t sl_si91x_host_init(void) -{ - // Enable clock (not needed on xG21) - CMU_ClockEnable(cmuClock_GPIO, true); + init.msbf = true; // MSB first transmission for SPI compatibility + init.autoCsEnable = true; // Allow the USART to assert CS + init.baudrate = USART_INITSYNC_BAUDRATE; -#if SL_SPICTRL_MUX - spi_board_init(); -#endif // Configure SPI bus pins GPIO_PinModeSet(SPI_MISO_PIN.port, SPI_MISO_PIN.pin, gpioModeInput, 0); GPIO_PinModeSet(SPI_MOSI_PIN.port, SPI_MOSI_PIN.pin, gpioModePushPull, 0); @@ -105,12 +96,6 @@ sl_status_t sl_si91x_host_init(void) // Enable clock (not needed on xG21) CMU_ClockEnable(SPI_USART_CMU_CLOCK, true); - // Default asynchronous initializer (master mode, 1 Mbps, 8-bit data) - USART_InitSync_TypeDef init = USART_INITSYNC_DEFAULT; - - init.msbf = true; // MSB first transmission for SPI compatibility - init.autoCsEnable = true; // Allow the USART to assert CS - init.baudrate = 12500000; /* * Route USART RX, TX, and CLK to the specified pins. Note that CS is * not controlled by USART so there is no write to the corresponding @@ -139,33 +124,64 @@ sl_status_t sl_si91x_host_init(void) SPI_USART->TIMING |= /*USART_TIMING_TXDELAY_ONE | USART_TIMING_CSSETUP_ONE |*/ USART_TIMING_CSHOLD_ONE; // SPI_USART->CTRL_SET |= USART_CTRL_SMSDELAY; + + // configure packet pending interrupt priority + NVIC_SetPriority(GPIO_ODD_IRQn, PACKET_PENDING_INT_PRI); + GPIOINT_CallbackRegister(INTERRUPT_PIN.pin, gpio_interrupt); + GPIO_PinModeSet(INTERRUPT_PIN.port, INTERRUPT_PIN.pin, gpioModeInputPullFilter, 0); + GPIO_ExtIntConfig(INTERRUPT_PIN.port, INTERRUPT_PIN.pin, INTERRUPT_PIN.pin, true, false, true); +} + +void sl_si91x_host_set_sleep_indicator(void) +{ + GPIO_PinOutSet(SLEEP_CONFIRM_PIN.port, SLEEP_CONFIRM_PIN.pin); +} + +void sl_si91x_host_clear_sleep_indicator(void) +{ + GPIO_PinOutClear(SLEEP_CONFIRM_PIN.port, SLEEP_CONFIRM_PIN.pin); +} + +uint32_t sl_si91x_host_get_wake_indicator(void) +{ + return GPIO_PinInGet(WAKE_INDICATOR_PIN.port, WAKE_INDICATOR_PIN.pin); +} + +sl_status_t sl_si91x_host_init(sl_si91x_host_init_configuration * config) +{ + init_config.rx_irq = config->rx_irq; + init_config.rx_done = config->rx_done; + + // Enable clock (not needed on xG21) + CMU_ClockEnable(cmuClock_GPIO, true); + +#if SL_SPICTRL_MUX + spi_board_init(); +#endif + if (transfer_done_semaphore == NULL) { transfer_done_semaphore = osSemaphoreNew(1, 0, NULL); } - if (spi_transfer_mutex == 0) + if (ncp_transfer_mutex == 0) { - spi_transfer_mutex = osMutexNew(NULL); + ncp_transfer_mutex = osMutexNew(NULL); } - DMADRV_Init(); - DMADRV_AllocateChannel(&rx_ldma_channel, NULL); - DMADRV_AllocateChannel(&tx_ldma_channel, NULL); + efx32_spi_init(); // Start reset line low GPIO_PinModeSet(RESET_PIN.port, RESET_PIN.pin, gpioModePushPull, 0); - // configure packet pending interrupt priority - NVIC_SetPriority(GPIO_ODD_IRQn, PACKET_PENDING_INT_PRI); - // Configure interrupt, sleep and wake confirmation pins - GPIOINT_CallbackRegister(INTERRUPT_PIN.pin, gpio_interrupt); - GPIO_PinModeSet(INTERRUPT_PIN.port, INTERRUPT_PIN.pin, gpioModeInputPullFilter, 0); - GPIO_ExtIntConfig(INTERRUPT_PIN.port, INTERRUPT_PIN.pin, INTERRUPT_PIN.pin, true, false, true); GPIO_PinModeSet(SLEEP_CONFIRM_PIN.port, SLEEP_CONFIRM_PIN.pin, gpioModeWiredOrPullDown, 1); GPIO_PinModeSet(WAKE_INDICATOR_PIN.port, WAKE_INDICATOR_PIN.pin, gpioModeWiredOrPullDown, 0); + DMADRV_Init(); + DMADRV_AllocateChannel(&rx_ldma_channel, NULL); + DMADRV_AllocateChannel(&tx_ldma_channel, NULL); + return SL_STATUS_OK; } @@ -174,11 +190,7 @@ sl_status_t sl_si91x_host_deinit(void) return SL_STATUS_OK; } -void sl_si91x_host_enable_high_speed_bus() -{ - // SPI_USART->CTRL_SET |= USART_CTRL_SMSDELAY | USART_CTRL_SSSEARLY; - // USART_BaudrateSyncSet(SPI_USART, 0, 20000000); -} +void sl_si91x_host_enable_high_speed_bus() {} /*==================================================================*/ /** @@ -194,7 +206,7 @@ void sl_si91x_host_enable_high_speed_bus() */ sl_status_t sl_si91x_host_spi_transfer(const void * tx_buffer, void * rx_buffer, uint16_t buffer_length) { - osMutexAcquire(spi_transfer_mutex, 0xFFFFFFFFUL); + osMutexAcquire(ncp_transfer_mutex, 0xFFFFFFFFUL); #if SL_SPICTRL_MUX sl_wfx_host_spi_cs_assert(); @@ -268,7 +280,7 @@ sl_status_t sl_si91x_host_spi_transfer(const void * tx_buffer, void * rx_buffer, } } - osMutexRelease(spi_transfer_mutex); + osMutexRelease(ncp_transfer_mutex); #if SL_SPICTRL_MUX sl_wfx_host_spi_cs_deassert(); #endif // SL_SPICTRL_MUX @@ -288,6 +300,7 @@ void sl_si91x_host_release_from_reset(void) void sl_si91x_host_enable_bus_interrupt(void) { + NVIC_ClearPendingIRQ(GPIO_ODD_IRQn); NVIC_EnableIRQ(GPIO_ODD_IRQn); } diff --git a/examples/platform/silabs/efr32/rs911x/rs9117.gni b/examples/platform/silabs/efr32/rs911x/rs9117.gni index 251de0be213fe6..5a561c9f201eab 100644 --- a/examples/platform/silabs/efr32/rs911x/rs9117.gni +++ b/examples/platform/silabs/efr32/rs911x/rs9117.gni @@ -27,7 +27,8 @@ rs9117_src_sapi = [ "${wifi_sdk_root}/components/device/silabs/si91x/wireless/sl_net/src/sl_net_rsi_utility.c", "${wifi_sdk_root}/components/device/silabs/si91x/wireless/sl_net/src/sl_net_si91x_integration_handler.c", "${wifi_sdk_root}/components/device/silabs/si91x/wireless/sl_net/src/sl_si91x_net_credentials.c", - "${wifi_sdk_root}/components/device/silabs/si91x/wireless/spi_interface/sl_si91x_spi_driver.c", + "${wifi_sdk_root}/components/device/silabs/si91x/wireless/ncp_interface/spi/sl_si91x_spi.c", + "${wifi_sdk_root}/components/device/silabs/si91x/wireless/ncp_interface/sl_si91x_ncp_driver.c", # wifi component "${wifi_sdk_root}/components/protocol/wifi/src/sl_wifi_callback_framework.c", diff --git a/examples/platform/silabs/efr32/wf200/host_if.cpp b/examples/platform/silabs/efr32/wf200/host_if.cpp index 3240c2642a3080..041a1778421ed3 100644 --- a/examples/platform/silabs/efr32/wf200/host_if.cpp +++ b/examples/platform/silabs/efr32/wf200/host_if.cpp @@ -607,7 +607,7 @@ static void wfx_events_task(void * p_arg) { // Enable the power save SILABS_LOG("WF200 going to DTIM based sleep"); - sl_wfx_set_power_mode(WFM_PM_MODE_DTIM, WFM_PM_POLL_FAST_PS, BEACON_1); + sl_wfx_set_power_mode(WFM_PM_MODE_DTIM, WFM_PM_POLL_FAST_PS, BEACON_1, 0 /*timeout*/); sl_wfx_enable_device_power_save(); } #endif /* CHIP_CONFIG_ENABLE_ICD_SERVER */ diff --git a/src/platform/silabs/SilabsConfig.cpp b/src/platform/silabs/SilabsConfig.cpp index d15fef86b7985c..f98ced75a3e1d8 100644 --- a/src/platform/silabs/SilabsConfig.cpp +++ b/src/platform/silabs/SilabsConfig.cpp @@ -33,6 +33,7 @@ #include #include +#ifndef SIWX_917 // 917soc/wifi-sdk implements the same nvm3 lock/unlock mechanism and it currently can't be overide. #include #include // Substitute the GSDK weak nvm3_lockBegin and nvm3_lockEnd @@ -57,6 +58,7 @@ void nvm3_lockEnd(void) VerifyOrDie(nvm3_Sem != NULL); xSemaphoreGive(nvm3_Sem); } +#endif // !SIWX_917 namespace chip { namespace DeviceLayer { @@ -76,9 +78,9 @@ CHIP_ERROR SilabsConfig::Init() void SilabsConfig::DeInit() { -#ifndef BRD4325A // TODO: fix semaphore usage in nvm3_lock for siwx917. use weak implementation for that board instead +#ifndef SIWX_917 vSemaphoreDelete(nvm3_Sem); -#endif // not BRD4325A +#endif // !SIWX_917 nvm3_close(nvm3_defaultHandle); } diff --git a/third_party/silabs/efr32_sdk.gni b/third_party/silabs/efr32_sdk.gni index bed0a1e43c308d..9868b47efb8a8d 100644 --- a/third_party/silabs/efr32_sdk.gni +++ b/third_party/silabs/efr32_sdk.gni @@ -916,11 +916,11 @@ template("efr32_sdk") { "${efr32_sdk_root}/platform/security/sl_component/sl_mbedtls_support/src/crypto_aes.c", "${efr32_sdk_root}/platform/security/sl_component/sl_protocol_crypto/src/sli_protocol_crypto_crypto.c", "${efr32_sdk_root}/platform/security/sl_component/sl_psa_driver/src/crypto_management.c", + "${efr32_sdk_root}/platform/security/sl_component/sl_psa_driver/src/sli_crypto_driver_trng.c", "${efr32_sdk_root}/platform/security/sl_component/sl_psa_driver/src/sli_crypto_transparent_driver_aead.c", "${efr32_sdk_root}/platform/security/sl_component/sl_psa_driver/src/sli_crypto_transparent_driver_cipher.c", "${efr32_sdk_root}/platform/security/sl_component/sl_psa_driver/src/sli_crypto_transparent_driver_hash.c", "${efr32_sdk_root}/platform/security/sl_component/sl_psa_driver/src/sli_crypto_transparent_driver_mac.c", - "${efr32_sdk_root}/platform/security/sl_component/sl_psa_driver/src/sli_crypto_trng_driver.c", "${efr32_sdk_root}/platform/service/device_init/src/sl_device_init_dcdc_s1.c", "${efr32_sdk_root}/platform/service/device_init/src/sl_device_init_emu_s1.c", "${efr32_sdk_root}/platform/service/device_init/src/sl_device_init_hfxo_s1.c", diff --git a/third_party/silabs/gecko_sdk b/third_party/silabs/gecko_sdk index 124fa19de8c8b3..911f6cdefccbae 160000 --- a/third_party/silabs/gecko_sdk +++ b/third_party/silabs/gecko_sdk @@ -1 +1 @@ -Subproject commit 124fa19de8c8b3961d21c20857f7df32239786da +Subproject commit 911f6cdefccbae03bc66e8c790ceb7e67ca07417 diff --git a/third_party/silabs/matter_support b/third_party/silabs/matter_support index 70800e2f6d5fbc..53f098de9fdc7d 160000 --- a/third_party/silabs/matter_support +++ b/third_party/silabs/matter_support @@ -1 +1 @@ -Subproject commit 70800e2f6d5fbc972d22387fd4969a92568b455b +Subproject commit 53f098de9fdc7db248a72eabbe07d8ce4876daab diff --git a/third_party/silabs/wifi_sdk b/third_party/silabs/wifi_sdk index a63c4cd9c4d5cc..00dd57a85e0982 160000 --- a/third_party/silabs/wifi_sdk +++ b/third_party/silabs/wifi_sdk @@ -1 +1 @@ -Subproject commit a63c4cd9c4d5cc63c0d8c6d89c35c0891fc47bf8 +Subproject commit 00dd57a85e0982f85a41d029e15050479f69256b From 3258b46218889d6df56dcb88cf787bec94f13d5e Mon Sep 17 00:00:00 2001 From: Andrei Litvin Date: Fri, 16 Feb 2024 13:25:35 -0500 Subject: [PATCH 09/33] Removed provisional tag from `Fan Control Cluster` (#32174) This is not provisional since https://github.com/CHIP-Specifications/connectedhomeip-spec/pull/8597 --- .../air-purifier-common/air-purifier-app.matter | 2 +- .../all-clusters-common/all-clusters-app.matter | 2 +- .../all-clusters-common/all-clusters-minimal-app.matter | 2 +- examples/chef/devices/rootnode_airpurifier_73a6fe2651.matter | 2 +- ...emperaturesensor_humiditysensor_thermostat_56de3d5f45.matter | 2 +- examples/chef/devices/rootnode_fan_7N2TobIlOX.matter | 2 +- .../chef/devices/rootnode_heatingcoolingunit_ncdGai1E5a.matter | 2 +- .../chef/devices/rootnode_roomairconditioner_9cf3607804.matter | 2 +- examples/chef/devices/rootnode_thermostat_bm3fb8dhYi.matter | 2 +- .../zap-templates/zcl/data-model/chip/fan-control-cluster.xml | 2 +- src/controller/data_model/controller-clusters.matter | 2 +- 11 files changed, 11 insertions(+), 11 deletions(-) diff --git a/examples/air-purifier-app/air-purifier-common/air-purifier-app.matter b/examples/air-purifier-app/air-purifier-common/air-purifier-app.matter index a801aac5943356..caedd98bf1be48 100644 --- a/examples/air-purifier-app/air-purifier-common/air-purifier-app.matter +++ b/examples/air-purifier-app/air-purifier-common/air-purifier-app.matter @@ -1595,7 +1595,7 @@ cluster Thermostat = 513 { } /** An interface for controlling a fan in a heating/cooling system. */ -provisional cluster FanControl = 514 { +cluster FanControl = 514 { revision 4; enum AirflowDirectionEnum : enum8 { diff --git a/examples/all-clusters-app/all-clusters-common/all-clusters-app.matter b/examples/all-clusters-app/all-clusters-common/all-clusters-app.matter index 79367dbbf1075c..62dc0d7d84c3fa 100644 --- a/examples/all-clusters-app/all-clusters-common/all-clusters-app.matter +++ b/examples/all-clusters-app/all-clusters-common/all-clusters-app.matter @@ -5268,7 +5268,7 @@ cluster Thermostat = 513 { } /** An interface for controlling a fan in a heating/cooling system. */ -provisional cluster FanControl = 514 { +cluster FanControl = 514 { revision 4; enum AirflowDirectionEnum : enum8 { diff --git a/examples/all-clusters-minimal-app/all-clusters-common/all-clusters-minimal-app.matter b/examples/all-clusters-minimal-app/all-clusters-common/all-clusters-minimal-app.matter index fe32702e2c847d..dbb244cf6265b3 100644 --- a/examples/all-clusters-minimal-app/all-clusters-common/all-clusters-minimal-app.matter +++ b/examples/all-clusters-minimal-app/all-clusters-common/all-clusters-minimal-app.matter @@ -3861,7 +3861,7 @@ cluster Thermostat = 513 { } /** An interface for controlling a fan in a heating/cooling system. */ -provisional cluster FanControl = 514 { +cluster FanControl = 514 { revision 4; enum AirflowDirectionEnum : enum8 { diff --git a/examples/chef/devices/rootnode_airpurifier_73a6fe2651.matter b/examples/chef/devices/rootnode_airpurifier_73a6fe2651.matter index 554cdfa7e42e23..bcc9bd054ff722 100644 --- a/examples/chef/devices/rootnode_airpurifier_73a6fe2651.matter +++ b/examples/chef/devices/rootnode_airpurifier_73a6fe2651.matter @@ -1250,7 +1250,7 @@ cluster ActivatedCarbonFilterMonitoring = 114 { } /** An interface for controlling a fan in a heating/cooling system. */ -provisional cluster FanControl = 514 { +cluster FanControl = 514 { revision 4; enum AirflowDirectionEnum : enum8 { diff --git a/examples/chef/devices/rootnode_airpurifier_airqualitysensor_temperaturesensor_humiditysensor_thermostat_56de3d5f45.matter b/examples/chef/devices/rootnode_airpurifier_airqualitysensor_temperaturesensor_humiditysensor_thermostat_56de3d5f45.matter index 734ed039932a9f..e827ce800b081d 100644 --- a/examples/chef/devices/rootnode_airpurifier_airqualitysensor_temperaturesensor_humiditysensor_thermostat_56de3d5f45.matter +++ b/examples/chef/devices/rootnode_airpurifier_airqualitysensor_temperaturesensor_humiditysensor_thermostat_56de3d5f45.matter @@ -1518,7 +1518,7 @@ cluster Thermostat = 513 { } /** An interface for controlling a fan in a heating/cooling system. */ -provisional cluster FanControl = 514 { +cluster FanControl = 514 { revision 4; enum AirflowDirectionEnum : enum8 { diff --git a/examples/chef/devices/rootnode_fan_7N2TobIlOX.matter b/examples/chef/devices/rootnode_fan_7N2TobIlOX.matter index 71d511aedcc508..097015b4634695 100644 --- a/examples/chef/devices/rootnode_fan_7N2TobIlOX.matter +++ b/examples/chef/devices/rootnode_fan_7N2TobIlOX.matter @@ -1286,7 +1286,7 @@ cluster FixedLabel = 64 { } /** An interface for controlling a fan in a heating/cooling system. */ -provisional cluster FanControl = 514 { +cluster FanControl = 514 { revision 4; enum AirflowDirectionEnum : enum8 { diff --git a/examples/chef/devices/rootnode_heatingcoolingunit_ncdGai1E5a.matter b/examples/chef/devices/rootnode_heatingcoolingunit_ncdGai1E5a.matter index d1aee2ea4e8135..bcef3bca0f1b1e 100644 --- a/examples/chef/devices/rootnode_heatingcoolingunit_ncdGai1E5a.matter +++ b/examples/chef/devices/rootnode_heatingcoolingunit_ncdGai1E5a.matter @@ -1875,7 +1875,7 @@ cluster Thermostat = 513 { } /** An interface for controlling a fan in a heating/cooling system. */ -provisional cluster FanControl = 514 { +cluster FanControl = 514 { revision 4; enum AirflowDirectionEnum : enum8 { diff --git a/examples/chef/devices/rootnode_roomairconditioner_9cf3607804.matter b/examples/chef/devices/rootnode_roomairconditioner_9cf3607804.matter index de4a1c961cd506..0aa08d68385f6d 100644 --- a/examples/chef/devices/rootnode_roomairconditioner_9cf3607804.matter +++ b/examples/chef/devices/rootnode_roomairconditioner_9cf3607804.matter @@ -1458,7 +1458,7 @@ cluster Thermostat = 513 { } /** An interface for controlling a fan in a heating/cooling system. */ -provisional cluster FanControl = 514 { +cluster FanControl = 514 { revision 4; enum AirflowDirectionEnum : enum8 { diff --git a/examples/chef/devices/rootnode_thermostat_bm3fb8dhYi.matter b/examples/chef/devices/rootnode_thermostat_bm3fb8dhYi.matter index fdefbfc5c9dbee..ce01f50bd303e7 100644 --- a/examples/chef/devices/rootnode_thermostat_bm3fb8dhYi.matter +++ b/examples/chef/devices/rootnode_thermostat_bm3fb8dhYi.matter @@ -1678,7 +1678,7 @@ cluster Thermostat = 513 { } /** An interface for controlling a fan in a heating/cooling system. */ -provisional cluster FanControl = 514 { +cluster FanControl = 514 { revision 4; enum AirflowDirectionEnum : enum8 { diff --git a/src/app/zap-templates/zcl/data-model/chip/fan-control-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/fan-control-cluster.xml index ad6279b2ef65e2..c2deff336eae46 100644 --- a/src/app/zap-templates/zcl/data-model/chip/fan-control-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/fan-control-cluster.xml @@ -73,7 +73,7 @@ limitations under the License. - + Fan Control HVAC An interface for controlling a fan in a heating/cooling system. diff --git a/src/controller/data_model/controller-clusters.matter b/src/controller/data_model/controller-clusters.matter index b9ce299a283f57..89864630b8e85e 100644 --- a/src/controller/data_model/controller-clusters.matter +++ b/src/controller/data_model/controller-clusters.matter @@ -6474,7 +6474,7 @@ cluster Thermostat = 513 { } /** An interface for controlling a fan in a heating/cooling system. */ -provisional cluster FanControl = 514 { +cluster FanControl = 514 { revision 4; enum AirflowDirectionEnum : enum8 { From a609e596cfbe2133f6d2448489d60524efd49dd3 Mon Sep 17 00:00:00 2001 From: Terence Hampson Date: Fri, 16 Feb 2024 13:36:29 -0500 Subject: [PATCH 10/33] Add nlfaultinjection version of the all clusters app (#32179) --- integrations/docker/images/chip-cert-bins/Dockerfile | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/integrations/docker/images/chip-cert-bins/Dockerfile b/integrations/docker/images/chip-cert-bins/Dockerfile index 553b3d65718e16..33662e66d3a9ba 100644 --- a/integrations/docker/images/chip-cert-bins/Dockerfile +++ b/integrations/docker/images/chip-cert-bins/Dockerfile @@ -180,6 +180,7 @@ RUN case ${TARGETPLATFORM} in \ --target linux-x64-shell-ipv6only-platform-mdns \ --target linux-x64-chip-cert-ipv6only-platform-mdns \ --target linux-x64-all-clusters-ipv6only \ + --target linux-x64-all-clusters-ipv6only-nlfaultinject \ --target linux-x64-all-clusters-minimal-ipv6only \ --target linux-x64-bridge-ipv6only \ --target linux-x64-tv-app-ipv6only \ @@ -198,6 +199,7 @@ RUN case ${TARGETPLATFORM} in \ && mv out/linux-x64-shell-ipv6only-platform-mdns/chip-shell out/chip-shell \ && mv out/linux-x64-chip-cert-ipv6only-platform-mdns/chip-cert out/chip-cert \ && mv out/linux-x64-all-clusters-ipv6only/chip-all-clusters-app out/chip-all-clusters-app \ + && mv out/linux-x64-all-clusters-ipv6only-nlfaultinject/chip-all-clusters-app out/chip-all-clusters-app-nlfaultinject \ && mv out/linux-x64-all-clusters-minimal-ipv6only/chip-all-clusters-minimal-app out/chip-all-clusters-minimal-app \ && mv out/linux-x64-bridge-ipv6only/chip-bridge-app out/chip-bridge-app \ && mv out/linux-x64-tv-app-ipv6only/chip-tv-app out/chip-tv-app \ @@ -220,6 +222,7 @@ RUN case ${TARGETPLATFORM} in \ --target linux-arm64-shell-ipv6only-platform-mdns \ --target linux-arm64-chip-cert-ipv6only-platform-mdns \ --target linux-arm64-all-clusters-ipv6only \ + --target linux-arm64-all-clusters-ipv6only-nlfaultinject \ --target linux-arm64-all-clusters-minimal-ipv6only \ --target linux-arm64-bridge-ipv6only \ --target linux-arm64-tv-app-ipv6only \ @@ -238,6 +241,7 @@ RUN case ${TARGETPLATFORM} in \ && mv out/linux-arm64-shell-ipv6only-platform-mdns/chip-shell out/chip-shell \ && mv out/linux-arm64-chip-cert-ipv6only-platform-mdns/chip-cert out/chip-cert \ && mv out/linux-arm64-all-clusters-ipv6only/chip-all-clusters-app out/chip-all-clusters-app \ + && mv out/linux-arm64-all-clusters-ipv6only-nlfaultinject/chip-all-clusters-app out/chip-all-clusters-app-nlfaultinject \ && mv out/linux-arm64-all-clusters-minimal-ipv6only/chip-all-clusters-minimal-app out/chip-all-clusters-minimal-app \ && mv out/linux-arm64-bridge-ipv6only/chip-bridge-app out/chip-bridge-app \ && mv out/linux-arm64-tv-app-ipv6only/chip-tv-app out/chip-tv-app \ @@ -269,6 +273,7 @@ COPY --from=chip-build-cert-bins /root/connectedhomeip/out/chip-tool chip-tool COPY --from=chip-build-cert-bins /root/connectedhomeip/out/chip-shell chip-shell COPY --from=chip-build-cert-bins /root/connectedhomeip/out/chip-cert chip-cert COPY --from=chip-build-cert-bins /root/connectedhomeip/out/chip-all-clusters-app chip-all-clusters-app +COPY --from=chip-build-cert-bins /root/connectedhomeip/out/chip-all-clusters-app-nlfaultinject chip-all-clusters-app-nlfaultinject COPY --from=chip-build-cert-bins /root/connectedhomeip/out/chip-all-clusters-minimal-app chip-all-clusters-minimal-app COPY --from=chip-build-cert-bins /root/connectedhomeip/out/chip-lighting-app chip-lighting-app COPY --from=chip-build-cert-bins /root/connectedhomeip/out/chip-tv-casting-app chip-tv-casting-app From d8f53c80d297aedd1b73042be430ee26fd2fd2d8 Mon Sep 17 00:00:00 2001 From: C Freeman Date: Fri, 16 Feb 2024 13:39:18 -0500 Subject: [PATCH 11/33] TC-ACE-2.1/2.2: Remove workaround for fixed scraper bug (#32158) Test: Manually verified the python code gets the correct value from the spec XML now. TC-ACE-2.1 and 2.2 pass. --- src/python_testing/spec_parsing_support.py | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/python_testing/spec_parsing_support.py b/src/python_testing/spec_parsing_support.py index 3a784178cdb880..3d6cedfb4da8bf 100644 --- a/src/python_testing/spec_parsing_support.py +++ b/src/python_testing/spec_parsing_support.py @@ -512,12 +512,6 @@ def remove_problem(location: typing.Union[CommandPathLocation, FeaturePathLocati 0x05: XmlAttribute(name='SupportedTemperatureLevels', datatype='list', conformance=feature(0x02, 'TL'), read_access=view, write_access=none, write_optional=False), } - # Workaround for incorrect parsing of access control cluster. - # Remove this workaround when https://github.com/csa-data-model/projects/issues/397 is fixed. - acl_id = Clusters.AccessControl.id - clusters[acl_id].attributes[Clusters.AccessControl.Attributes.Acl.attribute_id].write_access = Clusters.AccessControl.Enums.AccessControlEntryPrivilegeEnum.kAdminister - clusters[acl_id].attributes[Clusters.AccessControl.Attributes.Extension.attribute_id].write_access = Clusters.AccessControl.Enums.AccessControlEntryPrivilegeEnum.kAdminister - check_clusters_for_unknown_commands(clusters, problems) return clusters, problems From 39b2382c32129e52ecf394dd487063c7b93f01a5 Mon Sep 17 00:00:00 2001 From: adabreuti <76965454+adabreuti@users.noreply.github.com> Date: Fri, 16 Feb 2024 13:06:21 -0600 Subject: [PATCH 12/33] SHA-256 Stream Clear API to call lower level mbedtls free (#31607) * Update MBEDTLS SHA-256 Clear to call lower level HW implementation * Enable Power maangement for SHA-256 HW accel on TI platforms * Revert "Enable Power maangement for SHA-256 HW accel on TI platforms" This reverts commit db270a368b2c36fb5ddfbbdedc9c733e66d960d0. --- src/crypto/CHIPCryptoPALmbedTLS.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/crypto/CHIPCryptoPALmbedTLS.cpp b/src/crypto/CHIPCryptoPALmbedTLS.cpp index d7e0dee28edea6..4df0ce97e30989 100644 --- a/src/crypto/CHIPCryptoPALmbedTLS.cpp +++ b/src/crypto/CHIPCryptoPALmbedTLS.cpp @@ -199,8 +199,6 @@ Hash_SHA256_stream::Hash_SHA256_stream() Hash_SHA256_stream::~Hash_SHA256_stream() { - mbedtls_sha256_context * context = to_inner_hash_sha256_context(&mContext); - mbedtls_sha256_free(context); Clear(); } @@ -272,6 +270,9 @@ CHIP_ERROR Hash_SHA256_stream::Finish(MutableByteSpan & out_buffer) void Hash_SHA256_stream::Clear() { + mbedtls_sha256_context * context = to_inner_hash_sha256_context(&mContext); + mbedtls_sha256_free(context); + mbedtls_platform_zeroize(this, sizeof(*this)); } From 573511d733210bb253d9c2014d79a02b7a5671a4 Mon Sep 17 00:00:00 2001 From: Matthew Swartwout Date: Fri, 16 Feb 2024 11:17:32 -0800 Subject: [PATCH 13/33] Delete Concrete(Read|Data)AttributePath equality operator (#32131) * Delete Concrete(Read|Data)AttributePath equality operator Right now these default to using the ConcreteAttributePath equality operator, which is misleading because it will return true for objects which are not actually equal. Replace this with the MatchesConcreteAttributePath function. A new equality operator for these classes will be introduced in a follow-up PR. I'm introducing this change separately to ensure that CI catches any current usage of the equality operator. * Restyled by clang-format * Add unit tests * Restyled by clang-format --------- Co-authored-by: Restyled.io --- src/app/ConcreteAttributePath.h | 10 +++ src/app/ReadClient.cpp | 5 +- src/app/tests/BUILD.gn | 1 + src/app/tests/TestConcreteAttributePath.cpp | 94 +++++++++++++++++++++ 4 files changed, 107 insertions(+), 3 deletions(-) create mode 100644 src/app/tests/TestConcreteAttributePath.cpp diff --git a/src/app/ConcreteAttributePath.h b/src/app/ConcreteAttributePath.h index 076575dcafa2a1..253b590ef90739 100644 --- a/src/app/ConcreteAttributePath.h +++ b/src/app/ConcreteAttributePath.h @@ -87,6 +87,10 @@ struct ConcreteReadAttributePath : public ConcreteAttributePath mListIndex.SetValue(aListIndex); } + bool operator==(const ConcreteReadAttributePath & aOther) const = delete; + bool operator!=(const ConcreteReadAttributePath & aOther) const = delete; + bool operator<(const ConcreteReadAttributePath & aOther) const = delete; + Optional mListIndex; }; @@ -138,6 +142,12 @@ struct ConcreteDataAttributePath : public ConcreteAttributePath ChipLogValueMEI(mClusterId), ChipLogValueMEI(mAttributeId)); } + bool MatchesConcreteAttributePath(const ConcreteAttributePath & aOther) { return ConcreteAttributePath::operator==(aOther); } + + bool operator==(const ConcreteDataAttributePath & aOther) const = delete; + bool operator!=(const ConcreteDataAttributePath & aOther) const = delete; + bool operator<(const ConcreteDataAttributePath & aOther) const = delete; + // // This index is only valid if `mListOp` is set to a list item operation, i.e // ReplaceItem, DeleteItem or AppendItem. Otherwise, it is to be ignored. diff --git a/src/app/ReadClient.cpp b/src/app/ReadClient.cpp index 4a123fe01b6291..57ef57362a25fa 100644 --- a/src/app/ReadClient.cpp +++ b/src/app/ReadClient.cpp @@ -799,9 +799,8 @@ CHIP_ERROR ReadClient::ProcessAttributeReportIBs(TLV::TLVReader & aAttributeRepo attributePath.mListOp = ConcreteDataAttributePath::ListOperation::ReplaceAll; } - if (attributePath == - ConcreteDataAttributePath(kRootEndpointId, Clusters::IcdManagement::Id, - Clusters::IcdManagement::Attributes::OperatingMode::Id)) + if (attributePath.MatchesConcreteAttributePath(ConcreteAttributePath( + kRootEndpointId, Clusters::IcdManagement::Id, Clusters::IcdManagement::Attributes::OperatingMode::Id))) { PeerType peerType; TLV::TLVReader operatingModeTlvReader; diff --git a/src/app/tests/BUILD.gn b/src/app/tests/BUILD.gn index be78dd8ade9e54..e4ab60329f218e 100644 --- a/src/app/tests/BUILD.gn +++ b/src/app/tests/BUILD.gn @@ -135,6 +135,7 @@ chip_test_suite_using_nltest("tests") { "TestClusterInfo.cpp", "TestCommandInteraction.cpp", "TestCommandPathParams.cpp", + "TestConcreteAttributePath.cpp", "TestDataModelSerialization.cpp", "TestDefaultOTARequestorStorage.cpp", "TestEventLoggingNoUTCTime.cpp", diff --git a/src/app/tests/TestConcreteAttributePath.cpp b/src/app/tests/TestConcreteAttributePath.cpp new file mode 100644 index 00000000000000..6e3451be26a78f --- /dev/null +++ b/src/app/tests/TestConcreteAttributePath.cpp @@ -0,0 +1,94 @@ +/* + * + * Copyright (c) 2024 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include + +using namespace chip; +using namespace chip::app; + +namespace { + +void TestConcreteAttributePathEqualityDefaultConstructor(nlTestSuite * aSuite, void * aContext) +{ + ConcreteAttributePath path_one; + ConcreteAttributePath path_two; + NL_TEST_ASSERT(aSuite, path_one == path_two); +} + +void TestConcreteAttributePathEquality(nlTestSuite * aSuite, void * aContext) +{ + ConcreteAttributePath path_one(/*aEndpointId=*/1, /*aClusterId=*/2, /*aAttributeId=*/3); + ConcreteAttributePath path_two(/*aEndpointId=*/1, /*aClusterId=*/2, /*aAttributeId=*/3); + NL_TEST_ASSERT(aSuite, path_one == path_two); +} + +void TestConcreteAttributePathInequalityDifferentAttributeId(nlTestSuite * aSuite, void * aContext) +{ + ConcreteAttributePath path_one(/*aEndpointId=*/1, /*aClusterId=*/2, /*aAttributeId=*/3); + ConcreteAttributePath path_two(/*aEndpointId=*/1, /*aClusterId=*/2, /*aAttributeId=*/4); + NL_TEST_ASSERT(aSuite, path_one != path_two); +} + +void TestConcreteDataAttributePathMatchesConcreteAttributePathEquality(nlTestSuite * aSuite, void * aContext) +{ + ConcreteAttributePath path(/*aEndpointId=*/1, /*aClusterId=*/2, /*aAttributeId=*/3); + ConcreteDataAttributePath data_path(/*aEndpointId=*/1, /*aClusterId=*/2, /*aAttributeId=*/3); + ConcreteDataAttributePath data_path_with_version(/*aEndpointId=*/1, /*aClusterId=*/2, /*aAttributeId=*/3, + /*aDataVersion=*/MakeOptional(4U)); + ConcreteDataAttributePath data_path_with_list(/*aEndpointId=*/1, /*aClusterId=*/2, /*aAttributeId=*/3, + /*aListOp=*/ConcreteDataAttributePath::ListOperation::ReplaceAll, + /*aListIndex=*/5U); + + NL_TEST_ASSERT(aSuite, data_path.MatchesConcreteAttributePath(path)); + NL_TEST_ASSERT(aSuite, data_path_with_version.MatchesConcreteAttributePath(path)); + NL_TEST_ASSERT(aSuite, data_path_with_list.MatchesConcreteAttributePath(path)); +} + +void TestConcreteDataAttributePathMatchesConcreteAttributePathInequality(nlTestSuite * aSuite, void * aContext) +{ + ConcreteAttributePath path(/*aEndpointId=*/1, /*aClusterId=*/2, /*aAttributeId=*/3); + ConcreteDataAttributePath data_path(/*aEndpointId=*/1, /*aClusterId=*/2, /*aAttributeId=*/4); + + NL_TEST_ASSERT(aSuite, !data_path.MatchesConcreteAttributePath(path)); +} + +const nlTest sTests[] = { + NL_TEST_DEF("TestConcreteAttributePathEqualityDefaultConstructor", TestConcreteAttributePathEqualityDefaultConstructor), + NL_TEST_DEF("TestConcreteAttributePathEquality", TestConcreteAttributePathEquality), + NL_TEST_DEF("TestConcreteAttributePathInequalityDifferentAttributeId", TestConcreteAttributePathInequalityDifferentAttributeId), + NL_TEST_DEF("TestConcreteDataAttributePathMatchesConcreteAttributePathEquality", + TestConcreteDataAttributePathMatchesConcreteAttributePathEquality), + NL_TEST_DEF("TestConcreteDataAttributePathMatchesConcreteAttributePathInequality", + TestConcreteDataAttributePathMatchesConcreteAttributePathInequality), + NL_TEST_SENTINEL() +}; + +} // anonymous namespace + +int TestConcreteAttributePath() +{ + nlTestSuite theSuite = { "ConcreteAttributePath", &sTests[0], nullptr, nullptr }; + + nlTestRunner(&theSuite, nullptr); + + return (nlTestRunnerStats(&theSuite)); +} + +CHIP_REGISTER_TEST_SUITE(TestConcreteAttributePath) From 2d3a221ecaba843986fcc00e480001d5f85a378b Mon Sep 17 00:00:00 2001 From: lpbeliveau-silabs <112982107+lpbeliveau-silabs@users.noreply.github.com> Date: Fri, 16 Feb 2024 16:22:43 -0500 Subject: [PATCH 14/33] Split overloaded steps 1b and 2d in 2_6 and added fabric removal for TH2 and TH3 at the end (#32177) --- .../suites/certification/Test_TC_S_2_6.yaml | 56 ++++++++++++++++--- 1 file changed, 47 insertions(+), 9 deletions(-) diff --git a/src/app/tests/suites/certification/Test_TC_S_2_6.yaml b/src/app/tests/suites/certification/Test_TC_S_2_6.yaml index 4c81d96190abfc..c3b5b6561bfd57 100644 --- a/src/app/tests/suites/certification/Test_TC_S_2_6.yaml +++ b/src/app/tests/suites/certification/Test_TC_S_2_6.yaml @@ -101,7 +101,7 @@ tests: CHIP:TOO: } disabled: true - - label: "Step 1b: Repeat Step 1a with TH2 and TH3." + - label: "Step 1b: Repeat Step 1a with TH2." PICS: S.S.C03.Rsp verification: | ./chip-tool scenesmanagement remove-all-scenes 0x0000 2 1 --commissioner-name beta @@ -116,7 +116,11 @@ tests: [1700826575.191974][15971:15973] CHIP:TOO: status: 0 [1700826575.191985][15971:15973] CHIP:TOO: groupID: 0 [1700826575.191995][15971:15973] CHIP:TOO: } + disabled: true + - label: "Step 1C: Repeat Step 1a with TH3." + PICS: S.S.C03.Rsp + verification: | ./chip-tool scenesmanagement remove-all-scenes 0x0000 3 1 --commissioner-name gamma Verify the RemoveAllScenesResponse with following fields: @@ -282,10 +286,10 @@ tests: [1701242801.625919][7636:7638] CHIP:TOO: RemainingCapacity: 7 [1701242801.625930][7636:7638] CHIP:TOO: FabricIndex: 2 [1701242801.625941][7636:7638] CHIP:TOO: } + disabled: true - - TH3: - + - label: "Step 2e: Repeat Step 2b and 2c with TH3." + verification: | Please use Interactive mode to Verify the subscription of an event Here the command to enter interactive mode:-- ./chip-tool interactive start @@ -966,11 +970,11 @@ tests: disabled: true - label: - Verify that the DUT sends a report data to TH2 for FabricSceneInfo - after the MinIntervalFloor time; store the RemainingCapacity field - from this fabric’s entry reported in FabricSceneInfo into - Remaining2ndCapacity; verify Remaining2ndCapacity equals - (MaxRemainingCapacity). + "Step 10b: Verify that the DUT sends a report data to TH2 for + FabricSceneInfo after the MinIntervalFloor time; store the + RemainingCapacity field from this fabric’s entry reported in + FabricSceneInfo into Remaining2ndCapacity; verify Remaining2ndCapacity + equals (MaxRemainingCapacity)." verification: | ./chip-tool scenesmanagement subscribe fabric-scene-info 100 200 2 1 --commissioner-name beta @@ -989,3 +993,37 @@ tests: [1705915866.717640][21433:21435] CHIP:TOO: } disabled: true + + - label: + "Step 11a: TH1 removes the TH2 fabric by sending the RemoveFabric + command to the DUT with the FabricIndex set to th2FabricIndex" + verification: | + ./chip-tool operationalcredentials remove-fabric th2FabricIndex 1 0 + + On TH1(chip-tool) verify the success with the nocresponse with statuscode is success(0) + + [1784416866.004187][21433:21435] CHIP:DMG: Received Command Response Data, Endpoint=0 Cluster=0x0000_003E Command=0x0000_0008 + [1784416866.004214][21433:21435] CHIP:TOO: Endpoint: 0 Cluster: 0x0000_003E Command 0x0000_0008 + [1784416866.004236][21433:21435] CHIP:TOO: NOCResponse: { + [1784416866.004250][21433:21435] CHIP:TOO: statusCode: 0 + [1784416866.004255][21433:21435] CHIP:TOO: fabricIndex: th2FabricIndex + [1784416866.004259][21433:21435] CHIP:TOO: } + [1784416866.004270][21433:21435] CHIP:DMG: ICR moving to [AwaitingDe] + disabled: true + + - label: + "Step 11b: TH1 removes the TH3 fabric by sending the RemoveFabric + command to the DUT with the FabricIndex set to th3FabricIndex" + verification: | + ./chip-tool operationalcredentials remove-fabric th3FabricIndex 1 0 + + On TH1(chip-tool) verify the success with the nocresponse with statuscode is success(0) + + [1784416866.004187][21433:21435] CHIP:DMG: Received Command Response Data, Endpoint=0 Cluster=0x0000_003E Command=0x0000_0008 + [1784416866.004214][21433:21435] CHIP:TOO: Endpoint: 0 Cluster: 0x0000_003E Command 0x0000_0008 + [1784416866.004236][21433:21435] CHIP:TOO: NOCResponse: { + [1784416866.004250][21433:21435] CHIP:TOO: statusCode: 0 + [1784416866.004255][21433:21435] CHIP:TOO: fabricIndex: th3FabricIndex + [1784416866.004259][21433:21435] CHIP:TOO: } + [1784416866.004270][21433:21435] CHIP:DMG: ICR moving to [AwaitingDe] + disabled: true From f7494fa3aaf220964d606f6e61a6132270cf4549 Mon Sep 17 00:00:00 2001 From: C Freeman Date: Fri, 16 Feb 2024 16:22:49 -0500 Subject: [PATCH 15/33] TC-IDM-10.2: Work around conformance for color control (#32157) Some attributes are using a non-standard conformance marker in the spec. For now, treat all these as optional and default to the color control cluster tests to properly verify these values. Test: Tested against the example lighting app. The app still HAS conformance issues, but these particular attribues are no longer listed as problems. --- src/python_testing/spec_parsing_support.py | 27 ++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/src/python_testing/spec_parsing_support.py b/src/python_testing/spec_parsing_support.py index 3d6cedfb4da8bf..9b65df0d0dcab5 100644 --- a/src/python_testing/spec_parsing_support.py +++ b/src/python_testing/spec_parsing_support.py @@ -496,6 +496,33 @@ def remove_problem(location: typing.Union[CommandPathLocation, FeaturePathLocati clusters[id] = new # TODO: All these fixups should be removed BEFORE SVE if at all possible + # Workaround for Color Control cluster - the spec uses a non-standard conformance. Set all to optional now, will need + # to implement either arithmetic conformance handling (once spec changes land here) or specific test + # https://github.com/CHIP-Specifications/connectedhomeip-spec/pull/7808 for spec changes. + # see 3.2.8. Defined Primaries Information Attribute Set, affects Primary<#>X/Y/Intensity attributes. + cc_id = Clusters.ColorControl.id + cc_attr = Clusters.ColorControl.Attributes + affected_attributes = [cc_attr.Primary1X, + cc_attr.Primary1Y, + cc_attr.Primary1Intensity, + cc_attr.Primary2X, + cc_attr.Primary2Y, + cc_attr.Primary2Intensity, + cc_attr.Primary3X, + cc_attr.Primary3Y, + cc_attr.Primary3Intensity, + cc_attr.Primary4X, + cc_attr.Primary4Y, + cc_attr.Primary4Intensity, + cc_attr.Primary5X, + cc_attr.Primary5Y, + cc_attr.Primary5Intensity, + cc_attr.Primary6X, + cc_attr.Primary6Y, + cc_attr.Primary6Intensity, + ] + for a in affected_attributes: + clusters[cc_id].attributes[a.attribute_id].conformance = optional() # Workaround for temp control cluster - this is parsed incorrectly in the DM XML and is missing all its attributes # Remove this workaround when https://github.com/csa-data-model/projects/issues/330 is fixed From 02cc3cb4d48d1a1adada88fa0dcb97a8a9536a56 Mon Sep 17 00:00:00 2001 From: adabreuti <76965454+adabreuti@users.noreply.github.com> Date: Fri, 16 Feb 2024 15:58:41 -0600 Subject: [PATCH 16/33] [TI] Protect AES Crypto Driver access for Matter (#32180) * Update TI AES HW Implementation to protect resource access * Enable AES HW Accel * Restyled by clang-format --------- Co-authored-by: Restyled.io --- src/platform/cc13xx_26xx/cc13x4_26x4/crypto/aes_alt.c | 7 ++++++- .../cc13x4_26x4/crypto/cc13x4_26x4-mbedtls-config.h | 2 +- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/platform/cc13xx_26xx/cc13x4_26x4/crypto/aes_alt.c b/src/platform/cc13xx_26xx/cc13x4_26x4/crypto/aes_alt.c index b6b790489a9916..91e9004dffdbac 100644 --- a/src/platform/cc13xx_26xx/cc13x4_26x4/crypto/aes_alt.c +++ b/src/platform/cc13xx_26xx/cc13x4_26x4/crypto/aes_alt.c @@ -26,6 +26,7 @@ #include #include +#include /* * number of active contexts, used for power on/off of the crypto core @@ -111,8 +112,11 @@ int mbedtls_aes_setkey_dec(mbedtls_aes_context * ctx, const unsigned char * key, int mbedtls_aes_crypt_ecb(mbedtls_aes_context * ctx, int mode, const unsigned char input[16], unsigned char output[16]) { int statusCrypto; + uint32_t key; AESECB_Operation operationOneStepEncrypt; + key = HwiP_disable(); + /* run it through the authentication + encryption, pass the ccmLVal = 2 */ AESECB_Operation_init(&operationOneStepEncrypt); @@ -125,9 +129,10 @@ int mbedtls_aes_crypt_ecb(mbedtls_aes_context * ctx, int mode, const unsigned ch if (CryptoKey_STATUS_SUCCESS != statusCrypto) { + HwiP_restore(key); return MBEDTLS_ERR_AES_HW_ACCEL_FAILED; } - + HwiP_restore(key); return 0; } #endif diff --git a/src/platform/cc13xx_26xx/cc13x4_26x4/crypto/cc13x4_26x4-mbedtls-config.h b/src/platform/cc13xx_26xx/cc13x4_26x4/crypto/cc13x4_26x4-mbedtls-config.h index 2ac87444764fd6..ce09760f8bf3dc 100644 --- a/src/platform/cc13xx_26xx/cc13x4_26x4/crypto/cc13x4_26x4-mbedtls-config.h +++ b/src/platform/cc13xx_26xx/cc13x4_26x4/crypto/cc13x4_26x4-mbedtls-config.h @@ -38,7 +38,7 @@ /* Enable Hardware Acceleration */ -// #define MBEDTLS_AES_ALT +#define MBEDTLS_AES_ALT // #define MBEDTLS_ECDH_COMPUTE_SHARED_ALT // #define MBEDTLS_ECDH_GEN_PUBLIC_ALT #define MBEDTLS_ECDSA_SIGN_ALT From 13f3e0525b88af723586770e4e93bb42dd42535b Mon Sep 17 00:00:00 2001 From: Tennessee Carmel-Veilleux Date: Fri, 16 Feb 2024 17:15:00 -0500 Subject: [PATCH 17/33] Introduce TC-CNET-4.4 automation (#32176) - Automate TC-CNET-4.4 per test plan. Testing done: - Ran against ESP32 and succeeded. Co-authored-by: cecille --- src/python_testing/TC_CNET_4_4.py | 132 ++++++++++++++++++++++++++++++ 1 file changed, 132 insertions(+) create mode 100644 src/python_testing/TC_CNET_4_4.py diff --git a/src/python_testing/TC_CNET_4_4.py b/src/python_testing/TC_CNET_4_4.py new file mode 100644 index 00000000000000..12407e6c5fd6b0 --- /dev/null +++ b/src/python_testing/TC_CNET_4_4.py @@ -0,0 +1,132 @@ +# +# Copyright (c) 2024 Project CHIP Authors +# All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +import logging +import random +import string +from typing import Optional + +import chip.clusters as Clusters +from chip.clusters.Types import NullValue +from matter_testing_support import MatterBaseTest, TestStep, async_test_body, default_matter_test_main, type_matches +from mobly import asserts + + +class TC_CNET_4_4(MatterBaseTest): + def steps_TC_CNET_4_4(self): + return [TestStep("precondition", "TH is commissioned", is_commissioning=True), + TestStep(1, 'TH reads from the DUT the Network Commissioning Cluster FeatureMap. If the FeatureMap does not include the WI flag (bit 0), skip the remaining steps in this test case'), + TestStep(2, 'TH reads from the DUT the SupportedWifiBands attribute and saves as supported_wifi_bands'), + TestStep(3, 'TH reads from the DUT the Networks attribute.'), + TestStep(4, 'TH sends ScanNetworks command to the DUT with the SSID field set to null and Breadcrumb field set to 1'), + TestStep(5, 'TH reads from the DUT the Breadcrumb attribute from the General Commissioning Cluster'), + TestStep(6, 'TH sends ScanNetworks Command to the DUT with SSID field set to known_ssid and Breadcrumb field set to 2'), + TestStep(7, 'TH reads Breadcrumb attribute from the General Commissioning Cluster'), + TestStep(8, 'TH sends ScanNetworks Command to the DUT with SSID field set to a string of 31 random alphabetical characters and Breadcrumb field set to 2')] + + def def_TC_CNET_4_4(self): + return '[TC-CNET-4.4] [Wi-Fi] Verification for ScanNetworks command [DUT-Server]' + + def pics_TC_CNET_4_4(self): + return ['CNET.S'] + + @async_test_body + async def test_TC_CNET_4_4(self): + # Commissioning is already done + self.step("precondition") + + cnet = Clusters.NetworkCommissioning + attr = cnet.Attributes + + self.step(1) + feature_map = await self.read_single_attribute_check_success(cluster=cnet, attribute=attr.FeatureMap) + if not (feature_map & cnet.Bitmaps.Feature.kWiFiNetworkInterface): + logging.info('Device does not support WiFi on endpoint, skipping remaining steps') + self.skip_all_remaining_steps(2) + return + + self.step(2) + supported_wifi_bands = await self.read_single_attribute_check_success(cluster=cnet, attribute=attr.SupportedWiFiBands) + + self.step(3) + networks = await self.read_single_attribute_check_success(cluster=cnet, attribute=attr.Networks) + connected = [network for network in networks if network.connected is True] + asserts.assert_greater_equal(len(connected), 1, "Did not find any connected networks on a commissioned device") + known_ssid = connected[0].networkID + + async def scan_and_check(ssid_to_scan: Optional[bytes], breadcrumb: int, expect_results: bool = True): + all_security = 0 + for security_bitmask in cnet.Bitmaps.WiFiSecurityBitmap: + all_security |= security_bitmask + + ssid = ssid_to_scan if ssid_to_scan is not None else NullValue + cmd = cnet.Commands.ScanNetworks(ssid=ssid, breadcrumb=breadcrumb) + scan_results = await self.send_single_cmd(cmd=cmd) + asserts.assert_true(type_matches(scan_results, cnet.Commands.ScanNetworksResponse), + "Unexpected value returned from scan network") + logging.info(f"Scan results: {scan_results}") + + if scan_results.debugText: + debug_text_len = len(scan_results.debug_text) + asserts.assert_less_equal(debug_text_len, 512, f"DebugText length {debug_text_len} was out of range") + + if expect_results: + asserts.assert_equal(scan_results.networkingStatus, cnet.Enums.NetworkCommissioningStatusEnum.kSuccess, + f"ScanNetworks was expected to have succeeded, got {scan_results.networkingStatus} instead") + asserts.assert_greater_equal(len(scan_results.wiFiScanResults), 1, "No responses returned from ScanNetwork command") + else: + asserts.assert_equal(scan_results.networkingStatus, cnet.Enums.NetworkCommissioningStatusEnum.kNetworkNotFound, + f"ScanNetworks was expected to received NetworkNotFound(5), got {scan_results.networkingStatus} instead") + return + + for network in scan_results.wiFiScanResults: + asserts.assert_true((network.security & ~all_security) == 0, "Unexpected bitmap in the security field") + asserts.assert_less_equal(len(network.ssid), 32, f"Returned SSID {network.ssid} is too long") + if ssid_to_scan is not None: + asserts.assert_equal(network.ssid, ssid_to_scan, "Unexpected SSID returned in directed scan") + asserts.assert_true(type_matches(network.bssid, bytes), "Incorrect type for BSSID") + asserts.assert_equal(len(network.bssid), 6, "Unexpected length of BSSID") + # TODO: this is inherited from the old test plan, but we should match the channel to the supported band. This range is unreasonably large. + asserts.assert_less_equal(network.channel, 65535, "Unexpected channel value") + if network.wiFiBand: + asserts.assert_true(network.wiFiBand in supported_wifi_bands, + "Listed wiFiBand is not in supported_wifi_bands") + if network.rssi: + asserts.assert_greater_equal(network.rssi, -120, "RSSI out of range") + asserts.assert_less_equal(network.rssi, 0, "RSSI out of range") + + self.step(4) + await scan_and_check(ssid_to_scan=None, breadcrumb=1, expect_results=True) + + self.step(5) + breadcrumb = await self.read_single_attribute_check_success(cluster=Clusters.GeneralCommissioning, attribute=Clusters.GeneralCommissioning.Attributes.Breadcrumb, endpoint=0) + asserts.assert_equal(breadcrumb, 1, "Incorrect breadcrumb value") + + self.step(6) + await scan_and_check(ssid_to_scan=known_ssid, breadcrumb=2, expect_results=True) + + self.step(7) + breadcrumb = await self.read_single_attribute_check_success(cluster=Clusters.GeneralCommissioning, attribute=Clusters.GeneralCommissioning.Attributes.Breadcrumb, endpoint=0) + asserts.assert_equal(breadcrumb, 2, "Incorrect breadcrumb value") + + self.step(8) + random_ssid = ''.join(random.choice(string.ascii_letters) for _ in range(31)).encode("utf-8") + await scan_and_check(ssid_to_scan=random_ssid, breadcrumb=2, expect_results=False) + + +if __name__ == "__main__": + default_matter_test_main() From 8937d2739f670479122d2404f2d5aae367ae6b4d Mon Sep 17 00:00:00 2001 From: Tennessee Carmel-Veilleux Date: Fri, 16 Feb 2024 18:12:22 -0500 Subject: [PATCH 18/33] Fix NetworkCommissioning post-review from #32156 (#32172) * Fix NetworkCommissioning post-review from #32156 - Found a regression on Thread scanning. - Changed some ConstraintError to InvalidCommand where more applicable. - Removed an update of cluster state on fail safe expiry. Testing done: - Retested on Wi-Fi - Testing on Thread as well * Re-notify errors on empty network at fail-safe expiry * Fix MobileDeviceTest * Fix Cirque tests --- .../network-commissioning.cpp | 23 +++++++++++-------- .../test_scripts/network_commissioning.py | 8 +++---- 2 files changed, 18 insertions(+), 13 deletions(-) diff --git a/src/app/clusters/network-commissioning/network-commissioning.cpp b/src/app/clusters/network-commissioning/network-commissioning.cpp index cb847a13867d5d..8212ea9f8008dc 100644 --- a/src/app/clusters/network-commissioning/network-commissioning.cpp +++ b/src/app/clusters/network-commissioning/network-commissioning.cpp @@ -477,7 +477,7 @@ void Instance::HandleScanNetworks(HandlerContext & ctx, const Commands::ScanNetw } if (ssid.size() > DeviceLayer::Internal::kMaxWiFiSSIDLength) { - // This should not happen, it means it's a broken driver. + // Clients should never use too large a SSID. ctx.mCommandHandler.AddStatus(ctx.mRequestPath, Protocols::InteractionModel::Status::ConstraintError); SetLastNetworkingStatusValue(MakeNullable(Status::kUnknownError)); return; @@ -491,10 +491,10 @@ void Instance::HandleScanNetworks(HandlerContext & ctx, const Commands::ScanNetw } else if (mFeatureFlags.Has(Feature::kThreadNetworkInterface)) { - // Not allowed to populate SSID for Thread. - if (!req.ssid.HasValue()) + // SSID present on Thread violates the `[WI]` conformance. + if (req.ssid.HasValue()) { - ctx.mCommandHandler.AddStatus(ctx.mRequestPath, Protocols::InteractionModel::Status::ConstraintError); + ctx.mCommandHandler.AddStatus(ctx.mRequestPath, Protocols::InteractionModel::Status::InvalidCommand); return; } @@ -559,7 +559,7 @@ void Instance::HandleAddOrUpdateWiFiNetwork(HandlerContext & ctx, const Commands return; } #endif // CHIP_DEVICE_CONFIG_ENABLE_WIFI_PDC - ctx.mCommandHandler.AddStatus(ctx.mRequestPath, Protocols::InteractionModel::Status::ConstraintError); + ctx.mCommandHandler.AddStatus(ctx.mRequestPath, Protocols::InteractionModel::Status::InvalidCommand); return; } @@ -1202,11 +1202,16 @@ void Instance::OnFailSafeTimerExpired() mpWirelessDriver->RevertConfiguration(); mAsyncCommandHandle.Release(); - // Reset state on failsafe expiry. + // Mark the network list changed since `mpWirelessDriver->RevertConfiguration()` may have updated it. ReportNetworksListChanged(); - SetLastNetworkId(ByteSpan{}); - SetLastConnectErrorValue(NullNullable); - SetLastNetworkingStatusValue(NullNullable); + + // If no networks are left, clear-out errors; + if (mpBaseDriver && (CountAndRelease(mpBaseDriver->GetNetworks()) == 0)) + { + SetLastNetworkId(ByteSpan{}); + SetLastConnectErrorValue(NullNullable); + SetLastNetworkingStatusValue(NullNullable); + } } CHIP_ERROR Instance::EnumerateAcceptedCommands(const ConcreteClusterPath & cluster, CommandIdCallback callback, void * context) diff --git a/src/controller/python/test/test_scripts/network_commissioning.py b/src/controller/python/test/test_scripts/network_commissioning.py index 72635677be9c9d..8ecbd59f78393b 100644 --- a/src/controller/python/test/test_scripts/network_commissioning.py +++ b/src/controller/python/test/test_scripts/network_commissioning.py @@ -149,9 +149,9 @@ async def test_wifi(self, endpointId): # Scan networks logger.info("Scan networks") - req = Clusters.NetworkCommissioning.Commands.ScanNetworks( - ssid=b'', breadcrumb=self.with_breadcrumb()) + req = Clusters.NetworkCommissioning.Commands.ScanNetworks(breadcrumb=self.with_breadcrumb()) interactionTimeoutMs = self._devCtrl.ComputeRoundTripTimeout(self._nodeid, upperLayerProcessingTimeoutMs=30000) + logger.info(f"Request: {req}") res = await self._devCtrl.SendCommand( nodeid=self._nodeid, endpoint=endpointId, @@ -309,8 +309,8 @@ async def test_thread(self, endpointId): # Scan networks logger.info("Scan networks") - req = Clusters.NetworkCommissioning.Commands.ScanNetworks( - ssid=b'', breadcrumb=self.with_breadcrumb()) + req = Clusters.NetworkCommissioning.Commands.ScanNetworks(breadcrumb=self.with_breadcrumb()) + logger.info(f"Request: {req}") interactionTimeoutMs = self._devCtrl.ComputeRoundTripTimeout(self._nodeid, upperLayerProcessingTimeoutMs=30000) res = await self._devCtrl.SendCommand(nodeid=self._nodeid, endpoint=endpointId, From 977d90e1cde27669c1a4671dbb43d2c5762bccae Mon Sep 17 00:00:00 2001 From: lpbeliveau-silabs <112982107+lpbeliveau-silabs@users.noreply.github.com> Date: Fri, 16 Feb 2024 18:15:45 -0500 Subject: [PATCH 19/33] Fixed the differences with the VS Documents (#32183) --- .../suites/certification/Test_TC_S_2_2.yaml | 54 +--- .../suites/certification/Test_TC_S_2_3.yaml | 77 +++--- .../suites/certification/Test_TC_S_2_5.yaml | 4 +- .../suites/certification/Test_TC_S_2_6.yaml | 257 ++++++++++++++---- 4 files changed, 247 insertions(+), 145 deletions(-) diff --git a/src/app/tests/suites/certification/Test_TC_S_2_2.yaml b/src/app/tests/suites/certification/Test_TC_S_2_2.yaml index b27d4bfd333cee..02407f8807d993 100644 --- a/src/app/tests/suites/certification/Test_TC_S_2_2.yaml +++ b/src/app/tests/suites/certification/Test_TC_S_2_2.yaml @@ -643,48 +643,18 @@ tests: to 60 000 000 (60 000s) and a set of extension fields appropriate to AC1." verification: | - ./chip-tool scenes add-scene 0x0001 1 60000000 "Test Name" '[{"clusterId": value, "attributeValueList":[{"attributeId": value, "attributeValue": value}]}' nodeId endpointId - - Note: The number of ExtensionFieldSets, the value of clusterId of each ExtensionFieldSet, the number of attributes in attributeValueList and their values varies for each application - - Verify the "status is success" on the TH(Chip-tool) Log and below is the sample log provided for the raspi platform: - [1670970505.887060][5742:5744] CHIP:DMG: InvokeResponseMessage = - [1670970505.887118][5742:5744] CHIP:DMG: { - [1670970505.887172][5742:5744] CHIP:DMG: suppressResponse = false, - [1670970505.887231][5742:5744] CHIP:DMG: InvokeResponseIBs = - [1670970505.887307][5742:5744] CHIP:DMG: [ - [1670970505.887366][5742:5744] CHIP:DMG: InvokeResponseIB = - [1670970505.887444][5742:5744] CHIP:DMG: { - [1670970505.887507][5742:5744] CHIP:DMG: CommandDataIB = - [1670970505.887576][5742:5744] CHIP:DMG: { - [1670970505.887713][5742:5744] CHIP:DMG: CommandPathIB = - [1670970505.887804][5742:5744] CHIP:DMG: { - [1670970505.887940][5742:5744] CHIP:DMG: EndpointId = 0x1, - [1670970505.888093][5742:5744] CHIP:DMG: ClusterId = 0x5, - [1670970505.888242][5742:5744] CHIP:DMG: CommandId = 0x0, - [1670970505.888385][5742:5744] CHIP:DMG: }, - [1670970505.888692][5742:5744] CHIP:DMG: - [1670970505.888769][5742:5744] CHIP:DMG: CommandFields = - [1670970505.888852][5742:5744] CHIP:DMG: { - [1670970505.889030][5742:5744] CHIP:DMG: 0x0 = 0, - [1670970505.889183][5742:5744] CHIP:DMG: 0x1 = 1, - [1670970505.889406][5742:5744] CHIP:DMG: 0x2 = 1, - [1670970505.889515][5742:5744] CHIP:DMG: }, - [1670970505.889603][5742:5744] CHIP:DMG: }, - [1670970505.889684][5742:5744] CHIP:DMG: - [1670970505.889745][5742:5744] CHIP:DMG: }, - [1670970505.889821][5742:5744] CHIP:DMG: - [1670970505.889878][5742:5744] CHIP:DMG: ], - [1670970505.889953][5742:5744] CHIP:DMG: - [1670970505.890009][5742:5744] CHIP:DMG: InteractionModelRevision = 1 - [1670970505.890066][5742:5744] CHIP:DMG: }, - [1670970505.890212][5742:5744] CHIP:DMG: Received Command Response Data, Endpoint=1 Cluster=0x0000_0005 Command=0x0000_0000 - [1670970505.890328][5742:5744] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0005 Command 0x0000_0000 - [1670970505.890458][5742:5744] CHIP:TOO: AddSceneResponse: { - [1670970505.890551][5742:5744] CHIP:TOO: status: 0 - [1670970505.890608][5742:5744] CHIP:TOO: groupId: 1 - [1670970505.890717][5742:5744] CHIP:TOO: sceneId: 1 - [1670970505.890774][5742:5744] CHIP:TOO: } + ./chip-tool scenesmanagement add-scene 0x0001 0x01 60000000 "scene name" '[{"clusterID": "0x0300", "attributeValueList":[{"attributeID": "0x4001", "attributeValue": "0x01"}]}]' 1 1 + + Verify DUT sends a AddSceneResponse command to TH with the Status field set to 0x00 (SUCCESS), the GroupID field set to G1 and the SceneID field set to 0x01 on the TH(Chip-tool) Log and below is the sample log provided for the raspi platform: + + [1706763610.675038][4232:4234] CHIP:DMG: }, + [1706763610.675108][4232:4234] CHIP:DMG: Received Command Response Data, Endpoint=1 Cluster=0x0000_0062 Command=0x0000_0000 + [1706763610.675134][4232:4234] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0062 Command 0x0000_0000 + [1706763610.675187][4232:4234] CHIP:TOO: AddSceneResponse: { + [1706763610.675215][4232:4234] CHIP:TOO: status: 0 + [1706763610.675229][4232:4234] CHIP:TOO: groupID: 1 + [1706763610.675244][4232:4234] CHIP:TOO: sceneID: 1 + [1706763610.675258][4232:4234] CHIP:TOO: } cluster: "LogCommands" command: "UserPrompt" PICS: PICS_SKIP_SAMPLE_APP diff --git a/src/app/tests/suites/certification/Test_TC_S_2_3.yaml b/src/app/tests/suites/certification/Test_TC_S_2_3.yaml index eeeabe22dc4f4c..859204e549f7b2 100644 --- a/src/app/tests/suites/certification/Test_TC_S_2_3.yaml +++ b/src/app/tests/suites/certification/Test_TC_S_2_3.yaml @@ -376,50 +376,39 @@ tests: set to G1 and the SceneID field set to 0x01." PICS: S.S.C01.Rsp && PICS_SKIP_SAMPLE_APP verification: | - ./chip-tool scenesmanagement view-scene GroupId SceneId Node-Id EndpointId - - Note: The number of ExtensionFieldSets, the value of clusterId of each ExtensionFieldSet, the number of attributes in attributeValueList and their values varies for each application - - Verify that the extension fields in the log match the ones expected in the following log: - [1705680224.968551][5827:5829] CHIP:DMG: Received Command Response Data, Endpoint=1 Cluster=0x0000_0062 Command=0x0000_0001 - [1705680224.968559][5827:5829] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0062 Command 0x0000_0001 - CHIP:TOO: ViewSceneResponse: { - CHIP:TOO: status: 0 - CHIP:TOO: groupID: 1 - CHIP:TOO: sceneID: 1 - CHIP:TOO: transitionTime: 1000 - CHIP:TOO: sceneName: - CHIP:TOO: extensionFieldSets: 3 entries - CHIP:TOO: [1]: { - CHIP:TOO: ClusterID: XX - CHIP:TOO: AttributeValueList: X entries - CHIP:TOO: [1]: { - CHIP:TOO: AttributeID: XX - CHIP:TOO: AttributeValue:XX - CHIP:TOO: } - CHIP:TOO: } - CHIP:TOO: [2]: { - CHIP:TOO: ClusterID: XX - CHIP:TOO: AttributeValueList: X entries - CHIP:TOO: [1]: { - CHIP:TOO: AttributeID: XX - CHIP:TOO: AttributeValue: XX - CHIP:TOO: } - CHIP:TOO: } - CHIP:TOO: [3]: { - CHIP:TOO: ClusterID: XX - CHIP:TOO: AttributeValueList: XX entries - CHIP:TOO: [X]: { - CHIP:TOO: AttributeID: XX - CHIP:TOO: AttributeValue: XX - CHIP:TOO: } - ... - CHIP:TOO: [X]: { - CHIP:TOO: AttributeID: XX - CHIP:TOO: AttributeValue: XX - CHIP:TOO: } - CHIP:TOO: } - CHIP:TOO: } + ./chip-tool scenesmanagement view-scene 0x0101 0x01 1 1 + + Verify DUT sends a ViewSceneResponse command to TH with the Status field set to 0x00 (SUCCESS), the GroupID field set to G1, the SceneID field set to 0x01, the TransitionTime field set to 1000 and a set of extension fields appropriate to AC1 on the TH(Chip-tool) Log and below is the sample log provided for the raspi platform: + + + NOTE: The values below are expected to match the values from the specific AC tested + + [1708071897.294470][7731:7733] CHIP:DMG: Received Command Response Data, Endpoint=1 Cluster=0x0000_0062 Command=0x0000_0001 + [1708071897.294486][7731:7733] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0062 Command 0x0000_0001 + [1708071897.294520][7731:7733] CHIP:TOO: ViewSceneResponse: { + [1708071897.294527][7731:7733] CHIP:TOO: status: 0 + [1708071897.294530][7731:7733] CHIP:TOO: groupID: 257 + [1708071897.294533][7731:7733] CHIP:TOO: sceneID: 1 + [1708071897.294536][7731:7733] CHIP:TOO: transitionTime: 1000 + [1708071897.294540][7731:7733] CHIP:TOO: sceneName: scene name + [1708071897.294554][7731:7733] CHIP:TOO: extensionFieldSets: 2 entries + [1708071897.294569][7731:7733] CHIP:TOO: [1]: { + [1708071897.294574][7731:7733] CHIP:TOO: ClusterID: 6 + [1708071897.294580][7731:7733] CHIP:TOO: AttributeValueList: 1 entries + [1708071897.294589][7731:7733] CHIP:TOO: [1]: { + [1708071897.294593][7731:7733] CHIP:TOO: AttributeID: 1 + [1708071897.294596][7731:7733] CHIP:TOO: AttributeValue: 1 + [1708071897.294599][7731:7733] CHIP:TOO: } + [1708071897.294603][7731:7733] CHIP:TOO: } + [1708071897.294611][7731:7733] CHIP:TOO: [2]: { + [1708071897.294615][7731:7733] CHIP:TOO: ClusterID: 8 + [1708071897.294621][7731:7733] CHIP:TOO: AttributeValueList: 1 entries + [1708071897.294628][7731:7733] CHIP:TOO: [1]: { + [1708071897.294633][7731:7733] CHIP:TOO: AttributeID: 0 + [1708071897.294636][7731:7733] CHIP:TOO: AttributeValue: 100 + [1708071897.294639][7731:7733] CHIP:TOO: } + [1708071897.294643][7731:7733] CHIP:TOO: } + [1708071897.294647][7731:7733] CHIP:TOO: } cluster: "LogCommands" command: "UserPrompt" arguments: diff --git a/src/app/tests/suites/certification/Test_TC_S_2_5.yaml b/src/app/tests/suites/certification/Test_TC_S_2_5.yaml index e1624bf79d7e64..e0a2998e06d965 100644 --- a/src/app/tests/suites/certification/Test_TC_S_2_5.yaml +++ b/src/app/tests/suites/certification/Test_TC_S_2_5.yaml @@ -250,7 +250,7 @@ tests: to 20000 (20s) and no extension field sets." PICS: S.S.C00.Rsp verification: | - scenesmanagement add-scene 0x0001 0x01 20 scene1 [] 1 1 + ./chip-tool scenesmanagement add-scene 0x0001 0x01 20000 scene1 [] 1 1 Verify the AddSceneResponse with following fields: Status is SUCCESS @@ -412,7 +412,7 @@ tests: field sets. If RemainingCapacity is 0, continue to Step 8a." PICS: S.S.C00.Rsp verification: | - ./chip-tool scenesmanagement add-scene 0x0001 0x03 20 scene1 [] 1 1 + ./chip-tool scenesmanagement add-scene 0x0001 0x03 20000 scene1 [] 1 1 Verify the AddSceneResponse with following fields: Status is SUCCESS diff --git a/src/app/tests/suites/certification/Test_TC_S_2_6.yaml b/src/app/tests/suites/certification/Test_TC_S_2_6.yaml index c3b5b6561bfd57..2c8d0ce4e5a820 100644 --- a/src/app/tests/suites/certification/Test_TC_S_2_6.yaml +++ b/src/app/tests/suites/certification/Test_TC_S_2_6.yaml @@ -94,11 +94,15 @@ tests: verification: | ./chip-tool scenesmanagement remove-all-scenes 0x0000 1 1 - CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0005 Command 0x0000_0003 - CHIP:TOO: RemoveAllScenesResponse: { - CHIP:TOO: status: 0 - CHIP:TOO: groupID: 0 - CHIP:TOO: } + Verify the RemoveAllScenesResponse with following fields: + Status is SUCCESS + Group ID is 0x0000 on the TH(Chip-tool) log and below is the sample log provided for the raspi platform: + + [1701173905.688536][36687:36689] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0062 Command 0x0000_0003 + [1701173905.688553][36687:36689] CHIP:TOO: RemoveAllScenesResponse: { + [1701173905.688558][36687:36689] CHIP:TOO: status: 0 + [1701173905.688561][36687:36689] CHIP:TOO: groupID: 0 + [1701173905.688563][36687:36689] CHIP:TOO: } disabled: true - label: "Step 1b: Repeat Step 1a with TH2." @@ -354,7 +358,7 @@ tests: set to 20000 (20s) and no extension field sets." PICS: S.S.C00.Rsp verification: | - ./chip-tool scenesmanagement add-scene 0x0000 0x01 20 scene1 [] 1 1 + ./chip-tool scenesmanagement add-scene 0x0000 0x01 20000 scene1 [] 1 1 Verify the AddSceneResponse with following fields: Status is SUCCESS @@ -377,7 +381,7 @@ tests: FabricSceneInfo into Remaining1stCapacity; verify Remaining1stCapacity equals (MaxRemainingCapacity-1)." verification: | - ./chip-tool scenesmanagement subscribe fabric-scene-info 100 200 1 1 + ./chipt-tool scenesmanagement subscribe fabric-scene-info 100 200 1 1 Verify the DUT sends a report data to TH1 for FabricSceneInfo after the MinIntervalFloor time; store the RemainingCapacity field from this fabric’s entry reported in FabricSceneInfo into Remaining1stCapacity and is equals to (MaxRemainingCapacity-1) on the TH (Chip-tool) and below is the sample log provided for the raspi platform: @@ -439,34 +443,137 @@ tests: verification: | ./chip-tool scenesmanagement add-scene 0x0000 0x02 20000 scene2 [] 1 1 - CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0005 Command 0x0000_0000 - CHIP:TOO: AddSceneResponse: { - CHIP:TOO: status: 0 - CHIP:TOO: groupID: 0 - CHIP:TOO: sceneID: 2 - CHIP:TOO: } + Verify the AddSceneResponse with following fields: + Status is SUCCESS + Group ID is 0x0000 + SceneID field set to 0x02 on the TH1(Chip-tool) log and below is the sample log provided for the raspi platform: + + [1700827508.579671][16026:16028] CHIP:DMG: Received Command Response Data, Endpoint=1 Cluster=0x0000_0062 Command=0x0000_0000 + [1700827508.579675][16026:16028] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0062 Command 0x0000_0000 + [1700827508.579684][16026:16028] CHIP:TOO: AddSceneResponse: { + [1700827508.579688][16026:16028] CHIP:TOO: status: 0 + [1700827508.579691][16026:16028] CHIP:TOO: groupID: 0 + [1700827508.579694][16026:16028] CHIP:TOO: sceneID: 2 + [1700827508.579697][16026:16028] CHIP:TOO: } + + + ./chip-tool scenesmanagement subscribe fabric-scene-info 100 200 1 1 + Verify the DUT sends a report data messages after the MinIntervalFloor time to TH1 for RemainingCapacity field in FabricSceneInfo for that fabric with updated valueon the TH1 (Chip-tool) and below is the sample log provided for the raspi platform: + [1701243677.717829][7642:7644] CHIP:DMG: ReportDataMessage = + [1701243677.717834][7642:7644] CHIP:DMG: { + [1701243677.717839][7642:7644] CHIP:DMG: SubscriptionId = 0xbbe8695b, + [1701243677.717844][7642:7644] CHIP:DMG: AttributeReportIBs = + [1701243677.717854][7642:7644] CHIP:DMG: [ + [1701243677.717858][7642:7644] CHIP:DMG: AttributeReportIB = + [1701243677.717866][7642:7644] CHIP:DMG: { + [1701243677.717870][7642:7644] CHIP:DMG: AttributeDataIB = + [1701243677.717875][7642:7644] CHIP:DMG: { + [1701243677.717881][7642:7644] CHIP:DMG: DataVersion = 0x4daee689, + [1701243677.717886][7642:7644] CHIP:DMG: AttributePathIB = + [1701243677.717893][7642:7644] CHIP:DMG: { + [1701243677.717899][7642:7644] CHIP:DMG: Endpoint = 0x1, + [1701243677.717906][7642:7644] CHIP:DMG: Cluster = 0x62, + [1701243677.717912][7642:7644] CHIP:DMG: Attribute = 0x0000_0002, + [1701243677.717917][7642:7644] CHIP:DMG: } + [1701243677.717924][7642:7644] CHIP:DMG: + [1701243677.717929][7642:7644] CHIP:DMG: Data = [ + [1701243677.717935][7642:7644] CHIP:DMG: + [1701243677.717941][7642:7644] CHIP:DMG: { + [1701243677.717948][7642:7644] CHIP:DMG: 0x0 = 2, + [1701243677.717954][7642:7644] CHIP:DMG: 0x1 = 0, + [1701243677.717960][7642:7644] CHIP:DMG: 0x2 = 0, + [1701243677.717967][7642:7644] CHIP:DMG: 0x3 = false, + [1701243677.717973][7642:7644] CHIP:DMG: 0x4 = 5, + [1701243677.717979][7642:7644] CHIP:DMG: 0xfe = 1, + [1701243677.717986][7642:7644] CHIP:DMG: }, + [1701243677.717991][7642:7644] CHIP:DMG: ], + [1701243677.717996][7642:7644] CHIP:DMG: }, + [1701243677.718006][7642:7644] CHIP:DMG: + [1701243677.718010][7642:7644] CHIP:DMG: }, + [1701243677.718020][7642:7644] CHIP:DMG: + [1701243677.718024][7642:7644] CHIP:DMG: ], + [1701243677.718034][7642:7644] CHIP:DMG: + [1701243677.718037][7642:7644] CHIP:DMG: InteractionModelRevision = 11 + [1701243677.718040][7642:7644] CHIP:DMG: } + [1701243677.718133][7642:7644] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0062 Attribute 0x0000_0002 DataVersion: 1303307913 + [1701243677.718146][7642:7644] CHIP:TOO: FabricSceneInfo: 1 entries + [1701243677.718154][7642:7644] CHIP:TOO: [1]: { + [1701243677.718157][7642:7644] CHIP:TOO: SceneCount: 2 + [1701243677.718160][7642:7644] CHIP:TOO: CurrentScene: 0 + [1701243677.718162][7642:7644] CHIP:TOO: CurrentGroup: 0 + [1701243677.718165][7642:7644] CHIP:TOO: SceneValid: FALSE + [1701243677.718168][7642:7644] CHIP:TOO: RemainingCapacity: 5 + [1701243677.718170][7642:7644] CHIP:TOO: FabricIndex: 1 + [1701243677.718173][7642:7644] CHIP:TOO: } . . . - ./chip-tool scenesmanagement add-scene 0x0000 0x07 20000 scene2 [] 1 1 - - CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0005 Command 0x0000_0000 - CHIP:TOO: AddSceneResponse: { - CHIP:TOO: status: 0 - CHIP:TOO: groupID: 0 - CHIP:TOO: sceneID: 7 - CHIP:TOO: } - - You should see the following data in the next report: - CHIP:TOO: FabricSceneInfo: 1 entries - CHIP:TOO: [1]: { - CHIP:TOO: SceneCount: 7 - CHIP:TOO: CurrentScene: 0 - CHIP:TOO: CurrentGroup: 0 - CHIP:TOO: SceneValid: FALSE - CHIP:TOO: RemainingCapacity: 0 - CHIP:TOO: FabricIndex: 1 - CHIP:TOO: } + ./chip-tool scenesmanagement add-scene 0x0000 0x07 20000 scene8 [] 1 1 + + Verify the AddSceneResponse with following fields: + Status is SUCCESS + Group ID is 0x0000 + SceneID field set to 0x07 on the TH(Chip-tool) log and below is the sample log provided for the raspi platform: + + [1700827941.415335][16068:16070] CHIP:DMG: }, + [1700827941.415392][16068:16070] CHIP:DMG: Received Command Response Data, Endpoint=1 Cluster=0x0000_0062 Command=0x0000_0000 + [1700827941.415406][16068:16070] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0062 Command 0x0000_0000 + [1700827941.415462][16068:16070] CHIP:TOO: AddSceneResponse: { + [1700827941.415477][16068:16070] CHIP:TOO: status: 0 + [1700827941.415488][16068:16070] CHIP:TOO: groupID: 0 + [1700827941.415498][16068:16070] CHIP:TOO: sceneID: 7 + [1700827941.415508][16068:16070] CHIP:TOO: } + + ./chip-tool scenesmanagement subscribe fabric-scene-info 100 200 1 1 + + Verify the DUT sends a report data messages after the MinIntervalFloor time to TH1 for RemainingCapacity field in FabricSceneInfo for that fabric with updated valueon the TH1 (Chip-tool) and below is the sample log provided for the raspi platform: + + [1701244322.682421][7642:7644] CHIP:DMG: ReportDataMessage = + [1701244322.682435][7642:7644] CHIP:DMG: { + [1701244322.682447][7642:7644] CHIP:DMG: SubscriptionId = 0xbbe8695b, + [1701244322.682458][7642:7644] CHIP:DMG: AttributeReportIBs = + [1701244322.682484][7642:7644] CHIP:DMG: [ + [1701244322.682495][7642:7644] CHIP:DMG: AttributeReportIB = + [1701244322.682518][7642:7644] CHIP:DMG: { + [1701244322.682528][7642:7644] CHIP:DMG: AttributeDataIB = + [1701244322.682542][7642:7644] CHIP:DMG: { + [1701244322.682555][7642:7644] CHIP:DMG: DataVersion = 0x4daee697, + [1701244322.682566][7642:7644] CHIP:DMG: AttributePathIB = + [1701244322.682579][7642:7644] CHIP:DMG: { + [1701244322.682592][7642:7644] CHIP:DMG: Endpoint = 0x1, + [1701244322.682605][7642:7644] CHIP:DMG: Cluster = 0x62, + [1701244322.682619][7642:7644] CHIP:DMG: Attribute = 0x0000_0002, + [1701244322.682631][7642:7644] CHIP:DMG: } + [1701244322.682647][7642:7644] CHIP:DMG: + [1701244322.682659][7642:7644] CHIP:DMG: Data = [ + [1701244322.682672][7642:7644] CHIP:DMG: + [1701244322.682687][7642:7644] CHIP:DMG: { + [1701244322.682701][7642:7644] CHIP:DMG: 0x0 = 7, + [1701244322.682715][7642:7644] CHIP:DMG: 0x1 = 0, + [1701244322.682729][7642:7644] CHIP:DMG: 0x2 = 0, + [1701244322.682742][7642:7644] CHIP:DMG: 0x3 = false, + [1701244322.682756][7642:7644] CHIP:DMG: 0x4 = 0, + [1701244322.682770][7642:7644] CHIP:DMG: 0xfe = 1, + [1701244322.682784][7642:7644] CHIP:DMG: }, + [1701244322.682807][7642:7644] CHIP:DMG: ], + [1701244322.682818][7642:7644] CHIP:DMG: }, + [1701244322.682843][7642:7644] CHIP:DMG: + [1701244322.682853][7642:7644] CHIP:DMG: }, + [1701244322.682876][7642:7644] CHIP:DMG: + [1701244322.682887][7642:7644] CHIP:DMG: ], + [1701244322.682908][7642:7644] CHIP:DMG: + [1701244322.682919][7642:7644] CHIP:DMG: InteractionModelRevision = 11 + [1701244322.682930][7642:7644] CHIP:DMG: } + [1701244322.683149][7642:7644] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0062 Attribute 0x0000_0002 DataVersion: 1303307927 + [1701244322.683191][7642:7644] CHIP:TOO: FabricSceneInfo: 1 entries + [1701244322.683224][7642:7644] CHIP:TOO: [1]: { + [1701244322.683236][7642:7644] CHIP:TOO: SceneCount: 7 + [1701244322.683247][7642:7644] CHIP:TOO: CurrentScene: 0 + [1701244322.683258][7642:7644] CHIP:TOO: CurrentGroup: 0 + [1701244322.683269][7642:7644] CHIP:TOO: SceneValid: FALSE + [1701244322.683282][7642:7644] CHIP:TOO: RemainingCapacity: 0 + [1701244322.683293][7642:7644] CHIP:TOO: FabricIndex: 1 + [1701244322.683304][7642:7644] CHIP:TOO: } disabled: true - label: @@ -476,7 +583,7 @@ tests: field sets." PICS: S.S.C00.Rsp verification: | - ./chip-tool scenesmanagement add-scene 0x0000 0x08 0x0014 scene9 [] 1 1 + ./chip-tool scenesmanagement add-scene 0x0000 0x08 20000 scene9 [] 1 1 Verify the AddSceneResponse with following fields: Status is RESOURCE_EXHAUSTED(0x89) on the TH1(Chip-tool) log and below is the sample log provided for the raspi platform: @@ -578,7 +685,7 @@ tests: [1700829509.052521][16198:16200] CHIP:TOO: sceneID: 8 [1700829509.052532][16198:16200] CHIP:TOO: } - ./chip-tool scenesmanagement subscribe fabric-scene-info 100 200 2 1 --commissioner-name beta + ./chip-tool scenesmanagement subscribe fabric-scene-info 100 200 2 1 --commissioner-name beta Verify the DUT sends a report data messages after the MinIntervalFloor time to TH2 for RemainingCapacity field in FabricSceneInfo for that fabric with updated value(decreasing to 0) on the TH2 (Chip-tool) and below is the sample log provided for the raspi platform: @@ -629,7 +736,6 @@ tests: [1701245132.870584][7824:7826] CHIP:TOO: FabricIndex: 2 [1701245132.870594][7824:7826] CHIP:TOO: } - ./chip-tool scenesmanagement subscribe fabric-scene-info 100 200 3 1 --commissioner-name gamma Verify that the DUT sends report data messages after the MinIntervalFloor time to TH3 for RemainingCapacity field in FabricSceneInfo for that fabric with updated value (decreasing to SceneTableSize - (2 * MaxRemainingCapacity)) on the TH2 (Chip-tool) and below is the sample log provided for the raspi platform: @@ -658,7 +764,7 @@ tests: [1705916737.108102][21608:21610] CHIP:DMG: 0x1 = 0, [1705916737.108106][21608:21610] CHIP:DMG: 0x2 = 0, [1705916737.108109][21608:21610] CHIP:DMG: 0x3 = false, - [1705916737.108113][21608:21610] CHIP:DMG: 0x4 = 7, + [1705916737.108113][21608:21610] CHIP:DMG: 0x4 = 2, [1705916737.108117][21608:21610] CHIP:DMG: 0xfe = 3, [1705916737.108120][21608:21610] CHIP:DMG: }, [1705916737.108123][21608:21610] CHIP:DMG: ], @@ -715,10 +821,10 @@ tests: [1705915133.114065][21363:21365] CHIP:TOO: AddSceneResponse: { [1705915133.114081][21363:21365] CHIP:TOO: status: 0 [1705915133.114092][21363:21365] CHIP:TOO: groupID: 0 - [1705915133.114103][21363:21365] CHIP:TOO: sceneID: 1 + [1705915133.114103][21363:21365] CHIP:TOO: sceneID: 2 [1705915133.114113][21363:21365] CHIP:TOO: } - ./chip-tool scenesmanagement subscribe fabric-scene-info 100 200 3 1 --commissioner-name gamma + scenesmanagement subscribe fabric-scene-info 100 200 3 1 --commissioner-name gamma Verify that the DUT sends report data messages after the MinIntervalFloor time to TH3 for RemainingCapacity field in FabricSceneInfo for that fabric with updated value on the TH3(Chip-tool) log and below is the sample log provided for the raspi platform: @@ -770,7 +876,7 @@ tests: [1705915183.312690][21363:21365] CHIP:TOO: } - ./chip-tool scenesmanagement add-scene 0x0000 0x03 0x0014 scene2 [] 3 1 --commissioner-name gamma + scenesmanagement add-scene 0x0000 0x03 0x0014 scene2 [] 3 1 --commissioner-name gamma Verify the AddSceneResponse with following fields: Status is SUCCESS @@ -786,7 +892,6 @@ tests: [1705915237.987161][21363:21365] CHIP:TOO: sceneID: 3 [1705915237.987171][21363:21365] CHIP:TOO: } - ./chip-tool scenesmanagement subscribe fabric-scene-info 100 200 3 1 --commissioner-name gamma Verify that the DUT sends report data messages after the MinIntervalFloor time to TH3 for RemainingCapacity field in FabricSceneInfo for that fabric with updated value((decreasing to 0)) on the TH3(Chip-tool) log and below is the sample log provided for the raspi platform: @@ -837,6 +942,7 @@ tests: [1705915281.586073][21387:21389] CHIP:TOO: RemainingCapacity: 0 [1705915281.586084][21387:21389] CHIP:TOO: FabricIndex: 3 [1705915281.586095][21387:21389] CHIP:TOO: } + disabled: true - label: @@ -845,7 +951,7 @@ tests: set to 20000 20s and no extension field sets." PICS: S.S.C00.Rsp verification: | - ./chip-tool scenesmanagement add-scene 0x0000 0x01 0x0014 scene [] 3 1 --commissioner-name gamma + ./chipt-tool scenesmanagement add-scene 0x0000 0x01 20000 scene [] 3 1 --commissioner-name gamma Verify the AddSceneResponse with following fields: Status is RESOURCE_EXHAUSTED(0x89) on the TH3(Chip-tool) log and below is the sample log provided for the raspi platform: @@ -865,7 +971,7 @@ tests: set to 0x0000, the SceneID field set to 0x01." PICS: S.S.C04.Rsp verification: | - ./chip-tool scenesmanagement store-scene 0x0000 0x01 3 1 --commissioner-name gamma + ./chipt-tool scenesmanagement store-scene 0x0000 0x01 3 1 --commissioner-name gamma Verify the StoreSceneResponse with following fields: Status is RESOURCE_EXHAUSTED(0x89) on the TH3(Chip-tool) log and below is the sample log provided for the raspi platform: @@ -887,7 +993,7 @@ tests: to 0x0000 and the scene identifier to field set to 0xFE." PICS: S.S.C40.Rsp verification: | - ./chip-tool scenesmanagement copy-scene 0x00 0x0000 0x02 0x0000 0x00 3 1 --commissioner-name gamma + ./chipt-tool scenesmanagement copy-scene 0x00 0x0000 0x02 0x0000 0x00 3 1 --commissioner-name gamma Verify the CopySceneResponse with following fields: Status is RESOURCE_EXHAUSTED(0x89) on the TH(Chip-tool) log and below is the sample log provided for the raspi platform: @@ -907,7 +1013,7 @@ tests: field set to 0x0000." PICS: S.S.C03.Rsp verification: | - ./chip-tool scenesmanagement remove-all-scenes 0x0000 1 1 + ./chipt-tool scenesmanagement remove-all-scenes 0x0000 1 1 Verify the RemoveAllScenesResponse with following fields: Status is SUCCESS @@ -932,21 +1038,58 @@ tests: should send 'empty' report data since there is no update for this attribute for TH2)." verification: | - ./chip-tool scenesmanagement subscribe fabric-scene-info 100 200 1 1 + ./chipt-tool scenesmanagement subscribe fabric-scene-info 100 200 1 1 Verify that the DUT sends a report data to TH1 for FabricSceneInfo after the MinIntervalFloor time; store the RemainingCapacity field from this fabric’s entry the reported in FabricSceneInfo into Remaining1stCapacity; verify Remaining1stCapacity equals (MaxRemainingCapacity) on TH1(Chip-tool) log and below is the sample log provided for the raspi platform: - [1705915725.959835][21417:21419] CHIP:DMG: } - [1705915725.959889][21417:21419] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0062 Attribute 0x0000_0002 DataVersion: 2122634911 - [1705915725.959913][21417:21419] CHIP:TOO: FabricSceneInfo: 1 entries - [1705915725.959926][21417:21419] CHIP:TOO: [1]: { - [1705915725.959929][21417:21419] CHIP:TOO: SceneCount: 0 - [1705915725.959931][21417:21419] CHIP:TOO: CurrentScene: 0 - [1705915725.959935][21417:21419] CHIP:TOO: CurrentGroup: 0 - [1705915725.959939][21417:21419] CHIP:TOO: SceneValid: FALSE - [1705915725.959943][21417:21419] CHIP:TOO: RemainingCapacity: 7 - [1705915725.959945][21417:21419] CHIP:TOO: FabricIndex: 1 - [1705915725.959948][21417:21419] CHIP:TOO: } + [1707984148.067226][18155:18157] CHIP:DMG: ReportDataMessage = + [1707984148.067240][18155:18157] CHIP:DMG: { + [1707984148.067250][18155:18157] CHIP:DMG: SubscriptionId = 0x53cf322d, + [1707984148.067258][18155:18157] CHIP:DMG: AttributeReportIBs = + [1707984148.067280][18155:18157] CHIP:DMG: [ + [1707984148.067295][18155:18157] CHIP:DMG: AttributeReportIB = + [1707984148.067320][18155:18157] CHIP:DMG: { + [1707984148.067331][18155:18157] CHIP:DMG: AttributeDataIB = + [1707984148.067343][18155:18157] CHIP:DMG: { + [1707984148.067355][18155:18157] CHIP:DMG: DataVersion = 0xc9875f20, + [1707984148.067367][18155:18157] CHIP:DMG: AttributePathIB = + [1707984148.067381][18155:18157] CHIP:DMG: { + [1707984148.067397][18155:18157] CHIP:DMG: Endpoint = 0x1, + [1707984148.067411][18155:18157] CHIP:DMG: Cluster = 0x62, + [1707984148.067431][18155:18157] CHIP:DMG: Attribute = 0x0000_0002, + [1707984148.067443][18155:18157] CHIP:DMG: } + [1707984148.067462][18155:18157] CHIP:DMG: + [1707984148.067474][18155:18157] CHIP:DMG: Data = [ + [1707984148.067488][18155:18157] CHIP:DMG: + [1707984148.067502][18155:18157] CHIP:DMG: { + [1707984148.067516][18155:18157] CHIP:DMG: 0x0 = 0, + [1707984148.067531][18155:18157] CHIP:DMG: 0x1 = 0, + [1707984148.067545][18155:18157] CHIP:DMG: 0x2 = 0, + [1707984148.067561][18155:18157] CHIP:DMG: 0x3 = false, + [1707984148.067575][18155:18157] CHIP:DMG: 0x4 = 7, + [1707984148.067589][18155:18157] CHIP:DMG: 0xfe = 1, + [1707984148.067603][18155:18157] CHIP:DMG: }, + [1707984148.067618][18155:18157] CHIP:DMG: ], + [1707984148.067629][18155:18157] CHIP:DMG: }, + [1707984148.067654][18155:18157] CHIP:DMG: + [1707984148.067664][18155:18157] CHIP:DMG: }, + [1707984148.067687][18155:18157] CHIP:DMG: + [1707984148.067696][18155:18157] CHIP:DMG: ], + [1707984148.067722][18155:18157] CHIP:DMG: + [1707984148.067733][18155:18157] CHIP:DMG: InteractionModelRevision = 11 + [1707984148.067744][18155:18157] CHIP:DMG: } + [1707984148.067925][18155:18157] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0062 Attribute 0x0000_0002 DataVersion: 3381092128 + [1707984148.067967][18155:18157] CHIP:TOO: FabricSceneInfo: 1 entries + [1707984148.067999][18155:18157] CHIP:TOO: [1]: { + [1707984148.068011][18155:18157] CHIP:TOO: SceneCount: 0 + [1707984148.068023][18155:18157] CHIP:TOO: CurrentScene: 0 + [1707984148.068033][18155:18157] CHIP:TOO: CurrentGroup: 0 + [1707984148.068045][18155:18157] CHIP:TOO: SceneValid: FALSE + [1707984148.068057][18155:18157] CHIP:TOO: RemainingCapacity: 7 + [1707984148.068068][18155:18157] CHIP:TOO: FabricIndex: 1 + [1707984148.068079][18155:18157] CHIP:TOO: } + + Verify that the DUT does not send report data to TH2 for FabricSceneInfo after the MinIntervalFloor time with updated value (it should send 'empty' report data since there is no update for this attribute for TH2). disabled: true - label: @@ -954,7 +1097,7 @@ tests: field set to 0x0000." PICS: S.S.C03.Rsp verification: | - ./chip-tool scenesmanagement remove-all-scenes 0x0000 2 1 --commissioner-name beta + ./chipt-tool scenesmanagement remove-all-scenes 0x0000 2 1 --commissioner-name beta Verify the RemoveAllScenesResponse with following fields: Status is SUCCESS From 116c28fb52228ccaeb96d985f5a4609e23db6a9f Mon Sep 17 00:00:00 2001 From: yunhanw-google Date: Fri, 16 Feb 2024 20:16:18 -0800 Subject: [PATCH 20/33] fix report status in android (#32167) --- src/controller/java/AndroidCallbacks.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/controller/java/AndroidCallbacks.cpp b/src/controller/java/AndroidCallbacks.cpp index cc6107cae3a431..eb6e8b1a5f255b 100644 --- a/src/controller/java/AndroidCallbacks.cpp +++ b/src/controller/java/AndroidCallbacks.cpp @@ -281,9 +281,8 @@ void ReportCallback::OnAttributeData(const app::ConcreteDataAttributePath & aPat jobject wrapperCallback = mWrapperCallbackRef.ObjectRef(); jobject nodeState = GetNodeStateObj(env, mNodeStateClassSignature, wrapperCallback); - if (aStatus.IsFailure()) + { - ChipLogError(Controller, "Receive bad status %s", ErrorStr(aStatus.ToChipError())); // Add Attribute Status to wrapperCallback jmethodID addAttributeStatusMethod = nullptr; err = JniReferences::GetInstance().FindMethod(env, nodeState, "addAttributeStatus", "(IJJILjava/lang/Integer;)V", @@ -305,8 +304,10 @@ void ReportCallback::OnAttributeData(const app::ConcreteDataAttributePath & aPat static_cast(aPath.mClusterId), static_cast(aPath.mAttributeId), static_cast(aStatus.mStatus), jClusterState); VerifyOrReturn(!env->ExceptionCheck(), env->ExceptionDescribe()); - return; } + + VerifyOrReturn(aStatus.IsSuccess(), ChipLogError(Controller, "Receive bad status %s", ErrorStr(aStatus.ToChipError())); + aPath.LogPath()); VerifyOrReturn(apData != nullptr, ChipLogError(Controller, "Receive empty apData"); aPath.LogPath()); TLV::TLVReader readerForJavaTLV; @@ -415,9 +416,8 @@ void ReportCallback::OnEventData(const app::EventHeader & aEventHeader, TLV::TLV ChipLogError(Controller, "mReportCallbackRef is not valid in %s", __func__)); jobject wrapperCallback = mWrapperCallbackRef.ObjectRef(); jobject nodeState = GetNodeStateObj(env, mNodeStateClassSignature, wrapperCallback); - if (apStatus != nullptr && apStatus->IsFailure()) + if (apStatus != nullptr) { - ChipLogError(Controller, "Receive bad status %s", ErrorStr(apStatus->ToChipError())); // Add Event Status to NodeState jmethodID addEventStatusMethod; err = JniReferences::GetInstance().FindMethod(env, nodeState, "addEventStatus", "(IJJILjava/lang/Integer;)V", From 1da449efc6738ee5e5dc1ab9a45433d109837b31 Mon Sep 17 00:00:00 2001 From: Justin Wood Date: Fri, 16 Feb 2024 20:25:05 -0800 Subject: [PATCH 21/33] Implement time sync for darwin (#32185) * Implement time sync for darwin * Restyled by whitespace * Restyled by clang-format * Fixing format string * Restyled by clang-format --------- Co-authored-by: Restyled.io --- src/darwin/Framework/CHIP/MTRConversion.h | 12 + src/darwin/Framework/CHIP/MTRConversion.mm | 33 ++- src/darwin/Framework/CHIP/MTRDevice.mm | 244 ++++++++++++++++++++- 3 files changed, 283 insertions(+), 6 deletions(-) diff --git a/src/darwin/Framework/CHIP/MTRConversion.h b/src/darwin/Framework/CHIP/MTRConversion.h index 543d80968566c6..b14f4c240f9f67 100644 --- a/src/darwin/Framework/CHIP/MTRConversion.h +++ b/src/darwin/Framework/CHIP/MTRConversion.h @@ -46,6 +46,18 @@ inline NSDate * MatterEpochSecondsAsDate(uint32_t matterEpochSeconds) */ bool DateToMatterEpochSeconds(NSDate * date, uint32_t & epoch); +/** + * Returns whether the conversion could be performed. Will return false if the + * passed-in date is our of the range representable as a Matter epoch-s value. + */ +bool DateToMatterEpochMilliseconds(NSDate * date, uint64_t & matterEpochMilliseconds); + +/** + * Returns whether the conversion could be performed. Will return false if the + * passed-in date is our of the range representable as a Matter epoch-s value. + */ +bool DateToMatterEpochMicroseconds(NSDate * date, uint64_t & matterEpochMicroseconds); + /** * Utilities for converting between NSSet and chip::CATValues. */ diff --git a/src/darwin/Framework/CHIP/MTRConversion.mm b/src/darwin/Framework/CHIP/MTRConversion.mm index c6ba6ec52fbf32..5e657b9330a8e5 100644 --- a/src/darwin/Framework/CHIP/MTRConversion.mm +++ b/src/darwin/Framework/CHIP/MTRConversion.mm @@ -63,18 +63,41 @@ CHIP_ERROR SetToCATValues(NSSet * catSet, chip::CATValues & values) bool DateToMatterEpochSeconds(NSDate * date, uint32_t & matterEpochSeconds) { - auto timeSinceUnixEpoch = date.timeIntervalSince1970; - if (timeSinceUnixEpoch < static_cast(chip::kChipEpochSecondsSinceUnixEpoch)) { - // This is a pre-Matter-epoch time, and cannot be represented in epoch-s. + uint64_t matterEpochMicroseconds = 0; + if (!DateToMatterEpochMicroseconds(date, matterEpochMicroseconds)) { + // Could not convert time return false; } - auto timeSinceMatterEpoch = timeSinceUnixEpoch - chip::kChipEpochSecondsSinceUnixEpoch; + uint64_t timeSinceMatterEpoch = matterEpochMicroseconds / chip::kMicrosecondsPerSecond; if (timeSinceMatterEpoch > UINT32_MAX) { // Too far into the future. return false; } - matterEpochSeconds = static_cast(timeSinceMatterEpoch); return true; } + +bool DateToMatterEpochMilliseconds(NSDate * date, uint64_t & matterEpochMilliseconds) +{ + uint64_t matterEpochMicroseconds = 0; + if (!DateToMatterEpochMicroseconds(date, matterEpochMicroseconds)) { + // Could not convert time + return false; + } + + matterEpochMilliseconds = matterEpochMicroseconds / chip::kMicrosecondsPerMillisecond; + return true; +} + +bool DateToMatterEpochMicroseconds(NSDate * date, uint64_t & matterEpochMicroseconds) +{ + uint64_t timeSinceUnixEpoch = static_cast(date.timeIntervalSince1970 * chip::kMicrosecondsPerSecond); + if (timeSinceUnixEpoch < chip::kChipEpochUsSinceUnixEpoch) { + // This is a pre-Matter-epoch time, and cannot be represented as an epoch time value. + return false; + } + + matterEpochMicroseconds = timeSinceUnixEpoch - chip::kChipEpochUsSinceUnixEpoch; + return true; +} diff --git a/src/darwin/Framework/CHIP/MTRDevice.mm b/src/darwin/Framework/CHIP/MTRDevice.mm index 2307a25d22361f..1b42caecf80c76 100644 --- a/src/darwin/Framework/CHIP/MTRDevice.mm +++ b/src/darwin/Framework/CHIP/MTRDevice.mm @@ -20,11 +20,13 @@ #import "MTRAsyncWorkQueue.h" #import "MTRAttributeSpecifiedCheck.h" +#import "MTRBaseClusters.h" #import "MTRBaseDevice_Internal.h" #import "MTRBaseSubscriptionCallback.h" #import "MTRCluster.h" #import "MTRClusterConstants.h" #import "MTRCommandTimedCheck.h" +#import "MTRConversion.h" #import "MTRDefines_Internal.h" #import "MTRDeviceController_Internal.h" #import "MTRDevice_Internal.h" @@ -143,6 +145,9 @@ typedef NS_ENUM(NSUInteger, MTRDeviceWorkItemDuplicateTypeID) { @interface MTRDevice () @property (nonatomic, readonly) os_unfair_lock lock; // protects the caches and device state +// protects against concurrent time updates by guarding timeUpdateScheduled flag which manages time updates scheduling, +// and protects device calls to setUTCTime and setDSTOffset +@property (nonatomic, readonly) os_unfair_lock timeSyncLock; @property (nonatomic) chip::FabricIndex fabricIndex; @property (nonatomic) MTRWeakReference> * weakDelegate; @property (nonatomic) dispatch_queue_t delegateQueue; @@ -190,6 +195,8 @@ @interface MTRDevice () @property (nonatomic) BOOL expirationCheckScheduled; +@property (nonatomic) BOOL timeUpdateScheduled; + @property (nonatomic) NSDate * estimatedStartTimeFromGeneralDiagnosticsUpTime; @property (nonatomic) NSMutableDictionary * temporaryMetaDataCache; @@ -224,6 +231,7 @@ - (instancetype)initWithNodeID:(NSNumber *)nodeID controller:(MTRDeviceControlle { if (self = [super init]) { _lock = OS_UNFAIR_LOCK_INIT; + _timeSyncLock = OS_UNFAIR_LOCK_INIT; _nodeID = [nodeID copy]; _fabricIndex = controller.fabricIndex; _deviceController = controller; @@ -249,6 +257,226 @@ + (MTRDevice *)deviceWithNodeID:(NSNumber *)nodeID controller:(MTRDeviceControll return [controller deviceForNodeID:nodeID]; } +#pragma mark - Time Synchronization + +- (void)_setTimeOnDevice +{ + NSDate * now = [NSDate date]; + // If no date available, error + if (!now) { + MTR_LOG_ERROR("%@ Could not retrieve current date. Unable to setUTCTime on endpoints.", self); + return; + } + + NSTimeZone * localTimeZone = [NSTimeZone localTimeZone]; + BOOL setDST = TRUE; + if (!localTimeZone) { + MTR_LOG_ERROR("%@ Could not retrieve local time zone. Unable to setDSTOffset on endpoints.", self); + setDST = FALSE; + } + + uint64_t matterEpochTimeMicroseconds = 0; + uint64_t nextDSTInMatterEpochTimeMicroseconds = 0; + if (!DateToMatterEpochMicroseconds(now, matterEpochTimeMicroseconds)) { + MTR_LOG_ERROR("%@ Could not convert NSDate (%@) to Matter Epoch Time. Unable to setUTCTime on endpoints.", self, now); + return; + } + + int32_t dstOffset = 0; + if (setDST) { + NSTimeInterval dstOffsetAsInterval = [localTimeZone daylightSavingTimeOffsetForDate:now]; + dstOffset = int32_t(dstOffsetAsInterval); + + // Calculate time to next DST. This is needed when we set the current DST. + NSDate * nextDSTTransitionDate = [localTimeZone nextDaylightSavingTimeTransition]; + if (!DateToMatterEpochMicroseconds(nextDSTTransitionDate, nextDSTInMatterEpochTimeMicroseconds)) { + MTR_LOG_ERROR("%@ Could not convert NSDate (%@) to Matter Epoch Time. Unable to setDSTOffset on endpoints.", self, nextDSTTransitionDate); + setDST = FALSE; + } + } + + // Set Time on each Endpoint with a Time Synchronization Cluster Server + NSArray * endpointsToSync = [self _endpointsWithTimeSyncClusterServer]; + for (NSNumber * endpoint in endpointsToSync) { + MTR_LOG_DEBUG("%@ Setting Time on Endpoint %@", self, endpoint); + [self _setUTCTime:matterEpochTimeMicroseconds withGranularity:MTRTimeSynchronizationGranularityMicrosecondsGranularity forEndpoint:endpoint]; + if (setDST) { + [self _setDSTOffset:dstOffset validStarting:0 validUntil:nextDSTInMatterEpochTimeMicroseconds forEndpoint:endpoint]; + } + } +} + +- (void)_scheduleNextUpdate:(UInt64)nextUpdateInSeconds +{ + MTRWeakReference * weakSelf = [MTRWeakReference weakReferenceWithObject:self]; + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t) (nextUpdateInSeconds * NSEC_PER_SEC)), self.queue, ^{ + MTR_LOG_DEBUG("%@ Timer expired, start Device Time Update", self); + MTRDevice * strongSelf = weakSelf.strongObject; + if (strongSelf) { + [strongSelf _performScheduledTimeUpdate]; + } else { + MTR_LOG_DEBUG("%@ MTRDevice no longer valid. No Timer Scheduled will be scheduled for a Device Time Update.", self); + return; + } + }); + self.timeUpdateScheduled = YES; + MTR_LOG_DEBUG("%@ Timer Scheduled for next Device Time Update, in %llu seconds", self, nextUpdateInSeconds); +} + +// Time Updates are a day apart (this can be changed in the future) +#define MTR_DEVICE_TIME_UPDATE_DEFAULT_WAIT_TIME_SEC (24 * 60 * 60) +// assume lock is held +- (void)_updateDeviceTimeAndScheduleNextUpdate +{ + os_unfair_lock_assert_owner(&self->_timeSyncLock); + if (self.timeUpdateScheduled) { + MTR_LOG_DEBUG("%@ Device Time Update already scheduled", self); + return; + } + + [self _setTimeOnDevice]; + [self _scheduleNextUpdate:MTR_DEVICE_TIME_UPDATE_DEFAULT_WAIT_TIME_SEC]; +} + +- (void)_performScheduledTimeUpdate +{ + os_unfair_lock_lock(&self->_timeSyncLock); + // Device needs to still be reachable + if (self.state != MTRDeviceStateReachable) { + MTR_LOG_DEBUG("%@ Device is not reachable, canceling Device Time Updates.", self); + os_unfair_lock_unlock(&self->_timeSyncLock); + return; + } + // Device must not be invalidated + if (!self.timeUpdateScheduled) { + MTR_LOG_DEBUG("%@ Device Time Update is no longer scheduled, MTRDevice may have been invalidated.", self); + os_unfair_lock_unlock(&self->_timeSyncLock); + return; + } + self.timeUpdateScheduled = NO; + [self _updateDeviceTimeAndScheduleNextUpdate]; + os_unfair_lock_unlock(&self->_timeSyncLock); +} + +- (NSArray *)_endpointsWithTimeSyncClusterServer +{ + auto partsList = [self readAttributeWithEndpointID:@(0) clusterID:@(MTRClusterIDTypeDescriptorID) attributeID:@(MTRAttributeIDTypeClusterDescriptorAttributePartsListID) params:nil]; + NSMutableArray * endpointsOnDevice = [self arrayOfNumbersFromAttributeValue:partsList]; + if (!endpointsOnDevice) { + endpointsOnDevice = [[NSMutableArray alloc] init]; + } + // Add Root node! + [endpointsOnDevice addObject:@(0)]; + + NSMutableArray * endpointsWithTimeSyncCluster = [[NSMutableArray alloc] init]; + for (NSNumber * endpoint in endpointsOnDevice) { + // Get list of server clusters on endpoint + auto clusterList = [self readAttributeWithEndpointID:endpoint clusterID:@(MTRClusterIDTypeDescriptorID) attributeID:@(MTRAttributeIDTypeClusterDescriptorAttributeServerListID) params:nil]; + NSArray * clusterArray = [self arrayOfNumbersFromAttributeValue:clusterList]; + + if (clusterArray && [clusterArray containsObject:@(MTRClusterIDTypeTimeSynchronizationID)]) { + [endpointsWithTimeSyncCluster addObject:endpoint]; + } + } + MTR_LOG_DEBUG("%@ Device has following endpoints with Time Sync Cluster Server: %@", self, endpointsWithTimeSyncCluster); + return endpointsWithTimeSyncCluster; +} + +- (void)_setUTCTime:(UInt64)matterEpochTime withGranularity:(uint8_t)granularity forEndpoint:(NSNumber *)endpoint +{ + MTR_LOG_DEBUG(" %@ _setUTCTime with matterEpochTime: %llu, endpoint %@", self, matterEpochTime, endpoint); + MTRTimeSynchronizationClusterSetUTCTimeParams * params = [[MTRTimeSynchronizationClusterSetUTCTimeParams + alloc] init]; + params.utcTime = @(matterEpochTime); + params.granularity = @(granularity); + auto setUTCTimeResponseHandler = ^(id _Nullable response, NSError * _Nullable error) { + if (error) { + MTR_LOG_ERROR("%@ _setUTCTime failed on endpoint %@, with parameters %@, error: %@", self, endpoint, params, error); + } + }; + + [self _invokeKnownCommandWithEndpointID:endpoint + clusterID:@(MTRClusterIDTypeTimeSynchronizationID) + commandID:@(MTRCommandIDTypeClusterTimeSynchronizationCommandSetUTCTimeID) + commandPayload:params + expectedValues:nil + expectedValueInterval:nil + timedInvokeTimeout:nil + serverSideProcessingTimeout:params.serverSideProcessingTimeout + responseClass:nil + queue:self.queue + completion:setUTCTimeResponseHandler]; +} + +- (void)_setDSTOffset:(int32_t)dstOffset validStarting:(uint64_t)validStarting validUntil:(uint64_t)validUntil forEndpoint:(NSNumber *)endpoint +{ + MTR_LOG_DEBUG("%@ _setDSTOffset with offset: %d, validStarting: %llu, validUntil: %llu, endpoint %@", + self, + dstOffset, validStarting, validUntil, endpoint); + + MTRTimeSynchronizationClusterSetDSTOffsetParams * params = [[MTRTimeSynchronizationClusterSetDSTOffsetParams + alloc] init]; + MTRTimeSynchronizationClusterDSTOffsetStruct * dstOffsetStruct = [[MTRTimeSynchronizationClusterDSTOffsetStruct alloc] init]; + dstOffsetStruct.offset = @(dstOffset); + dstOffsetStruct.validStarting = @(validStarting); + dstOffsetStruct.validUntil = @(validUntil); + params.dstOffset = @[ dstOffsetStruct ]; + + auto setDSTOffsetResponseHandler = ^(id _Nullable response, NSError * _Nullable error) { + if (error) { + MTR_LOG_ERROR("%@ _setDSTOffset failed on endpoint %@, with parameters %@, error: %@", self, endpoint, params, error); + } + }; + + [self _invokeKnownCommandWithEndpointID:endpoint + clusterID:@(MTRClusterIDTypeTimeSynchronizationID) + commandID:@(MTRCommandIDTypeClusterTimeSynchronizationCommandSetDSTOffsetID) + commandPayload:params + expectedValues:nil + expectedValueInterval:nil + timedInvokeTimeout:nil + serverSideProcessingTimeout:params.serverSideProcessingTimeout + responseClass:nil + queue:self.queue + completion:setDSTOffsetResponseHandler]; +} + +- (NSMutableArray *)arrayOfNumbersFromAttributeValue:(NSDictionary *)dataDictionary +{ + if (![MTRArrayValueType isEqual:dataDictionary[MTRTypeKey]]) { + return nil; + } + + id value = dataDictionary[MTRValueKey]; + if (![value isKindOfClass:NSArray.class]) { + return nil; + } + + NSArray * valueArray = value; + __auto_type outputArray = [NSMutableArray arrayWithCapacity:valueArray.count]; + + for (id item in valueArray) { + if (![item isKindOfClass:NSDictionary.class]) { + return nil; + } + + NSDictionary * itemDictionary = item; + id data = itemDictionary[MTRDataKey]; + if (![data isKindOfClass:NSDictionary.class]) { + return nil; + } + + NSDictionary * dataDictionary = data; + id dataType = dataDictionary[MTRTypeKey]; + id dataValue = dataDictionary[MTRValueKey]; + if (![dataType isKindOfClass:NSString.class] || ![dataValue isKindOfClass:NSNumber.class]) { + return nil; + } + [outputArray addObject:dataValue]; + } + return outputArray; +} + #pragma mark Subscription and delegate handling // subscription intervals are in seconds @@ -287,6 +515,10 @@ - (void)invalidate [_asyncWorkQueue invalidate]; + os_unfair_lock_lock(&self->_timeSyncLock); + _timeUpdateScheduled = NO; + os_unfair_lock_unlock(&self->_timeSyncLock); + os_unfair_lock_lock(&self->_lock); _state = MTRDeviceStateUnknown; @@ -370,6 +602,8 @@ - (void)_changeState:(MTRDeviceState)state } } +// First Time Sync happens 2 minutes after reachability (this can be changed in the future) +#define MTR_DEVICE_TIME_UPDATE_INITIAL_WAIT_TIME_SEC (60 * 2) - (void)_handleSubscriptionEstablished { os_unfair_lock_lock(&self->_lock); @@ -380,6 +614,14 @@ - (void)_handleSubscriptionEstablished [self _changeState:MTRDeviceStateReachable]; os_unfair_lock_unlock(&self->_lock); + + os_unfair_lock_lock(&self->_timeSyncLock); + + if (!self.timeUpdateScheduled) { + [self _scheduleNextUpdate:MTR_DEVICE_TIME_UPDATE_INITIAL_WAIT_TIME_SEC]; + } + + os_unfair_lock_unlock(&self->_timeSyncLock); } - (void)_handleSubscriptionError:(NSError *)error @@ -893,7 +1135,7 @@ - (void)_setupSubscription return; } - MTR_LOG_DEFAULT("%@ Subscribe with data version list size %lu, reduced by %lu", self, dataVersions.count, dataVersionFilterListSizeReduction); + MTR_LOG_DEFAULT("%@ Subscribe with data version list size %lu, reduced by %lu", self, (unsigned long) dataVersions.count, (unsigned long) dataVersionFilterListSizeReduction); // Callback and ClusterStateCache and ReadClient will be deleted // when OnDone is called. From 663de6553fd73414b79f965180c4247556c37966 Mon Sep 17 00:00:00 2001 From: Andrei Litvin Date: Fri, 16 Feb 2024 23:27:10 -0500 Subject: [PATCH 22/33] Update `data_model` scraped XML version to latest spec and scraper (#32170) * Ran scraper 1.2.4 on the latest spec version * Add in-progress scraping * Remove odd comment parts from NetworkCommissioningCluster.xml * Removed old files, re-generated new ones * Remove comments again * Remove the cluster suffix in names of clusters * Fix parsing error * Fix direction logic * Fix direction key --- data_model/README.md | 2 +- data_model/clusters/ACL-Cluster.xml | 25 +- data_model/clusters/AccountLogin.xml | 33 +- .../clusters/AdminCommissioningCluster.xml | 19 +- data_model/clusters/AirQuality.xml | 5 + data_model/clusters/AlarmBase.xml | 9 +- data_model/clusters/ApplicationBasic.xml | 5 + data_model/clusters/ApplicationLauncher.xml | 12 +- data_model/clusters/AudioOutput.xml | 9 +- data_model/clusters/BallastConfiguration.xml | 5 + .../clusters/BasicInformationCluster.xml | 61 +-- data_model/clusters/Binding-Cluster.xml | 5 + data_model/clusters/BooleanState.xml | 5 + .../clusters/BooleanStateConfiguration.xml | 9 +- data_model/clusters/Channel.xml | 284 ++++++++++++- data_model/clusters/ColorControl.xml | 119 +++--- data_model/clusters/ContentAppObserver.xml | 8 +- data_model/clusters/ContentControl.xml | 36 +- data_model/clusters/ContentLauncher.xml | 91 ++++- .../clusters/DemandResponseLoadControl.xml | 103 ++++- data_model/clusters/Descriptor-Cluster.xml | 5 + .../clusters/DeviceEnergyManagement.xml | 21 +- data_model/clusters/DiagnosticLogsCluster.xml | 18 +- data_model/clusters/DiagnosticsEthernet.xml | 5 +- data_model/clusters/DiagnosticsGeneral.xml | 74 ++-- data_model/clusters/DiagnosticsSoftware.xml | 24 +- data_model/clusters/DiagnosticsThread.xml | 28 +- data_model/clusters/DiagnosticsWiFi.xml | 13 +- data_model/clusters/DishwasherAlarm.xml | 5 + data_model/clusters/DoorLock.xml | 263 ++++++++++--- data_model/clusters/EVSE-Attributes.xml | 45 --- data_model/clusters/EVSE-Classification.xml | 45 --- data_model/clusters/EVSE-ClusterID.xml | 45 --- data_model/clusters/EVSE-Commands.xml | 45 --- data_model/clusters/EVSE-DataTypes.xml | 45 --- data_model/clusters/EVSE-Definitions.xml | 45 --- data_model/clusters/EVSE-Dependencies.xml | 45 --- data_model/clusters/EVSE-Events.xml | 45 --- data_model/clusters/EVSE-Features.xml | 45 --- data_model/clusters/EVSE-RevisionHistory.xml | 45 --- .../clusters/ElectricalEnergyMeasurement.xml | 59 ++- .../clusters/ElectricalPowerMeasurement.xml | 67 ++++ data_model/clusters/EnergyCalendar.xml | 5 + data_model/clusters/EnergyEVSE.xml | 20 +- data_model/clusters/EnergyPreference.xml | 5 + data_model/clusters/EnergyPrice.xml | 9 +- data_model/clusters/FanControl.xml | 7 +- data_model/clusters/FlowMeasurement.xml | 5 + .../clusters/GeneralCommissioningCluster.xml | 5 +- .../clusters/Group-Key-Management-Cluster.xml | 52 +-- data_model/clusters/Groups.xml | 21 +- data_model/clusters/ICDManagement.xml | 51 ++- data_model/clusters/Identify.xml | 9 +- .../clusters/IlluminanceMeasurement.xml | 5 + data_model/clusters/KeypadInput.xml | 8 +- ...ml => Label-Cluster-FixedLabelCluster.xml} | 5 + ...bel.xml => Label-Cluster-LabelCluster.xml} | 5 + ...xml => Label-Cluster-UserLabelCluster.xml} | 5 + data_model/clusters/LaundryDryerControls.xml | 3 + data_model/clusters/LaundryWasherControls.xml | 3 + data_model/clusters/LevelControl.xml | 21 +- .../clusters/LocalizationConfiguration.xml | 13 +- .../clusters/LocalizationTimeFormat.xml | 6 +- data_model/clusters/LocalizationUnit.xml | 3 + data_model/clusters/LowPower.xml | 7 +- data_model/clusters/MediaInput.xml | 13 +- data_model/clusters/MediaPlayback.xml | 251 +++++++++++- data_model/clusters/Messages.xml | 11 +- data_model/clusters/MicrowaveOvenControl.xml | 11 +- data_model/clusters/ModeBase.xml | 5 +- data_model/clusters/ModeSelect.xml | 5 +- .../clusters/Mode_DeviceEnergyManagement.xml | 5 + data_model/clusters/Mode_Dishwasher.xml | 5 + data_model/clusters/Mode_EVSE.xml | 5 + data_model/clusters/Mode_LaundryWasher.xml | 5 + data_model/clusters/Mode_MicrowaveOven.xml | 11 +- data_model/clusters/Mode_Oven.xml | 5 + data_model/clusters/Mode_RVCClean.xml | 5 + data_model/clusters/Mode_RVCRun.xml | 5 + data_model/clusters/Mode_Refrigerator.xml | 5 + data_model/clusters/Mode_WaterHeater.xml | 5 + .../clusters/NetworkCommissioningCluster.xml | 177 ++++++--- .../clusters/NetworkIdentityManagement.xml | 11 +- data_model/clusters/OTAProvider.xml | 52 +-- data_model/clusters/OTARequestor.xml | 24 +- data_model/clusters/OTASoftwareUpdate.xml | 2 - data_model/clusters/OccupancySensing.xml | 5 + data_model/clusters/OnOff.xml | 17 +- .../clusters/OperationalCredentialCluster.xml | 79 ++-- data_model/clusters/OperationalState.xml | 50 +++ data_model/clusters/OperationalState_Oven.xml | 5 + data_model/clusters/OperationalState_RVC.xml | 25 +- data_model/clusters/PowerSourceCluster.xml | 44 ++- .../PowerSourceConfigurationCluster.xml | 5 +- data_model/clusters/PowerTopology.xml | 5 + data_model/clusters/PressureMeasurement.xml | 5 + .../clusters/PumpConfigurationControl.xml | 204 +++++++++- data_model/clusters/RefrigeratorAlarm.xml | 8 +- data_model/clusters/ResourceMonitoring.xml | 4 +- data_model/clusters/Scenes.xml | 37 +- data_model/clusters/SmokeCOAlarm.xml | 7 +- data_model/clusters/Switch.xml | 3 + data_model/clusters/TargetNavigator.xml | 29 +- data_model/clusters/TemperatureControl.xml | 56 ++- .../clusters/TemperatureMeasurement.xml | 5 + data_model/clusters/Thermostat.xml | 372 +++++++++++++++++- .../ThermostatUserInterfaceConfiguration.xml | 3 + .../ThreadBorderRouterDiagnostics.xml | 11 +- data_model/clusters/TimeSync.xml | 36 +- .../clusters/ValveConfigurationControl.xml | 9 +- data_model/clusters/WakeOnLAN.xml | 7 +- .../clusters/WaterContentMeasurement.xml | 5 + data_model/clusters/WaterHeaterManagement.xml | 9 +- data_model/clusters/WiFiNetworkManagement.xml | 10 +- data_model/clusters/WindowCovering.xml | 19 +- ...xml => bridge-clusters-ActionsCluster.xml} | 52 +-- ...-BridgedDeviceBasicInformationCluster.xml} | 10 +- data_model/clusters/energy_management.xml | 2 + .../clusters/network_infrastructure.xml | 2 +- data_model/device_types/BaseDeviceType.xml | 19 - data_model/device_types/Cooktop.xml | 3 - .../DeviceEnergyManagement.xml} | 80 +--- data_model/device_types/EVSE.xml | 22 -- data_model/device_types/Thermostat.xml | 4 +- data_model/scraper_version | 2 +- data_model/spec_sha | 2 +- scripts/spec_xml/generate_spec_xml.py | 2 +- src/python_testing/spec_parsing_support.py | 3 + 128 files changed, 2824 insertions(+), 1221 deletions(-) delete mode 100644 data_model/clusters/EVSE-Attributes.xml delete mode 100644 data_model/clusters/EVSE-Classification.xml delete mode 100644 data_model/clusters/EVSE-ClusterID.xml delete mode 100644 data_model/clusters/EVSE-Commands.xml delete mode 100644 data_model/clusters/EVSE-DataTypes.xml delete mode 100644 data_model/clusters/EVSE-Definitions.xml delete mode 100644 data_model/clusters/EVSE-Dependencies.xml delete mode 100644 data_model/clusters/EVSE-Events.xml delete mode 100644 data_model/clusters/EVSE-Features.xml delete mode 100644 data_model/clusters/EVSE-RevisionHistory.xml rename data_model/clusters/{Label-Cluster-FixedLabel.xml => Label-Cluster-FixedLabelCluster.xml} (96%) rename data_model/clusters/{Label-Cluster-Label.xml => Label-Cluster-LabelCluster.xml} (96%) rename data_model/clusters/{Label-Cluster-UserLabel.xml => Label-Cluster-UserLabelCluster.xml} (96%) rename data_model/clusters/{bridge-clusters-Actions.xml => bridge-clusters-ActionsCluster.xml} (87%) rename data_model/clusters/{bridge-clusters-BridgedDeviceBasicInformation.xml => bridge-clusters-BridgedDeviceBasicInformationCluster.xml} (95%) rename data_model/{clusters/Timer.xml => device_types/DeviceEnergyManagement.xml} (55%) diff --git a/data_model/README.md b/data_model/README.md index 36f38cae0ff1f8..a26b1c4ff65558 100644 --- a/data_model/README.md +++ b/data_model/README.md @@ -17,7 +17,7 @@ update the spec XML files, however this is not done automatically. You will require access to the following tools locally: - `scraper`. A binary copy generally available - [here](https://github.com/csa-data-model/projects/tree/main/DM-Editor/bin/1.2.0/scrape) + [here](https://github.com/csa-data-model/projects/tree/main/DM-Editor/bin/scrape) - Specification repository checkout from https://github.com/CHIP-Specifications/connectedhomeip-spec diff --git a/data_model/clusters/ACL-Cluster.xml b/data_model/clusters/ACL-Cluster.xml index 9ef2f500e96e01..b965eb84234e0d 100644 --- a/data_model/clusters/ACL-Cluster.xml +++ b/data_model/clusters/ACL-Cluster.xml @@ -55,10 +55,13 @@ Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA --> - + + + + @@ -112,25 +115,27 @@ Davis, CA 95616, USA - + + - + - + + - + - + - + @@ -150,12 +155,14 @@ Davis, CA 95616, USA - + + - + + diff --git a/data_model/clusters/AccountLogin.xml b/data_model/clusters/AccountLogin.xml index 91f675eaba693b..db87d05dc74902 100644 --- a/data_model/clusters/AccountLogin.xml +++ b/data_model/clusters/AccountLogin.xml @@ -54,14 +54,20 @@ This notice and disclaimer must be included on all copies of this document. Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA + +:xrefstyle: basic --> - + + + + + - + @@ -70,14 +76,14 @@ Davis, CA 95616, USA - + - + @@ -86,12 +92,27 @@ Davis, CA 95616, USA - + + + + - + + + + + + + + + + + + + \ No newline at end of file diff --git a/data_model/clusters/AdminCommissioningCluster.xml b/data_model/clusters/AdminCommissioningCluster.xml index b94b25ec5520c2..eea41bc65b6e2c 100644 --- a/data_model/clusters/AdminCommissioningCluster.xml +++ b/data_model/clusters/AdminCommissioningCluster.xml @@ -1,7 +1,5 @@ + + + diff --git a/data_model/clusters/AlarmBase.xml b/data_model/clusters/AlarmBase.xml index 9ba73c14ab6e63..f4ffc6344a8b90 100644 --- a/data_model/clusters/AlarmBase.xml +++ b/data_model/clusters/AlarmBase.xml @@ -54,11 +54,16 @@ This notice and disclaimer must be included on all copies of this document. Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA + +:xrefstyle: basic --> + + + @@ -91,7 +96,7 @@ Davis, CA 95616, USA - + @@ -100,7 +105,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/clusters/ApplicationBasic.xml b/data_model/clusters/ApplicationBasic.xml index 086839a2338cfc..fa197a8d1e5cca 100644 --- a/data_model/clusters/ApplicationBasic.xml +++ b/data_model/clusters/ApplicationBasic.xml @@ -54,11 +54,16 @@ This notice and disclaimer must be included on all copies of this document. Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA + +:xrefstyle: basic --> + + + diff --git a/data_model/clusters/ApplicationLauncher.xml b/data_model/clusters/ApplicationLauncher.xml index 5d716981a55d38..6b84436e73d42d 100644 --- a/data_model/clusters/ApplicationLauncher.xml +++ b/data_model/clusters/ApplicationLauncher.xml @@ -54,11 +54,16 @@ This notice and disclaimer must be included on all copies of this document. Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA + +:xrefstyle: basic --> + + + @@ -111,7 +116,7 @@ Davis, CA 95616, USA - + @@ -124,7 +129,7 @@ Davis, CA 95616, USA - + @@ -134,7 +139,7 @@ Davis, CA 95616, USA - + @@ -145,7 +150,6 @@ Davis, CA 95616, USA - diff --git a/data_model/clusters/AudioOutput.xml b/data_model/clusters/AudioOutput.xml index 176e75b16c19c9..468ba2750152a6 100644 --- a/data_model/clusters/AudioOutput.xml +++ b/data_model/clusters/AudioOutput.xml @@ -54,11 +54,16 @@ This notice and disclaimer must be included on all copies of this document. Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA + +:xrefstyle: basic --> + + + @@ -111,14 +116,14 @@ Davis, CA 95616, USA - + - + diff --git a/data_model/clusters/BallastConfiguration.xml b/data_model/clusters/BallastConfiguration.xml index 416b8cd7014beb..f25bef22cb4b6c 100644 --- a/data_model/clusters/BallastConfiguration.xml +++ b/data_model/clusters/BallastConfiguration.xml @@ -54,6 +54,8 @@ This notice and disclaimer must be included on all copies of this document. Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA + +:xrefstyle: basic --> @@ -62,6 +64,9 @@ Davis, CA 95616, USA + + + diff --git a/data_model/clusters/BasicInformationCluster.xml b/data_model/clusters/BasicInformationCluster.xml index 87fa765f65b2f5..82b9283b0d21d6 100644 --- a/data_model/clusters/BasicInformationCluster.xml +++ b/data_model/clusters/BasicInformationCluster.xml @@ -59,8 +59,11 @@ Davis, CA 95616, USA - + + + + @@ -175,50 +178,50 @@ Davis, CA 95616, USA - + - + - + - + - + - + - + - + - + - + - + @@ -226,41 +229,41 @@ Davis, CA 95616, USA - + - + - + - + - + - + - + - + - + - + - + - + @@ -271,11 +274,11 @@ Davis, CA 95616, USA - + - + @@ -293,6 +296,12 @@ Davis, CA 95616, USA + + + + + + diff --git a/data_model/clusters/Binding-Cluster.xml b/data_model/clusters/Binding-Cluster.xml index 95f68f1d6ff995..eca291a7d895ff 100644 --- a/data_model/clusters/Binding-Cluster.xml +++ b/data_model/clusters/Binding-Cluster.xml @@ -54,11 +54,16 @@ This notice and disclaimer must be included on all copies of this document. Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA + +:xrefstyle: basic --> + + + diff --git a/data_model/clusters/BooleanState.xml b/data_model/clusters/BooleanState.xml index 5b298075fbaefc..9205310c58f2be 100644 --- a/data_model/clusters/BooleanState.xml +++ b/data_model/clusters/BooleanState.xml @@ -54,11 +54,16 @@ This notice and disclaimer must be included on all copies of this document. Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA + +:xrefstyle: basic --> + + + diff --git a/data_model/clusters/BooleanStateConfiguration.xml b/data_model/clusters/BooleanStateConfiguration.xml index 160cb7fadb7a93..dc17f93a7295f0 100644 --- a/data_model/clusters/BooleanStateConfiguration.xml +++ b/data_model/clusters/BooleanStateConfiguration.xml @@ -54,11 +54,16 @@ This notice and disclaimer must be included on all copies of this document. Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA + +:xrefstyle: basic --> + + + @@ -164,7 +169,7 @@ Davis, CA 95616, USA - + @@ -173,7 +178,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/clusters/Channel.xml b/data_model/clusters/Channel.xml index 9ace62ca720a53..1809f5262e7166 100644 --- a/data_model/clusters/Channel.xml +++ b/data_model/clusters/Channel.xml @@ -54,11 +54,17 @@ This notice and disclaimer must be included on all copies of this document. Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA + +:xrefstyle: basic --> - + + + + + @@ -67,8 +73,28 @@ Davis, CA 95616, USA + + + + + + + + + + + + + + + + + + + + @@ -85,6 +111,17 @@ Davis, CA 95616, USA + + + + + + + + + + + @@ -101,6 +138,22 @@ Davis, CA 95616, USA + + + + + + + + + + + + + + + + @@ -117,6 +170,132 @@ Davis, CA 95616, USA + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -142,7 +321,7 @@ Davis, CA 95616, USA - + @@ -155,7 +334,6 @@ Davis, CA 95616, USA - @@ -170,7 +348,7 @@ Davis, CA 95616, USA - + @@ -180,12 +358,108 @@ Davis, CA 95616, USA - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/data_model/clusters/ColorControl.xml b/data_model/clusters/ColorControl.xml index c0b0655261b10b..b913009f852761 100644 --- a/data_model/clusters/ColorControl.xml +++ b/data_model/clusters/ColorControl.xml @@ -54,6 +54,8 @@ This notice and disclaimer must be included on all copies of this document. Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA + +:xrefstyle: basic --> @@ -64,6 +66,9 @@ Davis, CA 95616, USA + + + @@ -123,19 +128,19 @@ Davis, CA 95616, USA - + - + - + - + - + @@ -158,13 +163,13 @@ Davis, CA 95616, USA - + - + - + @@ -356,16 +361,16 @@ Davis, CA 95616, USA - + - + - + - + @@ -434,7 +439,7 @@ Davis, CA 95616, USA - + @@ -449,7 +454,7 @@ Davis, CA 95616, USA - + @@ -460,16 +465,16 @@ Davis, CA 95616, USA - + - + - + - + @@ -489,23 +494,23 @@ Davis, CA 95616, USA - + - + - + - + - + @@ -524,23 +529,23 @@ Davis, CA 95616, USA - + - + - + - + - + @@ -562,7 +567,7 @@ Davis, CA 95616, USA - + @@ -584,23 +589,23 @@ Davis, CA 95616, USA - + - + - + - + - + @@ -619,23 +624,23 @@ Davis, CA 95616, USA - + - + - + - + - + @@ -657,7 +662,7 @@ Davis, CA 95616, USA - + @@ -683,7 +688,7 @@ Davis, CA 95616, USA - + @@ -709,7 +714,7 @@ Davis, CA 95616, USA - + @@ -729,7 +734,7 @@ Davis, CA 95616, USA - + @@ -753,7 +758,7 @@ Davis, CA 95616, USA - + @@ -775,7 +780,7 @@ Davis, CA 95616, USA - + @@ -800,7 +805,7 @@ Davis, CA 95616, USA - + @@ -821,7 +826,7 @@ Davis, CA 95616, USA - + @@ -846,7 +851,7 @@ Davis, CA 95616, USA - + @@ -871,7 +876,7 @@ Davis, CA 95616, USA - + @@ -899,13 +904,13 @@ Davis, CA 95616, USA - + - + - + @@ -914,10 +919,10 @@ Davis, CA 95616, USA - + - + @@ -939,7 +944,7 @@ Davis, CA 95616, USA - + @@ -957,7 +962,7 @@ Davis, CA 95616, USA - + @@ -986,7 +991,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/clusters/ContentAppObserver.xml b/data_model/clusters/ContentAppObserver.xml index b426daa5ec3379..184cce14924cda 100644 --- a/data_model/clusters/ContentAppObserver.xml +++ b/data_model/clusters/ContentAppObserver.xml @@ -54,11 +54,16 @@ This notice and disclaimer must be included on all copies of this document. Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA + +:xrefstyle: basic --> + + + @@ -71,7 +76,7 @@ Davis, CA 95616, USA - + @@ -84,7 +89,6 @@ Davis, CA 95616, USA - diff --git a/data_model/clusters/ContentControl.xml b/data_model/clusters/ContentControl.xml index b51bdff9397448..14996a7c28011a 100644 --- a/data_model/clusters/ContentControl.xml +++ b/data_model/clusters/ContentControl.xml @@ -59,6 +59,9 @@ Davis, CA 95616, USA + + + @@ -255,7 +258,7 @@ Davis, CA 95616, USA - + @@ -269,14 +272,13 @@ Davis, CA 95616, USA - + - @@ -285,15 +287,15 @@ Davis, CA 95616, USA - + - + - + @@ -307,7 +309,7 @@ Davis, CA 95616, USA - + @@ -317,19 +319,19 @@ Davis, CA 95616, USA - + - + - + @@ -339,7 +341,7 @@ Davis, CA 95616, USA - + @@ -349,7 +351,7 @@ Davis, CA 95616, USA - + @@ -359,7 +361,7 @@ Davis, CA 95616, USA - + @@ -369,7 +371,7 @@ Davis, CA 95616, USA - + @@ -379,7 +381,7 @@ Davis, CA 95616, USA - + @@ -389,7 +391,7 @@ Davis, CA 95616, USA - + @@ -398,7 +400,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/clusters/ContentLauncher.xml b/data_model/clusters/ContentLauncher.xml index 2c310c6f2ccb3d..b8f80de2e51ea7 100644 --- a/data_model/clusters/ContentLauncher.xml +++ b/data_model/clusters/ContentLauncher.xml @@ -54,11 +54,17 @@ This notice and disclaimer must be included on all copies of this document. Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA + +:xrefstyle: basic --> - + + + + + @@ -67,6 +73,15 @@ Davis, CA 95616, USA + + + + + + + + + @@ -119,12 +134,21 @@ Davis, CA 95616, USA - + + + + + + + + + + @@ -136,6 +160,16 @@ Davis, CA 95616, USA + + + + + + + + + + @@ -206,6 +240,27 @@ Davis, CA 95616, USA + + + + + + + + + + + + + + + + + + + + + @@ -220,6 +275,23 @@ Davis, CA 95616, USA + + + + + + + + + + + + + + + + + @@ -242,7 +314,7 @@ Davis, CA 95616, USA - + @@ -258,8 +330,15 @@ Davis, CA 95616, USA + + + + + + + - + @@ -273,9 +352,11 @@ Davis, CA 95616, USA + + + - diff --git a/data_model/clusters/DemandResponseLoadControl.xml b/data_model/clusters/DemandResponseLoadControl.xml index a5322bfb4f7206..206201b347612c 100644 --- a/data_model/clusters/DemandResponseLoadControl.xml +++ b/data_model/clusters/DemandResponseLoadControl.xml @@ -55,13 +55,16 @@ Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA --> - + + + + @@ -192,6 +195,59 @@ Davis, CA 95616, USA + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -222,6 +278,41 @@ Davis, CA 95616, USA + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -361,14 +452,14 @@ Davis, CA 95616, USA - + - + @@ -376,14 +467,14 @@ Davis, CA 95616, USA - + - + @@ -394,7 +485,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/clusters/Descriptor-Cluster.xml b/data_model/clusters/Descriptor-Cluster.xml index 9944d8a3f6ea4c..1b17fb4fdfdaea 100644 --- a/data_model/clusters/Descriptor-Cluster.xml +++ b/data_model/clusters/Descriptor-Cluster.xml @@ -54,12 +54,17 @@ This notice and disclaimer must be included on all copies of this document. Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA + +:xrefstyle: basic --> + + + diff --git a/data_model/clusters/DeviceEnergyManagement.xml b/data_model/clusters/DeviceEnergyManagement.xml index 21f74a737d52cb..e493c5b332182e 100644 --- a/data_model/clusters/DeviceEnergyManagement.xml +++ b/data_model/clusters/DeviceEnergyManagement.xml @@ -54,6 +54,8 @@ This notice and disclaimer must be included on all copies of this document. Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA + +:xrefstyle: basic --> @@ -61,6 +63,9 @@ Davis, CA 95616, USA + + + + @@ -487,13 +492,13 @@ Davis, CA 95616, USA - + - + @@ -507,7 +512,7 @@ Davis, CA 95616, USA - + @@ -521,13 +526,13 @@ Davis, CA 95616, USA - + - + @@ -545,7 +550,7 @@ Davis, CA 95616, USA - + @@ -560,7 +565,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/clusters/DiagnosticLogsCluster.xml b/data_model/clusters/DiagnosticLogsCluster.xml index 14f995ca1855a6..5b67564b18f298 100644 --- a/data_model/clusters/DiagnosticLogsCluster.xml +++ b/data_model/clusters/DiagnosticLogsCluster.xml @@ -1,7 +1,5 @@ - + + + + @@ -138,11 +139,11 @@ Davis, CA 95616, USA - + - + @@ -221,7 +222,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/clusters/DishwasherAlarm.xml b/data_model/clusters/DishwasherAlarm.xml index 7fda78ad163116..b3b67e2bffb500 100644 --- a/data_model/clusters/DishwasherAlarm.xml +++ b/data_model/clusters/DishwasherAlarm.xml @@ -54,11 +54,16 @@ This notice and disclaimer must be included on all copies of this document. Connectivity Standards Alliance + 508 Second Street, Suite 206 + Davis, CA 95616, USA + +:xrefstyle: short --> + + + diff --git a/data_model/clusters/DoorLock.xml b/data_model/clusters/DoorLock.xml index 4f84afca85ff1e..6284b973eb63e1 100644 --- a/data_model/clusters/DoorLock.xml +++ b/data_model/clusters/DoorLock.xml @@ -54,8 +54,10 @@ This notice and disclaimer must be included on all copies of this document. Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA + +:xrefstyle: basic --> - + @@ -64,7 +66,11 @@ Davis, CA 95616, USA + + + + @@ -98,14 +104,19 @@ Davis, CA 95616, USA - - - - - - - - + + + + + + + + + + + + + @@ -119,6 +130,14 @@ Davis, CA 95616, USA + + + + + + + + @@ -201,6 +220,23 @@ Davis, CA 95616, USA + + + + + + + + + + + + + + + @@ -334,6 +370,21 @@ Davis, CA 95616, USA + + + + + + + + + + + + + + + @@ -482,6 +533,11 @@ Davis, CA 95616, USA + + + + + @@ -1053,9 +1109,84 @@ Davis, CA 95616, USA + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + @@ -1067,7 +1198,7 @@ Davis, CA 95616, USA - + @@ -1079,11 +1210,11 @@ Davis, CA 95616, USA - + - + @@ -1098,7 +1229,7 @@ Davis, CA 95616, USA - + @@ -1109,7 +1240,6 @@ Davis, CA 95616, USA - @@ -1138,7 +1268,7 @@ Davis, CA 95616, USA - + @@ -1165,7 +1295,7 @@ Davis, CA 95616, USA - + @@ -1181,7 +1311,6 @@ Davis, CA 95616, USA - @@ -1209,7 +1338,7 @@ Davis, CA 95616, USA - + @@ -1225,7 +1354,7 @@ Davis, CA 95616, USA - + @@ -1236,7 +1365,7 @@ Davis, CA 95616, USA - + @@ -1259,7 +1388,7 @@ Davis, CA 95616, USA - + @@ -1279,7 +1408,6 @@ Davis, CA 95616, USA - @@ -1293,7 +1421,7 @@ Davis, CA 95616, USA - + @@ -1326,7 +1454,7 @@ Davis, CA 95616, USA - + @@ -1341,7 +1469,6 @@ Davis, CA 95616, USA - @@ -1377,7 +1504,7 @@ Davis, CA 95616, USA - + @@ -1392,7 +1519,7 @@ Davis, CA 95616, USA - + @@ -1412,7 +1539,7 @@ Davis, CA 95616, USA - + @@ -1427,7 +1554,6 @@ Davis, CA 95616, USA - @@ -1450,7 +1576,7 @@ Davis, CA 95616, USA - + @@ -1465,7 +1591,7 @@ Davis, CA 95616, USA - + @@ -1484,7 +1610,7 @@ Davis, CA 95616, USA - + @@ -1495,7 +1621,6 @@ Davis, CA 95616, USA - @@ -1520,7 +1645,7 @@ Davis, CA 95616, USA - + @@ -1531,7 +1656,7 @@ Davis, CA 95616, USA - + @@ -1553,7 +1678,7 @@ Davis, CA 95616, USA - + @@ -1573,7 +1698,6 @@ Davis, CA 95616, USA - @@ -1587,7 +1711,7 @@ Davis, CA 95616, USA - + @@ -1615,7 +1739,7 @@ Davis, CA 95616, USA - + @@ -1631,7 +1755,6 @@ Davis, CA 95616, USA - @@ -1659,7 +1782,7 @@ Davis, CA 95616, USA - + @@ -1675,7 +1798,7 @@ Davis, CA 95616, USA - + @@ -1686,7 +1809,7 @@ Davis, CA 95616, USA - + @@ -1731,7 +1854,7 @@ Davis, CA 95616, USA - + @@ -1742,7 +1865,6 @@ Davis, CA 95616, USA - @@ -1792,7 +1914,7 @@ Davis, CA 95616, USA - + @@ -1844,7 +1966,7 @@ Davis, CA 95616, USA - + @@ -1885,7 +2007,6 @@ Davis, CA 95616, USA - @@ -1904,7 +2025,7 @@ Davis, CA 95616, USA - + @@ -1914,7 +2035,6 @@ Davis, CA 95616, USA - @@ -1939,8 +2059,15 @@ Davis, CA 95616, USA + + + + + + + - + @@ -1951,7 +2078,7 @@ Davis, CA 95616, USA - + @@ -1965,6 +2092,36 @@ Davis, CA 95616, USA + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/data_model/clusters/EVSE-Attributes.xml b/data_model/clusters/EVSE-Attributes.xml deleted file mode 100644 index 2d492a27c4c0a1..00000000000000 --- a/data_model/clusters/EVSE-Attributes.xml +++ /dev/null @@ -1,45 +0,0 @@ - - - \ No newline at end of file diff --git a/data_model/clusters/EVSE-Classification.xml b/data_model/clusters/EVSE-Classification.xml deleted file mode 100644 index 22df357be3e9d0..00000000000000 --- a/data_model/clusters/EVSE-Classification.xml +++ /dev/null @@ -1,45 +0,0 @@ - - - \ No newline at end of file diff --git a/data_model/clusters/EVSE-ClusterID.xml b/data_model/clusters/EVSE-ClusterID.xml deleted file mode 100644 index 6f84afeb8d04bc..00000000000000 --- a/data_model/clusters/EVSE-ClusterID.xml +++ /dev/null @@ -1,45 +0,0 @@ - - - \ No newline at end of file diff --git a/data_model/clusters/EVSE-Commands.xml b/data_model/clusters/EVSE-Commands.xml deleted file mode 100644 index 030565e20f8f96..00000000000000 --- a/data_model/clusters/EVSE-Commands.xml +++ /dev/null @@ -1,45 +0,0 @@ - - - \ No newline at end of file diff --git a/data_model/clusters/EVSE-DataTypes.xml b/data_model/clusters/EVSE-DataTypes.xml deleted file mode 100644 index 790d66143c7025..00000000000000 --- a/data_model/clusters/EVSE-DataTypes.xml +++ /dev/null @@ -1,45 +0,0 @@ - - - \ No newline at end of file diff --git a/data_model/clusters/EVSE-Definitions.xml b/data_model/clusters/EVSE-Definitions.xml deleted file mode 100644 index 7ff6135a3d2976..00000000000000 --- a/data_model/clusters/EVSE-Definitions.xml +++ /dev/null @@ -1,45 +0,0 @@ - - - \ No newline at end of file diff --git a/data_model/clusters/EVSE-Dependencies.xml b/data_model/clusters/EVSE-Dependencies.xml deleted file mode 100644 index a87cb67a4623ae..00000000000000 --- a/data_model/clusters/EVSE-Dependencies.xml +++ /dev/null @@ -1,45 +0,0 @@ - - - \ No newline at end of file diff --git a/data_model/clusters/EVSE-Events.xml b/data_model/clusters/EVSE-Events.xml deleted file mode 100644 index 51401775a6fe59..00000000000000 --- a/data_model/clusters/EVSE-Events.xml +++ /dev/null @@ -1,45 +0,0 @@ - - - \ No newline at end of file diff --git a/data_model/clusters/EVSE-Features.xml b/data_model/clusters/EVSE-Features.xml deleted file mode 100644 index a8b48a53b401e9..00000000000000 --- a/data_model/clusters/EVSE-Features.xml +++ /dev/null @@ -1,45 +0,0 @@ - - - \ No newline at end of file diff --git a/data_model/clusters/EVSE-RevisionHistory.xml b/data_model/clusters/EVSE-RevisionHistory.xml deleted file mode 100644 index 89ca30f749e5e1..00000000000000 --- a/data_model/clusters/EVSE-RevisionHistory.xml +++ /dev/null @@ -1,45 +0,0 @@ - - - \ No newline at end of file diff --git a/data_model/clusters/ElectricalEnergyMeasurement.xml b/data_model/clusters/ElectricalEnergyMeasurement.xml index c6bf8e73863c41..98020764397116 100644 --- a/data_model/clusters/ElectricalEnergyMeasurement.xml +++ b/data_model/clusters/ElectricalEnergyMeasurement.xml @@ -54,11 +54,16 @@ This notice and disclaimer must be included on all copies of this document. Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA + +:xrefstyle: basic --> + + + @@ -74,7 +79,59 @@ Davis, CA 95616, USA - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/data_model/clusters/ElectricalPowerMeasurement.xml b/data_model/clusters/ElectricalPowerMeasurement.xml index aa5baeaf368cbb..c695e8db031790 100644 --- a/data_model/clusters/ElectricalPowerMeasurement.xml +++ b/data_model/clusters/ElectricalPowerMeasurement.xml @@ -54,11 +54,16 @@ This notice and disclaimer must be included on all copies of this document. Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA + +:xrefstyle: basic --> + + + @@ -95,6 +100,68 @@ Davis, CA 95616, USA + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/data_model/clusters/EnergyCalendar.xml b/data_model/clusters/EnergyCalendar.xml index a21845d92c47c4..8d3f1b343bb4a7 100644 --- a/data_model/clusters/EnergyCalendar.xml +++ b/data_model/clusters/EnergyCalendar.xml @@ -54,6 +54,8 @@ This notice and disclaimer must be included on all copies of this document. Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA + +:xrefstyle: short --> @@ -61,6 +63,9 @@ Davis, CA 95616, USA + + + diff --git a/data_model/clusters/EnergyEVSE.xml b/data_model/clusters/EnergyEVSE.xml index f59d41807d43e6..fa15692e78896d 100644 --- a/data_model/clusters/EnergyEVSE.xml +++ b/data_model/clusters/EnergyEVSE.xml @@ -54,12 +54,17 @@ This notice and disclaimer must be included on all copies of this document. Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA + +:xrefstyle: basic --> + + + @@ -395,7 +400,6 @@ Davis, CA 95616, USA - @@ -405,11 +409,11 @@ Davis, CA 95616, USA - + - + @@ -425,7 +429,7 @@ Davis, CA 95616, USA - + @@ -439,11 +443,11 @@ Davis, CA 95616, USA - + - + @@ -454,13 +458,13 @@ Davis, CA 95616, USA - + - + diff --git a/data_model/clusters/EnergyPreference.xml b/data_model/clusters/EnergyPreference.xml index 7156be8eafe025..c3676520ed6d01 100644 --- a/data_model/clusters/EnergyPreference.xml +++ b/data_model/clusters/EnergyPreference.xml @@ -54,11 +54,16 @@ This notice and disclaimer must be included on all copies of this document. Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA + +:xrefstyle: basic --> + + + diff --git a/data_model/clusters/EnergyPrice.xml b/data_model/clusters/EnergyPrice.xml index 23072a6a99ead5..1683fe1bbc13cf 100644 --- a/data_model/clusters/EnergyPrice.xml +++ b/data_model/clusters/EnergyPrice.xml @@ -54,6 +54,8 @@ This notice and disclaimer must be included on all copies of this document. Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA + +:xrefstyle: short --> @@ -62,6 +64,9 @@ Davis, CA 95616, USA + + + @@ -173,7 +178,7 @@ Davis, CA 95616, USA - + @@ -188,7 +193,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/clusters/FanControl.xml b/data_model/clusters/FanControl.xml index acf1d59e54d91e..756a7bd27466b3 100644 --- a/data_model/clusters/FanControl.xml +++ b/data_model/clusters/FanControl.xml @@ -54,6 +54,8 @@ This notice and disclaimer must be included on all copies of this document. Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA + +:xrefstyle: short --> @@ -62,6 +64,9 @@ Davis, CA 95616, USA + + + @@ -277,7 +282,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/clusters/FlowMeasurement.xml b/data_model/clusters/FlowMeasurement.xml index 66ad022c2c64ef..29f9d9d7ae58f9 100644 --- a/data_model/clusters/FlowMeasurement.xml +++ b/data_model/clusters/FlowMeasurement.xml @@ -54,6 +54,8 @@ This notice and disclaimer must be included on all copies of this document. Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA + +:xrefstyle: basic --> @@ -61,6 +63,9 @@ Davis, CA 95616, USA + + + diff --git a/data_model/clusters/GeneralCommissioningCluster.xml b/data_model/clusters/GeneralCommissioningCluster.xml index a25cdfc6ac934e..635a6635990654 100644 --- a/data_model/clusters/GeneralCommissioningCluster.xml +++ b/data_model/clusters/GeneralCommissioningCluster.xml @@ -1,7 +1,5 @@ - + + + + @@ -86,21 +89,22 @@ Davis, CA 95616, USA - + - + + - + - + - + - + @@ -117,35 +121,35 @@ Davis, CA 95616, USA - + - + - + - + - + - + - + - + - + @@ -160,13 +164,15 @@ Davis, CA 95616, USA - + + - + + @@ -184,14 +190,14 @@ Davis, CA 95616, USA - + - + @@ -199,20 +205,19 @@ Davis, CA 95616, USA - - + - + @@ -220,7 +225,6 @@ Davis, CA 95616, USA - diff --git a/data_model/clusters/Groups.xml b/data_model/clusters/Groups.xml index 175c9caf26a435..72902e878cbe9f 100644 --- a/data_model/clusters/Groups.xml +++ b/data_model/clusters/Groups.xml @@ -54,6 +54,8 @@ This notice and disclaimer must be included on all copies of this document. Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA + +:xrefstyle: basic --> @@ -62,6 +64,9 @@ Davis, CA 95616, USA + + + @@ -84,7 +89,7 @@ Davis, CA 95616, USA - + @@ -97,7 +102,6 @@ Davis, CA 95616, USA - @@ -108,7 +112,7 @@ Davis, CA 95616, USA - + @@ -117,7 +121,6 @@ Davis, CA 95616, USA - @@ -132,7 +135,7 @@ Davis, CA 95616, USA - + @@ -143,7 +146,6 @@ Davis, CA 95616, USA - @@ -156,7 +158,7 @@ Davis, CA 95616, USA - + @@ -165,7 +167,6 @@ Davis, CA 95616, USA - @@ -176,11 +177,11 @@ Davis, CA 95616, USA - + - + diff --git a/data_model/clusters/ICDManagement.xml b/data_model/clusters/ICDManagement.xml index 3cc6c9bfab4416..2a770a4f97f2b4 100644 --- a/data_model/clusters/ICDManagement.xml +++ b/data_model/clusters/ICDManagement.xml @@ -54,21 +54,41 @@ This notice and disclaimer must be included on all copies of this document. Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA + +// Update Name --> - + + + + + - + + + + + + + + + + + + + + + @@ -133,9 +153,28 @@ Davis, CA 95616, USA + + + + + + + + + + + + + + + + + + + - + @@ -156,7 +195,6 @@ Davis, CA 95616, USA - @@ -164,7 +202,7 @@ Davis, CA 95616, USA - + @@ -177,7 +215,7 @@ Davis, CA 95616, USA - + @@ -190,7 +228,6 @@ Davis, CA 95616, USA - diff --git a/data_model/clusters/Identify.xml b/data_model/clusters/Identify.xml index 379e684e51297d..1cdc33aa0df727 100644 --- a/data_model/clusters/Identify.xml +++ b/data_model/clusters/Identify.xml @@ -54,6 +54,8 @@ This notice and disclaimer must be included on all copies of this document. Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA + +:xrefstyle: basic --> @@ -62,6 +64,9 @@ Davis, CA 95616, USA + + + @@ -127,14 +132,14 @@ Davis, CA 95616, USA - + - + diff --git a/data_model/clusters/IlluminanceMeasurement.xml b/data_model/clusters/IlluminanceMeasurement.xml index c9be9fa6879293..c39daa0e6bdc4d 100644 --- a/data_model/clusters/IlluminanceMeasurement.xml +++ b/data_model/clusters/IlluminanceMeasurement.xml @@ -54,6 +54,8 @@ This notice and disclaimer must be included on all copies of this document. Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA + +:xrefstyle: basic --> @@ -61,6 +63,9 @@ Davis, CA 95616, USA + + + diff --git a/data_model/clusters/KeypadInput.xml b/data_model/clusters/KeypadInput.xml index f0459e6b1bff1a..4cfb509b06d0be 100644 --- a/data_model/clusters/KeypadInput.xml +++ b/data_model/clusters/KeypadInput.xml @@ -54,11 +54,16 @@ This notice and disclaimer must be included on all copies of this document. Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA + +:xrefstyle: basic --> + + + @@ -345,7 +350,7 @@ Davis, CA 95616, USA - + @@ -353,7 +358,6 @@ Davis, CA 95616, USA - diff --git a/data_model/clusters/Label-Cluster-FixedLabel.xml b/data_model/clusters/Label-Cluster-FixedLabelCluster.xml similarity index 96% rename from data_model/clusters/Label-Cluster-FixedLabel.xml rename to data_model/clusters/Label-Cluster-FixedLabelCluster.xml index 558664a5d69f72..e73bfc274a9da4 100644 --- a/data_model/clusters/Label-Cluster-FixedLabel.xml +++ b/data_model/clusters/Label-Cluster-FixedLabelCluster.xml @@ -54,11 +54,16 @@ This notice and disclaimer must be included on all copies of this document. Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA + +:xrefstyle: basic --> + + + diff --git a/data_model/clusters/Label-Cluster-Label.xml b/data_model/clusters/Label-Cluster-LabelCluster.xml similarity index 96% rename from data_model/clusters/Label-Cluster-Label.xml rename to data_model/clusters/Label-Cluster-LabelCluster.xml index ee64da775b05cd..f107a0a7b3f12b 100644 --- a/data_model/clusters/Label-Cluster-Label.xml +++ b/data_model/clusters/Label-Cluster-LabelCluster.xml @@ -54,11 +54,16 @@ This notice and disclaimer must be included on all copies of this document. Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA + +:xrefstyle: basic --> + + + diff --git a/data_model/clusters/Label-Cluster-UserLabel.xml b/data_model/clusters/Label-Cluster-UserLabelCluster.xml similarity index 96% rename from data_model/clusters/Label-Cluster-UserLabel.xml rename to data_model/clusters/Label-Cluster-UserLabelCluster.xml index bca4b1453f22de..f7e809ab785c00 100644 --- a/data_model/clusters/Label-Cluster-UserLabel.xml +++ b/data_model/clusters/Label-Cluster-UserLabelCluster.xml @@ -54,11 +54,16 @@ This notice and disclaimer must be included on all copies of this document. Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA + +:xrefstyle: basic --> + + + diff --git a/data_model/clusters/LaundryDryerControls.xml b/data_model/clusters/LaundryDryerControls.xml index 461f08666093b8..a3f7b911fc9e9c 100644 --- a/data_model/clusters/LaundryDryerControls.xml +++ b/data_model/clusters/LaundryDryerControls.xml @@ -59,6 +59,9 @@ Davis, CA 95616, USA + + + diff --git a/data_model/clusters/LaundryWasherControls.xml b/data_model/clusters/LaundryWasherControls.xml index 5a9d108ccc1b01..16879842721473 100644 --- a/data_model/clusters/LaundryWasherControls.xml +++ b/data_model/clusters/LaundryWasherControls.xml @@ -59,6 +59,9 @@ Davis, CA 95616, USA + + + diff --git a/data_model/clusters/LevelControl.xml b/data_model/clusters/LevelControl.xml index 8a348a2dc05cbd..6b2b3cace52ec3 100644 --- a/data_model/clusters/LevelControl.xml +++ b/data_model/clusters/LevelControl.xml @@ -54,6 +54,8 @@ This notice and disclaimer must be included on all copies of this document. Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA + +:xrefstyle: basic --> @@ -65,6 +67,7 @@ Davis, CA 95616, USA + @@ -210,7 +213,7 @@ Davis, CA 95616, USA - + @@ -230,7 +233,7 @@ Davis, CA 95616, USA - + @@ -250,7 +253,7 @@ Davis, CA 95616, USA - + @@ -273,7 +276,7 @@ Davis, CA 95616, USA - + @@ -285,23 +288,23 @@ Davis, CA 95616, USA - + - + - + - + - + diff --git a/data_model/clusters/LocalizationConfiguration.xml b/data_model/clusters/LocalizationConfiguration.xml index b264698b6d5393..f3c2d5b2d7662b 100644 --- a/data_model/clusters/LocalizationConfiguration.xml +++ b/data_model/clusters/LocalizationConfiguration.xml @@ -59,18 +59,25 @@ Davis, CA 95616, USA + + + - + - + - + + + + + \ No newline at end of file diff --git a/data_model/clusters/LocalizationTimeFormat.xml b/data_model/clusters/LocalizationTimeFormat.xml index 204f145f9c8b07..fb8ceea3ee17a8 100644 --- a/data_model/clusters/LocalizationTimeFormat.xml +++ b/data_model/clusters/LocalizationTimeFormat.xml @@ -59,6 +59,9 @@ Davis, CA 95616, USA + + + @@ -132,7 +135,8 @@ Davis, CA 95616, USA - + + diff --git a/data_model/clusters/LocalizationUnit.xml b/data_model/clusters/LocalizationUnit.xml index 24c54638b4ffd7..be7ea6a0aa2d78 100644 --- a/data_model/clusters/LocalizationUnit.xml +++ b/data_model/clusters/LocalizationUnit.xml @@ -59,6 +59,9 @@ Davis, CA 95616, USA + + + diff --git a/data_model/clusters/LowPower.xml b/data_model/clusters/LowPower.xml index f8ee432eef58a7..4c228d3154dfa1 100644 --- a/data_model/clusters/LowPower.xml +++ b/data_model/clusters/LowPower.xml @@ -54,14 +54,19 @@ This notice and disclaimer must be included on all copies of this document. Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA + +:xrefstyle: basic --> + + + - + diff --git a/data_model/clusters/MediaInput.xml b/data_model/clusters/MediaInput.xml index 9ca0f351d1f59f..b7d9d2ef017035 100644 --- a/data_model/clusters/MediaInput.xml +++ b/data_model/clusters/MediaInput.xml @@ -54,11 +54,16 @@ This notice and disclaimer must be included on all copies of this document. Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA + +:xrefstyle: basic --> + + + @@ -132,22 +137,22 @@ Davis, CA 95616, USA - + - + - + - + diff --git a/data_model/clusters/MediaPlayback.xml b/data_model/clusters/MediaPlayback.xml index f2cdf5c4a7c851..0a457a446208dd 100644 --- a/data_model/clusters/MediaPlayback.xml +++ b/data_model/clusters/MediaPlayback.xml @@ -54,11 +54,17 @@ This notice and disclaimer must be included on all copies of this document. Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA + +:xrefstyle: basic --> - + + + + + @@ -67,8 +73,73 @@ Davis, CA 95616, USA + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -118,6 +189,30 @@ Davis, CA 95616, USA + + + + + + + + + + + + + + + + + + + + + + + + @@ -172,52 +267,96 @@ Davis, CA 95616, USA + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - + - + - + - + - + - + + + + + + - + + + + + + - + - + @@ -225,7 +364,6 @@ Davis, CA 95616, USA - @@ -235,7 +373,7 @@ Davis, CA 95616, USA - + @@ -244,5 +382,92 @@ Davis, CA 95616, USA + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/data_model/clusters/Messages.xml b/data_model/clusters/Messages.xml index 9dd223d9a63f46..cea28ac15f54c9 100644 --- a/data_model/clusters/Messages.xml +++ b/data_model/clusters/Messages.xml @@ -55,6 +55,8 @@ Connectivity Standards Alliance + 508 Second Street, Suite 206 + Davis, CA 95616, USA +:xrefstyle: short + Copyright (C) Connectivity Standards Alliance (2021). All rights reserved. This information within this document is the property of the Connectivity Standards Alliance and its use and disclosure are restricted. @@ -91,6 +93,8 @@ are made. Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA + +:xrefstyle: basic --> @@ -98,6 +102,9 @@ Davis, CA 95616, USA + + + @@ -245,7 +252,7 @@ Davis, CA 95616, USA - + @@ -275,7 +282,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/clusters/MicrowaveOvenControl.xml b/data_model/clusters/MicrowaveOvenControl.xml index c95d713714854f..d7c6f72f740d3d 100644 --- a/data_model/clusters/MicrowaveOvenControl.xml +++ b/data_model/clusters/MicrowaveOvenControl.xml @@ -54,11 +54,16 @@ This notice and disclaimer must be included on all copies of this document. Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA + +:xrefstyle: basic --> + + + @@ -114,7 +119,7 @@ Davis, CA 95616, USA - + @@ -139,7 +144,7 @@ Davis, CA 95616, USA - + @@ -166,7 +171,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/clusters/ModeBase.xml b/data_model/clusters/ModeBase.xml index 5774a7fec0c5a5..2a11f85d343b39 100644 --- a/data_model/clusters/ModeBase.xml +++ b/data_model/clusters/ModeBase.xml @@ -61,6 +61,9 @@ Davis, CA 95616, USA + + + @@ -122,7 +125,7 @@ Require at least one standard mode tag. Define reserved ranges for base/derived - + diff --git a/data_model/clusters/ModeSelect.xml b/data_model/clusters/ModeSelect.xml index 19fe502c1fcfe2..a30a5b9bf8eca5 100644 --- a/data_model/clusters/ModeSelect.xml +++ b/data_model/clusters/ModeSelect.xml @@ -60,6 +60,9 @@ Davis, CA 95616, USA + + + @@ -133,7 +136,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/clusters/Mode_DeviceEnergyManagement.xml b/data_model/clusters/Mode_DeviceEnergyManagement.xml index 4181b9b60ead42..592c7d4290a342 100644 --- a/data_model/clusters/Mode_DeviceEnergyManagement.xml +++ b/data_model/clusters/Mode_DeviceEnergyManagement.xml @@ -54,11 +54,16 @@ This notice and disclaimer must be included on all copies of this document. Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA + +:xrefstyle: basic --> + + + diff --git a/data_model/clusters/Mode_Dishwasher.xml b/data_model/clusters/Mode_Dishwasher.xml index 22d0fab7897696..4ff6e78714f648 100644 --- a/data_model/clusters/Mode_Dishwasher.xml +++ b/data_model/clusters/Mode_Dishwasher.xml @@ -54,12 +54,17 @@ This notice and disclaimer must be included on all copies of this document. Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA + +:xrefstyle: basic --> + + + diff --git a/data_model/clusters/Mode_EVSE.xml b/data_model/clusters/Mode_EVSE.xml index 2a600e3e381325..de88cb3717c8bf 100644 --- a/data_model/clusters/Mode_EVSE.xml +++ b/data_model/clusters/Mode_EVSE.xml @@ -54,10 +54,15 @@ This notice and disclaimer must be included on all copies of this document. Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA + +:xrefstyle: basic --> + + + \ No newline at end of file diff --git a/data_model/clusters/Mode_LaundryWasher.xml b/data_model/clusters/Mode_LaundryWasher.xml index e89778fa9ea579..c59b2c3fef9051 100644 --- a/data_model/clusters/Mode_LaundryWasher.xml +++ b/data_model/clusters/Mode_LaundryWasher.xml @@ -54,12 +54,17 @@ This notice and disclaimer must be included on all copies of this document. Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA + +:xrefstyle: basic --> + + + diff --git a/data_model/clusters/Mode_MicrowaveOven.xml b/data_model/clusters/Mode_MicrowaveOven.xml index cd98c189c12844..6e8a129444b9fd 100644 --- a/data_model/clusters/Mode_MicrowaveOven.xml +++ b/data_model/clusters/Mode_MicrowaveOven.xml @@ -54,11 +54,16 @@ This notice and disclaimer must be included on all copies of this document. Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA + +:xrefstyle: basic --> + + + @@ -75,12 +80,10 @@ Davis, CA 95616, USA - - + - - + diff --git a/data_model/clusters/Mode_Oven.xml b/data_model/clusters/Mode_Oven.xml index 56a369dd425572..f6c7111bb844cd 100644 --- a/data_model/clusters/Mode_Oven.xml +++ b/data_model/clusters/Mode_Oven.xml @@ -54,10 +54,15 @@ This notice and disclaimer must be included on all copies of this document. Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA + +:xrefstyle: basic --> + + + \ No newline at end of file diff --git a/data_model/clusters/Mode_RVCClean.xml b/data_model/clusters/Mode_RVCClean.xml index 64118517a03c1b..d1b2272fc7e756 100644 --- a/data_model/clusters/Mode_RVCClean.xml +++ b/data_model/clusters/Mode_RVCClean.xml @@ -54,12 +54,17 @@ This notice and disclaimer must be included on all copies of this document. Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA + +:xrefstyle: basic --> + + + diff --git a/data_model/clusters/Mode_RVCRun.xml b/data_model/clusters/Mode_RVCRun.xml index 8f49741f7cfeb8..8e19b45a8385fc 100644 --- a/data_model/clusters/Mode_RVCRun.xml +++ b/data_model/clusters/Mode_RVCRun.xml @@ -54,12 +54,17 @@ This notice and disclaimer must be included on all copies of this document. Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA + +:xrefstyle: basic --> + + + diff --git a/data_model/clusters/Mode_Refrigerator.xml b/data_model/clusters/Mode_Refrigerator.xml index cf6a65721e0efd..d51e30b68d1320 100644 --- a/data_model/clusters/Mode_Refrigerator.xml +++ b/data_model/clusters/Mode_Refrigerator.xml @@ -54,12 +54,17 @@ This notice and disclaimer must be included on all copies of this document. Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA + +:xrefstyle: basic --> + + + diff --git a/data_model/clusters/Mode_WaterHeater.xml b/data_model/clusters/Mode_WaterHeater.xml index 69fba08b940293..56f1a1e9a66951 100644 --- a/data_model/clusters/Mode_WaterHeater.xml +++ b/data_model/clusters/Mode_WaterHeater.xml @@ -54,10 +54,15 @@ This notice and disclaimer must be included on all copies of this document. Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA + +:xrefstyle: basic --> + + + \ No newline at end of file diff --git a/data_model/clusters/NetworkCommissioningCluster.xml b/data_model/clusters/NetworkCommissioningCluster.xml index 0153146c149d26..86c7a01ce9f951 100644 --- a/data_model/clusters/NetworkCommissioningCluster.xml +++ b/data_model/clusters/NetworkCommissioningCluster.xml @@ -1,7 +1,5 @@ - + + + + @@ -73,6 +76,11 @@ Davis, CA 95616, USA + + + + + @@ -169,15 +177,34 @@ Davis, CA 95616, USA + + + - + - + + + + + + + + + + + + + + + + + @@ -191,11 +218,11 @@ Davis, CA 95616, USA - + - + @@ -229,17 +256,17 @@ Davis, CA 95616, USA - + - + - + - + @@ -265,10 +292,11 @@ Davis, CA 95616, USA - + + - + @@ -302,24 +330,25 @@ Davis, CA 95616, USA - + - + - + + - + @@ -337,7 +366,7 @@ Davis, CA 95616, USA - + @@ -345,19 +374,18 @@ Davis, CA 95616, USA - + - + - @@ -368,54 +396,68 @@ Davis, CA 95616, USA - + - + - + + - + + - + - + - + - + - + + + + + + + + + + + + + - + - + - + - + @@ -423,16 +465,15 @@ Davis, CA 95616, USA - + - + - @@ -443,16 +484,28 @@ Davis, CA 95616, USA - + - + - + + + + + + + + + + + + + - + @@ -460,16 +513,15 @@ Davis, CA 95616, USA - + - + - @@ -479,7 +531,7 @@ Davis, CA 95616, USA - + @@ -487,7 +539,7 @@ Davis, CA 95616, USA - + @@ -495,9 +547,9 @@ Davis, CA 95616, USA - + - + @@ -507,5 +559,32 @@ Davis, CA 95616, USA + + + + + + + + + + + + + + + + + + + + + + + + + + + - \ No newline at end of file + diff --git a/data_model/clusters/NetworkIdentityManagement.xml b/data_model/clusters/NetworkIdentityManagement.xml index 08bee6af5871ff..8769b68583e4b9 100644 --- a/data_model/clusters/NetworkIdentityManagement.xml +++ b/data_model/clusters/NetworkIdentityManagement.xml @@ -54,11 +54,16 @@ This notice and disclaimer must be included on all copies of this document. Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA + +:xrefstyle: basic --> + + + @@ -119,7 +124,7 @@ Davis, CA 95616, USA - + @@ -130,7 +135,7 @@ Davis, CA 95616, USA - + @@ -141,7 +146,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/clusters/OTAProvider.xml b/data_model/clusters/OTAProvider.xml index 73157662cd6f6e..baf3996d3b911f 100644 --- a/data_model/clusters/OTAProvider.xml +++ b/data_model/clusters/OTAProvider.xml @@ -1,7 +1,5 @@ @@ -62,6 +64,9 @@ Davis, CA 95616, USA + + + diff --git a/data_model/clusters/OnOff.xml b/data_model/clusters/OnOff.xml index 0d64837ea57fbb..0b1e32af50cddb 100644 --- a/data_model/clusters/OnOff.xml +++ b/data_model/clusters/OnOff.xml @@ -54,6 +54,8 @@ This notice and disclaimer must be included on all copies of this document. Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA + +:xrefstyle: basic --> @@ -64,6 +66,9 @@ Davis, CA 95616, USA + + + @@ -171,11 +176,11 @@ Davis, CA 95616, USA - + - + @@ -183,7 +188,7 @@ Davis, CA 95616, USA - + @@ -191,7 +196,7 @@ Davis, CA 95616, USA - + @@ -205,13 +210,13 @@ Davis, CA 95616, USA - + - + diff --git a/data_model/clusters/OperationalCredentialCluster.xml b/data_model/clusters/OperationalCredentialCluster.xml index ec523ba33671d1..1a2becd5c478a2 100644 --- a/data_model/clusters/OperationalCredentialCluster.xml +++ b/data_model/clusters/OperationalCredentialCluster.xml @@ -1,7 +1,5 @@ - + + + + @@ -98,10 +99,10 @@ Davis, CA 95616, USA - + - + @@ -115,11 +116,11 @@ Davis, CA 95616, USA - + - + - + @@ -136,32 +137,34 @@ Davis, CA 95616, USA - + - + - + - + - + + - + - + + - + @@ -175,10 +178,14 @@ Davis, CA 95616, USA - + + + + + @@ -186,7 +193,7 @@ Davis, CA 95616, USA - + @@ -195,7 +202,6 @@ Davis, CA 95616, USA - @@ -206,7 +212,7 @@ Davis, CA 95616, USA - + @@ -215,14 +221,13 @@ Davis, CA 95616, USA - - + @@ -234,7 +239,6 @@ Davis, CA 95616, USA - @@ -245,29 +249,29 @@ Davis, CA 95616, USA - + - + - + - + - + - + - + - + - + @@ -280,7 +284,6 @@ Davis, CA 95616, USA - @@ -294,7 +297,7 @@ Davis, CA 95616, USA - + @@ -302,7 +305,7 @@ Davis, CA 95616, USA - + @@ -310,12 +313,12 @@ Davis, CA 95616, USA - + - + - + diff --git a/data_model/clusters/OperationalState.xml b/data_model/clusters/OperationalState.xml index dcb5753b2c1998..0062b38b4b3981 100644 --- a/data_model/clusters/OperationalState.xml +++ b/data_model/clusters/OperationalState.xml @@ -60,6 +60,9 @@ Davis, CA 95616, USA + + + @@ -143,6 +146,53 @@ Davis, CA 95616, USA + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/data_model/clusters/OperationalState_Oven.xml b/data_model/clusters/OperationalState_Oven.xml index 947e93f8ec2348..c44ac37b7ccac9 100644 --- a/data_model/clusters/OperationalState_Oven.xml +++ b/data_model/clusters/OperationalState_Oven.xml @@ -54,10 +54,15 @@ This notice and disclaimer must be included on all copies of this document. Connectivity Standards Alliance + 508 Second Street, Suite 206 + Davis, CA 95616, USA + +:xrefstyle: basic --> + + + \ No newline at end of file diff --git a/data_model/clusters/OperationalState_RVC.xml b/data_model/clusters/OperationalState_RVC.xml index bc4e5505e45d6d..6426e2639a7b83 100644 --- a/data_model/clusters/OperationalState_RVC.xml +++ b/data_model/clusters/OperationalState_RVC.xml @@ -54,32 +54,29 @@ This notice and disclaimer must be included on all copies of this document. Connectivity Standards Alliance + 508 Second Street, Suite 206 + Davis, CA 95616, USA + +:xrefstyle: basic --> + + + - - - - - + + - - + - - - - - - - + + + diff --git a/data_model/clusters/PowerSourceCluster.xml b/data_model/clusters/PowerSourceCluster.xml index 16d6f0ac98cad5..ffd628de6686b8 100644 --- a/data_model/clusters/PowerSourceCluster.xml +++ b/data_model/clusters/PowerSourceCluster.xml @@ -61,6 +61,9 @@ Davis, CA 95616, USA + + + @@ -911,13 +914,13 @@ Davis, CA 95616, USA - + - + @@ -928,12 +931,14 @@ Davis, CA 95616, USA + + - + @@ -944,9 +949,10 @@ Davis, CA 95616, USA + - + @@ -957,13 +963,15 @@ Davis, CA 95616, USA - + + - + - + + - + @@ -971,13 +979,15 @@ Davis, CA 95616, USA - + + - + - + + - + @@ -985,13 +995,15 @@ Davis, CA 95616, USA - + + - + - + + - + diff --git a/data_model/clusters/PowerSourceConfigurationCluster.xml b/data_model/clusters/PowerSourceConfigurationCluster.xml index 5548bf6ad8e6b5..11e3bd47dd9186 100644 --- a/data_model/clusters/PowerSourceConfigurationCluster.xml +++ b/data_model/clusters/PowerSourceConfigurationCluster.xml @@ -59,10 +59,13 @@ Davis, CA 95616, USA + + + - + diff --git a/data_model/clusters/PowerTopology.xml b/data_model/clusters/PowerTopology.xml index c8d90baeeded19..d8c8a50d22a3a6 100644 --- a/data_model/clusters/PowerTopology.xml +++ b/data_model/clusters/PowerTopology.xml @@ -54,11 +54,16 @@ This notice and disclaimer must be included on all copies of this document. Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA + +:xrefstyle: short --> + + + diff --git a/data_model/clusters/PressureMeasurement.xml b/data_model/clusters/PressureMeasurement.xml index 70093485639090..d9c4a4584404fe 100644 --- a/data_model/clusters/PressureMeasurement.xml +++ b/data_model/clusters/PressureMeasurement.xml @@ -54,6 +54,8 @@ This notice and disclaimer must be included on all copies of this document. Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA + +:xrefstyle: basic --> @@ -61,6 +63,9 @@ Davis, CA 95616, USA + + + diff --git a/data_model/clusters/PumpConfigurationControl.xml b/data_model/clusters/PumpConfigurationControl.xml index f3fc98a52cee9e..cfd2971a395ecb 100644 --- a/data_model/clusters/PumpConfigurationControl.xml +++ b/data_model/clusters/PumpConfigurationControl.xml @@ -62,6 +62,9 @@ Davis, CA 95616, USA + + + @@ -169,7 +172,206 @@ Davis, CA 95616, USA - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/data_model/clusters/RefrigeratorAlarm.xml b/data_model/clusters/RefrigeratorAlarm.xml index c987c3860a4f52..caad94da1f6fad 100644 --- a/data_model/clusters/RefrigeratorAlarm.xml +++ b/data_model/clusters/RefrigeratorAlarm.xml @@ -54,11 +54,16 @@ This notice and disclaimer must be included on all copies of this document. Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA + +:xrefstyle: short --> + + + @@ -73,8 +78,7 @@ Davis, CA 95616, USA - - + diff --git a/data_model/clusters/ResourceMonitoring.xml b/data_model/clusters/ResourceMonitoring.xml index 17fc7554ac41f0..6b0e8f3a203ded 100644 --- a/data_model/clusters/ResourceMonitoring.xml +++ b/data_model/clusters/ResourceMonitoring.xml @@ -54,6 +54,8 @@ This notice and disclaimer must be included on all copies of this document. Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA + +:xrefstyle: basic --> @@ -164,7 +166,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/clusters/Scenes.xml b/data_model/clusters/Scenes.xml index 0c4347c4e8be8a..5d9be300d1abbc 100644 --- a/data_model/clusters/Scenes.xml +++ b/data_model/clusters/Scenes.xml @@ -54,11 +54,16 @@ This notice and disclaimer must be included on all copies of this document. Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA + +:xrefstyle: basic --> + + + @@ -116,17 +121,14 @@ Davis, CA 95616, USA - - - @@ -177,7 +179,7 @@ Davis, CA 95616, USA - + @@ -189,7 +191,7 @@ Davis, CA 95616, USA - + @@ -202,7 +204,6 @@ Davis, CA 95616, USA - @@ -216,7 +217,7 @@ Davis, CA 95616, USA - + @@ -228,7 +229,6 @@ Davis, CA 95616, USA - @@ -242,7 +242,7 @@ Davis, CA 95616, USA - + @@ -251,7 +251,7 @@ Davis, CA 95616, USA - + @@ -263,7 +263,6 @@ Davis, CA 95616, USA - @@ -277,7 +276,7 @@ Davis, CA 95616, USA - + @@ -285,7 +284,6 @@ Davis, CA 95616, USA - @@ -295,7 +293,7 @@ Davis, CA 95616, USA - + @@ -307,7 +305,6 @@ Davis, CA 95616, USA - @@ -321,7 +318,7 @@ Davis, CA 95616, USA - + @@ -337,7 +334,7 @@ Davis, CA 95616, USA - + @@ -345,7 +342,6 @@ Davis, CA 95616, USA - @@ -362,7 +358,7 @@ Davis, CA 95616, USA - + @@ -383,9 +379,8 @@ Davis, CA 95616, USA - - + diff --git a/data_model/clusters/SmokeCOAlarm.xml b/data_model/clusters/SmokeCOAlarm.xml index 0db5c78f4e947f..d3d35f13f15f25 100644 --- a/data_model/clusters/SmokeCOAlarm.xml +++ b/data_model/clusters/SmokeCOAlarm.xml @@ -54,11 +54,16 @@ This notice and disclaimer must be included on all copies of this document. Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA + +:xrefstyle: basic --> + + + @@ -226,7 +231,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/clusters/Switch.xml b/data_model/clusters/Switch.xml index 30602c35bf794f..e7170049ac051f 100644 --- a/data_model/clusters/Switch.xml +++ b/data_model/clusters/Switch.xml @@ -59,6 +59,9 @@ Davis, CA 95616, USA + + + diff --git a/data_model/clusters/TargetNavigator.xml b/data_model/clusters/TargetNavigator.xml index 343f1427176e41..cfb3a0c17a6f99 100644 --- a/data_model/clusters/TargetNavigator.xml +++ b/data_model/clusters/TargetNavigator.xml @@ -54,11 +54,17 @@ This notice and disclaimer must be included on all copies of this document. Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA + +:xrefstyle: basic --> - + + + + + @@ -95,7 +101,7 @@ Davis, CA 95616, USA - + @@ -106,7 +112,6 @@ Davis, CA 95616, USA - @@ -116,4 +121,22 @@ Davis, CA 95616, USA + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/data_model/clusters/TemperatureControl.xml b/data_model/clusters/TemperatureControl.xml index f457238bab1d8a..70fc100d83bbab 100644 --- a/data_model/clusters/TemperatureControl.xml +++ b/data_model/clusters/TemperatureControl.xml @@ -59,6 +59,9 @@ Davis, CA 95616, USA + + + @@ -73,9 +76,58 @@ Davis, CA 95616, USA - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + diff --git a/data_model/clusters/TemperatureMeasurement.xml b/data_model/clusters/TemperatureMeasurement.xml index e1603fd3358bc3..540af82bcedd18 100644 --- a/data_model/clusters/TemperatureMeasurement.xml +++ b/data_model/clusters/TemperatureMeasurement.xml @@ -54,6 +54,8 @@ This notice and disclaimer must be included on all copies of this document. Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA + +:xrefstyle: basic --> @@ -62,6 +64,9 @@ Davis, CA 95616, USA + + + diff --git a/data_model/clusters/Thermostat.xml b/data_model/clusters/Thermostat.xml index 400d55a048a116..756e27940c2cba 100644 --- a/data_model/clusters/Thermostat.xml +++ b/data_model/clusters/Thermostat.xml @@ -55,7 +55,7 @@ Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA --> - + @@ -63,7 +63,11 @@ Davis, CA 95616, USA + + + + @@ -102,6 +106,17 @@ Davis, CA 95616, USA + + + + + + + + + + + @@ -212,13 +227,36 @@ Davis, CA 95616, USA + + + + + + + + + + + + + + + + + + + + - + + + + @@ -297,7 +335,7 @@ Davis, CA 95616, USA - + @@ -372,6 +410,14 @@ Davis, CA 95616, USA + + + + + + + + @@ -451,6 +497,149 @@ Davis, CA 95616, USA + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -823,9 +1012,110 @@ Davis, CA 95616, USA + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + @@ -837,7 +1127,6 @@ Davis, CA 95616, USA - @@ -858,7 +1147,7 @@ Davis, CA 95616, USA - + @@ -881,9 +1170,8 @@ Davis, CA 95616, USA - - + @@ -909,7 +1197,7 @@ Davis, CA 95616, USA - + @@ -923,17 +1211,79 @@ Davis, CA 95616, USA - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/data_model/clusters/ThermostatUserInterfaceConfiguration.xml b/data_model/clusters/ThermostatUserInterfaceConfiguration.xml index 6c8d1d920e6ef7..63fdba001c67a9 100644 --- a/data_model/clusters/ThermostatUserInterfaceConfiguration.xml +++ b/data_model/clusters/ThermostatUserInterfaceConfiguration.xml @@ -60,6 +60,9 @@ Davis, CA 95616, USA + + + diff --git a/data_model/clusters/ThreadBorderRouterDiagnostics.xml b/data_model/clusters/ThreadBorderRouterDiagnostics.xml index 29b5da9b8511f0..5527c486a0cc51 100644 --- a/data_model/clusters/ThreadBorderRouterDiagnostics.xml +++ b/data_model/clusters/ThreadBorderRouterDiagnostics.xml @@ -54,19 +54,23 @@ This notice and disclaimer must be included on all copies of this document. Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA + +:xrefstyle: basic --> + + + - + - @@ -75,12 +79,11 @@ Davis, CA 95616, USA - + - diff --git a/data_model/clusters/TimeSync.xml b/data_model/clusters/TimeSync.xml index 096e0ff2798261..99ec173bc7e6e1 100644 --- a/data_model/clusters/TimeSync.xml +++ b/data_model/clusters/TimeSync.xml @@ -1,7 +1,5 @@ + + + @@ -112,19 +116,19 @@ Davis, CA 95616, USA - + - + - + - + @@ -133,22 +137,22 @@ Davis, CA 95616, USA - + - + - + - + - + - + @@ -178,9 +182,9 @@ Davis, CA 95616, USA - + - + @@ -192,10 +196,6 @@ Davis, CA 95616, USA - - - - \ No newline at end of file diff --git a/data_model/clusters/ValveConfigurationControl.xml b/data_model/clusters/ValveConfigurationControl.xml index 32620ad9cce97d..548fed7d7357c2 100644 --- a/data_model/clusters/ValveConfigurationControl.xml +++ b/data_model/clusters/ValveConfigurationControl.xml @@ -54,11 +54,16 @@ This notice and disclaimer must be included on all copies of this document. Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA + +:xrefstyle: basic --> + + + @@ -171,7 +176,7 @@ Davis, CA 95616, USA - + @@ -186,7 +191,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/clusters/WakeOnLAN.xml b/data_model/clusters/WakeOnLAN.xml index 799c92a03fd9b8..deb5af5a75ac7d 100644 --- a/data_model/clusters/WakeOnLAN.xml +++ b/data_model/clusters/WakeOnLAN.xml @@ -54,11 +54,16 @@ This notice and disclaimer must be included on all copies of this document. Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA + +:xrefstyle: basic --> - + + + + diff --git a/data_model/clusters/WaterContentMeasurement.xml b/data_model/clusters/WaterContentMeasurement.xml index 8b1ff6a9a049bc..85d44793c93ae4 100644 --- a/data_model/clusters/WaterContentMeasurement.xml +++ b/data_model/clusters/WaterContentMeasurement.xml @@ -54,6 +54,8 @@ This notice and disclaimer must be included on all copies of this document. Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA + +:xrefstyle: basic --> @@ -61,6 +63,9 @@ Davis, CA 95616, USA + + + diff --git a/data_model/clusters/WaterHeaterManagement.xml b/data_model/clusters/WaterHeaterManagement.xml index 073da0094b0b4b..4b6368555bf1d6 100644 --- a/data_model/clusters/WaterHeaterManagement.xml +++ b/data_model/clusters/WaterHeaterManagement.xml @@ -54,11 +54,16 @@ This notice and disclaimer must be included on all copies of this document. Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA + +:xrefstyle: basic --> + + + @@ -129,7 +134,7 @@ Davis, CA 95616, USA - + @@ -151,7 +156,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/clusters/WiFiNetworkManagement.xml b/data_model/clusters/WiFiNetworkManagement.xml index 6308eca7e4b184..fbb7a84a4e17b2 100644 --- a/data_model/clusters/WiFiNetworkManagement.xml +++ b/data_model/clusters/WiFiNetworkManagement.xml @@ -54,11 +54,16 @@ This notice and disclaimer must be included on all copies of this document. Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA + +:xrefstyle: basic --> - + + + + @@ -69,12 +74,11 @@ Davis, CA 95616, USA - + - diff --git a/data_model/clusters/WindowCovering.xml b/data_model/clusters/WindowCovering.xml index 3ee6d43ded8bce..7b0afd461fcb96 100644 --- a/data_model/clusters/WindowCovering.xml +++ b/data_model/clusters/WindowCovering.xml @@ -54,6 +54,8 @@ This notice and disclaimer must be included on all copies of this document. Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA + +:xrefstyle: basic --> @@ -63,6 +65,9 @@ Davis, CA 95616, USA + + + @@ -608,19 +613,19 @@ Davis, CA 95616, USA - + - + - + - + @@ -633,7 +638,7 @@ Davis, CA 95616, USA - + @@ -655,7 +660,7 @@ Davis, CA 95616, USA - + @@ -668,7 +673,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/clusters/bridge-clusters-Actions.xml b/data_model/clusters/bridge-clusters-ActionsCluster.xml similarity index 87% rename from data_model/clusters/bridge-clusters-Actions.xml rename to data_model/clusters/bridge-clusters-ActionsCluster.xml index 51f7ee79bb4bad..e02b12e43d64a4 100644 --- a/data_model/clusters/bridge-clusters-Actions.xml +++ b/data_model/clusters/bridge-clusters-ActionsCluster.xml @@ -54,11 +54,16 @@ This notice and disclaimer must be included on all copies of this document. Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA + +:sectnums: --> + + + @@ -159,7 +164,7 @@ Davis, CA 95616, USA - + @@ -181,7 +186,7 @@ Davis, CA 95616, USA - + @@ -189,32 +194,35 @@ Davis, CA 95616, USA - + + - + - + + - + - + + - + - + - + - + @@ -223,7 +231,7 @@ Davis, CA 95616, USA - + @@ -235,7 +243,7 @@ Davis, CA 95616, USA - + @@ -244,7 +252,7 @@ Davis, CA 95616, USA - + @@ -256,7 +264,7 @@ Davis, CA 95616, USA - + @@ -265,7 +273,7 @@ Davis, CA 95616, USA - + @@ -274,7 +282,7 @@ Davis, CA 95616, USA - + @@ -286,7 +294,7 @@ Davis, CA 95616, USA - + @@ -295,7 +303,7 @@ Davis, CA 95616, USA - + @@ -304,7 +312,7 @@ Davis, CA 95616, USA - + @@ -316,7 +324,7 @@ Davis, CA 95616, USA - + @@ -325,7 +333,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/clusters/bridge-clusters-BridgedDeviceBasicInformation.xml b/data_model/clusters/bridge-clusters-BridgedDeviceBasicInformationCluster.xml similarity index 95% rename from data_model/clusters/bridge-clusters-BridgedDeviceBasicInformation.xml rename to data_model/clusters/bridge-clusters-BridgedDeviceBasicInformationCluster.xml index 5c4bd86b9ab7e4..1dd336ef3656a3 100644 --- a/data_model/clusters/bridge-clusters-BridgedDeviceBasicInformation.xml +++ b/data_model/clusters/bridge-clusters-BridgedDeviceBasicInformationCluster.xml @@ -54,13 +54,18 @@ This notice and disclaimer must be included on all copies of this document. Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA + +:sectnums: --> - + + + + @@ -129,6 +134,9 @@ Davis, CA 95616, USA + + + diff --git a/data_model/clusters/energy_management.xml b/data_model/clusters/energy_management.xml index 792560796cdd4d..93858d1d1b3c89 100644 --- a/data_model/clusters/energy_management.xml +++ b/data_model/clusters/energy_management.xml @@ -54,5 +54,7 @@ This notice and disclaimer must be included on all copies of this document. Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA + +:toc: --> \ No newline at end of file diff --git a/data_model/clusters/network_infrastructure.xml b/data_model/clusters/network_infrastructure.xml index 181ee350003454..7e75cc0af8229f 100644 --- a/data_model/clusters/network_infrastructure.xml +++ b/data_model/clusters/network_infrastructure.xml @@ -59,4 +59,4 @@ Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA --> - \ No newline at end of file + diff --git a/data_model/device_types/BaseDeviceType.xml b/data_model/device_types/BaseDeviceType.xml index a92816ac49d6e1..22cec956aa6061 100644 --- a/data_model/device_types/BaseDeviceType.xml +++ b/data_model/device_types/BaseDeviceType.xml @@ -62,23 +62,4 @@ Davis, CA 95616, USA - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/data_model/device_types/Cooktop.xml b/data_model/device_types/Cooktop.xml index 233c72ed37590a..ea94653008d25a 100644 --- a/data_model/device_types/Cooktop.xml +++ b/data_model/device_types/Cooktop.xml @@ -71,9 +71,6 @@ Davis, CA 95616, USA - - - diff --git a/data_model/clusters/Timer.xml b/data_model/device_types/DeviceEnergyManagement.xml similarity index 55% rename from data_model/clusters/Timer.xml rename to data_model/device_types/DeviceEnergyManagement.xml index ad0d864f016e92..9d993a9454ea15 100644 --- a/data_model/clusters/Timer.xml +++ b/data_model/device_types/DeviceEnergyManagement.xml @@ -55,77 +55,17 @@ Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA --> - + - + - - - - - - - - - - - - - - - - - - - - - - - - - + + + - - - - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file + + + \ No newline at end of file diff --git a/data_model/device_types/EVSE.xml b/data_model/device_types/EVSE.xml index f15b1db770b454..9e6ce7be28f301 100644 --- a/data_model/device_types/EVSE.xml +++ b/data_model/device_types/EVSE.xml @@ -65,28 +65,6 @@ Davis, CA 95616, USA - - - - - - - - - - - - - - - - - - - - - - diff --git a/data_model/device_types/Thermostat.xml b/data_model/device_types/Thermostat.xml index fc154468e97c5f..cbdedb7c039ed5 100644 --- a/data_model/device_types/Thermostat.xml +++ b/data_model/device_types/Thermostat.xml @@ -82,13 +82,13 @@ Davis, CA 95616, USA - + - + diff --git a/data_model/scraper_version b/data_model/scraper_version index 0495c4a88caed0..e8ea05db81420d 100644 --- a/data_model/scraper_version +++ b/data_model/scraper_version @@ -1 +1 @@ -1.2.3 +1.2.4 diff --git a/data_model/spec_sha b/data_model/spec_sha index ec683a1872fc3e..97f7f06deb9fe9 100644 --- a/data_model/spec_sha +++ b/data_model/spec_sha @@ -1 +1 @@ -72ce960f71810d6ca96125aea54e4fb0a9631e34 +b0310bae0264a29665f23a8f3d4dc4f742be6075 diff --git a/scripts/spec_xml/generate_spec_xml.py b/scripts/spec_xml/generate_spec_xml.py index f4f30d060096a0..016f92d4b5759a 100755 --- a/scripts/spec_xml/generate_spec_xml.py +++ b/scripts/spec_xml/generate_spec_xml.py @@ -79,7 +79,7 @@ def scrape_clusters(scraper, spec_root, output_dir, dry_run): def scrape_cluster(filename: str) -> None: xml_path = get_xml_path(filename, clusters_output_dir) - cmd = [scraper, 'cluster', '-i', filename, '-o', xml_path, '-nd'] + cmd = [scraper, 'cluster', '-i', filename, '-o', xml_path, '-nd', '--define', 'in-progress'] if dry_run: print(cmd) else: diff --git a/src/python_testing/spec_parsing_support.py b/src/python_testing/spec_parsing_support.py index 9b65df0d0dcab5..6a9d1f87ae3442 100644 --- a/src/python_testing/spec_parsing_support.py +++ b/src/python_testing/spec_parsing_support.py @@ -354,6 +354,9 @@ def get_command_type(self, element: ElementTree.Element) -> CommandType: return CommandType.GENERATED if element.attrib['direction'].lower() == 'commandtoclient': return CommandType.UNKNOWN + if element.attrib['direction'].lower() == 'commandtoserver': + return CommandType.ACCEPTED + raise Exception(f"Unknown direction: {element.attrib['direction']}") except KeyError: return CommandType.ACCEPTED From c13b324a3b9dcd3b278015c03c33ceab5fbd1a30 Mon Sep 17 00:00:00 2001 From: Erwin Pan Date: Sat, 17 Feb 2024 13:10:39 +0800 Subject: [PATCH 23/33] [Chef] fix air quality sensor build broken (#32191) * [Chef] fix air quality senesor build broken * Restyled by clang-format --------- Co-authored-by: Restyled.io --- examples/chef/common/chef-air-quality.h | 12 ++++++------ .../chef/common/chef-concentration-measurement.h | 13 +++++++------ 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/examples/chef/common/chef-air-quality.h b/examples/chef/common/chef-air-quality.h index 2eaf3ef28fdf66..e7589488d41d74 100644 --- a/examples/chef/common/chef-air-quality.h +++ b/examples/chef/common/chef-air-quality.h @@ -22,10 +22,10 @@ #include #ifdef MATTER_DM_PLUGIN_AIR_QUALITY_SERVER -Protocols::InteractionModel::Status chefAirQualityWriteCallback(chip::EndpointId endpoint, chip::ClusterId clusterId, - const EmberAfAttributeMetadata * attributeMetadata, - uint8_t * buffer); -Protocols::InteractionModel::Status chefAirQualityReadCallback(chip::EndpointId endpoint, chip::ClusterId clusterId, - const EmberAfAttributeMetadata * attributeMetadata, uint8_t * buffer, - uint16_t maxReadLength); +chip::Protocols::InteractionModel::Status chefAirQualityWriteCallback(chip::EndpointId endpoint, chip::ClusterId clusterId, + const EmberAfAttributeMetadata * attributeMetadata, + uint8_t * buffer); +chip::Protocols::InteractionModel::Status chefAirQualityReadCallback(chip::EndpointId endpoint, chip::ClusterId clusterId, + const EmberAfAttributeMetadata * attributeMetadata, + uint8_t * buffer, uint16_t maxReadLength); #endif diff --git a/examples/chef/common/chef-concentration-measurement.h b/examples/chef/common/chef-concentration-measurement.h index 9b8fc571872c6b..887df7d943ee08 100644 --- a/examples/chef/common/chef-concentration-measurement.h +++ b/examples/chef/common/chef-concentration-measurement.h @@ -31,10 +31,11 @@ defined(MATTER_DM_PLUGIN_PM10_CONCENTRATION_MEASUREMENT_SERVER) || \ defined(MATTER_DM_PLUGIN_TOTAL_VOLATILE_ORGANIC_COMPOUNDS_CONCENTRATION_MEASUREMENT_SERVER) || \ defined(MATTER_DM_PLUGIN_RADON_CONCENTRATION_MEASUREMENT_SERVER) -Protocols::InteractionModel::Status chefConcentrationMeasurementWriteCallback(chip::EndpointId endpoint, chip::ClusterId clusterId, - const EmberAfAttributeMetadata * attributeMetadata, - uint8_t * buffer); -Protocols::InteractionModel::Status chefConcentrationMeasurementReadCallback(chip::EndpointId endpoint, chip::ClusterId clusterId, - const EmberAfAttributeMetadata * attributeMetadata, - uint8_t * buffer, uint16_t maxReadLength); +chip::Protocols::InteractionModel::Status +chefConcentrationMeasurementWriteCallback(chip::EndpointId endpoint, chip::ClusterId clusterId, + const EmberAfAttributeMetadata * attributeMetadata, uint8_t * buffer); +chip::Protocols::InteractionModel::Status +chefConcentrationMeasurementReadCallback(chip::EndpointId endpoint, chip::ClusterId clusterId, + const EmberAfAttributeMetadata * attributeMetadata, uint8_t * buffer, + uint16_t maxReadLength); #endif From 2f2c4f1e311c9c35912e21156f816837986bc857 Mon Sep 17 00:00:00 2001 From: Jeff Tung <100387939+jtung-apple@users.noreply.github.com> Date: Fri, 16 Feb 2024 23:57:19 -0800 Subject: [PATCH 24/33] [Darwin] MTRDevice attribute cache persistent storage local test facility (#32181) * [Darwin] MTRDevice attribute cache persistent storage local test facility * Fix header scope * Fix CI compilation issue * Added MTR_PER_CONTROLLER_STORAGE_ENABLED check to fix darwin CI * Fix for the previous fix - now double tested --- src/darwin/Framework/CHIP/MTRBaseDevice.mm | 2 +- .../Framework/CHIP/MTRDeviceController.mm | 22 +++- .../MTRDeviceControllerLocalTestStorage.h | 37 +++++++ .../MTRDeviceControllerLocalTestStorage.m | 97 +++++++++++++++++ .../Framework/CHIPTests/MTRDeviceTests.m | 101 +++++++++++++++--- .../CHIPTests/MTRPerControllerStorageTests.m | 23 +--- .../TestHelpers/MTRTestDeclarations.h | 60 +++++++++++ .../Matter.xcodeproj/project.pbxproj | 17 +-- 8 files changed, 313 insertions(+), 46 deletions(-) create mode 100644 src/darwin/Framework/CHIP/MTRDeviceControllerLocalTestStorage.h create mode 100644 src/darwin/Framework/CHIP/MTRDeviceControllerLocalTestStorage.m create mode 100644 src/darwin/Framework/CHIPTests/TestHelpers/MTRTestDeclarations.h diff --git a/src/darwin/Framework/CHIP/MTRBaseDevice.mm b/src/darwin/Framework/CHIP/MTRBaseDevice.mm index 00f65b25dc000b..2a981cdd860fff 100644 --- a/src/darwin/Framework/CHIP/MTRBaseDevice.mm +++ b/src/darwin/Framework/CHIP/MTRBaseDevice.mm @@ -1976,7 +1976,6 @@ - (void)failSubscribers:(dispatch_queue_t)queue completion:(void (^)(void))compl MTR_LOG_DEBUG("Causing failure in subscribers on purpose"); CauseReadClientFailure(self.deviceController, self.nodeID, queue, completion); } -#endif // The following method is for unit testing purpose only + (id)CHIPEncodeAndDecodeNSObject:(id)object @@ -2018,6 +2017,7 @@ + (id)CHIPEncodeAndDecodeNSObject:(id)object } return decodedData.GetDecodedObject(); } +#endif - (void)readEventsWithEndpointID:(NSNumber * _Nullable)endpointID clusterID:(NSNumber * _Nullable)clusterID diff --git a/src/darwin/Framework/CHIP/MTRDeviceController.mm b/src/darwin/Framework/CHIP/MTRDeviceController.mm index 64d70ce647cdb7..edd521845b2415 100644 --- a/src/darwin/Framework/CHIP/MTRDeviceController.mm +++ b/src/darwin/Framework/CHIP/MTRDeviceController.mm @@ -32,6 +32,7 @@ #import "MTRConversion.h" #import "MTRDeviceControllerDelegateBridge.h" #import "MTRDeviceControllerFactory_Internal.h" +#import "MTRDeviceControllerLocalTestStorage.h" #import "MTRDeviceControllerStartupParams.h" #import "MTRDeviceControllerStartupParams_Internal.h" #import "MTRDevice_Internal.h" @@ -173,12 +174,31 @@ - (instancetype)initWithFactory:(MTRDeviceControllerFactory *)factory return nil; } + id storageDelegateToUse = storageDelegate; +#if MTR_PER_CONTROLLER_STORAGE_ENABLED + if (MTRDeviceControllerLocalTestStorage.localTestStorageEnabled) { + storageDelegateToUse = [[MTRDeviceControllerLocalTestStorage alloc] initWithPassThroughStorage:storageDelegate]; + } +#endif // MTR_PER_CONTROLLER_STORAGE_ENABLED _controllerDataStore = [[MTRDeviceControllerDataStore alloc] initWithController:self - storageDelegate:storageDelegate + storageDelegate:storageDelegateToUse storageDelegateQueue:storageDelegateQueue]; if (_controllerDataStore == nil) { return nil; } + } else { +#if MTR_PER_CONTROLLER_STORAGE_ENABLED + if (MTRDeviceControllerLocalTestStorage.localTestStorageEnabled) { + dispatch_queue_t localTestStorageQueue = dispatch_queue_create("org.csa-iot.matter.framework.devicecontroller.localteststorage", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); + MTRDeviceControllerLocalTestStorage * localTestStorage = [[MTRDeviceControllerLocalTestStorage alloc] initWithPassThroughStorage:nil]; + _controllerDataStore = [[MTRDeviceControllerDataStore alloc] initWithController:self + storageDelegate:localTestStorage + storageDelegateQueue:localTestStorageQueue]; + if (_controllerDataStore == nil) { + return nil; + } + } +#endif // MTR_PER_CONTROLLER_STORAGE_ENABLED } // Ensure the otaProviderDelegate, if any, is valid. diff --git a/src/darwin/Framework/CHIP/MTRDeviceControllerLocalTestStorage.h b/src/darwin/Framework/CHIP/MTRDeviceControllerLocalTestStorage.h new file mode 100644 index 00000000000000..915834ecabd35c --- /dev/null +++ b/src/darwin/Framework/CHIP/MTRDeviceControllerLocalTestStorage.h @@ -0,0 +1,37 @@ +// +/** + * Copyright (c) 2023 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import +#import + +#if MTR_PER_CONTROLLER_STORAGE_ENABLED + +NS_ASSUME_NONNULL_BEGIN + +MTR_EXTERN @interface MTRDeviceControllerLocalTestStorage : NSObject + +// Setting this variable only affects subsequent MTRDeviceController initializations +@property (class, nonatomic, assign) BOOL localTestStorageEnabled; + +// This storage persists items to NSUserDefaults for MTRStorageSharingTypeNotShared data. Items with other sharing types will be droppped, or stored/fetched with the "passthrough storage" if one is specified. +- (instancetype)initWithPassThroughStorage:(id _Nullable)passThroughStorage; + +@end + +NS_ASSUME_NONNULL_END + +#endif // MTR_PER_CONTROLLER_STORAGE_ENABLED diff --git a/src/darwin/Framework/CHIP/MTRDeviceControllerLocalTestStorage.m b/src/darwin/Framework/CHIP/MTRDeviceControllerLocalTestStorage.m new file mode 100644 index 00000000000000..4d52e4bf18afb6 --- /dev/null +++ b/src/darwin/Framework/CHIP/MTRDeviceControllerLocalTestStorage.m @@ -0,0 +1,97 @@ +// +/** + * Copyright (c) 2023 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "MTRDeviceControllerLocalTestStorage.h" + +#if MTR_PER_CONTROLLER_STORAGE_ENABLED + +static NSString * const kLocalTestUserDefaultDomain = @"org.csa-iot.matter.darwintest"; +static NSString * const kLocalTestUserDefaultEnabledKey = @"enableTestStorage"; + +@implementation MTRDeviceControllerLocalTestStorage { + id _passThroughStorage; +} + ++ (BOOL)localTestStorageEnabled +{ + NSUserDefaults * defaults = [[NSUserDefaults alloc] initWithSuiteName:kLocalTestUserDefaultDomain]; + return [defaults boolForKey:kLocalTestUserDefaultEnabledKey]; +} + ++ (void)setLocalTestStorageEnabled:(BOOL)localTestStorageEnabled +{ + NSUserDefaults * defaults = [[NSUserDefaults alloc] initWithSuiteName:kLocalTestUserDefaultDomain]; + [defaults setBool:localTestStorageEnabled forKey:kLocalTestUserDefaultEnabledKey]; +} + +- (instancetype)initWithPassThroughStorage:(id)passThroughStorage +{ + if (self = [super init]) { + _passThroughStorage = passThroughStorage; + } + return self; +} + +- (nullable id)controller:(MTRDeviceController *)controller + valueForKey:(NSString *)key + securityLevel:(MTRStorageSecurityLevel)securityLevel + sharingType:(MTRStorageSharingType)sharingType +{ + if (sharingType == MTRStorageSharingTypeNotShared) { + NSUserDefaults * defaults = [[NSUserDefaults alloc] initWithSuiteName:kLocalTestUserDefaultDomain]; + NSData * storedData = [defaults dataForKey:key]; + NSError * error; + id value = [NSKeyedUnarchiver unarchivedObjectOfClasses:MTRDeviceControllerStorageClasses() fromData:storedData error:&error]; + return value; + } else { + return [_passThroughStorage controller:controller valueForKey:key securityLevel:securityLevel sharingType:sharingType]; + } +} + +- (BOOL)controller:(MTRDeviceController *)controller + storeValue:(id)value + forKey:(NSString *)key + securityLevel:(MTRStorageSecurityLevel)securityLevel + sharingType:(MTRStorageSharingType)sharingType +{ + if (sharingType == MTRStorageSharingTypeNotShared) { + NSError * error; + NSData * data = [NSKeyedArchiver archivedDataWithRootObject:value requiringSecureCoding:YES error:&error]; + NSUserDefaults * defaults = [[NSUserDefaults alloc] initWithSuiteName:kLocalTestUserDefaultDomain]; + [defaults setObject:data forKey:key]; + return YES; + } else { + return [_passThroughStorage controller:controller storeValue:value forKey:key securityLevel:securityLevel sharingType:sharingType]; + } +} + +- (BOOL)controller:(MTRDeviceController *)controller + removeValueForKey:(NSString *)key + securityLevel:(MTRStorageSecurityLevel)securityLevel + sharingType:(MTRStorageSharingType)sharingType +{ + if (sharingType == MTRStorageSharingTypeNotShared) { + NSUserDefaults * defaults = [[NSUserDefaults alloc] initWithSuiteName:kLocalTestUserDefaultDomain]; + [defaults removeObjectForKey:key]; + return YES; + } else { + return [_passThroughStorage controller:controller removeValueForKey:key securityLevel:securityLevel sharingType:sharingType]; + } +} +@end + +#endif // MTR_PER_CONTROLLER_STORAGE_ENABLED diff --git a/src/darwin/Framework/CHIPTests/MTRDeviceTests.m b/src/darwin/Framework/CHIPTests/MTRDeviceTests.m index 66bca12cc47bfd..e4628bd475b5ae 100644 --- a/src/darwin/Framework/CHIPTests/MTRDeviceTests.m +++ b/src/darwin/Framework/CHIPTests/MTRDeviceTests.m @@ -25,8 +25,10 @@ #import #import "MTRCommandPayloadExtensions_Internal.h" +#import "MTRDeviceControllerLocalTestStorage.h" #import "MTRDeviceTestDelegate.h" #import "MTRErrorTestUtils.h" +#import "MTRTestDeclarations.h" #import "MTRTestKeys.h" #import "MTRTestResetCommissioneeHelper.h" #import "MTRTestStorage.h" @@ -74,19 +76,6 @@ static void WaitForCommissionee(XCTestExpectation * expectation) return mConnectedDevice; } -#ifdef DEBUG -@interface MTRBaseDevice (Test) -- (void)failSubscribers:(dispatch_queue_t)queue completion:(void (^)(void))completion; - -// Test function for whitebox testing -+ (id)CHIPEncodeAndDecodeNSObject:(id)object; -@end - -@interface MTRDevice (Test) -- (void)unitTestInjectEventReport:(NSArray *> *)eventReport; -@end -#endif - @interface MTRDeviceTestDeviceControllerDelegate : NSObject @property (nonatomic, strong) XCTestExpectation * expectation; @end @@ -129,10 +118,19 @@ @interface MTRDeviceTests : XCTestCase @implementation MTRDeviceTests +#if MTR_PER_CONTROLLER_STORAGE_ENABLED +static BOOL slocalTestStorageEnabledBeforeUnitTest; +#endif // MTR_PER_CONTROLLER_STORAGE_ENABLED + + (void)setUp { XCTestExpectation * pairingExpectation = [[XCTestExpectation alloc] initWithDescription:@"Pairing Complete"]; +#if MTR_PER_CONTROLLER_STORAGE_ENABLED + slocalTestStorageEnabledBeforeUnitTest = MTRDeviceControllerLocalTestStorage.localTestStorageEnabled; + MTRDeviceControllerLocalTestStorage.localTestStorageEnabled = YES; +#endif // MTR_PER_CONTROLLER_STORAGE_ENABLED + __auto_type * factory = [MTRDeviceControllerFactory sharedInstance]; XCTAssertNotNil(factory); @@ -182,6 +180,14 @@ + (void)tearDown { ResetCommissionee(GetConnectedDevice(), dispatch_get_main_queue(), nil, kTimeoutInSeconds); +#if MTR_PER_CONTROLLER_STORAGE_ENABLED + // Restore testing setting to previous state, and remove all persisted attributes + MTRDeviceControllerLocalTestStorage.localTestStorageEnabled = slocalTestStorageEnabledBeforeUnitTest; + [sController.controllerDataStore clearAllStoredAttributes]; + NSArray * storedAttributesAfterClear = [sController.controllerDataStore getStoredAttributesForNodeID:@(kDeviceId)]; + XCTAssertEqual(storedAttributesAfterClear.count, 0); +#endif // MTR_PER_CONTROLLER_STORAGE_ENABLED + MTRDeviceController * controller = sController; XCTAssertNotNil(controller); [controller shutdown]; @@ -1236,7 +1242,7 @@ - (void)test015_FailedSubscribeWithQueueAcrossShutdown __auto_type * params = [[MTRSubscribeParams alloc] init]; params.resubscribeAutomatically = NO; params.replaceExistingSubscriptions = NO; // Not strictly needed, but checking that doing this does not - // affect this subscription erroring out correctly. + // affect this subscription erroring out correctly. [device subscribeWithQueue:queue minInterval:1 maxInterval:2 @@ -1344,6 +1350,11 @@ - (void)test016_FailedSubscribeWithCacheReadDuringFailure - (void)test017_TestMTRDeviceBasics { + // Ensure the test starts with clean slate, even with MTRDeviceControllerLocalTestStorage enabled + [sController.controllerDataStore clearAllStoredAttributes]; + NSArray * storedAttributesAfterClear = [sController.controllerDataStore getStoredAttributesForNodeID:@(kDeviceId)]; + XCTAssertEqual(storedAttributesAfterClear.count, 0); + __auto_type * device = [MTRDevice deviceWithNodeID:kDeviceId deviceController:sController]; dispatch_queue_t queue = dispatch_get_main_queue(); @@ -1526,6 +1537,7 @@ - (void)test017_TestMTRDeviceBasics // Resubscription test setup XCTestExpectation * subscriptionDroppedExpectation = [self expectationWithDescription:@"Subscription has dropped"]; + delegate.onNotReachable = ^() { [subscriptionDroppedExpectation fulfill]; }; @@ -1600,7 +1612,7 @@ - (void)test018_SubscriptionErrorWhenNotResubscribing MTRSubscribeParams * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(1) maxInterval:@(10)]; params.resubscribeAutomatically = NO; params.replaceExistingSubscriptions = NO; // Not strictly needed, but checking that doing this does not - // affect this subscription erroring out correctly. + // affect this subscription erroring out correctly. __block BOOL subscriptionEstablished = NO; [device subscribeToAttributesWithEndpointID:@1 clusterID:@6 @@ -2826,6 +2838,65 @@ - (void)test030_DeviceAndClusterProperties XCTAssertEqualObjects(cluster.endpointID, @(0)); } +#if MTR_PER_CONTROLLER_STORAGE_ENABLED +- (void)test031_MTRDeviceAttributeCacheLocalTestStorage +{ + dispatch_queue_t queue = dispatch_get_main_queue(); + + // First start with clean slate and + __auto_type * device = [MTRDevice deviceWithNodeID:@(kDeviceId) controller:sController]; + [sController removeDevice:device]; + [sController.controllerDataStore clearAllStoredAttributes]; + NSArray * storedAttributesAfterClear = [sController.controllerDataStore getStoredAttributesForNodeID:@(kDeviceId)]; + XCTAssertEqual(storedAttributesAfterClear.count, 0); + + // Now recreate device and get subscription primed + device = [MTRDevice deviceWithNodeID:@(kDeviceId) controller:sController]; + XCTestExpectation * gotReportsExpectation = [self expectationWithDescription:@"Attribute and Event reports have been received"]; + __auto_type * delegate = [[MTRDeviceTestDelegate alloc] init]; + __weak __auto_type weakDelegate = delegate; + delegate.onReportEnd = ^{ + [gotReportsExpectation fulfill]; + __strong __auto_type strongDelegate = weakDelegate; + strongDelegate.onReportEnd = nil; + }; + [device setDelegate:delegate queue:queue]; + + [self waitForExpectations:@[ gotReportsExpectation ] timeout:60]; + + NSUInteger attributesReportedWithFirstSubscription = [device unitTestAttributesReportedSinceLastCheck]; + + NSArray * dataStoreValuesAfterFirstSubscription = [sController.controllerDataStore getStoredAttributesForNodeID:@(kDeviceId)]; + XCTAssertTrue(dataStoreValuesAfterFirstSubscription.count > 0); + + // Now remove device, resubscribe, and see that it succeeds + [sController removeDevice:device]; + device = [MTRDevice deviceWithNodeID:@(kDeviceId) controller:sController]; + + XCTestExpectation * resubGotReportsExpectation = [self expectationWithDescription:@"Attribute and Event reports have been received for resubscription"]; + delegate.onReportEnd = ^{ + [resubGotReportsExpectation fulfill]; + __strong __auto_type strongDelegate = weakDelegate; + strongDelegate.onReportEnd = nil; + }; + [device setDelegate:delegate queue:queue]; + + [self waitForExpectations:@[ resubGotReportsExpectation ] timeout:60]; + + NSUInteger attributesReportedWithSecondSubscription = [device unitTestAttributesReportedSinceLastCheck]; + + XCTAssertTrue(attributesReportedWithSecondSubscription < attributesReportedWithFirstSubscription); + + // 1) MTRDevice actually gets some attributes reported more than once + // 2) Some attributes do change on resubscribe + // * With all-clusts-app as of 2024-02-10, out of 1287 persisted attributes, still 450 attributes were reported with filter + // And so conservatively, assert that data version filters save at least 300 entries. + NSArray * dataStoreValuesAfterSecondSubscription = [sController.controllerDataStore getStoredAttributesForNodeID:@(kDeviceId)]; + NSUInteger storedAttributeCountDifferenceFromMTRDeviceReport = dataStoreValuesAfterSecondSubscription.count - attributesReportedWithSecondSubscription; + XCTAssertTrue(storedAttributeCountDifferenceFromMTRDeviceReport > 300); +} +#endif // MTR_PER_CONTROLLER_STORAGE_ENABLED + @end @interface MTRDeviceEncoderTests : XCTestCase diff --git a/src/darwin/Framework/CHIPTests/MTRPerControllerStorageTests.m b/src/darwin/Framework/CHIPTests/MTRPerControllerStorageTests.m index 661dbadb9ac445..38795bcc8cef87 100644 --- a/src/darwin/Framework/CHIPTests/MTRPerControllerStorageTests.m +++ b/src/darwin/Framework/CHIPTests/MTRPerControllerStorageTests.m @@ -22,6 +22,7 @@ #import "MTRDeviceTestDelegate.h" #import "MTRErrorTestUtils.h" #import "MTRFabricInfoChecker.h" +#import "MTRTestDeclarations.h" #import "MTRTestKeys.h" #import "MTRTestPerControllerStorage.h" #import "MTRTestResetCommissioneeHelper.h" @@ -33,28 +34,6 @@ static NSString * kOnboardingPayload = @"MT:-24J0AFN00KA0648G00"; static const uint16_t kTestVendorId = 0xFFF1u; -#ifdef DEBUG -// MTRDeviceControllerDataStore.h includes C++ header, and so we need to declare the methods separately -@protocol MTRDeviceControllerDataStoreAttributeStoreMethods -- (nullable NSArray *)getStoredAttributesForNodeID:(NSNumber *)nodeID; -- (void)storeAttributeValues:(NSArray *)dataValues forNodeID:(NSNumber *)nodeID; -- (void)clearStoredAttributesForNodeID:(NSNumber *)nodeID; -- (void)clearAllStoredAttributes; -@end - -// Declare internal methods for testing -@interface MTRDeviceController (Test) -+ (void)forceLocalhostAdvertisingOnly; -- (void)removeDevice:(MTRDevice *)device; -@property (nonatomic, readonly, nullable) id controllerDataStore; -@end - -@interface MTRDevice (Test) -- (BOOL)_attributeDataValue:(NSDictionary *)one isEqualToDataValue:(NSDictionary *)theOther; -- (NSUInteger)unitTestAttributesReportedSinceLastCheck; -@end -#endif // DEBUG - @interface MTRPerControllerStorageTestsControllerDelegate : NSObject @property (nonatomic, strong) XCTestExpectation * expectation; @property (nonatomic, strong) NSNumber * deviceID; diff --git a/src/darwin/Framework/CHIPTests/TestHelpers/MTRTestDeclarations.h b/src/darwin/Framework/CHIPTests/TestHelpers/MTRTestDeclarations.h new file mode 100644 index 00000000000000..5b77d0ec06aad7 --- /dev/null +++ b/src/darwin/Framework/CHIPTests/TestHelpers/MTRTestDeclarations.h @@ -0,0 +1,60 @@ +// +/** + * Copyright (c) 2023 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import +#import + +NS_ASSUME_NONNULL_BEGIN + +#pragma mark - Declarations for internal methods + +// MTRDeviceControllerDataStore.h includes C++ header, and so we need to declare the methods separately +@protocol MTRDeviceControllerDataStoreAttributeStoreMethods +- (nullable NSArray *)getStoredAttributesForNodeID:(NSNumber *)nodeID; +- (void)storeAttributeValues:(NSArray *)dataValues forNodeID:(NSNumber *)nodeID; +- (void)clearStoredAttributesForNodeID:(NSNumber *)nodeID; +- (void)clearAllStoredAttributes; +@end + +// Declare internal methods for testing +@interface MTRDeviceController (Test) ++ (void)forceLocalhostAdvertisingOnly; +- (void)removeDevice:(MTRDevice *)device; +@property (nonatomic, readonly, nullable) id controllerDataStore; +@end + +@interface MTRDevice (Test) +- (BOOL)_attributeDataValue:(NSDictionary *)one isEqualToDataValue:(NSDictionary *)theOther; +@end + +#pragma mark - Declarations for items compiled only for DEBUG configuration + +#ifdef DEBUG +@interface MTRBaseDevice (TestDebug) +- (void)failSubscribers:(dispatch_queue_t)queue completion:(void (^)(void))completion; + +// Test function for whitebox testing ++ (id)CHIPEncodeAndDecodeNSObject:(id)object; +@end + +@interface MTRDevice (TestDebug) +- (void)unitTestInjectEventReport:(NSArray *> *)eventReport; +- (NSUInteger)unitTestAttributesReportedSinceLastCheck; +@end +#endif + +NS_ASSUME_NONNULL_END diff --git a/src/darwin/Framework/Matter.xcodeproj/project.pbxproj b/src/darwin/Framework/Matter.xcodeproj/project.pbxproj index 5e227bc7a8d2b2..a49b33fa3a1ea4 100644 --- a/src/darwin/Framework/Matter.xcodeproj/project.pbxproj +++ b/src/darwin/Framework/Matter.xcodeproj/project.pbxproj @@ -240,6 +240,8 @@ 5ACDDD7D27CD16D200EFD68A /* MTRClusterStateCacheContainer.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5ACDDD7C27CD16D200EFD68A /* MTRClusterStateCacheContainer.mm */; }; 5ACDDD7E27CD3F3A00EFD68A /* MTRClusterStateCacheContainer_Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 5ACDDD7B27CD14AF00EFD68A /* MTRClusterStateCacheContainer_Internal.h */; }; 5AE6D4E427A99041001F2493 /* MTRDeviceTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 5AE6D4E327A99041001F2493 /* MTRDeviceTests.m */; }; + 75139A6F2B7FE5E900E3A919 /* MTRDeviceControllerLocalTestStorage.m in Sources */ = {isa = PBXBuildFile; fileRef = 75139A6E2B7FE5E900E3A919 /* MTRDeviceControllerLocalTestStorage.m */; }; + 75139A702B7FE68C00E3A919 /* MTRDeviceControllerLocalTestStorage.h in Headers */ = {isa = PBXBuildFile; fileRef = 75139A6D2B7FE5D600E3A919 /* MTRDeviceControllerLocalTestStorage.h */; settings = {ATTRIBUTES = (Private, ); }; }; 7534F12828BFF20300390851 /* MTRDeviceAttestationDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = 7534F12628BFF20300390851 /* MTRDeviceAttestationDelegate.mm */; }; 7534F12928BFF20300390851 /* MTRDeviceAttestationDelegate_Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 7534F12728BFF20300390851 /* MTRDeviceAttestationDelegate_Internal.h */; }; 754F3DF427FBB94B00E60580 /* MTREventTLVValueDecoder_Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 754F3DF327FBB94B00E60580 /* MTREventTLVValueDecoder_Internal.h */; }; @@ -633,6 +635,9 @@ 5ACDDD7B27CD14AF00EFD68A /* MTRClusterStateCacheContainer_Internal.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MTRClusterStateCacheContainer_Internal.h; sourceTree = ""; }; 5ACDDD7C27CD16D200EFD68A /* MTRClusterStateCacheContainer.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = MTRClusterStateCacheContainer.mm; sourceTree = ""; }; 5AE6D4E327A99041001F2493 /* MTRDeviceTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MTRDeviceTests.m; sourceTree = ""; }; + 75139A6C2B7FE19100E3A919 /* MTRTestDeclarations.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MTRTestDeclarations.h; sourceTree = ""; }; + 75139A6D2B7FE5D600E3A919 /* MTRDeviceControllerLocalTestStorage.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MTRDeviceControllerLocalTestStorage.h; sourceTree = ""; }; + 75139A6E2B7FE5E900E3A919 /* MTRDeviceControllerLocalTestStorage.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MTRDeviceControllerLocalTestStorage.m; sourceTree = ""; }; 7534F12628BFF20300390851 /* MTRDeviceAttestationDelegate.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MTRDeviceAttestationDelegate.mm; sourceTree = ""; }; 7534F12728BFF20300390851 /* MTRDeviceAttestationDelegate_Internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MTRDeviceAttestationDelegate_Internal.h; sourceTree = ""; }; 754F3DF327FBB94B00E60580 /* MTREventTLVValueDecoder_Internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MTREventTLVValueDecoder_Internal.h; sourceTree = ""; }; @@ -792,9 +797,6 @@ 039145E02993102B00257B3E /* main.mm */, 03F430A52994100000166449 /* controller */, 039547092992DB02006D42A8 /* editline */, - 039546AD2991E193006D42A8 /* log */, - 039546B12991E194006D42A8 /* system */, - 039546A72991E185006D42A8 /* delay */, 039546A22991E132006D42A8 /* interaction_model */, 039546972991DFC4006D42A8 /* lib_json */, 039546872991C400006D42A8 /* chip-tool */, @@ -815,7 +817,6 @@ 03FB93DA2A46200A0048CB35 /* discover */, 037C3D7C2991BD4F00B7EEE2 /* pairing */, 037C3D852991BD4F00B7EEE2 /* clusters */, - 037C3D8B2991BD4F00B7EEE2 /* tests */, 037C3D8D2991BD4F00B7EEE2 /* provider */, 037C3D932991BD4F00B7EEE2 /* payload */, 037C3D972991BD4F00B7EEE2 /* storage */, @@ -1105,6 +1106,7 @@ 51C984602A61CE2A00B0AD9A /* MTRFabricInfoChecker.m */, 75B0D01C2B71B46F002074DD /* MTRDeviceTestDelegate.h */, 75B0D01D2B71B47F002074DD /* MTRDeviceTestDelegate.m */, + 75139A6C2B7FE19100E3A919 /* MTRTestDeclarations.h */, ); path = TestHelpers; sourceTree = ""; @@ -1238,6 +1240,8 @@ 5136661228067D550025EDAE /* MTRDeviceControllerFactory.h */, 5136661128067D540025EDAE /* MTRDeviceControllerFactory_Internal.h */, 5136661028067D540025EDAE /* MTRDeviceControllerFactory.mm */, + 75139A6D2B7FE5D600E3A919 /* MTRDeviceControllerLocalTestStorage.h */, + 75139A6E2B7FE5E900E3A919 /* MTRDeviceControllerLocalTestStorage.m */, 5A6FEC8D27B5624E00F25F42 /* MTRDeviceControllerOverXPC.h */, 5A830D6B27CFCF590053B85D /* MTRDeviceControllerOverXPC_Internal.h */, 5A6FEC8F27B563D900F25F42 /* MTRDeviceControllerOverXPC.mm */, @@ -1555,6 +1559,7 @@ 1EC4CE6425CC276600D7304F /* MTRBaseClusters.h in Headers */, 3D843712294977000070D20A /* MTRCallbackBridgeBase.h in Headers */, 3DECCB742934C21B00585AEC /* MTRDefines.h in Headers */, + 75139A702B7FE68C00E3A919 /* MTRDeviceControllerLocalTestStorage.h in Headers */, 2C5EEEF6268A85C400CAE3D3 /* MTRDeviceConnectionBridge.h in Headers */, 2C8C8FC0253E0C2100797F05 /* MTRPersistentStorageDelegateBridge.h in Headers */, 51FE72352ACDB40000437032 /* MTRCommandPayloads_Internal.h in Headers */, @@ -1753,7 +1758,6 @@ B45373EF2A9FEBFE00807602 /* ops-raw-skt.c in Sources */, 516411332B6BF77700E67C05 /* MTRServerAccessControl.mm in Sources */, 037C3DD52991C2E200B7EEE2 /* CHIPCommandBridge.mm in Sources */, - 039546BC2991E1CB006D42A8 /* LogCommands.cpp in Sources */, 516411312B6BF70300E67C05 /* DataModelHandler.cpp in Sources */, B45373E12A9FEB7F00807602 /* ops-h1.c in Sources */, B45373EB2A9FEBDB00807602 /* ops-listen.c in Sources */, @@ -1766,13 +1770,11 @@ B45373E62A9FEBA400807602 /* header.c in Sources */, B45374002A9FEC4F00807602 /* unix-init.c in Sources */, B45373DF2A9FEB6F00807602 /* system.c in Sources */, - 039546BD2991E1CB006D42A8 /* SystemCommands.cpp in Sources */, B45373FC2A9FEC4F00807602 /* unix-caps.c in Sources */, B4E262162AA0CF1C00DBA5BC /* RemoteDataModelLogger.mm in Sources */, B45373ED2A9FEBEC00807602 /* ops-pipe.c in Sources */, B45373C02A9FEA9100807602 /* output.c in Sources */, 0395470F2992DB37006D42A8 /* complete.c in Sources */, - 039546BE2991E1CB006D42A8 /* DelayCommands.cpp in Sources */, B4E2621B2AA0D02000DBA5BC /* SleepCommand.mm in Sources */, B45373FF2A9FEC4F00807602 /* unix-misc.c in Sources */, B45373D92A9FEB3800807602 /* poll.c in Sources */, @@ -1840,6 +1842,7 @@ 75B765C32A1D82D30014719B /* MTRAttributeSpecifiedCheck.mm in Sources */, AF5F90FF2878D351005503FA /* MTROTAProviderDelegateBridge.mm in Sources */, 516415FF2B6B132200D5CE11 /* DataModelHandler.cpp in Sources */, + 75139A6F2B7FE5E900E3A919 /* MTRDeviceControllerLocalTestStorage.m in Sources */, 51E95DFC2A78443C00A434F0 /* MTRSessionResumptionStorageBridge.mm in Sources */, 514C79ED2B62ADCD00DD6D7B /* ember-compatibility-functions.cpp in Sources */, 7534F12828BFF20300390851 /* MTRDeviceAttestationDelegate.mm in Sources */, From acedec197c61d8b2b2bbe55fac16faf8a73b190e Mon Sep 17 00:00:00 2001 From: Hasty Granbery Date: Sun, 18 Feb 2024 04:45:59 +0900 Subject: [PATCH 25/33] Power Topology: add test scripts (#32114) * Initial XML for Power Topology cluster * Regen * Restyled really wants newlines at the end of every JSON file * Rename LeafTopology to TreeTopology * [Feature] Power Topology server & all-clusters-app stub * Make endpointId a constructor arg for PowerTopologyDelegate * Change PowerTopologyDelegate to not return std::vectors * Remove unneeded entries in attributeAccessInterfaceAttributes for Power Topology cluster * Typo in python/chip/clusters/__init__.py * Format zcl.json * Add DynamicPowerFlow feature to PowerTopology stub * Add Power Topology to client * Set CI PICS values * Python test script for Power Topology * Linted python script * Add Power Topology python script test * Add PWRTL_1_1 to ciTests.json * Restyled * Regen * Format PICS.yaml --- .github/workflows/tests.yaml | 1 + src/app/tests/suites/certification/PICS.yaml | 33 +++++ .../certification/Test_TC_PWRTL_1_1.yaml | 119 ++++++++++++++++++ .../tests/suites/certification/ci-pics-values | 12 ++ src/app/tests/suites/ciTests.json | 1 + src/app/tests/suites/manualTests.json | 2 + src/app/zap_cluster_list.json | 2 +- src/python_testing/TC_PWRTL_2_1.py | 69 ++++++++++ 8 files changed, 238 insertions(+), 1 deletion(-) create mode 100644 src/app/tests/suites/certification/Test_TC_PWRTL_1_1.yaml create mode 100644 src/python_testing/TC_PWRTL_2_1.py diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index 05d2670edd665e..f083cd70bccd7c 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -502,6 +502,7 @@ jobs: scripts/run_in_python_env.sh out/venv './scripts/tests/run_python_test.py --app out/linux-x64-all-clusters-ipv6only-no-ble-no-wifi-tsan-clang-test/chip-all-clusters-app --factoryreset --app-args "--discriminator 1234 --KVS kvs1 --trace-to json:out/trace_data/app-{SCRIPT_BASE_NAME}.json" --script "src/python_testing/TC_IDM_1_2.py" --script-args "--storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --trace-to json:out/trace_data/test-{SCRIPT_BASE_NAME}.json --trace-to perfetto:out/trace_data/test-{SCRIPT_BASE_NAME}.perfetto"' scripts/run_in_python_env.sh out/venv './scripts/tests/run_python_test.py --app out/linux-x64-all-clusters-ipv6only-no-ble-no-wifi-tsan-clang-test/chip-all-clusters-app --factoryreset --app-args "--discriminator 1234 --KVS kvs1 --trace-to json:out/trace_data/app-{SCRIPT_BASE_NAME}.json --enable-key 000102030405060708090a0b0c0d0e0f" --script "src/python_testing/TC_IDM_1_4.py" --script-args "--hex-arg PIXIT.DGGEN.TEST_EVENT_TRIGGER_KEY:000102030405060708090a0b0c0d0e0f --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --trace-to json:out/trace_data/test-{SCRIPT_BASE_NAME}.json --trace-to perfetto:out/trace_data/test-{SCRIPT_BASE_NAME}.perfetto"' scripts/run_in_python_env.sh out/venv './scripts/tests/run_python_test.py --app out/linux-x64-all-clusters-ipv6only-no-ble-no-wifi-tsan-clang-test/chip-all-clusters-app --factoryreset --app-args "--discriminator 1234 --KVS kvs1 --trace-to json:out/trace_data/app-{SCRIPT_BASE_NAME}.json" --script "src/python_testing/TC_IDM_4_2.py" --script-args "--storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --trace-to json:out/trace_data/test-{SCRIPT_BASE_NAME}.json --trace-to perfetto:out/trace_data/test-{SCRIPT_BASE_NAME}.perfetto"' + scripts/run_in_python_env.sh out/venv './scripts/tests/run_python_test.py --app out/linux-x64-all-clusters-ipv6only-no-ble-no-wifi-tsan-clang-test/chip-all-clusters-app --factoryreset --app-args "--discriminator 1234 --KVS kvs1 --trace-to json:out/trace_data/app-{SCRIPT_BASE_NAME}.json" --script "src/python_testing/TC_PWRTL_2_1.py" --script-args "--storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --trace-to json:out/trace_data/test-{SCRIPT_BASE_NAME}.json --trace-to perfetto:out/trace_data/test-{SCRIPT_BASE_NAME}.perfetto"' scripts/run_in_python_env.sh out/venv './scripts/tests/run_python_test.py --app out/linux-x64-all-clusters-ipv6only-no-ble-no-wifi-tsan-clang-test/chip-all-clusters-app --factoryreset --app-args "--discriminator 1234 --KVS kvs1 --trace-to json:out/trace_data/app-{SCRIPT_BASE_NAME}.json" --script "src/python_testing/TC_RR_1_1.py" --script-args "--storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --trace-to json:out/trace_data/test-{SCRIPT_BASE_NAME}.json --trace-to perfetto:out/trace_data/test-{SCRIPT_BASE_NAME}.perfetto"' scripts/run_in_python_env.sh out/venv './scripts/tests/run_python_test.py --app out/linux-x64-all-clusters-ipv6only-no-ble-no-wifi-tsan-clang-test/chip-all-clusters-app --factoryreset --app-args "--discriminator 1234 --KVS kvs1 --trace-to json:out/trace_data/app-{SCRIPT_BASE_NAME}.json" --script "src/python_testing/TC_RVCCLEANM_1_2.py" --script-args "--int-arg PIXIT_ENDPOINT:1 --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --trace-to json:out/trace_data/test-{SCRIPT_BASE_NAME}.json --trace-to perfetto:out/trace_data/test-{SCRIPT_BASE_NAME}.perfetto"' scripts/run_in_python_env.sh out/venv './scripts/tests/run_python_test.py --app out/linux-x64-all-clusters-ipv6only-no-ble-no-wifi-tsan-clang-test/chip-all-clusters-app --factoryreset --app-args "--discriminator 1234 --KVS kvs1 --trace-to json:out/trace_data/app-{SCRIPT_BASE_NAME}.json" --script "src/python_testing/TC_RVCRUNM_1_2.py" --script-args "--int-arg PIXIT_ENDPOINT:1 --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --trace-to json:out/trace_data/test-{SCRIPT_BASE_NAME}.json --trace-to perfetto:out/trace_data/test-{SCRIPT_BASE_NAME}.perfetto"' diff --git a/src/app/tests/suites/certification/PICS.yaml b/src/app/tests/suites/certification/PICS.yaml index 068db7f0dfe525..49554c37f4e3b6 100644 --- a/src/app/tests/suites/certification/PICS.yaml +++ b/src/app/tests/suites/certification/PICS.yaml @@ -10160,3 +10160,36 @@ PICS: - label: "Can the mode change be manually controlled?" id: EEVSEM.S.M.CAN_MANUALLY_CONTROLLED + + # + # Power Topology Cluster + # + - label: "Does the device implement the Power Topology Cluster as a server?" + id: PWRTL.S + + # Features + + - label: + "Does the associated endpoint provide or consume power for the entire + node?" + id: PWRTL.S.F00 + + - label: + "Does the associated endpoint provide or consume power for itself and + its child endpoints?" + id: PWRTL.S.F01 + + - label: + "Does the associated endpoint provide or consume power for a provided + set of endpoints?" + id: PWRTL.S.F02 + + - label: "Can the provided set of endpoints change?" + id: PWRTL.S.F03 + + #Server attributes + - label: "Does the device implement the AvailableEndpoints attribute?" + id: PWRTL.S.A0000 + + - label: "Does the device implement the ActiveEndpoints attribute?" + id: PWRTL.S.A0001 diff --git a/src/app/tests/suites/certification/Test_TC_PWRTL_1_1.yaml b/src/app/tests/suites/certification/Test_TC_PWRTL_1_1.yaml new file mode 100644 index 00000000000000..cfe6fd860be240 --- /dev/null +++ b/src/app/tests/suites/certification/Test_TC_PWRTL_1_1.yaml @@ -0,0 +1,119 @@ +# Copyright (c) 2021 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# Auto-generated scripts for harness use only, please review before automation. The endpoints and cluster names are currently set to default + +name: 44.1.1. [TC-PWRTL-1.1] Global Attributes with DUT as Server + +PICS: + - PWRTL.S + +config: + nodeId: 0x12344321 + cluster: "Power Topology" + endpoint: 1 + +tests: + - label: "Step 1: Wait for the commissioned device to be retrieved" + cluster: "DelayCommands" + command: "WaitForCommissionee" + arguments: + values: + - name: "nodeId" + value: nodeId + + - label: "Step 2: TH reads the ClusterRevision from DUT" + command: "readAttribute" + attribute: "ClusterRevision" + response: + value: 1 + constraints: + type: int16u + + - label: + "Step 3a: Given PWRTL.S.F00(Node) ensure featuremap has the correct + bit set" + PICS: PWRTL.S.F00 + command: "readAttribute" + attribute: "FeatureMap" + response: + constraints: + type: bitmap32 + hasMasksSet: [0x1] + hasMasksClear: [0x2, 0x4, 0x8] + + - label: + "Step 3b: Given PWRTL.S.F01(Leaf) ensure featuremap has the correct + bit set" + PICS: PWRTL.S.F01 + command: "readAttribute" + attribute: "FeatureMap" + response: + constraints: + type: bitmap32 + hasMasksSet: [0x2] + hasMasksClear: [0x1, 0x4, 0x8] + + - label: + "Step 3c: Given PWRTL.S.F02(Set) ensure featuremap has the correct bit + set" + PICS: PWRTL.S.F02 + command: "readAttribute" + attribute: "FeatureMap" + response: + constraints: + type: bitmap32 + hasMasksSet: [0x4] + hasMasksClear: [0x1, 0x2] + + - label: + "Step 3d: Given PWRTL.S.F03(Dynamic Power Flow) ensure featuremap has + the correct bit set" + PICS: PWRTL.S.F03 + command: "readAttribute" + attribute: "FeatureMap" + response: + constraints: + type: bitmap32 + hasMasksSet: [0x4, 0x8] + + - label: "Step 4a: TH reads AttributeList from DUT" + PICS: "!PICS_SF_SET && !PICS_SF_DYPF" + command: "readAttribute" + attribute: "AttributeList" + response: + constraints: + type: list + contains: [] + + - label: + "Step 4b: TH reads feature dependent attribute(AvailableEndpoints) + AttributeList from DUT" + PICS: "PICS_SF_SET && !PICS_SF_DYPF" + command: "readAttribute" + attribute: "AttributeList" + response: + constraints: + type: list + contains: [0] + + - label: + "Step 4c: TH reads feature dependent attribute(ActiveEndpoints) + AttributeList from DUT" + PICS: "PICS_SF_SET && PICS_SF_DYPF" + command: "readAttribute" + attribute: "AttributeList" + response: + constraints: + type: list + contains: [0, 1] diff --git a/src/app/tests/suites/certification/ci-pics-values b/src/app/tests/suites/certification/ci-pics-values index c710f846f0a13a..f200ad302931ff 100644 --- a/src/app/tests/suites/certification/ci-pics-values +++ b/src/app/tests/suites/certification/ci-pics-values @@ -2939,3 +2939,15 @@ DEMM.S.C01.Tx=1 #Manual controllable DEMM.S.M.CAN_TEST_MODE_FAILURE=1 DEMM.S.M.CAN_MANUALLY_CONTROLLED=1 + +#Power Topology Cluster +# Server +PWRTL.S=1 +PWRTL.S.A0000=1 +PWRTL.S.A0001=1 + +#Features +PWRTL.S.F00=0 +PWRTL.S.F01=0 +PWRTL.S.F02=1 +PWRTL.S.F03=1 \ No newline at end of file diff --git a/src/app/tests/suites/ciTests.json b/src/app/tests/suites/ciTests.json index ee6b5436451a6f..26efd799ad7efd 100644 --- a/src/app/tests/suites/ciTests.json +++ b/src/app/tests/suites/ciTests.json @@ -191,6 +191,7 @@ "Test_TC_OO_2_4" ], "PowerSource": ["Test_TC_PS_1_1", "Test_TC_PS_2_1"], + "PowerTopology": ["Test_TC_PWRTL_1_1"], "PressureMeasurement": [ "Test_TC_PRS_1_1", "Test_TC_PRS_2_1", diff --git a/src/app/tests/suites/manualTests.json b/src/app/tests/suites/manualTests.json index 774b3d8dce35f3..d199a682492150 100644 --- a/src/app/tests/suites/manualTests.json +++ b/src/app/tests/suites/manualTests.json @@ -311,6 +311,7 @@ "AccessControlEnforcement": [], "OvenMode": ["Test_TC_OTCCM_1_1", "Test_TC_OTCCM_1_2"], "EnergyEVSE": ["Test_TC_EEVSE_1_1", "Test_TC_EEVSE_2_1"], + "PowerTopology": ["Test_TC_PWRTL_1_1"], "collection": [ "DeviceDiscovery", "Groups", @@ -338,6 +339,7 @@ "ModeSelect", "OTASoftwareUpdate", "PowerSourceConfiguration", + "PowerTopology", "PressureMeasurement", "SecureChannel", "SoftwareDiagnostics", diff --git a/src/app/zap_cluster_list.json b/src/app/zap_cluster_list.json index b3993634639869..56adf0a1126f95 100644 --- a/src/app/zap_cluster_list.json +++ b/src/app/zap_cluster_list.json @@ -68,7 +68,6 @@ "MESSAGES_CLUSTER": [], "MODE_SELECT_CLUSTER": [], "NETWORK_COMMISSIONING_CLUSTER": [], - "POWER_TOPOLOGY_CLUSTER": [], "SAMPLE_MEI_CLUSTER": [], "NITROGEN_DIOXIDE_CONCENTRATION_MEASUREMENT_CLUSTER": [], "OCCUPANCY_SENSING_CLUSTER": ["occupancy-sensor-server"], @@ -91,6 +90,7 @@ "POWER_PROFILE_CLUSTER": [], "POWER_SOURCE_CLUSTER": [], "POWER_SOURCE_CONFIGURATION_CLUSTER": [], + "POWER_TOPOLOGY_CLUSTER": [], "PRESSURE_MEASUREMENT_CLUSTER": [], "PROXY_CONFIGURATION_CLUSTER": [], "PROXY_DISCOVERY_CLUSTER": [], diff --git a/src/python_testing/TC_PWRTL_2_1.py b/src/python_testing/TC_PWRTL_2_1.py new file mode 100644 index 00000000000000..bd839cd5f072f4 --- /dev/null +++ b/src/python_testing/TC_PWRTL_2_1.py @@ -0,0 +1,69 @@ +# +# Copyright (c) 2024 Project CHIP Authors +# All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +import logging + +import chip.clusters as Clusters +from chip.clusters.Types import NullValue +from matter_testing_support import MatterBaseTest, async_test_body, default_matter_test_main +from mobly import asserts + + +class TC_PWRTL_2_1(MatterBaseTest): + + def pics_TC_PWRTL_2_1(self) -> list[str]: + return ["PWRTL.S"] + + @async_test_body + async def test_TC_PWRTL_2_1(self): + + attributes = Clusters.PowerTopology.Attributes + + endpoint = self.user_params.get("endpoint", 1) + + self.print_step(1, "Commissioning, already done") + + if not self.check_pics("PWRTL.S.A0000"): + logging.info("Test skipped because PICS PWRTL.S.A0000 is not set") + return + + self.print_step(2, "Read AvailableAttributes attribute") + available_endpoints = await self.read_single_attribute_check_success(endpoint=endpoint, cluster=Clusters.Objects.PowerTopology, attribute=attributes.AvailableEndpoints) + + if available_endpoints == NullValue: + logging.info("AvailableEndpoints is null") + else: + logging.info("AvailableEndpoints: %s" % (available_endpoints)) + + asserts.assert_less_equal(len(available_endpoints), 21, + "AvailableEndpoints length %d must be less than 21!" % len(available_endpoints)) + + if not self.check_pics("PWRTL.S.A0001"): + logging.info("Test skipped because PICS PWRTL.S.A0001 is not set") + return + + self.print_step(3, "Read ActiveEndpoints attribute") + active_endpoints = await self.read_single_attribute_check_success(endpoint=endpoint, cluster=Clusters.Objects.PowerTopology, attribute=attributes.ActiveEndpoints) + logging.info("ActiveEndpoints: %s" % (active_endpoints)) + + if available_endpoints == NullValue: + asserts.assert_true(active_endpoints == NullValue, + "ActiveEndpoints should be null when AvailableEndpoints is null: %s" % active_endpoints) + + +if __name__ == "__main__": + default_matter_test_main() From dbc6ed396be4b99faa5ea064e13e33c80e1ded4b Mon Sep 17 00:00:00 2001 From: yunhanw-google Date: Sun, 18 Feb 2024 02:10:50 -0800 Subject: [PATCH 26/33] [Android]Pass write response status from jni to application (#32164) --- .../clusterclient/BasicClientFragment.kt | 5 +- .../OtaProviderClientFragment.kt | 9 +- .../clusterclient/WildcardFragment.kt | 5 +- .../pairing/PairOnNetworkLongImReadCommand.kt | 9 +- .../PairOnNetworkLongImWriteCommand.kt | 8 +- kotlin-detect-config.yaml | 4 +- .../generators/java/ChipClusters_java.jinja | 12 ++- .../several_clusters/java/ChipClusters.java | 12 ++- src/controller/java/AndroidCallbacks.cpp | 22 +++-- src/controller/java/BUILD.gn | 2 + .../chip/devicecontroller/ChipClusters.java | 12 ++- .../devicecontroller/StatusException.java | 34 ++++++++ .../WriteAttributesCallback.java | 4 +- .../WriteAttributesCallbackJni.java | 12 ++- .../chip/devicecontroller/model/Status.java | 80 +++++++++++++++-- .../matter/controller/MatterControllerImpl.kt | 8 +- .../controller/WriteAttributesCallback.kt | 4 +- .../controller/WriteAttributesCallbackJni.kt | 12 ++- .../src/matter/controller/model/States.kt | 2 - .../src/matter/controller/model/Status.kt | 86 +++++++++++++++++++ .../python/chip/interaction_model/__init__.py | 1 + .../interaction_model/StatusCodeList.h | 5 +- 22 files changed, 296 insertions(+), 52 deletions(-) create mode 100644 src/controller/java/src/chip/devicecontroller/StatusException.java create mode 100644 src/controller/java/src/matter/controller/model/Status.kt diff --git a/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/clusterclient/BasicClientFragment.kt b/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/clusterclient/BasicClientFragment.kt index 0662ec08dc2146..f38cacbd259073 100644 --- a/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/clusterclient/BasicClientFragment.kt +++ b/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/clusterclient/BasicClientFragment.kt @@ -17,6 +17,7 @@ import chip.devicecontroller.model.AttributeWriteRequest import chip.devicecontroller.model.ChipAttributePath import chip.devicecontroller.model.ChipEventPath import chip.devicecontroller.model.NodeState +import chip.devicecontroller.model.Status import com.google.chip.chiptool.ChipClient import com.google.chip.chiptool.GenericChipDeviceListener import com.google.chip.chiptool.R @@ -191,8 +192,8 @@ class BasicClientFragment : Fragment() { Log.e(TAG, "Write ${attribute.name} failure", ex) } - override fun onResponse(attributePath: ChipAttributePath?) { - showMessage("Write ${attribute.name} success") + override fun onResponse(attributePath: ChipAttributePath, status: Status) { + showMessage("Write ${attribute.name} response: $status") } }, devicePtr, diff --git a/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/clusterclient/OtaProviderClientFragment.kt b/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/clusterclient/OtaProviderClientFragment.kt index 87735856fa4844..c27159193ed2dc 100644 --- a/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/clusterclient/OtaProviderClientFragment.kt +++ b/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/clusterclient/OtaProviderClientFragment.kt @@ -32,6 +32,7 @@ import chip.devicecontroller.model.AttributeWriteRequest import chip.devicecontroller.model.ChipAttributePath import chip.devicecontroller.model.ChipEventPath import chip.devicecontroller.model.NodeState +import chip.devicecontroller.model.Status import com.google.chip.chiptool.ChipClient import com.google.chip.chiptool.GenericChipDeviceListener import com.google.chip.chiptool.R @@ -223,9 +224,9 @@ class OtaProviderClientFragment : Fragment() { showMessage("Error : ${e.toString()}") } - override fun onResponse(attributePath: ChipAttributePath?) { + override fun onResponse(attributePath: ChipAttributePath, status: Status) { Log.d(TAG, "onResponse") - showMessage("write Success") + showMessage("$attributePath : Write response: $status") } }, ChipClient.getConnectedDevicePointer(requireContext(), addressUpdateFragment.deviceId), @@ -350,9 +351,9 @@ class OtaProviderClientFragment : Fragment() { showMessage("error : ${e.toString()}") } - override fun onResponse(attributePath: ChipAttributePath?) { + override fun onResponse(attributePath: ChipAttributePath, status: Status) { Log.d(TAG, "onResponse") - showMessage("write success") + showMessage("$attributePath : Write response: $status") } }, ChipClient.getConnectedDevicePointer(requireContext(), addressUpdateFragment.deviceId), diff --git a/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/clusterclient/WildcardFragment.kt b/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/clusterclient/WildcardFragment.kt index 1978951e02e210..af119581a7047f 100644 --- a/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/clusterclient/WildcardFragment.kt +++ b/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/clusterclient/WildcardFragment.kt @@ -27,6 +27,7 @@ import chip.devicecontroller.model.ChipEventPath import chip.devicecontroller.model.ChipPathId import chip.devicecontroller.model.InvokeElement import chip.devicecontroller.model.NodeState +import chip.devicecontroller.model.Status import com.google.chip.chiptool.ChipClient import com.google.chip.chiptool.R import com.google.chip.chiptool.databinding.WildcardFragmentBinding @@ -92,8 +93,8 @@ class WildcardFragment : Fragment() { Log.e(TAG, "Report error for $attributePath: $ex") } - override fun onResponse(attributePath: ChipAttributePath?) { - val text = "$attributePath : Write Success" + override fun onResponse(attributePath: ChipAttributePath, status: Status) { + val text = "$attributePath : Write response: $status" requireActivity().runOnUiThread { binding.outputTv.text = text } } diff --git a/examples/java-matter-controller/java/src/com/matter/controller/commands/pairing/PairOnNetworkLongImReadCommand.kt b/examples/java-matter-controller/java/src/com/matter/controller/commands/pairing/PairOnNetworkLongImReadCommand.kt index e0a95d584130eb..1758fbd868fbfb 100644 --- a/examples/java-matter-controller/java/src/com/matter/controller/commands/pairing/PairOnNetworkLongImReadCommand.kt +++ b/examples/java-matter-controller/java/src/com/matter/controller/commands/pairing/PairOnNetworkLongImReadCommand.kt @@ -67,13 +67,12 @@ class PairOnNetworkLongImReadCommand( } fun checkUnitTestClusterGeneralStatus(status: Status): Boolean = - (status.getStatus() == CLUSTER_ID_TEST_GENERAL_ERROR_STATUS) && - !status.getClusterStatus().isPresent() + (status.getStatus() == Status.Code.InvalidDataType) && !status.getClusterStatus().isPresent() fun checkUnitTestClusterClusterStatus(status: Status): Boolean = - (status.getStatus() == CLUSTER_ID_TEST_CLUSTER_ERROR_STATUS) && + (status.getStatus() == Status.Code.Failure) && status.getClusterStatus().isPresent() && - status.getClusterStatus().get() == CLUSTER_ID_TEST_CLUSTER_ERROR_CLUSTER_STATUS + (status.getClusterStatus().get() == CLUSTER_ID_TEST_CLUSTER_ERROR_CLUSTER_STATUS) private fun validateResponse(nodeState: NodeState) { val endpointZero = @@ -243,8 +242,6 @@ class PairOnNetworkLongImReadCommand( private const val CLUSTER_ID_BASIC_VERSION = 0L private const val CLUSTER_ID_TEST_GENERAL_ERROR_BOOLEAN = 0x0031L private const val CLUSTER_ID_TEST_CLUSTER_ERROR_BOOLEAN = 0x0032L - private const val CLUSTER_ID_TEST_GENERAL_ERROR_STATUS = 0x8d - private const val CLUSTER_ID_TEST_CLUSTER_ERROR_STATUS = 1 private const val CLUSTER_ID_TEST_CLUSTER_ERROR_CLUSTER_STATUS = 17 } } diff --git a/examples/java-matter-controller/java/src/com/matter/controller/commands/pairing/PairOnNetworkLongImWriteCommand.kt b/examples/java-matter-controller/java/src/com/matter/controller/commands/pairing/PairOnNetworkLongImWriteCommand.kt index 3e90935d22268e..fdb74c5d065b5c 100644 --- a/examples/java-matter-controller/java/src/com/matter/controller/commands/pairing/PairOnNetworkLongImWriteCommand.kt +++ b/examples/java-matter-controller/java/src/com/matter/controller/commands/pairing/PairOnNetworkLongImWriteCommand.kt @@ -22,6 +22,7 @@ import chip.devicecontroller.GetConnectedDeviceCallbackJni.GetConnectedDeviceCal import chip.devicecontroller.WriteAttributesCallback import chip.devicecontroller.model.AttributeWriteRequest import chip.devicecontroller.model.ChipAttributePath +import chip.devicecontroller.model.Status import com.matter.controller.commands.common.CredentialsIssuer import java.util.logging.Level import java.util.logging.Logger @@ -51,11 +52,8 @@ class PairOnNetworkLongImWriteCommand( setFailure("write failure") } - override fun onResponse(attributePath: ChipAttributePath?) { - logger.log(Level.INFO, "Write receive OnResponse on ") - if (attributePath != null) { - logger.log(Level.INFO, attributePath.toString()) - } + override fun onResponse(attributePath: ChipAttributePath, status: Status) { + logger.log(Level.INFO, "$attributePath : Write response: $status") setSuccess() } } diff --git a/kotlin-detect-config.yaml b/kotlin-detect-config.yaml index 6de03b283f7065..2ad54a05d6c483 100644 --- a/kotlin-detect-config.yaml +++ b/kotlin-detect-config.yaml @@ -36,8 +36,8 @@ style: - "**/src/controller/java/src/matter/tlv/types.kt" - "**/src/controller/java/src/matter/tlv/utils.kt" - "**/src/controller/java/src/matter/tlv/values.kt" - - "**/src/controller/java/src/chip/WildcardImport - examples/android/CHIPTest/app/src/androidTest/java/com/tcl/chip/chiptest/ExampleInstrumentedTest.kt" + - "**/src/controller/java/src/matter/tlv/values.kt" + - "**/src/controller/java/src/matter/controller/model/Status.kt" - "**/src/controller/java/tests/chip/devicecontroller/cluster/ChipClusterEventStructTest.kt" - "**/src/controller/java/tests/chip/devicecontroller/cluster/ChipClusterStructTest.kt" - "**/src/controller/java/tests/matter/jsontlv/JsonToTlvToJsonTest.kt" diff --git a/scripts/py_matter_idl/matter_idl/generators/java/ChipClusters_java.jinja b/scripts/py_matter_idl/matter_idl/generators/java/ChipClusters_java.jinja index ba0abf5976f49c..6c8ad742068684 100644 --- a/scripts/py_matter_idl/matter_idl/generators/java/ChipClusters_java.jinja +++ b/scripts/py_matter_idl/matter_idl/generators/java/ChipClusters_java.jinja @@ -102,6 +102,7 @@ import chip.devicecontroller.model.ClusterState; import chip.devicecontroller.model.EndpointState; import chip.devicecontroller.model.InvokeElement; import chip.devicecontroller.model.NodeState; +import chip.devicecontroller.model.Status; import javax.annotation.Nullable; import java.util.ArrayList; @@ -318,8 +319,15 @@ public class ChipClusters { } @Override - public void onResponse(ChipAttributePath attributePath) { - callback.onSuccess(); + public void onResponse(ChipAttributePath attributePath, Status status) { + if (status.getStatus() == Status.Code.Success) + { + callback.onSuccess(); + } + else + { + callback.onError(new StatusException(status.getStatus())); + } } @Override diff --git a/scripts/py_matter_idl/matter_idl/tests/outputs/several_clusters/java/ChipClusters.java b/scripts/py_matter_idl/matter_idl/tests/outputs/several_clusters/java/ChipClusters.java index 9b6287a9a954ae..37c5c031b5c5ae 100644 --- a/scripts/py_matter_idl/matter_idl/tests/outputs/several_clusters/java/ChipClusters.java +++ b/scripts/py_matter_idl/matter_idl/tests/outputs/several_clusters/java/ChipClusters.java @@ -25,6 +25,7 @@ import chip.devicecontroller.model.EndpointState; import chip.devicecontroller.model.InvokeElement; import chip.devicecontroller.model.NodeState; +import chip.devicecontroller.model.Status; import javax.annotation.Nullable; import java.util.ArrayList; @@ -241,8 +242,15 @@ static class WriteAttributesCallbackImpl implements WriteAttributesCallback { } @Override - public void onResponse(ChipAttributePath attributePath) { - callback.onSuccess(); + public void onResponse(ChipAttributePath attributePath, Status status) { + if (status.getStatus() == Status.Code.Success) + { + callback.onSuccess(); + } + else + { + callback.onError(new StatusException(status.getStatus())); + } } @Override diff --git a/src/controller/java/AndroidCallbacks.cpp b/src/controller/java/AndroidCallbacks.cpp index eb6e8b1a5f255b..eb1584b531e292 100644 --- a/src/controller/java/AndroidCallbacks.cpp +++ b/src/controller/java/AndroidCallbacks.cpp @@ -669,23 +669,27 @@ void WriteAttributesCallback::OnResponse(const app::WriteClient * apWriteClient, JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread(); VerifyOrReturn(env != nullptr, ChipLogError(Controller, "Could not get JNIEnv for current thread")); JniLocalReferenceScope scope(env); - - if (aStatus.mStatus != Protocols::InteractionModel::Status::Success) - { - ReportError(&aPath, aStatus.mStatus); - return; - } - jmethodID onResponseMethod; VerifyOrReturn(mWrapperCallbackRef.HasValidObjectRef(), ChipLogError(Controller, "mWrapperCallbackRef is not valid in %s", __func__)); jobject wrapperCallback = mWrapperCallbackRef.ObjectRef(); - err = JniReferences::GetInstance().FindMethod(env, wrapperCallback, "onResponse", "(IJJ)V", &onResponseMethod); + err = JniReferences::GetInstance().FindMethod(env, wrapperCallback, "onResponse", "(IJJILjava/lang/Integer;)V", + &onResponseMethod); VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Controller, "Unable to find onError method: %s", ErrorStr(err))); + jobject jClusterState = nullptr; + if (aStatus.mClusterStatus.HasValue()) + { + err = JniReferences::GetInstance().CreateBoxedObject( + "java/lang/Integer", "(I)V", static_cast(aStatus.mClusterStatus.Value()), jClusterState); + VerifyOrReturn(err == CHIP_NO_ERROR, + ChipLogError(Controller, "Could not CreateBoxedObject with error %" CHIP_ERROR_FORMAT, err.Format())); + } + DeviceLayer::StackUnlock unlock; env->CallVoidMethod(wrapperCallback, onResponseMethod, static_cast(aPath.mEndpointId), - static_cast(aPath.mClusterId), static_cast(aPath.mAttributeId)); + static_cast(aPath.mClusterId), static_cast(aPath.mAttributeId), aStatus.mStatus, + jClusterState); VerifyOrReturn(!env->ExceptionCheck(), env->ExceptionDescribe()); } diff --git a/src/controller/java/BUILD.gn b/src/controller/java/BUILD.gn index b2ec93cb67f160..bf41b962b4cc3d 100644 --- a/src/controller/java/BUILD.gn +++ b/src/controller/java/BUILD.gn @@ -391,6 +391,7 @@ kotlin_library("kotlin_matter_controller") { "src/matter/controller/WriteAttributesCallbackJni.kt", "src/matter/controller/model/Paths.kt", "src/matter/controller/model/States.kt", + "src/matter/controller/model/Status.kt", ] sources += matter_structs_sources @@ -477,6 +478,7 @@ android_library("java") { "src/chip/devicecontroller/ReportCallback.java", "src/chip/devicecontroller/ReportCallbackJni.java", "src/chip/devicecontroller/ResubscriptionAttemptCallback.java", + "src/chip/devicecontroller/StatusException.java", "src/chip/devicecontroller/SubscriptionEstablishedCallback.java", "src/chip/devicecontroller/ThreadScanResult.java", "src/chip/devicecontroller/UnpairDeviceCallback.java", diff --git a/src/controller/java/generated/java/chip/devicecontroller/ChipClusters.java b/src/controller/java/generated/java/chip/devicecontroller/ChipClusters.java index 6e479c5f37094c..fcc9154511d2b7 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/ChipClusters.java +++ b/src/controller/java/generated/java/chip/devicecontroller/ChipClusters.java @@ -25,6 +25,7 @@ import chip.devicecontroller.model.EndpointState; import chip.devicecontroller.model.InvokeElement; import chip.devicecontroller.model.NodeState; +import chip.devicecontroller.model.Status; import javax.annotation.Nullable; import java.util.ArrayList; @@ -241,8 +242,15 @@ static class WriteAttributesCallbackImpl implements WriteAttributesCallback { } @Override - public void onResponse(ChipAttributePath attributePath) { - callback.onSuccess(); + public void onResponse(ChipAttributePath attributePath, Status status) { + if (status.getStatus() == Status.Code.Success) + { + callback.onSuccess(); + } + else + { + callback.onError(new StatusException(status.getStatus())); + } } @Override diff --git a/src/controller/java/src/chip/devicecontroller/StatusException.java b/src/controller/java/src/chip/devicecontroller/StatusException.java new file mode 100644 index 00000000000000..6a97e5b0e19aeb --- /dev/null +++ b/src/controller/java/src/chip/devicecontroller/StatusException.java @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2024 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package chip.devicecontroller; + +import chip.devicecontroller.model.Status; + +/** Exception class holding error codes defined by Interaction Model */ +public class StatusException extends Exception { + private static final long serialVersionUID = 1L; + + public Status.Code code = Status.Code.Success; + + public StatusException() {} + + public StatusException(Status.Code code) { + super(String.format("CHIP IM status error: %s", code.name())); + this.code = code; + } +} diff --git a/src/controller/java/src/chip/devicecontroller/WriteAttributesCallback.java b/src/controller/java/src/chip/devicecontroller/WriteAttributesCallback.java index 4e469ab0e58245..477f133c81a9c4 100644 --- a/src/controller/java/src/chip/devicecontroller/WriteAttributesCallback.java +++ b/src/controller/java/src/chip/devicecontroller/WriteAttributesCallback.java @@ -18,6 +18,7 @@ package chip.devicecontroller; import chip.devicecontroller.model.ChipAttributePath; +import chip.devicecontroller.model.Status; import javax.annotation.Nullable; /** An interface for receiving write response. */ @@ -40,8 +41,9 @@ public interface WriteAttributesCallback { * path. * * @param attributePath The attribute path field in write response. + * @param status The status field in write response. */ - void onResponse(ChipAttributePath attributePath); + void onResponse(ChipAttributePath attributePath, Status status); default void onDone() {} } diff --git a/src/controller/java/src/chip/devicecontroller/WriteAttributesCallbackJni.java b/src/controller/java/src/chip/devicecontroller/WriteAttributesCallbackJni.java index fd7f8066c80a73..7b95b30759222f 100644 --- a/src/controller/java/src/chip/devicecontroller/WriteAttributesCallbackJni.java +++ b/src/controller/java/src/chip/devicecontroller/WriteAttributesCallbackJni.java @@ -18,6 +18,8 @@ package chip.devicecontroller; import chip.devicecontroller.model.ChipAttributePath; +import chip.devicecontroller.model.Status; +import javax.annotation.Nullable; /** JNI wrapper callback class for {@link WriteAttributesCallback}. */ public final class WriteAttributesCallbackJni { @@ -45,9 +47,15 @@ private void onError( e); } - private void onResponse(int endpointId, long clusterId, long attributeId) { + private void onResponse( + int endpointId, + long clusterId, + long attributeId, + int status, + @Nullable Integer clusterStatus) { wrappedWriteAttributesCallback.onResponse( - ChipAttributePath.newInstance(endpointId, clusterId, attributeId)); + ChipAttributePath.newInstance(endpointId, clusterId, attributeId), + Status.newInstance(status, clusterStatus)); } private void onDone() { diff --git a/src/controller/java/src/chip/devicecontroller/model/Status.java b/src/controller/java/src/chip/devicecontroller/model/Status.java index c367535f5e8578..d859fae9f189e0 100644 --- a/src/controller/java/src/chip/devicecontroller/model/Status.java +++ b/src/controller/java/src/chip/devicecontroller/model/Status.java @@ -21,17 +21,87 @@ import java.util.Locale; import java.util.Optional; +/** Class for Interaction Model Status * */ public final class Status { - private Integer status; + public enum Code { + Success(0x0), + Failure(0x01), + InvalidSusbscription(0x7d), + UnsupportedAccess(0x7e), + UnsupportedEndPoint(0x7f), + InvalidAction(0x80), + UnsupportedCommand(0x81), + Deprecated82(0x82), + Deprecated83(0x83), + Deprecated84(0x84), + InvalidCommand(0x85), + UnsupportedAttribute(0x86), + ConstraintError(0x87), + UnsupportedWrite(0x88), + ResourceExhausted(0x89), + Deprecated8a(0x8a), + NotFound(0x8b), + UnreportableAttribute(0x8c), + InvalidDataType(0x8d), + Deprecated8e(0x8e), + UnsupportedRead(0x8f), + Deprecated90(0x90), + Deprecated91(0x91), + DataVersionMismatch(0x92), + Deprecated93(0x93), + Timeout(0x94), + Reserved95(0x95), + Reserved96(0x96), + Reserved97(0x97), + Reserved98(0x98), + Reserved99(0x99), + Reserved9a(0x9a), + Busy(0x9c), + Deprecatedc0(0xc0), + Deprecatedc1(0xc1), + Deprecatedc2(0xc2), + UnsupportedCluster(0xc3), + Deprecatedc4(0xc4), + NoUpstreamSubsricption(0xc5), + NeedTimedInteraction(0xc6), + UnsupportedEvent(0xc7), + PathExhausted(0xc8), + TimedRequestMismatch(0xc9), + FailsafeRequired(0xca), + InvalidInState(0xcb), + NoCommandResponse(0xcc), + WriteIgnored(0xf0); + + private int id = 0; + + Code(int id) { + this.id = id; + } + + public int getId() { + return id; + } + + public static Code fromId(int id) { + for (Code type : values()) { + if (type.getId() == id) { + return type; + } + } + return null; + } + } + + private Code status = Code.Success; private Optional clusterStatus; private Status(int status, Optional clusterStatus) { - this.status = status; + this.status = Code.fromId(status); this.clusterStatus = clusterStatus; } // Getters - public Integer getStatus() { + public Code getStatus() { return status; } @@ -43,7 +113,7 @@ public String toString() { return String.format( Locale.ENGLISH, "status %s, clusterStatus %s", - String.valueOf(status), + status.name(), clusterStatus.isPresent() ? String.valueOf(clusterStatus.get()) : "None"); } @@ -51,7 +121,7 @@ public static Status newInstance(int status) { return new Status(status, Optional.empty()); } - static Status newInstance(int status, Integer clusterStatus) { + public static Status newInstance(int status, Integer clusterStatus) { return new Status(status, Optional.ofNullable(clusterStatus)); } } diff --git a/src/controller/java/src/matter/controller/MatterControllerImpl.kt b/src/controller/java/src/matter/controller/MatterControllerImpl.kt index 202d97a99e1ad0..6ae71f33a0faac 100644 --- a/src/controller/java/src/matter/controller/MatterControllerImpl.kt +++ b/src/controller/java/src/matter/controller/MatterControllerImpl.kt @@ -36,6 +36,7 @@ import matter.controller.model.AttributePath import matter.controller.model.EventPath import matter.controller.model.EventState import matter.controller.model.NodeState +import matter.controller.model.Status /** Controller to interact with the CHIP device. */ class MatterControllerImpl(params: ControllerParams) : MatterController { @@ -340,8 +341,11 @@ class MatterControllerImpl(params: ControllerParams) : MatterController { return suspendCancellableCoroutine { continuation -> val writeCallback = object : WriteAttributesCallback { - override fun onResponse(attributePath: AttributePath) { - logger.log(Level.INFO, "write success for attributePath:%s", attributePath.toString()) + override fun onResponse(attributePath: AttributePath, status: Status) { + logger.log( + Level.INFO, + "Receive write response for attributePath: ${attributePath} and status ${status}" + ) } override fun onError(attributePath: AttributePath?, ex: Exception) { diff --git a/src/controller/java/src/matter/controller/WriteAttributesCallback.kt b/src/controller/java/src/matter/controller/WriteAttributesCallback.kt index b4a3f112a02f83..6b1b3f7056f71e 100644 --- a/src/controller/java/src/matter/controller/WriteAttributesCallback.kt +++ b/src/controller/java/src/matter/controller/WriteAttributesCallback.kt @@ -18,6 +18,7 @@ package matter.controller import matter.controller.model.AttributePath +import matter.controller.model.Status /** An interface for receiving write response. */ interface WriteAttributesCallback { @@ -38,8 +39,9 @@ interface WriteAttributesCallback { * path. * * @param attributePath The attribute path field in write response. + * @param status The attribute status field in write response. */ - fun onResponse(attributePath: AttributePath) + fun onResponse(attributePath: AttributePath, status: Status) fun onDone() {} } diff --git a/src/controller/java/src/matter/controller/WriteAttributesCallbackJni.kt b/src/controller/java/src/matter/controller/WriteAttributesCallbackJni.kt index bd0bad3e228dda..fe52a329ff3078 100644 --- a/src/controller/java/src/matter/controller/WriteAttributesCallbackJni.kt +++ b/src/controller/java/src/matter/controller/WriteAttributesCallbackJni.kt @@ -18,6 +18,7 @@ package matter.controller import matter.controller.model.AttributePath +import matter.controller.model.Status /** JNI wrapper callback class for [WriteAttributesCallback]. */ class WriteAttributesCallbackJni( @@ -53,9 +54,16 @@ class WriteAttributesCallbackJni( ) } - private fun onResponse(endpointId: Int, clusterId: Long, attributeId: Long) { + private fun onResponse( + endpointId: Int, + clusterId: Long, + attributeId: Long, + status: Int, + clusterStatus: Int? + ) { wrappedWriteAttributesCallback.onResponse( - AttributePath(endpointId.toUShort(), clusterId.toUInt(), attributeId.toUInt()) + AttributePath(endpointId.toUShort(), clusterId.toUInt(), attributeId.toUInt()), + Status(status, clusterStatus) ) } diff --git a/src/controller/java/src/matter/controller/model/States.kt b/src/controller/java/src/matter/controller/model/States.kt index c913b37b9986f4..e7799f1f5a64e1 100644 --- a/src/controller/java/src/matter/controller/model/States.kt +++ b/src/controller/java/src/matter/controller/model/States.kt @@ -273,5 +273,3 @@ data class EventState( return null } } - -data class Status(val status: Int, val clusterStatus: Int?) diff --git a/src/controller/java/src/matter/controller/model/Status.kt b/src/controller/java/src/matter/controller/model/Status.kt new file mode 100644 index 00000000000000..fa12f0b1cb25a5 --- /dev/null +++ b/src/controller/java/src/matter/controller/model/Status.kt @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2023 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package matter.controller.model + +/** + * Represents information about a node, including data on all available endpoints. + * + * @param endpoints A mapping of endpoint IDs with the associated cluster data. + */ +data class Status(val status: Int, val clusterStatus: Int?) { + enum class Code(val id: Int) { + SUCCESS(0X0), + FAILURE(0X01), + INVALID_SUSBSCRIPTION(0X7D), + UNSUPPORTED_ACCESS(0X7E), + UNSUPPORTED_ENDPOINT(0X7F), + INVALID_ACTION(0X80), + UNSUPPORTED_COMMAND(0X81), + DEPRECATED82(0X82), + DEPRECATED83(0X83), + DEPRECATED84(0X84), + INVALID_COMMAND(0X85), + UNSUPPORTED_ATTRIBUTE(0X86), + CONSTRAINT_ERROR(0X87), + UNSUPPORTED_WRITE(0X88), + RESOURCE_EXHAUSTED(0X89), + DEPRECATED8A(0X8A), + NOT_FOUND(0X8B), + UNREPORTABLE_ATTRIBUTE(0X8C), + INVALID_DATATYPE(0X8D), + DEPRECATED8E(0X8E), + UNSUPPORTED_READ(0X8F), + DEPRECATED90(0X90), + DEPRECATED91(0X91), + DATA_VERSION_MISMATCH(0X92), + DEPRECATED93(0X93), + TIMEOUT(0X94), + RESERVED95(0X95), + RESERVED96(0X96), + RESERVED97(0X97), + RESERVED98(0X98), + RESERVED99(0X99), + RESERVED9A(0X9A), + BUSY(0X9C), + DEPRECATEDC0(0XC0), + DEPRECATEDC1(0XC1), + DEPRECATEDC2(0XC2), + UNSUPPORTED_CLUSTER(0XC3), + DEPRECATEDC4(0XC4), + NO_UPSTREAM_SUBSRICPTION(0XC5), + NEEDS_TIMED_INTERACTION(0XC6), + UNSUPPORTED_EVENT(0XC7), + PATH_EXHAUSTED(0XC8), + TIMED_REQUEST_MISMATCH(0XC9), + FAILSAFE_REQUIRED(0XCA), + INVALID_IN_STATE(0XCB), + NO_COMMAND_RESPONSE(0XCC), + WRITE_IGNORED(0XF0) + } + + fun getCode(): Code? { + for (code in Code.values()) { + if (code.id == status) { + return code + } + } + return null + } + + override fun toString(): String = "$status/$clusterStatus/" +} diff --git a/src/controller/python/chip/interaction_model/__init__.py b/src/controller/python/chip/interaction_model/__init__.py index 61faa7f7d5d741..ec100846b085a5 100644 --- a/src/controller/python/chip/interaction_model/__init__.py +++ b/src/controller/python/chip/interaction_model/__init__.py @@ -86,6 +86,7 @@ class Status(enum.IntEnum): FailsafeRequired = 0xca InvalidInState = 0xcb NoCommandResponse = 0xcc + WriteIgnored = 0xf0 class InteractionModelError(ChipStackException): diff --git a/src/protocols/interaction_model/StatusCodeList.h b/src/protocols/interaction_model/StatusCodeList.h index 3b79e4a698b7b5..5538478d76ce52 100644 --- a/src/protocols/interaction_model/StatusCodeList.h +++ b/src/protocols/interaction_model/StatusCodeList.h @@ -22,7 +22,10 @@ * include this file, then undefine the macro. */ -/// WARNING: If you touch this list, please also update src/controller/python/chip/interaction_model/__init__.py +/// WARNING: If you touch this list, +/// please update src/controller/python/chip/interaction_model/__init__.py +/// please update src/controller/java/src/chip/devicecontroller/model/Status.java +/// please update src/controller/java/src/matter/controller/model/Status.kt // clang-format off CHIP_IM_STATUS_CODE(Success , SUCCESS , 0x0) From c4688b86cdb9345e4c4f12f8086b08ee237de555 Mon Sep 17 00:00:00 2001 From: yunhanw-google Date: Sun, 18 Feb 2024 20:03:58 -0800 Subject: [PATCH 27/33] [Android]rename MatterController-JNI.cpp to MatterInteractionClient-JNI.cpp (#32161) --- src/controller/java/BUILD.gn | 2 +- ...MatterController-JNI.cpp => MatterInteractionClient-JNI.cpp} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename src/controller/java/{MatterController-JNI.cpp => MatterInteractionClient-JNI.cpp} (100%) diff --git a/src/controller/java/BUILD.gn b/src/controller/java/BUILD.gn index bf41b962b4cc3d..678a03a6bf63bc 100644 --- a/src/controller/java/BUILD.gn +++ b/src/controller/java/BUILD.gn @@ -67,7 +67,7 @@ shared_library("jni") { "DeviceAttestationDelegateBridge.h", "GroupDeviceProxy.h", "MatterCallbacks-JNI.cpp", - "MatterController-JNI.cpp", + "MatterInteractionClient-JNI.cpp", ] deps = [ diff --git a/src/controller/java/MatterController-JNI.cpp b/src/controller/java/MatterInteractionClient-JNI.cpp similarity index 100% rename from src/controller/java/MatterController-JNI.cpp rename to src/controller/java/MatterInteractionClient-JNI.cpp From 11ea4316f3e5a60f8d34fcad8deeb154803498a8 Mon Sep 17 00:00:00 2001 From: Kamil Kasperczyk <66371704+kkasperczyk-no@users.noreply.github.com> Date: Mon, 19 Feb 2024 09:11:59 +0100 Subject: [PATCH 28/33] [nrfconnect] Added port for lit-icd-app example. (#32196) Implemented nrfconnect port for the lit-icd-app example. --- examples/lit-icd-app/nrfconnect/.gitignore | 1 + .../lit-icd-app/nrfconnect/CMakeLists.txt | 66 +++ examples/lit-icd-app/nrfconnect/Kconfig | 41 ++ examples/lit-icd-app/nrfconnect/README.md | 401 ++++++++++++++ .../boards/nrf52840dk_nrf52840.overlay | 54 ++ .../boards/nrf5340dk_nrf5340_cpuapp.overlay | 45 ++ .../boards/nrf52840dk_nrf52840.overlay | 21 + .../nrf52840dk_nrf52840_release.overlay | 21 + .../boards/nrf5340dk_nrf5340_cpuapp.overlay | 20 + .../nrf5340dk_nrf5340_cpuapp_release.overlay | 21 + .../nrfconnect/child_image/mcuboot/prj.conf | 30 ++ .../child_image/mcuboot/prj_release.conf | 30 ++ .../child_image/multiprotocol_rpmsg/prj.conf | 25 + .../multiprotocol_rpmsg/prj_no_dfu.conf | 25 + .../multiprotocol_rpmsg/prj_release.conf | 25 + .../nrf52840dk_nrf52840/pm_static_dfu.yml | 42 ++ .../pm_static_dfu.yml | 56 ++ .../lit-icd-app/nrfconnect/main/AppTask.cpp | 502 ++++++++++++++++++ .../nrfconnect/main/include/AppConfig.h | 33 ++ .../nrfconnect/main/include/AppEvent.h | 72 +++ .../nrfconnect/main/include/AppTask.h | 74 +++ .../main/include/CHIPProjectConfig.h | 28 + examples/lit-icd-app/nrfconnect/main/main.cpp | 33 ++ examples/lit-icd-app/nrfconnect/prj.conf | 46 ++ .../lit-icd-app/nrfconnect/prj_no_dfu.conf | 48 ++ .../lit-icd-app/nrfconnect/prj_release.conf | 60 +++ .../nrfconnect/third_party/connectedhomeip | 1 + 27 files changed, 1821 insertions(+) create mode 100644 examples/lit-icd-app/nrfconnect/.gitignore create mode 100644 examples/lit-icd-app/nrfconnect/CMakeLists.txt create mode 100644 examples/lit-icd-app/nrfconnect/Kconfig create mode 100644 examples/lit-icd-app/nrfconnect/README.md create mode 100644 examples/lit-icd-app/nrfconnect/boards/nrf52840dk_nrf52840.overlay create mode 100644 examples/lit-icd-app/nrfconnect/boards/nrf5340dk_nrf5340_cpuapp.overlay create mode 100644 examples/lit-icd-app/nrfconnect/child_image/mcuboot/boards/nrf52840dk_nrf52840.overlay create mode 100644 examples/lit-icd-app/nrfconnect/child_image/mcuboot/boards/nrf52840dk_nrf52840_release.overlay create mode 100644 examples/lit-icd-app/nrfconnect/child_image/mcuboot/boards/nrf5340dk_nrf5340_cpuapp.overlay create mode 100644 examples/lit-icd-app/nrfconnect/child_image/mcuboot/boards/nrf5340dk_nrf5340_cpuapp_release.overlay create mode 100644 examples/lit-icd-app/nrfconnect/child_image/mcuboot/prj.conf create mode 100644 examples/lit-icd-app/nrfconnect/child_image/mcuboot/prj_release.conf create mode 100644 examples/lit-icd-app/nrfconnect/child_image/multiprotocol_rpmsg/prj.conf create mode 100644 examples/lit-icd-app/nrfconnect/child_image/multiprotocol_rpmsg/prj_no_dfu.conf create mode 100644 examples/lit-icd-app/nrfconnect/child_image/multiprotocol_rpmsg/prj_release.conf create mode 100644 examples/lit-icd-app/nrfconnect/configuration/nrf52840dk_nrf52840/pm_static_dfu.yml create mode 100644 examples/lit-icd-app/nrfconnect/configuration/nrf5340dk_nrf5340_cpuapp/pm_static_dfu.yml create mode 100644 examples/lit-icd-app/nrfconnect/main/AppTask.cpp create mode 100644 examples/lit-icd-app/nrfconnect/main/include/AppConfig.h create mode 100644 examples/lit-icd-app/nrfconnect/main/include/AppEvent.h create mode 100644 examples/lit-icd-app/nrfconnect/main/include/AppTask.h create mode 100644 examples/lit-icd-app/nrfconnect/main/include/CHIPProjectConfig.h create mode 100644 examples/lit-icd-app/nrfconnect/main/main.cpp create mode 100644 examples/lit-icd-app/nrfconnect/prj.conf create mode 100644 examples/lit-icd-app/nrfconnect/prj_no_dfu.conf create mode 100644 examples/lit-icd-app/nrfconnect/prj_release.conf create mode 120000 examples/lit-icd-app/nrfconnect/third_party/connectedhomeip diff --git a/examples/lit-icd-app/nrfconnect/.gitignore b/examples/lit-icd-app/nrfconnect/.gitignore new file mode 100644 index 00000000000000..84c048a73cc2e5 --- /dev/null +++ b/examples/lit-icd-app/nrfconnect/.gitignore @@ -0,0 +1 @@ +/build/ diff --git a/examples/lit-icd-app/nrfconnect/CMakeLists.txt b/examples/lit-icd-app/nrfconnect/CMakeLists.txt new file mode 100644 index 00000000000000..a9b921016670e7 --- /dev/null +++ b/examples/lit-icd-app/nrfconnect/CMakeLists.txt @@ -0,0 +1,66 @@ +# +# Copyright (c) 2024 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +cmake_minimum_required(VERSION 3.13.1) + +get_filename_component(CHIP_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/third_party/connectedhomeip REALPATH) +get_filename_component(NRFCONNECT_COMMON ${CHIP_ROOT}/examples/platform/nrfconnect REALPATH) +get_filename_component(GEN_DIR ${CHIP_ROOT}/zzz_generated/ REALPATH) + +include(${CHIP_ROOT}/config/nrfconnect/app/check-nrfconnect-version.cmake) + +# Set Kconfig root files that will be processed as a first Kconfig for used child images. +set(mcuboot_KCONFIG_ROOT ${CHIP_ROOT}/config/nrfconnect/chip-module/Kconfig.mcuboot.root) +set(multiprotocol_rpmsg_KCONFIG_ROOT ${CHIP_ROOT}/config/nrfconnect/chip-module/Kconfig.multiprotocol_rpmsg.root) + +if(NOT CONF_FILE STREQUAL "prj_no_dfu.conf") + set(PM_STATIC_YML_FILE ${CMAKE_CURRENT_SOURCE_DIR}/configuration/${BOARD}/pm_static_dfu.yml) +endif() + +list(APPEND ZEPHYR_EXTRA_MODULES ${CHIP_ROOT}/config/nrfconnect/chip-module) +find_package(Zephyr HINTS $ENV{ZEPHYR_BASE}) + +# -Wmaybe-uninitialized has too many false positives, including on std::optional +# and chip::Optional. Make it nonfatal. +# +# See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80635 +target_compile_options(app PRIVATE -Werror -Wno-error=maybe-uninitialized) + +project(chip-nrfconnect-lit-icd-app-example) + +include(${CHIP_ROOT}/config/nrfconnect/app/enable-gnu-std.cmake) +include(${CHIP_ROOT}/config/nrfconnect/app/flashing.cmake) +include(${CHIP_ROOT}/src/app/chip_data_model.cmake) + +target_include_directories(app PRIVATE + main/include + ${GEN_DIR}/app-common + ${GEN_DIR}/lit-icd-app + ${NRFCONNECT_COMMON}/util/include + ${NRFCONNECT_COMMON}/app/include) + +target_sources(app PRIVATE + main/AppTask.cpp + main/main.cpp + ${NRFCONNECT_COMMON}/util/LEDWidget.cpp) + +chip_configure_data_model(app + INCLUDE_SERVER + ZAP_FILE ${CMAKE_CURRENT_SOURCE_DIR}/../lit-icd-common/lit-icd-server-app.zap +) + +if(CONFIG_CHIP_OTA_REQUESTOR) + target_sources(app PRIVATE ${NRFCONNECT_COMMON}/util/OTAUtil.cpp) +endif() diff --git a/examples/lit-icd-app/nrfconnect/Kconfig b/examples/lit-icd-app/nrfconnect/Kconfig new file mode 100644 index 00000000000000..4d9501ac5cab90 --- /dev/null +++ b/examples/lit-icd-app/nrfconnect/Kconfig @@ -0,0 +1,41 @@ +# +# Copyright (c) 2024 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +mainmenu "Matter nRF Connect LIT ICD Example Application" + +config STATE_LEDS + bool "Use LEDs to indicate the device state" + default y + help + Use LEDs to render the current state of the device such as the progress of commissioning of + the device into a network or the factory reset initiation. Note that setting this option to + 'n' does not disable the LED indicating the state of the simulated bolt. + +# Sample configuration used for Thread networking +if NET_L2_OPENTHREAD + +choice OPENTHREAD_NORDIC_LIBRARY_CONFIGURATION + default OPENTHREAD_NORDIC_LIBRARY_MTD +endchoice + +choice OPENTHREAD_DEVICE_TYPE + default OPENTHREAD_MTD +endchoice + +endif # NET_L2_OPENTHREAD + +rsource "../../../config/nrfconnect/chip-module/Kconfig.features" +rsource "../../../config/nrfconnect/chip-module/Kconfig.defaults" +source "Kconfig.zephyr" diff --git a/examples/lit-icd-app/nrfconnect/README.md b/examples/lit-icd-app/nrfconnect/README.md new file mode 100644 index 00000000000000..704950fdcac63e --- /dev/null +++ b/examples/lit-icd-app/nrfconnect/README.md @@ -0,0 +1,401 @@ +# Matter nRF Connect LIT ICD Example Application + +The nRF Connect LIT ICD Example allows to test the device that utilizes Long +Idle Time feature from the Intermittently Connected Device Management cluster. +It uses buttons to change the device states and LEDs to show the state of these +changes. You can use this example as a reference for creating your own +application. + +Nordic Semiconductor logo +nRF52840 DK + +The example is based on +[Matter](https://github.com/project-chip/connectedhomeip) and Nordic +Semiconductor's nRF Connect SDK, and was created to facilitate testing and +certification of a Matter device communicating over a low-power, 802.15.4 Thread +network. + +The example behaves as a Matter accessory, that is a device that can be paired +into an existing Matter network and can be controlled by this network. + +
+ +## Overview + +This example is running on the nRF Connect platform, which is based on Nordic +Semiconductor's +[nRF Connect SDK](https://developer.nordicsemi.com/nRF_Connect_SDK/doc/latest/nrf/index.html) +and [Zephyr RTOS](https://zephyrproject.org/). Visit Matter's +[nRF Connect platform overview](../../../docs/guides/nrfconnect_platform_overview.md) +to read more about the platform structure and dependencies. + +By default, the Matter accessory device has IPv6 networking disabled. You must +pair it with the Matter controller over Bluetooth® LE to get the configuration +from the controller to use the device within a Thread network. You have to make +the device discoverable manually (for security reasons). See +[Bluetooth LE advertising](#bluetooth-le-advertising) to learn how to do this. +The controller must get the commissioning information from the Matter accessory +device and provision the device into the network. + +The sample uses buttons for changing the device states, and LEDs to show the +state of these changes. + +### Bluetooth LE advertising + +In this example, to commission the device onto a Matter network, it must be +discoverable over Bluetooth LE. For security reasons, you must start Bluetooth +LE advertising manually after powering up the device by pressing **Button 4**. + +### Bluetooth LE rendezvous + +In this example, the commissioning procedure is done over Bluetooth LE between a +Matter device and the Matter controller, where the controller has the +commissioner role. + +To start the rendezvous, the controller must get the commissioning information +from the Matter device. The data payload is encoded within a QR code, printed to +the UART console, and shared using an NFC tag. The emulation of the NFC tag +emulation starts automatically when Bluetooth LE advertising is started and +stays enabled until Bluetooth LE advertising timeout expires. + +#### Thread provisioning + +The provisioning operation, which is the Last part of the rendezvous procedure, +involves sending the Thread network credentials from the Matter controller to +the Matter device. As a result, the device joins the Thread network and can +communicate with other devices in the network. + +### Device Firmware Upgrade + +The example supports over-the-air (OTA) device firmware upgrade (DFU) using +Matter OTA mechanism, which is enabled by default. + +The +[MCUboot](https://developer.nordicsemi.com/nRF_Connect_SDK/doc/latest/mcuboot/index.html) +bootloader solution is used to replace the old firmware image with the new one. + +#### Matter Over-the-Air Update + +The Matter over-the-air update distinguishes two types of nodes: OTA Provider +and OTA Requestor. + +An OTA Provider is a node that hosts a new firmware image and is able to respond +on an OTA Requestor's queries regarding availability of new firmware images or +requests to start sending the update packages. + +An OTA Requestor is a node that wants to download a new firmware image and sends +requests to an OTA Provider to start the update process. + +#### Bootloader + +MCUboot is a secure bootloader used for swapping firmware images of different +versions and generating proper build output files that can be used in the device +firmware upgrade process. + +The bootloader solution requires an area of flash memory to swap application +images during the firmware upgrade. Nordic Semiconductor devices use an external +memory chip for this purpose. The memory chip communicates with the +microcontroller through the QSPI bus. + +See the +[Building with Device Firmware Upgrade support](#building-with-device-firmware-upgrade-support) +section to learn how to change MCUboot and flash configuration in this example. + +
+ +## Requirements + +The application requires a specific revision of the nRF Connect SDK to work +correctly. See [Setting up the environment](#setting-up-the-environment) for +more information. + +### Supported devices + +The example supports building and running on the following devices: + +| Hardware platform | Build target | Platform image | +| ----------------------------------------------------------------------------------------- | -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ | +| [nRF52840 DK](https://www.nordicsemi.com/Software-and-Tools/Development-Kits/nRF52840-DK) | `nrf52840dk_nrf52840` |
nRF52840 DKnRF52840 DK
| +| [nRF5340 DK](https://www.nordicsemi.com/Software-and-Tools/Development-Kits/nRF5340-DK) | `nrf5340dk_nrf5340_cpuapp` |
nRF5340 DKnRF5340 DK
| + +
+ +## Device UI + +This section lists the User Interface elements that you can use to control and +monitor the state of the device. These correspond to PCB components on the +platform image. + +**LED 1** shows the overall state of the device and its connectivity. The +following states are possible: + +- _Short Flash On (50 ms on/950 ms off)_ — The device is in the + unprovisioned (unpaired) state and is waiting for a commissioning + application to connect. + +- _Rapid Even Flashing (100 ms on/100 ms off)_ — The device is in the + unprovisioned state and a commissioning application is connected through + Bluetooth LE. + +- _Short Flash Off (950ms on/50ms off)_ — The device is fully + provisioned, but does not yet have full connectivity for Thread network. + +- _Solid On_ — The device is fully provisioned. + +**LED 2** is used for the Identify feature purpose. The LED starts blinking +evenly (500 ms on/500 ms off) when the Identify command of the Identify cluster +is received on the endpoint 1. The command’s argument can be used to specify the +duration of the effect. + +**Button 1** Pressing the button for more than 3 s initiates the factory reset +of the device. Releasing the button within the 3-second window cancels the +factory reset procedure. + +**Button 3** Represents the User Active Mode Trigger feature from the +Intermittently Connected Devices Management cluster. Pressing it puts the ICD +device in the active mode and makes it responsive. + +**Button 4** Starts the NFC tag emulation, enables Bluetooth LE advertising for +the predefined period of time (15 minutes by default), and makes the device +discoverable over Bluetooth LE. This button is used during the commissioning +procedure. + +**SEGGER J-Link USB port** can be used to get logs from the device or +communicate with it using the +[command line interface](../../../docs/guides/nrfconnect_examples_cli.md). + +**NFC port with antenna attached** can be used to start the +[rendezvous](#bluetooth-le-rendezvous) by providing the commissioning +information from the Matter device in a data payload that can be shared using +NFC. + +
+ +## Setting up the environment + +Before building the example, check out the Matter repository and sync submodules +using the following command: + + $ python3 scripts/checkout_submodules.py --shallow --platform nrfconnect + +> **Note**: +> +> For Linux operating system install +> [SEGGER J-Link Software](https://www.segger.com/downloads/jlink/#J-LinkSoftwareAndDocumentationPack). + +### Install Command Line Tools + +With admin permissions enabled, download and install the +[nRF Command Line Tools](https://www.nordicsemi.com/Products/Development-tools/nrf-command-line-tools). + +### Install Toolchain Manager + +Toolchain Manager is available from +[nRF Connect for Desktop](https://www.nordicsemi.com/Products/Development-tools/nrf-connect-for-desktop), +a cross-platform tool that provides different applications that simplify +installing the nRF Connect SDK. Both the tool and the application are available +for Windows, Linux, and macOS. + +To install the Toolchain Manager app, complete the following steps: + +1. [Download nRF Connect for Desktop](https://www.nordicsemi.com/Products/Development-tools/nrf-connect-for-desktop/download#infotabs) + for your operating system. + +2. Install and run the tool on your machine. + +3. In the **APPS** section, click **Install** button on the Toolchain Manager + tab. + +### Install nRF Connect SDK + +Complete the following steps to install the nRF Connect SDK: + +1. Open Toolchain Manager in nRF Connect for Desktop. + +2. Click the **Install** button next to the + [recommended](../../../config/nrfconnect/.nrfconnect-recommended-revision) + version of the nRF Connect SDK. + +3. A pop-up window will inform you about the current installation directory. If + you want to change the directory, click the **Change directory** button. + Otherwise, click the **Continue installation** button. + +4. When the nRF Connect SDK is installed on your machine, the **Install** + button changes to the **Open VS Code** button. + +5. Click the dropdown menu next to the **Open VS Code** button for the + installed nRF Connect SDK version, and select **Open terminal**. + +6. Make sure that the nRF Connect SDK version is compatible with the Matter SDK + version: + + ``` + $ cd {connectedhomeip directory} + $ python3 scripts/setup/nrfconnect/update_ncs.py --update + ``` + +Now you can proceed with the [Building](#building) instruction. + +
+ +## Building + +Complete the following steps to build the sample: + +1. Navigate to the example's directory: + + $ cd examples/lit-icd-app/nrfconnect + +2. Run the following command to build the example, with _build-target_ replaced + with the build target name of the Nordic Semiconductor's kit you own, for + example `nrf52840dk_nrf52840`: + + $ west build -b build-target + + You only need to specify the build target on the first build. See + [Requirements](#requirements) for the build target names of compatible kits. + +The output `zephyr.hex` file will be available in the `build/zephyr/` directory. + +### Removing build artifacts + +If you're planning to build the example for a different kit or make changes to +the configuration, remove all build artifacts before building. To do so, use the +following command: + + $ rm -r build + +### Building with release configuration + +To build the example with release configuration that disables the diagnostic +features like logs and command-line interface, run the following command: + + $ west build -b build-target -- -DCONF_FILE=prj_release.conf + +Remember to replace _build-target_ with the build target name of the Nordic +Semiconductor's kit you own. + +### Building with Device Firmware Upgrade support + +Support for DFU using Matter OTA is enabled by default. + +To completely disable support for DFU, run the following command with +_build-target_ replaced with the build target name of the Nordic Semiconductor +kit you are using (for example `nrf52840dk_nrf52840`): + + $ west build -b build-target -- -DCONF_FILE=prj_no_dfu.conf + +> **Note**: +> +> There are two types of Device Firmware Upgrade modes: single-image DFU and +> multi-image DFU. Single-image mode supports upgrading only one firmware image, +> the application image, and should be used for single-core nRF52840 DK devices. +> Multi-image mode allows to upgrade more firmware images and is suitable for +> upgrading the application core and network core firmware in two-core nRF5340 +> DK devices. + +#### Changing bootloader configuration + +To change the default MCUboot configuration, edit the `prj.conf` file located in +the `child_image/mcuboot` directory. + +Make sure to keep the configuration consistent with changes made to the +application configuration. This is necessary for the configuration to work, as +the bootloader image is a separate application from the user application and it +has its own configuration file. + +#### Changing flash memory settings + +In the default configuration, the MCUboot uses the +[Partition Manager](https://developer.nordicsemi.com/nRF_Connect_SDK/doc/latest/nrf/scripts/partition_manager/partition_manager.html#partition-manager) +to configure flash partitions used for the bootloader application image slot +purposes. You can change these settings by defining +[static partitions](https://developer.nordicsemi.com/nRF_Connect_SDK/doc/latest/nrf/scripts/partition_manager/partition_manager.html#ug-pm-static). +This example uses this option to define using an external flash. + +To modify the flash settings of your board (that is, your _build-target_, for +example `nrf52840dk_nrf52840`), edit the `pm_static_dfu.yml` file located in the +`configuration/build-target/` directory. + +
+ +## Configuring the example + +The Zephyr ecosystem is based on Kconfig files and the settings can be modified +using the menuconfig utility. + +To open the menuconfig utility, run the following command from the example +directory: + + $ west build -b build-target -t menuconfig + +Remember to replace _build-target_ with the build target name of the Nordic +Semiconductor's kit you own. + +Changes done with menuconfig will be lost if the `build` directory is deleted. +To make them persistent, save the configuration options in the `prj.conf` file. + +### Example build types + +The example uses different configuration files depending on the supported +features. Configuration files are provided for different build types and they +are located in the application root directory. + +The `prj.conf` file represents a debug build type. Other build types are covered +by dedicated files with the build type added as a suffix to the prj part, as per +the following list. For example, the release build type file name is +`prj_release.conf`. If a board has other configuration files, for example +associated with partition layout or child image configuration, these follow the +same pattern. + +Before you start testing the application, you can select one of the build types +supported by the sample. This sample supports the following build types, +depending on the selected board: + +- debug -- Debug version of the application - can be used to enable additional + features for verifying the application behavior, such as logs or + command-line shell. +- release -- Release version of the application - can be used to enable only + the necessary application functionalities to optimize its performance. +- no_dfu -- Debug version of the application without Device Firmware Upgrade + feature support. + +For more information, see the +[Configuring nRF Connect SDK examples](../../../docs/guides/nrfconnect_examples_configuration.md) +page. + +
+ +## Flashing and debugging + +To flash the application to the device, use the west tool and run the following +command from the example directory: + + $ west flash --erase + +If you have multiple development kits connected, west will prompt you to pick +the correct one. + +To debug the application on target, run the following command from the example +directory: + + $ west debug + +
+ +## Testing the example + +Check the [CLI tutorial](../../../docs/guides/nrfconnect_examples_cli.md) to +learn how to use command-line interface of the application. + +### Testing using Linux CHIPTool + +Read the [CHIP Tool user guide](../../../docs/guides/chip_tool_guide.md) to see +how to use [CHIP Tool for Linux or mac OS](../../chip-tool/README.md) to +commission and control the application within a Matter-enabled Thread network. + +### Testing Device Firmware Upgrade + +Read the +[DFU tutorial](../../../docs/guides/nrfconnect_examples_software_update.md) to +see how to upgrade your device firmware. diff --git a/examples/lit-icd-app/nrfconnect/boards/nrf52840dk_nrf52840.overlay b/examples/lit-icd-app/nrfconnect/boards/nrf52840dk_nrf52840.overlay new file mode 100644 index 00000000000000..7babe0424821ba --- /dev/null +++ b/examples/lit-icd-app/nrfconnect/boards/nrf52840dk_nrf52840.overlay @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2024 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/ { + chosen { + nordic,pm-ext-flash = &mx25r64; + }; + + /* + * In some default configurations within the nRF Connect SDK, + * e.g. on nRF52840, the chosen zephyr,entropy node is &cryptocell. + * This devicetree overlay ensures that default is overridden wherever it + * is set, as this application uses the RNG node for entropy exclusively. + */ + chosen { + zephyr,entropy = &rng; + }; +}; + +/* Disable unused peripherals to reduce power consumption */ +&adc { + status = "disabled"; +}; +&uart1 { + status = "disabled"; +}; +&i2c0 { + status = "disabled"; +}; +&pwm0 { + status = "disabled"; +}; +&spi1 { + status = "disabled"; +}; +&spi3 { + status = "disabled"; +}; +&usbd { + status = "disabled"; +}; diff --git a/examples/lit-icd-app/nrfconnect/boards/nrf5340dk_nrf5340_cpuapp.overlay b/examples/lit-icd-app/nrfconnect/boards/nrf5340dk_nrf5340_cpuapp.overlay new file mode 100644 index 00000000000000..12155ffcd1f509 --- /dev/null +++ b/examples/lit-icd-app/nrfconnect/boards/nrf5340dk_nrf5340_cpuapp.overlay @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2024 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +/ { + chosen { + nordic,pm-ext-flash = &mx25r64; + }; +}; + +/* Set IPC thread priority to the highest value to not collide with other threads. */ +&ipc0 { + zephyr,priority = <0 PRIO_COOP>; +}; + +/* Disable unused peripherals to reduce power consumption */ +&adc { + status = "disabled"; +}; +&i2c1 { + status = "disabled"; +}; +&pwm0 { + status = "disabled"; +}; +&spi2 { + status = "disabled"; +}; +&usbd { + status = "disabled"; +}; diff --git a/examples/lit-icd-app/nrfconnect/child_image/mcuboot/boards/nrf52840dk_nrf52840.overlay b/examples/lit-icd-app/nrfconnect/child_image/mcuboot/boards/nrf52840dk_nrf52840.overlay new file mode 100644 index 00000000000000..9f9128c6beff60 --- /dev/null +++ b/examples/lit-icd-app/nrfconnect/child_image/mcuboot/boards/nrf52840dk_nrf52840.overlay @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2024 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/ { + chosen { + nordic,pm-ext-flash = &mx25r64; + }; +}; diff --git a/examples/lit-icd-app/nrfconnect/child_image/mcuboot/boards/nrf52840dk_nrf52840_release.overlay b/examples/lit-icd-app/nrfconnect/child_image/mcuboot/boards/nrf52840dk_nrf52840_release.overlay new file mode 100644 index 00000000000000..9f9128c6beff60 --- /dev/null +++ b/examples/lit-icd-app/nrfconnect/child_image/mcuboot/boards/nrf52840dk_nrf52840_release.overlay @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2024 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/ { + chosen { + nordic,pm-ext-flash = &mx25r64; + }; +}; diff --git a/examples/lit-icd-app/nrfconnect/child_image/mcuboot/boards/nrf5340dk_nrf5340_cpuapp.overlay b/examples/lit-icd-app/nrfconnect/child_image/mcuboot/boards/nrf5340dk_nrf5340_cpuapp.overlay new file mode 100644 index 00000000000000..50069180506973 --- /dev/null +++ b/examples/lit-icd-app/nrfconnect/child_image/mcuboot/boards/nrf5340dk_nrf5340_cpuapp.overlay @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2024 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/ { + chosen { + nordic,pm-ext-flash = &mx25r64; + }; +}; diff --git a/examples/lit-icd-app/nrfconnect/child_image/mcuboot/boards/nrf5340dk_nrf5340_cpuapp_release.overlay b/examples/lit-icd-app/nrfconnect/child_image/mcuboot/boards/nrf5340dk_nrf5340_cpuapp_release.overlay new file mode 100644 index 00000000000000..9f9128c6beff60 --- /dev/null +++ b/examples/lit-icd-app/nrfconnect/child_image/mcuboot/boards/nrf5340dk_nrf5340_cpuapp_release.overlay @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2024 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/ { + chosen { + nordic,pm-ext-flash = &mx25r64; + }; +}; diff --git a/examples/lit-icd-app/nrfconnect/child_image/mcuboot/prj.conf b/examples/lit-icd-app/nrfconnect/child_image/mcuboot/prj.conf new file mode 100644 index 00000000000000..3f43b733b4bb96 --- /dev/null +++ b/examples/lit-icd-app/nrfconnect/child_image/mcuboot/prj.conf @@ -0,0 +1,30 @@ +# +# Copyright (c) 2024 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# This target uses Kconfig.mcuboot.defaults to set options common for all +# samples using mcuboot. This file should contain only options specific for this sample +# mcuboot configuration or overrides of default values. + +CONFIG_MBEDTLS_CFG_FILE="mcuboot-mbedtls-cfg.h" + +# Bootloader size optimization +# Disable not used modules that cannot be set in Kconfig.mcuboot.defaults due to overriding +# in board files. +CONFIG_CONSOLE=n +CONFIG_SERIAL=n +CONFIG_UART_CONSOLE=n +CONFIG_USE_SEGGER_RTT=n +CONFIG_GPIO=n diff --git a/examples/lit-icd-app/nrfconnect/child_image/mcuboot/prj_release.conf b/examples/lit-icd-app/nrfconnect/child_image/mcuboot/prj_release.conf new file mode 100644 index 00000000000000..3f43b733b4bb96 --- /dev/null +++ b/examples/lit-icd-app/nrfconnect/child_image/mcuboot/prj_release.conf @@ -0,0 +1,30 @@ +# +# Copyright (c) 2024 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# This target uses Kconfig.mcuboot.defaults to set options common for all +# samples using mcuboot. This file should contain only options specific for this sample +# mcuboot configuration or overrides of default values. + +CONFIG_MBEDTLS_CFG_FILE="mcuboot-mbedtls-cfg.h" + +# Bootloader size optimization +# Disable not used modules that cannot be set in Kconfig.mcuboot.defaults due to overriding +# in board files. +CONFIG_CONSOLE=n +CONFIG_SERIAL=n +CONFIG_UART_CONSOLE=n +CONFIG_USE_SEGGER_RTT=n +CONFIG_GPIO=n diff --git a/examples/lit-icd-app/nrfconnect/child_image/multiprotocol_rpmsg/prj.conf b/examples/lit-icd-app/nrfconnect/child_image/multiprotocol_rpmsg/prj.conf new file mode 100644 index 00000000000000..48deaa9fa18135 --- /dev/null +++ b/examples/lit-icd-app/nrfconnect/child_image/multiprotocol_rpmsg/prj.conf @@ -0,0 +1,25 @@ +# +# Copyright (c) 2024 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# This target uses Kconfig.multiprotocol_rpmsg.defaults to set options common for all +# samples using multiprotocol_rpmsg. This file should contain only options specific for this sample +# multiprotocol_rpmsg configuration or overrides of default values. + +# Disable not used modules that cannot be set in Kconfig.multiprotocol_rpmsg.defaults due to overriding +# in board files. + +CONFIG_SERIAL=n +CONFIG_UART_CONSOLE=n diff --git a/examples/lit-icd-app/nrfconnect/child_image/multiprotocol_rpmsg/prj_no_dfu.conf b/examples/lit-icd-app/nrfconnect/child_image/multiprotocol_rpmsg/prj_no_dfu.conf new file mode 100644 index 00000000000000..48deaa9fa18135 --- /dev/null +++ b/examples/lit-icd-app/nrfconnect/child_image/multiprotocol_rpmsg/prj_no_dfu.conf @@ -0,0 +1,25 @@ +# +# Copyright (c) 2024 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# This target uses Kconfig.multiprotocol_rpmsg.defaults to set options common for all +# samples using multiprotocol_rpmsg. This file should contain only options specific for this sample +# multiprotocol_rpmsg configuration or overrides of default values. + +# Disable not used modules that cannot be set in Kconfig.multiprotocol_rpmsg.defaults due to overriding +# in board files. + +CONFIG_SERIAL=n +CONFIG_UART_CONSOLE=n diff --git a/examples/lit-icd-app/nrfconnect/child_image/multiprotocol_rpmsg/prj_release.conf b/examples/lit-icd-app/nrfconnect/child_image/multiprotocol_rpmsg/prj_release.conf new file mode 100644 index 00000000000000..48deaa9fa18135 --- /dev/null +++ b/examples/lit-icd-app/nrfconnect/child_image/multiprotocol_rpmsg/prj_release.conf @@ -0,0 +1,25 @@ +# +# Copyright (c) 2024 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# This target uses Kconfig.multiprotocol_rpmsg.defaults to set options common for all +# samples using multiprotocol_rpmsg. This file should contain only options specific for this sample +# multiprotocol_rpmsg configuration or overrides of default values. + +# Disable not used modules that cannot be set in Kconfig.multiprotocol_rpmsg.defaults due to overriding +# in board files. + +CONFIG_SERIAL=n +CONFIG_UART_CONSOLE=n diff --git a/examples/lit-icd-app/nrfconnect/configuration/nrf52840dk_nrf52840/pm_static_dfu.yml b/examples/lit-icd-app/nrfconnect/configuration/nrf52840dk_nrf52840/pm_static_dfu.yml new file mode 100644 index 00000000000000..ce42b39e55ee87 --- /dev/null +++ b/examples/lit-icd-app/nrfconnect/configuration/nrf52840dk_nrf52840/pm_static_dfu.yml @@ -0,0 +1,42 @@ +mcuboot: + address: 0x0 + size: 0x7000 + region: flash_primary +mcuboot_pad: + address: 0x7000 + size: 0x200 +app: + address: 0x7200 + size: 0xf3e00 +mcuboot_primary: + orig_span: &id001 + - mcuboot_pad + - app + span: *id001 + address: 0x7000 + size: 0xf4000 + region: flash_primary +mcuboot_primary_app: + orig_span: &id002 + - app + span: *id002 + address: 0x7200 + size: 0xf3e00 +factory_data: + address: 0xfb000 + size: 0x1000 + region: flash_primary +settings_storage: + address: 0xfc000 + size: 0x4000 + region: flash_primary +mcuboot_secondary: + address: 0x0 + size: 0xf4000 + device: MX25R64 + region: external_flash +external_flash: + address: 0xf4000 + size: 0x70c000 + device: MX25R64 + region: external_flash diff --git a/examples/lit-icd-app/nrfconnect/configuration/nrf5340dk_nrf5340_cpuapp/pm_static_dfu.yml b/examples/lit-icd-app/nrfconnect/configuration/nrf5340dk_nrf5340_cpuapp/pm_static_dfu.yml new file mode 100644 index 00000000000000..10e8680c363a53 --- /dev/null +++ b/examples/lit-icd-app/nrfconnect/configuration/nrf5340dk_nrf5340_cpuapp/pm_static_dfu.yml @@ -0,0 +1,56 @@ +mcuboot: + address: 0x0 + size: 0x8000 + region: flash_primary +mcuboot_pad: + address: 0x8000 + size: 0x200 +app: + address: 0x8200 + size: 0xf2e00 +mcuboot_primary: + orig_span: &id001 + - mcuboot_pad + - app + span: *id001 + address: 0x8000 + size: 0xf3000 + region: flash_primary +mcuboot_primary_app: + orig_span: &id002 + - app + span: *id002 + address: 0x8200 + size: 0xf2e00 +factory_data: + address: 0xfb000 + size: 0x1000 + region: flash_primary +settings_storage: + address: 0xfc000 + size: 0x4000 + region: flash_primary +mcuboot_primary_1: + address: 0x0 + size: 0x40000 + device: flash_ctrl + region: ram_flash +mcuboot_secondary: + address: 0x0 + size: 0xf3000 + device: MX25R64 + region: external_flash +mcuboot_secondary_1: + address: 0xf3000 + size: 0x40000 + device: MX25R64 + region: external_flash +external_flash: + address: 0x133000 + size: 0x6CD000 + device: MX25R64 + region: external_flash +pcd_sram: + address: 0x20000000 + size: 0x2000 + region: sram_primary diff --git a/examples/lit-icd-app/nrfconnect/main/AppTask.cpp b/examples/lit-icd-app/nrfconnect/main/AppTask.cpp new file mode 100644 index 00000000000000..50622d0c88b96e --- /dev/null +++ b/examples/lit-icd-app/nrfconnect/main/AppTask.cpp @@ -0,0 +1,502 @@ +/* + * Copyright (c) 2024 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "AppTask.h" +#include "AppConfig.h" +#include "AppEvent.h" +#include "FabricTableDelegate.h" +#include "LEDUtil.h" + +#include + +#include +#include + +#include +#include +#include +#include + +#include +#include + +#if CONFIG_CHIP_OTA_REQUESTOR +#include "OTAUtil.h" +#endif + +#include +#include +#include + +LOG_MODULE_DECLARE(app, CONFIG_CHIP_APP_LOG_LEVEL); + +using namespace ::chip; +using namespace ::chip::app; +using namespace ::chip::Credentials; +using namespace ::chip::DeviceLayer; + +namespace { +constexpr uint32_t kFactoryResetTriggerTimeout = 3000; +constexpr uint32_t kFactoryResetCancelWindowTimeout = 3000; +constexpr size_t kAppEventQueueSize = 10; +constexpr EndpointId kIdentifyEndpointId = 1; + +// NOTE! This key is for test/certification only and should not be available in production devices! +// If CONFIG_CHIP_FACTORY_DATA is enabled, this value is read from the factory data. +uint8_t sTestEventTriggerEnableKey[TestEventTriggerDelegate::kEnableKeyLength] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, + 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff }; + +K_MSGQ_DEFINE(sAppEventQueue, sizeof(AppEvent), kAppEventQueueSize, alignof(AppEvent)); +k_timer sFunctionTimer; + +chip::DeviceLayer::DeviceInfoProviderImpl gExampleDeviceInfoProvider; + +Identify sIdentify = { kIdentifyEndpointId, AppTask::IdentifyStartHandler, AppTask::IdentifyStopHandler, + Clusters::Identify::IdentifyTypeEnum::kVisibleIndicator }; + +LEDWidget sStatusLED; +LEDWidget sIdentifyLED; +FactoryResetLEDsWrapper<2> sFactoryResetLEDs{ { FACTORY_RESET_SIGNAL_LED, FACTORY_RESET_SIGNAL_LED1 } }; + +bool sIsNetworkProvisioned = false; +bool sIsNetworkEnabled = false; +bool sHaveBLEConnections = false; + +} // namespace + +namespace LedConsts { +constexpr uint32_t kBlinkRate_ms{ 500 }; +constexpr uint32_t kIdentifyBlinkRate_ms{ 500 }; +namespace StatusLed { +namespace Unprovisioned { +constexpr uint32_t kOn_ms{ 100 }; +constexpr uint32_t kOff_ms{ kOn_ms }; +} // namespace Unprovisioned +namespace Provisioned { +constexpr uint32_t kOn_ms{ 50 }; +constexpr uint32_t kOff_ms{ 950 }; +} // namespace Provisioned + +} // namespace StatusLed +} // namespace LedConsts + +CHIP_ERROR AppTask::Init() +{ + // Initialize CHIP stack + LOG_INF("Init CHIP stack"); + + CHIP_ERROR err = chip::Platform::MemoryInit(); + if (err != CHIP_NO_ERROR) + { + LOG_ERR("Platform::MemoryInit() failed"); + return err; + } + + err = PlatformMgr().InitChipStack(); + if (err != CHIP_NO_ERROR) + { + LOG_ERR("PlatformMgr().InitChipStack() failed"); + return err; + } + +#if defined(CONFIG_NET_L2_OPENTHREAD) + err = ThreadStackMgr().InitThreadStack(); + if (err != CHIP_NO_ERROR) + { + LOG_ERR("ThreadStackMgr().InitThreadStack() failed"); + return err; + } + +#ifdef CONFIG_OPENTHREAD_MTD_SED + err = ConnectivityMgr().SetThreadDeviceType(ConnectivityManager::kThreadDeviceType_SleepyEndDevice); +#else + err = ConnectivityMgr().SetThreadDeviceType(ConnectivityManager::kThreadDeviceType_MinimalEndDevice); +#endif + if (err != CHIP_NO_ERROR) + { + LOG_ERR("ConnectivityMgr().SetThreadDeviceType() failed"); + return err; + } +#else + return CHIP_ERROR_INTERNAL; +#endif // CONFIG_NET_L2_OPENTHREAD + + // Initialize LEDs + LEDWidget::InitGpio(); + LEDWidget::SetStateUpdateCallback(LEDStateUpdateHandler); + + sStatusLED.Init(SYSTEM_STATE_LED); + sIdentifyLED.Init(IDENTIFY_STATE_LED); + sIdentifyLED.Set(false); + + UpdateStatusLED(); + + // Initialize buttons + auto ret = dk_buttons_init(ButtonEventHandler); + if (ret) + { + LOG_ERR("dk_buttons_init() failed"); + return chip::System::MapErrorZephyr(ret); + } + + // Initialize timer user data + k_timer_init(&sFunctionTimer, &AppTask::FunctionTimerTimeoutCallback, nullptr); + k_timer_user_data_set(&sFunctionTimer, this); + +#ifdef CONFIG_CHIP_OTA_REQUESTOR + /* OTA image confirmation must be done before the factory data init. */ + OtaConfirmNewImage(); +#endif + + // Initialize CHIP server +#if CONFIG_CHIP_FACTORY_DATA + ReturnErrorOnFailure(mFactoryDataProvider.Init()); + SetDeviceInstanceInfoProvider(&mFactoryDataProvider); + SetDeviceAttestationCredentialsProvider(&mFactoryDataProvider); + SetCommissionableDataProvider(&mFactoryDataProvider); + // Read EnableKey from the factory data. + MutableByteSpan enableKey(sTestEventTriggerEnableKey); + err = mFactoryDataProvider.GetEnableKey(enableKey); + if (err != CHIP_NO_ERROR) + { + LOG_ERR("mFactoryDataProvider.GetEnableKey() failed. Could not delegate a test event trigger"); + memset(sTestEventTriggerEnableKey, 0, sizeof(sTestEventTriggerEnableKey)); + } +#else + SetDeviceInstanceInfoProvider(&DeviceInstanceInfoProviderMgrImpl()); + SetDeviceAttestationCredentialsProvider(Examples::GetExampleDACProvider()); +#endif + + static CommonCaseDeviceServerInitParams initParams; + static SimpleTestEventTriggerDelegate sTestEventTriggerDelegate{}; + static OTATestEventTriggerHandler sOtaTestEventTriggerHandler{}; + VerifyOrDie(sTestEventTriggerDelegate.Init(ByteSpan(sTestEventTriggerEnableKey)) == CHIP_NO_ERROR); + VerifyOrDie(sTestEventTriggerDelegate.AddHandler(&sOtaTestEventTriggerHandler) == CHIP_NO_ERROR); + (void) initParams.InitializeStaticResourcesBeforeServerInit(); + initParams.testEventTriggerDelegate = &sTestEventTriggerDelegate; + ReturnErrorOnFailure(chip::Server::GetInstance().Init(initParams)); + AppFabricTableDelegate::Init(); + + gExampleDeviceInfoProvider.SetStorageDelegate(&Server::GetInstance().GetPersistentStorage()); + chip::DeviceLayer::SetDeviceInfoProvider(&gExampleDeviceInfoProvider); + ConfigurationMgr().LogDeviceConfig(); + PrintOnboardingCodes(chip::RendezvousInformationFlag(chip::RendezvousInformationFlag::kBLE)); + + // Add CHIP event handler and start CHIP thread. + // Note that all the initialization code should happen prior to this point to avoid data races + // between the main and the CHIP threads + PlatformMgr().AddEventHandler(ChipEventHandler, 0); + err = PlatformMgr().StartEventLoopTask(); + if (err != CHIP_NO_ERROR) + { + LOG_ERR("PlatformMgr().StartEventLoopTask() failed"); + } + + return err; +} + +CHIP_ERROR AppTask::StartApp() +{ + ReturnErrorOnFailure(Init()); + + AppEvent event{}; + + while (true) + { + k_msgq_get(&sAppEventQueue, &event, K_FOREVER); + DispatchEvent(event); + } + + return CHIP_NO_ERROR; +} + +void AppTask::IdentifyStartHandler(Identify *) +{ + AppEvent event; + event.Type = AppEventType::IdentifyStart; + event.Handler = [](const AppEvent &) { sIdentifyLED.Blink(LedConsts::kIdentifyBlinkRate_ms); }; + PostEvent(event); +} + +void AppTask::IdentifyStopHandler(Identify *) +{ + AppEvent event; + event.Type = AppEventType::IdentifyStop; + event.Handler = [](const AppEvent &) { sIdentifyLED.Set(false); }; + PostEvent(event); +} + +void AppTask::ButtonEventHandler(uint32_t buttonState, uint32_t hasChanged) +{ + AppEvent button_event; + button_event.Type = AppEventType::Button; + + if (BLE_ADVERTISEMENT_START_BUTTON_MASK & buttonState & hasChanged) + { + button_event.ButtonEvent.PinNo = BLE_ADVERTISEMENT_START_BUTTON; + button_event.ButtonEvent.Action = static_cast(AppEventType::ButtonPushed); + button_event.Handler = StartBLEAdvertisementHandler; + PostEvent(button_event); + } + + if (FUNCTION_BUTTON_MASK & hasChanged) + { + button_event.ButtonEvent.PinNo = FUNCTION_BUTTON; + button_event.ButtonEvent.Action = + static_cast((FUNCTION_BUTTON_MASK & buttonState) ? AppEventType::ButtonPushed : AppEventType::ButtonReleased); + button_event.Handler = FunctionHandler; + PostEvent(button_event); + } + + if (ICD_UAT_BUTTON_MASK & hasChanged) + { + button_event.ButtonEvent.PinNo = ICD_UAT_BUTTON; + button_event.ButtonEvent.Action = static_cast(AppEventType::ButtonPushed); + button_event.Handler = IcdUatEventHandler; + PostEvent(button_event); + } +} + +void AppTask::IcdUatEventHandler(const AppEvent &) +{ + Server::GetInstance().GetICDManager().UpdateOperationState(ICDManager::OperationalState::ActiveMode); +} + +void AppTask::FunctionTimerTimeoutCallback(k_timer * timer) +{ + if (!timer) + { + return; + } + + AppEvent event; + event.Type = AppEventType::Timer; + event.TimerEvent.Context = k_timer_user_data_get(timer); + event.Handler = FunctionTimerEventHandler; + PostEvent(event); +} + +void AppTask::FunctionTimerEventHandler(const AppEvent & event) +{ + if (event.Type != AppEventType::Timer || !Instance().mFunctionTimerActive) + { + return; + } + + // If we reached here, the button was held past kFactoryResetTriggerTimeout, initiate factory reset + if (Instance().mFunction == FunctionEvent::SoftwareUpdate) + { + LOG_INF("Factory Reset Triggered. Release button within %ums to cancel.", kFactoryResetTriggerTimeout); + + // Start timer for kFactoryResetCancelWindowTimeout to allow user to cancel, if required. + Instance().StartTimer(kFactoryResetCancelWindowTimeout); + Instance().mFunction = FunctionEvent::FactoryReset; + + // Turn off all LEDs before starting blink to make sure blink is coordinated. + sStatusLED.Set(false); + sFactoryResetLEDs.Set(false); + + sStatusLED.Blink(LedConsts::kBlinkRate_ms); + sFactoryResetLEDs.Blink(LedConsts::kBlinkRate_ms); + } + else if (Instance().mFunction == FunctionEvent::FactoryReset) + { + // Actually trigger Factory Reset + Instance().mFunction = FunctionEvent::NoneSelected; + chip::Server::GetInstance().ScheduleFactoryReset(); + } + else if (Instance().mFunction == FunctionEvent::AdvertisingStart) + { + // The button was held past kAdvertisingTriggerTimeout, start BLE advertisement if we have 2 buttons UI + StartBLEAdvertisementHandler(event); + } +} + +void AppTask::FunctionHandler(const AppEvent & event) +{ + if (event.ButtonEvent.PinNo != FUNCTION_BUTTON) + return; + + // To trigger software update: press the FUNCTION_BUTTON button briefly (< FACTORY_RESET_TRIGGER_TIMEOUT) + // To initiate factory reset: press the FUNCTION_BUTTON for FACTORY_RESET_TRIGGER_TIMEOUT + FACTORY_RESET_CANCEL_WINDOW_TIMEOUT + // All LEDs start blinking after FACTORY_RESET_TRIGGER_TIMEOUT to signal factory reset has been initiated. + // To cancel factory reset: release the FUNCTION_BUTTON once all LEDs start blinking within the + // FACTORY_RESET_CANCEL_WINDOW_TIMEOUT + if (event.ButtonEvent.Action == static_cast(AppEventType::ButtonPushed)) + { + if (!Instance().mFunctionTimerActive && Instance().mFunction == FunctionEvent::NoneSelected) + { + Instance().StartTimer(kFactoryResetTriggerTimeout); + + Instance().mFunction = FunctionEvent::SoftwareUpdate; + } + } + else + { + // If the button was released before factory reset got initiated, trigger a software update. + if (Instance().mFunctionTimerActive && Instance().mFunction == FunctionEvent::SoftwareUpdate) + { + Instance().CancelTimer(); + Instance().mFunction = FunctionEvent::NoneSelected; + } + else if (Instance().mFunctionTimerActive && Instance().mFunction == FunctionEvent::FactoryReset) + { + sFactoryResetLEDs.Set(false); + UpdateStatusLED(); + Instance().CancelTimer(); + Instance().mFunction = FunctionEvent::NoneSelected; + LOG_INF("Factory Reset has been Canceled"); + } + } +} + +void AppTask::StartBLEAdvertisementHandler(const AppEvent &) +{ + if (Server::GetInstance().GetFabricTable().FabricCount() != 0) + { + LOG_INF("Matter service BLE advertising not started - device is already commissioned"); + return; + } + + if (ConnectivityMgr().IsBLEAdvertisingEnabled()) + { + LOG_INF("BLE advertising is already enabled"); + return; + } + + if (Server::GetInstance().GetCommissioningWindowManager().OpenBasicCommissioningWindow() != CHIP_NO_ERROR) + { + LOG_ERR("OpenBasicCommissioningWindow() failed"); + } +} + +void AppTask::UpdateLedStateEventHandler(const AppEvent & event) +{ + if (event.Type == AppEventType::UpdateLedState) + { + event.UpdateLedStateEvent.LedWidget->UpdateState(); + } +} + +void AppTask::LEDStateUpdateHandler(LEDWidget & ledWidget) +{ + AppEvent event; + event.Type = AppEventType::UpdateLedState; + event.Handler = UpdateLedStateEventHandler; + event.UpdateLedStateEvent.LedWidget = &ledWidget; + PostEvent(event); +} + +void AppTask::UpdateStatusLED() +{ +#ifdef CONFIG_STATE_LEDS + // Update the status LED. + // + // If IPv6 network and service provisioned, keep the LED On constantly. + // + // If the system has BLE connection(s) until the stage above, THEN blink the LED at an even + // rate of 100ms. + // + // Otherwise, blink the LED for a very short time. + if (sIsNetworkProvisioned && sIsNetworkEnabled) + { + sStatusLED.Set(true); + } + else if (sHaveBLEConnections) + { + sStatusLED.Blink(LedConsts::StatusLed::Unprovisioned::kOn_ms, LedConsts::StatusLed::Unprovisioned::kOff_ms); + } + else + { + sStatusLED.Blink(LedConsts::StatusLed::Provisioned::kOn_ms, LedConsts::StatusLed::Provisioned::kOff_ms); + } +#endif +} + +void AppTask::ChipEventHandler(const ChipDeviceEvent * event, intptr_t /* arg */) +{ + switch (event->Type) + { + case DeviceEventType::kCHIPoBLEAdvertisingChange: +#ifdef CONFIG_CHIP_NFC_COMMISSIONING + if (event->CHIPoBLEAdvertisingChange.Result == kActivity_Started) + { + if (NFCMgr().IsTagEmulationStarted()) + { + LOG_INF("NFC Tag emulation is already started"); + } + else + { + ShareQRCodeOverNFC(chip::RendezvousInformationFlags(chip::RendezvousInformationFlag::kBLE)); + } + } + else if (event->CHIPoBLEAdvertisingChange.Result == kActivity_Stopped) + { + NFCMgr().StopTagEmulation(); + } +#endif + sHaveBLEConnections = ConnectivityMgr().NumBLEConnections() != 0; + UpdateStatusLED(); + break; +#if defined(CONFIG_NET_L2_OPENTHREAD) + case DeviceEventType::kDnssdInitialized: +#if CONFIG_CHIP_OTA_REQUESTOR + InitBasicOTARequestor(); +#endif // CONFIG_CHIP_OTA_REQUESTOR + break; + case DeviceEventType::kThreadStateChange: + sIsNetworkProvisioned = ConnectivityMgr().IsThreadProvisioned(); + sIsNetworkEnabled = ConnectivityMgr().IsThreadEnabled(); + UpdateStatusLED(); + break; +#endif // CONFIG_NET_L2_OPENTHREAD + default: + break; + } +} + +void AppTask::CancelTimer() +{ + k_timer_stop(&sFunctionTimer); + Instance().mFunctionTimerActive = false; +} + +void AppTask::StartTimer(uint32_t aTimeoutInMs) +{ + k_timer_start(&sFunctionTimer, K_MSEC(aTimeoutInMs), K_NO_WAIT); + Instance().mFunctionTimerActive = true; +} + +void AppTask::PostEvent(const AppEvent & event) +{ + if (k_msgq_put(&sAppEventQueue, &event, K_NO_WAIT) != 0) + { + LOG_INF("Failed to post event to app task event queue"); + } +} + +void AppTask::DispatchEvent(const AppEvent & event) +{ + if (event.Handler) + { + event.Handler(event); + } + else + { + LOG_INF("Event received with no handler. Dropping event."); + } +} diff --git a/examples/lit-icd-app/nrfconnect/main/include/AppConfig.h b/examples/lit-icd-app/nrfconnect/main/include/AppConfig.h new file mode 100644 index 00000000000000..26f63f5ec1fa06 --- /dev/null +++ b/examples/lit-icd-app/nrfconnect/main/include/AppConfig.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2024 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include "BoardUtil.h" + +// ---- LIT ICD Application example config ---- + +#define FUNCTION_BUTTON DK_BTN1 +#define FUNCTION_BUTTON_MASK DK_BTN1_MSK +#define ICD_UAT_BUTTON DK_BTN3 +#define ICD_UAT_BUTTON_MASK DK_BTN3_MSK +#define BLE_ADVERTISEMENT_START_BUTTON DK_BTN4 +#define BLE_ADVERTISEMENT_START_BUTTON_MASK DK_BTN4_MSK +#define SYSTEM_STATE_LED DK_LED1 +#define IDENTIFY_STATE_LED DK_LED2 +#define FACTORY_RESET_SIGNAL_LED DK_LED3 +#define FACTORY_RESET_SIGNAL_LED1 DK_LED4 diff --git a/examples/lit-icd-app/nrfconnect/main/include/AppEvent.h b/examples/lit-icd-app/nrfconnect/main/include/AppEvent.h new file mode 100644 index 00000000000000..27ae7408f52e08 --- /dev/null +++ b/examples/lit-icd-app/nrfconnect/main/include/AppEvent.h @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2024 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include + +#include "EventTypes.h" + +class LEDWidget; + +enum class AppEventType : uint8_t +{ + None = 0, + Button, + ButtonPushed, + ButtonReleased, + Timer, + UpdateLedState, + IdentifyStart, + IdentifyStop, +}; + +enum class FunctionEvent : uint8_t +{ + NoneSelected = 0, + SoftwareUpdate = 0, + FactoryReset, + AdvertisingStart +}; + +struct AppEvent +{ + union + { + struct + { + uint8_t PinNo; + uint8_t Action; + } ButtonEvent; + struct + { + void * Context; + } TimerEvent; + struct + { + uint8_t Action; + int32_t Actor; + } LockEvent; + struct + { + LEDWidget * LedWidget; + } UpdateLedStateEvent; + }; + + AppEventType Type{ AppEventType::None }; + EventHandler Handler; +}; diff --git a/examples/lit-icd-app/nrfconnect/main/include/AppTask.h b/examples/lit-icd-app/nrfconnect/main/include/AppTask.h new file mode 100644 index 00000000000000..f1513b2d1e75cb --- /dev/null +++ b/examples/lit-icd-app/nrfconnect/main/include/AppTask.h @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2024 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include + +#include "AppEvent.h" +#include "LEDWidget.h" + +#if CONFIG_CHIP_FACTORY_DATA +#include +#else +#include +#endif + +struct k_timer; +struct Identify; + +class AppTask +{ +public: + static AppTask & Instance(void) + { + static AppTask sAppTask; + return sAppTask; + }; + CHIP_ERROR StartApp(); + + static void IdentifyStartHandler(Identify *); + static void IdentifyStopHandler(Identify *); + + static void PostEvent(const AppEvent & event); + +private: + CHIP_ERROR Init(); + + static void CancelTimer(); + static void StartTimer(uint32_t timeoutInMs); + + static void DispatchEvent(const AppEvent & event); + static void FunctionTimerEventHandler(const AppEvent & event); + static void FunctionHandler(const AppEvent & event); + static void StartBLEAdvertisementHandler(const AppEvent & event); + static void IcdUatEventHandler(const AppEvent & event); + static void UpdateLedStateEventHandler(const AppEvent & event); + + static void ChipEventHandler(const chip::DeviceLayer::ChipDeviceEvent * event, intptr_t arg); + static void ButtonEventHandler(uint32_t buttonState, uint32_t hasChanged); + static void LEDStateUpdateHandler(LEDWidget & ledWidget); + static void FunctionTimerTimeoutCallback(k_timer * timer); + static void UpdateStatusLED(); + + FunctionEvent mFunction = FunctionEvent::NoneSelected; + bool mFunctionTimerActive = false; + +#if CONFIG_CHIP_FACTORY_DATA + chip::DeviceLayer::FactoryDataProvider mFactoryDataProvider; +#endif +}; diff --git a/examples/lit-icd-app/nrfconnect/main/include/CHIPProjectConfig.h b/examples/lit-icd-app/nrfconnect/main/include/CHIPProjectConfig.h new file mode 100644 index 00000000000000..4baa186190f638 --- /dev/null +++ b/examples/lit-icd-app/nrfconnect/main/include/CHIPProjectConfig.h @@ -0,0 +1,28 @@ +/* + * + * Copyright (c) 2020 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * Example project configuration file for CHIP. + * + * This is a place to put application or project-specific overrides + * to the default configuration values for general CHIP features. + * + */ + +#pragma once diff --git a/examples/lit-icd-app/nrfconnect/main/main.cpp b/examples/lit-icd-app/nrfconnect/main/main.cpp new file mode 100644 index 00000000000000..0f9b0451e4284d --- /dev/null +++ b/examples/lit-icd-app/nrfconnect/main/main.cpp @@ -0,0 +1,33 @@ +/* + * + * Copyright (c) 2024 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "AppTask.h" + +#include + +LOG_MODULE_REGISTER(app, CONFIG_CHIP_APP_LOG_LEVEL); + +using namespace ::chip; + +int main() +{ + CHIP_ERROR err = AppTask::Instance().StartApp(); + + LOG_ERR("Exited with code %" CHIP_ERROR_FORMAT, err.Format()); + return err == CHIP_NO_ERROR ? EXIT_SUCCESS : EXIT_FAILURE; +} diff --git a/examples/lit-icd-app/nrfconnect/prj.conf b/examples/lit-icd-app/nrfconnect/prj.conf new file mode 100644 index 00000000000000..950be7c8c394e4 --- /dev/null +++ b/examples/lit-icd-app/nrfconnect/prj.conf @@ -0,0 +1,46 @@ +# +# Copyright (c) 2024 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# This sample uses Kconfig.defaults to set options common for all +# samples. This file should contain only options specific for this sample +# or overrides of default values. + +# Enable CHIP +CONFIG_CHIP=y +CONFIG_CHIP_PROJECT_CONFIG="main/include/CHIPProjectConfig.h" +CONFIG_STD_CPP17=y + +# Add support for LEDs and buttons on Nordic development kits +CONFIG_DK_LIBRARY=y + +# Bluetooth Low Energy configuration +CONFIG_BT_DEVICE_NAME="MatterLIT" + +# Other settings +CONFIG_THREAD_NAME=y +CONFIG_MPU_STACK_GUARD=y +CONFIG_RESET_ON_FATAL_ERROR=n + +# Reduce application size +CONFIG_USE_SEGGER_RTT=n + +# Enable Factory Data feature +CONFIG_CHIP_FACTORY_DATA=y +CONFIG_CHIP_FACTORY_DATA_BUILD=y + +# Enable LIT ICD configuration +CONFIG_CHIP_ENABLE_ICD_SUPPORT=y +CONFIG_CHIP_ICD_LIT_SUPPORT=y diff --git a/examples/lit-icd-app/nrfconnect/prj_no_dfu.conf b/examples/lit-icd-app/nrfconnect/prj_no_dfu.conf new file mode 100644 index 00000000000000..00607e349a31ab --- /dev/null +++ b/examples/lit-icd-app/nrfconnect/prj_no_dfu.conf @@ -0,0 +1,48 @@ +# +# Copyright (c) 2024 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# This sample uses Kconfig.defaults to set options common for all +# samples. This file should contain only options specific for this sample +# or overrides of default values. + +# Enable CHIP +CONFIG_CHIP=y +CONFIG_CHIP_PROJECT_CONFIG="main/include/CHIPProjectConfig.h" +CONFIG_STD_CPP17=y + +# Add support for LEDs and buttons on Nordic development kits +CONFIG_DK_LIBRARY=y + +# Bluetooth Low Energy configuration +CONFIG_BT_DEVICE_NAME="MatterLIT" + +# Other settings +CONFIG_THREAD_NAME=y +CONFIG_MPU_STACK_GUARD=y +CONFIG_RESET_ON_FATAL_ERROR=n + +# Reduce application size +CONFIG_USE_SEGGER_RTT=n + +# Disable Matter OTA DFU +CONFIG_CHIP_OTA_REQUESTOR=n + +# Disable QSPI NOR +CONFIG_CHIP_QSPI_NOR=n + +# Enable LIT ICD configuration +CONFIG_CHIP_ENABLE_ICD_SUPPORT=y +CONFIG_CHIP_ICD_LIT_SUPPORT=y diff --git a/examples/lit-icd-app/nrfconnect/prj_release.conf b/examples/lit-icd-app/nrfconnect/prj_release.conf new file mode 100644 index 00000000000000..61b6b3dfc6f8f8 --- /dev/null +++ b/examples/lit-icd-app/nrfconnect/prj_release.conf @@ -0,0 +1,60 @@ +# +# Copyright (c) 2024 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# This sample uses Kconfig.defaults to set options common for all +# samples. This file should contain only options specific for this sample +# or overrides of default values. + +# Enable CHIP +CONFIG_CHIP=y +CONFIG_CHIP_PROJECT_CONFIG="main/include/CHIPProjectConfig.h" +CONFIG_STD_CPP17=y + +# Add support for LEDs and buttons on Nordic development kits +CONFIG_DK_LIBRARY=y + +# Bluetooth Low Energy configuration +CONFIG_BT_DEVICE_NAME="MatterLIT" + +# Enable system reset on fatal error +CONFIG_RESET_ON_FATAL_ERROR=y + +# Suspend devices when the CPU goes into sleep +CONFIG_PM_DEVICE=y + +# Disable all debug features +CONFIG_USE_SEGGER_RTT=n +CONFIG_SHELL=n +CONFIG_OPENTHREAD_SHELL=n +CONFIG_CONSOLE=n +CONFIG_UART_CONSOLE=n +CONFIG_SERIAL=n +CONFIG_LOG=n +CONFIG_LOG_MODE_MINIMAL=n +CONFIG_ASSERT_VERBOSE=n +CONFIG_ASSERT_NO_FILE_INFO=y +CONFIG_PRINTK=n +CONFIG_PRINTK_SYNC=n +CONFIG_THREAD_NAME=n +CONFIG_BOOT_BANNER=n + +# Enable Factory Data feature +CONFIG_CHIP_FACTORY_DATA=y +CONFIG_CHIP_FACTORY_DATA_BUILD=y + +# Enable LIT ICD configuration +CONFIG_CHIP_ENABLE_ICD_SUPPORT=y +CONFIG_CHIP_ICD_LIT_SUPPORT=y diff --git a/examples/lit-icd-app/nrfconnect/third_party/connectedhomeip b/examples/lit-icd-app/nrfconnect/third_party/connectedhomeip new file mode 120000 index 00000000000000..c866b86874994d --- /dev/null +++ b/examples/lit-icd-app/nrfconnect/third_party/connectedhomeip @@ -0,0 +1 @@ +../../../.. \ No newline at end of file From 1fd60e56f67a077b933e140f1917c36480b31812 Mon Sep 17 00:00:00 2001 From: Justin Wood Date: Mon, 19 Feb 2024 09:22:23 -0800 Subject: [PATCH 29/33] Update cherry-picks.yaml --- .github/workflows/cherry-picks.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/cherry-picks.yaml b/.github/workflows/cherry-picks.yaml index 6d9b5339b40b9e..a062aa5fcf9b87 100644 --- a/.github/workflows/cherry-picks.yaml +++ b/.github/workflows/cherry-picks.yaml @@ -14,7 +14,6 @@ jobs: (github.event.pull_request.merged == true) && ( (contains(github.event.pull_request.labels.*.name, 'sve')) - || (contains(github.event.pull_request.labels.*.name, 'spec')) || (contains(github.event.pull_request.labels.*.name, 'request sve')) || (contains(github.event.pull_request.labels.*.name, 'cert blocker')) ) @@ -27,11 +26,12 @@ jobs: uses: carloscastrojumo/github-cherry-pick-action@v1.0.9 with: token: ${{ secrets.MATTER_PAT }} - branch: sve-2 + branch: 1.3-sve labels: | sve cherry pick reviewers: | woody-apple andy31415 + raju-apple env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} From f5b7a1d54497e9f9838d1b9b590b20334260aa12 Mon Sep 17 00:00:00 2001 From: Arkadiusz Bokowy Date: Mon, 19 Feb 2024 18:27:57 +0100 Subject: [PATCH 30/33] [Linux] Fix BLE infinite advertising (#32093) * [Linux] Fix BLE infinite advertising According to BlueZ documentation, discoverable timeout of 0 should disable the timeout. However, due to a bug, setting timeout to 0 stops advertising immediately after sending ADV frame. * Add comments for commented-out properties * Add comments to D-Bus interfaces which are owned by us * Update the comment so it will be easier to understand the meaning --- .../Linux/bluez/BluezAdvertisement.cpp | 2 +- src/platform/Linux/dbus/bluez/DbusBluez.xml | 42 +++++++++++++++++-- 2 files changed, 40 insertions(+), 4 deletions(-) diff --git a/src/platform/Linux/bluez/BluezAdvertisement.cpp b/src/platform/Linux/bluez/BluezAdvertisement.cpp index db74da8bec1ec4..1b95aae41a4f11 100644 --- a/src/platform/Linux/bluez/BluezAdvertisement.cpp +++ b/src/platform/Linux/bluez/BluezAdvertisement.cpp @@ -65,7 +65,7 @@ BluezLEAdvertisement1 * BluezAdvertisement::CreateLEAdvertisement() // Bluez to set "BR/EDR Not Supported" flag. Bluez doesn't provide API to do that explicitly // and the flag is necessary to force using LE transport. bluez_leadvertisement1_set_discoverable(adv, TRUE); - bluez_leadvertisement1_set_discoverable_timeout(adv, 0 /* infinite */); + // empty discoverable timeout for infinite discoverability // empty includes bluez_leadvertisement1_set_local_name(adv, mAdvName); diff --git a/src/platform/Linux/dbus/bluez/DbusBluez.xml b/src/platform/Linux/dbus/bluez/DbusBluez.xml index 00887dc5e147a9..0a42da708d50a9 100644 --- a/src/platform/Linux/dbus/bluez/DbusBluez.xml +++ b/src/platform/Linux/dbus/bluez/DbusBluez.xml @@ -108,6 +108,10 @@ + @@ -115,6 +119,10 @@ + @@ -152,6 +160,10 @@ + @@ -172,6 +184,10 @@ + @@ -183,13 +199,33 @@ + - - - + + + From d2ed79c086f62e6355c38eb9ce99bd1d28bbb4a5 Mon Sep 17 00:00:00 2001 From: Vivien Nicolas Date: Mon, 19 Feb 2024 18:29:12 +0100 Subject: [PATCH 31/33] [DiagnosticLogs] When the size of the logs for the target intent is 0, the server returns Exhausted instead of NoLogs (#32205) --- .../diagnostic-logs-server/diagnostic-logs-server.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/app/clusters/diagnostic-logs-server/diagnostic-logs-server.cpp b/src/app/clusters/diagnostic-logs-server/diagnostic-logs-server.cpp index 95d9a332819ae3..83beb46484bb71 100644 --- a/src/app/clusters/diagnostic-logs-server/diagnostic-logs-server.cpp +++ b/src/app/clusters/diagnostic-logs-server/diagnostic-logs-server.cpp @@ -115,6 +115,9 @@ void DiagnosticLogsServer::HandleLogRequestForResponsePayload(CommandHandler * c Optional timeStamp; Optional timeSinceBoot; + auto size = delegate->GetSizeForIntent(intent); + VerifyOrReturn(size != 0, AddResponse(commandObj, path, StatusEnum::kNoLogs)); + auto err = delegate->GetLogForIntent(intent, logContent, timeStamp, timeSinceBoot); VerifyOrReturn(CHIP_ERROR_NOT_FOUND != err, AddResponse(commandObj, path, StatusEnum::kNoLogs)); VerifyOrReturn(CHIP_NO_ERROR == err, AddResponse(commandObj, path, StatusEnum::kDenied)); @@ -136,10 +139,13 @@ void DiagnosticLogsServer::HandleLogRequestForBdx(CommandHandler * commandObj, c auto * delegate = GetDiagnosticLogsProviderDelegate(path.mEndpointId); VerifyOrReturn(nullptr != delegate, AddResponse(commandObj, path, StatusEnum::kNoLogs)); + auto size = delegate->GetSizeForIntent(intent); + // In the case where the size is 0 sets the Status field of the RetrieveLogsResponse to NoLogs and do not start a BDX session. + VerifyOrReturn(size != 0, HandleLogRequestForResponsePayload(commandObj, path, intent, StatusEnum::kNoLogs)); + // In the case where the Node is able to fit the entirety of the requested logs within the LogContent field, the Status field of // the RetrieveLogsResponse SHALL be set to Exhausted and a BDX session SHALL NOT be initiated. - VerifyOrReturn(delegate->GetSizeForIntent(intent) > kMaxLogContentSize, - HandleLogRequestForResponsePayload(commandObj, path, intent, StatusEnum::kExhausted)); + VerifyOrReturn(size > kMaxLogContentSize, HandleLogRequestForResponsePayload(commandObj, path, intent, StatusEnum::kExhausted)); // If the RequestedProtocol is set to BDX and either the Node does not support BDX or it is not possible for the Node // to establish a BDX session, then the Node SHALL utilize the LogContent field of the RetrieveLogsResponse command From a5be64326e57636795d2cef5390832708097075a Mon Sep 17 00:00:00 2001 From: Vivien Nicolas Date: Mon, 19 Feb 2024 18:29:26 +0100 Subject: [PATCH 32/33] [DiagnosticLogs] When the size of the TransferFileDesignator is 0, the server should returns CONSTRAINT_ERROR (#32207) --- .../clusters/diagnostic-logs-server/diagnostic-logs-server.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/app/clusters/diagnostic-logs-server/diagnostic-logs-server.cpp b/src/app/clusters/diagnostic-logs-server/diagnostic-logs-server.cpp index 83beb46484bb71..7b1b036ee4857b 100644 --- a/src/app/clusters/diagnostic-logs-server/diagnostic-logs-server.cpp +++ b/src/app/clusters/diagnostic-logs-server/diagnostic-logs-server.cpp @@ -132,6 +132,8 @@ void DiagnosticLogsServer::HandleLogRequestForBdx(CommandHandler * commandObj, c // INVALID_COMMAND. VerifyOrReturn(transferFileDesignator.HasValue(), commandObj->AddStatus(path, Status::InvalidCommand)); + VerifyOrReturn(transferFileDesignator.Value().size() > 0, commandObj->AddStatus(path, Status::ConstraintError)); + VerifyOrReturn(transferFileDesignator.Value().size() <= kMaxFileDesignatorLen, commandObj->AddStatus(path, Status::ConstraintError)); From 73d827cada19badc12f7e849fb08dd44860ad6ac Mon Sep 17 00:00:00 2001 From: Arkadiusz Bokowy Date: Mon, 19 Feb 2024 18:34:33 +0100 Subject: [PATCH 33/33] [Linux] Lock CHIP stack before calling WiFi diagnostic delegate (#32137) * Get rid of static functions by wrapping glib callbacks with lambda * Get rid of the rest of static functions * Keep sWiFiIfName as an instance member * Lock CHIP stack before calling WiFi diagnostic delegate * Do not use sInstance internally in ConnectivityManagerImpl * Fix signatures for properties-changed and scan-done callbacks * Keep all members of ConnectivityManagerImpl as instance members * Fix freeing char objects allocated by glib * Restyled by clang-format * Fix compilation warnings --------- Co-authored-by: Restyled.io --- .../Linux/ConnectivityManagerImpl.cpp | 200 +++++++++++------- src/platform/Linux/ConnectivityManagerImpl.h | 56 ++--- src/platform/Linux/PlatformManagerImpl.cpp | 4 +- 3 files changed, 152 insertions(+), 108 deletions(-) diff --git a/src/platform/Linux/ConnectivityManagerImpl.cpp b/src/platform/Linux/ConnectivityManagerImpl.cpp index d03cefef4f0ef7..eef7ce883f0042 100644 --- a/src/platform/Linux/ConnectivityManagerImpl.cpp +++ b/src/platform/Linux/ConnectivityManagerImpl.cpp @@ -98,15 +98,6 @@ namespace DeviceLayer { ConnectivityManagerImpl ConnectivityManagerImpl::sInstance; -#if CHIP_DEVICE_CONFIG_ENABLE_WIFI -char ConnectivityManagerImpl::sWiFiIfName[]; -#endif - -WiFiDriver::ScanCallback * ConnectivityManagerImpl::mpScanCallback; -NetworkCommissioning::Internal::WirelessDriver::ConnectCallback * ConnectivityManagerImpl::mpConnectCallback; -uint8_t ConnectivityManagerImpl::sInterestedSSID[Internal::kMaxWiFiSSIDLength]; -uint8_t ConnectivityManagerImpl::sInterestedSSIDLen; - CHIP_ERROR ConnectivityManagerImpl::_Init() { #if CHIP_DEVICE_CONFIG_ENABLE_WPA @@ -166,12 +157,6 @@ void ConnectivityManagerImpl::_OnPlatformEvent(const ChipDeviceEvent * event) #if CHIP_DEVICE_CONFIG_ENABLE_WPA -bool ConnectivityManagerImpl::mAssociationStarted = false; -BitFlags::ConnectivityFlags> - ConnectivityManagerImpl::mConnectivityFlag; -struct GDBusWpaSupplicant ConnectivityManagerImpl::mWpaSupplicant; -std::mutex ConnectivityManagerImpl::mWpaSupplicantMutex; - ConnectivityManager::WiFiStationMode ConnectivityManagerImpl::_GetWiFiStationMode() { if (mWiFiStationMode != kWiFiStationMode_ApplicationControlled) @@ -313,7 +298,7 @@ CHIP_ERROR ConnectivityManagerImpl::_SetWiFiAPMode(WiFiAPMode val) ChipLogProgress(DeviceLayer, "WiFi AP mode change: %s -> %s", WiFiAPModeToStr(mWiFiAPMode), WiFiAPModeToStr(val)); mWiFiAPMode = val; - DeviceLayer::SystemLayer().ScheduleWork(DriveAPState, nullptr); + DeviceLayer::SystemLayer().ScheduleLambda([this] { DriveAPState(); }); } exit: @@ -326,7 +311,7 @@ void ConnectivityManagerImpl::_DemandStartWiFiAP() { ChipLogProgress(DeviceLayer, "wpa_supplicant: Demand start WiFi AP"); mLastAPDemandTime = System::SystemClock().GetMonotonicTimestamp(); - DeviceLayer::SystemLayer().ScheduleWork(DriveAPState, nullptr); + DeviceLayer::SystemLayer().ScheduleLambda([this] { DriveAPState(); }); } else { @@ -340,7 +325,7 @@ void ConnectivityManagerImpl::_StopOnDemandWiFiAP() { ChipLogProgress(DeviceLayer, "wpa_supplicant: Demand stop WiFi AP"); mLastAPDemandTime = System::Clock::kZero; - DeviceLayer::SystemLayer().ScheduleWork(DriveAPState, nullptr); + DeviceLayer::SystemLayer().ScheduleLambda([this] { DriveAPState(); }); } else { @@ -362,7 +347,7 @@ void ConnectivityManagerImpl::_MaintainOnDemandWiFiAP() void ConnectivityManagerImpl::_SetWiFiAPIdleTimeout(System::Clock::Timeout val) { mWiFiAPIdleTimeout = val; - DeviceLayer::SystemLayer().ScheduleWork(DriveAPState, nullptr); + DeviceLayer::SystemLayer().ScheduleLambda([this] { DriveAPState(); }); } void ConnectivityManagerImpl::UpdateNetworkStatus() @@ -391,12 +376,11 @@ void ConnectivityManagerImpl::UpdateNetworkStatus() MakeOptional(GetDisconnectReason())); } -void ConnectivityManagerImpl::_OnWpaPropertiesChanged(WpaFiW1Wpa_supplicant1Interface * proxy, GVariant * changed_properties, - const gchar * const * invalidated_properties, gpointer user_data) +void ConnectivityManagerImpl::_OnWpaPropertiesChanged(WpaFiW1Wpa_supplicant1Interface * proxy, GVariant * changedProperties) { std::lock_guard lock(mWpaSupplicantMutex); - if (g_variant_n_children(changed_properties) > 0) + if (g_variant_n_children(changedProperties) > 0) { GAutoPtr iter; const gchar * key; @@ -404,7 +388,7 @@ void ConnectivityManagerImpl::_OnWpaPropertiesChanged(WpaFiW1Wpa_supplicant1Inte WiFiDiagnosticsDelegate * delegate = GetDiagnosticDataProvider().GetWiFiDiagnosticsDelegate(); - g_variant_get(changed_properties, "a{sv}", &MakeUniquePointerReceiver(iter).Get()); + g_variant_get(changedProperties, "a{sv}", &MakeUniquePointerReceiver(iter).Get()); while (g_variant_iter_loop(iter.get(), "{&sv}", &key, &value)) { @@ -424,6 +408,7 @@ void ConnectivityManagerImpl::_OnWpaPropertiesChanged(WpaFiW1Wpa_supplicant1Inte if (delegate) { + chip::DeviceLayer::StackLock stackLock; delegate->OnDisconnectionDetected(reason); delegate->OnConnectionStatusChanged(static_cast(ConnectionStatusEnum::kConnected)); } @@ -453,7 +438,7 @@ void ConnectivityManagerImpl::_OnWpaPropertiesChanged(WpaFiW1Wpa_supplicant1Inte break; } - DeviceLayer::SystemLayer().ScheduleLambda([reason]() { + DeviceLayer::SystemLayer().ScheduleLambda([this, reason]() { if (mpConnectCallback != nullptr) { mpConnectCallback->OnResult(NetworkCommissioning::Status::kUnknownError, CharSpan(), reason); @@ -463,6 +448,7 @@ void ConnectivityManagerImpl::_OnWpaPropertiesChanged(WpaFiW1Wpa_supplicant1Inte if (delegate) { + chip::DeviceLayer::StackLock stackLock; delegate->OnAssociationFailureDetected(associationFailureCause, status); } } @@ -475,6 +461,7 @@ void ConnectivityManagerImpl::_OnWpaPropertiesChanged(WpaFiW1Wpa_supplicant1Inte { if (delegate) { + chip::DeviceLayer::StackLock stackLock; delegate->OnConnectionStatusChanged(static_cast(ConnectionStatusEnum::kNotConnected)); } @@ -484,7 +471,7 @@ void ConnectivityManagerImpl::_OnWpaPropertiesChanged(WpaFiW1Wpa_supplicant1Inte { if (mAssociationStarted) { - DeviceLayer::SystemLayer().ScheduleLambda([]() { + DeviceLayer::SystemLayer().ScheduleLambda([this]() { if (mpConnectCallback != nullptr) { mpConnectCallback->OnResult(NetworkCommissioning::Status::kSuccess, CharSpan(), 0); @@ -500,7 +487,7 @@ void ConnectivityManagerImpl::_OnWpaPropertiesChanged(WpaFiW1Wpa_supplicant1Inte } } -void ConnectivityManagerImpl::_OnWpaInterfaceProxyReady(GObject * source_object, GAsyncResult * res, gpointer user_data) +void ConnectivityManagerImpl::_OnWpaInterfaceProxyReady(GObject * sourceObject, GAsyncResult * res) { // When creating D-Bus proxy object, the thread default context must be initialized. Otherwise, // all D-Bus signals will be delivered to the GLib global default main context. @@ -525,8 +512,17 @@ void ConnectivityManagerImpl::_OnWpaInterfaceProxyReady(GObject * source_object, mWpaSupplicant.state = GDBusWpaSupplicant::WPA_INTERFACE_CONNECTED; ChipLogProgress(DeviceLayer, "wpa_supplicant: connected to wpa_supplicant interface proxy"); - g_signal_connect(mWpaSupplicant.iface, "properties-changed", G_CALLBACK(_OnWpaPropertiesChanged), NULL); - g_signal_connect(mWpaSupplicant.iface, "scan-done", G_CALLBACK(_OnWpaInterfaceScanDone), NULL); + g_signal_connect( + mWpaSupplicant.iface, "properties-changed", + G_CALLBACK(+[](WpaFiW1Wpa_supplicant1Interface * proxy, GVariant * properties, ConnectivityManagerImpl * self) { + return self->_OnWpaPropertiesChanged(proxy, properties); + }), + this); + g_signal_connect(mWpaSupplicant.iface, "scan-done", + G_CALLBACK(+[](WpaFiW1Wpa_supplicant1Interface * proxy, gboolean success, ConnectivityManagerImpl * self) { + return self->_OnWpaInterfaceScanDone(proxy, success); + }), + this); } else { @@ -537,7 +533,7 @@ void ConnectivityManagerImpl::_OnWpaInterfaceProxyReady(GObject * source_object, } // We need to stop auto scan or it will block our network scan. - DeviceLayer::SystemLayer().ScheduleLambda([]() { + DeviceLayer::SystemLayer().ScheduleLambda([this]() { CHIP_ERROR errInner = StopAutoScan(); if (errInner != CHIP_NO_ERROR) { @@ -546,7 +542,7 @@ void ConnectivityManagerImpl::_OnWpaInterfaceProxyReady(GObject * source_object, }); } -void ConnectivityManagerImpl::_OnWpaBssProxyReady(GObject * source_object, GAsyncResult * res, gpointer user_data) +void ConnectivityManagerImpl::_OnWpaBssProxyReady(GObject * sourceObject, GAsyncResult * res) { // When creating D-Bus proxy object, the thread default context must be initialized. Otherwise, // all D-Bus signals will be delivered to the GLib global default main context. @@ -577,7 +573,7 @@ void ConnectivityManagerImpl::_OnWpaBssProxyReady(GObject * source_object, GAsyn } } -void ConnectivityManagerImpl::_OnWpaInterfaceReady(GObject * source_object, GAsyncResult * res, gpointer user_data) +void ConnectivityManagerImpl::_OnWpaInterfaceReady(GObject * sourceObject, GAsyncResult * res) { // When creating D-Bus proxy object, the thread default context must be initialized. Otherwise, // all D-Bus signals will be delivered to the GLib global default main context. @@ -594,12 +590,21 @@ void ConnectivityManagerImpl::_OnWpaInterfaceReady(GObject * source_object, GAsy mWpaSupplicant.state = GDBusWpaSupplicant::WPA_GOT_INTERFACE_PATH; ChipLogProgress(DeviceLayer, "wpa_supplicant: WiFi interface: %s", mWpaSupplicant.interfacePath); - wpa_fi_w1_wpa_supplicant1_interface_proxy_new_for_bus(G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE, kWpaSupplicantServiceName, - mWpaSupplicant.interfacePath, nullptr, _OnWpaInterfaceProxyReady, - nullptr); - - wpa_fi_w1_wpa_supplicant1_bss_proxy_new_for_bus(G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE, kWpaSupplicantServiceName, - mWpaSupplicant.interfacePath, nullptr, _OnWpaBssProxyReady, nullptr); + wpa_fi_w1_wpa_supplicant1_interface_proxy_new_for_bus( + G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE, kWpaSupplicantServiceName, mWpaSupplicant.interfacePath, nullptr, + reinterpret_cast( + +[](GObject * sourceObject_, GAsyncResult * res_, ConnectivityManagerImpl * self) { + return self->_OnWpaInterfaceProxyReady(sourceObject_, res_); + }), + this); + + wpa_fi_w1_wpa_supplicant1_bss_proxy_new_for_bus( + G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE, kWpaSupplicantServiceName, mWpaSupplicant.interfacePath, nullptr, + reinterpret_cast( + +[](GObject * sourceObject_, GAsyncResult * res_, ConnectivityManagerImpl * self) { + return self->_OnWpaBssProxyReady(sourceObject_, res_); + }), + this); } else { @@ -626,12 +631,21 @@ void ConnectivityManagerImpl::_OnWpaInterfaceReady(GObject * source_object, GAsy Platform::CopyString(sWiFiIfName, CHIP_DEVICE_CONFIG_WIFI_STATION_IF_NAME); - wpa_fi_w1_wpa_supplicant1_interface_proxy_new_for_bus(G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE, - kWpaSupplicantServiceName, mWpaSupplicant.interfacePath, nullptr, - _OnWpaInterfaceProxyReady, nullptr); - - wpa_fi_w1_wpa_supplicant1_bss_proxy_new_for_bus(G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE, kWpaSupplicantServiceName, - mWpaSupplicant.interfacePath, nullptr, _OnWpaBssProxyReady, nullptr); + wpa_fi_w1_wpa_supplicant1_interface_proxy_new_for_bus( + G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE, kWpaSupplicantServiceName, mWpaSupplicant.interfacePath, nullptr, + reinterpret_cast( + +[](GObject * sourceObject_, GAsyncResult * res_, ConnectivityManagerImpl * self) { + return self->_OnWpaInterfaceProxyReady(sourceObject_, res_); + }), + this); + + wpa_fi_w1_wpa_supplicant1_bss_proxy_new_for_bus( + G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE, kWpaSupplicantServiceName, mWpaSupplicant.interfacePath, nullptr, + reinterpret_cast( + +[](GObject * sourceObject_, GAsyncResult * res_, ConnectivityManagerImpl * self) { + return self->_OnWpaBssProxyReady(sourceObject_, res_); + }), + this); } else { @@ -649,8 +663,7 @@ void ConnectivityManagerImpl::_OnWpaInterfaceReady(GObject * source_object, GAsy } } -void ConnectivityManagerImpl::_OnWpaInterfaceAdded(WpaFiW1Wpa_supplicant1 * proxy, const gchar * path, GVariant * properties, - gpointer user_data) +void ConnectivityManagerImpl::_OnWpaInterfaceAdded(WpaFiW1Wpa_supplicant1 * proxy, const char * path, GVariant * properties) { // When creating D-Bus proxy object, the thread default context must be initialized. Otherwise, // all D-Bus signals will be delivered to the GLib global default main context. @@ -669,17 +682,25 @@ void ConnectivityManagerImpl::_OnWpaInterfaceAdded(WpaFiW1Wpa_supplicant1 * prox mWpaSupplicant.state = GDBusWpaSupplicant::WPA_GOT_INTERFACE_PATH; ChipLogProgress(DeviceLayer, "wpa_supplicant: WiFi interface added: %s", mWpaSupplicant.interfacePath); - wpa_fi_w1_wpa_supplicant1_interface_proxy_new_for_bus(G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE, kWpaSupplicantServiceName, - mWpaSupplicant.interfacePath, nullptr, _OnWpaInterfaceProxyReady, - nullptr); - - wpa_fi_w1_wpa_supplicant1_bss_proxy_new_for_bus(G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE, kWpaSupplicantServiceName, - mWpaSupplicant.interfacePath, nullptr, _OnWpaBssProxyReady, nullptr); + wpa_fi_w1_wpa_supplicant1_interface_proxy_new_for_bus( + G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE, kWpaSupplicantServiceName, mWpaSupplicant.interfacePath, nullptr, + reinterpret_cast( + +[](GObject * sourceObject_, GAsyncResult * res_, ConnectivityManagerImpl * self) { + return self->_OnWpaInterfaceProxyReady(sourceObject_, res_); + }), + this); + + wpa_fi_w1_wpa_supplicant1_bss_proxy_new_for_bus( + G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE, kWpaSupplicantServiceName, mWpaSupplicant.interfacePath, nullptr, + reinterpret_cast( + +[](GObject * sourceObject_, GAsyncResult * res_, ConnectivityManagerImpl * self) { + return self->_OnWpaBssProxyReady(sourceObject_, res_); + }), + this); } } -void ConnectivityManagerImpl::_OnWpaInterfaceRemoved(WpaFiW1Wpa_supplicant1 * proxy, const gchar * path, GVariant * properties, - gpointer user_data) +void ConnectivityManagerImpl::_OnWpaInterfaceRemoved(WpaFiW1Wpa_supplicant1 * proxy, const char * path, GVariant * properties) { std::lock_guard lock(mWpaSupplicantMutex); @@ -716,7 +737,7 @@ void ConnectivityManagerImpl::_OnWpaInterfaceRemoved(WpaFiW1Wpa_supplicant1 * pr } } -void ConnectivityManagerImpl::_OnWpaProxyReady(GObject * source_object, GAsyncResult * res, gpointer user_data) +void ConnectivityManagerImpl::_OnWpaProxyReady(GObject * sourceObject, GAsyncResult * res) { // When creating D-Bus proxy object, the thread default context must be initialized. Otherwise, // all D-Bus signals will be delivered to the GLib global default main context. @@ -732,11 +753,24 @@ void ConnectivityManagerImpl::_OnWpaProxyReady(GObject * source_object, GAsyncRe mWpaSupplicant.state = GDBusWpaSupplicant::WPA_CONNECTED; ChipLogProgress(DeviceLayer, "wpa_supplicant: connected to wpa_supplicant proxy"); - g_signal_connect(mWpaSupplicant.proxy, "interface-added", G_CALLBACK(_OnWpaInterfaceAdded), NULL); - - g_signal_connect(mWpaSupplicant.proxy, "interface-removed", G_CALLBACK(_OnWpaInterfaceRemoved), NULL); - - wpa_fi_w1_wpa_supplicant1_call_get_interface(mWpaSupplicant.proxy, sWiFiIfName, nullptr, _OnWpaInterfaceReady, nullptr); + g_signal_connect( + mWpaSupplicant.proxy, "interface-added", + G_CALLBACK(+[](WpaFiW1Wpa_supplicant1 * proxy, const char * path, GVariant * properties, + ConnectivityManagerImpl * self) { return self->_OnWpaInterfaceAdded(proxy, path, properties); }), + this); + g_signal_connect( + mWpaSupplicant.proxy, "interface-removed", + G_CALLBACK(+[](WpaFiW1Wpa_supplicant1 * proxy, const char * path, GVariant * properties, + ConnectivityManagerImpl * self) { return self->_OnWpaInterfaceRemoved(proxy, path, properties); }), + this); + + wpa_fi_w1_wpa_supplicant1_call_get_interface( + mWpaSupplicant.proxy, sWiFiIfName, nullptr, + reinterpret_cast( + +[](GObject * sourceObject_, GAsyncResult * res_, ConnectivityManagerImpl * self) { + return self->_OnWpaInterfaceReady(sourceObject_, res_); + }), + this); } else { @@ -753,7 +787,8 @@ void ConnectivityManagerImpl::StartWiFiManagement() mConnectivityFlag.ClearAll(); mWpaSupplicant = GDBusWpaSupplicant{}; - CHIP_ERROR err = PlatformMgrImpl().GLibMatterContextInvokeSync(_StartWiFiManagement, this); + CHIP_ERROR err = PlatformMgrImpl().GLibMatterContextInvokeSync( + +[](ConnectivityManagerImpl * self) { return self->_StartWiFiManagement(); }, this); VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(DeviceLayer, "Failed to start WiFi management")); } @@ -829,7 +864,7 @@ void ConnectivityManagerImpl::DriveAPState() // Compute the amount of idle time before the AP should be deactivated and // arm a timer to fire at that time. System::Clock::Timeout apTimeout = (mLastAPDemandTime + mWiFiAPIdleTimeout) - now; - err = DeviceLayer::SystemLayer().StartTimer(apTimeout, DriveAPState, nullptr); + err = DeviceLayer::SystemLayer().StartTimer(apTimeout, DriveAPState, this); SuccessOrExit(err); ChipLogProgress(DeviceLayer, "Next WiFi AP timeout in %" PRIu32 " s", std::chrono::duration_cast(apTimeout).count()); @@ -916,7 +951,7 @@ CHIP_ERROR ConnectivityManagerImpl::ConfigureWiFiAP() // Clean up current network if exists if (mWpaSupplicant.networkPath) { - g_object_unref(mWpaSupplicant.networkPath); + g_free(mWpaSupplicant.networkPath); mWpaSupplicant.networkPath = nullptr; } @@ -956,7 +991,7 @@ CHIP_ERROR ConnectivityManagerImpl::ConfigureWiFiAP() if (mWpaSupplicant.networkPath) { - g_object_unref(mWpaSupplicant.networkPath); + g_free(mWpaSupplicant.networkPath); mWpaSupplicant.networkPath = nullptr; } @@ -977,7 +1012,7 @@ void ConnectivityManagerImpl::ChangeWiFiAPState(WiFiAPState newState) void ConnectivityManagerImpl::DriveAPState(::chip::System::Layer * aLayer, void * aAppState) { - sInstance.DriveAPState(); + reinterpret_cast(aAppState)->DriveAPState(); } CHIP_ERROR @@ -1030,8 +1065,14 @@ ConnectivityManagerImpl::_ConnectWiFiNetworkAsync(GVariant * args, wpa_fi_w1_wpa_supplicant1_interface_call_disconnect_sync(mWpaSupplicant.iface, nullptr, nullptr); ChipLogProgress(DeviceLayer, "wpa_supplicant: added network: %s", mWpaSupplicant.networkPath); - wpa_fi_w1_wpa_supplicant1_interface_call_select_network(mWpaSupplicant.iface, mWpaSupplicant.networkPath, nullptr, - _ConnectWiFiNetworkAsyncCallback, this); + wpa_fi_w1_wpa_supplicant1_interface_call_select_network( + mWpaSupplicant.iface, mWpaSupplicant.networkPath, nullptr, + reinterpret_cast( + +[](GObject * sourceObject_, GAsyncResult * res_, ConnectivityManagerImpl * self) { + return self->_ConnectWiFiNetworkAsyncCallback(sourceObject_, res_); + }), + this); + mpConnectCallback = apCallback; } else @@ -1040,7 +1081,7 @@ ConnectivityManagerImpl::_ConnectWiFiNetworkAsync(GVariant * args, if (mWpaSupplicant.networkPath) { - g_object_unref(mWpaSupplicant.networkPath); + g_free(mWpaSupplicant.networkPath); mWpaSupplicant.networkPath = nullptr; } @@ -1191,9 +1232,8 @@ CHIP_ERROR ConnectivityManagerImpl::ConnectWiFiNetworkWithPDCAsync( } #endif // CHIP_DEVICE_CONFIG_ENABLE_WIFI_PDC -void ConnectivityManagerImpl::_ConnectWiFiNetworkAsyncCallback(GObject * source_object, GAsyncResult * res, gpointer user_data) +void ConnectivityManagerImpl::_ConnectWiFiNetworkAsyncCallback(GObject * sourceObject, GAsyncResult * res) { - ConnectivityManagerImpl * this_ = reinterpret_cast(user_data); GAutoPtr err; std::lock_guard lock(mWpaSupplicantMutex); @@ -1204,12 +1244,12 @@ void ConnectivityManagerImpl::_ConnectWiFiNetworkAsyncCallback(GObject * source_ if (!result) { ChipLogError(DeviceLayer, "Failed to perform connect network: %s", err == nullptr ? "unknown error" : err->message); - DeviceLayer::SystemLayer().ScheduleLambda([this_]() { + DeviceLayer::SystemLayer().ScheduleLambda([this]() { if (mpConnectCallback != nullptr) { // TODO(#14175): Replace this with actual thread attach result. - this_->mpConnectCallback->OnResult(NetworkCommissioning::Status::kUnknownError, CharSpan(), 0); - this_->mpConnectCallback = nullptr; + mpConnectCallback->OnResult(NetworkCommissioning::Status::kUnknownError, CharSpan(), 0); + mpConnectCallback = nullptr; } mpConnectCallback = nullptr; }); @@ -1796,7 +1836,7 @@ bool ConnectivityManagerImpl::_GetBssInfo(const gchar * bssPath, NetworkCommissi return true; } -void ConnectivityManagerImpl::_OnWpaInterfaceScanDone(GObject * source_object, GAsyncResult * res, gpointer user_data) +void ConnectivityManagerImpl::_OnWpaInterfaceScanDone(WpaFiW1Wpa_supplicant1Interface * proxy, gboolean success) { std::lock_guard lock(mWpaSupplicantMutex); @@ -1806,7 +1846,7 @@ void ConnectivityManagerImpl::_OnWpaInterfaceScanDone(GObject * source_object, G if (bsss == nullptr) { ChipLogProgress(DeviceLayer, "wpa_supplicant: no network found"); - DeviceLayer::SystemLayer().ScheduleLambda([]() { + DeviceLayer::SystemLayer().ScheduleLambda([this]() { if (mpScanCallback != nullptr) { mpScanCallback->OnFinished(Status::kSuccess, CharSpan(), nullptr); @@ -1833,7 +1873,7 @@ void ConnectivityManagerImpl::_OnWpaInterfaceScanDone(GObject * source_object, G } } - DeviceLayer::SystemLayer().ScheduleLambda([networkScanned]() { + DeviceLayer::SystemLayer().ScheduleLambda([this, networkScanned]() { // Note: We cannot post a event in ScheduleLambda since std::vector is not trivial copiable. This results in the use of // const_cast but should be fine for almost all cases, since we actually handled the ownership of this element to this // lambda. @@ -1850,15 +1890,19 @@ void ConnectivityManagerImpl::_OnWpaInterfaceScanDone(GObject * source_object, G g_strfreev(oldBsss); } -CHIP_ERROR ConnectivityManagerImpl::_StartWiFiManagement(ConnectivityManagerImpl * self) +CHIP_ERROR ConnectivityManagerImpl::_StartWiFiManagement() { // When creating D-Bus proxy object, the thread default context must be initialized. Otherwise, // all D-Bus signals will be delivered to the GLib global default main context. VerifyOrDie(g_main_context_get_thread_default() != nullptr); ChipLogProgress(DeviceLayer, "wpa_supplicant: Start WiFi management"); - wpa_fi_w1_wpa_supplicant1_proxy_new_for_bus(G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE, kWpaSupplicantServiceName, - kWpaSupplicantObjectPath, nullptr, self->_OnWpaProxyReady, nullptr); + wpa_fi_w1_wpa_supplicant1_proxy_new_for_bus( + G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE, kWpaSupplicantServiceName, kWpaSupplicantObjectPath, nullptr, + reinterpret_cast(+[](GObject * sourceObject_, GAsyncResult * res_, ConnectivityManagerImpl * self) { + return self->_OnWpaProxyReady(sourceObject_, res_); + }), + this); return CHIP_NO_ERROR; } diff --git a/src/platform/Linux/ConnectivityManagerImpl.h b/src/platform/Linux/ConnectivityManagerImpl.h index 930b84fb4d455b..26d6172ad438eb 100644 --- a/src/platform/Linux/ConnectivityManagerImpl.h +++ b/src/platform/Linux/ConnectivityManagerImpl.h @@ -155,14 +155,14 @@ class ConnectivityManagerImpl final : public ConnectivityManager, CHIP_ERROR _ConnectWiFiNetworkAsync(GVariant * networkArgs, NetworkCommissioning::Internal::WirelessDriver::ConnectCallback * connectCallback) CHIP_REQUIRES(mWpaSupplicantMutex); - static void _ConnectWiFiNetworkAsyncCallback(GObject * source_object, GAsyncResult * res, gpointer user_data); + void _ConnectWiFiNetworkAsyncCallback(GObject * sourceObject, GAsyncResult * res); #endif public: const char * GetEthernetIfName() { return (mEthIfName[0] == '\0') ? nullptr : mEthIfName; } #if CHIP_DEVICE_CONFIG_ENABLE_WIFI - static const char * GetWiFiIfName() { return (sWiFiIfName[0] == '\0') ? nullptr : sWiFiIfName; } + const char * GetWiFiIfName() { return (sWiFiIfName[0] == '\0') ? nullptr : sWiFiIfName; } #endif private: @@ -205,29 +205,27 @@ class ConnectivityManagerImpl final : public ConnectivityManager, System::Clock::Timeout _GetWiFiAPIdleTimeout(); void _SetWiFiAPIdleTimeout(System::Clock::Timeout val); void UpdateNetworkStatus(); - static CHIP_ERROR StopAutoScan(); - - static void _OnWpaProxyReady(GObject * source_object, GAsyncResult * res, gpointer user_data); - static void _OnWpaInterfaceRemoved(WpaFiW1Wpa_supplicant1 * proxy, const gchar * path, GVariant * properties, - gpointer user_data); - static void _OnWpaInterfaceAdded(WpaFiW1Wpa_supplicant1 * proxy, const gchar * path, GVariant * properties, gpointer user_data); - static void _OnWpaPropertiesChanged(WpaFiW1Wpa_supplicant1Interface * proxy, GVariant * changed_properties, - const gchar * const * invalidated_properties, gpointer user_data); - static void _OnWpaInterfaceReady(GObject * source_object, GAsyncResult * res, gpointer user_data); - static void _OnWpaInterfaceProxyReady(GObject * source_object, GAsyncResult * res, gpointer user_data); - static void _OnWpaBssProxyReady(GObject * source_object, GAsyncResult * res, gpointer user_data); - static void _OnWpaInterfaceScanDone(GObject * source_object, GAsyncResult * res, gpointer user_data); - - static bool _GetBssInfo(const gchar * bssPath, NetworkCommissioning::WiFiScanResponse & result); - - static CHIP_ERROR _StartWiFiManagement(ConnectivityManagerImpl * self); - - static bool mAssociationStarted; - static BitFlags mConnectivityFlag; - static GDBusWpaSupplicant mWpaSupplicant CHIP_GUARDED_BY(mWpaSupplicantMutex); + CHIP_ERROR StopAutoScan(); + + void _OnWpaProxyReady(GObject * sourceObject, GAsyncResult * res); + void _OnWpaInterfaceRemoved(WpaFiW1Wpa_supplicant1 * proxy, const char * path, GVariant * properties); + void _OnWpaInterfaceAdded(WpaFiW1Wpa_supplicant1 * proxy, const char * path, GVariant * properties); + void _OnWpaPropertiesChanged(WpaFiW1Wpa_supplicant1Interface * proxy, GVariant * properties); + void _OnWpaInterfaceScanDone(WpaFiW1Wpa_supplicant1Interface * proxy, gboolean success); + void _OnWpaInterfaceReady(GObject * sourceObject, GAsyncResult * res); + void _OnWpaInterfaceProxyReady(GObject * sourceObject, GAsyncResult * res); + void _OnWpaBssProxyReady(GObject * sourceObject, GAsyncResult * res); + + bool _GetBssInfo(const gchar * bssPath, NetworkCommissioning::WiFiScanResponse & result); + + CHIP_ERROR _StartWiFiManagement(); + + bool mAssociationStarted = false; + BitFlags mConnectivityFlag; + GDBusWpaSupplicant mWpaSupplicant CHIP_GUARDED_BY(mWpaSupplicantMutex); // Access to mWpaSupplicant has to be protected by a mutex because it is accessed from // the CHIP event loop thread and dedicated D-Bus thread started by platform manager. - static std::mutex mWpaSupplicantMutex; + std::mutex mWpaSupplicantMutex; NetworkCommissioning::Internal::BaseDriver::NetworkStatusChangeCallback * mpStatusChangeCallback = nullptr; #endif @@ -262,13 +260,15 @@ class ConnectivityManagerImpl final : public ConnectivityManager, #endif #if CHIP_DEVICE_CONFIG_ENABLE_WIFI - static char sWiFiIfName[IFNAMSIZ]; + char sWiFiIfName[IFNAMSIZ]; #endif - static uint8_t sInterestedSSID[Internal::kMaxWiFiSSIDLength]; - static uint8_t sInterestedSSIDLen; - static NetworkCommissioning::WiFiDriver::ScanCallback * mpScanCallback; - static NetworkCommissioning::Internal::WirelessDriver::ConnectCallback * mpConnectCallback; +#if CHIP_DEVICE_CONFIG_ENABLE_WPA + uint8_t sInterestedSSID[Internal::kMaxWiFiSSIDLength]; + uint8_t sInterestedSSIDLen; +#endif + NetworkCommissioning::WiFiDriver::ScanCallback * mpScanCallback; + NetworkCommissioning::Internal::WirelessDriver::ConnectCallback * mpConnectCallback; }; #if CHIP_DEVICE_CONFIG_ENABLE_WPA diff --git a/src/platform/Linux/PlatformManagerImpl.cpp b/src/platform/Linux/PlatformManagerImpl.cpp index 0098eb01ae96eb..401d72bbe413bd 100644 --- a/src/platform/Linux/PlatformManagerImpl.cpp +++ b/src/platform/Linux/PlatformManagerImpl.cpp @@ -108,13 +108,13 @@ gboolean WiFiIPChangeListener(GIOChannel * ch, GIOCondition /* condition */, voi continue; } - if (ConnectivityManagerImpl::GetWiFiIfName() == nullptr) + if (ConnectivityMgrImpl().GetWiFiIfName() == nullptr) { ChipLogDetail(DeviceLayer, "No wifi interface name. Ignoring IP update event."); continue; } - if (strcmp(name, ConnectivityManagerImpl::GetWiFiIfName()) != 0) + if (strcmp(name, ConnectivityMgrImpl().GetWiFiIfName()) != 0) { continue; }