From 19e202e62f3051f62e720412f439c4777405485d Mon Sep 17 00:00:00 2001 From: chrisdecenzo <61757564+chrisdecenzo@users.noreply.github.com> Date: Wed, 20 Dec 2023 06:15:10 -0800 Subject: [PATCH 01/29] Media Clusters: Fix for cert test failures (#31047) * Fix for cert test failures * Fix for channel test cases --- .../clusters/channel/ChannelManager.cpp | 63 ++++++++++++++++++- .../clusters/channel/ChannelManager.h | 3 + .../ContentAppObserver.cpp | 23 +++++-- .../content-app-observer/ContentAppObserver.h | 4 +- .../content-control/ContentController.cpp | 40 ++++++------ .../content-control/ContentController.h | 4 +- .../media-playback/MediaPlaybackManager.h | 30 ++++----- examples/tv-app/tv-common/include/AppTv.h | 4 +- .../tv-app/tv-common/src/ZCLCallbacks.cpp | 26 ++++++-- 9 files changed, 144 insertions(+), 53 deletions(-) diff --git a/examples/tv-app/tv-common/clusters/channel/ChannelManager.cpp b/examples/tv-app/tv-common/clusters/channel/ChannelManager.cpp index 59b00e828aff26..a278de45489112 100644 --- a/examples/tv-app/tv-common/clusters/channel/ChannelManager.cpp +++ b/examples/tv-app/tv-common/clusters/channel/ChannelManager.cpp @@ -62,6 +62,36 @@ ChannelManager::ChannelManager() 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 * 60; + + mPrograms.push_back(program1); + + ProgramType program_abc1; + program_abc1.identifier = chip::CharSpan::fromCharString("progid-pbs1"); + program_abc1.channel = pbs; + program_abc1.title = chip::CharSpan::fromCharString("PBS Title1"); + program_abc1.subtitle = MakeOptional(chip::CharSpan::fromCharString("My Program Subtitle1")); + program_abc1.startTime = 0; + program_abc1.endTime = 30 * 60 * 60; + + mPrograms.push_back(program_abc1); + + 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 * 60; + program2.endTime = 30 * 60 * 60; + + mPrograms.push_back(program2); } CHIP_ERROR ChannelManager::HandleGetChannelList(AttributeValueEncoder & aEncoder) @@ -203,9 +233,19 @@ void ChannelManager::HandleGetProgramGuide( // 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); + ProgramGuideResponseType response; - // response.channelPagingStruct; - // response.programList; + // response.channelPagingStruct = channelPaging; + response.programList = DataModel::List(mPrograms.data(), mPrograms.size()); + helper.Success(response); } @@ -214,6 +254,16 @@ bool ChannelManager::HandleRecordProgram(const chip::CharSpan & programIdentifie 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 (strcmp(idString.c_str(), nextIdString.c_str()) == 0) + { + program.recordingFlag = MakeOptional(static_cast(shouldRecordSeries ? 2 : 1)); + } + } + return true; } @@ -222,6 +272,15 @@ bool ChannelManager::HandleCancelRecordProgram(const chip::CharSpan & programIde 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 (strcmp(idString.c_str(), nextIdString.c_str()) == 0) + { + program.recordingFlag = MakeOptional(static_cast(0)); + } + } return true; } diff --git a/examples/tv-app/tv-common/clusters/channel/ChannelManager.h b/examples/tv-app/tv-common/clusters/channel/ChannelManager.h index 68c473e74dc70d..c0c28bb9d00c08 100644 --- a/examples/tv-app/tv-common/clusters/channel/ChannelManager.h +++ b/examples/tv-app/tv-common/clusters/channel/ChannelManager.h @@ -31,6 +31,8 @@ using ChannelInfoType = chip::app::Clusters::Channel::Structs::Channel 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; class ChannelManager : public ChannelDelegate { @@ -66,6 +68,7 @@ class ChannelManager : public ChannelDelegate uint16_t mCurrentChannelIndex; ChannelInfoType mCurrentChannel; std::vector mChannels; + std::vector mPrograms; private: // TODO: set this based upon meta data from app diff --git a/examples/tv-app/tv-common/clusters/content-app-observer/ContentAppObserver.cpp b/examples/tv-app/tv-common/clusters/content-app-observer/ContentAppObserver.cpp index 7145ba24305f21..0b5c949216ed55 100644 --- a/examples/tv-app/tv-common/clusters/content-app-observer/ContentAppObserver.cpp +++ b/examples/tv-app/tv-common/clusters/content-app-observer/ContentAppObserver.cpp @@ -24,13 +24,28 @@ using namespace std; using namespace chip; using namespace chip::app::Clusters::ContentAppObserver; -ContentAppObserver::ContentAppObserver() +ContentAppObserverManager::ContentAppObserverManager() { // Create Test Data } -void ContentAppObserver::HandleContentAppMessage(chip::app::CommandResponseHelper & helper, - const chip::Optional & data, const chip::CharSpan & encodingHint) +void ContentAppObserverManager::HandleContentAppMessage(chip::app::CommandResponseHelper & helper, + const chip::Optional & data, + const chip::CharSpan & encodingHint) { - ChipLogProgress(Zcl, "ContentAppObserver::HandleContentAppMessage"); + ChipLogProgress(Zcl, "ContentAppObserverManager::HandleContentAppMessage"); + + string dataString(data.HasValue() ? data.Value().data() : "", data.HasValue() ? data.Value().size() : 0); + string encodingHintString(encodingHint.data(), encodingHint.size()); + + ChipLogProgress(Zcl, "ContentAppObserverManager::HandleContentAppMessage TEST CASE hint=%s data=%s ", + encodingHintString.c_str(), dataString.c_str()); + + ContentAppMessageResponse response; + // TODO: Insert code here + // TODO: optional and mandatory are swapped + response.data = CharSpan::fromCharString("exampleData"); + response.encodingHint = CharSpan::fromCharString(encodingHintString.c_str()); + response.status = chip::MakeOptional(StatusEnum::kSuccess); + helper.Success(response); } diff --git a/examples/tv-app/tv-common/clusters/content-app-observer/ContentAppObserver.h b/examples/tv-app/tv-common/clusters/content-app-observer/ContentAppObserver.h index 07ba89b2de3a1a..0c0f6fb6efbaec 100644 --- a/examples/tv-app/tv-common/clusters/content-app-observer/ContentAppObserver.h +++ b/examples/tv-app/tv-common/clusters/content-app-observer/ContentAppObserver.h @@ -25,10 +25,10 @@ using ContentAppObserverDelegate = chip::app::Clusters::ContentAppObserver::Delegate; using ContentAppMessageResponse = chip::app::Clusters::ContentAppObserver::Commands::ContentAppMessageResponse::Type; -class ContentAppObserver : public ContentAppObserverDelegate +class ContentAppObserverManager : public ContentAppObserverDelegate { public: - ContentAppObserver(); + ContentAppObserverManager(); void HandleContentAppMessage(chip::app::CommandResponseHelper & helper, const chip::Optional & data, const chip::CharSpan & encodingHint) override; diff --git a/examples/tv-app/tv-common/clusters/content-control/ContentController.cpp b/examples/tv-app/tv-common/clusters/content-control/ContentController.cpp index c4eee0355f4552..7ebb2ee4a45954 100644 --- a/examples/tv-app/tv-common/clusters/content-control/ContentController.cpp +++ b/examples/tv-app/tv-common/clusters/content-control/ContentController.cpp @@ -25,74 +25,74 @@ using namespace chip::app::Clusters; using namespace chip::app::DataModel; using namespace chip::app::Clusters::ContentControl; -ContentController::ContentController() +ContentControlManager::ContentControlManager() { // Create Test Data } // Attribute Delegates -bool ContentController::HandleGetEnabled() +bool ContentControlManager::HandleGetEnabled() { return false; } -CHIP_ERROR ContentController::HandleGetOnDemandRatings(chip::app::AttributeValueEncoder & aEncoder) +CHIP_ERROR ContentControlManager::HandleGetOnDemandRatings(chip::app::AttributeValueEncoder & aEncoder) { return aEncoder.Encode(chip::CharSpan()); } -chip::CharSpan ContentController::HandleGetOnDemandRatingThreshold() +chip::CharSpan ContentControlManager::HandleGetOnDemandRatingThreshold() { return chip::CharSpan(); } -CHIP_ERROR ContentController::HandleGetScheduledContentRatings(chip::app::AttributeValueEncoder & aEncoder) +CHIP_ERROR ContentControlManager::HandleGetScheduledContentRatings(chip::app::AttributeValueEncoder & aEncoder) { return aEncoder.Encode(chip::CharSpan()); } -chip::CharSpan ContentController::HandleGetScheduledContentRatingThreshold() +chip::CharSpan ContentControlManager::HandleGetScheduledContentRatingThreshold() { return chip::CharSpan(); } -uint32_t ContentController::HandleGetScreenDailyTime() +uint32_t ContentControlManager::HandleGetScreenDailyTime() { return (uint32_t) 0xFFFFFFFF; } -uint32_t ContentController::HandleGetRemainingScreenTime() +uint32_t ContentControlManager::HandleGetRemainingScreenTime() { return (uint32_t) 0xFFFFFFFF; } -bool ContentController::HandleGetBlockUnrated() +bool ContentControlManager::HandleGetBlockUnrated() { return false; } // Command Delegates -void ContentController::HandleUpdatePIN(chip::Optional oldPIN, chip::CharSpan newPIN) {} +void ContentControlManager::HandleUpdatePIN(chip::Optional oldPIN, chip::CharSpan newPIN) {} -void ContentController::HandleResetPIN(chip::app::CommandResponseHelper & helper) {} +void ContentControlManager::HandleResetPIN(chip::app::CommandResponseHelper & helper) {} -void ContentController::HandleEnable() {} +void ContentControlManager::HandleEnable() {} -void ContentController::HandleDisable() {} +void ContentControlManager::HandleDisable() {} -void ContentController::HandleAddBonusTime(chip::Optional PINCode, chip::Optional bonusTime) {} +void ContentControlManager::HandleAddBonusTime(chip::Optional PINCode, chip::Optional bonusTime) {} -void ContentController::HandleSetScreenDailyTime(uint32_t screenDailyTime) {} +void ContentControlManager::HandleSetScreenDailyTime(uint32_t screenDailyTime) {} -void ContentController::HandleBlockUnratedContent() {} +void ContentControlManager::HandleBlockUnratedContent() {} -void ContentController::HandleUnblockUnratedContent() {} +void ContentControlManager::HandleUnblockUnratedContent() {} -void ContentController::HandleSetOnDemandRatingThreshold(chip::CharSpan rating) {} +void ContentControlManager::HandleSetOnDemandRatingThreshold(chip::CharSpan rating) {} -void ContentController::HandleSetScheduledContentRatingThreshold(chip::CharSpan rating) {} +void ContentControlManager::HandleSetScheduledContentRatingThreshold(chip::CharSpan rating) {} -uint32_t ContentController::GetFeatureMap(chip::EndpointId endpoint) +uint32_t ContentControlManager::GetFeatureMap(chip::EndpointId endpoint) { if (endpoint >= EMBER_AF_CONTENT_CONTROL_CLUSTER_SERVER_ENDPOINT_COUNT) { diff --git a/examples/tv-app/tv-common/clusters/content-control/ContentController.h b/examples/tv-app/tv-common/clusters/content-control/ContentController.h index 01636f37fcb772..719d42bcbf79b4 100644 --- a/examples/tv-app/tv-common/clusters/content-control/ContentController.h +++ b/examples/tv-app/tv-common/clusters/content-control/ContentController.h @@ -25,10 +25,10 @@ using ContentControlDelegate = chip::app::Clusters::ContentControl::Delegate; using ResetPINResponseType = chip::app::Clusters::ContentControl::Commands::ResetPINResponse::Type; -class ContentController : public ContentControlDelegate +class ContentControlManager : public ContentControlDelegate { public: - ContentController(); + ContentControlManager(); // Attribute Delegates bool HandleGetEnabled() override; diff --git a/examples/tv-app/tv-common/clusters/media-playback/MediaPlaybackManager.h b/examples/tv-app/tv-common/clusters/media-playback/MediaPlaybackManager.h index 54fc9de5b67e87..18ed5ca1a12bd9 100644 --- a/examples/tv-app/tv-common/clusters/media-playback/MediaPlaybackManager.h +++ b/examples/tv-app/tv-common/clusters/media-playback/MediaPlaybackManager.h @@ -73,37 +73,37 @@ class MediaPlaybackManager : public MediaPlaybackDelegate PlaybackPositionType mPlaybackPosition = { 0, chip::app::DataModel::Nullable(0) }; TrackType mActiveAudioTrack = { chip::CharSpan("activeAudioTrackId_0", 20), chip::app::DataModel::Nullable( - { chip::CharSpan("languageCode", 12), + { chip::CharSpan("languageCode1", 13), chip::Optional>( - { chip::app::DataModel::MakeNullable(chip::CharSpan("displayName", 11)) }) }) }; + { chip::app::DataModel::MakeNullable(chip::CharSpan("displayName1", 12)) }) }) }; std::vector mAvailableAudioTracks = { { chip::CharSpan("activeAudioTrackId_0", 20), chip::app::DataModel::Nullable( - { chip::CharSpan("languageCode", 12), + { chip::CharSpan("languageCode1", 13), chip::Optional>( - { chip::app::DataModel::MakeNullable(chip::CharSpan("displayName", 11)) }) }) }, + { chip::app::DataModel::MakeNullable(chip::CharSpan("displayName1", 12)) }) }) }, { chip::CharSpan("activeAudioTrackId_1", 20), chip::app::DataModel::Nullable( - { chip::CharSpan("languageCode", 12), + { chip::CharSpan("languageCode2", 13), chip::Optional>( - { chip::app::DataModel::MakeNullable(chip::CharSpan("displayName", 11)) }) }) } + { chip::app::DataModel::MakeNullable(chip::CharSpan("displayName2", 12)) }) }) } }; - TrackType mActiveTextTrack = { chip::CharSpan("activeTextTrackId_0", 20), + TrackType mActiveTextTrack = { chip::CharSpan("activeTextTrackId_0", 19), chip::app::DataModel::Nullable( - { chip::CharSpan("languageCode", 12), + { chip::CharSpan("languageCode1", 13), chip::Optional>( - { chip::app::DataModel::MakeNullable(chip::CharSpan("displayName", 11)) }) }) }; + { chip::app::DataModel::MakeNullable(chip::CharSpan("displayName1", 12)) }) }) }; std::vector mAvailableTextTracks = { - { chip::CharSpan("activeTextTrackId_0", 20), + { chip::CharSpan("activeTextTrackId_0", 19), chip::app::DataModel::Nullable( - { chip::CharSpan("languageCode", 12), + { chip::CharSpan("languageCode1", 13), chip::Optional>( - { chip::app::DataModel::MakeNullable(chip::CharSpan("displayName", 11)) }) }) }, - { chip::CharSpan("activeTextTrackId_1", 20), + { chip::app::DataModel::MakeNullable(chip::CharSpan("displayName1", 12)) }) }) }, + { chip::CharSpan("activeTextTrackId_1", 19), chip::app::DataModel::Nullable( - { chip::CharSpan("languageCode", 12), + { chip::CharSpan("languageCode2", 13), chip::Optional>( - { chip::app::DataModel::MakeNullable(chip::CharSpan("displayName", 11)) }) }) } + { chip::app::DataModel::MakeNullable(chip::CharSpan("displayName2", 12)) }) }) } }; float mPlaybackSpeed = 0; uint64_t mStartTime = 0; diff --git a/examples/tv-app/tv-common/include/AppTv.h b/examples/tv-app/tv-common/include/AppTv.h index 8bfdf558dd1465..0a56ebe1da8624 100644 --- a/examples/tv-app/tv-common/include/AppTv.h +++ b/examples/tv-app/tv-common/include/AppTv.h @@ -101,8 +101,8 @@ class DLL_EXPORT ContentAppImpl : public ContentApp ApplicationLauncherManager mApplicationLauncherDelegate; ChannelManager mChannelDelegate; ContentLauncherManager mContentLauncherDelegate; - ContentAppObserver mContentAppObserverDelegate; - ContentController mContentControlDelegate; + ContentAppObserverManager mContentAppObserverDelegate; + ContentControlManager mContentControlDelegate; KeypadInputManager mKeypadInputDelegate; MediaPlaybackManager mMediaPlaybackDelegate; TargetNavigatorManager mTargetNavigatorDelegate; diff --git a/examples/tv-app/tv-common/src/ZCLCallbacks.cpp b/examples/tv-app/tv-common/src/ZCLCallbacks.cpp index 8a5416ff3569b4..1358ab0bba9bb1 100644 --- a/examples/tv-app/tv-common/src/ZCLCallbacks.cpp +++ b/examples/tv-app/tv-common/src/ZCLCallbacks.cpp @@ -51,6 +51,8 @@ static ApplicationLauncherManager applicationLauncherManager(false); #endif // CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED static AudioOutputManager audioOutputManager; static ChannelManager channelManager; +static ContentAppObserverManager contentAppObserverManager; +static ContentControlManager contentControlManager; static ContentLauncherManager contentLauncherManager; static KeypadInputManager keypadInputManager; static LowPowerManager lowPowerManager; @@ -104,12 +106,6 @@ void emberAfOnOffClusterInitCallback(EndpointId endpoint) // TODO: implement any additional Cluster Server init actions } -void emberAfContentLauncherClusterInitCallback(EndpointId endpoint) -{ - ChipLogProgress(Zcl, "TV Linux App: ContentLauncher::SetDefaultDelegate"); - ContentLauncher::SetDefaultDelegate(endpoint, &contentLauncherManager); -} - void emberAfAccountLoginClusterInitCallback(EndpointId endpoint) { ChipLogProgress(Zcl, "TV Linux App: AccountLogin::SetDefaultDelegate"); @@ -134,6 +130,24 @@ void emberAfAudioOutputClusterInitCallback(EndpointId endpoint) AudioOutput::SetDefaultDelegate(endpoint, &audioOutputManager); } +void emberAfContentAppObserverClusterInitCallback(EndpointId endpoint) +{ + ChipLogProgress(Zcl, "TV Linux App: ContentAppObserverManager::SetDefaultDelegate"); + ContentAppObserver::SetDefaultDelegate(endpoint, &contentAppObserverManager); +} + +void emberAfContentControlClusterInitCallback(EndpointId endpoint) +{ + ChipLogProgress(Zcl, "TV Linux App: ContentControlManager::SetDefaultDelegate"); + ContentControl::SetDefaultDelegate(endpoint, &contentControlManager); +} + +void emberAfContentLauncherClusterInitCallback(EndpointId endpoint) +{ + ChipLogProgress(Zcl, "TV Linux App: ContentLauncher::SetDefaultDelegate"); + ContentLauncher::SetDefaultDelegate(endpoint, &contentLauncherManager); +} + void emberAfChannelClusterInitCallback(EndpointId endpoint) { ChipLogProgress(Zcl, "TV Linux App: Channel::SetDefaultDelegate"); From aaa94059648ef299d21840ffa134e801274135eb Mon Sep 17 00:00:00 2001 From: Karsten Sperling <113487422+ksperling-apple@users.noreply.github.com> Date: Thu, 21 Dec 2023 07:08:45 +1300 Subject: [PATCH 02/29] Simplify CertificationDeclaration EncodeSignerInfo (#31087) ... by using ConvertECDSASignatureRawToDER which directly integrates with the ASN.1 writer rather than EcdsaRawSignatureToAsn1 from CHIPCryptoPAL. Also make the same change in the chip-cert gen-cd command. --- src/credentials/CertificationDeclaration.cpp | 10 +++++----- src/tools/chip-cert/Cmd_GenCD.cpp | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/credentials/CertificationDeclaration.cpp b/src/credentials/CertificationDeclaration.cpp index 42bd9656b30750..9795270474fcc7 100644 --- a/src/credentials/CertificationDeclaration.cpp +++ b/src/credentials/CertificationDeclaration.cpp @@ -473,12 +473,12 @@ CHIP_ERROR EncodeSignerInfo(const ByteSpan & signerKeyId, const P256ECDSASignatu } ASN1_END_SEQUENCE; - uint8_t asn1SignatureBuf[kMax_ECDSA_Signature_Length_Der]; - MutableByteSpan asn1Signature(asn1SignatureBuf); - ReturnErrorOnFailure(EcdsaRawSignatureToAsn1(kP256_FE_Length, signature.Span(), asn1Signature)); - // signature OCTET STRING - ReturnErrorOnFailure(writer.PutOctetString(asn1Signature.data(), static_cast(asn1Signature.size()))); + ASN1_START_OCTET_STRING_ENCAPSULATED + { + ReturnErrorOnFailure(ConvertECDSASignatureRawToDER(P256ECDSASignatureSpan(signature.ConstBytes()), writer)); + } + ASN1_END_ENCAPSULATED; } ASN1_END_SEQUENCE; } diff --git a/src/tools/chip-cert/Cmd_GenCD.cpp b/src/tools/chip-cert/Cmd_GenCD.cpp index f851bf77cf0495..acea3c5a1c4239 100644 --- a/src/tools/chip-cert/Cmd_GenCD.cpp +++ b/src/tools/chip-cert/Cmd_GenCD.cpp @@ -1000,7 +1000,7 @@ CHIP_ERROR EncodeSignerInfo_Ignor_Error(const ByteSpan & signerKeyId, const P256 uint8_t asn1SignatureBuf[kMax_ECDSA_Signature_Length_Der]; MutableByteSpan asn1Signature(asn1SignatureBuf); - ReturnErrorOnFailure(EcdsaRawSignatureToAsn1(kP256_FE_Length, signature.Span(), asn1Signature)); + ReturnErrorOnFailure(ConvertECDSASignatureRawToDER(P256ECDSASignatureSpan(signature.ConstBytes()), asn1Signature)); if (!cdConfig.IsCMSSignatureCorrect()) { From 017a9db0d63d2fe2fa3d7140757844e665f76d35 Mon Sep 17 00:00:00 2001 From: joonhaengHeo <85541460+joonhaengHeo@users.noreply.github.com> Date: Thu, 21 Dec 2023 04:13:08 +0900 Subject: [PATCH 03/29] Add java empty event struct (#31128) --- .../java/ChipEventStructs_java.jinja | 4 +- .../devicecontroller/ChipEventStructs.java | 930 +++++++++++++++++- 2 files changed, 929 insertions(+), 5 deletions(-) diff --git a/scripts/py_matter_idl/matter_idl/generators/java/ChipEventStructs_java.jinja b/scripts/py_matter_idl/matter_idl/generators/java/ChipEventStructs_java.jinja index 95f733f9b986b1..e3a8074bc11a6c 100644 --- a/scripts/py_matter_idl/matter_idl/generators/java/ChipEventStructs_java.jinja +++ b/scripts/py_matter_idl/matter_idl/generators/java/ChipEventStructs_java.jinja @@ -80,7 +80,6 @@ public class ChipEventStructs { {%- for cluster in clientClusters | sort(attribute='code') -%} {%- set typeLookup = idl | createLookupContext(cluster) %} {%- for event in cluster.events %} -{%- if event.fields %} public static class {{cluster.name}}Cluster{{event.name}}Event { {%- for field in event.fields %} {%- set encodable = field | asEncodable(typeLookup) %} @@ -133,6 +132,7 @@ public static class {{cluster.name}}Cluster{{event.name}}Event { {%- endif -%} ; {%- endfor %} +{%- if event.fields %} for (StructElement element: ((StructType)tlvValue).value()) { {%- for field in event.fields -%} {%- set encodable = field | asEncodable(typeLookup) %} @@ -146,6 +146,7 @@ public static class {{cluster.name}}Cluster{{event.name}}Event { } {%- endraw %} } +{%- endif %} return new {{cluster.name}}Cluster{{event.name}}Event( {%- for field in event.fields %} {{field.name}}{%- if loop.index0 < loop.length - 1 -%}{{","}}{%- endif %} @@ -177,7 +178,6 @@ public static class {{cluster.name}}Cluster{{event.name}}Event { return output.toString(); } } -{%- endif %} {%- endfor %} {%- endfor %} } diff --git a/src/controller/java/generated/java/chip/devicecontroller/ChipEventStructs.java b/src/controller/java/generated/java/chip/devicecontroller/ChipEventStructs.java index b140401dcc6689..9d18a3e786d5b4 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/ChipEventStructs.java +++ b/src/controller/java/generated/java/chip/devicecontroller/ChipEventStructs.java @@ -449,6 +449,34 @@ public String toString() { return output.toString(); } } +public static class BasicInformationClusterShutDownEvent { + + public BasicInformationClusterShutDownEvent( + ) { + } + + public StructType encodeTlv() { + ArrayList values = new ArrayList<>(); + + return new StructType(values); + } + + public static BasicInformationClusterShutDownEvent decodeTlv(BaseTLVType tlvValue) { + if (tlvValue == null || tlvValue.type() != TLVType.Struct) { + return null; + } + return new BasicInformationClusterShutDownEvent( + ); + } + + @Override + public String toString() { + StringBuilder output = new StringBuilder(); + output.append("BasicInformationClusterShutDownEvent {\n"); + output.append("}\n"); + return output.toString(); + } +} public static class BasicInformationClusterLeaveEvent { public Integer fabricIndex; private static final long FABRIC_INDEX_ID = 0L; @@ -1532,6 +1560,34 @@ public String toString() { return output.toString(); } } +public static class TimeSynchronizationClusterDSTTableEmptyEvent { + + public TimeSynchronizationClusterDSTTableEmptyEvent( + ) { + } + + public StructType encodeTlv() { + ArrayList values = new ArrayList<>(); + + return new StructType(values); + } + + public static TimeSynchronizationClusterDSTTableEmptyEvent decodeTlv(BaseTLVType tlvValue) { + if (tlvValue == null || tlvValue.type() != TLVType.Struct) { + return null; + } + return new TimeSynchronizationClusterDSTTableEmptyEvent( + ); + } + + @Override + public String toString() { + StringBuilder output = new StringBuilder(); + output.append("TimeSynchronizationClusterDSTTableEmptyEvent {\n"); + output.append("}\n"); + return output.toString(); + } +} public static class TimeSynchronizationClusterDSTStatusEvent { public Boolean DSTOffsetActive; private static final long D_S_T_OFFSET_ACTIVE_ID = 0L; @@ -1639,6 +1695,62 @@ public String toString() { return output.toString(); } } +public static class TimeSynchronizationClusterTimeFailureEvent { + + public TimeSynchronizationClusterTimeFailureEvent( + ) { + } + + public StructType encodeTlv() { + ArrayList values = new ArrayList<>(); + + return new StructType(values); + } + + public static TimeSynchronizationClusterTimeFailureEvent decodeTlv(BaseTLVType tlvValue) { + if (tlvValue == null || tlvValue.type() != TLVType.Struct) { + return null; + } + return new TimeSynchronizationClusterTimeFailureEvent( + ); + } + + @Override + public String toString() { + StringBuilder output = new StringBuilder(); + output.append("TimeSynchronizationClusterTimeFailureEvent {\n"); + output.append("}\n"); + return output.toString(); + } +} +public static class TimeSynchronizationClusterMissingTrustedTimeSourceEvent { + + public TimeSynchronizationClusterMissingTrustedTimeSourceEvent( + ) { + } + + public StructType encodeTlv() { + ArrayList values = new ArrayList<>(); + + return new StructType(values); + } + + public static TimeSynchronizationClusterMissingTrustedTimeSourceEvent decodeTlv(BaseTLVType tlvValue) { + if (tlvValue == null || tlvValue.type() != TLVType.Struct) { + return null; + } + return new TimeSynchronizationClusterMissingTrustedTimeSourceEvent( + ); + } + + @Override + public String toString() { + StringBuilder output = new StringBuilder(); + output.append("TimeSynchronizationClusterMissingTrustedTimeSourceEvent {\n"); + output.append("}\n"); + return output.toString(); + } +} public static class BridgedDeviceBasicInformationClusterStartUpEvent { public Long softwareVersion; private static final long SOFTWARE_VERSION_ID = 0L; @@ -1685,6 +1797,62 @@ public String toString() { return output.toString(); } } +public static class BridgedDeviceBasicInformationClusterShutDownEvent { + + public BridgedDeviceBasicInformationClusterShutDownEvent( + ) { + } + + public StructType encodeTlv() { + ArrayList values = new ArrayList<>(); + + return new StructType(values); + } + + public static BridgedDeviceBasicInformationClusterShutDownEvent decodeTlv(BaseTLVType tlvValue) { + if (tlvValue == null || tlvValue.type() != TLVType.Struct) { + return null; + } + return new BridgedDeviceBasicInformationClusterShutDownEvent( + ); + } + + @Override + public String toString() { + StringBuilder output = new StringBuilder(); + output.append("BridgedDeviceBasicInformationClusterShutDownEvent {\n"); + output.append("}\n"); + return output.toString(); + } +} +public static class BridgedDeviceBasicInformationClusterLeaveEvent { + + public BridgedDeviceBasicInformationClusterLeaveEvent( + ) { + } + + public StructType encodeTlv() { + ArrayList values = new ArrayList<>(); + + return new StructType(values); + } + + public static BridgedDeviceBasicInformationClusterLeaveEvent decodeTlv(BaseTLVType tlvValue) { + if (tlvValue == null || tlvValue.type() != TLVType.Struct) { + return null; + } + return new BridgedDeviceBasicInformationClusterLeaveEvent( + ); + } + + @Override + public String toString() { + StringBuilder output = new StringBuilder(); + output.append("BridgedDeviceBasicInformationClusterLeaveEvent {\n"); + output.append("}\n"); + return output.toString(); + } +} public static class BridgedDeviceBasicInformationClusterReachableChangedEvent { public Boolean reachableNewValue; private static final long REACHABLE_NEW_VALUE_ID = 0L; @@ -2480,6 +2648,146 @@ public String toString() { return output.toString(); } } +public static class SmokeCoAlarmClusterHardwareFaultEvent { + + public SmokeCoAlarmClusterHardwareFaultEvent( + ) { + } + + public StructType encodeTlv() { + ArrayList values = new ArrayList<>(); + + return new StructType(values); + } + + public static SmokeCoAlarmClusterHardwareFaultEvent decodeTlv(BaseTLVType tlvValue) { + if (tlvValue == null || tlvValue.type() != TLVType.Struct) { + return null; + } + return new SmokeCoAlarmClusterHardwareFaultEvent( + ); + } + + @Override + public String toString() { + StringBuilder output = new StringBuilder(); + output.append("SmokeCoAlarmClusterHardwareFaultEvent {\n"); + output.append("}\n"); + return output.toString(); + } +} +public static class SmokeCoAlarmClusterEndOfServiceEvent { + + public SmokeCoAlarmClusterEndOfServiceEvent( + ) { + } + + public StructType encodeTlv() { + ArrayList values = new ArrayList<>(); + + return new StructType(values); + } + + public static SmokeCoAlarmClusterEndOfServiceEvent decodeTlv(BaseTLVType tlvValue) { + if (tlvValue == null || tlvValue.type() != TLVType.Struct) { + return null; + } + return new SmokeCoAlarmClusterEndOfServiceEvent( + ); + } + + @Override + public String toString() { + StringBuilder output = new StringBuilder(); + output.append("SmokeCoAlarmClusterEndOfServiceEvent {\n"); + output.append("}\n"); + return output.toString(); + } +} +public static class SmokeCoAlarmClusterSelfTestCompleteEvent { + + public SmokeCoAlarmClusterSelfTestCompleteEvent( + ) { + } + + public StructType encodeTlv() { + ArrayList values = new ArrayList<>(); + + return new StructType(values); + } + + public static SmokeCoAlarmClusterSelfTestCompleteEvent decodeTlv(BaseTLVType tlvValue) { + if (tlvValue == null || tlvValue.type() != TLVType.Struct) { + return null; + } + return new SmokeCoAlarmClusterSelfTestCompleteEvent( + ); + } + + @Override + public String toString() { + StringBuilder output = new StringBuilder(); + output.append("SmokeCoAlarmClusterSelfTestCompleteEvent {\n"); + output.append("}\n"); + return output.toString(); + } +} +public static class SmokeCoAlarmClusterAlarmMutedEvent { + + public SmokeCoAlarmClusterAlarmMutedEvent( + ) { + } + + public StructType encodeTlv() { + ArrayList values = new ArrayList<>(); + + return new StructType(values); + } + + public static SmokeCoAlarmClusterAlarmMutedEvent decodeTlv(BaseTLVType tlvValue) { + if (tlvValue == null || tlvValue.type() != TLVType.Struct) { + return null; + } + return new SmokeCoAlarmClusterAlarmMutedEvent( + ); + } + + @Override + public String toString() { + StringBuilder output = new StringBuilder(); + output.append("SmokeCoAlarmClusterAlarmMutedEvent {\n"); + output.append("}\n"); + return output.toString(); + } +} +public static class SmokeCoAlarmClusterMuteEndedEvent { + + public SmokeCoAlarmClusterMuteEndedEvent( + ) { + } + + public StructType encodeTlv() { + ArrayList values = new ArrayList<>(); + + return new StructType(values); + } + + public static SmokeCoAlarmClusterMuteEndedEvent decodeTlv(BaseTLVType tlvValue) { + if (tlvValue == null || tlvValue.type() != TLVType.Struct) { + return null; + } + return new SmokeCoAlarmClusterMuteEndedEvent( + ); + } + + @Override + public String toString() { + StringBuilder output = new StringBuilder(); + output.append("SmokeCoAlarmClusterMuteEndedEvent {\n"); + output.append("}\n"); + return output.toString(); + } +} public static class SmokeCoAlarmClusterInterconnectSmokeAlarmEvent { public Integer alarmSeverityLevel; private static final long ALARM_SEVERITY_LEVEL_ID = 0L; @@ -2572,9 +2880,37 @@ public String toString() { return output.toString(); } } -public static class DishwasherAlarmClusterNotifyEvent { - public Long active; - public Long inactive; +public static class SmokeCoAlarmClusterAllClearEvent { + + public SmokeCoAlarmClusterAllClearEvent( + ) { + } + + public StructType encodeTlv() { + ArrayList values = new ArrayList<>(); + + return new StructType(values); + } + + public static SmokeCoAlarmClusterAllClearEvent decodeTlv(BaseTLVType tlvValue) { + if (tlvValue == null || tlvValue.type() != TLVType.Struct) { + return null; + } + return new SmokeCoAlarmClusterAllClearEvent( + ); + } + + @Override + public String toString() { + StringBuilder output = new StringBuilder(); + output.append("SmokeCoAlarmClusterAllClearEvent {\n"); + output.append("}\n"); + return output.toString(); + } +} +public static class DishwasherAlarmClusterNotifyEvent { + public Long active; + public Long inactive; public Long state; public Long mask; private static final long ACTIVE_ID = 0L; @@ -3424,6 +3760,34 @@ public String toString() { return output.toString(); } } +public static class DeviceEnergyManagementClusterPowerAdjustStartEvent { + + public DeviceEnergyManagementClusterPowerAdjustStartEvent( + ) { + } + + public StructType encodeTlv() { + ArrayList values = new ArrayList<>(); + + return new StructType(values); + } + + public static DeviceEnergyManagementClusterPowerAdjustStartEvent decodeTlv(BaseTLVType tlvValue) { + if (tlvValue == null || tlvValue.type() != TLVType.Struct) { + return null; + } + return new DeviceEnergyManagementClusterPowerAdjustStartEvent( + ); + } + + @Override + public String toString() { + StringBuilder output = new StringBuilder(); + output.append("DeviceEnergyManagementClusterPowerAdjustStartEvent {\n"); + output.append("}\n"); + return output.toString(); + } +} public static class DeviceEnergyManagementClusterPowerAdjustEndEvent { public Integer cause; public Long duration; @@ -3500,6 +3864,62 @@ public String toString() { return output.toString(); } } +public static class DeviceEnergyManagementClusterPausedEvent { + + public DeviceEnergyManagementClusterPausedEvent( + ) { + } + + public StructType encodeTlv() { + ArrayList values = new ArrayList<>(); + + return new StructType(values); + } + + public static DeviceEnergyManagementClusterPausedEvent decodeTlv(BaseTLVType tlvValue) { + if (tlvValue == null || tlvValue.type() != TLVType.Struct) { + return null; + } + return new DeviceEnergyManagementClusterPausedEvent( + ); + } + + @Override + public String toString() { + StringBuilder output = new StringBuilder(); + output.append("DeviceEnergyManagementClusterPausedEvent {\n"); + output.append("}\n"); + return output.toString(); + } +} +public static class DeviceEnergyManagementClusterResumedEvent { + + public DeviceEnergyManagementClusterResumedEvent( + ) { + } + + public StructType encodeTlv() { + ArrayList values = new ArrayList<>(); + + return new StructType(values); + } + + public static DeviceEnergyManagementClusterResumedEvent decodeTlv(BaseTLVType tlvValue) { + if (tlvValue == null || tlvValue.type() != TLVType.Struct) { + return null; + } + return new DeviceEnergyManagementClusterResumedEvent( + ); + } + + @Override + public String toString() { + StringBuilder output = new StringBuilder(); + output.append("DeviceEnergyManagementClusterResumedEvent {\n"); + output.append("}\n"); + return output.toString(); + } +} public static class EnergyEvseClusterEVConnectedEvent { public Long sessionID; private static final long SESSION_I_D_ID = 0L; @@ -4441,6 +4861,482 @@ public String toString() { return output.toString(); } } +public static class PumpConfigurationAndControlClusterSupplyVoltageLowEvent { + + public PumpConfigurationAndControlClusterSupplyVoltageLowEvent( + ) { + } + + public StructType encodeTlv() { + ArrayList values = new ArrayList<>(); + + return new StructType(values); + } + + public static PumpConfigurationAndControlClusterSupplyVoltageLowEvent decodeTlv(BaseTLVType tlvValue) { + if (tlvValue == null || tlvValue.type() != TLVType.Struct) { + return null; + } + return new PumpConfigurationAndControlClusterSupplyVoltageLowEvent( + ); + } + + @Override + public String toString() { + StringBuilder output = new StringBuilder(); + output.append("PumpConfigurationAndControlClusterSupplyVoltageLowEvent {\n"); + output.append("}\n"); + return output.toString(); + } +} +public static class PumpConfigurationAndControlClusterSupplyVoltageHighEvent { + + public PumpConfigurationAndControlClusterSupplyVoltageHighEvent( + ) { + } + + public StructType encodeTlv() { + ArrayList values = new ArrayList<>(); + + return new StructType(values); + } + + public static PumpConfigurationAndControlClusterSupplyVoltageHighEvent decodeTlv(BaseTLVType tlvValue) { + if (tlvValue == null || tlvValue.type() != TLVType.Struct) { + return null; + } + return new PumpConfigurationAndControlClusterSupplyVoltageHighEvent( + ); + } + + @Override + public String toString() { + StringBuilder output = new StringBuilder(); + output.append("PumpConfigurationAndControlClusterSupplyVoltageHighEvent {\n"); + output.append("}\n"); + return output.toString(); + } +} +public static class PumpConfigurationAndControlClusterPowerMissingPhaseEvent { + + public PumpConfigurationAndControlClusterPowerMissingPhaseEvent( + ) { + } + + public StructType encodeTlv() { + ArrayList values = new ArrayList<>(); + + return new StructType(values); + } + + public static PumpConfigurationAndControlClusterPowerMissingPhaseEvent decodeTlv(BaseTLVType tlvValue) { + if (tlvValue == null || tlvValue.type() != TLVType.Struct) { + return null; + } + return new PumpConfigurationAndControlClusterPowerMissingPhaseEvent( + ); + } + + @Override + public String toString() { + StringBuilder output = new StringBuilder(); + output.append("PumpConfigurationAndControlClusterPowerMissingPhaseEvent {\n"); + output.append("}\n"); + return output.toString(); + } +} +public static class PumpConfigurationAndControlClusterSystemPressureLowEvent { + + public PumpConfigurationAndControlClusterSystemPressureLowEvent( + ) { + } + + public StructType encodeTlv() { + ArrayList values = new ArrayList<>(); + + return new StructType(values); + } + + public static PumpConfigurationAndControlClusterSystemPressureLowEvent decodeTlv(BaseTLVType tlvValue) { + if (tlvValue == null || tlvValue.type() != TLVType.Struct) { + return null; + } + return new PumpConfigurationAndControlClusterSystemPressureLowEvent( + ); + } + + @Override + public String toString() { + StringBuilder output = new StringBuilder(); + output.append("PumpConfigurationAndControlClusterSystemPressureLowEvent {\n"); + output.append("}\n"); + return output.toString(); + } +} +public static class PumpConfigurationAndControlClusterSystemPressureHighEvent { + + public PumpConfigurationAndControlClusterSystemPressureHighEvent( + ) { + } + + public StructType encodeTlv() { + ArrayList values = new ArrayList<>(); + + return new StructType(values); + } + + public static PumpConfigurationAndControlClusterSystemPressureHighEvent decodeTlv(BaseTLVType tlvValue) { + if (tlvValue == null || tlvValue.type() != TLVType.Struct) { + return null; + } + return new PumpConfigurationAndControlClusterSystemPressureHighEvent( + ); + } + + @Override + public String toString() { + StringBuilder output = new StringBuilder(); + output.append("PumpConfigurationAndControlClusterSystemPressureHighEvent {\n"); + output.append("}\n"); + return output.toString(); + } +} +public static class PumpConfigurationAndControlClusterDryRunningEvent { + + public PumpConfigurationAndControlClusterDryRunningEvent( + ) { + } + + public StructType encodeTlv() { + ArrayList values = new ArrayList<>(); + + return new StructType(values); + } + + public static PumpConfigurationAndControlClusterDryRunningEvent decodeTlv(BaseTLVType tlvValue) { + if (tlvValue == null || tlvValue.type() != TLVType.Struct) { + return null; + } + return new PumpConfigurationAndControlClusterDryRunningEvent( + ); + } + + @Override + public String toString() { + StringBuilder output = new StringBuilder(); + output.append("PumpConfigurationAndControlClusterDryRunningEvent {\n"); + output.append("}\n"); + return output.toString(); + } +} +public static class PumpConfigurationAndControlClusterMotorTemperatureHighEvent { + + public PumpConfigurationAndControlClusterMotorTemperatureHighEvent( + ) { + } + + public StructType encodeTlv() { + ArrayList values = new ArrayList<>(); + + return new StructType(values); + } + + public static PumpConfigurationAndControlClusterMotorTemperatureHighEvent decodeTlv(BaseTLVType tlvValue) { + if (tlvValue == null || tlvValue.type() != TLVType.Struct) { + return null; + } + return new PumpConfigurationAndControlClusterMotorTemperatureHighEvent( + ); + } + + @Override + public String toString() { + StringBuilder output = new StringBuilder(); + output.append("PumpConfigurationAndControlClusterMotorTemperatureHighEvent {\n"); + output.append("}\n"); + return output.toString(); + } +} +public static class PumpConfigurationAndControlClusterPumpMotorFatalFailureEvent { + + public PumpConfigurationAndControlClusterPumpMotorFatalFailureEvent( + ) { + } + + public StructType encodeTlv() { + ArrayList values = new ArrayList<>(); + + return new StructType(values); + } + + public static PumpConfigurationAndControlClusterPumpMotorFatalFailureEvent decodeTlv(BaseTLVType tlvValue) { + if (tlvValue == null || tlvValue.type() != TLVType.Struct) { + return null; + } + return new PumpConfigurationAndControlClusterPumpMotorFatalFailureEvent( + ); + } + + @Override + public String toString() { + StringBuilder output = new StringBuilder(); + output.append("PumpConfigurationAndControlClusterPumpMotorFatalFailureEvent {\n"); + output.append("}\n"); + return output.toString(); + } +} +public static class PumpConfigurationAndControlClusterElectronicTemperatureHighEvent { + + public PumpConfigurationAndControlClusterElectronicTemperatureHighEvent( + ) { + } + + public StructType encodeTlv() { + ArrayList values = new ArrayList<>(); + + return new StructType(values); + } + + public static PumpConfigurationAndControlClusterElectronicTemperatureHighEvent decodeTlv(BaseTLVType tlvValue) { + if (tlvValue == null || tlvValue.type() != TLVType.Struct) { + return null; + } + return new PumpConfigurationAndControlClusterElectronicTemperatureHighEvent( + ); + } + + @Override + public String toString() { + StringBuilder output = new StringBuilder(); + output.append("PumpConfigurationAndControlClusterElectronicTemperatureHighEvent {\n"); + output.append("}\n"); + return output.toString(); + } +} +public static class PumpConfigurationAndControlClusterPumpBlockedEvent { + + public PumpConfigurationAndControlClusterPumpBlockedEvent( + ) { + } + + public StructType encodeTlv() { + ArrayList values = new ArrayList<>(); + + return new StructType(values); + } + + public static PumpConfigurationAndControlClusterPumpBlockedEvent decodeTlv(BaseTLVType tlvValue) { + if (tlvValue == null || tlvValue.type() != TLVType.Struct) { + return null; + } + return new PumpConfigurationAndControlClusterPumpBlockedEvent( + ); + } + + @Override + public String toString() { + StringBuilder output = new StringBuilder(); + output.append("PumpConfigurationAndControlClusterPumpBlockedEvent {\n"); + output.append("}\n"); + return output.toString(); + } +} +public static class PumpConfigurationAndControlClusterSensorFailureEvent { + + public PumpConfigurationAndControlClusterSensorFailureEvent( + ) { + } + + public StructType encodeTlv() { + ArrayList values = new ArrayList<>(); + + return new StructType(values); + } + + public static PumpConfigurationAndControlClusterSensorFailureEvent decodeTlv(BaseTLVType tlvValue) { + if (tlvValue == null || tlvValue.type() != TLVType.Struct) { + return null; + } + return new PumpConfigurationAndControlClusterSensorFailureEvent( + ); + } + + @Override + public String toString() { + StringBuilder output = new StringBuilder(); + output.append("PumpConfigurationAndControlClusterSensorFailureEvent {\n"); + output.append("}\n"); + return output.toString(); + } +} +public static class PumpConfigurationAndControlClusterElectronicNonFatalFailureEvent { + + public PumpConfigurationAndControlClusterElectronicNonFatalFailureEvent( + ) { + } + + public StructType encodeTlv() { + ArrayList values = new ArrayList<>(); + + return new StructType(values); + } + + public static PumpConfigurationAndControlClusterElectronicNonFatalFailureEvent decodeTlv(BaseTLVType tlvValue) { + if (tlvValue == null || tlvValue.type() != TLVType.Struct) { + return null; + } + return new PumpConfigurationAndControlClusterElectronicNonFatalFailureEvent( + ); + } + + @Override + public String toString() { + StringBuilder output = new StringBuilder(); + output.append("PumpConfigurationAndControlClusterElectronicNonFatalFailureEvent {\n"); + output.append("}\n"); + return output.toString(); + } +} +public static class PumpConfigurationAndControlClusterElectronicFatalFailureEvent { + + public PumpConfigurationAndControlClusterElectronicFatalFailureEvent( + ) { + } + + public StructType encodeTlv() { + ArrayList values = new ArrayList<>(); + + return new StructType(values); + } + + public static PumpConfigurationAndControlClusterElectronicFatalFailureEvent decodeTlv(BaseTLVType tlvValue) { + if (tlvValue == null || tlvValue.type() != TLVType.Struct) { + return null; + } + return new PumpConfigurationAndControlClusterElectronicFatalFailureEvent( + ); + } + + @Override + public String toString() { + StringBuilder output = new StringBuilder(); + output.append("PumpConfigurationAndControlClusterElectronicFatalFailureEvent {\n"); + output.append("}\n"); + return output.toString(); + } +} +public static class PumpConfigurationAndControlClusterGeneralFaultEvent { + + public PumpConfigurationAndControlClusterGeneralFaultEvent( + ) { + } + + public StructType encodeTlv() { + ArrayList values = new ArrayList<>(); + + return new StructType(values); + } + + public static PumpConfigurationAndControlClusterGeneralFaultEvent decodeTlv(BaseTLVType tlvValue) { + if (tlvValue == null || tlvValue.type() != TLVType.Struct) { + return null; + } + return new PumpConfigurationAndControlClusterGeneralFaultEvent( + ); + } + + @Override + public String toString() { + StringBuilder output = new StringBuilder(); + output.append("PumpConfigurationAndControlClusterGeneralFaultEvent {\n"); + output.append("}\n"); + return output.toString(); + } +} +public static class PumpConfigurationAndControlClusterLeakageEvent { + + public PumpConfigurationAndControlClusterLeakageEvent( + ) { + } + + public StructType encodeTlv() { + ArrayList values = new ArrayList<>(); + + return new StructType(values); + } + + public static PumpConfigurationAndControlClusterLeakageEvent decodeTlv(BaseTLVType tlvValue) { + if (tlvValue == null || tlvValue.type() != TLVType.Struct) { + return null; + } + return new PumpConfigurationAndControlClusterLeakageEvent( + ); + } + + @Override + public String toString() { + StringBuilder output = new StringBuilder(); + output.append("PumpConfigurationAndControlClusterLeakageEvent {\n"); + output.append("}\n"); + return output.toString(); + } +} +public static class PumpConfigurationAndControlClusterAirDetectionEvent { + + public PumpConfigurationAndControlClusterAirDetectionEvent( + ) { + } + + public StructType encodeTlv() { + ArrayList values = new ArrayList<>(); + + return new StructType(values); + } + + public static PumpConfigurationAndControlClusterAirDetectionEvent decodeTlv(BaseTLVType tlvValue) { + if (tlvValue == null || tlvValue.type() != TLVType.Struct) { + return null; + } + return new PumpConfigurationAndControlClusterAirDetectionEvent( + ); + } + + @Override + public String toString() { + StringBuilder output = new StringBuilder(); + output.append("PumpConfigurationAndControlClusterAirDetectionEvent {\n"); + output.append("}\n"); + return output.toString(); + } +} +public static class PumpConfigurationAndControlClusterTurbineOperationEvent { + + public PumpConfigurationAndControlClusterTurbineOperationEvent( + ) { + } + + public StructType encodeTlv() { + ArrayList values = new ArrayList<>(); + + return new StructType(values); + } + + public static PumpConfigurationAndControlClusterTurbineOperationEvent decodeTlv(BaseTLVType tlvValue) { + if (tlvValue == null || tlvValue.type() != TLVType.Struct) { + return null; + } + return new PumpConfigurationAndControlClusterTurbineOperationEvent( + ); + } + + @Override + public String toString() { + StringBuilder output = new StringBuilder(); + output.append("PumpConfigurationAndControlClusterTurbineOperationEvent {\n"); + output.append("}\n"); + return output.toString(); + } +} public static class TargetNavigatorClusterTargetUpdatedEvent { public ArrayList targetList; public Integer currentTarget; @@ -4729,6 +5625,34 @@ public String toString() { return output.toString(); } } +public static class ContentControlClusterRemainingScreenTimeExpiredEvent { + + public ContentControlClusterRemainingScreenTimeExpiredEvent( + ) { + } + + public StructType encodeTlv() { + ArrayList values = new ArrayList<>(); + + return new StructType(values); + } + + public static ContentControlClusterRemainingScreenTimeExpiredEvent decodeTlv(BaseTLVType tlvValue) { + if (tlvValue == null || tlvValue.type() != TLVType.Struct) { + return null; + } + return new ContentControlClusterRemainingScreenTimeExpiredEvent( + ); + } + + @Override + public String toString() { + StringBuilder output = new StringBuilder(); + output.append("ContentControlClusterRemainingScreenTimeExpiredEvent {\n"); + output.append("}\n"); + return output.toString(); + } +} public static class UnitTestingClusterTestEventEvent { public Integer arg1; public Integer arg2; From f7cd2d66150f5b0b21613f80e907f88191a1a753 Mon Sep 17 00:00:00 2001 From: Tennessee Carmel-Veilleux Date: Wed, 20 Dec 2023 14:26:07 -0500 Subject: [PATCH 04/29] Introduce a Status + Cluster Code abstraction (#31121) * Introduce a Status + Cluster Code abstraction - Existing code always has to split IM status and cluster-specific status codes, which causes clumsy implementation of clusters (see issue #31120). - This PR introduces a value that encapsulates both the IM status and cluster-specific status, in an easy-to-pass-around abstraction, which can be directly used in place of Status. - Subsequent PR will implement usage in IM with overloads for common cases, such as for AddStatus. Issue #31120 Testing done: - Added unit tests - Other tests still pass * Restyled by clang-format * Restyled by gn * Address review comments * Rename ClusterStatus to ClusterStatusCode * Fix build deps * Restyled by gn --------- Co-authored-by: Restyled.io --- examples/darwin-framework-tool/BUILD.gn | 2 +- src/BUILD.gn | 1 + src/app/BUILD.gn | 1 + src/app/common/BUILD.gn | 1 + src/app/tests/TestStatusIB.cpp | 1 + .../commands/interaction_model/BUILD.gn | 2 +- src/protocols/BUILD.gn | 17 +-- src/protocols/interaction_model/BUILD.gn | 34 +++++ src/protocols/interaction_model/StatusCode.h | 109 ++++++++++++++ .../interaction_model/tests/BUILD.gn | 35 +++++ .../tests/TestStatusCode.cpp | 135 ++++++++++++++++++ 11 files changed, 320 insertions(+), 18 deletions(-) create mode 100644 src/protocols/interaction_model/BUILD.gn create mode 100644 src/protocols/interaction_model/tests/BUILD.gn create mode 100644 src/protocols/interaction_model/tests/TestStatusCode.cpp diff --git a/examples/darwin-framework-tool/BUILD.gn b/examples/darwin-framework-tool/BUILD.gn index e6b1a3e7654da3..7ee396dd04e24a 100644 --- a/examples/darwin-framework-tool/BUILD.gn +++ b/examples/darwin-framework-tool/BUILD.gn @@ -248,7 +248,7 @@ executable("darwin-framework-tool") { # pics is needed by tests "${chip_root}/src/app/tests/suites/pics", - "${chip_root}/src/protocols:im_status", + "${chip_root}/src/protocols/interaction_model", ] defines = [] diff --git a/src/BUILD.gn b/src/BUILD.gn index 532da2a4d8db3f..2d0204d49fa741 100644 --- a/src/BUILD.gn +++ b/src/BUILD.gn @@ -60,6 +60,7 @@ if (chip_build_tests) { "${chip_root}/src/lib/core/tests", "${chip_root}/src/messaging/tests", "${chip_root}/src/protocols/bdx/tests", + "${chip_root}/src/protocols/interaction_model/tests", "${chip_root}/src/protocols/user_directed_commissioning/tests", "${chip_root}/src/transport/retransmit/tests", ] diff --git a/src/app/BUILD.gn b/src/app/BUILD.gn index e053756a62c928..a96dc222b2aac3 100644 --- a/src/app/BUILD.gn +++ b/src/app/BUILD.gn @@ -250,6 +250,7 @@ static_library("app") { "${chip_root}/src/lib/address_resolve", "${chip_root}/src/lib/support", "${chip_root}/src/messaging", + "${chip_root}/src/protocols/interaction_model", "${chip_root}/src/protocols/secure_channel", "${chip_root}/src/system", "${nlio_root}:nlio", diff --git a/src/app/common/BUILD.gn b/src/app/common/BUILD.gn index fee9795dc5982c..c6c350e547fd86 100644 --- a/src/app/common/BUILD.gn +++ b/src/app/common/BUILD.gn @@ -27,6 +27,7 @@ static_library("cluster-objects") { public_deps = [ "${chip_root}/src/lib/core", "${chip_root}/src/lib/support", + "${chip_root}/src/protocols/interaction_model", ] defines = [] diff --git a/src/app/tests/TestStatusIB.cpp b/src/app/tests/TestStatusIB.cpp index 4ff97e4b7ccbc3..3eb47f438f67df 100644 --- a/src/app/tests/TestStatusIB.cpp +++ b/src/app/tests/TestStatusIB.cpp @@ -22,6 +22,7 @@ #include #include #include +#include #include diff --git a/src/app/tests/suites/commands/interaction_model/BUILD.gn b/src/app/tests/suites/commands/interaction_model/BUILD.gn index e1329714c68772..ecefa4a854be15 100644 --- a/src/app/tests/suites/commands/interaction_model/BUILD.gn +++ b/src/app/tests/suites/commands/interaction_model/BUILD.gn @@ -16,7 +16,7 @@ import("//build_overrides/build.gni") import("//build_overrides/chip.gni") static_library("interaction_model") { - output_name = "libInteractionModel" + output_name = "libInteractionModelCommands" sources = [ "InteractionModel.cpp", diff --git a/src/protocols/BUILD.gn b/src/protocols/BUILD.gn index 10b48fb7e46cc3..2895334c3393ab 100644 --- a/src/protocols/BUILD.gn +++ b/src/protocols/BUILD.gn @@ -38,27 +38,12 @@ static_library("protocols") { cflags = [ "-Wconversion" ] public_deps = [ - ":im_status", ":type_definitions", "${chip_root}/src/lib/core", "${chip_root}/src/lib/support", "${chip_root}/src/messaging", "${chip_root}/src/protocols/bdx", + "${chip_root}/src/protocols/interaction_model", "${chip_root}/src/protocols/secure_channel", ] } - -static_library("im_status") { - sources = [ - "interaction_model/StatusCode.cpp", - "interaction_model/StatusCode.h", - ] - - cflags = [ "-Wconversion" ] - - public_deps = [ - ":type_definitions", - "${chip_root}/src/lib/core", - "${chip_root}/src/lib/support", - ] -} diff --git a/src/protocols/interaction_model/BUILD.gn b/src/protocols/interaction_model/BUILD.gn new file mode 100644 index 00000000000000..b8c3bd7be7f000 --- /dev/null +++ b/src/protocols/interaction_model/BUILD.gn @@ -0,0 +1,34 @@ +# Copyright (c) 2020 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("//build_overrides/chip.gni") + +static_library("interaction_model") { + output_name = "libInteractionModel" + + sources = [ + "Constants.h", + "StatusCode.cpp", + "StatusCode.h", + "StatusCodeList.h", + ] + + cflags = [ "-Wconversion" ] + + public_deps = [ + "${chip_root}/src/lib/core", + "${chip_root}/src/lib/support", + "${chip_root}/src/protocols:type_definitions", + ] +} diff --git a/src/protocols/interaction_model/StatusCode.h b/src/protocols/interaction_model/StatusCode.h index 5d0453ec3dceaf..31615673d1140f 100644 --- a/src/protocols/interaction_model/StatusCode.h +++ b/src/protocols/interaction_model/StatusCode.h @@ -17,9 +17,12 @@ #pragma once +#include #include #include +#include +#include #include #if CHIP_CONFIG_IM_STATUS_CODE_VERBOSE_FORMAT @@ -48,6 +51,112 @@ enum class Status : uint8_t const char * StatusName(Status status); #endif // CHIP_CONFIG_IM_STATUS_CODE_VERBOSE_FORMAT +/** + * @brief Class to encapsulate a Status code, including possibly a + * cluster-specific code for generic SUCCESS/FAILURE. + * + * This abstractions joins together Status and ClusterStatus, which + * are the components of a StatusIB, used in many IM actions, in a + * way which allows both of them to carry together. + * + * This can be used everywhere a `Status` is used, but it is lossy + * to the cluster-specific code if used in place of `Status` when + * the cluster-specific code is set. + * + * This class can only be directly constructed from a `Status`. To + * attach a cluster-specific-code, please use the `ClusterSpecificFailure()` + * and `ClusterSpecificSuccess()` factory methods. + */ +class ClusterStatusCode +{ +public: + explicit ClusterStatusCode(Status status) : mStatus(status) {} + + // We only have simple copyable members, so we should be trivially copyable. + ClusterStatusCode(const ClusterStatusCode & other) = default; + ClusterStatusCode & operator=(const ClusterStatusCode & other) = default; + + bool operator==(const ClusterStatusCode & other) + { + return (this->mStatus == other.mStatus) && (this->HasClusterSpecificCode() == other.HasClusterSpecificCode()) && + (this->GetClusterSpecificCode() == other.GetClusterSpecificCode()); + } + + bool operator!=(const ClusterStatusCode & other) { return !(*this == other); } + + ClusterStatusCode & operator=(const Status & status) + { + this->mStatus = status; + this->mClusterSpecificCode = chip::NullOptional; + return *this; + } + + /** + * @brief Builder for a cluster-specific failure status code. + * + * @tparam T - enum type for the cluster-specific status code + * (e.g. chip::app::Clusters::AdministratorCommissioning::CommissioningWindowStatusEnum) + * @param cluster_specific_code - cluster-specific code to record with the failure + * (e.g. chip::app::Clusters::AdministratorCommissioning::CommissioningWindowStatusEnum::kWindowNotOpen) + * @return a ClusterStatusCode instance properly configured. + */ + template + static ClusterStatusCode ClusterSpecificFailure(T cluster_specific_code) + { + static_assert(std::numeric_limits::max() <= std::numeric_limits::max(), "Type used must fit in uint8_t"); + return ClusterStatusCode(Status::Failure, chip::to_underlying(cluster_specific_code)); + } + + /** + * @brief Builder for a cluster-specific success status code. + * + * @tparam T - enum type for the cluster-specific status code + * (e.g. chip::app::Clusters::AdministratorCommissioning::CommissioningWindowStatusEnum) + * @param cluster_specific_code - cluster-specific code to record with the success + * (e.g. chip::app::Clusters::AdministratorCommissioning::CommissioningWindowStatusEnum::kBasicWindowOpen) + * @return a ClusterStatusCode instance properly configured. + */ + template + static ClusterStatusCode ClusterSpecificSuccess(T cluster_specific_code) + { + static_assert(std::numeric_limits::max() <= std::numeric_limits::max(), "Type used must fit in uint8_t"); + return ClusterStatusCode(Status::Success, chip::to_underlying(cluster_specific_code)); + } + + /// @return true if the core Status associated with this ClusterStatusCode is the one for success. + bool IsSuccess() const { return mStatus == Status::Success; } + + /// @return the core Status code associated withi this ClusterStatusCode. + Status GetStatus() const { return mStatus; } + + /// @return true if a cluster-specific code is associated with the ClusterStatusCode. + bool HasClusterSpecificCode() const { return mClusterSpecificCode.HasValue(); } + + /// @return the cluster-specific code associated with this ClusterStatusCode or chip::NullOptional if none is associated. + chip::Optional GetClusterSpecificCode() const + { + if ((mStatus != Status::Failure) && (mStatus != Status::Success)) + { + return chip::NullOptional; + } + return mClusterSpecificCode; + } + + // Automatic conversions to common types, using the status code alone. + operator Status() const { return mStatus; } + +private: + ClusterStatusCode() = delete; + ClusterStatusCode(Status status, ClusterStatus cluster_specific_code) : + mStatus(status), mClusterSpecificCode(chip::MakeOptional(cluster_specific_code)) + {} + + Status mStatus; + chip::Optional mClusterSpecificCode; +}; + +static_assert(sizeof(ClusterStatusCode) <= sizeof(uint32_t), "ClusterStatusCode must not grow to be larger than a uint32_t"); + } // namespace InteractionModel } // namespace Protocols } // namespace chip diff --git a/src/protocols/interaction_model/tests/BUILD.gn b/src/protocols/interaction_model/tests/BUILD.gn new file mode 100644 index 00000000000000..16792006e1eb8f --- /dev/null +++ b/src/protocols/interaction_model/tests/BUILD.gn @@ -0,0 +1,35 @@ +# 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("//build_overrides/build.gni") +import("//build_overrides/chip.gni") +import("//build_overrides/nlunit_test.gni") + +import("${chip_root}/build/chip/chip_test_suite.gni") + +chip_test_suite_using_nltest("tests") { + output_name = "libInteractionModelTests" + + test_sources = [ "TestStatusCode.cpp" ] + + public_deps = [ + "${chip_root}/src/lib/core", + "${chip_root}/src/lib/support", + "${chip_root}/src/lib/support:testing", + "${chip_root}/src/protocols/interaction_model", + "${nlunit_test_root}:nlunit-test", + ] + + cflags = [ "-Wconversion" ] +} diff --git a/src/protocols/interaction_model/tests/TestStatusCode.cpp b/src/protocols/interaction_model/tests/TestStatusCode.cpp new file mode 100644 index 00000000000000..4b89e0f4b1acfb --- /dev/null +++ b/src/protocols/interaction_model/tests/TestStatusCode.cpp @@ -0,0 +1,135 @@ +/* + * + * 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. + */ + +#include + +#include +#include +#include +#include + +#include + +using namespace ::chip; +using namespace ::chip::Protocols::InteractionModel; + +namespace { + +void TestStatusBasicValues(nlTestSuite * inSuite, void * inContext) +{ + NL_TEST_ASSERT_EQUALS(inSuite, static_cast(Status::Success), 0); + NL_TEST_ASSERT_EQUALS(inSuite, static_cast(Status::Failure), 1); + NL_TEST_ASSERT_EQUALS(inSuite, static_cast(Status::UnsupportedEndpoint), 0x7f); + NL_TEST_ASSERT_EQUALS(inSuite, static_cast(Status::InvalidInState), 0xcb); +} + +void TestClusterStatusCode(nlTestSuite * inSuite, void * inContext) +{ + // Basic usage as a Status. + { + ClusterStatusCode status_code_success{ Status::Success }; + NL_TEST_ASSERT_EQUALS(inSuite, status_code_success, Status::Success); + NL_TEST_ASSERT_EQUALS(inSuite, status_code_success.GetStatus(), Status::Success); + NL_TEST_ASSERT(inSuite, !status_code_success.HasClusterSpecificCode()); + NL_TEST_ASSERT_EQUALS(inSuite, status_code_success.GetClusterSpecificCode(), chip::NullOptional); + NL_TEST_ASSERT(inSuite, status_code_success.IsSuccess()); + + ClusterStatusCode status_code_failure{ Status::Failure }; + NL_TEST_ASSERT_EQUALS(inSuite, status_code_failure, Status::Failure); + NL_TEST_ASSERT_EQUALS(inSuite, status_code_failure.GetStatus(), Status::Failure); + NL_TEST_ASSERT(inSuite, !status_code_failure.HasClusterSpecificCode()); + NL_TEST_ASSERT(inSuite, !status_code_failure.IsSuccess()); + + ClusterStatusCode status_code_unsupported_ep{ Status::UnsupportedEndpoint }; + NL_TEST_ASSERT_EQUALS(inSuite, status_code_unsupported_ep, Status::UnsupportedEndpoint); + NL_TEST_ASSERT_EQUALS(inSuite, status_code_unsupported_ep.GetStatus(), Status::UnsupportedEndpoint); + NL_TEST_ASSERT(inSuite, !status_code_unsupported_ep.HasClusterSpecificCode()); + NL_TEST_ASSERT(inSuite, !status_code_unsupported_ep.IsSuccess()); + + ClusterStatusCode status_code_invalid_in_state{ Status::InvalidInState }; + NL_TEST_ASSERT_EQUALS(inSuite, status_code_invalid_in_state, Status::InvalidInState); + NL_TEST_ASSERT_EQUALS(inSuite, status_code_invalid_in_state.GetStatus(), Status::InvalidInState); + NL_TEST_ASSERT(inSuite, !status_code_invalid_in_state.HasClusterSpecificCode()); + NL_TEST_ASSERT(inSuite, !status_code_invalid_in_state.IsSuccess()); + } + + enum RobotoClusterStatus : uint8_t + { + kSandwichError = 7, + kSauceSuccess = 81, + }; + + // Cluster-specific usage. + { + ClusterStatusCode status_code_success = ClusterStatusCode::ClusterSpecificSuccess(RobotoClusterStatus::kSauceSuccess); + NL_TEST_ASSERT_EQUALS(inSuite, status_code_success, Status::Success); + NL_TEST_ASSERT(inSuite, status_code_success.HasClusterSpecificCode()); + NL_TEST_ASSERT_EQUALS(inSuite, status_code_success.GetClusterSpecificCode(), + static_cast(RobotoClusterStatus::kSauceSuccess)); + NL_TEST_ASSERT(inSuite, status_code_success.IsSuccess()); + + ClusterStatusCode status_code_failure = ClusterStatusCode::ClusterSpecificFailure(RobotoClusterStatus::kSandwichError); + NL_TEST_ASSERT_EQUALS(inSuite, status_code_failure, Status::Failure); + NL_TEST_ASSERT(inSuite, status_code_failure.HasClusterSpecificCode()); + NL_TEST_ASSERT_EQUALS(inSuite, status_code_failure.GetClusterSpecificCode(), + static_cast(RobotoClusterStatus::kSandwichError)); + NL_TEST_ASSERT(inSuite, !status_code_failure.IsSuccess()); + } + + // Copy/Assignment + { + ClusterStatusCode status_code_failure1 = ClusterStatusCode::ClusterSpecificFailure(RobotoClusterStatus::kSandwichError); + ClusterStatusCode status_code_failure2(status_code_failure1); + + NL_TEST_ASSERT_EQUALS(inSuite, status_code_failure1, status_code_failure2); + NL_TEST_ASSERT(inSuite, status_code_failure1.HasClusterSpecificCode()); + NL_TEST_ASSERT(inSuite, status_code_failure2.HasClusterSpecificCode()); + + NL_TEST_ASSERT_EQUALS(inSuite, status_code_failure1.GetClusterSpecificCode(), + static_cast(RobotoClusterStatus::kSandwichError)); + NL_TEST_ASSERT_EQUALS(inSuite, status_code_failure2.GetClusterSpecificCode(), + static_cast(RobotoClusterStatus::kSandwichError)); + + ClusterStatusCode status_code_failure3{ Status::InvalidCommand }; + NL_TEST_ASSERT(inSuite, status_code_failure2 != status_code_failure3); + + status_code_failure3 = status_code_failure2; + NL_TEST_ASSERT_EQUALS(inSuite, status_code_failure2, status_code_failure3); + } +} + +// clang-format off +const nlTest sTests[] = +{ + NL_TEST_DEF("TestStatusBasicValues", TestStatusBasicValues), + NL_TEST_DEF("TestClusterStatusCode", TestClusterStatusCode), + NL_TEST_SENTINEL() +}; +// clang-format on + +nlTestSuite sSuite = { "Test IM Status Code abstractions", &sTests[0], nullptr, nullptr }; +} // namespace + +int TestClusterStatusCode() +{ + nlTestRunner(&sSuite, nullptr); + + return (nlTestRunnerStats(&sSuite)); +} + +CHIP_REGISTER_TEST_SUITE(TestClusterStatusCode) From ad98820b717f4e0d50c8f5c308790ccbdf02591f Mon Sep 17 00:00:00 2001 From: Yufeng Wang Date: Wed, 20 Dec 2023 11:38:49 -0800 Subject: [PATCH 05/29] Return ConnectionFailureException which contains the connection state (#29305) --- src/app/OperationalSessionSetup.cpp | 62 +++++++++++++---- src/app/OperationalSessionSetup.h | 66 +++++++++++++++---- src/protocols/secure_channel/CASESession.cpp | 29 +++++++- src/protocols/secure_channel/CASESession.h | 2 + .../secure_channel/PairingSession.cpp | 4 +- src/protocols/secure_channel/PairingSession.h | 10 ++- .../SessionEstablishmentDelegate.h | 25 +++++++ 7 files changed, 169 insertions(+), 29 deletions(-) diff --git a/src/app/OperationalSessionSetup.cpp b/src/app/OperationalSessionSetup.cpp index 2996cf2dd891d4..179e2a3df5e120 100644 --- a/src/app/OperationalSessionSetup.cpp +++ b/src/app/OperationalSessionSetup.cpp @@ -92,7 +92,8 @@ bool OperationalSessionSetup::AttachToExistingSecureSession() } void OperationalSessionSetup::Connect(Callback::Callback * onConnection, - Callback::Callback * onFailure) + Callback::Callback * onFailure, + Callback::Callback * onSetupFailure) { CHIP_ERROR err = CHIP_NO_ERROR; bool isConnected = false; @@ -102,7 +103,7 @@ void OperationalSessionSetup::Connect(Callback::Callback * on // If anything goes wrong below, we'll trigger failures (including any queued from // a previous iteration which in theory shouldn't happen, but this is written to be more defensive) // - EnqueueConnectionCallbacks(onConnection, onFailure); + EnqueueConnectionCallbacks(onConnection, onFailure, onSetupFailure); switch (mState) { @@ -178,6 +179,18 @@ void OperationalSessionSetup::Connect(Callback::Callback * on } } +void OperationalSessionSetup::Connect(Callback::Callback * onConnection, + Callback::Callback * onFailure) +{ + Connect(onConnection, onFailure, nullptr); +} + +void OperationalSessionSetup::Connect(Callback::Callback * onConnection, + Callback::Callback * onSetupFailure) +{ + Connect(onConnection, nullptr, onSetupFailure); +} + void OperationalSessionSetup::UpdateDeviceData(const Transport::PeerAddress & addr, const ReliableMessageProtocolConfig & config) { #if CHIP_DEVICE_CONFIG_ENABLE_AUTOMATIC_CASE_RETRIES @@ -291,7 +304,8 @@ CHIP_ERROR OperationalSessionSetup::EstablishConnection(const ReliableMessagePro } void OperationalSessionSetup::EnqueueConnectionCallbacks(Callback::Callback * onConnection, - Callback::Callback * onFailure) + Callback::Callback * onFailure, + Callback::Callback * onSetupFailure) { if (onConnection != nullptr) { @@ -302,11 +316,17 @@ void OperationalSessionSetup::EnqueueConnectionCallbacks(Callback::CallbackCancel()); } + + if (onSetupFailure != nullptr) + { + mSetupFailure.Enqueue(onSetupFailure->Cancel()); + } } -void OperationalSessionSetup::DequeueConnectionCallbacks(CHIP_ERROR error, ReleaseBehavior releaseBehavior) +void OperationalSessionSetup::DequeueConnectionCallbacks(CHIP_ERROR error, SessionEstablishmentStage stage, + ReleaseBehavior releaseBehavior) { - Cancelable failureReady, successReady; + Cancelable failureReady, setupFailureReady, successReady; // // Dequeue both failure and success callback lists into temporary stack args before invoking either of them. @@ -314,6 +334,7 @@ void OperationalSessionSetup::DequeueConnectionCallbacks(CHIP_ERROR error, Relea // since the callee may destroy this object as part of that callback. // mConnectionFailure.DequeueAll(failureReady); + mSetupFailure.DequeueAll(setupFailureReady); mConnectionSuccess.DequeueAll(successReady); #if CHIP_DEVICE_CONFIG_ENABLE_AUTOMATIC_CASE_RETRIES @@ -339,13 +360,14 @@ void OperationalSessionSetup::DequeueConnectionCallbacks(CHIP_ERROR error, Relea // DO NOT touch any members of this object after this point. It's dead. - NotifyConnectionCallbacks(failureReady, successReady, error, peerId, performingAddressUpdate, exchangeMgr, - optionalSessionHandle); + NotifyConnectionCallbacks(failureReady, setupFailureReady, successReady, error, stage, peerId, performingAddressUpdate, + exchangeMgr, optionalSessionHandle); } -void OperationalSessionSetup::NotifyConnectionCallbacks(Cancelable & failureReady, Cancelable & successReady, CHIP_ERROR error, - const ScopedNodeId & peerId, bool performingAddressUpdate, - Messaging::ExchangeManager * exchangeMgr, +void OperationalSessionSetup::NotifyConnectionCallbacks(Cancelable & failureReady, Cancelable & setupFailureReady, + Cancelable & successReady, CHIP_ERROR error, + SessionEstablishmentStage stage, const ScopedNodeId & peerId, + bool performingAddressUpdate, Messaging::ExchangeManager * exchangeMgr, const Optional & optionalSessionHandle) { // @@ -367,6 +389,22 @@ void OperationalSessionSetup::NotifyConnectionCallbacks(Cancelable & failureRead } } + while (setupFailureReady.mNext != &setupFailureReady) + { + // We expect that we only have callbacks if we are not performing just address update. + VerifyOrDie(!performingAddressUpdate); + Callback::Callback * cb = Callback::Callback::FromCancelable(setupFailureReady.mNext); + + cb->Cancel(); + + if (error != CHIP_NO_ERROR) + { + // Initialize the ConnnectionFailureInfo object + ConnnectionFailureInfo failureInfo(peerId, error, stage); + cb->mCall(cb->mContext, failureInfo); + } + } + while (successReady.mNext != &successReady) { // We expect that we only have callbacks if we are not performing just address update. @@ -383,7 +421,7 @@ void OperationalSessionSetup::NotifyConnectionCallbacks(Cancelable & failureRead } } -void OperationalSessionSetup::OnSessionEstablishmentError(CHIP_ERROR error) +void OperationalSessionSetup::OnSessionEstablishmentError(CHIP_ERROR error, SessionEstablishmentStage stage) { VerifyOrReturn(mState == State::Connecting, ChipLogError(Discovery, "OnSessionEstablishmentError was called while we were not connecting")); @@ -438,7 +476,7 @@ void OperationalSessionSetup::OnSessionEstablishmentError(CHIP_ERROR error) #endif // CHIP_DEVICE_CONFIG_ENABLE_AUTOMATIC_CASE_RETRIES } - DequeueConnectionCallbacks(error); + DequeueConnectionCallbacks(error, stage); // Do not touch `this` instance anymore; it has been destroyed in DequeueConnectionCallbacks. } diff --git a/src/app/OperationalSessionSetup.h b/src/app/OperationalSessionSetup.h index 2925259066e6db..45b571a08aa633 100644 --- a/src/app/OperationalSessionSetup.h +++ b/src/app/OperationalSessionSetup.h @@ -155,6 +155,19 @@ typedef void (*OnDeviceConnectionRetry)(void * context, const ScopedNodeId & pee class DLL_EXPORT OperationalSessionSetup : public SessionEstablishmentDelegate, public AddressResolve::NodeListener { public: + struct ConnnectionFailureInfo + { + const ScopedNodeId peerId; + CHIP_ERROR error; + SessionEstablishmentStage sessionStage; + + ConnnectionFailureInfo(const ScopedNodeId & peer, CHIP_ERROR err, SessionEstablishmentStage stage) : + peerId(peer), error(err), sessionStage(stage) + {} + }; + + using OnSetupFailure = void (*)(void * context, const ConnnectionFailureInfo & failureInfo); + ~OperationalSessionSetup() override; OperationalSessionSetup(const CASEClientInitParams & params, CASEClientPoolDelegate * clientPool, ScopedNodeId peerId, @@ -180,8 +193,8 @@ class DLL_EXPORT OperationalSessionSetup : public SessionEstablishmentDelegate, * The device is expected to have been commissioned, A CASE session * setup will be triggered. * - * On establishing the session, the callback function `onConnection` will be called. If the - * session setup fails, `onFailure` will be called. + * If session setup succeeds, the callback function `onConnection` will be called. + * If session setup fails, `onFailure` will be called. * * If the session already exists, `onConnection` will be called immediately, * before the Connect call returns. @@ -192,11 +205,28 @@ class DLL_EXPORT OperationalSessionSetup : public SessionEstablishmentDelegate, */ void Connect(Callback::Callback * onConnection, Callback::Callback * onFailure); + /* + * This function can be called to establish a secure session with the device. + * + * The device is expected to have been commissioned, A CASE session + * setup will be triggered. + * + * If session setup succeeds, the callback function `onConnection` will be called. + * If session setup fails, `onSetupFailure` will be called. + * + * If the session already exists, `onConnection` will be called immediately, + * before the Connect call returns. + * + * `onSetupFailure` may be called before the Connect call returns, for error cases that are detected synchronously + * (e.g. inability to start an address lookup). + */ + void Connect(Callback::Callback * onConnection, Callback::Callback * onSetupFailure); + bool IsForAddressUpdate() const { return mPerformingAddressUpdate; } //////////// SessionEstablishmentDelegate Implementation /////////////// void OnSessionEstablished(const SessionHandle & session) override; - void OnSessionEstablishmentError(CHIP_ERROR error) override; + void OnSessionEstablishmentError(CHIP_ERROR error, SessionEstablishmentStage stage) override; ScopedNodeId GetPeerId() const { return mPeerId; } @@ -264,6 +294,7 @@ class DLL_EXPORT OperationalSessionSetup : public SessionEstablishmentDelegate, Callback::CallbackDeque mConnectionSuccess; Callback::CallbackDeque mConnectionFailure; + Callback::CallbackDeque mSetupFailure; OperationalSessionReleaseDelegate * mReleaseDelegate; @@ -306,8 +337,12 @@ class DLL_EXPORT OperationalSessionSetup : public SessionEstablishmentDelegate, void CleanupCASEClient(); + void Connect(Callback::Callback * onConnection, Callback::Callback * onFailure, + Callback::Callback * onSetupFailure); + void EnqueueConnectionCallbacks(Callback::Callback * onConnection, - Callback::Callback * onFailure); + Callback::Callback * onFailure, + Callback::Callback * onSetupFailure); enum class ReleaseBehavior { @@ -316,11 +351,13 @@ class DLL_EXPORT OperationalSessionSetup : public SessionEstablishmentDelegate, }; /* - * This dequeues all failure and success callbacks and appropriately - * invokes either set depending on the value of error. + * This dequeues all failure and success callbacks and appropriately invokes either set depending + * on the value of error. + * + * If error == CHIP_NO_ERROR, only success callbacks are invoked. Otherwise, only failure callbacks are invoked. * - * If error == CHIP_NO_ERROR, only success callbacks are invoked. - * Otherwise, only failure callbacks are invoked. + * The state offers additional context regarding the failure, indicating the specific state in which + * the error occurs. It is only relayed through failure callbacks when the error is not equal to CHIP_NO_ERROR. * * If releaseBehavior is Release, this uses mReleaseDelegate to release * ourselves (aka `this`). As a result any caller should return right away @@ -328,15 +365,22 @@ class DLL_EXPORT OperationalSessionSetup : public SessionEstablishmentDelegate, * * Setting releaseBehavior to DoNotRelease is meant for use from the destructor */ - void DequeueConnectionCallbacks(CHIP_ERROR error, ReleaseBehavior releaseBehavior = ReleaseBehavior::Release); + void DequeueConnectionCallbacks(CHIP_ERROR error, SessionEstablishmentStage stage, + ReleaseBehavior releaseBehavior = ReleaseBehavior::Release); + + void DequeueConnectionCallbacks(CHIP_ERROR error, ReleaseBehavior releaseBehavior = ReleaseBehavior::Release) + { + this->DequeueConnectionCallbacks(error, SessionEstablishmentStage::kNotInKeyExchange, releaseBehavior); + } /** * Helper for DequeueConnectionCallbacks that handles the actual callback * notifications. This happens after the object has been released, if it's * being released. */ - static void NotifyConnectionCallbacks(Callback::Cancelable & failureReady, Callback::Cancelable & successReady, - CHIP_ERROR error, const ScopedNodeId & peerId, bool performingAddressUpdate, + static void NotifyConnectionCallbacks(Callback::Cancelable & failureReady, Callback::Cancelable & setupFailureReady, + Callback::Cancelable & successReady, CHIP_ERROR error, SessionEstablishmentStage stage, + const ScopedNodeId & peerId, bool performingAddressUpdate, Messaging::ExchangeManager * exchangeMgr, const Optional & optionalSessionHandle); diff --git a/src/protocols/secure_channel/CASESession.cpp b/src/protocols/secure_channel/CASESession.cpp index 6e51d000e3822c..296ba0848150c7 100644 --- a/src/protocols/secure_channel/CASESession.cpp +++ b/src/protocols/secure_channel/CASESession.cpp @@ -556,9 +556,11 @@ void CASESession::OnResponseTimeout(ExchangeContext * ec) void CASESession::AbortPendingEstablish(CHIP_ERROR err) { + // This needs to come before Clear() which will reset mState. + SessionEstablishmentStage state = MapCASEStateToSessionEstablishmentStage(mState); Clear(); // Do this last in case the delegate frees us. - NotifySessionEstablishmentError(err); + NotifySessionEstablishmentError(err, state); } CHIP_ERROR CASESession::DeriveSecureSession(CryptoContext & session) const @@ -2255,4 +2257,29 @@ bool CASESession::InvokeBackgroundWorkWatchdog() return watchdogFired; } +// Helper function to map CASESession::State to SessionEstablishmentStage +SessionEstablishmentStage CASESession::MapCASEStateToSessionEstablishmentStage(State caseState) +{ + switch (caseState) + { + case State::kInitialized: + return SessionEstablishmentStage::kNotInKeyExchange; + case State::kSentSigma1: + case State::kSentSigma1Resume: + return SessionEstablishmentStage::kSentSigma1; + case State::kSentSigma2: + case State::kSentSigma2Resume: + return SessionEstablishmentStage::kSentSigma2; + case State::kSendSigma3Pending: + return SessionEstablishmentStage::kReceivedSigma2; + case State::kSentSigma3: + return SessionEstablishmentStage::kSentSigma3; + case State::kHandleSigma3Pending: + return SessionEstablishmentStage::kReceivedSigma3; + // Add more mappings here for other states + default: + return SessionEstablishmentStage::kUnknown; // Default mapping + } +} + } // namespace chip diff --git a/src/protocols/secure_channel/CASESession.h b/src/protocols/secure_channel/CASESession.h index 7453b6b5002dc4..6fc58dfb90dc83 100644 --- a/src/protocols/secure_channel/CASESession.h +++ b/src/protocols/secure_channel/CASESession.h @@ -320,6 +320,8 @@ class DLL_EXPORT CASESession : public Messaging::UnsolicitedMessageHandler, #if CONFIG_BUILD_FOR_HOST_UNIT_TEST Optional mStopHandshakeAtState = Optional::Missing(); #endif // CONFIG_BUILD_FOR_HOST_UNIT_TEST + + SessionEstablishmentStage MapCASEStateToSessionEstablishmentStage(State caseState); }; } // namespace chip diff --git a/src/protocols/secure_channel/PairingSession.cpp b/src/protocols/secure_channel/PairingSession.cpp index 63a1701e66541f..23daea30f2800c 100644 --- a/src/protocols/secure_channel/PairingSession.cpp +++ b/src/protocols/secure_channel/PairingSession.cpp @@ -255,7 +255,7 @@ void PairingSession::Clear() mSessionManager = nullptr; } -void PairingSession::NotifySessionEstablishmentError(CHIP_ERROR error) +void PairingSession::NotifySessionEstablishmentError(CHIP_ERROR error, SessionEstablishmentStage stage) { if (mDelegate == nullptr) { @@ -265,7 +265,7 @@ void PairingSession::NotifySessionEstablishmentError(CHIP_ERROR error) auto * delegate = mDelegate; mDelegate = nullptr; - delegate->OnSessionEstablishmentError(error); + delegate->OnSessionEstablishmentError(error, stage); } void PairingSession::OnSessionReleased() diff --git a/src/protocols/secure_channel/PairingSession.h b/src/protocols/secure_channel/PairingSession.h index 844fa33a41ae68..ffbb6d9966485d 100644 --- a/src/protocols/secure_channel/PairingSession.h +++ b/src/protocols/secure_channel/PairingSession.h @@ -218,10 +218,14 @@ class DLL_EXPORT PairingSession : public SessionDelegate void Clear(); /** - * Notify our delegate about a session establishment error, if we have not - * notified it of an error or success before. + * Notify our delegate about a session establishment error and the stage when the error occurs + * if we have not already notified it of an error or success before. + * + * @param error The error code to report. + * @param stage The stage of the session when the error occurs, defaults to kNotInKeyExchange. */ - void NotifySessionEstablishmentError(CHIP_ERROR error); + void NotifySessionEstablishmentError(CHIP_ERROR error, + SessionEstablishmentStage stage = SessionEstablishmentStage::kNotInKeyExchange); protected: CryptoContext::SessionRole mRole; diff --git a/src/protocols/secure_channel/SessionEstablishmentDelegate.h b/src/protocols/secure_channel/SessionEstablishmentDelegate.h index dc73a0ffe6997d..640dfca745921f 100644 --- a/src/protocols/secure_channel/SessionEstablishmentDelegate.h +++ b/src/protocols/secure_channel/SessionEstablishmentDelegate.h @@ -32,6 +32,18 @@ namespace chip { +enum class SessionEstablishmentStage : uint8_t +{ + kUnknown = 0, + kNotInKeyExchange = 1, + kSentSigma1 = 2, + kReceivedSigma1 = 3, + kSentSigma2 = 4, + kReceivedSigma2 = 5, + kSentSigma3 = 6, + kReceivedSigma3 = 7, +}; + class DLL_EXPORT SessionEstablishmentDelegate { public: @@ -39,9 +51,22 @@ class DLL_EXPORT SessionEstablishmentDelegate * Called when session establishment fails with an error. This will be * called at most once per session establishment and will not be called if * OnSessionEstablished is called. + * + * This overload of OnSessionEstablishmentError is not called directly. It's only called from the default + *. implemetation of the two-argument overload. */ virtual void OnSessionEstablishmentError(CHIP_ERROR error) {} + /** + * Called when session establishment fails with an error and state at the + * failure. This will be called at most once per session establishment and + * will not be called if OnSessionEstablished is called. + */ + virtual void OnSessionEstablishmentError(CHIP_ERROR error, SessionEstablishmentStage stage) + { + OnSessionEstablishmentError(error); + } + /** * Called on start of session establishment process */ From 2544b6e4163c6348a2f8f1ab7d4746a9867042d4 Mon Sep 17 00:00:00 2001 From: C Freeman Date: Wed, 20 Dec 2023 16:13:28 -0500 Subject: [PATCH 06/29] TC-ACE_1.6: Rework test to use TH keys (#30896) * TC-ACE_1.6: Rework test to use TH keys * Restyled by prettier-yaml * renumber steps, fix one missed key --------- Co-authored-by: Restyled.io --- .../suites/certification/Test_TC_ACE_1_6.yaml | 118 ++++++++++-------- 1 file changed, 69 insertions(+), 49 deletions(-) diff --git a/src/app/tests/suites/certification/Test_TC_ACE_1_6.yaml b/src/app/tests/suites/certification/Test_TC_ACE_1_6.yaml index 877d116305da25..7c353c2b2382b5 100644 --- a/src/app/tests/suites/certification/Test_TC_ACE_1_6.yaml +++ b/src/app/tests/suites/certification/Test_TC_ACE_1_6.yaml @@ -51,7 +51,7 @@ tests: saveAs: commissionerNodeId - label: - "Step 1: TH sends KeySetWrite command in the GroupKeyManagement + "Step 1a: TH sends KeySetWrite command in the GroupKeyManagement cluster to DUT using a key that is pre-installed on the TH. GroupKeySet fields are as follows: GroupKeySetID: 0x01a3 GroupKeySecurityPolicy: TrustFirst (0) EpochKey0: @@ -74,11 +74,35 @@ tests: EpochKey2: "hex:d2d1d2d3d4d5d6d7d8d9dadbdcdddedf", EpochStartTime2: 2220002, } + - label: + "Step 1b: TH sends KeySetWrite command in the GroupKeyManagement + cluster to DUT using a key that is pre-installed on the TH. + GroupKeySet fields are as follows: GroupKeySetID: 0x01a1 + GroupKeySecurityPolicy: TrustFirst (0) EpochKey0: + a0d1d2d3d4d5d6d7d8d9dadbdcdddedf EpochStartTime0: 2220000 EpochKey1: + b1d1d2d3d4d5d6d7d8d9dadbdcdddedf EpochStartTime1: 2220001 EpochKey2: + c2d1d2d3d4d5d6d7d8d9dadbdcdddedf EpochStartTime2: 2220002" + cluster: "Group Key Management" + command: "KeySetWrite" + arguments: + values: + - name: GroupKeySet + value: + { + GroupKeySetID: 0x01a1, + GroupKeySecurityPolicy: 0, + EpochKey0: "hex:a0d1d2d3d4d5d6d7d8d9dadbdcdddedf", + EpochStartTime0: 2220000, + EpochKey1: "hex:b1d1d2d3d4d5d6d7d8d9dadbdcdddedf", + EpochStartTime1: 2220001, + EpochKey2: "hex:c2d1d2d3d4d5d6d7d8d9dadbdcdddedf", + EpochStartTime2: 2220002, + } - label: "Step 2: TH binds GroupId to GroupKeySet with entries as follows: List item 1: GroupId: 0x0103, GroupKeySetId: 0x01a3, List item 2: GroupId: - 0x0104, GroupKeySetId: 0x01a3, List item 3: GroupId: 0x0105, + 0x0104, GroupKeySetId: 0x01a4, List item 3: GroupId: 0x0105, GroupKeySetId: 0x01a3" cluster: "Group Key Management" command: "writeAttribute" @@ -86,9 +110,9 @@ tests: arguments: value: [ + { FabricIndex: 0, GroupId: 0x0101, GroupKeySetID: 0x01a1 }, + { FabricIndex: 0, GroupId: 0x0102, GroupKeySetID: 0x01a1 }, { FabricIndex: 0, GroupId: 0x0103, GroupKeySetID: 0x01a3 }, - { FabricIndex: 0, GroupId: 0x0104, GroupKeySetID: 0x01a3 }, - { FabricIndex: 0, GroupId: 0x0105, GroupKeySetID: 0x01a3 }, ] - label: @@ -151,7 +175,7 @@ tests: - label: "Step 5: TH sends a AddGroup Command to the Groups cluster on Endpoint - PIXIT.G.ENDPOINT over CASE with the GroupID field set to 0x0104 and + PIXIT.G.ENDPOINT over CASE with the GroupID field set to 0x0101 and the GroupName set to an empty string" cluster: "Groups" endpoint: Groups.Endpoint @@ -159,7 +183,7 @@ tests: arguments: values: - name: GroupID - value: 0x0104 + value: 0x0101 - name: GroupName value: "" response: @@ -167,7 +191,7 @@ tests: - label: "Step 6: TH sends a AddGroup Command to the Groups cluster with the - GroupID field set to 0x0104 and the GroupName set to an empty string. + GroupID field set to 0x0101 and the GroupName set to an empty string. The command is sent as a group command using GroupID 0x0103" cluster: "Groups" groupId: 0x0103 @@ -175,7 +199,7 @@ tests: arguments: values: - name: GroupID - value: 0x0104 + value: 0x0101 - name: GroupName value: "" @@ -188,26 +212,19 @@ tests: - name: "ms" value: 1000 - #Issue : https://github.com/project-chip/connectedhomeip/issues/27982 - label: "Step 7: TH sends a AddGroup Command to the Groups cluster with the - GroupID field set to 0x0105 and the GroupName set to an empty string. - The command is sent as a group command using GroupID 0x0104" - verification: | - ./chip-tool groups add-group 261 '' 0xffffffffffff0104 1 --trace_decode 1 - - This step does not have any expected outcome as per the spec, Hence no verification logs has been provided. - - Further continuation of this step has been validated using "view group" command in Step 10 - cluster: "LogCommands" - command: "UserPrompt" - PICS: PICS_SKIP_SAMPLE_APP + GroupID field set to 0x0102 and the GroupName set to an empty string. + The command is sent as a group command using GroupID 0x0101" + cluster: "Groups" + groupId: 0x0101 + command: "AddGroup" arguments: values: - - name: "message" - value: "Enter 'y' after success" - - name: "expectedValue" - value: "y" + - name: GroupID + value: 0x0102 + - name: GroupName + value: "" # multicast if the unicast packet is sent immediately after the multicast one. - label: "Wait for AddGroup" @@ -239,7 +256,7 @@ tests: - label: "Step 9: TH sends a ViewGroup Command to the Groups cluster on - Endpoint PIXIT.G.ENDPOINT over CASE with the GroupID set to 0x0104 to + Endpoint PIXIT.G.ENDPOINT over CASE with the GroupID set to 0x0101 to confirm that the AddGroup command from step 6 was successful" cluster: "Groups" endpoint: Groups.Endpoint @@ -247,43 +264,35 @@ tests: arguments: values: - name: GroupID - value: 0x0104 + value: 0x0101 response: values: - name: Status value: 0 - name: GroupID - value: 0x0104 + value: 0x0101 - name: GroupName value: "" - #Issue : https://github.com/project-chip/connectedhomeip/issues/27967 - label: "Step 10: TH sends a ViewGroup Command to the Groups cluster on - Endpoint PIXIT.G.ENDPOINT over CASE with the GroupID set to 0x0105 to + Endpoint PIXIT.G.ENDPOINT over CASE with the GroupID set to 0x0102 to confirm that the AddGroup command from step 7 was not successful" - verification: | - ./chip-tool groups view-group 0x0105 1 0 - - Verify DUT sends a ViewGroupResponse with Status is set to NOT_FOUND on TH(chip-tool) Logs: - - [1685009398.600925][39795:39797] CHIP:DMG: Received Command Response Data, Endpoint=0 Cluster=0x0000_0004 Command=0x0000_0001 - [1685009398.600932][39795:39797] CHIP:TOO: Endpoint: 0 Cluster: 0x0000_0004 Command 0x0000_0001 - [1685009398.600944][39795:39797] CHIP:TOO: ViewGroupResponse: { - [1685009398.600949][39795:39797] CHIP:TOO: status: 139 - [1685009398.600952][39795:39797] CHIP:TOO: groupID: 261 - [1685009398.600955][39795:39797] CHIP:TOO: groupName: - [1685009398.600957][39795:39797] CHIP:TOO: } - [1685009398.600964][39795:39797] CHIP:DMG: ICR moving to [AwaitingDe] - cluster: "LogCommands" - command: "UserPrompt" - PICS: PICS_SKIP_SAMPLE_APP + cluster: "Groups" + endpoint: Groups.Endpoint + command: "ViewGroup" arguments: values: - - name: "message" - value: "Enter 'y' after success" - - name: "expectedValue" - value: "y" + - name: GroupID + value: 0x0102 + response: + values: + - name: Status + value: 139 + - name: GroupID + value: 0x0102 + - name: GroupName + value: "" - label: "Step 11: TH sends a AddGroup Command to the Groups cluster with the @@ -346,3 +355,14 @@ tests: values: - name: GroupKeySetID value: 0x01a3 + + - label: + "Step 16: TH resets the key set by sending the KeySetRemove command to + the GroupKeyManagement cluster over CASE with the following fields: + GroupKeySetID: 0x01a1" + cluster: "Group Key Management" + command: "KeySetRemove" + arguments: + values: + - name: GroupKeySetID + value: 0x01a1 From bd24a657d4aae54febad477cb558d22686438315 Mon Sep 17 00:00:00 2001 From: lpbeliveau-silabs <112982107+lpbeliveau-silabs@users.noreply.github.com> Date: Wed, 20 Dec 2023 19:02:36 -0500 Subject: [PATCH 07/29] [Report Scheduler] Empty node pool handling (#31136) * Changed check for no nodes in pool * Update src/app/reporting/SynchronizedReportSchedulerImpl.cpp Co-authored-by: Boris Zbarsky --------- Co-authored-by: Boris Zbarsky --- src/app/reporting/SynchronizedReportSchedulerImpl.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/app/reporting/SynchronizedReportSchedulerImpl.cpp b/src/app/reporting/SynchronizedReportSchedulerImpl.cpp index 6627cf7116bec3..7dfa84c70e5343 100644 --- a/src/app/reporting/SynchronizedReportSchedulerImpl.cpp +++ b/src/app/reporting/SynchronizedReportSchedulerImpl.cpp @@ -182,6 +182,9 @@ void SynchronizedReportSchedulerImpl::TimerFired() Timestamp now = mTimerDelegate->GetCurrentMonotonicTimestamp(); bool firedEarly = true; + // If there are no handlers registered, no need to do anything. + VerifyOrReturn(mNodesPool.Allocated()); + mNodesPool.ForEachActiveObject([now, &firedEarly](ReadHandlerNode * node) { if (node->GetMinTimestamp() <= now) { @@ -201,8 +204,7 @@ void SynchronizedReportSchedulerImpl::TimerFired() return Loop::Continue; }); - // If there are no handlers registers, no need to schedule the next report - if (mNodesPool.Allocated() && firedEarly) + if (firedEarly) { Timeout timeout = Milliseconds32(0); ReturnOnFailure(CalculateNextReportTimeout(timeout, nullptr, now)); From b7e3bc003871a200439ec9e4525f1d7c94e93e71 Mon Sep 17 00:00:00 2001 From: Karsten Sperling <113487422+ksperling-apple@users.noreply.github.com> Date: Thu, 21 Dec 2023 13:46:14 +1300 Subject: [PATCH 08/29] Darwin: Consistently use ivars in MTRDeviceController and a few other places (#31141) --- .../commands/common/CHIPToolKeypair.mm | 15 ++-- .../pairing/DeviceControllerDelegateBridge.mm | 3 - .../CHIP/MTRAsyncCallbackWorkQueue.mm | 4 + src/darwin/Framework/CHIP/MTRBaseDevice.mm | 4 +- .../Framework/CHIP/MTRDeviceController.mm | 89 +++++++++---------- .../CHIP/MTRThreadOperationalDataset.mm | 13 +-- 6 files changed, 59 insertions(+), 69 deletions(-) diff --git a/examples/darwin-framework-tool/commands/common/CHIPToolKeypair.mm b/examples/darwin-framework-tool/commands/common/CHIPToolKeypair.mm index fccf3d2734407e..4d6f53de9aa08f 100644 --- a/examples/darwin-framework-tool/commands/common/CHIPToolKeypair.mm +++ b/examples/darwin-framework-tool/commands/common/CHIPToolKeypair.mm @@ -12,15 +12,14 @@ static NSString * const kOperationalCredentialsIssuerKeypairStorage = @"ChipToolOpCredsCAKey"; static NSString * const kOperationalCredentialsIPK = @"ChipToolOpCredsIPK"; -@interface CHIPToolKeypair () -@property (nonatomic) chip::Crypto::P256Keypair mKeyPair; -@property (nonatomic) chip::Crypto::P256Keypair mIssuer; -@property (nonatomic) NSData * ipk; -@property (atomic) uint32_t mNow; -@property (nonatomic, readonly) SecKeyRef mPublicKey; -@end +@implementation CHIPToolKeypair { + chip::Crypto::P256Keypair _mKeyPair; + chip::Crypto::P256Keypair _mIssuer; + NSData * _ipk; + uint32_t _mNow; + SecKeyRef _mPublicKey; +} -@implementation CHIPToolKeypair - (instancetype)init { if (self = [super init]) { diff --git a/examples/darwin-framework-tool/commands/pairing/DeviceControllerDelegateBridge.mm b/examples/darwin-framework-tool/commands/pairing/DeviceControllerDelegateBridge.mm index b3476119c224b5..7b9f4369a79c7d 100644 --- a/examples/darwin-framework-tool/commands/pairing/DeviceControllerDelegateBridge.mm +++ b/examples/darwin-framework-tool/commands/pairing/DeviceControllerDelegateBridge.mm @@ -19,9 +19,6 @@ #include "DeviceControllerDelegateBridge.h" #import -@interface CHIPToolDeviceControllerDelegate () -@end - @implementation CHIPToolDeviceControllerDelegate - (void)controller:(MTRDeviceController *)controller statusUpdate:(MTRCommissioningStatus)status { diff --git a/src/darwin/Framework/CHIP/MTRAsyncCallbackWorkQueue.mm b/src/darwin/Framework/CHIP/MTRAsyncCallbackWorkQueue.mm index ece651a21238de..00b6d33788f6c0 100644 --- a/src/darwin/Framework/CHIP/MTRAsyncCallbackWorkQueue.mm +++ b/src/darwin/Framework/CHIP/MTRAsyncCallbackWorkQueue.mm @@ -15,6 +15,10 @@ * limitations under the License. */ +// NOTE: This class was not intended to be part of the public Matter API; +// internally this class has been replaced by MTRAsyncWorkQueue. This code +// remains here simply to preserve API/ABI compatibility. + #import #import diff --git a/src/darwin/Framework/CHIP/MTRBaseDevice.mm b/src/darwin/Framework/CHIP/MTRBaseDevice.mm index d053cc8f007cf8..a4bcf3742c8d6e 100644 --- a/src/darwin/Framework/CHIP/MTRBaseDevice.mm +++ b/src/darwin/Framework/CHIP/MTRBaseDevice.mm @@ -2744,12 +2744,10 @@ - (id)copyWithZone:(NSZone *)zone @end -@interface MTREventReport () { +@implementation MTREventReport { NSNumber * _timestampValue; } -@end -@implementation MTREventReport + (void)initialize { // One of our init methods ends up doing Platform::MemoryAlloc. diff --git a/src/darwin/Framework/CHIP/MTRDeviceController.mm b/src/darwin/Framework/CHIP/MTRDeviceController.mm index 04f92e8e3bdf1a..ba3ec1958a42fd 100644 --- a/src/darwin/Framework/CHIP/MTRDeviceController.mm +++ b/src/darwin/Framework/CHIP/MTRDeviceController.mm @@ -101,31 +101,27 @@ typedef id (^SyncWorkQueueBlockWithReturnValue)(void); typedef BOOL (^SyncWorkQueueBlockWithBoolReturnValue)(void); -@interface MTRDeviceController () { +@implementation MTRDeviceController { // Atomic because it can be touched from multiple threads. std::atomic _storedFabricIndex; -} - -// queue used to serialize all work performed by the MTRDeviceController -@property (atomic, readonly) dispatch_queue_t chipWorkQueue; -@property (readonly) chip::Controller::DeviceCommissioner * cppCommissioner; -@property (readonly) chip::Credentials::PartialDACVerifier * partialDACVerifier; -@property (readonly) chip::Credentials::DefaultDACVerifier * defaultDACVerifier; -@property (readonly) MTRDeviceControllerDelegateBridge * deviceControllerDelegateBridge; -@property (readonly) MTROperationalCredentialsDelegate * operationalCredentialsDelegate; -@property (readonly) MTRP256KeypairBridge signingKeypairBridge; -@property (readonly) MTRP256KeypairBridge operationalKeypairBridge; -@property (readonly) MTRDeviceAttestationDelegateBridge * deviceAttestationDelegateBridge; -@property (readonly) MTRDeviceControllerFactory * factory; -@property (readonly) NSMutableDictionary * nodeIDToDeviceMap; -@property (readonly) os_unfair_lock deviceMapLock; // protects nodeIDToDeviceMap -@property (readonly) MTRCommissionableBrowser * commissionableBrowser; -@property (readonly) MTRAttestationTrustStoreBridge * attestationTrustStoreBridge; + // queue used to serialize all work performed by the MTRDeviceController + dispatch_queue_t _chipWorkQueue; -@end - -@implementation MTRDeviceController + chip::Controller::DeviceCommissioner * _cppCommissioner; + chip::Credentials::PartialDACVerifier * _partialDACVerifier; + chip::Credentials::DefaultDACVerifier * _defaultDACVerifier; + MTRDeviceControllerDelegateBridge * _deviceControllerDelegateBridge; + MTROperationalCredentialsDelegate * _operationalCredentialsDelegate; + MTRP256KeypairBridge _signingKeypairBridge; + MTRP256KeypairBridge _operationalKeypairBridge; + MTRDeviceAttestationDelegateBridge * _deviceAttestationDelegateBridge; + MTRDeviceControllerFactory * _factory; + NSMutableDictionary * _nodeIDToDeviceMap; + os_unfair_lock _deviceMapLock; // protects nodeIDToDeviceMap + MTRCommissionableBrowser * _commissionableBrowser; + MTRAttestationTrustStoreBridge * _attestationTrustStoreBridge; +} - (nullable instancetype)initWithParameters:(MTRDeviceControllerAbstractParameters *)parameters error:(NSError * __autoreleasing *)error { @@ -249,7 +245,7 @@ - (instancetype)initWithFactory:(MTRDeviceControllerFactory *)factory - (BOOL)isRunning { - return self.cppCommissioner != nullptr; + return _cppCommissioner != nullptr; } - (void)shutdown @@ -271,8 +267,8 @@ - (void)cleanupAfterStartup // while calling out into arbitrary invalidation code, snapshot the list of // devices before we start invalidating. os_unfair_lock_lock(&_deviceMapLock); - NSArray * devices = [self.nodeIDToDeviceMap allValues]; - [self.nodeIDToDeviceMap removeAllObjects]; + NSArray * devices = [_nodeIDToDeviceMap allValues]; + [_nodeIDToDeviceMap removeAllObjects]; os_unfair_lock_unlock(&_deviceMapLock); for (MTRDevice * device in devices) { @@ -590,7 +586,7 @@ - (BOOL)setupCommissioningSessionWithPayload:(MTRSetupPayload *)payload chip::NodeId nodeId = [newNodeID unsignedLongLongValue]; self->_operationalCredentialsDelegate->SetDeviceID(nodeId); - auto errorCode = self.cppCommissioner->EstablishPASEConnection(nodeId, [pairingCode UTF8String]); + auto errorCode = self->_cppCommissioner->EstablishPASEConnection(nodeId, [pairingCode UTF8String]); return ![MTRDeviceController checkForError:errorCode logMsg:kErrorPairDevice error:error]; }; @@ -612,7 +608,7 @@ - (BOOL)setupCommissioningSessionWithDiscoveredDevice:(MTRCommissionableBrowserR auto pinCode = static_cast(payload.setupPasscode.unsignedLongValue); params.Value().SetSetupPINCode(pinCode); - errorCode = self.cppCommissioner->EstablishPASEConnection(nodeId, params.Value()); + errorCode = self->_cppCommissioner->EstablishPASEConnection(nodeId, params.Value()); } else { // Try to get a QR code if possible (because it has a better // discriminator, etc), then fall back to manual code if that fails. @@ -630,7 +626,7 @@ - (BOOL)setupCommissioningSessionWithDiscoveredDevice:(MTRCommissionableBrowserR continue; } - errorCode = self.cppCommissioner->EstablishPASEConnection( + errorCode = self->_cppCommissioner->EstablishPASEConnection( nodeId, [pairingCode UTF8String], chip::Controller::DiscoveryType::kDiscoveryNetworkOnly, resolutionData); if (CHIP_NO_ERROR != errorCode) { break; @@ -745,7 +741,7 @@ - (BOOL)commissionNodeWithID:(NSNumber *)nodeID chip::NodeId deviceId = [nodeID unsignedLongLongValue]; self->_operationalCredentialsDelegate->SetDeviceID(deviceId); - auto errorCode = self.cppCommissioner->Commission(deviceId, params); + auto errorCode = self->_cppCommissioner->Commission(deviceId, params); return ![MTRDeviceController checkForError:errorCode logMsg:kErrorPairDevice error:error]; }; @@ -762,7 +758,7 @@ - (BOOL)continueCommissioningDevice:(void *)device : chip::Credentials::AttestationVerificationResult::kSuccess; auto deviceProxy = static_cast(device); - auto errorCode = self.cppCommissioner->ContinueCommissioningAfterDeviceAttestation(deviceProxy, + auto errorCode = self->_cppCommissioner->ContinueCommissioningAfterDeviceAttestation(deviceProxy, ignoreAttestationFailure ? chip::Credentials::AttestationVerificationResult::kSuccess : lastAttestationResult); return ![MTRDeviceController checkForError:errorCode logMsg:kErrorPairDevice error:error]; }; @@ -774,7 +770,7 @@ - (BOOL)cancelCommissioningForNodeID:(NSNumber *)nodeID error:(NSError * __autor { auto block = ^BOOL { self->_operationalCredentialsDelegate->ResetDeviceID(); - auto errorCode = self.cppCommissioner->StopPairing([nodeID unsignedLongLongValue]); + auto errorCode = self->_cppCommissioner->StopPairing([nodeID unsignedLongLongValue]); return ![MTRDeviceController checkForError:errorCode logMsg:kErrorStopPairing error:error]; }; @@ -784,7 +780,7 @@ - (BOOL)cancelCommissioningForNodeID:(NSNumber *)nodeID error:(NSError * __autor - (BOOL)startBrowseForCommissionables:(id)delegate queue:(dispatch_queue_t)queue { auto block = ^BOOL { - VerifyOrReturnValue(self.commissionableBrowser == nil, NO); + VerifyOrReturnValue(self->_commissionableBrowser == nil, NO); auto commissionableBrowser = [[MTRCommissionableBrowser alloc] initWithDelegate:delegate controller:self queue:queue]; VerifyOrReturnValue([commissionableBrowser start], NO); @@ -799,9 +795,9 @@ - (BOOL)startBrowseForCommissionables:(id)dele - (BOOL)stopBrowseForCommissionables { auto block = ^BOOL { - VerifyOrReturnValue(self.commissionableBrowser != nil, NO); + VerifyOrReturnValue(self->_commissionableBrowser != nil, NO); - auto commissionableBrowser = self.commissionableBrowser; + auto commissionableBrowser = self->_commissionableBrowser; VerifyOrReturnValue([commissionableBrowser stop], NO); self->_commissionableBrowser = nil; @@ -845,7 +841,7 @@ - (MTRBaseDevice *)baseDeviceForNodeID:(NSNumber *)nodeID - (MTRDevice *)deviceForNodeID:(NSNumber *)nodeID { os_unfair_lock_lock(&_deviceMapLock); - MTRDevice * deviceToReturn = self.nodeIDToDeviceMap[nodeID]; + MTRDevice * deviceToReturn = _nodeIDToDeviceMap[nodeID]; if (!deviceToReturn) { deviceToReturn = [[MTRDevice alloc] initWithNodeID:nodeID controller:self]; // If we're not running, don't add the device to our map. That would @@ -853,7 +849,7 @@ - (MTRDevice *)deviceForNodeID:(NSNumber *)nodeID // which will be in exactly the state it would be in if it were created // while we were running and then we got shut down. if ([self isRunning]) { - self.nodeIDToDeviceMap[nodeID] = deviceToReturn; + _nodeIDToDeviceMap[nodeID] = deviceToReturn; } } os_unfair_lock_unlock(&_deviceMapLock); @@ -864,12 +860,13 @@ - (MTRDevice *)deviceForNodeID:(NSNumber *)nodeID - (void)removeDevice:(MTRDevice *)device { os_unfair_lock_lock(&_deviceMapLock); - MTRDevice * deviceToRemove = self.nodeIDToDeviceMap[device.nodeID]; + auto * nodeID = device.nodeID; + MTRDevice * deviceToRemove = _nodeIDToDeviceMap[nodeID]; if (deviceToRemove == device) { [deviceToRemove invalidate]; - self.nodeIDToDeviceMap[device.nodeID] = nil; + _nodeIDToDeviceMap[nodeID] = nil; } else { - MTR_LOG_ERROR("Error: Cannot remove device %p with nodeID %llu", device, device.nodeID.unsignedLongLongValue); + MTR_LOG_ERROR("Error: Cannot remove device %p with nodeID %llu", device, nodeID.unsignedLongLongValue); } os_unfair_lock_unlock(&_deviceMapLock); } @@ -935,7 +932,7 @@ - (NSData * _Nullable)attestationChallengeForDeviceID:(NSNumber *)deviceID auto block = ^NSData * { chip::CommissioneeDeviceProxy * deviceProxy; - auto errorCode = self.cppCommissioner->GetDeviceBeingCommissioned([deviceID unsignedLongLongValue], &deviceProxy); + auto errorCode = self->_cppCommissioner->GetDeviceBeingCommissioned([deviceID unsignedLongLongValue], &deviceProxy); VerifyOrReturnValue(![MTRDeviceController checkForError:errorCode logMsg:kErrorGetCommissionee error:nil], nil); uint8_t challengeBuffer[chip::Crypto::kAES_CCM128_Key_Length]; @@ -1098,7 +1095,7 @@ - (void)asyncGetCommissionerOnMatterQueue:(void (^)(chip::Controller::DeviceComm return; } - block(self.cppCommissioner); + block(self->_cppCommissioner); }); } @@ -1208,7 +1205,7 @@ - (void)operationalInstanceAdded:(chip::NodeId)nodeID // Don't use deviceForNodeID here, because we don't want to create the // device if it does not already exist. os_unfair_lock_lock(&_deviceMapLock); - MTRDevice * device = self.nodeIDToDeviceMap[@(nodeID)]; + MTRDevice * device = _nodeIDToDeviceMap[@(nodeID)]; os_unfair_lock_unlock(&_deviceMapLock); if (device == nil) { @@ -1400,7 +1397,7 @@ - (BOOL)pairDevice:(uint64_t)deviceID VerifyOrReturnValue(![MTRDeviceController checkForError:errorCode logMsg:kErrorSetupCodeGen error:error], NO); self->_operationalCredentialsDelegate->SetDeviceID(deviceID); - errorCode = self.cppCommissioner->EstablishPASEConnection(deviceID, manualPairingCode.c_str()); + errorCode = self->_cppCommissioner->EstablishPASEConnection(deviceID, manualPairingCode.c_str()); return ![MTRDeviceController checkForError:errorCode logMsg:kErrorPairDevice error:error]; }; @@ -1421,7 +1418,7 @@ - (BOOL)pairDevice:(uint64_t)deviceID self->_operationalCredentialsDelegate->SetDeviceID(deviceID); auto params = chip::RendezvousParameters().SetSetupPINCode(setupPINCode).SetPeerAddress(peerAddress); - auto errorCode = self.cppCommissioner->EstablishPASEConnection(deviceID, params); + auto errorCode = self->_cppCommissioner->EstablishPASEConnection(deviceID, params); return ![MTRDeviceController checkForError:errorCode logMsg:kErrorPairDevice error:error]; }; @@ -1432,7 +1429,7 @@ - (BOOL)pairDevice:(uint64_t)deviceID onboardingPayload:(NSString *)onboardingPa { auto block = ^BOOL { self->_operationalCredentialsDelegate->SetDeviceID(deviceID); - auto errorCode = self.cppCommissioner->EstablishPASEConnection(deviceID, [onboardingPayload UTF8String]); + auto errorCode = self->_cppCommissioner->EstablishPASEConnection(deviceID, [onboardingPayload UTF8String]); return ![MTRDeviceController checkForError:errorCode logMsg:kErrorPairDevice error:error]; }; @@ -1468,7 +1465,7 @@ - (BOOL)openPairingWindow:(uint64_t)deviceID duration:(NSUInteger)duration error auto block = ^BOOL { auto errorCode = chip::Controller::AutoCommissioningWindowOpener::OpenBasicCommissioningWindow( - self.cppCommissioner, deviceID, chip::System::Clock::Seconds16(static_cast(duration))); + self->_cppCommissioner, deviceID, chip::System::Clock::Seconds16(static_cast(duration))); return ![MTRDeviceController checkForError:errorCode logMsg:kErrorOpenPairingWindow error:error]; }; @@ -1508,7 +1505,7 @@ - (NSString *)openPairingWindowWithPIN:(uint64_t)deviceID auto block = ^NSString * { chip::SetupPayload setupPayload; - auto errorCode = chip::Controller::AutoCommissioningWindowOpener::OpenCommissioningWindow(self.cppCommissioner, deviceID, + auto errorCode = chip::Controller::AutoCommissioningWindowOpener::OpenCommissioningWindow(self->_cppCommissioner, deviceID, chip::System::Clock::Seconds16(static_cast(duration)), chip::Crypto::kSpake2p_Min_PBKDF_Iterations, static_cast(discriminator), chip::MakeOptional(static_cast(setupPIN)), chip::NullOptional, setupPayload); diff --git a/src/darwin/Framework/CHIP/MTRThreadOperationalDataset.mm b/src/darwin/Framework/CHIP/MTRThreadOperationalDataset.mm index bb5db0af9a977b..a547321d88c2e0 100644 --- a/src/darwin/Framework/CHIP/MTRThreadOperationalDataset.mm +++ b/src/darwin/Framework/CHIP/MTRThreadOperationalDataset.mm @@ -29,14 +29,9 @@ size_t const MTRSizeThreadPSKc = chip::Thread::kSizePSKc; size_t const MTRSizeThreadPANID = 2; // Thread's PAN ID is 2 bytes -@interface MTRThreadOperationalDataset () - -@property (readonly) chip::Thread::OperationalDataset cppThreadOperationalDataset; -@property (nonatomic, copy) NSNumber * channelNumber; - -@end - -@implementation MTRThreadOperationalDataset +@implementation MTRThreadOperationalDataset { + chip::Thread::OperationalDataset _cppThreadOperationalDataset; +} - (instancetype _Nullable)initWithNetworkName:(NSString *)networkName extendedPANID:(NSData *)extendedPANID @@ -157,7 +152,7 @@ @implementation MTRThreadOperationalDataset (Deprecated) - (void)setChannel:(uint16_t)channel { - self.channelNumber = @(channel); + _channelNumber = @(channel); } - (uint16_t)channel From 711ca50d4f2937b62799e89dd80218a4f94ff3be Mon Sep 17 00:00:00 2001 From: lpbeliveau-silabs <112982107+lpbeliveau-silabs@users.noreply.github.com> Date: Wed, 20 Dec 2023 20:00:52 -0500 Subject: [PATCH 09/29] [ReportScheduler] Renaming mTestNextReportTimestamp (#31137) * Renaming mTestNextReportTimestamp since we now use it outside of tests * Updated member description in .h * Update src/app/reporting/SynchronizedReportSchedulerImpl.h Co-authored-by: Boris Zbarsky * Restyled by clang-format --------- Co-authored-by: Boris Zbarsky Co-authored-by: Restyled.io --- .../SynchronizedReportSchedulerImpl.cpp | 6 ++-- .../SynchronizedReportSchedulerImpl.h | 5 ++-- src/app/tests/TestReportScheduler.cpp | 28 +++++++++---------- 3 files changed, 20 insertions(+), 19 deletions(-) diff --git a/src/app/reporting/SynchronizedReportSchedulerImpl.cpp b/src/app/reporting/SynchronizedReportSchedulerImpl.cpp index 7dfa84c70e5343..a4066303cf23f1 100644 --- a/src/app/reporting/SynchronizedReportSchedulerImpl.cpp +++ b/src/app/reporting/SynchronizedReportSchedulerImpl.cpp @@ -48,8 +48,8 @@ void SynchronizedReportSchedulerImpl::OnTransitionToIdle() { Timestamp now = mTimerDelegate->GetCurrentMonotonicTimestamp(); uint32_t targetIdleInterval = static_cast(ICD_SLEEP_TIME_JITTER_MS); - VerifyOrReturn(now >= mTestNextReportTimestamp); - if (((mTestNextReportTimestamp - now) < Seconds16(targetIdleInterval)) && (now > mNextMinTimestamp)) + VerifyOrReturn(now >= mNextReportTimestamp); + if (((mNextReportTimestamp - now) < Seconds16(targetIdleInterval)) && (now > mNextMinTimestamp)) { // If the next report is due in less than the idle mode interval and we are past the min interval, we can just send it now CancelReport(); @@ -67,7 +67,7 @@ CHIP_ERROR SynchronizedReportSchedulerImpl::ScheduleReport(Timeout timeout, Read return CHIP_NO_ERROR; } ReturnErrorOnFailure(mTimerDelegate->StartTimer(this, timeout)); - mTestNextReportTimestamp = now + timeout; + mNextReportTimestamp = now + timeout; return CHIP_NO_ERROR; } diff --git a/src/app/reporting/SynchronizedReportSchedulerImpl.h b/src/app/reporting/SynchronizedReportSchedulerImpl.h index 1240395bb0fcea..59a675fab02c31 100644 --- a/src/app/reporting/SynchronizedReportSchedulerImpl.h +++ b/src/app/reporting/SynchronizedReportSchedulerImpl.h @@ -58,8 +58,9 @@ class SynchronizedReportSchedulerImpl : public ReportSchedulerImpl, public Timer Timestamp mNextMaxTimestamp = Milliseconds64(0); Timestamp mNextMinTimestamp = Milliseconds64(0); - // Timestamp of the next report to be scheduled, only used for testing - Timestamp mTestNextReportTimestamp = Milliseconds64(0); + // Timestamp of the next report to be scheduled, used by OnTransitionToIdle to determine whether we should emit a report before + // the device goes to idle mode + Timestamp mNextReportTimestamp = Milliseconds64(0); }; } // namespace reporting diff --git a/src/app/tests/TestReportScheduler.cpp b/src/app/tests/TestReportScheduler.cpp index 1c4d96660171f4..af6f367af8ccc6 100644 --- a/src/app/tests/TestReportScheduler.cpp +++ b/src/app/tests/TestReportScheduler.cpp @@ -494,7 +494,7 @@ class TestReportScheduler // Validates that the highest reportable min is selected as the common min interval (0 here) NL_TEST_ASSERT(aSuite, syncScheduler.mNextMinTimestamp == node1->GetMinTimestamp()); // Validates that the next report emission is scheduled on the common max timestamp - NL_TEST_ASSERT(aSuite, syncScheduler.mTestNextReportTimestamp == syncScheduler.mNextMaxTimestamp); + NL_TEST_ASSERT(aSuite, syncScheduler.mNextReportTimestamp == syncScheduler.mNextMaxTimestamp); // Simulate waiting for the max interval to expire (2s) sTestTimerSynchronizedDelegate.IncrementMockTimestamp(System::Clock::Milliseconds64(2000)); @@ -515,7 +515,7 @@ class TestReportScheduler // Validate that the max timestamp for both readhandlers got updated and that the next report emission is scheduled on // the new max timestamp for readhandler1 NL_TEST_ASSERT(aSuite, node1->GetMaxTimestamp() > sTestTimerSynchronizedDelegate.GetCurrentMonotonicTimestamp()); - NL_TEST_ASSERT(aSuite, syncScheduler.mTestNextReportTimestamp == node1->GetMaxTimestamp()); + NL_TEST_ASSERT(aSuite, syncScheduler.mNextReportTimestamp == node1->GetMaxTimestamp()); // Confirm behavior when a read handler becomes dirty readHandler2->ForceDirtyState(); @@ -530,7 +530,7 @@ class TestReportScheduler // Confirm that the next report emission is scheduled on the min timestamp of readHandler2 (now) as it is the highest // reportable - NL_TEST_ASSERT(aSuite, syncScheduler.mTestNextReportTimestamp == node2->GetMinTimestamp()); + NL_TEST_ASSERT(aSuite, syncScheduler.mNextReportTimestamp == node2->GetMinTimestamp()); NL_TEST_ASSERT(aSuite, node1->CanBeSynced() == true); // Simulate a report emission for readHandler1 @@ -570,7 +570,7 @@ class TestReportScheduler // Validate next report scheduled on the max timestamp of readHandler1 NL_TEST_ASSERT(aSuite, node1->GetMaxTimestamp() > sTestTimerSynchronizedDelegate.GetCurrentMonotonicTimestamp()); - NL_TEST_ASSERT(aSuite, syncScheduler.mTestNextReportTimestamp == node1->GetMaxTimestamp()); + NL_TEST_ASSERT(aSuite, syncScheduler.mNextReportTimestamp == node1->GetMaxTimestamp()); // Simulate readHandler1 becoming dirty after less than 1 seconds, since it is reportable now, this will Schedule an Engine // run immediately @@ -586,7 +586,7 @@ class TestReportScheduler NL_TEST_ASSERT(aSuite, !syncScheduler.IsReportableNow(readHandler2)); // The next report should be scheduler on the max timestamp of readHandler1 - NL_TEST_ASSERT(aSuite, syncScheduler.mTestNextReportTimestamp == node1->GetMaxTimestamp()); + NL_TEST_ASSERT(aSuite, syncScheduler.mNextReportTimestamp == node1->GetMaxTimestamp()); sTestTimerSynchronizedDelegate.IncrementMockTimestamp(System::Clock::Milliseconds64(2000)); // Confirm node 2 can now be synced since the scheduler timer has fired on the max timestamp of readHandler1 @@ -598,7 +598,7 @@ class TestReportScheduler readHandler2->mObserver->OnSubscriptionReportSent(readHandler2); NL_TEST_ASSERT(aSuite, !syncScheduler.IsReportableNow(readHandler1)); NL_TEST_ASSERT(aSuite, !syncScheduler.IsReportableNow(readHandler2)); - NL_TEST_ASSERT(aSuite, syncScheduler.mTestNextReportTimestamp == node1->GetMaxTimestamp()); + NL_TEST_ASSERT(aSuite, syncScheduler.mNextReportTimestamp == node1->GetMaxTimestamp()); // Simulate a new ReadHandler being added with a min timestamp that will force a conflict @@ -615,7 +615,7 @@ class TestReportScheduler // Since the min interval on readHandler3 is 2, it should be above the current max timestamp, therefore the next report // should still happen on the max timestamp of readHandler1 and the sync should be done on future reports - NL_TEST_ASSERT(aSuite, syncScheduler.mTestNextReportTimestamp == node1->GetMaxTimestamp()); + NL_TEST_ASSERT(aSuite, syncScheduler.mNextReportTimestamp == node1->GetMaxTimestamp()); // The min timestamp should also not have changed since the min of readhandler3 is higher than the current max NL_TEST_ASSERT(aSuite, syncScheduler.mNextMinTimestamp == node2->GetMinTimestamp()); @@ -635,7 +635,7 @@ class TestReportScheduler NL_TEST_ASSERT(aSuite, !syncScheduler.IsReportableNow(readHandler2)); // Confirm that next report is scheduled on the max timestamp of readHandler3 and other 2 readHandlers are synced - NL_TEST_ASSERT(aSuite, syncScheduler.mTestNextReportTimestamp == node3->GetMaxTimestamp()); + NL_TEST_ASSERT(aSuite, syncScheduler.mNextReportTimestamp == node3->GetMaxTimestamp()); sTestTimerSynchronizedDelegate.IncrementMockTimestamp(System::Clock::Milliseconds64(2000)); // Confirm nodes 1 and 2 can now be synced since the scheduler timer has fired on the max timestamp of readHandler1 @@ -655,7 +655,7 @@ class TestReportScheduler NL_TEST_ASSERT(aSuite, !syncScheduler.IsReportableNow(readHandler1)); NL_TEST_ASSERT(aSuite, !syncScheduler.IsReportableNow(readHandler2)); NL_TEST_ASSERT(aSuite, !syncScheduler.IsReportableNow(readHandler3)); - NL_TEST_ASSERT(aSuite, syncScheduler.mTestNextReportTimestamp == node1->GetMaxTimestamp()); + NL_TEST_ASSERT(aSuite, syncScheduler.mNextReportTimestamp == node1->GetMaxTimestamp()); // Now simulate a new readHandler being added with a max forcing a conflict ReadHandler * readHandler4 = @@ -667,7 +667,7 @@ class TestReportScheduler NL_TEST_ASSERT(aSuite, syncScheduler.GetNumReadHandlers() == 4); // Confirm next report is scheduled on the max timestamp of readHandler4 - NL_TEST_ASSERT(aSuite, syncScheduler.mTestNextReportTimestamp == node4->GetMaxTimestamp()); + NL_TEST_ASSERT(aSuite, syncScheduler.mNextReportTimestamp == node4->GetMaxTimestamp()); sTestTimerSynchronizedDelegate.IncrementMockTimestamp(System::Clock::Milliseconds64(1100)); // Confirm node 1 and 2 can now be synced since the scheduler timer has fired on the max timestamp of readHandler4 @@ -714,7 +714,7 @@ class TestReportScheduler NL_TEST_ASSERT(aSuite, !syncScheduler.IsReportableNow(readHandler4)); // Next emission should be scheduled on the max timestamp of readHandler4 as it is the most restrictive - NL_TEST_ASSERT(aSuite, syncScheduler.mTestNextReportTimestamp == node4->GetMaxTimestamp()); + NL_TEST_ASSERT(aSuite, syncScheduler.mNextReportTimestamp == node4->GetMaxTimestamp()); sTestTimerSynchronizedDelegate.IncrementMockTimestamp(System::Clock::Milliseconds64(1000)); // Confirm node 1 and 2 can now be synced since the scheduler timer has fired on the max timestamp of readHandler4 @@ -761,7 +761,7 @@ class TestReportScheduler NL_TEST_ASSERT(aSuite, !syncScheduler.IsReportableNow(readHandler2)); // Confirm next report is scheduled on the max timestamp of readHandler1 and readhandler2 is not synced - NL_TEST_ASSERT(aSuite, syncScheduler.mTestNextReportTimestamp == node1->GetMaxTimestamp()); + NL_TEST_ASSERT(aSuite, syncScheduler.mNextReportTimestamp == node1->GetMaxTimestamp()); // Node 2's sync timestamp should have remained unaffected since its min is higher NL_TEST_ASSERT(aSuite, node2->CanBeSynced() == false); @@ -775,7 +775,7 @@ class TestReportScheduler syncScheduler.OnSubscriptionReportSent(readHandler1); NL_TEST_ASSERT(aSuite, !syncScheduler.IsReportableNow(readHandler1)); NL_TEST_ASSERT(aSuite, !syncScheduler.IsReportableNow(readHandler2)); - NL_TEST_ASSERT(aSuite, syncScheduler.mTestNextReportTimestamp == node2->GetMinTimestamp()); + NL_TEST_ASSERT(aSuite, syncScheduler.mNextReportTimestamp == node2->GetMinTimestamp()); sTestTimerSynchronizedDelegate.IncrementMockTimestamp(System::Clock::Milliseconds64(1000)); NL_TEST_ASSERT(aSuite, node1->CanBeSynced() == true); @@ -786,7 +786,7 @@ class TestReportScheduler syncScheduler.OnSubscriptionReportSent(readHandler1); syncScheduler.OnSubscriptionReportSent(readHandler2); - NL_TEST_ASSERT(aSuite, syncScheduler.mTestNextReportTimestamp == node1->GetMaxTimestamp()); + NL_TEST_ASSERT(aSuite, syncScheduler.mNextReportTimestamp == node1->GetMaxTimestamp()); NL_TEST_ASSERT(aSuite, node2->CanBeSynced() == false); syncScheduler.UnregisterAllHandlers(); From b22a39645b72b26621467dd161209fc08c83fad6 Mon Sep 17 00:00:00 2001 From: joonhaengHeo <85541460+joonhaengHeo@users.noreply.github.com> Date: Thu, 21 Dec 2023 15:23:20 +0900 Subject: [PATCH 10/29] [ICD] Skip Get RegistrationInfo when parameter is already added (#31123) * Skip Get RegistrationInfo when param is already added * Remove onICDRegistrationInfoRequired callback in chip-tool * Restyled by clang-format * Add comment * Restyled by whitespace --------- Co-authored-by: Restyled.io --- examples/chip-tool/commands/pairing/PairingCommand.cpp | 9 ++------- examples/chip-tool/commands/pairing/PairingCommand.h | 1 - src/controller/AutoCommissioner.cpp | 5 +++++ src/controller/DevicePairingDelegate.h | 2 +- 4 files changed, 8 insertions(+), 9 deletions(-) diff --git a/examples/chip-tool/commands/pairing/PairingCommand.cpp b/examples/chip-tool/commands/pairing/PairingCommand.cpp index e15be0a1e8ae3c..e480b7a7c707c5 100644 --- a/examples/chip-tool/commands/pairing/PairingCommand.cpp +++ b/examples/chip-tool/commands/pairing/PairingCommand.cpp @@ -403,13 +403,6 @@ void PairingCommand::OnCommissioningComplete(NodeId nodeId, CHIP_ERROR err) SetCommandExitStatus(err); } -void PairingCommand::OnICDRegistrationInfoRequired() -{ - // Since we compute our ICD Registration info up front, we can call ICDRegistrationInfoReady() directly. - CurrentCommissioner().ICDRegistrationInfoReady(); - mDeviceIsICD = true; -} - void PairingCommand::OnICDRegistrationComplete(NodeId nodeId, uint32_t icdCounter) { char icdSymmetricKeyHex[chip::Crypto::kAES_CCM128_Key_Length * 2 + 1]; @@ -437,6 +430,8 @@ void PairingCommand::OnICDRegistrationComplete(NodeId nodeId, uint32_t icdCounte return; } + mDeviceIsICD = true; + ChipLogProgress(chipTool, "Saved ICD Symmetric key for " ChipLogFormatX64, ChipLogValueX64(nodeId)); ChipLogProgress(chipTool, "ICD Registration Complete for device " ChipLogFormatX64 " / Check-In NodeID: " ChipLogFormatX64 diff --git a/examples/chip-tool/commands/pairing/PairingCommand.h b/examples/chip-tool/commands/pairing/PairingCommand.h index be4722228a2bc8..145aa6ffd901ae 100644 --- a/examples/chip-tool/commands/pairing/PairingCommand.h +++ b/examples/chip-tool/commands/pairing/PairingCommand.h @@ -195,7 +195,6 @@ class PairingCommand : public CHIPCommand, void OnPairingComplete(CHIP_ERROR error) override; void OnPairingDeleted(CHIP_ERROR error) override; void OnCommissioningComplete(NodeId deviceId, CHIP_ERROR error) override; - void OnICDRegistrationInfoRequired() override; void OnICDRegistrationComplete(NodeId deviceId, uint32_t icdCounter) override; /////////// DeviceDiscoveryDelegate Interface ///////// diff --git a/src/controller/AutoCommissioner.cpp b/src/controller/AutoCommissioner.cpp index 1b286a400bccdb..5f289c662e696a 100644 --- a/src/controller/AutoCommissioner.cpp +++ b/src/controller/AutoCommissioner.cpp @@ -409,6 +409,11 @@ CommissioningStage AutoCommissioner::GetNextCommissioningStageInternal(Commissio case CommissioningStage::kConfigureTrustedTimeSource: if (mNeedIcdRegistration) { + if (mParams.GetICDCheckInNodeId().HasValue() && mParams.GetICDMonitoredSubject().HasValue() && + mParams.GetICDSymmetricKey().HasValue()) + { + return CommissioningStage::kICDRegistration; + } return CommissioningStage::kICDGetRegistrationInfo; } return GetNextCommissioningStageInternal(CommissioningStage::kICDSendStayActive, lastErr); diff --git a/src/controller/DevicePairingDelegate.h b/src/controller/DevicePairingDelegate.h index 31a906485fd904..6cf28d95892f79 100644 --- a/src/controller/DevicePairingDelegate.h +++ b/src/controller/DevicePairingDelegate.h @@ -125,7 +125,7 @@ class DLL_EXPORT DevicePairingDelegate * using CommissioningDelegate.SetCommissioningParameters(), and then call DeviceCommissioner.ICDRegistrationInfoReady() * in order to resume the commissioning process. * - * The implementation may set the credentials before start commissioning, and call ICDRegistrationInfoReady() directly. + * Not called if the ICD registration info is provided up front. */ virtual void OnICDRegistrationInfoRequired() {} From adafaf2b1eb28d980b12915e2af7b4e6e1ff2ea9 Mon Sep 17 00:00:00 2001 From: bhmanda-silabs <107180296+bhmanda-silabs@users.noreply.github.com> Date: Thu, 21 Dec 2023 21:22:22 +0530 Subject: [PATCH 11/29] [Silabs] - Support for 917 SoC combined OTA upgrade (#30335) * Added OTA support for 917 SoC platform * Added SIWX_917 macro for OTAConfig.cpp * Addressed review comments * Remove commented code * Restyled by whitespace * Restyled by clang-format * Restyled by gn * Added fix for NotifyupdateApplied command and TA alone image upgrade reset issue * Modified config file as per slc_1.2 * Restyled by whitespace * Restyled by clang-format * Removed SLC file Specific changes --------- Co-authored-by: Restyled.io Co-authored-by: kirankha --- examples/platform/silabs/OTAConfig.cpp | 12 +- examples/platform/silabs/SiWx917/BUILD.gn | 9 +- .../silabs/SiWx917/SiWx917/sl_wifi_if.c | 10 ++ src/platform/silabs/OTAImageProcessorImpl.h | 1 + src/platform/silabs/SiWx917/BUILD.gn | 5 +- .../silabs/SiWx917/OTAImageProcessorImpl.cpp | 113 ++++++++++-------- third_party/silabs/SiWx917_sdk.gni | 10 ++ 7 files changed, 104 insertions(+), 56 deletions(-) diff --git a/examples/platform/silabs/OTAConfig.cpp b/examples/platform/silabs/OTAConfig.cpp index 91c84054220b9c..adc6f23abb4606 100644 --- a/examples/platform/silabs/OTAConfig.cpp +++ b/examples/platform/silabs/OTAConfig.cpp @@ -17,10 +17,18 @@ */ #include "OTAConfig.h" +#include + +#ifndef SIWX_917 #include "application_properties.h" -#include +#if defined(SL_COMPONENT_CATALOG_PRESENT) +#include "sl_component_catalog.h" +#endif + +// Only include app properties if the Gecko SDK component that does it automatically isn't present +#if !defined(SL_CATALOG_GECKO_BOOTLOADER_INTERFACE_PRESENT) // Header used for building the image GBL file #define APP_PROPERTIES_VERSION 1 #define APP_PROPERTIES_ID \ @@ -65,6 +73,8 @@ __attribute__((used)) ApplicationProperties_t sl_app_properties = { /// Pointer to Long Token Data Section .longTokenSectionAddress = NULL, }; +#endif // SL_CATALOG_GECKO_BOOTLOADER_INTERFACE_PRESENT +#endif // SIWX_917 // Global OTA objects chip::DefaultOTARequestor gRequestorCore; diff --git a/examples/platform/silabs/SiWx917/BUILD.gn b/examples/platform/silabs/SiWx917/BUILD.gn index 36a5aef1a860c1..99be69fbbc9b14 100644 --- a/examples/platform/silabs/SiWx917/BUILD.gn +++ b/examples/platform/silabs/SiWx917/BUILD.gn @@ -144,10 +144,9 @@ config("siwx917-common-config") { defines += [ "QR_CODE_ENABLED" ] } - # TODO: Renable once ota is supported - # if (chip_enable_ota_requestor) { - # defines += [ "SILABS_OTA_ENABLED" ] - # } + if (chip_enable_ota_requestor) { + defines += [ "SILABS_OTA_ENABLED" ] + } if (enable_heap_monitoring) { defines += [ "HEAP_MONITORING" ] @@ -229,7 +228,7 @@ source_set("siwx917-common") { } if (chip_enable_ota_requestor) { - # TODO: OTA For CCP Platform + sources += [ "${silabs_common_plat_dir}/OTAConfig.cpp" ] } if (!disable_lcd) { diff --git a/examples/platform/silabs/SiWx917/SiWx917/sl_wifi_if.c b/examples/platform/silabs/SiWx917/SiWx917/sl_wifi_if.c index 27b677432b30d5..4c3df704dcae38 100644 --- a/examples/platform/silabs/SiWx917/SiWx917/sl_wifi_if.c +++ b/examples/platform/silabs/SiWx917/SiWx917/sl_wifi_if.c @@ -265,6 +265,16 @@ static sl_status_t wfx_rsi_init(void) return status; } #endif + + sl_wifi_version_string_t version = { 0 }; + status = sl_wifi_get_firmware_version(&version); + if (status != SL_STATUS_OK) + { + SILABS_LOG("Get fw version failed: %s", version.version); + return status; + } + SILABS_LOG("Get current fw version: %s", version.version); + status = sl_wifi_get_mac_address(SL_WIFI_CLIENT_INTERFACE, (sl_mac_address_t *) &wfx_rsi.sta_mac.octet[0]); if (status != SL_STATUS_OK) { diff --git a/src/platform/silabs/OTAImageProcessorImpl.h b/src/platform/silabs/OTAImageProcessorImpl.h index 30709bd7f32f3a..46b78b063f2172 100644 --- a/src/platform/silabs/OTAImageProcessorImpl.h +++ b/src/platform/silabs/OTAImageProcessorImpl.h @@ -75,6 +75,7 @@ class OTAImageProcessorImpl : public OTAImageProcessorInterface static uint8_t writeBuffer[kAlignmentBytes] __attribute__((aligned(4))); // Offset indicates how far the write buffer has been filled static uint16_t writeBufOffset; + static bool mReset; }; } // namespace chip diff --git a/src/platform/silabs/SiWx917/BUILD.gn b/src/platform/silabs/SiWx917/BUILD.gn index 039794e680e852..151c6e93bc5f40 100644 --- a/src/platform/silabs/SiWx917/BUILD.gn +++ b/src/platform/silabs/SiWx917/BUILD.gn @@ -66,11 +66,10 @@ static_library("SiWx917") { "PlatformManagerImpl.cpp", ] - # TODO: OTA on CCP platform if (chip_enable_ota_requestor) { sources += [ - #"OTAImageProcessorImpl.cpp", - #"${silabs_platform_dir}/OTAImageProcessorImpl.h", + "${silabs_platform_dir}/OTAImageProcessorImpl.h", + "OTAImageProcessorImpl.cpp", ] } diff --git a/src/platform/silabs/SiWx917/OTAImageProcessorImpl.cpp b/src/platform/silabs/SiWx917/OTAImageProcessorImpl.cpp index 2cfcc9694267e9..075317fb9cb2f3 100644 --- a/src/platform/silabs/SiWx917/OTAImageProcessorImpl.cpp +++ b/src/platform/silabs/SiWx917/OTAImageProcessorImpl.cpp @@ -20,19 +20,30 @@ #include #include +#include + +#ifdef __cplusplus extern "C" { -#include "btl_interface.h" -#include "em_bus.h" // For CORE_CRITICAL_SECTION +#endif +#include "sl_si91x_driver.h" +#ifdef RSI_M4_INTERFACE +#include "sl_si91x_hal_soc_soft_reset.h" +#endif +#ifdef __cplusplus } +#endif -#include - +#define RPS_HEADER 1 +#define RPS_DATA 2 /// No error, operation OK #define SL_BOOTLOADER_OK 0L +#define SL_STATUS_FW_UPDATE_DONE SL_STATUS_SI91X_NO_AP_FOUND +uint8_t flag = RPS_HEADER; namespace chip { // Define static memebers +bool OTAImageProcessorImpl::mReset = false; uint8_t OTAImageProcessorImpl::mSlotId = 0; uint32_t OTAImageProcessorImpl::mWriteOffset = 0; uint16_t OTAImageProcessorImpl::writeBufOffset = 0; @@ -129,7 +140,7 @@ void OTAImageProcessorImpl::HandlePrepareDownload(intptr_t context) ChipLogProgress(SoftwareUpdate, "HandlePrepareDownload"); - CORE_CRITICAL_SECTION(bootloader_init();) + mReset = false; mSlotId = 0; // Single slot until we support multiple images writeBufOffset = 0; mWriteOffset = 0; @@ -139,39 +150,39 @@ void OTAImageProcessorImpl::HandlePrepareDownload(intptr_t context) // Not calling bootloader_eraseStorageSlot(mSlotId) here because we erase during each write - imageProcessor->mDownloader->OnPreparedForDownload(err == SL_BOOTLOADER_OK ? CHIP_NO_ERROR : CHIP_ERROR_INTERNAL); + imageProcessor->mDownloader->OnPreparedForDownload(CHIP_NO_ERROR); } void OTAImageProcessorImpl::HandleFinalize(intptr_t context) { uint32_t err = SL_BOOTLOADER_OK; + int32_t status = 0; auto * imageProcessor = reinterpret_cast(context); if (imageProcessor == nullptr) { return; } - - // Pad the remainder of the write buffer with zeros and write it to bootloader storage if (writeBufOffset != 0) { // Account for last bytes of the image not yet written to storage imageProcessor->mParams.downloadedBytes += writeBufOffset; + status = sl_si91x_fwup_load(writeBuffer, writeBufOffset); + ChipLogProgress(SoftwareUpdate, "status: 0x%lX", status); - while (writeBufOffset != kAlignmentBytes) - { - writeBuffer[writeBufOffset] = 0; - writeBufOffset++; - } - - CORE_CRITICAL_SECTION(err = bootloader_eraseWriteStorage(mSlotId, mWriteOffset, writeBuffer, kAlignmentBytes);) - if (err) + if (status != SL_STATUS_OK) { - ChipLogError(SoftwareUpdate, "ERROR: In HandleFinalize bootloader_eraseWriteStorage() error %ld", err); - imageProcessor->mDownloader->EndDownload(CHIP_ERROR_WRITE_FAILED); - return; + if (status == SL_STATUS_FW_UPDATE_DONE) + { + mReset = true; + } + else + { + ChipLogError(SoftwareUpdate, "ERROR: In HandleFinalize for last chunk rsi_fwup() error %ld", status); + imageProcessor->mDownloader->EndDownload(CHIP_ERROR_WRITE_FAILED); + return; + } } } - imageProcessor->ReleaseBlock(); ChipLogProgress(SoftwareUpdate, "OTA image downloaded successfully"); @@ -186,28 +197,16 @@ void OTAImageProcessorImpl::HandleApply(intptr_t context) // Force KVS to store pending keys such as data from StoreCurrentUpdateInfo() chip::DeviceLayer::PersistedStorage::KeyValueStoreMgrImpl().ForceKeyMapSave(); - CORE_CRITICAL_SECTION(err = bootloader_verifyImage(mSlotId, NULL);) - if (err != SL_BOOTLOADER_OK) - { - ChipLogError(SoftwareUpdate, "ERROR: bootloader_verifyImage() error %ld", err); - // Call the OTARequestor API to reset the state - GetRequestorInstance()->CancelImageUpdate(); + ChipLogProgress(SoftwareUpdate, "OTA image downloaded successfully in HandleApply"); - return; - } - - CORE_CRITICAL_SECTION(err = bootloader_setImageToBootload(mSlotId);) - if (err != SL_BOOTLOADER_OK) + if (mReset) { - ChipLogError(SoftwareUpdate, "ERROR: bootloader_setImageToBootload() error %ld", err); - // Call the OTARequestor API to reset the state - GetRequestorInstance()->CancelImageUpdate(); - - return; + ChipLogProgress(SoftwareUpdate, "M4 Firmware update complete"); + // send system reset request to reset the MCU and upgrade the m4 image + ChipLogProgress(SoftwareUpdate, "SoC Soft Reset initiated!"); + // Reboots the device + sl_si91x_soc_soft_reset(); } - - // This reboots the device - CORE_CRITICAL_SECTION(bootloader_rebootAndInstall();) } void OTAImageProcessorImpl::HandleAbort(intptr_t context) @@ -225,6 +224,8 @@ void OTAImageProcessorImpl::HandleAbort(intptr_t context) void OTAImageProcessorImpl::HandleProcessBlock(intptr_t context) { uint32_t err = SL_BOOTLOADER_OK; + int32_t status = 0; + int32_t content_block = 0; auto * imageProcessor = reinterpret_cast(context); if (imageProcessor == nullptr) { @@ -258,19 +259,37 @@ void OTAImageProcessorImpl::HandleProcessBlock(intptr_t context) if (writeBufOffset == kAlignmentBytes) { writeBufOffset = 0; - - CORE_CRITICAL_SECTION(err = bootloader_eraseWriteStorage(mSlotId, mWriteOffset, writeBuffer, kAlignmentBytes);) - if (err) + if (flag == RPS_HEADER) { - ChipLogError(SoftwareUpdate, "ERROR: In HandleProcessBlock bootloader_eraseWriteStorage() error %ld", err); - imageProcessor->mDownloader->EndDownload(CHIP_ERROR_WRITE_FAILED); - return; + // Send RPS header which is received as first chunk + status = sl_si91x_fwup_start(writeBuffer); + status = sl_si91x_fwup_load(writeBuffer, kAlignmentBytes); + flag = RPS_DATA; } - mWriteOffset += kAlignmentBytes; + else if (flag == RPS_DATA) + { + // Send RPS content + status = sl_si91x_fwup_load(writeBuffer, kAlignmentBytes); + if (status != SL_STATUS_OK) + { + // If the last chunk of last block-writeBufOffset length is exactly kAlignmentBytes(64) bytes then mReset value + // should be set to true in HandleProcessBlock + if (status == SL_STATUS_FW_UPDATE_DONE) + { + mReset = true; + } + else + { + ChipLogError(SoftwareUpdate, "ERROR: In HandleFinalize for last chunk rsi_fwup() error %ld", status); + imageProcessor->mDownloader->EndDownload(CHIP_ERROR_WRITE_FAILED); + return; + } + } + } + // ChipLogProgress(SoftwareUpdate, "HandleProcessBlock status: 0x%lX", status); imageProcessor->mParams.downloadedBytes += kAlignmentBytes; } } - imageProcessor->mDownloader->FetchNextData(); } diff --git a/third_party/silabs/SiWx917_sdk.gni b/third_party/silabs/SiWx917_sdk.gni index 932ccebe79904c..b049d4b4b24073 100644 --- a/third_party/silabs/SiWx917_sdk.gni +++ b/third_party/silabs/SiWx917_sdk.gni @@ -130,6 +130,11 @@ template("siwx917_sdk") { "${efr32_sdk_root}/platform/service/iostream/inc", "${wifi_sdk_root}/components/siwx917_soc/drivers/hardware_drivers/button/inc", + + # OTA + "${wifi_sdk_root}/components/si91x/sl_net/protocols/firmware_upgrade", + "${wifi_sdk_root}/components/siwx917_soc/hal/inc", + "${wifi_sdk_root}/components/siwx917_soc/drivers/systemlevel/inc", ] if (silabs_board == "BRD4338A") { @@ -452,6 +457,11 @@ template("siwx917_sdk") { "${sdk_support_root}/matter/mbedtls/tinycrypt/src/x509write_csr.c", "${sdk_support_root}/matter/si91x/siwx917/${sdk_support_board}/autogen/sl_si91x_button_instances.c", "${wifi_sdk_root}/components/siwx917_soc/drivers/hardware_drivers/button/src/sl_si91x_button.c", + + # OTA + "${wifi_sdk_root}/components/si91x/sl_net/protocols/firmware_upgrade/firmware_upgradation.c", + "${wifi_sdk_root}/components/siwx917_soc/drivers/systemlevel/src/rsi_wwdt.c", + "${wifi_sdk_root}/components/siwx917_soc/hal/src/sl_si91x_hal_soc_soft_reset.c", ] # nvm3 ans startup From ca577f49474a985316df49e5c854536ea6b6b07c Mon Sep 17 00:00:00 2001 From: srningap <107042150+srningap@users.noreply.github.com> Date: Thu, 21 Dec 2023 21:33:10 +0530 Subject: [PATCH 12/29] [Silabs] Fix for wifi apps build issue (#31157) * Adds fix for wifi apps build failure * Restyled by whitespace --------- Co-authored-by: Restyled.io --- src/platform/silabs/CHIPDevicePlatformConfig.h | 2 ++ third_party/silabs/SiWx917_sdk.gni | 8 ++++++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/platform/silabs/CHIPDevicePlatformConfig.h b/src/platform/silabs/CHIPDevicePlatformConfig.h index 0ba1cecc6bef31..12aadb24400691 100644 --- a/src/platform/silabs/CHIPDevicePlatformConfig.h +++ b/src/platform/silabs/CHIPDevicePlatformConfig.h @@ -160,6 +160,7 @@ ICD Configuration Defines */ +#if SL_ICD_ENABLED #ifndef CHIP_DEVICE_CONFIG_ICD_SLOW_POLL_INTERVAL #define CHIP_DEVICE_CONFIG_ICD_SLOW_POLL_INTERVAL chip::System::Clock::Milliseconds32(SL_OT_IDLE_INTERVAL) #endif // CHIP_DEVICE_CONFIG_ICD_SLOW_POLL_INTERVAL @@ -167,3 +168,4 @@ #ifndef CHIP_DEVICE_CONFIG_ICD_FAST_POLL_INTERVAL #define CHIP_DEVICE_CONFIG_ICD_FAST_POLL_INTERVAL chip::System::Clock::Milliseconds32(SL_OT_ACTIVE_INTERVAL) #endif // CHIP_DEVICE_CONFIG_ICD_FAST_POLL_INTERVAL +#endif // SL_ICD_ENABLED diff --git a/third_party/silabs/SiWx917_sdk.gni b/third_party/silabs/SiWx917_sdk.gni index b049d4b4b24073..bc8b8c23bf67ab 100644 --- a/third_party/silabs/SiWx917_sdk.gni +++ b/third_party/silabs/SiWx917_sdk.gni @@ -276,8 +276,12 @@ template("siwx917_sdk") { if (chip_enable_icd_server) { defines += [ - "SL_CATALOG_POWER_MANAGER_PRESENT", - "SL_CATALOG_SLEEPTIMER_PRESENT", + "WIFI_DEBUG_ENABLED=1", + "SL_ICD_ENABLED=1", + "SL_ACTIVE_MODE_THRESHOLD=${sl_active_mode_threshold_ms}", + "SL_ACTIVE_MODE_INTERVAL=${sl_active_mode_interval_ms}", + "SL_IDLE_MODE_INTERVAL=${sl_idle_mode_interval_s}", + "SL_ICD_SUPPORTED_CLIENTS_PER_FABRIC=${sl_icd_supported_clients_per_fabric}", ] } From 3e8aeeb7d6cb58811b7ec5be57f576aef7855e13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damian=20Kr=C3=B3lik?= <66667989+Damian-Nordic@users.noreply.github.com> Date: Thu, 21 Dec 2023 17:06:02 +0100 Subject: [PATCH 13/29] [app] Fix DeferredAttributePersister memory leak (#31075) * [app] Fix DeferredAttributePerister memory leak ScopedMemoryBuffer's Release() method was used instead of Free(). Add CHECK_RETURN_VALUE annotation to the Release() method to prevent from making such a mistake in the future. Signed-off-by: Damian Krolik * Code review --------- Signed-off-by: Damian Krolik --- .../DeferredAttributePersistenceProvider.cpp | 2 +- src/darwin/Framework/CHIP/MTRBaseDevice.mm | 4 +-- src/lib/support/ScopedBuffer.h | 30 +++++++++++++------ 3 files changed, 24 insertions(+), 12 deletions(-) diff --git a/src/app/DeferredAttributePersistenceProvider.cpp b/src/app/DeferredAttributePersistenceProvider.cpp index 62d5c446fe2091..82652792806d5e 100644 --- a/src/app/DeferredAttributePersistenceProvider.cpp +++ b/src/app/DeferredAttributePersistenceProvider.cpp @@ -39,7 +39,7 @@ void DeferredAttribute::Flush(AttributePersistenceProvider & persister) { VerifyOrReturn(IsArmed()); persister.WriteValue(mPath, ByteSpan(mValue.Get(), mValue.AllocatedSize())); - mValue.Release(); + mValue.Free(); } CHIP_ERROR DeferredAttributePersistenceProvider::WriteValue(const ConcreteAttributePath & aPath, const ByteSpan & aValue) diff --git a/src/darwin/Framework/CHIP/MTRBaseDevice.mm b/src/darwin/Framework/CHIP/MTRBaseDevice.mm index a4bcf3742c8d6e..09a8e07b0e34da 100644 --- a/src/darwin/Framework/CHIP/MTRBaseDevice.mm +++ b/src/darwin/Framework/CHIP/MTRBaseDevice.mm @@ -1142,8 +1142,8 @@ - (void)readAttributePaths:(NSArray * _Nullable)attri // callback->AdoptReadClient(std::move(readClient)); callback.release(); - attributePathParamsList.Release(); - eventPathParamsList.Release(); + IgnoreUnusedVariable(attributePathParamsList.Release()); + IgnoreUnusedVariable(eventPathParamsList.Release()); return err; }); std::move(*bridge).DispatchAction(self); diff --git a/src/lib/support/ScopedBuffer.h b/src/lib/support/ScopedBuffer.h index 258b7f262935fb..7a3c0aaca5902c 100644 --- a/src/lib/support/ScopedBuffer.h +++ b/src/lib/support/ScopedBuffer.h @@ -25,6 +25,7 @@ #pragma once #include +#include #include #include @@ -84,10 +85,11 @@ class ScopedMemoryBufferBase const void * Ptr() const { return mBuffer; } /** - * Releases the undelying buffer. Buffer stops being managed and will not be - * auto-freed. + * Releases the underlying buffer. + * + * The buffer stops being managed and will not be auto-freed. */ - void * Release() + CHECK_RETURN_VALUE void * Release() { void * buffer = mBuffer; mBuffer = nullptr; @@ -139,13 +141,18 @@ class ScopedMemoryBuffer : public Impl::ScopedMemoryBufferBase static_assert(std::is_trivially_destructible::value, "Destructors won't get run"); - inline T * Get() { return static_cast(Base::Ptr()); } - inline T & operator[](size_t index) { return Get()[index]; } + T * Get() { return static_cast(Base::Ptr()); } + T & operator[](size_t index) { return Get()[index]; } - inline const T * Get() const { return static_cast(Base::Ptr()); } - inline const T & operator[](size_t index) const { return Get()[index]; } + const T * Get() const { return static_cast(Base::Ptr()); } + const T & operator[](size_t index) const { return Get()[index]; } - inline T * Release() { return static_cast(Base::Release()); } + /** + * Releases the underlying buffer. + * + * The buffer stops being managed and will not be auto-freed. + */ + CHECK_RETURN_VALUE T * Release() { return static_cast(Base::Release()); } ScopedMemoryBuffer & Calloc(size_t elementCount) { @@ -222,7 +229,12 @@ class ScopedMemoryBufferWithSize : public ScopedMemoryBuffer ScopedMemoryBuffer::Free(); } - T * Release() + /** + * Releases the underlying buffer. + * + * The buffer stops being managed and will not be auto-freed. + */ + CHECK_RETURN_VALUE T * Release() { T * buffer = ScopedMemoryBuffer::Release(); mCount = 0; From 6d05eb62049ca18733e50fffa7ef90a513a9f295 Mon Sep 17 00:00:00 2001 From: Lazar Kovacic Date: Thu, 21 Dec 2023 20:19:40 +0100 Subject: [PATCH 14/29] TV Matter Media: Resolve items from Issue 30807 (#31108) * Update TV&TV casting app per issue 30807 * ZAP Regen Script * Remove unused GetNodeId method Add provisional labels Updated ContentAppObserver to pass test cases --- .../all-clusters-minimal-app.matter | 2 +- ...ootnode_basicvideoplayer_0ff86e943b.matter | 2 +- .../placeholder/linux/apps/app1/config.matter | 4 +- .../placeholder/linux/apps/app2/config.matter | 4 +- .../ContentAppObserver.cpp | 7 +- examples/tv-app/tv-common/tv-app.matter | 43 +-- examples/tv-app/tv-common/tv-app.zap | 332 +++++++----------- .../tv-casting-common/tv-casting-app.matter | 129 ++++++- .../tv-casting-common/tv-casting-app.zap | 269 +++++++++++++- .../account-login-server.cpp | 27 -- .../zcl/data-model/chip/channel-cluster.xml | 4 +- .../chip/content-app-observer-cluster.xml | 8 +- .../chip/media-playback-cluster.xml | 4 +- .../data_model/controller-clusters.matter | 8 +- .../chip/devicecontroller/ChipClusters.java | 30 +- .../devicecontroller/ClusterInfoMapping.java | 14 +- .../cluster/clusters/ChannelCluster.kt | 16 +- .../clusters/ContentAppObserverCluster.kt | 34 +- .../zap-generated/CHIPInvokeCallbacks.cpp | 240 +++++++++++-- .../python/chip/clusters/Objects.py | 16 +- .../zap-generated/MTRCommandPayloadsObjc.h | 8 +- .../zap-generated/MTRCommandPayloadsObjc.mm | 108 ++++-- .../zap-generated/cluster-objects.cpp | 6 +- .../zap-generated/cluster-objects.h | 20 +- .../cluster/logging/DataModelLogger.cpp | 2 +- 25 files changed, 940 insertions(+), 397 deletions(-) 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 1e2f06d1039962..95dddce935ea21 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 @@ -4502,7 +4502,7 @@ cluster Channel = 1284 { } response struct ProgramGuideResponse = 5 { - int16s channelPagingStruct = 0; + ChannelPagingStruct paging = 0; ProgramStruct programList[] = 1; } diff --git a/examples/chef/devices/rootnode_basicvideoplayer_0ff86e943b.matter b/examples/chef/devices/rootnode_basicvideoplayer_0ff86e943b.matter index 54d007ef366a95..9157827f8f1311 100644 --- a/examples/chef/devices/rootnode_basicvideoplayer_0ff86e943b.matter +++ b/examples/chef/devices/rootnode_basicvideoplayer_0ff86e943b.matter @@ -1370,7 +1370,7 @@ cluster Channel = 1284 { } response struct ProgramGuideResponse = 5 { - int16s channelPagingStruct = 0; + ChannelPagingStruct paging = 0; ProgramStruct programList[] = 1; } diff --git a/examples/placeholder/linux/apps/app1/config.matter b/examples/placeholder/linux/apps/app1/config.matter index 8239122a760eb7..141c16cf46e6e3 100644 --- a/examples/placeholder/linux/apps/app1/config.matter +++ b/examples/placeholder/linux/apps/app1/config.matter @@ -6224,7 +6224,7 @@ cluster Channel = 1284 { } response struct ProgramGuideResponse = 5 { - int16s channelPagingStruct = 0; + ChannelPagingStruct paging = 0; ProgramStruct programList[] = 1; } @@ -6398,7 +6398,7 @@ cluster Channel = 1284 { } response struct ProgramGuideResponse = 5 { - int16s channelPagingStruct = 0; + ChannelPagingStruct paging = 0; ProgramStruct programList[] = 1; } diff --git a/examples/placeholder/linux/apps/app2/config.matter b/examples/placeholder/linux/apps/app2/config.matter index 3ed94e2c150b82..da0c83939f94a1 100644 --- a/examples/placeholder/linux/apps/app2/config.matter +++ b/examples/placeholder/linux/apps/app2/config.matter @@ -6181,7 +6181,7 @@ cluster Channel = 1284 { } response struct ProgramGuideResponse = 5 { - int16s channelPagingStruct = 0; + ChannelPagingStruct paging = 0; ProgramStruct programList[] = 1; } @@ -6355,7 +6355,7 @@ cluster Channel = 1284 { } response struct ProgramGuideResponse = 5 { - int16s channelPagingStruct = 0; + ChannelPagingStruct paging = 0; ProgramStruct programList[] = 1; } diff --git a/examples/tv-app/tv-common/clusters/content-app-observer/ContentAppObserver.cpp b/examples/tv-app/tv-common/clusters/content-app-observer/ContentAppObserver.cpp index 0b5c949216ed55..a6010a54b0a0f5 100644 --- a/examples/tv-app/tv-common/clusters/content-app-observer/ContentAppObserver.cpp +++ b/examples/tv-app/tv-common/clusters/content-app-observer/ContentAppObserver.cpp @@ -43,9 +43,8 @@ void ContentAppObserverManager::HandleContentAppMessage(chip::app::CommandRespon ContentAppMessageResponse response; // TODO: Insert code here - // TODO: optional and mandatory are swapped - response.data = CharSpan::fromCharString("exampleData"); - response.encodingHint = CharSpan::fromCharString(encodingHintString.c_str()); - response.status = chip::MakeOptional(StatusEnum::kSuccess); + response.data = chip::MakeOptional(CharSpan::fromCharString("exampleData")); + response.encodingHint = chip::MakeOptional(CharSpan::fromCharString(encodingHintString.c_str())); + response.status = StatusEnum::kSuccess; helper.Success(response); } diff --git a/examples/tv-app/tv-common/tv-app.matter b/examples/tv-app/tv-common/tv-app.matter index 13177041efa673..3f0d6b09e1f33b 100644 --- a/examples/tv-app/tv-common/tv-app.matter +++ b/examples/tv-app/tv-common/tv-app.matter @@ -2179,7 +2179,7 @@ cluster Channel = 1284 { } response struct ProgramGuideResponse = 5 { - int16s channelPagingStruct = 0; + ChannelPagingStruct paging = 0; ProgramStruct programList[] = 1; } @@ -3048,9 +3048,9 @@ cluster ContentAppObserver = 1296 { } response struct ContentAppMessageResponse = 1 { - optional StatusEnum status = 0; - char_string data = 1; - char_string encodingHint = 2; + StatusEnum status = 0; + optional char_string data = 1; + optional char_string encodingHint = 2; } /** Upon receipt, the data field MAY be parsed and interpreted. Message encoding is specific to the Content App. A Content App MAY when possible read attributes from the Basic Information Cluster on the Observer and use this to determine the Message encoding. */ @@ -3593,18 +3593,6 @@ endpoint 1 { handle command SetOnDemandRatingThreshold; handle command SetScheduledContentRatingThreshold; } - - server cluster ContentAppObserver { - callback attribute generatedCommandList; - callback attribute acceptedCommandList; - callback attribute eventList; - callback attribute attributeList; - ram attribute featureMap default = 0; - ram attribute clusterRevision default = 1; - - handle command ContentAppMessage; - handle command ContentAppMessageResponse; - } } endpoint 2 { device type ma_speaker = 34, version 1; @@ -3660,6 +3648,7 @@ endpoint 2 { endpoint 3 { device type ma_contentapp = 36, version 1; + binding cluster ContentAppObserver; server cluster Descriptor { callback attribute deviceTypeList; @@ -3670,6 +3659,16 @@ endpoint 3 { callback attribute clusterRevision; } + server cluster Binding { + callback attribute binding; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; + ram attribute featureMap default = 0; + ram attribute clusterRevision default = 1; + } + server cluster Channel { callback attribute channelList; callback attribute lineup; @@ -3825,18 +3824,6 @@ endpoint 3 { handle command SetOnDemandRatingThreshold; handle command SetScheduledContentRatingThreshold; } - - server cluster ContentAppObserver { - callback attribute generatedCommandList; - callback attribute acceptedCommandList; - callback attribute eventList; - callback attribute attributeList; - ram attribute featureMap default = 0; - ram attribute clusterRevision default = 1; - - handle command ContentAppMessage; - handle command ContentAppMessageResponse; - } } diff --git a/examples/tv-app/tv-common/tv-app.zap b/examples/tv-app/tv-common/tv-app.zap index ee3c171287a754..d49bfd9717a7bf 100644 --- a/examples/tv-app/tv-common/tv-app.zap +++ b/examples/tv-app/tv-common/tv-app.zap @@ -17,6 +17,12 @@ } ], "package": [ + { + "pathRelativity": "relativeToZap", + "path": "../../../src/app/zap-templates/app-templates.json", + "type": "gen-templates-json", + "version": "chip-v1" + }, { "pathRelativity": "relativeToZap", "path": "../../../src/app/zap-templates/zcl/zcl.json", @@ -24,12 +30,6 @@ "category": "matter", "version": 1, "description": "Matter SDK ZCL data" - }, - { - "pathRelativity": "relativeToZap", - "path": "../../../src/app/zap-templates/app-templates.json", - "type": "gen-templates-json", - "version": "chip-v1" } ], "endpointTypes": [ @@ -6295,130 +6295,6 @@ "included": 1 } ] - }, - { - "name": "Content App Observer", - "code": 1296, - "mfgCode": null, - "define": "CONTENT_APP_OBSERVER_CLUSTER", - "side": "server", - "enabled": 1, - "commands": [ - { - "name": "ContentAppMessage", - "code": 0, - "mfgCode": null, - "source": "client", - "isIncoming": 1, - "isEnabled": 1 - }, - { - "name": "ContentAppMessageResponse", - "code": 1, - "mfgCode": null, - "source": "server", - "isIncoming": 0, - "isEnabled": 1 - } - ], - "attributes": [ - { - "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": "1", - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - } - ] } ] }, @@ -7106,6 +6982,128 @@ } ] }, + { + "name": "Binding", + "code": 30, + "mfgCode": null, + "define": "BINDING_CLUSTER", + "side": "server", + "enabled": 1, + "attributes": [ + { + "name": "Binding", + "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": "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": "1", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + } + ] + }, { "name": "Channel", "code": 1284, @@ -8747,7 +8745,7 @@ "code": 1296, "mfgCode": null, "define": "CONTENT_APP_OBSERVER_CLUSTER", - "side": "server", + "side": "client", "enabled": 1, "commands": [ { @@ -8755,7 +8753,7 @@ "code": 0, "mfgCode": null, "source": "client", - "isIncoming": 1, + "isIncoming": 0, "isEnabled": 1 }, { @@ -8763,80 +8761,16 @@ "code": 1, "mfgCode": null, "source": "server", - "isIncoming": 0, + "isIncoming": 1, "isEnabled": 1 } ], "attributes": [ - { - "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", + "side": "client", "type": "bitmap32", "included": 1, "storageOption": "RAM", @@ -8852,7 +8786,7 @@ "name": "ClusterRevision", "code": 65533, "mfgCode": null, - "side": "server", + "side": "client", "type": "int16u", "included": 1, "storageOption": "RAM", diff --git a/examples/tv-casting-app/tv-casting-common/tv-casting-app.matter b/examples/tv-casting-app/tv-casting-common/tv-casting-app.matter index a8ed90807d29ba..d6d5b3f023d6ef 100644 --- a/examples/tv-casting-app/tv-casting-common/tv-casting-app.matter +++ b/examples/tv-casting-app/tv-casting-common/tv-casting-app.matter @@ -1641,7 +1641,7 @@ cluster Channel = 1284 { } response struct ProgramGuideResponse = 5 { - int16s channelPagingStruct = 0; + ChannelPagingStruct paging = 0; ProgramStruct programList[] = 1; } @@ -2405,6 +2405,120 @@ cluster AccountLogin = 1294 { fabric timed command Logout(LogoutRequest): DefaultSuccess = 3; } +/** This cluster is used for managing the content control (including "parental control") settings on a media device such as a TV, or Set-top Box. */ +cluster ContentControl = 1295 { + revision 1; // NOTE: Default/not specifically set + + bitmap Feature : bitmap32 { + kScreenTime = 0x1; + kPINManagement = 0x2; + kBlockUnrated = 0x3; + kOnDemandContentRating = 0x4; + kScheduledContentRating = 0x5; + } + + struct RatingNameStruct { + char_string ratingName = 0; + optional char_string ratingNameDesc = 1; + } + + info event RemainingScreenTimeExpired = 0 { + } + + readonly attribute boolean enabled = 0; + readonly attribute optional RatingNameStruct onDemandRatings[] = 1; + readonly attribute optional char_string<8> onDemandRatingThreshold = 2; + readonly attribute optional RatingNameStruct scheduledContentRatings[] = 3; + readonly attribute optional char_string<8> scheduledContentRatingThreshold = 4; + readonly attribute optional elapsed_s screenDailyTime = 5; + readonly attribute optional elapsed_s remainingScreenTime = 6; + readonly attribute boolean blockUnrated = 7; + 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 UpdatePINRequest { + optional char_string oldPIN = 0; + char_string newPIN = 1; + } + + response struct ResetPINResponse = 2 { + char_string PINCode = 0; + } + + request struct AddBonusTimeRequest { + optional char_string PINCode = 0; + optional elapsed_s bonusTime = 1; + } + + request struct SetScreenDailyTimeRequest { + elapsed_s screenTime = 0; + } + + request struct SetOnDemandRatingThresholdRequest { + char_string rating = 0; + } + + request struct SetScheduledContentRatingThresholdRequest { + char_string rating = 0; + } + + /** The purpose of this command is to update the PIN used for protecting configuration of the content control settings. Upon success, the old PIN SHALL no longer work. The PIN is used to ensure that only the Node (or User) with the PIN code can make changes to the Content Control settings, for example, turn off Content Controls or modify the ScreenDailyTime. The PIN is composed of a numeric string of up to 6 human readable characters (displayable) . Upon receipt of this command, the media device SHALL check if the OldPIN field of this command is the same as the current PIN. If the PINs are the same, then the PIN code SHALL be set to NewPIN. Otherwise a response with InvalidPINCode error status SHALL be returned. The media device MAY provide a default PIN to the User via an out of band mechanism. For security reasons, it is recommended that a client encourage the user to update the PIN from its default value when performing configuration of the Content Control settings exposed by this cluster. The ResetPIN command can also be used to obtain the default PIN. */ + command UpdatePIN(UpdatePINRequest): DefaultSuccess = 0; + /** The purpose of this command is to reset the PIN. If this command is executed successfully, a ResetPINResponse command with a new PIN SHALL be returned. */ + command ResetPIN(): ResetPINResponse = 1; + /** The purpose of this command is to turn on the Content Control feature on a media device. On receipt of the Enable command, the media device SHALL set the Enabled attribute to TRUE. */ + command Enable(): DefaultSuccess = 3; + /** The purpose of this command is to turn off the Content Control feature on a media device. On receipt of the Disable command, the media device SHALL set the Enabled attribute to FALSE. */ + command Disable(): DefaultSuccess = 4; + /** The purpose of this command is to add the extra screen time for the user. If a client with Operate privilege invokes this command, the media device SHALL check whether the PINCode passed in the command matches the current PINCode value. If these match, then the RemainingScreenTime attribute SHALL be increased by the specified BonusTime value. If the PINs do not match, then a response with InvalidPINCode error status SHALL be returned, and no changes SHALL be made to RemainingScreenTime. If a client with Manage privilege or greater invokes this command, the media device SHALL ignore the PINCode field and directly increase the RemainingScreenTime attribute by the specified BonusTime value. A server that does not support the PM feature SHALL respond with InvalidPINCode to clients that only have Operate privilege unless: It has been provided with the PIN value to expect via an out of band mechanism, and The client has provided a PINCode that matches the expected PIN value. */ + command AddBonusTime(AddBonusTimeRequest): DefaultSuccess = 5; + /** The purpose of this command is to set the ScreenDailyTime attribute. On receipt of the SetScreenDailyTime command, the media device SHALL set the ScreenDailyTime attribute to the ScreenTime value. */ + command SetScreenDailyTime(SetScreenDailyTimeRequest): DefaultSuccess = 6; + /** The purpose of this command is to specify whether programs with no Content rating must be blocked by this media device. On receipt of the BlockUnratedContent command, the media device SHALL set the BlockUnrated attribute to TRUE. */ + command BlockUnratedContent(): DefaultSuccess = 7; + /** The purpose of this command is to specify whether programs with no Content rating must be blocked by this media device. On receipt of the UnblockUnratedContent command, the media device SHALL set the BlockUnrated attribute to FALSE. */ + command UnblockUnratedContent(): DefaultSuccess = 8; + /** The purpose of this command is to set the OnDemandRatingThreshold attribute. On receipt of the SetOnDemandRatingThreshold command, the media device SHALL check if the Rating field is one of values present in the OnDemandRatings attribute. If not, then a response with InvalidRating error status SHALL be returned. */ + command SetOnDemandRatingThreshold(SetOnDemandRatingThresholdRequest): DefaultSuccess = 9; + /** The purpose of this command is to set ScheduledContentRatingThreshold attribute. On receipt of the SetScheduledContentRatingThreshold command, the media device SHALL check if the Rating field is one of values present in the ScheduledContentRatings attribute. If not, then a response with InvalidRating error status SHALL be returned. */ + command SetScheduledContentRatingThreshold(SetScheduledContentRatingThresholdRequest): DefaultSuccess = 10; +} + +/** This cluster provides an interface for sending targeted commands to an Observer of a Content App on a Video Player device such as a Streaming Media Player, Smart TV or Smart Screen. The cluster server for Content App Observer is implemented by an endpoint that communicates with a Content App, such as a Casting Video Client. The cluster client for Content App Observer is implemented by a Content App endpoint. A Content App is informed of the NodeId of an Observer when a binding is set on the Content App. The Content App can then send the ContentAppMessage to the Observer (server cluster), and the Observer responds with a ContentAppMessageResponse. */ +cluster ContentAppObserver = 1296 { + revision 1; // NOTE: Default/not specifically set + + enum StatusEnum : enum8 { + kSuccess = 0; + kUnexpectedData = 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 ContentAppMessageRequest { + optional char_string data = 0; + char_string encodingHint = 1; + } + + response struct ContentAppMessageResponse = 1 { + StatusEnum status = 0; + optional char_string data = 1; + optional char_string encodingHint = 2; + } + + /** Upon receipt, the data field MAY be parsed and interpreted. Message encoding is specific to the Content App. A Content App MAY when possible read attributes from the Basic Information Cluster on the Observer and use this to determine the Message encoding. */ + command ContentAppMessage(ContentAppMessageRequest): ContentAppMessageResponse = 0; +} + endpoint 0 { device type ma_rootdevice = 22, version 1; @@ -2660,6 +2774,7 @@ endpoint 1 { binding cluster ApplicationLauncher; binding cluster ApplicationBasic; binding cluster AccountLogin; + binding cluster ContentControl; server cluster Identify { ram attribute identifyTime default = 0x0000; @@ -2721,6 +2836,18 @@ endpoint 1 { ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; } + + server cluster ContentAppObserver { + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; + ram attribute featureMap default = 0; + ram attribute clusterRevision default = 1; + + handle command ContentAppMessage; + handle command ContentAppMessageResponse; + } } diff --git a/examples/tv-casting-app/tv-casting-common/tv-casting-app.zap b/examples/tv-casting-app/tv-casting-common/tv-casting-app.zap index abe20a454df785..de57d237e94c1c 100644 --- a/examples/tv-casting-app/tv-casting-common/tv-casting-app.zap +++ b/examples/tv-casting-app/tv-casting-common/tv-casting-app.zap @@ -17,6 +17,12 @@ } ], "package": [ + { + "pathRelativity": "relativeToZap", + "path": "../../../src/app/zap-templates/app-templates.json", + "type": "gen-templates-json", + "version": "chip-v1" + }, { "pathRelativity": "relativeToZap", "path": "../../../src/app/zap-templates/zcl/zcl.json", @@ -24,12 +30,6 @@ "category": "matter", "version": 1, "description": "Matter SDK ZCL data" - }, - { - "pathRelativity": "relativeToZap", - "path": "../../../src/app/zap-templates/app-templates.json", - "type": "gen-templates-json", - "version": "chip-v1" } ], "endpointTypes": [ @@ -3141,6 +3141,7 @@ "define": "BINARY_INPUT_BASIC_CLUSTER", "side": "server", "enabled": 1, + "apiMaturity": "deprecated", "attributes": [ { "name": "out of service", @@ -4395,6 +4396,262 @@ "reportableChange": 0 } ] + }, + { + "name": "Content Control", + "code": 1295, + "mfgCode": null, + "define": "CONTENT_CONTROL_CLUSTER", + "side": "client", + "enabled": 1, + "commands": [ + { + "name": "UpdatePIN", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "ResetPIN", + "code": 1, + "mfgCode": null, + "source": "client", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "ResetPINResponse", + "code": 2, + "mfgCode": null, + "source": "server", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "Enable", + "code": 3, + "mfgCode": null, + "source": "client", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "Disable", + "code": 4, + "mfgCode": null, + "source": "client", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "AddBonusTime", + "code": 5, + "mfgCode": null, + "source": "client", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "SetScreenDailyTime", + "code": 6, + "mfgCode": null, + "source": "client", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "BlockUnratedContent", + "code": 7, + "mfgCode": null, + "source": "client", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "UnblockUnratedContent", + "code": 8, + "mfgCode": null, + "source": "client", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "SetOnDemandRatingThreshold", + "code": 9, + "mfgCode": null, + "source": "client", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "SetScheduledContentRatingThreshold", + "code": 10, + "mfgCode": null, + "source": "client", + "isIncoming": 0, + "isEnabled": 1 + } + ], + "attributes": [ + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "client", + "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": "client", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + } + ] + }, + { + "name": "Content App Observer", + "code": 1296, + "mfgCode": null, + "define": "CONTENT_APP_OBSERVER_CLUSTER", + "side": "server", + "enabled": 1, + "commands": [ + { + "name": "ContentAppMessage", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "ContentAppMessageResponse", + "code": 1, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + } + ], + "attributes": [ + { + "name": "GeneratedCommandList", + "code": 65528, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "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": "", + "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": "", + "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": "", + "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 + } + ] } ] } diff --git a/src/app/clusters/account-login-server/account-login-server.cpp b/src/app/clusters/account-login-server/account-login-server.cpp index b9727a9ad9561f..1ba2218a69f737 100644 --- a/src/app/clusters/account-login-server/account-login-server.cpp +++ b/src/app/clusters/account-login-server/account-login-server.cpp @@ -52,33 +52,6 @@ static constexpr size_t kAccountLoginDeletageTableSize = EMBER_AF_ACCOUNT_LOGIN_CLUSTER_SERVER_ENDPOINT_COUNT + CHIP_DEVICE_CONFIG_DYNAMIC_ENDPOINT_COUNT; static_assert(kAccountLoginDeletageTableSize <= kEmberInvalidEndpointIndex, "AccountLogin Delegate table size error"); -NodeId getNodeId(const chip::app::CommandHandler * commandObj) -{ - // TODO: Why are we doing all these checks? At all the callsites we have - // just received a command, so we better have a handler, exchange, session, - // etc. The only thing we should be checking is that it's a CASE session. - if (nullptr == commandObj || nullptr == commandObj->GetExchangeContext()) - { - ChipLogError(Zcl, "Cannot access ExchangeContext of Command Object for Node ID"); - return kUndefinedNodeId; - } - - if (!commandObj->GetExchangeContext()->HasSessionHandle()) - { - ChipLogError(Zcl, "Cannot access session of Command Object for Node ID"); - return kUndefinedNodeId; - } - - auto descriptor = commandObj->GetExchangeContext()->GetSessionHandle()->GetSubjectDescriptor(); - if (descriptor.authMode != Access::AuthMode::kCase) - { - ChipLogError(Zcl, "Cannot get Node ID from non-CASE session of Command Object"); - return kUndefinedNodeId; - } - - return descriptor.subject; -} - // ----------------------------------------------------------------------------- // Delegate Implementation diff --git a/src/app/zap-templates/zcl/data-model/chip/channel-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/channel-cluster.xml index 5dc01df19f65f5..c5731ef9cd3a5f 100644 --- a/src/app/zap-templates/zcl/data-model/chip/channel-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/channel-cluster.xml @@ -61,9 +61,9 @@ limitations under the License. - + This command is a response to the GetProgramGuide command. - + diff --git a/src/app/zap-templates/zcl/data-model/chip/content-app-observer-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/content-app-observer-cluster.xml index 89d72eb768e519..c4fb56ecef7077 100644 --- a/src/app/zap-templates/zcl/data-model/chip/content-app-observer-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/content-app-observer-cluster.xml @@ -31,11 +31,11 @@ limitations under the License. - + This command SHALL be generated in response to ContentAppMessage command. - - - + + + diff --git a/src/app/zap-templates/zcl/data-model/chip/media-playback-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/media-playback-cluster.xml index 1d9b56dc9a1385..76c80819b279c2 100644 --- a/src/app/zap-templates/zcl/data-model/chip/media-playback-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/media-playback-cluster.xml @@ -34,9 +34,9 @@ limitations under the License. SeekRangeEnd SeekRangeStart ActiveAudioTrack - AvailableAudioTracks + AvailableAudioTracks ActiveTextTrack - AvailableTextTracks + AvailableTextTracks diff --git a/src/controller/data_model/controller-clusters.matter b/src/controller/data_model/controller-clusters.matter index 1d0fcc7ec86b61..b78cbfa007eca0 100644 --- a/src/controller/data_model/controller-clusters.matter +++ b/src/controller/data_model/controller-clusters.matter @@ -7313,7 +7313,7 @@ cluster Channel = 1284 { } response struct ProgramGuideResponse = 5 { - int16s channelPagingStruct = 0; + ChannelPagingStruct paging = 0; ProgramStruct programList[] = 1; } @@ -8182,9 +8182,9 @@ cluster ContentAppObserver = 1296 { } response struct ContentAppMessageResponse = 1 { - optional StatusEnum status = 0; - char_string data = 1; - char_string encodingHint = 2; + StatusEnum status = 0; + optional char_string data = 1; + optional char_string encodingHint = 2; } /** Upon receipt, the data field MAY be parsed and interpreted. Message encoding is specific to the Content App. A Content App MAY when possible read attributes from the Basic Information Cluster on the Observer and use this to determine the Message encoding. */ diff --git a/src/controller/java/generated/java/chip/devicecontroller/ChipClusters.java b/src/controller/java/generated/java/chip/devicecontroller/ChipClusters.java index 201229af2f710c..d9b1143464b577 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/ChipClusters.java +++ b/src/controller/java/generated/java/chip/devicecontroller/ChipClusters.java @@ -48973,15 +48973,15 @@ public void getProgramGuide(ProgramGuideResponseCallback callback, Optional programList = null; for (StructElement element: invokeStructValue.value()) { - if (element.contextTagNum() == channelPagingStructFieldID) { - if (element.value(BaseTLVType.class).type() == TLVType.Int) { - IntType castingValue = element.value(IntType.class); - channelPagingStruct = castingValue.value(Integer.class); + if (element.contextTagNum() == pagingFieldID) { + if (element.value(BaseTLVType.class).type() == TLVType.Struct) { + StructType castingValue = element.value(StructType.class); + paging = ChipStructs.ChannelClusterChannelPagingStruct.decodeTlv(castingValue); } } else if (element.contextTagNum() == programListFieldID) { if (element.value(BaseTLVType.class).type() == TLVType.Array) { @@ -48990,7 +48990,7 @@ public void onResponse(StructType invokeStructValue) { } } } - callback.onSuccess(channelPagingStruct, programList); + callback.onSuccess(paging, programList); }}, commandId, value, timedInvokeTimeoutMs); } @@ -49063,7 +49063,7 @@ public interface ChangeChannelResponseCallback extends BaseClusterCallback { } public interface ProgramGuideResponseCallback extends BaseClusterCallback { - void onSuccess(Integer channelPagingStruct, ArrayList programList); + void onSuccess(ChipStructs.ChannelClusterChannelPagingStruct paging, ArrayList programList); } public interface ChannelListAttributeCallback extends BaseAttributeCallback { @@ -53614,26 +53614,26 @@ public void contentAppMessage(ContentAppMessageResponseCallback callback, Option @Override public void onResponse(StructType invokeStructValue) { final long statusFieldID = 0L; - Optional status = Optional.empty(); + Integer status = null; final long dataFieldID = 1L; - String data = null; + Optional data = Optional.empty(); final long encodingHintFieldID = 2L; - String encodingHint = null; + Optional encodingHint = Optional.empty(); for (StructElement element: invokeStructValue.value()) { if (element.contextTagNum() == statusFieldID) { if (element.value(BaseTLVType.class).type() == TLVType.UInt) { UIntType castingValue = element.value(UIntType.class); - status = Optional.of(castingValue.value(Integer.class)); + status = castingValue.value(Integer.class); } } else if (element.contextTagNum() == dataFieldID) { if (element.value(BaseTLVType.class).type() == TLVType.String) { StringType castingValue = element.value(StringType.class); - data = castingValue.value(String.class); + data = Optional.of(castingValue.value(String.class)); } } else if (element.contextTagNum() == encodingHintFieldID) { if (element.value(BaseTLVType.class).type() == TLVType.String) { StringType castingValue = element.value(StringType.class); - encodingHint = castingValue.value(String.class); + encodingHint = Optional.of(castingValue.value(String.class)); } } } @@ -53642,7 +53642,7 @@ public void onResponse(StructType invokeStructValue) { } public interface ContentAppMessageResponseCallback extends BaseClusterCallback { - void onSuccess(Optional status, String data, String encodingHint); + void onSuccess(Integer status, Optional data, Optional encodingHint); } public interface GeneratedCommandListAttributeCallback extends BaseAttributeCallback { diff --git a/src/controller/java/generated/java/chip/devicecontroller/ClusterInfoMapping.java b/src/controller/java/generated/java/chip/devicecontroller/ClusterInfoMapping.java index 6860b30cff08ad..187400cba467b4 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/ClusterInfoMapping.java +++ b/src/controller/java/generated/java/chip/devicecontroller/ClusterInfoMapping.java @@ -16126,11 +16126,11 @@ public void setCallbackDelegate(ClusterCommandCallback callback) { } @Override - public void onSuccess(Integer channelPagingStruct, ArrayList programList) { + public void onSuccess(ChipStructs.ChannelClusterChannelPagingStruct paging, ArrayList programList) { Map responseValues = new LinkedHashMap<>(); - CommandResponseInfo channelPagingStructResponseValue = new CommandResponseInfo("channelPagingStruct", "Integer"); - responseValues.put(channelPagingStructResponseValue, channelPagingStruct); + // paging: Struct ChannelPagingStruct + // Conversion from this type to Java is not properly implemented yet // programList: ProgramStruct // Conversion from this type to Java is not properly implemented yet @@ -17783,14 +17783,14 @@ public void setCallbackDelegate(ClusterCommandCallback callback) { } @Override - public void onSuccess(Optional status, String data, String encodingHint) { + public void onSuccess(Integer status, Optional data, Optional encodingHint) { Map responseValues = new LinkedHashMap<>(); - CommandResponseInfo statusResponseValue = new CommandResponseInfo("status", "Optional"); + CommandResponseInfo statusResponseValue = new CommandResponseInfo("status", "Integer"); responseValues.put(statusResponseValue, status); - CommandResponseInfo dataResponseValue = new CommandResponseInfo("data", "String"); + CommandResponseInfo dataResponseValue = new CommandResponseInfo("data", "Optional"); responseValues.put(dataResponseValue, data); - CommandResponseInfo encodingHintResponseValue = new CommandResponseInfo("encodingHint", "String"); + CommandResponseInfo encodingHintResponseValue = new CommandResponseInfo("encodingHint", "Optional"); responseValues.put(encodingHintResponseValue, encodingHint); callback.onSuccess(responseValues); } diff --git a/src/controller/java/generated/java/matter/controller/cluster/clusters/ChannelCluster.kt b/src/controller/java/generated/java/matter/controller/cluster/clusters/ChannelCluster.kt index 7825944363b1aa..653f118fc66440 100644 --- a/src/controller/java/generated/java/matter/controller/cluster/clusters/ChannelCluster.kt +++ b/src/controller/java/generated/java/matter/controller/cluster/clusters/ChannelCluster.kt @@ -43,7 +43,7 @@ class ChannelCluster(private val controller: MatterController, private val endpo class ChangeChannelResponse(val status: UByte, val data: String?) class ProgramGuideResponse( - val channelPagingStruct: Short, + val paging: ChannelClusterChannelPagingStruct, val programList: List ) @@ -294,8 +294,8 @@ class ChannelCluster(private val controller: MatterController, private val endpo val tlvReader = TlvReader(response.payload) tlvReader.enterStructure(AnonymousTag) - val TAG_CHANNEL_PAGING_STRUCT: Int = 0 - var channelPagingStruct_decoded: Short? = null + val TAG_PAGING: Int = 0 + var paging_decoded: ChannelClusterChannelPagingStruct? = null val TAG_PROGRAM_LIST: Int = 1 var programList_decoded: List? = null @@ -303,8 +303,8 @@ class ChannelCluster(private val controller: MatterController, private val endpo while (!tlvReader.isEndOfContainer()) { val tag = tlvReader.peekElement().tag - if (tag == ContextSpecificTag(TAG_CHANNEL_PAGING_STRUCT)) { - channelPagingStruct_decoded = tlvReader.getShort(tag) + if (tag == ContextSpecificTag(TAG_PAGING)) { + paging_decoded = ChannelClusterChannelPagingStruct.fromTlv(tag, tlvReader) } if (tag == ContextSpecificTag(TAG_PROGRAM_LIST)) { @@ -321,8 +321,8 @@ class ChannelCluster(private val controller: MatterController, private val endpo } } - if (channelPagingStruct_decoded == null) { - throw IllegalStateException("channelPagingStruct not found in TLV") + if (paging_decoded == null) { + throw IllegalStateException("paging not found in TLV") } if (programList_decoded == null) { @@ -331,7 +331,7 @@ class ChannelCluster(private val controller: MatterController, private val endpo tlvReader.exitContainer() - return ProgramGuideResponse(channelPagingStruct_decoded, programList_decoded) + return ProgramGuideResponse(paging_decoded, programList_decoded) } suspend fun recordProgram( diff --git a/src/controller/java/generated/java/matter/controller/cluster/clusters/ContentAppObserverCluster.kt b/src/controller/java/generated/java/matter/controller/cluster/clusters/ContentAppObserverCluster.kt index 68ca2fa84898cb..4c08eb6499a918 100644 --- a/src/controller/java/generated/java/matter/controller/cluster/clusters/ContentAppObserverCluster.kt +++ b/src/controller/java/generated/java/matter/controller/cluster/clusters/ContentAppObserverCluster.kt @@ -43,7 +43,7 @@ class ContentAppObserverCluster( private val controller: MatterController, private val endpointId: UShort ) { - class ContentAppMessageResponse(val status: UByte?, val data: String, val encodingHint: String) + class ContentAppMessageResponse(val status: UByte, val data: String?, val encodingHint: String?) class GeneratedCommandListAttribute(val value: List) @@ -127,36 +127,42 @@ class ContentAppObserverCluster( val tag = tlvReader.peekElement().tag if (tag == ContextSpecificTag(TAG_STATUS)) { - status_decoded = + status_decoded = tlvReader.getUByte(tag) + } + + if (tag == ContextSpecificTag(TAG_DATA)) { + data_decoded = if (tlvReader.isNull()) { tlvReader.getNull(tag) null } else { if (tlvReader.isNextTag(tag)) { - tlvReader.getUByte(tag) + tlvReader.getString(tag) } else { null } } } - if (tag == ContextSpecificTag(TAG_DATA)) { - data_decoded = tlvReader.getString(tag) - } - if (tag == ContextSpecificTag(TAG_ENCODING_HINT)) { - encodingHint_decoded = tlvReader.getString(tag) + encodingHint_decoded = + if (tlvReader.isNull()) { + tlvReader.getNull(tag) + null + } else { + if (tlvReader.isNextTag(tag)) { + tlvReader.getString(tag) + } else { + null + } + } } else { tlvReader.skipElement() } } - if (data_decoded == null) { - throw IllegalStateException("data not found in TLV") - } - - if (encodingHint_decoded == null) { - throw IllegalStateException("encodingHint not found in TLV") + if (status_decoded == null) { + throw IllegalStateException("status not found in TLV") } tlvReader.exitContainer() diff --git a/src/controller/java/zap-generated/CHIPInvokeCallbacks.cpp b/src/controller/java/zap-generated/CHIPInvokeCallbacks.cpp index 2b5fa3ff8429ea..097ba520f805e3 100644 --- a/src/controller/java/zap-generated/CHIPInvokeCallbacks.cpp +++ b/src/controller/java/zap-generated/CHIPInvokeCallbacks.cpp @@ -5093,17 +5093,200 @@ void CHIPChannelClusterProgramGuideResponseCallback::CallbackFn( // Java callback is allowed to be null, exit early if this is the case. VerifyOrReturn(javaCallbackRef != nullptr); - err = JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/Integer;Ljava/util/ArrayList;)V", - &javaMethod); + err = JniReferences::GetInstance().FindMethod( + env, javaCallbackRef, "onSuccess", + "(Lchip/devicecontroller/ChipStructs$ChannelClusterChannelPagingStruct;Ljava/util/ArrayList;)V", &javaMethod); VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error invoking Java callback: %s", ErrorStr(err))); - jobject ChannelPagingStruct; - std::string ChannelPagingStructClassName = "java/lang/Integer"; - std::string ChannelPagingStructCtorSignature = "(I)V"; - jint jniChannelPagingStruct = static_cast(dataResponse.channelPagingStruct); - chip::JniReferences::GetInstance().CreateBoxedObject(ChannelPagingStructClassName.c_str(), - ChannelPagingStructCtorSignature.c_str(), jniChannelPagingStruct, - ChannelPagingStruct); + jobject Paging; + jobject Paging_previousToken; + if (!dataResponse.paging.previousToken.HasValue()) + { + chip::JniReferences::GetInstance().CreateOptional(nullptr, Paging_previousToken); + } + else + { + jobject Paging_previousTokenInsideOptional; + if (dataResponse.paging.previousToken.Value().IsNull()) + { + Paging_previousTokenInsideOptional = nullptr; + } + else + { + jobject Paging_previousTokenInsideOptional_limit; + if (!dataResponse.paging.previousToken.Value().Value().limit.HasValue()) + { + chip::JniReferences::GetInstance().CreateOptional(nullptr, Paging_previousTokenInsideOptional_limit); + } + else + { + jobject Paging_previousTokenInsideOptional_limitInsideOptional; + std::string Paging_previousTokenInsideOptional_limitInsideOptionalClassName = "java/lang/Integer"; + std::string Paging_previousTokenInsideOptional_limitInsideOptionalCtorSignature = "(I)V"; + jint jniPaging_previousTokenInsideOptional_limitInsideOptional = + static_cast(dataResponse.paging.previousToken.Value().Value().limit.Value()); + chip::JniReferences::GetInstance().CreateBoxedObject( + Paging_previousTokenInsideOptional_limitInsideOptionalClassName.c_str(), + Paging_previousTokenInsideOptional_limitInsideOptionalCtorSignature.c_str(), + jniPaging_previousTokenInsideOptional_limitInsideOptional, + Paging_previousTokenInsideOptional_limitInsideOptional); + chip::JniReferences::GetInstance().CreateOptional(Paging_previousTokenInsideOptional_limitInsideOptional, + Paging_previousTokenInsideOptional_limit); + } + jobject Paging_previousTokenInsideOptional_after; + if (!dataResponse.paging.previousToken.Value().Value().after.HasValue()) + { + chip::JniReferences::GetInstance().CreateOptional(nullptr, Paging_previousTokenInsideOptional_after); + } + else + { + jobject Paging_previousTokenInsideOptional_afterInsideOptional; + LogErrorOnFailure(chip::JniReferences::GetInstance().CharToStringUTF( + dataResponse.paging.previousToken.Value().Value().after.Value(), + Paging_previousTokenInsideOptional_afterInsideOptional)); + chip::JniReferences::GetInstance().CreateOptional(Paging_previousTokenInsideOptional_afterInsideOptional, + Paging_previousTokenInsideOptional_after); + } + jobject Paging_previousTokenInsideOptional_before; + if (!dataResponse.paging.previousToken.Value().Value().before.HasValue()) + { + chip::JniReferences::GetInstance().CreateOptional(nullptr, Paging_previousTokenInsideOptional_before); + } + else + { + jobject Paging_previousTokenInsideOptional_beforeInsideOptional; + LogErrorOnFailure(chip::JniReferences::GetInstance().CharToStringUTF( + dataResponse.paging.previousToken.Value().Value().before.Value(), + Paging_previousTokenInsideOptional_beforeInsideOptional)); + chip::JniReferences::GetInstance().CreateOptional(Paging_previousTokenInsideOptional_beforeInsideOptional, + Paging_previousTokenInsideOptional_before); + } + + jclass pageTokenStructStructClass_3; + err = chip::JniReferences::GetInstance().GetClassRef( + env, "chip/devicecontroller/ChipStructs$ChannelClusterPageTokenStruct", pageTokenStructStructClass_3); + if (err != CHIP_NO_ERROR) + { + ChipLogError(Zcl, "Could not find class ChipStructs$ChannelClusterPageTokenStruct"); + return; + } + jmethodID pageTokenStructStructCtor_3 = env->GetMethodID( + pageTokenStructStructClass_3, "", "(Ljava/util/Optional;Ljava/util/Optional;Ljava/util/Optional;)V"); + if (pageTokenStructStructCtor_3 == nullptr) + { + ChipLogError(Zcl, "Could not find ChipStructs$ChannelClusterPageTokenStruct constructor"); + return; + } + + Paging_previousTokenInsideOptional = + env->NewObject(pageTokenStructStructClass_3, pageTokenStructStructCtor_3, Paging_previousTokenInsideOptional_limit, + Paging_previousTokenInsideOptional_after, Paging_previousTokenInsideOptional_before); + } + chip::JniReferences::GetInstance().CreateOptional(Paging_previousTokenInsideOptional, Paging_previousToken); + } + jobject Paging_nextToken; + if (!dataResponse.paging.nextToken.HasValue()) + { + chip::JniReferences::GetInstance().CreateOptional(nullptr, Paging_nextToken); + } + else + { + jobject Paging_nextTokenInsideOptional; + if (dataResponse.paging.nextToken.Value().IsNull()) + { + Paging_nextTokenInsideOptional = nullptr; + } + else + { + jobject Paging_nextTokenInsideOptional_limit; + if (!dataResponse.paging.nextToken.Value().Value().limit.HasValue()) + { + chip::JniReferences::GetInstance().CreateOptional(nullptr, Paging_nextTokenInsideOptional_limit); + } + else + { + jobject Paging_nextTokenInsideOptional_limitInsideOptional; + std::string Paging_nextTokenInsideOptional_limitInsideOptionalClassName = "java/lang/Integer"; + std::string Paging_nextTokenInsideOptional_limitInsideOptionalCtorSignature = "(I)V"; + jint jniPaging_nextTokenInsideOptional_limitInsideOptional = + static_cast(dataResponse.paging.nextToken.Value().Value().limit.Value()); + chip::JniReferences::GetInstance().CreateBoxedObject( + Paging_nextTokenInsideOptional_limitInsideOptionalClassName.c_str(), + Paging_nextTokenInsideOptional_limitInsideOptionalCtorSignature.c_str(), + jniPaging_nextTokenInsideOptional_limitInsideOptional, Paging_nextTokenInsideOptional_limitInsideOptional); + chip::JniReferences::GetInstance().CreateOptional(Paging_nextTokenInsideOptional_limitInsideOptional, + Paging_nextTokenInsideOptional_limit); + } + jobject Paging_nextTokenInsideOptional_after; + if (!dataResponse.paging.nextToken.Value().Value().after.HasValue()) + { + chip::JniReferences::GetInstance().CreateOptional(nullptr, Paging_nextTokenInsideOptional_after); + } + else + { + jobject Paging_nextTokenInsideOptional_afterInsideOptional; + LogErrorOnFailure( + chip::JniReferences::GetInstance().CharToStringUTF(dataResponse.paging.nextToken.Value().Value().after.Value(), + Paging_nextTokenInsideOptional_afterInsideOptional)); + chip::JniReferences::GetInstance().CreateOptional(Paging_nextTokenInsideOptional_afterInsideOptional, + Paging_nextTokenInsideOptional_after); + } + jobject Paging_nextTokenInsideOptional_before; + if (!dataResponse.paging.nextToken.Value().Value().before.HasValue()) + { + chip::JniReferences::GetInstance().CreateOptional(nullptr, Paging_nextTokenInsideOptional_before); + } + else + { + jobject Paging_nextTokenInsideOptional_beforeInsideOptional; + LogErrorOnFailure( + chip::JniReferences::GetInstance().CharToStringUTF(dataResponse.paging.nextToken.Value().Value().before.Value(), + Paging_nextTokenInsideOptional_beforeInsideOptional)); + chip::JniReferences::GetInstance().CreateOptional(Paging_nextTokenInsideOptional_beforeInsideOptional, + Paging_nextTokenInsideOptional_before); + } + + jclass pageTokenStructStructClass_3; + err = chip::JniReferences::GetInstance().GetClassRef( + env, "chip/devicecontroller/ChipStructs$ChannelClusterPageTokenStruct", pageTokenStructStructClass_3); + if (err != CHIP_NO_ERROR) + { + ChipLogError(Zcl, "Could not find class ChipStructs$ChannelClusterPageTokenStruct"); + return; + } + jmethodID pageTokenStructStructCtor_3 = env->GetMethodID( + pageTokenStructStructClass_3, "", "(Ljava/util/Optional;Ljava/util/Optional;Ljava/util/Optional;)V"); + if (pageTokenStructStructCtor_3 == nullptr) + { + ChipLogError(Zcl, "Could not find ChipStructs$ChannelClusterPageTokenStruct constructor"); + return; + } + + Paging_nextTokenInsideOptional = + env->NewObject(pageTokenStructStructClass_3, pageTokenStructStructCtor_3, Paging_nextTokenInsideOptional_limit, + Paging_nextTokenInsideOptional_after, Paging_nextTokenInsideOptional_before); + } + chip::JniReferences::GetInstance().CreateOptional(Paging_nextTokenInsideOptional, Paging_nextToken); + } + + jclass channelPagingStructStructClass_0; + err = chip::JniReferences::GetInstance().GetClassRef(env, "chip/devicecontroller/ChipStructs$ChannelClusterChannelPagingStruct", + channelPagingStructStructClass_0); + if (err != CHIP_NO_ERROR) + { + ChipLogError(Zcl, "Could not find class ChipStructs$ChannelClusterChannelPagingStruct"); + return; + } + jmethodID channelPagingStructStructCtor_0 = + env->GetMethodID(channelPagingStructStructClass_0, "", "(Ljava/util/Optional;Ljava/util/Optional;)V"); + if (channelPagingStructStructCtor_0 == nullptr) + { + ChipLogError(Zcl, "Could not find ChipStructs$ChannelClusterChannelPagingStruct constructor"); + return; + } + + Paging = + env->NewObject(channelPagingStructStructClass_0, channelPagingStructStructCtor_0, Paging_previousToken, Paging_nextToken); jobject ProgramList; chip::JniReferences::GetInstance().CreateArrayList(ProgramList); @@ -5591,7 +5774,7 @@ void CHIPChannelClusterProgramGuideResponseCallback::CallbackFn( chip::JniReferences::GetInstance().AddToList(ProgramList, newElement_0); } - env->CallVoidMethod(javaCallbackRef, javaMethod, ChannelPagingStruct, ProgramList); + env->CallVoidMethod(javaCallbackRef, javaMethod, Paging, ProgramList); } CHIPTargetNavigatorClusterNavigateTargetResponseCallback::CHIPTargetNavigatorClusterNavigateTargetResponseCallback( jobject javaCallback) : Callback::Callback(CallbackFn, this) @@ -6112,29 +6295,38 @@ void CHIPContentAppObserverClusterContentAppMessageResponseCallback::CallbackFn( VerifyOrReturn(javaCallbackRef != nullptr); err = JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", - "(Ljava/util/Optional;Ljava/lang/String;Ljava/lang/String;)V", &javaMethod); + "(Ljava/lang/Integer;Ljava/util/Optional;Ljava/util/Optional;)V", &javaMethod); VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error invoking Java callback: %s", ErrorStr(err))); jobject Status; - if (!dataResponse.status.HasValue()) + std::string StatusClassName = "java/lang/Integer"; + std::string StatusCtorSignature = "(I)V"; + jint jniStatus = static_cast(dataResponse.status); + chip::JniReferences::GetInstance().CreateBoxedObject(StatusClassName.c_str(), StatusCtorSignature.c_str(), jniStatus, + Status); + jobject Data; + if (!dataResponse.data.HasValue()) { - chip::JniReferences::GetInstance().CreateOptional(nullptr, Status); + chip::JniReferences::GetInstance().CreateOptional(nullptr, Data); } else { - jobject StatusInsideOptional; - std::string StatusInsideOptionalClassName = "java/lang/Integer"; - std::string StatusInsideOptionalCtorSignature = "(I)V"; - jint jniStatusInsideOptional = static_cast(dataResponse.status.Value()); - chip::JniReferences::GetInstance().CreateBoxedObject(StatusInsideOptionalClassName.c_str(), - StatusInsideOptionalCtorSignature.c_str(), - jniStatusInsideOptional, StatusInsideOptional); - chip::JniReferences::GetInstance().CreateOptional(StatusInsideOptional, Status); + jobject DataInsideOptional; + LogErrorOnFailure(chip::JniReferences::GetInstance().CharToStringUTF(dataResponse.data.Value(), DataInsideOptional)); + chip::JniReferences::GetInstance().CreateOptional(DataInsideOptional, Data); } - jobject Data; - LogErrorOnFailure(chip::JniReferences::GetInstance().CharToStringUTF(dataResponse.data, Data)); jobject EncodingHint; - LogErrorOnFailure(chip::JniReferences::GetInstance().CharToStringUTF(dataResponse.encodingHint, EncodingHint)); + if (!dataResponse.encodingHint.HasValue()) + { + chip::JniReferences::GetInstance().CreateOptional(nullptr, EncodingHint); + } + else + { + jobject EncodingHintInsideOptional; + LogErrorOnFailure( + chip::JniReferences::GetInstance().CharToStringUTF(dataResponse.encodingHint.Value(), EncodingHintInsideOptional)); + chip::JniReferences::GetInstance().CreateOptional(EncodingHintInsideOptional, EncodingHint); + } env->CallVoidMethod(javaCallbackRef, javaMethod, Status, Data, EncodingHint); } diff --git a/src/controller/python/chip/clusters/Objects.py b/src/controller/python/chip/clusters/Objects.py index c5ca57c4ac6653..c5874b2aaec964 100644 --- a/src/controller/python/chip/clusters/Objects.py +++ b/src/controller/python/chip/clusters/Objects.py @@ -38338,11 +38338,11 @@ class ProgramGuideResponse(ClusterCommand): def descriptor(cls) -> ClusterObjectDescriptor: return ClusterObjectDescriptor( Fields=[ - ClusterObjectFieldDescriptor(Label="channelPagingStruct", Tag=0, Type=int), + ClusterObjectFieldDescriptor(Label="paging", Tag=0, Type=Channel.Structs.ChannelPagingStruct), ClusterObjectFieldDescriptor(Label="programList", Tag=1, Type=typing.List[Channel.Structs.ProgramStruct]), ]) - channelPagingStruct: 'int' = 0 + paging: 'Channel.Structs.ChannelPagingStruct' = field(default_factory=lambda: Channel.Structs.ChannelPagingStruct()) programList: 'typing.List[Channel.Structs.ProgramStruct]' = field(default_factory=lambda: []) @dataclass @@ -42079,14 +42079,14 @@ class ContentAppMessageResponse(ClusterCommand): def descriptor(cls) -> ClusterObjectDescriptor: return ClusterObjectDescriptor( Fields=[ - ClusterObjectFieldDescriptor(Label="status", Tag=0, Type=typing.Optional[ContentAppObserver.Enums.StatusEnum]), - ClusterObjectFieldDescriptor(Label="data", Tag=1, Type=str), - ClusterObjectFieldDescriptor(Label="encodingHint", Tag=2, Type=str), + ClusterObjectFieldDescriptor(Label="status", Tag=0, Type=ContentAppObserver.Enums.StatusEnum), + ClusterObjectFieldDescriptor(Label="data", Tag=1, Type=typing.Optional[str]), + ClusterObjectFieldDescriptor(Label="encodingHint", Tag=2, Type=typing.Optional[str]), ]) - status: 'typing.Optional[ContentAppObserver.Enums.StatusEnum]' = None - data: 'str' = "" - encodingHint: 'str' = "" + status: 'ContentAppObserver.Enums.StatusEnum' = 0 + data: 'typing.Optional[str]' = None + encodingHint: 'typing.Optional[str]' = None class Attributes: @dataclass diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.h b/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.h index a59c89efbeacd1..b504710419a283 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.h +++ b/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.h @@ -8564,7 +8564,7 @@ MTR_PROVISIONALLY_AVAILABLE MTR_PROVISIONALLY_AVAILABLE @interface MTRChannelClusterProgramGuideResponseParams : NSObject -@property (nonatomic, copy) NSNumber * _Nonnull channelPagingStruct MTR_PROVISIONALLY_AVAILABLE; +@property (nonatomic, copy) MTRChannelClusterChannelPagingStruct * _Nonnull paging MTR_PROVISIONALLY_AVAILABLE; @property (nonatomic, copy) NSArray * _Nonnull programList MTR_PROVISIONALLY_AVAILABLE; @@ -10201,11 +10201,11 @@ MTR_PROVISIONALLY_AVAILABLE MTR_PROVISIONALLY_AVAILABLE @interface MTRContentAppObserverClusterContentAppMessageResponseParams : NSObject -@property (nonatomic, copy) NSNumber * _Nullable status MTR_PROVISIONALLY_AVAILABLE; +@property (nonatomic, copy) NSNumber * _Nonnull status MTR_PROVISIONALLY_AVAILABLE; -@property (nonatomic, copy) NSString * _Nonnull data MTR_PROVISIONALLY_AVAILABLE; +@property (nonatomic, copy) NSString * _Nullable data MTR_PROVISIONALLY_AVAILABLE; -@property (nonatomic, copy) NSString * _Nonnull encodingHint MTR_PROVISIONALLY_AVAILABLE; +@property (nonatomic, copy) NSString * _Nullable encodingHint MTR_PROVISIONALLY_AVAILABLE; /** * Initialize an MTRContentAppObserverClusterContentAppMessageResponseParams with a response-value dictionary diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.mm b/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.mm index b82bb7872fbb24..35c71e8afd4c3f 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.mm @@ -23857,7 +23857,7 @@ - (instancetype)init { if (self = [super init]) { - _channelPagingStruct = @(0); + _paging = [MTRChannelClusterChannelPagingStruct new]; _programList = [NSArray array]; } @@ -23868,7 +23868,7 @@ - (id)copyWithZone:(NSZone * _Nullable)zone; { auto other = [[MTRChannelClusterProgramGuideResponseParams alloc] init]; - other.channelPagingStruct = self.channelPagingStruct; + other.paging = self.paging; other.programList = self.programList; return other; @@ -23876,7 +23876,7 @@ - (id)copyWithZone:(NSZone * _Nullable)zone; - (NSString *)description { - NSString * descriptionString = [NSString stringWithFormat:@"<%@: channelPagingStruct:%@; programList:%@; >", NSStringFromClass([self class]), _channelPagingStruct, _programList]; + NSString * descriptionString = [NSString stringWithFormat:@"<%@: paging:%@; programList:%@; >", NSStringFromClass([self class]), _paging, _programList]; return descriptionString; } @@ -23927,7 +23927,71 @@ @implementation MTRChannelClusterProgramGuideResponseParams (InternalMethods) - (CHIP_ERROR)_setFieldsFromDecodableStruct:(const chip::app::Clusters::Channel::Commands::ProgramGuideResponse::DecodableType &)decodableStruct { { - self.channelPagingStruct = [NSNumber numberWithShort:decodableStruct.channelPagingStruct]; + self.paging = [MTRChannelClusterChannelPagingStruct new]; + if (decodableStruct.paging.previousToken.HasValue()) { + if (decodableStruct.paging.previousToken.Value().IsNull()) { + self.paging.previousToken = nil; + } else { + self.paging.previousToken = [MTRChannelClusterPageTokenStruct new]; + if (decodableStruct.paging.previousToken.Value().Value().limit.HasValue()) { + self.paging.previousToken.limit = [NSNumber numberWithUnsignedShort:decodableStruct.paging.previousToken.Value().Value().limit.Value()]; + } else { + self.paging.previousToken.limit = nil; + } + if (decodableStruct.paging.previousToken.Value().Value().after.HasValue()) { + self.paging.previousToken.after = AsString(decodableStruct.paging.previousToken.Value().Value().after.Value()); + if (self.paging.previousToken.after == nil) { + CHIP_ERROR err = CHIP_ERROR_INVALID_ARGUMENT; + return err; + } + } else { + self.paging.previousToken.after = nil; + } + if (decodableStruct.paging.previousToken.Value().Value().before.HasValue()) { + self.paging.previousToken.before = AsString(decodableStruct.paging.previousToken.Value().Value().before.Value()); + if (self.paging.previousToken.before == nil) { + CHIP_ERROR err = CHIP_ERROR_INVALID_ARGUMENT; + return err; + } + } else { + self.paging.previousToken.before = nil; + } + } + } else { + self.paging.previousToken = nil; + } + if (decodableStruct.paging.nextToken.HasValue()) { + if (decodableStruct.paging.nextToken.Value().IsNull()) { + self.paging.nextToken = nil; + } else { + self.paging.nextToken = [MTRChannelClusterPageTokenStruct new]; + if (decodableStruct.paging.nextToken.Value().Value().limit.HasValue()) { + self.paging.nextToken.limit = [NSNumber numberWithUnsignedShort:decodableStruct.paging.nextToken.Value().Value().limit.Value()]; + } else { + self.paging.nextToken.limit = nil; + } + if (decodableStruct.paging.nextToken.Value().Value().after.HasValue()) { + self.paging.nextToken.after = AsString(decodableStruct.paging.nextToken.Value().Value().after.Value()); + if (self.paging.nextToken.after == nil) { + CHIP_ERROR err = CHIP_ERROR_INVALID_ARGUMENT; + return err; + } + } else { + self.paging.nextToken.after = nil; + } + if (decodableStruct.paging.nextToken.Value().Value().before.HasValue()) { + self.paging.nextToken.before = AsString(decodableStruct.paging.nextToken.Value().Value().before.Value()); + if (self.paging.nextToken.before == nil) { + CHIP_ERROR err = CHIP_ERROR_INVALID_ARGUMENT; + return err; + } + } else { + self.paging.nextToken.before = nil; + } + } + } else { + self.paging.nextToken = nil; + } } { { // Scope for our temporary variables @@ -28702,11 +28766,11 @@ - (instancetype)init { if (self = [super init]) { - _status = nil; + _status = @(0); - _data = @""; + _data = nil; - _encodingHint = @""; + _encodingHint = nil; } return self; } @@ -28775,24 +28839,28 @@ @implementation MTRContentAppObserverClusterContentAppMessageResponseParams (Int - (CHIP_ERROR)_setFieldsFromDecodableStruct:(const chip::app::Clusters::ContentAppObserver::Commands::ContentAppMessageResponse::DecodableType &)decodableStruct { { - if (decodableStruct.status.HasValue()) { - self.status = [NSNumber numberWithUnsignedChar:chip::to_underlying(decodableStruct.status.Value())]; - } else { - self.status = nil; - } + self.status = [NSNumber numberWithUnsignedChar:chip::to_underlying(decodableStruct.status)]; } { - self.data = AsString(decodableStruct.data); - if (self.data == nil) { - CHIP_ERROR err = CHIP_ERROR_INVALID_ARGUMENT; - return err; + if (decodableStruct.data.HasValue()) { + self.data = AsString(decodableStruct.data.Value()); + if (self.data == nil) { + CHIP_ERROR err = CHIP_ERROR_INVALID_ARGUMENT; + return err; + } + } else { + self.data = nil; } } { - self.encodingHint = AsString(decodableStruct.encodingHint); - if (self.encodingHint == nil) { - CHIP_ERROR err = CHIP_ERROR_INVALID_ARGUMENT; - return err; + if (decodableStruct.encodingHint.HasValue()) { + self.encodingHint = AsString(decodableStruct.encodingHint.Value()); + if (self.encodingHint == nil) { + CHIP_ERROR err = CHIP_ERROR_INVALID_ARGUMENT; + return err; + } + } else { + self.encodingHint = nil; } } return CHIP_NO_ERROR; diff --git a/zzz_generated/app-common/app-common/zap-generated/cluster-objects.cpp b/zzz_generated/app-common/app-common/zap-generated/cluster-objects.cpp index 770ec90ad04adb..7d25bcce933bb4 100644 --- a/zzz_generated/app-common/app-common/zap-generated/cluster-objects.cpp +++ b/zzz_generated/app-common/app-common/zap-generated/cluster-objects.cpp @@ -22108,7 +22108,7 @@ namespace ProgramGuideResponse { CHIP_ERROR Type::Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const { DataModel::WrappedStructEncoder encoder{ aWriter, aTag }; - encoder.Encode(to_underlying(Fields::kChannelPagingStruct), channelPagingStruct); + encoder.Encode(to_underlying(Fields::kPaging), paging); encoder.Encode(to_underlying(Fields::kProgramList), programList); return encoder.Finalize(); } @@ -22127,9 +22127,9 @@ CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader) CHIP_ERROR err = CHIP_NO_ERROR; const uint8_t __context_tag = std::get(__element); - if (__context_tag == to_underlying(Fields::kChannelPagingStruct)) + if (__context_tag == to_underlying(Fields::kPaging)) { - err = DataModel::Decode(reader, channelPagingStruct); + err = DataModel::Decode(reader, paging); } else if (__context_tag == to_underlying(Fields::kProgramList)) { diff --git a/zzz_generated/app-common/app-common/zap-generated/cluster-objects.h b/zzz_generated/app-common/app-common/zap-generated/cluster-objects.h index 703f14128611ae..c292a11f999cd8 100644 --- a/zzz_generated/app-common/app-common/zap-generated/cluster-objects.h +++ b/zzz_generated/app-common/app-common/zap-generated/cluster-objects.h @@ -33376,8 +33376,8 @@ struct DecodableType namespace ProgramGuideResponse { enum class Fields : uint8_t { - kChannelPagingStruct = 0, - kProgramList = 1, + kPaging = 0, + kProgramList = 1, }; struct Type @@ -33387,7 +33387,7 @@ struct Type static constexpr CommandId GetCommandId() { return Commands::ProgramGuideResponse::Id; } static constexpr ClusterId GetClusterId() { return Clusters::Channel::Id; } - int16_t channelPagingStruct = static_cast(0); + Structs::ChannelPagingStruct::Type paging; DataModel::List programList; CHIP_ERROR Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const; @@ -33403,7 +33403,7 @@ struct DecodableType static constexpr CommandId GetCommandId() { return Commands::ProgramGuideResponse::Id; } static constexpr ClusterId GetClusterId() { return Clusters::Channel::Id; } - int16_t channelPagingStruct = static_cast(0); + Structs::ChannelPagingStruct::DecodableType paging; DataModel::DecodableList programList; CHIP_ERROR Decode(TLV::TLVReader & reader); }; @@ -37276,9 +37276,9 @@ struct Type static constexpr CommandId GetCommandId() { return Commands::ContentAppMessageResponse::Id; } static constexpr ClusterId GetClusterId() { return Clusters::ContentAppObserver::Id; } - Optional status; - chip::CharSpan data; - chip::CharSpan encodingHint; + StatusEnum status = static_cast(0); + Optional data; + Optional encodingHint; CHIP_ERROR Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const; @@ -37293,9 +37293,9 @@ struct DecodableType static constexpr CommandId GetCommandId() { return Commands::ContentAppMessageResponse::Id; } static constexpr ClusterId GetClusterId() { return Clusters::ContentAppObserver::Id; } - Optional status; - chip::CharSpan data; - chip::CharSpan encodingHint; + StatusEnum status = static_cast(0); + Optional data; + Optional encodingHint; CHIP_ERROR Decode(TLV::TLVReader & reader); }; }; // namespace ContentAppMessageResponse diff --git a/zzz_generated/chip-tool/zap-generated/cluster/logging/DataModelLogger.cpp b/zzz_generated/chip-tool/zap-generated/cluster/logging/DataModelLogger.cpp index e0e24074789701..6089c40e02e3fd 100644 --- a/zzz_generated/chip-tool/zap-generated/cluster/logging/DataModelLogger.cpp +++ b/zzz_generated/chip-tool/zap-generated/cluster/logging/DataModelLogger.cpp @@ -7064,7 +7064,7 @@ CHIP_ERROR DataModelLogger::LogValue(const char * label, size_t indent, const Channel::Commands::ProgramGuideResponse::DecodableType & value) { DataModelLogger::LogString(label, indent, "{"); - ReturnErrorOnFailure(DataModelLogger::LogValue("channelPagingStruct", indent + 1, value.channelPagingStruct)); + ReturnErrorOnFailure(DataModelLogger::LogValue("paging", indent + 1, value.paging)); ReturnErrorOnFailure(DataModelLogger::LogValue("programList", indent + 1, value.programList)); DataModelLogger::LogString(indent, "}"); return CHIP_NO_ERROR; From 52f66e146765cb3f75d6a801a891afa70ab2537a Mon Sep 17 00:00:00 2001 From: Song GUO Date: Fri, 22 Dec 2023 04:43:19 +0800 Subject: [PATCH 15/29] [icd] read UserActiveModeTrigger during commissioning (#31039) * [icd] read UserActiveModeTrigger during commissioning * Update CommissionerMain.cpp fix typo --------- Co-authored-by: yunhanw-google --- .../commands/pairing/PairingCommand.cpp | 25 +++++++ .../commands/pairing/PairingCommand.h | 1 + examples/platform/linux/CommissionerMain.cpp | 23 +++++- src/controller/AutoCommissioner.cpp | 2 +- src/controller/CHIPDeviceController.cpp | 71 ++++++++++++++++--- src/controller/CommissioningDelegate.h | 23 +++++- 6 files changed, 133 insertions(+), 12 deletions(-) diff --git a/examples/chip-tool/commands/pairing/PairingCommand.cpp b/examples/chip-tool/commands/pairing/PairingCommand.cpp index e480b7a7c707c5..27edae038eb3a7 100644 --- a/examples/chip-tool/commands/pairing/PairingCommand.cpp +++ b/examples/chip-tool/commands/pairing/PairingCommand.cpp @@ -403,6 +403,31 @@ void PairingCommand::OnCommissioningComplete(NodeId nodeId, CHIP_ERROR err) SetCommandExitStatus(err); } +void PairingCommand::OnReadCommissioningInfo(const Controller::ReadCommissioningInfo & info) +{ + ChipLogProgress(AppServer, "OnReadCommissioningInfo - vendorId=0x%04X productId=0x%04X", info.basic.vendorId, + info.basic.productId); + + // The string in CharSpan received from the device is not null-terminated, we use std::string here for coping and + // appending a numm-terminator at the end of the string. + std::string userActiveModeTriggerInstruction; + + // Note: the callback doesn't own the buffer, should make a copy if it will be used it later. + if (info.icd.userActiveModeTriggerInstruction.size() != 0) + { + userActiveModeTriggerInstruction = + std::string(info.icd.userActiveModeTriggerInstruction.data(), info.icd.userActiveModeTriggerInstruction.size()); + } + + if (info.icd.userActiveModeTriggerHint.HasAny()) + { + ChipLogProgress(AppServer, "OnReadCommissioningInfo - LIT UserActiveModeTriggerHint=0x%08x", + info.icd.userActiveModeTriggerHint.Raw()); + ChipLogProgress(AppServer, "OnReadCommissioningInfo - LIT UserActiveModeTriggerInstruction=%s", + userActiveModeTriggerInstruction.c_str()); + } +} + void PairingCommand::OnICDRegistrationComplete(NodeId nodeId, uint32_t icdCounter) { char icdSymmetricKeyHex[chip::Crypto::kAES_CCM128_Key_Length * 2 + 1]; diff --git a/examples/chip-tool/commands/pairing/PairingCommand.h b/examples/chip-tool/commands/pairing/PairingCommand.h index 145aa6ffd901ae..c1df17282022b1 100644 --- a/examples/chip-tool/commands/pairing/PairingCommand.h +++ b/examples/chip-tool/commands/pairing/PairingCommand.h @@ -194,6 +194,7 @@ class PairingCommand : public CHIPCommand, void OnStatusUpdate(chip::Controller::DevicePairingDelegate::Status status) override; void OnPairingComplete(CHIP_ERROR error) override; void OnPairingDeleted(CHIP_ERROR error) override; + void OnReadCommissioningInfo(const chip::Controller::ReadCommissioningInfo & info) override; void OnCommissioningComplete(NodeId deviceId, CHIP_ERROR error) override; void OnICDRegistrationComplete(NodeId deviceId, uint32_t icdCounter) override; diff --git a/examples/platform/linux/CommissionerMain.cpp b/examples/platform/linux/CommissionerMain.cpp index 2b3f98ba5868b2..beaf915cf559c3 100644 --- a/examples/platform/linux/CommissionerMain.cpp +++ b/examples/platform/linux/CommissionerMain.cpp @@ -19,6 +19,8 @@ #include #include +#include + #if CHIP_DEVICE_CONFIG_ENABLE_BOTH_COMMISSIONER_AND_COMMISSIONEE #include @@ -342,10 +344,29 @@ void PairingCommand::OnCommissioningStatusUpdate(PeerId peerId, CommissioningSta } } -void PairingCommand::OnReadCommissioningInfo(const ReadCommissioningInfo & info) +void PairingCommand::OnReadCommissioningInfo(const Controller::ReadCommissioningInfo & info) { ChipLogProgress(AppServer, "OnReadCommissioningInfo - vendorId=0x%04X productId=0x%04X", info.basic.vendorId, info.basic.productId); + + // The string in CharSpan received from the device is not null-terminated, we use std::string here for coping and + // appending a numm-terminator at the end of the string. + std::string userActiveModeTriggerInstruction; + + // Note: the callback doesn't own the buffer, should make a copy if it will be used it later. + if (info.icd.userActiveModeTriggerInstruction.size() != 0) + { + userActiveModeTriggerInstruction = + std::string(info.icd.userActiveModeTriggerInstruction.data(), info.icd.userActiveModeTriggerInstruction.size()); + } + + if (info.icd.userActiveModeTriggerHint.HasAny()) + { + ChipLogProgress(AppServer, "OnReadCommissioningInfo - LIT UserActiveModeTriggerHint=0x%08x", + info.icd.userActiveModeTriggerHint.Raw()); + ChipLogProgress(AppServer, "OnReadCommissioningInfo - LIT UserActiveModeTriggerInstruction=%s", + userActiveModeTriggerInstruction.c_str()); + } } void PairingCommand::OnFabricCheck(NodeId matchingNodeId) diff --git a/src/controller/AutoCommissioner.cpp b/src/controller/AutoCommissioner.cpp index 5f289c662e696a..69a9c9b9c6bbf3 100644 --- a/src/controller/AutoCommissioner.cpp +++ b/src/controller/AutoCommissioner.cpp @@ -764,7 +764,7 @@ CHIP_ERROR AutoCommissioner::CommissioningStepFinished(CHIP_ERROR err, Commissio if (mParams.GetICDRegistrationStrategy() != ICDRegistrationStrategy::kIgnore) { - if (commissioningInfo.isLIT && commissioningInfo.checkInProtocolSupport) + if (commissioningInfo.icd.isLIT && commissioningInfo.icd.checkInProtocolSupport) { mNeedIcdRegistration = true; ChipLogDetail(Controller, "AutoCommissioner: ICD supports the check-in protocol."); diff --git a/src/controller/CHIPDeviceController.cpp b/src/controller/CHIPDeviceController.cpp index e69546161e661e..99cd69a5284bc7 100644 --- a/src/controller/CHIPDeviceController.cpp +++ b/src/controller/CHIPDeviceController.cpp @@ -1950,7 +1950,13 @@ void DeviceCommissioner::ParseCommissioningInfo() err = ParseCommissioningInfo2(info); } - mAttributeCache = nullptr; + // Move ownership of mAttributeCache to the stack, but don't release it until this function returns. + // This way we don't have to make a copy while parsing commissioning info, and it won't + // affect future commissioning steps. + // + // The stack reference needs to survive until CommissioningStageComplete and OnReadCommissioningInfo + // return. + auto attributeCache = std::move(mAttributeCache); if (mPairingDelegate != nullptr) { @@ -2265,21 +2271,24 @@ CHIP_ERROR DeviceCommissioner::ParseFabrics(ReadCommissioningInfo & info) CHIP_ERROR DeviceCommissioner::ParseICDInfo(ReadCommissioningInfo & info) { + using chip::app::Clusters::IcdManagement::UserActiveModeTriggerBitmap; + CHIP_ERROR err; IcdManagement::Attributes::FeatureMap::TypeInfo::DecodableType featureMap; + bool hasUserActiveModeTrigger = false; err = mAttributeCache->Get(kRootEndpointId, featureMap); if (err == CHIP_NO_ERROR) { - info.isLIT = true; - info.checkInProtocolSupport = !!(featureMap & to_underlying(IcdManagement::Feature::kCheckInProtocolSupport)); + info.icd.isLIT = !!(featureMap & to_underlying(IcdManagement::Feature::kLongIdleTimeSupport)); + info.icd.checkInProtocolSupport = !!(featureMap & to_underlying(IcdManagement::Feature::kCheckInProtocolSupport)); + hasUserActiveModeTrigger = !!(featureMap & to_underlying(IcdManagement::Feature::kUserActiveModeTrigger)); } else if (err == CHIP_ERROR_KEY_NOT_FOUND) { // This key is optional so not an error - err = CHIP_NO_ERROR; - info.isLIT = false; - err = CHIP_NO_ERROR; + info.icd.isLIT = false; + err = CHIP_NO_ERROR; } else if (err == CHIP_ERROR_IM_STATUS_CODE_RECEIVED) { @@ -2290,7 +2299,7 @@ CHIP_ERROR DeviceCommissioner::ParseICDInfo(ReadCommissioningInfo & info) { if (statusIB.mStatus == Protocols::InteractionModel::Status::UnsupportedCluster) { - info.isLIT = false; + info.icd.isLIT = false; } else { @@ -2299,6 +2308,45 @@ CHIP_ERROR DeviceCommissioner::ParseICDInfo(ReadCommissioningInfo & info) } } + ReturnErrorOnFailure(err); + + info.icd.userActiveModeTriggerHint.ClearAll(); + info.icd.userActiveModeTriggerInstruction = CharSpan(); + if (hasUserActiveModeTrigger) + { + // Intentionally ignore errors since they are not mandatory. + bool activeModeTriggerInstructionRequired = false; + + err = mAttributeCache->Get( + kRootEndpointId, info.icd.userActiveModeTriggerHint); + if (err != CHIP_NO_ERROR) + { + ChipLogError(Controller, "IcdManagement.UserActiveModeTriggerHint expected, but failed to read."); + return err; + } + + activeModeTriggerInstructionRequired = info.icd.userActiveModeTriggerHint.HasAny( + UserActiveModeTriggerBitmap::kCustomInstruction, UserActiveModeTriggerBitmap::kActuateSensorSeconds, + UserActiveModeTriggerBitmap::kActuateSensorTimes, UserActiveModeTriggerBitmap::kActuateSensorLightsBlink, + UserActiveModeTriggerBitmap::kResetButtonLightsBlink, UserActiveModeTriggerBitmap::kResetButtonSeconds, + UserActiveModeTriggerBitmap::kResetButtonTimes, UserActiveModeTriggerBitmap::kSetupButtonSeconds, + UserActiveModeTriggerBitmap::kSetupButtonTimes, UserActiveModeTriggerBitmap::kSetupButtonTimes, + UserActiveModeTriggerBitmap::kAppDefinedButton); + + if (activeModeTriggerInstructionRequired) + { + err = mAttributeCache->Get( + kRootEndpointId, info.icd.userActiveModeTriggerInstruction); + if (err != CHIP_NO_ERROR) + { + ChipLogError(Controller, + "IcdManagement.UserActiveModeTriggerInstruction expected for given active mode trigger hint, but " + "failed to read."); + return err; + } + } + } + return err; } @@ -2565,7 +2613,9 @@ void DeviceCommissioner::PerformCommissioningStep(DeviceProxy * proxy, Commissio // This is done in a separate step since we've already used up all the available read paths in the previous read step // NOTE: this array cannot have more than 9 entries, since the spec mandates that server only needs to support 9 // See R1.1, 2.11.2 Interaction Model Limits - app::AttributePathParams readPaths[3]; + + // Currently, we have at most 5 attributes to read in this stage. + app::AttributePathParams readPaths[5]; // Mandatory attribute readPaths[numberOfAttributes++] = @@ -2584,6 +2634,11 @@ void DeviceCommissioner::PerformCommissioningStep(DeviceProxy * proxy, Commissio readPaths[numberOfAttributes++] = app::AttributePathParams(endpoint, IcdManagement::Id, IcdManagement::Attributes::FeatureMap::Id); } + // Always read the active mode trigger hint attributes to notify users about it. + readPaths[numberOfAttributes++] = + app::AttributePathParams(endpoint, IcdManagement::Id, IcdManagement::Attributes::UserActiveModeTriggerHint::Id); + readPaths[numberOfAttributes++] = + app::AttributePathParams(endpoint, IcdManagement::Id, IcdManagement::Attributes::UserActiveModeTriggerInstruction::Id); SendCommissioningReadRequest(proxy, timeout, readPaths, numberOfAttributes); } diff --git a/src/controller/CommissioningDelegate.h b/src/controller/CommissioningDelegate.h index 67fe2e69878dfb..175c246e908f9d 100644 --- a/src/controller/CommissioningDelegate.h +++ b/src/controller/CommissioningDelegate.h @@ -679,6 +679,26 @@ struct GeneralCommissioningInfo ; }; +// ICDManagementClusterInfo is populated when the controller reads information from +// the ICD Management cluster, and is used to communicate that information. +struct ICDManagementClusterInfo +{ + // Whether the ICD is capable of functioning as a LIT device. If false, the ICD can only be a SIT device. + bool isLIT; + // Whether the ICD supports the check-in protocol. LIT devices have to support it, but SIT devices + // might or might not. + bool checkInProtocolSupport; + + // userActiveModeTriggerHint indicates which user action(s) will trigger the ICD to switch to Active mode. + // For a LIT: The device is required to provide a value for the bitmap. + // For a SIT: The device may not provide a value. In that case, none of the bits will be set. + // + // userActiveModeTriggerInstruction may provide additional information for users for some specific + // userActiveModeTriggerHint values. + BitMask userActiveModeTriggerHint; + CharSpan userActiveModeTriggerInstruction; +}; + struct ReadCommissioningInfo { NetworkClusters network; @@ -691,9 +711,8 @@ struct ReadCommissioningInfo uint8_t maxTimeZoneSize = 1; uint8_t maxDSTSize = 1; NodeId remoteNodeId = kUndefinedNodeId; - bool isLIT = false; - bool checkInProtocolSupport = false; bool supportsConcurrentConnection = true; + ICDManagementClusterInfo icd; }; struct TimeZoneResponseInfo From ab58186f11c00f9df117f5905bfd47750fa9ae2d Mon Sep 17 00:00:00 2001 From: Boris Zbarsky Date: Thu, 21 Dec 2023 21:01:56 -0500 Subject: [PATCH 16/29] Restore Darwin APIs that went missing. (#31163) We were inconsistent about our checks for the "allowed to not have params" case: some places used "command has no fields" as the check, and some used "command has only optional fields". This caused some APIs (for invoking commands with no params) to disappear when commands that used to have no fields got optional fields added to them. The fix: 1. Fixes the checks to consistently be "command has only optional fields" so the no-params APIs continue to exist for the commands that had optional fields added to them. 2. Fixes availability annotations for pre-existing commands with only optional fields so that we will not claim the no-params API is available before it was actually available, by basically listing all such commands in config-data.yaml. 3. Avoids generating deprecated overloads for the thins listed in item 2. 4. Moves the Darwin-only bits from the config-data.yaml in src/app into the Darwin version we are adding, and starts using that config file. --- src/app/common/templates/config-data.yaml | 7 -- .../CHIP/templates/MTRBaseClusters-src.zapt | 8 +- .../CHIP/templates/MTRBaseClusters.zapt | 15 +++- .../CHIP/templates/MTRClusters-src.zapt | 8 +- .../Framework/CHIP/templates/MTRClusters.zapt | 15 +++- .../Framework/CHIP/templates/config-data.yaml | 20 +++++ .../Framework/CHIP/templates/templates.json | 2 +- .../CHIP/zap-generated/MTRBaseClusters.h | 44 ++++++++++ .../CHIP/zap-generated/MTRBaseClusters.mm | 88 +++++++++++++++++++ .../CHIP/zap-generated/MTRClusters.h | 39 ++++++++ .../CHIP/zap-generated/MTRClusters.mm | 88 +++++++++++++++++++ 11 files changed, 318 insertions(+), 16 deletions(-) create mode 100644 src/darwin/Framework/CHIP/templates/config-data.yaml diff --git a/src/app/common/templates/config-data.yaml b/src/app/common/templates/config-data.yaml index 577e04ab04a856..5586614c6d7186 100644 --- a/src/app/common/templates/config-data.yaml +++ b/src/app/common/templates/config-data.yaml @@ -1,10 +1,3 @@ -DarwinForceWritable: - # Work-around for not allowing changes from writable to read-only - # happened in https://github.com/project-chip/connectedhomeip/pull/30134 - - ApplicationLauncher::CurrentApp - - ContentLauncher::SupportedStreamingProtocols - - FanControl::FanModeSequence - EnumsNotUsedAsTypeInXML: # List of enums that are not used as a type in XML. By adding an enum # to this list you prevent incorrectly assuming from code that you are diff --git a/src/darwin/Framework/CHIP/templates/MTRBaseClusters-src.zapt b/src/darwin/Framework/CHIP/templates/MTRBaseClusters-src.zapt index fb303d5589d2be..42b20c0c6cb0ef 100644 --- a/src/darwin/Framework/CHIP/templates/MTRBaseClusters-src.zapt +++ b/src/darwin/Framework/CHIP/templates/MTRBaseClusters-src.zapt @@ -63,7 +63,7 @@ MTR{{compatClusterNameRemapping parent.name}}Cluster{{compatCommandNameRemapping MTR{{cluster}}Cluster{{command}}Params {{/unless}} {{/inline}} -{{#unless hasArguments}} +{{#unless commandHasRequiredField}} - (void){{asLowerCamelCase name}}WithCompletion:({{>command_completion_type command=.}})completion { [self {{asLowerCamelCase name}}WithParams:nil completion:completion]; @@ -246,7 +246,10 @@ reportHandler:(void (^)({{asObjectiveCClass type parent.name}} * _Nullable value {{/if}} ]; } -{{#unless hasArguments}} +{{#unless commandHasRequiredField}} +{{#unless (isInConfigList + (concat (asUpperCamelCase cluster preserveAcronyms=true) "::" (asUpperCamelCase command preserveAcronyms=true)) + "LegacyCommandsWithOnlyOptionalArguments")}} {{! KeySetReadAllIndices grew this params-less API later _after_ it had already been shipped, so it needs to be special-cased here }} {{#unless (and (isStrEqual cluster "GroupKeyManagement") (isStrEqual command "KeySetReadAllIndices"))}} @@ -256,6 +259,7 @@ reportHandler:(void (^)({{asObjectiveCClass type parent.name}} * _Nullable value } {{/unless}} {{/unless}} +{{/unless}} {{/if}} {{/inline}} {{> commandImpl cluster=(compatClusterNameRemapping parent.name) diff --git a/src/darwin/Framework/CHIP/templates/MTRBaseClusters.zapt b/src/darwin/Framework/CHIP/templates/MTRBaseClusters.zapt index edd4f05e4a27b4..affc28304b89c8 100644 --- a/src/darwin/Framework/CHIP/templates/MTRBaseClusters.zapt +++ b/src/darwin/Framework/CHIP/templates/MTRBaseClusters.zapt @@ -30,15 +30,21 @@ NS_ASSUME_NONNULL_BEGIN * {{description}} */ - (void){{asLowerCamelCase name}}WithParams:(MTR{{cluster}}Cluster{{command}}Params * {{#unless commandHasRequiredField }}_Nullable{{/unless}})params completion:({{>command_completion_type command=.}})completion {{availability cluster command=command minimalRelease="First major API revamp"}}; -{{#unless hasArguments}} +{{#unless commandHasRequiredField}} - (void){{asLowerCamelCase name}}WithCompletion:({{>command_completion_type command=.}})completion {{! KeySetReadAllIndices grew this params-less API later _after_ it had already been shipped, so it needs to be special-cased here }} {{#if (and (isStrEqual command "KeySetReadAllIndices") (isStrEqual cluster "GroupKeyManagement"))}} {{availability cluster command=command minimalRelease="Fall 2023"}}; {{else}} +{{#if (isInConfigList + (concat (asUpperCamelCase cluster preserveAcronyms=true) "::" (asUpperCamelCase command preserveAcronyms=true)) + "LegacyCommandsWithOnlyOptionalArguments")}} +{{availability cluster command=command minimalRelease="Future"}}; {{! TODO: Use the right thing here when we know what it's called }} +{{else}} {{availability cluster command=command minimalRelease="First major API revamp"}}; {{/if}} +{{/if}} {{/unless}} {{/if}} {{/inline}} @@ -217,7 +223,11 @@ typedef NS_OPTIONS({{asUnderlyingZclType name}}, {{objCEnumName clusterName bitm (isSupported cluster command=command))}} - (void){{asLowerCamelCase command}}WithParams:(MTR{{cluster}}Cluster{{command}}Params * {{#unless commandHasRequiredField }}_Nullable{{/unless}})params completionHandler:({{>command_completion_type command=. compatRemapNames=true}})completionHandler {{availability cluster command=command deprecatedRelease="First major API revamp" deprecationMessage=(concat "Please use " (asLowerCamelCase name) "WithParams:completion:")}}; -{{#unless hasArguments}} +{{#unless commandHasRequiredField}} +{{! No need for these backwards-compat APIs for commands that never shipped them. }} +{{#unless (isInConfigList + (concat (asUpperCamelCase cluster preserveAcronyms=true) "::" (asUpperCamelCase command preserveAcronyms=true)) + "LegacyCommandsWithOnlyOptionalArguments")}} {{! KeySetReadAllIndices grew this params-less API later _after_ it had already been shipped, so it needs to be special-cased here }} {{#unless (and (isStrEqual cluster "GroupKeyManagement") (isStrEqual command "KeySetReadAllIndices"))}} @@ -225,6 +235,7 @@ typedef NS_OPTIONS({{asUnderlyingZclType name}}, {{objCEnumName clusterName bitm {{availability cluster command=command deprecatedRelease="First major API revamp" deprecationMessage=(concat "Please use " (asLowerCamelCase name) "WithCompletion:")}}; {{/unless}} {{/unless}} +{{/unless}} {{/if}} {{/inline}} {{> commandDecl cluster=(compatClusterNameRemapping parent.name) diff --git a/src/darwin/Framework/CHIP/templates/MTRClusters-src.zapt b/src/darwin/Framework/CHIP/templates/MTRClusters-src.zapt index 9cefaa1a510b13..41027b72fa8cc2 100644 --- a/src/darwin/Framework/CHIP/templates/MTRClusters-src.zapt +++ b/src/darwin/Framework/CHIP/templates/MTRClusters-src.zapt @@ -44,7 +44,7 @@ MTR{{compatClusterNameRemapping parent.name}}Cluster{{compatCommandNameRemapping MTR{{cluster}}Cluster{{command}}Params {{/unless}} {{/inline}} -{{#unless hasArguments}} +{{#unless commandHasRequiredField}} - (void){{asLowerCamelCase name}}WithExpectedValues:(NSArray *> *)expectedValues expectedValueInterval:(NSNumber *)expectedValueIntervalMs completion:({{>command_completion_type command=.}})completion { [self {{asLowerCamelCase name}}WithParams:nil expectedValues:expectedValues expectedValueInterval:expectedValueIntervalMs completion:completion]; @@ -171,7 +171,10 @@ MTR{{cluster}}Cluster{{command}}Params {{/if}} ]; } -{{#unless hasArguments}} +{{#unless commandHasRequiredField}} +{{#unless (isInConfigList + (concat (asUpperCamelCase cluster preserveAcronyms=true) "::" (asUpperCamelCase command preserveAcronyms=true)) + "LegacyCommandsWithOnlyOptionalArguments")}} {{! KeySetReadAllIndices grew this params-less API later _after_ it had already been shipped, so it needs to be special-cased here }} {{#unless (and (isStrEqual cluster "GroupKeyManagement") (isStrEqual command "KeySetReadAllIndices"))}} @@ -181,6 +184,7 @@ MTR{{cluster}}Cluster{{command}}Params } {{/unless}} {{/unless}} +{{/unless}} {{/if}} {{/inline}} {{> commandImpl cluster=(compatClusterNameRemapping parent.name) diff --git a/src/darwin/Framework/CHIP/templates/MTRClusters.zapt b/src/darwin/Framework/CHIP/templates/MTRClusters.zapt index c089804986d154..85ef7ad74a6ed4 100644 --- a/src/darwin/Framework/CHIP/templates/MTRClusters.zapt +++ b/src/darwin/Framework/CHIP/templates/MTRClusters.zapt @@ -25,15 +25,21 @@ NS_ASSUME_NONNULL_BEGIN {{#*inline "commandDecl"}} {{#if (isSupported cluster command=command)}} - (void){{asLowerCamelCase name}}WithParams:(MTR{{cluster}}Cluster{{command}}Params * {{#unless commandHasRequiredField}}_Nullable{{/unless}})params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:({{>command_completion_type command=.}})completion {{availability cluster command=command minimalRelease="First major API revamp"}}; -{{#unless hasArguments}} +{{#unless commandHasRequiredField}} - (void){{asLowerCamelCase name}}WithExpectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:({{>command_completion_type command=.}})completion {{! KeySetReadAllIndices grew this params-less API later _after_ it had already been shipped, so it needs to be special-cased here }} {{#if (and (isStrEqual command "KeySetReadAllIndices") (isStrEqual cluster "GroupKeyManagement"))}} {{availability cluster command=command minimalRelease="Fall 2023"}}; {{else}} +{{#if (isInConfigList + (concat (asUpperCamelCase cluster preserveAcronyms=true) "::" (asUpperCamelCase command preserveAcronyms=true)) + "LegacyCommandsWithOnlyOptionalArguments")}} +{{availability cluster command=command minimalRelease="Future"}}; {{! TODO: Use the right thing here when we know what it's called }} +{{else}} {{availability cluster command=command minimalRelease="First major API revamp"}}; {{/if}} +{{/if}} {{/unless}} {{/if}} {{/inline}} @@ -113,13 +119,18 @@ NS_ASSUME_NONNULL_BEGIN {{#if (and (wasIntroducedBeforeRelease "First major API revamp" cluster command=command) (isSupported cluster command=command))}} - (void){{asLowerCamelCase command}}WithParams:(MTR{{cluster}}Cluster{{command}}Params * {{#unless commandHasRequiredField}}_Nullable{{/unless}})params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completionHandler:({{>command_completion_type command=. compatRemapNames=true}})completionHandler {{availability cluster command=command deprecatedRelease="First major API revamp" deprecationMessage=(concat "Please use " (asLowerCamelCase name) "WithParams:expectedValues:expectedValueInterval:completion:")}}; -{{#unless hasArguments}} +{{#unless commandHasRequiredField}} +{{! No need for these backwards-compat APIs for commands that never shipped them. }} +{{#unless (isInConfigList + (concat (asUpperCamelCase cluster preserveAcronyms=true) "::" (asUpperCamelCase command preserveAcronyms=true)) + "LegacyCommandsWithOnlyOptionalArguments")}} {{! KeySetReadAllIndices grew this params-less API later _after_ it had already been shipped, so it needs to be special-cased here }} {{#unless (and (isStrEqual cluster "GroupKeyManagement") (isStrEqual command "KeySetReadAllIndices"))}} - (void){{asLowerCamelCase command}}WithExpectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completionHandler:({{>command_completion_type command=. compatRemapNames=true}})completionHandler {{availability cluster command=command deprecatedRelease="First major API revamp" deprecationMessage=(concat "Please use " (asLowerCamelCase name) "WithExpectedValues:expectedValueInterval:completion:")}}; {{/unless}} {{/unless}} +{{/unless}} {{/if}} {{/inline}} {{> commandDecl cluster=(compatClusterNameRemapping parent.name) diff --git a/src/darwin/Framework/CHIP/templates/config-data.yaml b/src/darwin/Framework/CHIP/templates/config-data.yaml new file mode 100644 index 00000000000000..575ce0ffc4b91d --- /dev/null +++ b/src/darwin/Framework/CHIP/templates/config-data.yaml @@ -0,0 +1,20 @@ +DarwinForceWritable: + # Work-around for not allowing changes from writable to read-only + # happened in https://github.com/project-chip/connectedhomeip/pull/30134 + - ApplicationLauncher::CurrentApp + - ContentLauncher::SupportedStreamingProtocols + - FanControl::FanModeSequence + +# A list of commands that used to have only optional arguments before we started +# generating the no-params-needed variants of methods for that case. These +# declarations need to have availability based on when we started generating +# those variants, not the command's own availability. +LegacyCommandsWithOnlyOptionalArguments: + - NetworkCommissioning::ScanNetworks + - DoorLock::LockDoor + - DoorLock::UnlockDoor + - ApplicationLauncher::LaunchApp + - ApplicationLauncher::StopApp + - ApplicationLauncher::HideApp + - UnitTesting::TestNullableOptionalRequest + - UnitTesting::TestSimpleOptionalArgumentRequest diff --git a/src/darwin/Framework/CHIP/templates/templates.json b/src/darwin/Framework/CHIP/templates/templates.json index 83b001285cfcf2..59a06b83c2fd99 100644 --- a/src/darwin/Framework/CHIP/templates/templates.json +++ b/src/darwin/Framework/CHIP/templates/templates.json @@ -12,7 +12,7 @@ ], "resources": { "availability-data": "availability.yaml", - "config-data": "../../../../app/common/templates/config-data.yaml" + "config-data": "config-data.yaml" }, "override": "../../../../../src/app/zap-templates/common/override.js", "partials": [ diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.h b/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.h index 9526a2cd3230c4..046e4442fa8725 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.h +++ b/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.h @@ -2481,6 +2481,8 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) * Detemine the set of networks the device sees as available. */ - (void)scanNetworksWithParams:(MTRNetworkCommissioningClusterScanNetworksParams * _Nullable)params completion:(void (^)(MTRNetworkCommissioningClusterScanNetworksResponseParams * _Nullable data, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); +- (void)scanNetworksWithCompletion:(void (^)(MTRNetworkCommissioningClusterScanNetworksResponseParams * _Nullable data, NSError * _Nullable error))completion + MTR_NEWLY_AVAILABLE; /** * Command AddOrUpdateWiFiNetwork * @@ -5750,6 +5752,8 @@ MTR_PROVISIONALLY_AVAILABLE * Set Temperature */ - (void)setTemperatureWithParams:(MTRTemperatureControlClusterSetTemperatureParams * _Nullable)params completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; +- (void)setTemperatureWithCompletion:(MTRStatusCompletion)completion + MTR_PROVISIONALLY_AVAILABLE; - (void)readAttributeTemperatureSetpointWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - (void)subscribeAttributeTemperatureSetpointWithParams:(MTRSubscribeParams *)params @@ -6418,6 +6422,8 @@ MTR_PROVISIONALLY_AVAILABLE * Set Cooking Parameters */ - (void)setCookingParametersWithParams:(MTRMicrowaveOvenControlClusterSetCookingParametersParams * _Nullable)params completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; +- (void)setCookingParametersWithCompletion:(MTRStatusCompletion)completion + MTR_PROVISIONALLY_AVAILABLE; /** * Command AddMoreTime * @@ -7122,6 +7128,8 @@ MTR_PROVISIONALLY_AVAILABLE * This command is used to set the valve to its open position. */ - (void)openWithParams:(MTRValveConfigurationAndControlClusterOpenParams * _Nullable)params completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; +- (void)openWithCompletion:(MTRStatusCompletion)completion + MTR_PROVISIONALLY_AVAILABLE; /** * Command Close * @@ -8010,12 +8018,16 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) * This command causes the lock device to lock the door. */ - (void)lockDoorWithParams:(MTRDoorLockClusterLockDoorParams * _Nullable)params completion:(MTRStatusCompletion)completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); +- (void)lockDoorWithCompletion:(MTRStatusCompletion)completion + MTR_NEWLY_AVAILABLE; /** * Command UnlockDoor * * This command causes the lock device to unlock the door. */ - (void)unlockDoorWithParams:(MTRDoorLockClusterUnlockDoorParams * _Nullable)params completion:(MTRStatusCompletion)completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); +- (void)unlockDoorWithCompletion:(MTRStatusCompletion)completion + MTR_NEWLY_AVAILABLE; /** * Command UnlockWithTimeout * @@ -8118,6 +8130,8 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) * This command causes the lock device to unlock the door without pulling the latch. */ - (void)unboltDoorWithParams:(MTRDoorLockClusterUnboltDoorParams * _Nullable)params completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; +- (void)unboltDoorWithCompletion:(MTRStatusCompletion)completion + MTR_PROVISIONALLY_AVAILABLE; - (void)readAttributeLockStateWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)subscribeAttributeLockStateWithParams:(MTRSubscribeParams *)params @@ -12364,6 +12378,8 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) * This command retrieves the program guide. It accepts several filter parameters to return specific schedule and program information from a content app. The command shall receive in response a ProgramGuideResponse. */ - (void)getProgramGuideWithParams:(MTRChannelClusterGetProgramGuideParams * _Nullable)params completion:(void (^)(MTRChannelClusterProgramGuideResponseParams * _Nullable data, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)getProgramGuideWithCompletion:(void (^)(MTRChannelClusterProgramGuideResponseParams * _Nullable data, NSError * _Nullable error))completion + MTR_PROVISIONALLY_AVAILABLE; /** * Command RecordProgram * @@ -12590,12 +12606,16 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) * Upon receipt, this SHALL Rewind through media. Different Rewind speeds can be used on the TV based upon the number of sequential calls to this function. This is to avoid needing to define every speed now (multiple fast, slow motion, etc). */ - (void)rewindWithParams:(MTRMediaPlaybackClusterRewindParams * _Nullable)params completion:(void (^)(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); +- (void)rewindWithCompletion:(void (^)(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data, NSError * _Nullable error))completion + MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); /** * Command FastForward * * Upon receipt, this SHALL Advance through media. Different FF speeds can be used on the TV based upon the number of sequential calls to this function. This is to avoid needing to define every speed now (multiple fast, slow motion, etc). */ - (void)fastForwardWithParams:(MTRMediaPlaybackClusterFastForwardParams * _Nullable)params completion:(void (^)(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); +- (void)fastForwardWithCompletion:(void (^)(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data, NSError * _Nullable error))completion + MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); /** * Command SkipForward * @@ -13182,18 +13202,24 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) * Upon receipt, this SHALL launch the specified app with optional data. The TV Device SHALL launch and bring to foreground the identified application in the command if the application is not already launched and in foreground. The TV Device SHALL update state attribute on the Application Basic cluster of the Endpoint corresponding to the launched application. This command returns a Launch Response. */ - (void)launchAppWithParams:(MTRApplicationLauncherClusterLaunchAppParams * _Nullable)params completion:(void (^)(MTRApplicationLauncherClusterLauncherResponseParams * _Nullable data, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); +- (void)launchAppWithCompletion:(void (^)(MTRApplicationLauncherClusterLauncherResponseParams * _Nullable data, NSError * _Nullable error))completion + MTR_NEWLY_AVAILABLE; /** * Command StopApp * * Upon receipt on a Video Player endpoint this SHALL stop the specified application if it is running. */ - (void)stopAppWithParams:(MTRApplicationLauncherClusterStopAppParams * _Nullable)params completion:(void (^)(MTRApplicationLauncherClusterLauncherResponseParams * _Nullable data, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); +- (void)stopAppWithCompletion:(void (^)(MTRApplicationLauncherClusterLauncherResponseParams * _Nullable data, NSError * _Nullable error))completion + MTR_NEWLY_AVAILABLE; /** * Command HideApp * * Upon receipt on a Video Player endpoint this SHALL hide the specified application if it is running and visible. */ - (void)hideAppWithParams:(MTRApplicationLauncherClusterHideAppParams * _Nullable)params completion:(void (^)(MTRApplicationLauncherClusterLauncherResponseParams * _Nullable data, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); +- (void)hideAppWithCompletion:(void (^)(MTRApplicationLauncherClusterLauncherResponseParams * _Nullable data, NSError * _Nullable error))completion + MTR_NEWLY_AVAILABLE; - (void)readAttributeCatalogListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)subscribeAttributeCatalogListWithParams:(MTRSubscribeParams *)params @@ -13397,6 +13423,8 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) * The purpose of this command is to instruct the Content App to clear the current user account. This command SHOULD be used by clients of a Content App to indicate the end of a user session. */ - (void)logoutWithParams:(MTRAccountLoginClusterLogoutParams * _Nullable)params completion:(MTRStatusCompletion)completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); +- (void)logoutWithCompletion:(MTRStatusCompletion)completion + MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)readAttributeGeneratedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)subscribeAttributeGeneratedCommandListWithParams:(MTRSubscribeParams *)params @@ -13495,6 +13523,8 @@ MTR_PROVISIONALLY_AVAILABLE * The purpose of this command is to add the extra screen time for the user. If a client with Operate privilege invokes this command, the media device SHALL check whether the PINCode passed in the command matches the current PINCode value. If these match, then the RemainingScreenTime attribute SHALL be increased by the specified BonusTime value. If the PINs do not match, then a response with InvalidPINCode error status SHALL be returned, and no changes SHALL be made to RemainingScreenTime. If a client with Manage privilege or greater invokes this command, the media device SHALL ignore the PINCode field and directly increase the RemainingScreenTime attribute by the specified BonusTime value. A server that does not support the PM feature SHALL respond with InvalidPINCode to clients that only have Operate privilege unless: It has been provided with the PIN value to expect via an out of band mechanism, and The client has provided a PINCode that matches the expected PIN value. */ - (void)addBonusTimeWithParams:(MTRContentControlClusterAddBonusTimeParams * _Nullable)params completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; +- (void)addBonusTimeWithCompletion:(MTRStatusCompletion)completion + MTR_PROVISIONALLY_AVAILABLE; /** * Command SetScreenDailyTime * @@ -14688,6 +14718,8 @@ MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) if that' false the argument it received. */ - (void)testNullableOptionalRequestWithParams:(MTRUnitTestingClusterTestNullableOptionalRequestParams * _Nullable)params completion:(void (^)(MTRUnitTestingClusterTestNullableOptionalResponseParams * _Nullable data, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); +- (void)testNullableOptionalRequestWithCompletion:(void (^)(MTRUnitTestingClusterTestNullableOptionalResponseParams * _Nullable data, NSError * _Nullable error))completion + MTR_NEWLY_AVAILABLE; /** * Command TestComplexNullableOptionalRequest * @@ -14718,6 +14750,8 @@ MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) * Command that takes an optional argument which is bool. It responds with a success value if the optional is set to any value. */ - (void)testSimpleOptionalArgumentRequestWithParams:(MTRUnitTestingClusterTestSimpleOptionalArgumentRequestParams * _Nullable)params completion:(MTRStatusCompletion)completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); +- (void)testSimpleOptionalArgumentRequestWithCompletion:(MTRStatusCompletion)completion + MTR_NEWLY_AVAILABLE; /** * Command TestEmitTestEventRequest * @@ -25949,8 +25983,12 @@ typedef NS_OPTIONS(uint8_t, MTRTestClusterSimpleBitmap) { MTR_DEPRECATED("Please use nextWithCompletion:", ios(16.1, 16.4), macos(13.0, 13.3), watchos(9.1, 9.4), tvos(16.1, 16.4)); - (void)rewindWithParams:(MTRMediaPlaybackClusterRewindParams * _Nullable)params completionHandler:(void (^)(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data, NSError * _Nullable error))completionHandler MTR_DEPRECATED("Please use rewindWithParams:completion:", ios(16.1, 16.4), macos(13.0, 13.3), watchos(9.1, 9.4), tvos(16.1, 16.4)); +- (void)rewindWithCompletionHandler:(void (^)(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data, NSError * _Nullable error))completionHandler + MTR_DEPRECATED("Please use rewindWithCompletion:", ios(16.1, 16.4), macos(13.0, 13.3), watchos(9.1, 9.4), tvos(16.1, 16.4)); - (void)fastForwardWithParams:(MTRMediaPlaybackClusterFastForwardParams * _Nullable)params completionHandler:(void (^)(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data, NSError * _Nullable error))completionHandler MTR_DEPRECATED("Please use fastForwardWithParams:completion:", ios(16.1, 16.4), macos(13.0, 13.3), watchos(9.1, 9.4), tvos(16.1, 16.4)); +- (void)fastForwardWithCompletionHandler:(void (^)(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data, NSError * _Nullable error))completionHandler + MTR_DEPRECATED("Please use fastForwardWithCompletion:", ios(16.1, 16.4), macos(13.0, 13.3), watchos(9.1, 9.4), tvos(16.1, 16.4)); - (void)skipForwardWithParams:(MTRMediaPlaybackClusterSkipForwardParams *)params completionHandler:(void (^)(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data, NSError * _Nullable error))completionHandler MTR_DEPRECATED("Please use skipForwardWithParams:completion:", ios(16.1, 16.4), macos(13.0, 13.3), watchos(9.1, 9.4), tvos(16.1, 16.4)); - (void)skipBackwardWithParams:(MTRMediaPlaybackClusterSkipBackwardParams *)params completionHandler:(void (^)(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data, NSError * _Nullable error))completionHandler @@ -26511,6 +26549,8 @@ typedef NS_OPTIONS(uint8_t, MTRTestClusterSimpleBitmap) { MTR_DEPRECATED("Please use loginWithParams:completion:", ios(16.1, 16.4), macos(13.0, 13.3), watchos(9.1, 9.4), tvos(16.1, 16.4)); - (void)logoutWithParams:(MTRAccountLoginClusterLogoutParams * _Nullable)params completionHandler:(MTRStatusCompletion)completionHandler MTR_DEPRECATED("Please use logoutWithParams:completion:", ios(16.1, 16.4), macos(13.0, 13.3), watchos(9.1, 9.4), tvos(16.1, 16.4)); +- (void)logoutWithCompletionHandler:(MTRStatusCompletion)completionHandler + MTR_DEPRECATED("Please use logoutWithCompletion:", ios(16.1, 16.4), macos(13.0, 13.3), watchos(9.1, 9.4), tvos(16.1, 16.4)); - (void)readAttributeGeneratedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler MTR_DEPRECATED("Please use readAttributeGeneratedCommandListWithCompletion:", ios(16.1, 16.4), macos(13.0, 13.3), watchos(9.1, 9.4), tvos(16.1, 16.4)); - (void)subscribeAttributeGeneratedCommandListWithMinInterval:(NSNumber * _Nonnull)minInterval maxInterval:(NSNumber * _Nonnull)maxInterval @@ -27557,6 +27597,8 @@ typedef NS_OPTIONS(uint8_t, MTRTestClusterSimpleBitmap) { MTR_DEPRECATED("Please use testEnumsRequestWithParams:completion:", ios(16.1, 16.4), macos(13.0, 13.3), watchos(9.1, 9.4), tvos(16.1, 16.4)); - (void)testNullableOptionalRequestWithParams:(MTRTestClusterClusterTestNullableOptionalRequestParams * _Nullable)params completionHandler:(void (^)(MTRTestClusterClusterTestNullableOptionalResponseParams * _Nullable data, NSError * _Nullable error))completionHandler MTR_DEPRECATED("Please use testNullableOptionalRequestWithParams:completion:", ios(16.1, 16.4), macos(13.0, 13.3), watchos(9.1, 9.4), tvos(16.1, 16.4)); +- (void)testNullableOptionalRequestWithCompletionHandler:(void (^)(MTRTestClusterClusterTestNullableOptionalResponseParams * _Nullable data, NSError * _Nullable error))completionHandler + MTR_DEPRECATED("Please use testNullableOptionalRequestWithCompletion:", ios(16.1, 16.4), macos(13.0, 13.3), watchos(9.1, 9.4), tvos(16.1, 16.4)); - (void)testComplexNullableOptionalRequestWithParams:(MTRTestClusterClusterTestComplexNullableOptionalRequestParams *)params completionHandler:(void (^)(MTRTestClusterClusterTestComplexNullableOptionalResponseParams * _Nullable data, NSError * _Nullable error))completionHandler MTR_DEPRECATED("Please use testComplexNullableOptionalRequestWithParams:completion:", ios(16.1, 16.4), macos(13.0, 13.3), watchos(9.1, 9.4), tvos(16.1, 16.4)); - (void)simpleStructEchoRequestWithParams:(MTRTestClusterClusterSimpleStructEchoRequestParams *)params completionHandler:(void (^)(MTRTestClusterClusterSimpleStructResponseParams * _Nullable data, NSError * _Nullable error))completionHandler @@ -27567,6 +27609,8 @@ typedef NS_OPTIONS(uint8_t, MTRTestClusterSimpleBitmap) { MTR_DEPRECATED("Please use timedInvokeRequestWithCompletion:", ios(16.1, 16.4), macos(13.0, 13.3), watchos(9.1, 9.4), tvos(16.1, 16.4)); - (void)testSimpleOptionalArgumentRequestWithParams:(MTRTestClusterClusterTestSimpleOptionalArgumentRequestParams * _Nullable)params completionHandler:(MTRStatusCompletion)completionHandler MTR_DEPRECATED("Please use testSimpleOptionalArgumentRequestWithParams:completion:", ios(16.1, 16.4), macos(13.0, 13.3), watchos(9.1, 9.4), tvos(16.1, 16.4)); +- (void)testSimpleOptionalArgumentRequestWithCompletionHandler:(MTRStatusCompletion)completionHandler + MTR_DEPRECATED("Please use testSimpleOptionalArgumentRequestWithCompletion:", ios(16.1, 16.4), macos(13.0, 13.3), watchos(9.1, 9.4), tvos(16.1, 16.4)); - (void)testEmitTestEventRequestWithParams:(MTRTestClusterClusterTestEmitTestEventRequestParams *)params completionHandler:(void (^)(MTRTestClusterClusterTestEmitTestEventResponseParams * _Nullable data, NSError * _Nullable error))completionHandler MTR_DEPRECATED("Please use testEmitTestEventRequestWithParams:completion:", ios(16.1, 16.4), macos(13.0, 13.3), watchos(9.1, 9.4), tvos(16.1, 16.4)); - (void)testEmitTestFabricScopedEventRequestWithParams:(MTRTestClusterClusterTestEmitTestFabricScopedEventRequestParams *)params completionHandler:(void (^)(MTRTestClusterClusterTestEmitTestFabricScopedEventResponseParams * _Nullable data, NSError * _Nullable error))completionHandler diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.mm b/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.mm index ff63771e70e0f4..19b00a2c799aaa 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.mm @@ -20065,6 +20065,10 @@ - (nullable instancetype)initWithDevice:(MTRBaseDevice *)device @implementation MTRBaseClusterNetworkCommissioning +- (void)scanNetworksWithCompletion:(void (^)(MTRNetworkCommissioningClusterScanNetworksResponseParams * _Nullable data, NSError * _Nullable error))completion +{ + [self scanNetworksWithParams:nil completion:completion]; +} - (void)scanNetworksWithParams:(MTRNetworkCommissioningClusterScanNetworksParams * _Nullable)params completion:(void (^)(MTRNetworkCommissioningClusterScanNetworksResponseParams * _Nullable data, NSError * _Nullable error))completion { if (params == nil) { @@ -43591,6 +43595,10 @@ + (void)readAttributeClusterRevisionWithClusterStateCache:(MTRClusterStateCacheC @implementation MTRBaseClusterTemperatureControl +- (void)setTemperatureWithCompletion:(MTRStatusCompletion)completion +{ + [self setTemperatureWithParams:nil completion:completion]; +} - (void)setTemperatureWithParams:(MTRTemperatureControlClusterSetTemperatureParams * _Nullable)params completion:(MTRStatusCompletion)completion { if (params == nil) { @@ -46541,6 +46549,10 @@ + (void)readAttributeClusterRevisionWithClusterStateCache:(MTRClusterStateCacheC @implementation MTRBaseClusterMicrowaveOvenControl +- (void)setCookingParametersWithCompletion:(MTRStatusCompletion)completion +{ + [self setCookingParametersWithParams:nil completion:completion]; +} - (void)setCookingParametersWithParams:(MTRMicrowaveOvenControlClusterSetCookingParametersParams * _Nullable)params completion:(MTRStatusCompletion)completion { if (params == nil) { @@ -49669,6 +49681,10 @@ + (void)readAttributeClusterRevisionWithClusterStateCache:(MTRClusterStateCacheC @implementation MTRBaseClusterValveConfigurationAndControl +- (void)openWithCompletion:(MTRStatusCompletion)completion +{ + [self openWithParams:nil completion:completion]; +} - (void)openWithParams:(MTRValveConfigurationAndControlClusterOpenParams * _Nullable)params completion:(MTRStatusCompletion)completion { if (params == nil) { @@ -53968,6 +53984,10 @@ + (void)readAttributeClusterRevisionWithClusterStateCache:(MTRClusterStateCacheC @implementation MTRBaseClusterDoorLock +- (void)lockDoorWithCompletion:(MTRStatusCompletion)completion +{ + [self lockDoorWithParams:nil completion:completion]; +} - (void)lockDoorWithParams:(MTRDoorLockClusterLockDoorParams * _Nullable)params completion:(MTRStatusCompletion)completion { if (params == nil) { @@ -53995,6 +54015,10 @@ - (void)lockDoorWithParams:(MTRDoorLockClusterLockDoorParams * _Nullable)params queue:self.callbackQueue completion:responseHandler]; } +- (void)unlockDoorWithCompletion:(MTRStatusCompletion)completion +{ + [self unlockDoorWithParams:nil completion:completion]; +} - (void)unlockDoorWithParams:(MTRDoorLockClusterUnlockDoorParams * _Nullable)params completion:(MTRStatusCompletion)completion { if (params == nil) { @@ -54421,6 +54445,10 @@ - (void)clearCredentialWithParams:(MTRDoorLockClusterClearCredentialParams *)par queue:self.callbackQueue completion:responseHandler]; } +- (void)unboltDoorWithCompletion:(MTRStatusCompletion)completion +{ + [self unboltDoorWithParams:nil completion:completion]; +} - (void)unboltDoorWithParams:(MTRDoorLockClusterUnboltDoorParams * _Nullable)params completion:(MTRStatusCompletion)completion { if (params == nil) { @@ -90354,6 +90382,10 @@ - (void)skipChannelWithParams:(MTRChannelClusterSkipChannelParams *)params compl queue:self.callbackQueue completion:responseHandler]; } +- (void)getProgramGuideWithCompletion:(void (^)(MTRChannelClusterProgramGuideResponseParams * _Nullable data, NSError * _Nullable error))completion +{ + [self getProgramGuideWithParams:nil completion:completion]; +} - (void)getProgramGuideWithParams:(MTRChannelClusterGetProgramGuideParams * _Nullable)params completion:(void (^)(MTRChannelClusterProgramGuideResponseParams * _Nullable data, NSError * _Nullable error))completion { if (params == nil) { @@ -91815,6 +91847,10 @@ - (void)nextWithParams:(MTRMediaPlaybackClusterNextParams * _Nullable)params com queue:self.callbackQueue completion:responseHandler]; } +- (void)rewindWithCompletion:(void (^)(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data, NSError * _Nullable error))completion +{ + [self rewindWithParams:nil completion:completion]; +} - (void)rewindWithParams:(MTRMediaPlaybackClusterRewindParams * _Nullable)params completion:(void (^)(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data, NSError * _Nullable error))completion { if (params == nil) { @@ -91839,6 +91875,10 @@ - (void)rewindWithParams:(MTRMediaPlaybackClusterRewindParams * _Nullable)params queue:self.callbackQueue completion:responseHandler]; } +- (void)fastForwardWithCompletion:(void (^)(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data, NSError * _Nullable error))completion +{ + [self fastForwardWithParams:nil completion:completion]; +} - (void)fastForwardWithParams:(MTRMediaPlaybackClusterFastForwardParams * _Nullable)params completion:(void (^)(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data, NSError * _Nullable error))completion { if (params == nil) { @@ -92708,6 +92748,10 @@ - (void)rewindWithParams:(MTRMediaPlaybackClusterRewindParams * _Nullable)params completionHandler(static_cast(data), error); }]; } +- (void)rewindWithCompletionHandler:(void (^)(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data, NSError * _Nullable error))completionHandler +{ + [self rewindWithParams:nil completionHandler:completionHandler]; +} - (void)fastForwardWithParams:(MTRMediaPlaybackClusterFastForwardParams * _Nullable)params completionHandler:(void (^)(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data, NSError * _Nullable error))completionHandler { [self fastForwardWithParams:params completion: @@ -92716,6 +92760,10 @@ - (void)fastForwardWithParams:(MTRMediaPlaybackClusterFastForwardParams * _Nulla completionHandler(static_cast(data), error); }]; } +- (void)fastForwardWithCompletionHandler:(void (^)(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data, NSError * _Nullable error))completionHandler +{ + [self fastForwardWithParams:nil completionHandler:completionHandler]; +} - (void)skipForwardWithParams:(MTRMediaPlaybackClusterSkipForwardParams *)params completionHandler:(void (^)(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data, NSError * _Nullable error))completionHandler { [self skipForwardWithParams:params completion: @@ -95997,6 +96045,10 @@ - (nullable instancetype)initWithDevice:(MTRBaseDevice *)device @implementation MTRBaseClusterApplicationLauncher +- (void)launchAppWithCompletion:(void (^)(MTRApplicationLauncherClusterLauncherResponseParams * _Nullable data, NSError * _Nullable error))completion +{ + [self launchAppWithParams:nil completion:completion]; +} - (void)launchAppWithParams:(MTRApplicationLauncherClusterLaunchAppParams * _Nullable)params completion:(void (^)(MTRApplicationLauncherClusterLauncherResponseParams * _Nullable data, NSError * _Nullable error))completion { if (params == nil) { @@ -96021,6 +96073,10 @@ - (void)launchAppWithParams:(MTRApplicationLauncherClusterLaunchAppParams * _Nul queue:self.callbackQueue completion:responseHandler]; } +- (void)stopAppWithCompletion:(void (^)(MTRApplicationLauncherClusterLauncherResponseParams * _Nullable data, NSError * _Nullable error))completion +{ + [self stopAppWithParams:nil completion:completion]; +} - (void)stopAppWithParams:(MTRApplicationLauncherClusterStopAppParams * _Nullable)params completion:(void (^)(MTRApplicationLauncherClusterLauncherResponseParams * _Nullable data, NSError * _Nullable error))completion { if (params == nil) { @@ -96045,6 +96101,10 @@ - (void)stopAppWithParams:(MTRApplicationLauncherClusterStopAppParams * _Nullabl queue:self.callbackQueue completion:responseHandler]; } +- (void)hideAppWithCompletion:(void (^)(MTRApplicationLauncherClusterLauncherResponseParams * _Nullable data, NSError * _Nullable error))completion +{ + [self hideAppWithParams:nil completion:completion]; +} - (void)hideAppWithParams:(MTRApplicationLauncherClusterHideAppParams * _Nullable)params completion:(void (^)(MTRApplicationLauncherClusterLauncherResponseParams * _Nullable data, NSError * _Nullable error))completion { if (params == nil) { @@ -97717,6 +97777,10 @@ - (void)loginWithParams:(MTRAccountLoginClusterLoginParams *)params completion:( queue:self.callbackQueue completion:responseHandler]; } +- (void)logoutWithCompletion:(MTRStatusCompletion)completion +{ + [self logoutWithParams:nil completion:completion]; +} - (void)logoutWithParams:(MTRAccountLoginClusterLogoutParams * _Nullable)params completion:(MTRStatusCompletion)completion { if (params == nil) { @@ -97983,6 +98047,10 @@ - (void)logoutWithParams:(MTRAccountLoginClusterLogoutParams * _Nullable)params [self logoutWithParams:params completion: completionHandler]; } +- (void)logoutWithCompletionHandler:(MTRStatusCompletion)completionHandler +{ + [self logoutWithParams:nil completionHandler:completionHandler]; +} - (void)readAttributeGeneratedCommandListWithCompletionHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completionHandler { @@ -98278,6 +98346,10 @@ - (void)disableWithParams:(MTRContentControlClusterDisableParams * _Nullable)par queue:self.callbackQueue completion:responseHandler]; } +- (void)addBonusTimeWithCompletion:(MTRStatusCompletion)completion +{ + [self addBonusTimeWithParams:nil completion:completion]; +} - (void)addBonusTimeWithParams:(MTRContentControlClusterAddBonusTimeParams * _Nullable)params completion:(MTRStatusCompletion)completion { if (params == nil) { @@ -109410,6 +109482,10 @@ - (void)testEnumsRequestWithParams:(MTRUnitTestingClusterTestEnumsRequestParams queue:self.callbackQueue completion:responseHandler]; } +- (void)testNullableOptionalRequestWithCompletion:(void (^)(MTRUnitTestingClusterTestNullableOptionalResponseParams * _Nullable data, NSError * _Nullable error))completion +{ + [self testNullableOptionalRequestWithParams:nil completion:completion]; +} - (void)testNullableOptionalRequestWithParams:(MTRUnitTestingClusterTestNullableOptionalRequestParams * _Nullable)params completion:(void (^)(MTRUnitTestingClusterTestNullableOptionalResponseParams * _Nullable data, NSError * _Nullable error))completion { if (params == nil) { @@ -109513,6 +109589,10 @@ - (void)timedInvokeRequestWithParams:(MTRUnitTestingClusterTimedInvokeRequestPar queue:self.callbackQueue completion:responseHandler]; } +- (void)testSimpleOptionalArgumentRequestWithCompletion:(MTRStatusCompletion)completion +{ + [self testSimpleOptionalArgumentRequestWithParams:nil completion:completion]; +} - (void)testSimpleOptionalArgumentRequestWithParams:(MTRUnitTestingClusterTestSimpleOptionalArgumentRequestParams * _Nullable)params completion:(MTRStatusCompletion)completion { if (params == nil) { @@ -115711,6 +115791,10 @@ - (void)testNullableOptionalRequestWithParams:(MTRTestClusterClusterTestNullable completionHandler(static_cast(data), error); }]; } +- (void)testNullableOptionalRequestWithCompletionHandler:(void (^)(MTRTestClusterClusterTestNullableOptionalResponseParams * _Nullable data, NSError * _Nullable error))completionHandler +{ + [self testNullableOptionalRequestWithParams:nil completionHandler:completionHandler]; +} - (void)testComplexNullableOptionalRequestWithParams:(MTRTestClusterClusterTestComplexNullableOptionalRequestParams *)params completionHandler:(void (^)(MTRTestClusterClusterTestComplexNullableOptionalResponseParams * _Nullable data, NSError * _Nullable error))completionHandler { [self testComplexNullableOptionalRequestWithParams:params completion: @@ -115741,6 +115825,10 @@ - (void)testSimpleOptionalArgumentRequestWithParams:(MTRTestClusterClusterTestSi [self testSimpleOptionalArgumentRequestWithParams:params completion: completionHandler]; } +- (void)testSimpleOptionalArgumentRequestWithCompletionHandler:(MTRStatusCompletion)completionHandler +{ + [self testSimpleOptionalArgumentRequestWithParams:nil completionHandler:completionHandler]; +} - (void)testEmitTestEventRequestWithParams:(MTRTestClusterClusterTestEmitTestEventRequestParams *)params completionHandler:(void (^)(MTRTestClusterClusterTestEmitTestEventResponseParams * _Nullable data, NSError * _Nullable error))completionHandler { [self testEmitTestEventRequestWithParams:params completion: diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRClusters.h b/src/darwin/Framework/CHIP/zap-generated/MTRClusters.h index 912cb7f36a1bc4..d9b141845086a7 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRClusters.h +++ b/src/darwin/Framework/CHIP/zap-generated/MTRClusters.h @@ -1186,6 +1186,8 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) @interface MTRClusterNetworkCommissioning : MTRGenericCluster - (void)scanNetworksWithParams:(MTRNetworkCommissioningClusterScanNetworksParams * _Nullable)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRNetworkCommissioningClusterScanNetworksResponseParams * _Nullable data, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); +- (void)scanNetworksWithExpectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRNetworkCommissioningClusterScanNetworksResponseParams * _Nullable data, NSError * _Nullable error))completion + MTR_NEWLY_AVAILABLE; - (void)addOrUpdateWiFiNetworkWithParams:(MTRNetworkCommissioningClusterAddOrUpdateWiFiNetworkParams *)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRNetworkCommissioningClusterNetworkConfigResponseParams * _Nullable data, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)addOrUpdateThreadNetworkWithParams:(MTRNetworkCommissioningClusterAddOrUpdateThreadNetworkParams *)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRNetworkCommissioningClusterNetworkConfigResponseParams * _Nullable data, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)removeNetworkWithParams:(MTRNetworkCommissioningClusterRemoveNetworkParams *)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRNetworkCommissioningClusterNetworkConfigResponseParams * _Nullable data, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); @@ -2704,6 +2706,8 @@ MTR_PROVISIONALLY_AVAILABLE @interface MTRClusterTemperatureControl : MTRGenericCluster - (void)setTemperatureWithParams:(MTRTemperatureControlClusterSetTemperatureParams * _Nullable)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; +- (void)setTemperatureWithExpectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(MTRStatusCompletion)completion + MTR_PROVISIONALLY_AVAILABLE; - (NSDictionary * _Nullable)readAttributeTemperatureSetpointWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; @@ -3039,6 +3043,8 @@ MTR_PROVISIONALLY_AVAILABLE @interface MTRClusterMicrowaveOvenControl : MTRGenericCluster - (void)setCookingParametersWithParams:(MTRMicrowaveOvenControlClusterSetCookingParametersParams * _Nullable)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; +- (void)setCookingParametersWithExpectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(MTRStatusCompletion)completion + MTR_PROVISIONALLY_AVAILABLE; - (void)addMoreTimeWithParams:(MTRMicrowaveOvenControlClusterAddMoreTimeParams *)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; - (NSDictionary * _Nullable)readAttributeCookTimeWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; @@ -3375,6 +3381,8 @@ MTR_PROVISIONALLY_AVAILABLE @interface MTRClusterValveConfigurationAndControl : MTRGenericCluster - (void)openWithParams:(MTRValveConfigurationAndControlClusterOpenParams * _Nullable)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; +- (void)openWithExpectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(MTRStatusCompletion)completion + MTR_PROVISIONALLY_AVAILABLE; - (void)closeWithParams:(MTRValveConfigurationAndControlClusterCloseParams * _Nullable)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; - (void)closeWithExpectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; @@ -3768,7 +3776,11 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) @interface MTRClusterDoorLock : MTRGenericCluster - (void)lockDoorWithParams:(MTRDoorLockClusterLockDoorParams * _Nullable)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(MTRStatusCompletion)completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); +- (void)lockDoorWithExpectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(MTRStatusCompletion)completion + MTR_NEWLY_AVAILABLE; - (void)unlockDoorWithParams:(MTRDoorLockClusterUnlockDoorParams * _Nullable)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(MTRStatusCompletion)completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); +- (void)unlockDoorWithExpectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(MTRStatusCompletion)completion + MTR_NEWLY_AVAILABLE; - (void)unlockWithTimeoutWithParams:(MTRDoorLockClusterUnlockWithTimeoutParams *)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(MTRStatusCompletion)completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)setWeekDayScheduleWithParams:(MTRDoorLockClusterSetWeekDayScheduleParams *)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(MTRStatusCompletion)completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)getWeekDayScheduleWithParams:(MTRDoorLockClusterGetWeekDayScheduleParams *)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRDoorLockClusterGetWeekDayScheduleResponseParams * _Nullable data, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); @@ -3786,6 +3798,8 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) - (void)getCredentialStatusWithParams:(MTRDoorLockClusterGetCredentialStatusParams *)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRDoorLockClusterGetCredentialStatusResponseParams * _Nullable data, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)clearCredentialWithParams:(MTRDoorLockClusterClearCredentialParams *)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(MTRStatusCompletion)completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)unboltDoorWithParams:(MTRDoorLockClusterUnboltDoorParams * _Nullable)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; +- (void)unboltDoorWithExpectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(MTRStatusCompletion)completion + MTR_PROVISIONALLY_AVAILABLE; - (NSDictionary * _Nullable)readAttributeLockStateWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); @@ -5713,6 +5727,8 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) - (void)changeChannelByNumberWithParams:(MTRChannelClusterChangeChannelByNumberParams *)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(MTRStatusCompletion)completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)skipChannelWithParams:(MTRChannelClusterSkipChannelParams *)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(MTRStatusCompletion)completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)getProgramGuideWithParams:(MTRChannelClusterGetProgramGuideParams * _Nullable)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRChannelClusterProgramGuideResponseParams * _Nullable data, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)getProgramGuideWithExpectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRChannelClusterProgramGuideResponseParams * _Nullable data, NSError * _Nullable error))completion + MTR_PROVISIONALLY_AVAILABLE; - (void)recordProgramWithParams:(MTRChannelClusterRecordProgramParams *)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; - (void)cancelRecordProgramWithParams:(MTRChannelClusterCancelRecordProgramParams *)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; @@ -5819,7 +5835,11 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) - (void)nextWithExpectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)rewindWithParams:(MTRMediaPlaybackClusterRewindParams * _Nullable)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); +- (void)rewindWithExpectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data, NSError * _Nullable error))completion + MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)fastForwardWithParams:(MTRMediaPlaybackClusterFastForwardParams * _Nullable)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); +- (void)fastForwardWithExpectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data, NSError * _Nullable error))completion + MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)skipForwardWithParams:(MTRMediaPlaybackClusterSkipForwardParams *)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)skipBackwardWithParams:(MTRMediaPlaybackClusterSkipBackwardParams *)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)seekWithParams:(MTRMediaPlaybackClusterSeekParams *)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); @@ -6103,8 +6123,14 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) @interface MTRClusterApplicationLauncher : MTRGenericCluster - (void)launchAppWithParams:(MTRApplicationLauncherClusterLaunchAppParams * _Nullable)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRApplicationLauncherClusterLauncherResponseParams * _Nullable data, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); +- (void)launchAppWithExpectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRApplicationLauncherClusterLauncherResponseParams * _Nullable data, NSError * _Nullable error))completion + MTR_NEWLY_AVAILABLE; - (void)stopAppWithParams:(MTRApplicationLauncherClusterStopAppParams * _Nullable)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRApplicationLauncherClusterLauncherResponseParams * _Nullable data, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); +- (void)stopAppWithExpectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRApplicationLauncherClusterLauncherResponseParams * _Nullable data, NSError * _Nullable error))completion + MTR_NEWLY_AVAILABLE; - (void)hideAppWithParams:(MTRApplicationLauncherClusterHideAppParams * _Nullable)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRApplicationLauncherClusterLauncherResponseParams * _Nullable data, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); +- (void)hideAppWithExpectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRApplicationLauncherClusterLauncherResponseParams * _Nullable data, NSError * _Nullable error))completion + MTR_NEWLY_AVAILABLE; - (NSDictionary * _Nullable)readAttributeCatalogListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); @@ -6203,6 +6229,8 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) - (void)getSetupPINWithParams:(MTRAccountLoginClusterGetSetupPINParams *)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRAccountLoginClusterGetSetupPINResponseParams * _Nullable data, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)loginWithParams:(MTRAccountLoginClusterLoginParams *)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(MTRStatusCompletion)completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)logoutWithParams:(MTRAccountLoginClusterLogoutParams * _Nullable)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(MTRStatusCompletion)completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); +- (void)logoutWithExpectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(MTRStatusCompletion)completion + MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (NSDictionary * _Nullable)readAttributeGeneratedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); @@ -6251,6 +6279,8 @@ MTR_PROVISIONALLY_AVAILABLE - (void)disableWithExpectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; - (void)addBonusTimeWithParams:(MTRContentControlClusterAddBonusTimeParams * _Nullable)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; +- (void)addBonusTimeWithExpectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(MTRStatusCompletion)completion + MTR_PROVISIONALLY_AVAILABLE; - (void)setScreenDailyTimeWithParams:(MTRContentControlClusterSetScreenDailyTimeParams *)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; - (void)blockUnratedContentWithParams:(MTRContentControlClusterBlockUnratedContentParams * _Nullable)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; - (void)blockUnratedContentWithExpectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(MTRStatusCompletion)completion @@ -6688,12 +6718,16 @@ MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) - (void)testListInt8UReverseRequestWithParams:(MTRUnitTestingClusterTestListInt8UReverseRequestParams *)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRUnitTestingClusterTestListInt8UReverseResponseParams * _Nullable data, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)testEnumsRequestWithParams:(MTRUnitTestingClusterTestEnumsRequestParams *)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRUnitTestingClusterTestEnumsResponseParams * _Nullable data, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)testNullableOptionalRequestWithParams:(MTRUnitTestingClusterTestNullableOptionalRequestParams * _Nullable)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRUnitTestingClusterTestNullableOptionalResponseParams * _Nullable data, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); +- (void)testNullableOptionalRequestWithExpectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRUnitTestingClusterTestNullableOptionalResponseParams * _Nullable data, NSError * _Nullable error))completion + MTR_NEWLY_AVAILABLE; - (void)testComplexNullableOptionalRequestWithParams:(MTRUnitTestingClusterTestComplexNullableOptionalRequestParams *)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRUnitTestingClusterTestComplexNullableOptionalResponseParams * _Nullable data, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)simpleStructEchoRequestWithParams:(MTRUnitTestingClusterSimpleStructEchoRequestParams *)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRUnitTestingClusterSimpleStructResponseParams * _Nullable data, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)timedInvokeRequestWithParams:(MTRUnitTestingClusterTimedInvokeRequestParams * _Nullable)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(MTRStatusCompletion)completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)timedInvokeRequestWithExpectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(MTRStatusCompletion)completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)testSimpleOptionalArgumentRequestWithParams:(MTRUnitTestingClusterTestSimpleOptionalArgumentRequestParams * _Nullable)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(MTRStatusCompletion)completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); +- (void)testSimpleOptionalArgumentRequestWithExpectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(MTRStatusCompletion)completion + MTR_NEWLY_AVAILABLE; - (void)testEmitTestEventRequestWithParams:(MTRUnitTestingClusterTestEmitTestEventRequestParams *)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRUnitTestingClusterTestEmitTestEventResponseParams * _Nullable data, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)testEmitTestFabricScopedEventRequestWithParams:(MTRUnitTestingClusterTestEmitTestFabricScopedEventRequestParams *)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRUnitTestingClusterTestEmitTestFabricScopedEventResponseParams * _Nullable data, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); @@ -7750,7 +7784,9 @@ MTR_DEPRECATED("Please use MTRClusterUnitTesting", ios(16.1, 16.4), macos(13.0, - (void)nextWithParams:(MTRMediaPlaybackClusterNextParams * _Nullable)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completionHandler:(void (^)(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data, NSError * _Nullable error))completionHandler MTR_DEPRECATED("Please use nextWithParams:expectedValues:expectedValueInterval:completion:", ios(16.1, 16.4), macos(13.0, 13.3), watchos(9.1, 9.4), tvos(16.1, 16.4)); - (void)nextWithExpectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completionHandler:(void (^)(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data, NSError * _Nullable error))completionHandler MTR_DEPRECATED("Please use nextWithExpectedValues:expectedValueInterval:completion:", ios(16.1, 16.4), macos(13.0, 13.3), watchos(9.1, 9.4), tvos(16.1, 16.4)); - (void)rewindWithParams:(MTRMediaPlaybackClusterRewindParams * _Nullable)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completionHandler:(void (^)(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data, NSError * _Nullable error))completionHandler MTR_DEPRECATED("Please use rewindWithParams:expectedValues:expectedValueInterval:completion:", ios(16.1, 16.4), macos(13.0, 13.3), watchos(9.1, 9.4), tvos(16.1, 16.4)); +- (void)rewindWithExpectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completionHandler:(void (^)(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data, NSError * _Nullable error))completionHandler MTR_DEPRECATED("Please use rewindWithExpectedValues:expectedValueInterval:completion:", ios(16.1, 16.4), macos(13.0, 13.3), watchos(9.1, 9.4), tvos(16.1, 16.4)); - (void)fastForwardWithParams:(MTRMediaPlaybackClusterFastForwardParams * _Nullable)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completionHandler:(void (^)(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data, NSError * _Nullable error))completionHandler MTR_DEPRECATED("Please use fastForwardWithParams:expectedValues:expectedValueInterval:completion:", ios(16.1, 16.4), macos(13.0, 13.3), watchos(9.1, 9.4), tvos(16.1, 16.4)); +- (void)fastForwardWithExpectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completionHandler:(void (^)(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data, NSError * _Nullable error))completionHandler MTR_DEPRECATED("Please use fastForwardWithExpectedValues:expectedValueInterval:completion:", ios(16.1, 16.4), macos(13.0, 13.3), watchos(9.1, 9.4), tvos(16.1, 16.4)); - (void)skipForwardWithParams:(MTRMediaPlaybackClusterSkipForwardParams *)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completionHandler:(void (^)(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data, NSError * _Nullable error))completionHandler MTR_DEPRECATED("Please use skipForwardWithParams:expectedValues:expectedValueInterval:completion:", ios(16.1, 16.4), macos(13.0, 13.3), watchos(9.1, 9.4), tvos(16.1, 16.4)); - (void)skipBackwardWithParams:(MTRMediaPlaybackClusterSkipBackwardParams *)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completionHandler:(void (^)(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data, NSError * _Nullable error))completionHandler MTR_DEPRECATED("Please use skipBackwardWithParams:expectedValues:expectedValueInterval:completion:", ios(16.1, 16.4), macos(13.0, 13.3), watchos(9.1, 9.4), tvos(16.1, 16.4)); - (void)seekWithParams:(MTRMediaPlaybackClusterSeekParams *)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completionHandler:(void (^)(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data, NSError * _Nullable error))completionHandler MTR_DEPRECATED("Please use seekWithParams:expectedValues:expectedValueInterval:completion:", ios(16.1, 16.4), macos(13.0, 13.3), watchos(9.1, 9.4), tvos(16.1, 16.4)); @@ -7837,6 +7873,7 @@ MTR_DEPRECATED("Please use MTRClusterUnitTesting", ios(16.1, 16.4), macos(13.0, - (void)getSetupPINWithParams:(MTRAccountLoginClusterGetSetupPINParams *)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completionHandler:(void (^)(MTRAccountLoginClusterGetSetupPINResponseParams * _Nullable data, NSError * _Nullable error))completionHandler MTR_DEPRECATED("Please use getSetupPINWithParams:expectedValues:expectedValueInterval:completion:", ios(16.1, 16.4), macos(13.0, 13.3), watchos(9.1, 9.4), tvos(16.1, 16.4)); - (void)loginWithParams:(MTRAccountLoginClusterLoginParams *)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completionHandler:(MTRStatusCompletion)completionHandler MTR_DEPRECATED("Please use loginWithParams:expectedValues:expectedValueInterval:completion:", ios(16.1, 16.4), macos(13.0, 13.3), watchos(9.1, 9.4), tvos(16.1, 16.4)); - (void)logoutWithParams:(MTRAccountLoginClusterLogoutParams * _Nullable)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completionHandler:(MTRStatusCompletion)completionHandler MTR_DEPRECATED("Please use logoutWithParams:expectedValues:expectedValueInterval:completion:", ios(16.1, 16.4), macos(13.0, 13.3), watchos(9.1, 9.4), tvos(16.1, 16.4)); +- (void)logoutWithExpectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completionHandler:(MTRStatusCompletion)completionHandler MTR_DEPRECATED("Please use logoutWithExpectedValues:expectedValueInterval:completion:", ios(16.1, 16.4), macos(13.0, 13.3), watchos(9.1, 9.4), tvos(16.1, 16.4)); @end @interface MTRClusterElectricalMeasurement (Deprecated) @@ -7876,11 +7913,13 @@ MTR_DEPRECATED("Please use MTRClusterUnitTesting", ios(16.1, 16.4), macos(13.0, - (void)testListInt8UReverseRequestWithParams:(MTRTestClusterClusterTestListInt8UReverseRequestParams *)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completionHandler:(void (^)(MTRTestClusterClusterTestListInt8UReverseResponseParams * _Nullable data, NSError * _Nullable error))completionHandler MTR_DEPRECATED("Please use testListInt8UReverseRequestWithParams:expectedValues:expectedValueInterval:completion:", ios(16.1, 16.4), macos(13.0, 13.3), watchos(9.1, 9.4), tvos(16.1, 16.4)); - (void)testEnumsRequestWithParams:(MTRTestClusterClusterTestEnumsRequestParams *)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completionHandler:(void (^)(MTRTestClusterClusterTestEnumsResponseParams * _Nullable data, NSError * _Nullable error))completionHandler MTR_DEPRECATED("Please use testEnumsRequestWithParams:expectedValues:expectedValueInterval:completion:", ios(16.1, 16.4), macos(13.0, 13.3), watchos(9.1, 9.4), tvos(16.1, 16.4)); - (void)testNullableOptionalRequestWithParams:(MTRTestClusterClusterTestNullableOptionalRequestParams * _Nullable)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completionHandler:(void (^)(MTRTestClusterClusterTestNullableOptionalResponseParams * _Nullable data, NSError * _Nullable error))completionHandler MTR_DEPRECATED("Please use testNullableOptionalRequestWithParams:expectedValues:expectedValueInterval:completion:", ios(16.1, 16.4), macos(13.0, 13.3), watchos(9.1, 9.4), tvos(16.1, 16.4)); +- (void)testNullableOptionalRequestWithExpectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completionHandler:(void (^)(MTRTestClusterClusterTestNullableOptionalResponseParams * _Nullable data, NSError * _Nullable error))completionHandler MTR_DEPRECATED("Please use testNullableOptionalRequestWithExpectedValues:expectedValueInterval:completion:", ios(16.1, 16.4), macos(13.0, 13.3), watchos(9.1, 9.4), tvos(16.1, 16.4)); - (void)testComplexNullableOptionalRequestWithParams:(MTRTestClusterClusterTestComplexNullableOptionalRequestParams *)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completionHandler:(void (^)(MTRTestClusterClusterTestComplexNullableOptionalResponseParams * _Nullable data, NSError * _Nullable error))completionHandler MTR_DEPRECATED("Please use testComplexNullableOptionalRequestWithParams:expectedValues:expectedValueInterval:completion:", ios(16.1, 16.4), macos(13.0, 13.3), watchos(9.1, 9.4), tvos(16.1, 16.4)); - (void)simpleStructEchoRequestWithParams:(MTRTestClusterClusterSimpleStructEchoRequestParams *)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completionHandler:(void (^)(MTRTestClusterClusterSimpleStructResponseParams * _Nullable data, NSError * _Nullable error))completionHandler MTR_DEPRECATED("Please use simpleStructEchoRequestWithParams:expectedValues:expectedValueInterval:completion:", ios(16.1, 16.4), macos(13.0, 13.3), watchos(9.1, 9.4), tvos(16.1, 16.4)); - (void)timedInvokeRequestWithParams:(MTRTestClusterClusterTimedInvokeRequestParams * _Nullable)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completionHandler:(MTRStatusCompletion)completionHandler MTR_DEPRECATED("Please use timedInvokeRequestWithParams:expectedValues:expectedValueInterval:completion:", ios(16.1, 16.4), macos(13.0, 13.3), watchos(9.1, 9.4), tvos(16.1, 16.4)); - (void)timedInvokeRequestWithExpectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completionHandler:(MTRStatusCompletion)completionHandler MTR_DEPRECATED("Please use timedInvokeRequestWithExpectedValues:expectedValueInterval:completion:", ios(16.1, 16.4), macos(13.0, 13.3), watchos(9.1, 9.4), tvos(16.1, 16.4)); - (void)testSimpleOptionalArgumentRequestWithParams:(MTRTestClusterClusterTestSimpleOptionalArgumentRequestParams * _Nullable)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completionHandler:(MTRStatusCompletion)completionHandler MTR_DEPRECATED("Please use testSimpleOptionalArgumentRequestWithParams:expectedValues:expectedValueInterval:completion:", ios(16.1, 16.4), macos(13.0, 13.3), watchos(9.1, 9.4), tvos(16.1, 16.4)); +- (void)testSimpleOptionalArgumentRequestWithExpectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completionHandler:(MTRStatusCompletion)completionHandler MTR_DEPRECATED("Please use testSimpleOptionalArgumentRequestWithExpectedValues:expectedValueInterval:completion:", ios(16.1, 16.4), macos(13.0, 13.3), watchos(9.1, 9.4), tvos(16.1, 16.4)); - (void)testEmitTestEventRequestWithParams:(MTRTestClusterClusterTestEmitTestEventRequestParams *)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completionHandler:(void (^)(MTRTestClusterClusterTestEmitTestEventResponseParams * _Nullable data, NSError * _Nullable error))completionHandler MTR_DEPRECATED("Please use testEmitTestEventRequestWithParams:expectedValues:expectedValueInterval:completion:", ios(16.1, 16.4), macos(13.0, 13.3), watchos(9.1, 9.4), tvos(16.1, 16.4)); - (void)testEmitTestFabricScopedEventRequestWithParams:(MTRTestClusterClusterTestEmitTestFabricScopedEventRequestParams *)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completionHandler:(void (^)(MTRTestClusterClusterTestEmitTestFabricScopedEventResponseParams * _Nullable data, NSError * _Nullable error))completionHandler MTR_DEPRECATED("Please use testEmitTestFabricScopedEventRequestWithParams:expectedValues:expectedValueInterval:completion:", ios(16.1, 16.4), macos(13.0, 13.3), watchos(9.1, 9.4), tvos(16.1, 16.4)); @end diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRClusters.mm b/src/darwin/Framework/CHIP/zap-generated/MTRClusters.mm index d319e14799a619..0ab55d5776856e 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRClusters.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRClusters.mm @@ -3737,6 +3737,10 @@ - (void)commissioningCompleteWithExpectedValues:(NSArray *> *)expectedValues expectedValueInterval:(NSNumber *)expectedValueIntervalMs completion:(void (^)(MTRNetworkCommissioningClusterScanNetworksResponseParams * _Nullable data, NSError * _Nullable error))completion +{ + [self scanNetworksWithParams:nil expectedValues:expectedValues expectedValueInterval:expectedValueIntervalMs completion:completion]; +} - (void)scanNetworksWithParams:(MTRNetworkCommissioningClusterScanNetworksParams * _Nullable)params expectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRNetworkCommissioningClusterScanNetworksResponseParams * _Nullable data, NSError * _Nullable error))completion { if (params == nil) { @@ -7674,6 +7678,10 @@ - (void)writeAttributeOnModeWithValue:(NSDictionary *)dataValueD @implementation MTRClusterTemperatureControl +- (void)setTemperatureWithExpectedValues:(NSArray *> *)expectedValues expectedValueInterval:(NSNumber *)expectedValueIntervalMs completion:(MTRStatusCompletion)completion +{ + [self setTemperatureWithParams:nil expectedValues:expectedValues expectedValueInterval:expectedValueIntervalMs completion:completion]; +} - (void)setTemperatureWithParams:(MTRTemperatureControlClusterSetTemperatureParams * _Nullable)params expectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(MTRStatusCompletion)completion { if (params == nil) { @@ -8249,6 +8257,10 @@ @implementation MTRClusterMicrowaveOvenMode @implementation MTRClusterMicrowaveOvenControl +- (void)setCookingParametersWithExpectedValues:(NSArray *> *)expectedValues expectedValueInterval:(NSNumber *)expectedValueIntervalMs completion:(MTRStatusCompletion)completion +{ + [self setCookingParametersWithParams:nil expectedValues:expectedValues expectedValueInterval:expectedValueIntervalMs completion:completion]; +} - (void)setCookingParametersWithParams:(MTRMicrowaveOvenControlClusterSetCookingParametersParams * _Nullable)params expectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(MTRStatusCompletion)completion { if (params == nil) { @@ -9089,6 +9101,10 @@ - (void)writeAttributeCurrentSensitivityLevelWithValue:(NSDictionary *> *)expectedValues expectedValueInterval:(NSNumber *)expectedValueIntervalMs completion:(MTRStatusCompletion)completion +{ + [self openWithParams:nil expectedValues:expectedValues expectedValueInterval:expectedValueIntervalMs completion:completion]; +} - (void)openWithParams:(MTRValveConfigurationAndControlClusterOpenParams * _Nullable)params expectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(MTRStatusCompletion)completion { if (params == nil) { @@ -10308,6 +10324,10 @@ - (void)writeAttributeCurrentLowPowerModeSensitivityWithValue:(NSDictionary *> *)expectedValues expectedValueInterval:(NSNumber *)expectedValueIntervalMs completion:(MTRStatusCompletion)completion +{ + [self lockDoorWithParams:nil expectedValues:expectedValues expectedValueInterval:expectedValueIntervalMs completion:completion]; +} - (void)lockDoorWithParams:(MTRDoorLockClusterLockDoorParams * _Nullable)params expectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(MTRStatusCompletion)completion { if (params == nil) { @@ -10338,6 +10358,10 @@ - (void)lockDoorWithParams:(MTRDoorLockClusterLockDoorParams * _Nullable)params completion:responseHandler]; } +- (void)unlockDoorWithExpectedValues:(NSArray *> *)expectedValues expectedValueInterval:(NSNumber *)expectedValueIntervalMs completion:(MTRStatusCompletion)completion +{ + [self unlockDoorWithParams:nil expectedValues:expectedValues expectedValueInterval:expectedValueIntervalMs completion:completion]; +} - (void)unlockDoorWithParams:(MTRDoorLockClusterUnlockDoorParams * _Nullable)params expectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(MTRStatusCompletion)completion { if (params == nil) { @@ -10815,6 +10839,10 @@ - (void)clearCredentialWithParams:(MTRDoorLockClusterClearCredentialParams *)par completion:responseHandler]; } +- (void)unboltDoorWithExpectedValues:(NSArray *> *)expectedValues expectedValueInterval:(NSNumber *)expectedValueIntervalMs completion:(MTRStatusCompletion)completion +{ + [self unboltDoorWithParams:nil expectedValues:expectedValues expectedValueInterval:expectedValueIntervalMs completion:completion]; +} - (void)unboltDoorWithParams:(MTRDoorLockClusterUnboltDoorParams * _Nullable)params expectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(MTRStatusCompletion)completion { if (params == nil) { @@ -16139,6 +16167,10 @@ - (void)skipChannelWithParams:(MTRChannelClusterSkipChannelParams *)params expec completion:responseHandler]; } +- (void)getProgramGuideWithExpectedValues:(NSArray *> *)expectedValues expectedValueInterval:(NSNumber *)expectedValueIntervalMs completion:(void (^)(MTRChannelClusterProgramGuideResponseParams * _Nullable data, NSError * _Nullable error))completion +{ + [self getProgramGuideWithParams:nil expectedValues:expectedValues expectedValueInterval:expectedValueIntervalMs completion:completion]; +} - (void)getProgramGuideWithParams:(MTRChannelClusterGetProgramGuideParams * _Nullable)params expectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRChannelClusterProgramGuideResponseParams * _Nullable data, NSError * _Nullable error))completion { if (params == nil) { @@ -16570,6 +16602,10 @@ - (void)nextWithParams:(MTRMediaPlaybackClusterNextParams * _Nullable)params exp completion:responseHandler]; } +- (void)rewindWithExpectedValues:(NSArray *> *)expectedValues expectedValueInterval:(NSNumber *)expectedValueIntervalMs completion:(void (^)(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data, NSError * _Nullable error))completion +{ + [self rewindWithParams:nil expectedValues:expectedValues expectedValueInterval:expectedValueIntervalMs completion:completion]; +} - (void)rewindWithParams:(MTRMediaPlaybackClusterRewindParams * _Nullable)params expectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data, NSError * _Nullable error))completion { if (params == nil) { @@ -16597,6 +16633,10 @@ - (void)rewindWithParams:(MTRMediaPlaybackClusterRewindParams * _Nullable)params completion:responseHandler]; } +- (void)fastForwardWithExpectedValues:(NSArray *> *)expectedValues expectedValueInterval:(NSNumber *)expectedValueIntervalMs completion:(void (^)(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data, NSError * _Nullable error))completion +{ + [self fastForwardWithParams:nil expectedValues:expectedValues expectedValueInterval:expectedValueIntervalMs completion:completion]; +} - (void)fastForwardWithParams:(MTRMediaPlaybackClusterFastForwardParams * _Nullable)params expectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data, NSError * _Nullable error))completion { if (params == nil) { @@ -16964,6 +17004,10 @@ - (void)rewindWithParams:(MTRMediaPlaybackClusterRewindParams * _Nullable)params completionHandler(static_cast(data), error); }]; } +- (void)rewindWithExpectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completionHandler:(void (^)(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data, NSError * _Nullable error))completionHandler +{ + [self rewindWithParams:nil expectedValues:expectedValues expectedValueInterval:expectedValueIntervalMs completionHandler:completionHandler]; +} - (void)fastForwardWithParams:(MTRMediaPlaybackClusterFastForwardParams * _Nullable)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completionHandler:(void (^)(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data, NSError * _Nullable error))completionHandler { [self fastForwardWithParams:params expectedValues:expectedDataValueDictionaries expectedValueInterval:expectedValueIntervalMs completion: @@ -16972,6 +17016,10 @@ - (void)fastForwardWithParams:(MTRMediaPlaybackClusterFastForwardParams * _Nulla completionHandler(static_cast(data), error); }]; } +- (void)fastForwardWithExpectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completionHandler:(void (^)(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data, NSError * _Nullable error))completionHandler +{ + [self fastForwardWithParams:nil expectedValues:expectedValues expectedValueInterval:expectedValueIntervalMs completionHandler:completionHandler]; +} - (void)skipForwardWithParams:(MTRMediaPlaybackClusterSkipForwardParams *)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completionHandler:(void (^)(MTRMediaPlaybackClusterPlaybackResponseParams * _Nullable data, NSError * _Nullable error))completionHandler { [self skipForwardWithParams:params expectedValues:expectedDataValueDictionaries expectedValueInterval:expectedValueIntervalMs completion: @@ -17609,6 +17657,10 @@ - (void)renameOutputWithParams:(MTRAudioOutputClusterRenameOutputParams *)params @implementation MTRClusterApplicationLauncher +- (void)launchAppWithExpectedValues:(NSArray *> *)expectedValues expectedValueInterval:(NSNumber *)expectedValueIntervalMs completion:(void (^)(MTRApplicationLauncherClusterLauncherResponseParams * _Nullable data, NSError * _Nullable error))completion +{ + [self launchAppWithParams:nil expectedValues:expectedValues expectedValueInterval:expectedValueIntervalMs completion:completion]; +} - (void)launchAppWithParams:(MTRApplicationLauncherClusterLaunchAppParams * _Nullable)params expectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRApplicationLauncherClusterLauncherResponseParams * _Nullable data, NSError * _Nullable error))completion { if (params == nil) { @@ -17636,6 +17688,10 @@ - (void)launchAppWithParams:(MTRApplicationLauncherClusterLaunchAppParams * _Nul completion:responseHandler]; } +- (void)stopAppWithExpectedValues:(NSArray *> *)expectedValues expectedValueInterval:(NSNumber *)expectedValueIntervalMs completion:(void (^)(MTRApplicationLauncherClusterLauncherResponseParams * _Nullable data, NSError * _Nullable error))completion +{ + [self stopAppWithParams:nil expectedValues:expectedValues expectedValueInterval:expectedValueIntervalMs completion:completion]; +} - (void)stopAppWithParams:(MTRApplicationLauncherClusterStopAppParams * _Nullable)params expectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRApplicationLauncherClusterLauncherResponseParams * _Nullable data, NSError * _Nullable error))completion { if (params == nil) { @@ -17663,6 +17719,10 @@ - (void)stopAppWithParams:(MTRApplicationLauncherClusterStopAppParams * _Nullabl completion:responseHandler]; } +- (void)hideAppWithExpectedValues:(NSArray *> *)expectedValues expectedValueInterval:(NSNumber *)expectedValueIntervalMs completion:(void (^)(MTRApplicationLauncherClusterLauncherResponseParams * _Nullable data, NSError * _Nullable error))completion +{ + [self hideAppWithParams:nil expectedValues:expectedValues expectedValueInterval:expectedValueIntervalMs completion:completion]; +} - (void)hideAppWithParams:(MTRApplicationLauncherClusterHideAppParams * _Nullable)params expectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRApplicationLauncherClusterLauncherResponseParams * _Nullable data, NSError * _Nullable error))completion { if (params == nil) { @@ -17921,6 +17981,10 @@ - (void)loginWithParams:(MTRAccountLoginClusterLoginParams *)params expectedValu completion:responseHandler]; } +- (void)logoutWithExpectedValues:(NSArray *> *)expectedValues expectedValueInterval:(NSNumber *)expectedValueIntervalMs completion:(MTRStatusCompletion)completion +{ + [self logoutWithParams:nil expectedValues:expectedValues expectedValueInterval:expectedValueIntervalMs completion:completion]; +} - (void)logoutWithParams:(MTRAccountLoginClusterLogoutParams * _Nullable)params expectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(MTRStatusCompletion)completion { if (params == nil) { @@ -18008,6 +18072,10 @@ - (void)logoutWithParams:(MTRAccountLoginClusterLogoutParams * _Nullable)params [self logoutWithParams:params expectedValues:expectedDataValueDictionaries expectedValueInterval:expectedValueIntervalMs completion: completionHandler]; } +- (void)logoutWithExpectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completionHandler:(MTRStatusCompletion)completionHandler +{ + [self logoutWithParams:nil expectedValues:expectedValues expectedValueInterval:expectedValueIntervalMs completionHandler:completionHandler]; +} @end @implementation MTRClusterContentControl @@ -18132,6 +18200,10 @@ - (void)disableWithParams:(MTRContentControlClusterDisableParams * _Nullable)par completion:responseHandler]; } +- (void)addBonusTimeWithExpectedValues:(NSArray *> *)expectedValues expectedValueInterval:(NSNumber *)expectedValueIntervalMs completion:(MTRStatusCompletion)completion +{ + [self addBonusTimeWithParams:nil expectedValues:expectedValues expectedValueInterval:expectedValueIntervalMs completion:completion]; +} - (void)addBonusTimeWithParams:(MTRContentControlClusterAddBonusTimeParams * _Nullable)params expectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(MTRStatusCompletion)completion { if (params == nil) { @@ -19701,6 +19773,10 @@ - (void)testEnumsRequestWithParams:(MTRUnitTestingClusterTestEnumsRequestParams completion:responseHandler]; } +- (void)testNullableOptionalRequestWithExpectedValues:(NSArray *> *)expectedValues expectedValueInterval:(NSNumber *)expectedValueIntervalMs completion:(void (^)(MTRUnitTestingClusterTestNullableOptionalResponseParams * _Nullable data, NSError * _Nullable error))completion +{ + [self testNullableOptionalRequestWithParams:nil expectedValues:expectedValues expectedValueInterval:expectedValueIntervalMs completion:completion]; +} - (void)testNullableOptionalRequestWithParams:(MTRUnitTestingClusterTestNullableOptionalRequestParams * _Nullable)params expectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRUnitTestingClusterTestNullableOptionalResponseParams * _Nullable data, NSError * _Nullable error))completion { if (params == nil) { @@ -19816,6 +19892,10 @@ - (void)timedInvokeRequestWithParams:(MTRUnitTestingClusterTimedInvokeRequestPar completion:responseHandler]; } +- (void)testSimpleOptionalArgumentRequestWithExpectedValues:(NSArray *> *)expectedValues expectedValueInterval:(NSNumber *)expectedValueIntervalMs completion:(MTRStatusCompletion)completion +{ + [self testSimpleOptionalArgumentRequestWithParams:nil expectedValues:expectedValues expectedValueInterval:expectedValueIntervalMs completion:completion]; +} - (void)testSimpleOptionalArgumentRequestWithParams:(MTRUnitTestingClusterTestSimpleOptionalArgumentRequestParams * _Nullable)params expectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(MTRStatusCompletion)completion { if (params == nil) { @@ -21388,6 +21468,10 @@ - (void)testNullableOptionalRequestWithParams:(MTRTestClusterClusterTestNullable completionHandler(static_cast(data), error); }]; } +- (void)testNullableOptionalRequestWithExpectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completionHandler:(void (^)(MTRTestClusterClusterTestNullableOptionalResponseParams * _Nullable data, NSError * _Nullable error))completionHandler +{ + [self testNullableOptionalRequestWithParams:nil expectedValues:expectedValues expectedValueInterval:expectedValueIntervalMs completionHandler:completionHandler]; +} - (void)testComplexNullableOptionalRequestWithParams:(MTRTestClusterClusterTestComplexNullableOptionalRequestParams *)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completionHandler:(void (^)(MTRTestClusterClusterTestComplexNullableOptionalResponseParams * _Nullable data, NSError * _Nullable error))completionHandler { [self testComplexNullableOptionalRequestWithParams:params expectedValues:expectedDataValueDictionaries expectedValueInterval:expectedValueIntervalMs completion: @@ -21418,6 +21502,10 @@ - (void)testSimpleOptionalArgumentRequestWithParams:(MTRTestClusterClusterTestSi [self testSimpleOptionalArgumentRequestWithParams:params expectedValues:expectedDataValueDictionaries expectedValueInterval:expectedValueIntervalMs completion: completionHandler]; } +- (void)testSimpleOptionalArgumentRequestWithExpectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completionHandler:(MTRStatusCompletion)completionHandler +{ + [self testSimpleOptionalArgumentRequestWithParams:nil expectedValues:expectedValues expectedValueInterval:expectedValueIntervalMs completionHandler:completionHandler]; +} - (void)testEmitTestEventRequestWithParams:(MTRTestClusterClusterTestEmitTestEventRequestParams *)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completionHandler:(void (^)(MTRTestClusterClusterTestEmitTestEventResponseParams * _Nullable data, NSError * _Nullable error))completionHandler { [self testEmitTestEventRequestWithParams:params expectedValues:expectedDataValueDictionaries expectedValueInterval:expectedValueIntervalMs completion: From d0d95d319016b07b6b0cd80742ac28b7593fc51a Mon Sep 17 00:00:00 2001 From: Boris Zbarsky Date: Thu, 21 Dec 2023 22:02:48 -0500 Subject: [PATCH 17/29] MTRSetupPayload initWithSetupPasscode should not produce invalid payloads. (#31132) It's using a long discriminator, so has to have discovery capabilities available. Fixes https://github.com/project-chip/connectedhomeip/issues/31129 --- src/darwin/Framework/CHIP/MTRSetupPayload.mm | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/darwin/Framework/CHIP/MTRSetupPayload.mm b/src/darwin/Framework/CHIP/MTRSetupPayload.mm index adfeb7cd3a9ac4..d7b08c7c0a44a4 100644 --- a/src/darwin/Framework/CHIP/MTRSetupPayload.mm +++ b/src/darwin/Framework/CHIP/MTRSetupPayload.mm @@ -139,7 +139,10 @@ - (instancetype)initWithSetupPasscode:(NSNumber *)setupPasscode discriminator:(N _vendorID = @(0); // Not available. _productID = @(0); // Not available. _commissioningFlow = MTRCommissioningFlowStandard; - _discoveryCapabilities = MTRDiscoveryCapabilitiesUnknown; + // We are using a long discriminator, so have to have a known + // discoveryCapabilities to be a valid payload. Just default to "try + // all discovery methods". + _discoveryCapabilities = MTRDiscoveryCapabilitiesAllMask; _hasShortDiscriminator = NO; _discriminator = discriminator; _setupPasscode = setupPasscode; From c349debda6be01c03b28751017da8755b7945833 Mon Sep 17 00:00:00 2001 From: Boris Zbarsky Date: Thu, 21 Dec 2023 23:25:53 -0500 Subject: [PATCH 18/29] Explicitly mark EnergyPreference as not-yet-ready-for-release on Darwin. (#31165) --- src/darwin/Framework/CHIP/templates/availability.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/src/darwin/Framework/CHIP/templates/availability.yaml b/src/darwin/Framework/CHIP/templates/availability.yaml index 935a3889eea738..a546dfed9c956d 100644 --- a/src/darwin/Framework/CHIP/templates/availability.yaml +++ b/src/darwin/Framework/CHIP/templates/availability.yaml @@ -8260,6 +8260,7 @@ - ContentAppObserver - DeviceEnergyManagement - ElectricalEnergyMeasurement + - EnergyPreference attributes: NetworkCommissioning: # Targeting Spring 2024 Matter release From 4cc18bb24fc7b0a95104846fdf746cbba7cebaf2 Mon Sep 17 00:00:00 2001 From: Shubham Patil Date: Fri, 22 Dec 2023 12:41:22 +0530 Subject: [PATCH 19/29] [ESP32] Added an API to set the CD in DAC providers and some documentation changes (#31104) * [ESP32] Added an API to set the CD in DAC providers * Usage of SetCertificationDeclaration() API in lighting-app/esp32 * [docs] Added some references for production workflows * fix the readme files * Add some docs for the lifetime of data * adjustment to the API documentation --- config/esp32/components/chip/Kconfig | 9 +++++++ docs/guides/esp32/factory_data.md | 27 ++++++++++++++++++- docs/guides/esp32/secure_cert_partition.md | 23 ++++++++++++++++ examples/lighting-app/esp32/README.md | 16 +++++------ .../lighting-app/esp32/main/CMakeLists.txt | 4 +++ examples/lighting-app/esp32/main/main.cpp | 14 +++++++++- .../ESP32/ESP32FactoryDataProvider.cpp | 4 +++ src/platform/ESP32/ESP32FactoryDataProvider.h | 27 +++++++++++++++++++ .../ESP32/ESP32SecureCertDACProvider.cpp | 4 +++ .../ESP32/ESP32SecureCertDACProvider.h | 27 +++++++++++++++++++ 10 files changed, 144 insertions(+), 11 deletions(-) diff --git a/config/esp32/components/chip/Kconfig b/config/esp32/components/chip/Kconfig index ec2ab1a6b26d64..d616603c6bb03d 100644 --- a/config/esp32/components/chip/Kconfig +++ b/config/esp32/components/chip/Kconfig @@ -867,6 +867,15 @@ menu "CHIP Device Layer" then this option gets enabled. Also, please disable ESP_SECURE_CERT_DS_PERIPHERAL from the menuconfig when this option is disabled + config ENABLE_SET_CERT_DECLARATION_API + depends on ENABLE_ESP32_FACTORY_DATA_PROVIDER || SEC_CERT_DAC_PROVIDER + bool "Enable Set CD API" + default n + help + By default, the implementation reads the Certification Declaration (CD) from the 'chip-factory' + NVS namespace. If this option is enabled, the application can use an API to set a CD, + the configured CD will be used for subsequent CD reads. + config ENABLE_ESP_INSIGHTS_TRACE bool "Enable Matter ESP Insights" depends on ESP_INSIGHTS_ENABLED diff --git a/docs/guides/esp32/factory_data.md b/docs/guides/esp32/factory_data.md index 179fb2e315a9c0..9ea2e12d1a87d3 100644 --- a/docs/guides/esp32/factory_data.md +++ b/docs/guides/esp32/factory_data.md @@ -1,5 +1,19 @@ ## Using ESP32 Factory Data Provider +**WARNING:** The following steps outline the development workflow for building a +matter device. + +Please take a look at +[security considerations](https://docs.espressif.com/projects/esp-matter/en/latest/esp32/security.html) +and review the security guidelines outlined in +[security workflow](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/security/host-based-security-workflows.html) +for production workflows. + +Ensure to select the appropriate SoC from the menu on the left-hand side, as the +provided references are specific to ESP32. + +--- + By default applications uses test-mode or default commissionable data provider, device attestation credentials provider, device instance info provider, and device info provider. @@ -47,6 +61,15 @@ specific implementation of `CommissionableDataProvider` and [Component config → CHIP Device Layer → Commissioning options → Use ESP32 Factory Data Provider] +By default, the factory data provider implementation reads the Certification +Declaration (CD) from the 'chip-factory' NVS namespace. Enable +`CONFIG_ENABLE_SET_CERT_DECLARATION_API` option to enable an API which lets you +set the CD from the application and the configured CD will be used for +subsequent CD reads. + +[Component config -> CHIP Device Layer -> Commissioning options -> Enable Set CD +API] + Enable config option `CONFIG_ENABLE_ESP32_DEVICE_INSTANCE_INFO_PROVIDER` to use ESP32 specific implementation of `DeviceInstanceInfoProvider`. @@ -107,4 +130,6 @@ appropriate address. ### Securing NVS binary image with NVS Encryption -Please check [Flash and NVS encryption guide](flash_nvs_encryption.md) +WARNING: NVS binary image may contain the sensitive information and it must be +secured using NVS encryption. For more details please check +[Flash and NVS encryption guide](flash_nvs_encryption.md) diff --git a/docs/guides/esp32/secure_cert_partition.md b/docs/guides/esp32/secure_cert_partition.md index 40d40d92d4432a..cef971f30f0910 100644 --- a/docs/guides/esp32/secure_cert_partition.md +++ b/docs/guides/esp32/secure_cert_partition.md @@ -1,5 +1,19 @@ # Using esp_secure_cert partition +**WARNING:** The following steps outline the development workflow for building a +matter device. + +Please take a look at +[security considerations](https://docs.espressif.com/projects/esp-matter/en/latest/esp32/security.html) +and review the security guidelines outlined in +[security workflow](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/security/host-based-security-workflows.html) +for production workflows. + +Ensure to select the appropriate SoC from the menu on the left-hand side, as the +provided references are specific to ESP32. + +--- + ## 1.1 ESP Secure Cert Partition - When a device is pre-provisioned, PKI credentials are generated for the @@ -177,6 +191,15 @@ CONFIG_ENABLE_ESP32_DEVICE_INSTANCE_INFO_PROVIDER=y CONFIG_CHIP_FACTORY_NAMESPACE_PARTITION_LABEL="fctry" ``` +By default, the secure cert DAC provider implementation reads the Certification +Declaration (CD) from the 'chip-factory' NVS namespace. Enable +`CONFIG_ENABLE_SET_CERT_DECLARATION_API` option to enable an API which lets you +set the CD from the application and the configured CD will be used for +subsequent CD reads. + +[Component config -> CHIP Device Layer -> Commissioning options -> Enable Set CD +API] + In order to use the esp_secure_cert_partition, in addition to enabling the above config options, you should also have the esp_secure_cert_partition and factory partition in your app. For reference, refer to partitions.csv file of diff --git a/examples/lighting-app/esp32/README.md b/examples/lighting-app/esp32/README.md index 5a6f9be37d286a..3e3dc5ee0a27cf 100644 --- a/examples/lighting-app/esp32/README.md +++ b/examples/lighting-app/esp32/README.md @@ -16,8 +16,8 @@ guides to get started. - Create a file named insights_auth_key.txt in the main directory of the example. -- Follow the steps - present[here](https://github.com/espressif/esp-insights/blob/main/examples/README.md#set-up-esp-insights-account) +- Follow the steps present + [here](https://github.com/espressif/esp-insights/blob/main/examples/README.md#set-up-esp-insights-account) to set up an insights_account and the auth key created while setting it up will be used in the example. @@ -27,13 +27,6 @@ guides to get started. cp /path/to/auth/key.txt path/to/connectedhomeip/examples/lighting-app/esp32/main/insights_auth_key.txt ``` ---- - -- [Cluster Control](#cluster-control) -- [Matter OTA guide](../../../docs/guides/esp32/ota.md) - ---- - ### Cluster Control - After successful commissioning, use the OnOff cluster command to control the @@ -50,3 +43,8 @@ cp /path/to/auth/key.txt path/to/connectedhomeip/examples/lighting-app/esp32/mai control the color attributes: $ ./out/debug/chip-tool colorcontrol move-to-hue-and-saturation 240 100 0 0 0 1 + +### Matter OTA + +For Matter OTA please take a look at +[Matter OTA guide](../../../docs/guides/esp32/ota.md). diff --git a/examples/lighting-app/esp32/main/CMakeLists.txt b/examples/lighting-app/esp32/main/CMakeLists.txt index 96279bd4d83dde..a7cc4136145981 100644 --- a/examples/lighting-app/esp32/main/CMakeLists.txt +++ b/examples/lighting-app/esp32/main/CMakeLists.txt @@ -111,6 +111,10 @@ if (CONFIG_ENABLE_ESP_INSIGHTS_TRACE) target_add_binary_data(${COMPONENT_TARGET} "insights_auth_key.txt" TEXT) endif() +if (CONFIG_ENABLE_SET_CERT_DECLARATION_API) + target_add_binary_data(${COMPONENT_TARGET} "certification_declaration.der" BINARY) +endif() + set_property(TARGET ${COMPONENT_LIB} PROPERTY CXX_STANDARD 17) target_compile_options(${COMPONENT_LIB} PRIVATE "-DCHIP_HAVE_CONFIG_H") target_compile_options(${COMPONENT_LIB} PUBLIC diff --git a/examples/lighting-app/esp32/main/main.cpp b/examples/lighting-app/esp32/main/main.cpp index adb2bafd84f577..120c004782c895 100644 --- a/examples/lighting-app/esp32/main/main.cpp +++ b/examples/lighting-app/esp32/main/main.cpp @@ -100,13 +100,25 @@ DeviceLayer::DeviceInfoProviderImpl gExampleDeviceInfoProvider; DeviceLayer::ESP32SecureCertDACProvider gSecureCertDACProvider; #endif // CONFIG_SEC_CERT_DAC_PROVIDER +#ifdef CONFIG_ENABLE_SET_CERT_DECLARATION_API +extern const uint8_t cd_start[] asm("_binary_certification_declaration_der_start"); +extern const uint8_t cd_end[] asm("_binary_certification_declaration_der_end"); +ByteSpan cdSpan(cd_start, static_cast(cd_end - cd_start)); +#endif // CONFIG_ENABLE_SET_CERT_DECLARATION_API + chip::Credentials::DeviceAttestationCredentialsProvider * get_dac_provider(void) { #if CONFIG_SEC_CERT_DAC_PROVIDER +#ifdef CONFIG_ENABLE_SET_CERT_DECLARATION_API + gSecureCertDACProvider.SetCertificationDeclaration(cdSpan); +#endif // CONFIG_ENABLE_SET_CERT_DECLARATION_API return &gSecureCertDACProvider; #elif CONFIG_ENABLE_ESP32_FACTORY_DATA_PROVIDER +#ifdef CONFIG_ENABLE_SET_CERT_DECLARATION_API + sFactoryDataProvider.SetCertificationDeclaration(cdSpan); +#endif // CONFIG_ENABLE_SET_CERT_DECLARATION_API return &sFactoryDataProvider; -#else // EXAMPLE_DAC_PROVIDER +#else // EXAMPLE_DAC_PROVIDER return chip::Credentials::Examples::GetExampleDACProvider(); #endif } diff --git a/src/platform/ESP32/ESP32FactoryDataProvider.cpp b/src/platform/ESP32/ESP32FactoryDataProvider.cpp index 1066955292d6fd..4ff4f9d2d29678 100644 --- a/src/platform/ESP32/ESP32FactoryDataProvider.cpp +++ b/src/platform/ESP32/ESP32FactoryDataProvider.cpp @@ -123,11 +123,15 @@ CHIP_ERROR ESP32FactoryDataProvider::GetDeviceAttestationCert(MutableByteSpan & CHIP_ERROR ESP32FactoryDataProvider::GetProductAttestationIntermediateCert(MutableByteSpan & outBuffer) { +#ifdef CONFIG_ENABLE_SET_CERT_DECLARATION_API + return CopySpanToMutableSpan(mCD, outBuffer); +#else size_t certSize; ReturnErrorOnFailure( ESP32Config::ReadConfigValueBin(ESP32Config::kConfigKey_PAICert, outBuffer.data(), outBuffer.size(), certSize)); outBuffer.reduce_size(certSize); return CHIP_NO_ERROR; +#endif // CONFIG_ENABLE_SET_CERT_DECLARATION_API } CHIP_ERROR ESP32FactoryDataProvider::SignWithDeviceAttestationKey(const ByteSpan & messageToSign, MutableByteSpan & outSignBuffer) diff --git a/src/platform/ESP32/ESP32FactoryDataProvider.h b/src/platform/ESP32/ESP32FactoryDataProvider.h index d69e64ffd1fcc1..1d78f2c2e8fa0b 100644 --- a/src/platform/ESP32/ESP32FactoryDataProvider.h +++ b/src/platform/ESP32/ESP32FactoryDataProvider.h @@ -60,6 +60,28 @@ class ESP32FactoryDataProvider : public CommissionableDataProvider, CHIP_ERROR GetProductAttestationIntermediateCert(MutableByteSpan & outBuffer) override; CHIP_ERROR SignWithDeviceAttestationKey(const ByteSpan & messageToSign, MutableByteSpan & outSignBuffer) override; +#ifdef CONFIG_ENABLE_SET_CERT_DECLARATION_API + /** + * @brief API to set the Certification Declaration (CD). + * + * The GetCertificationDeclaration() API implementation reads the CD from the NVS namespace `chip-factory`. + * Use this API to set the CD if it is stored at a different location, e.g., embedded in the firmware. + * Subsequent reads after calling this API will return the set CD. + * + * @param[in] cd ByteSpan containing the Certification Declaration. + * The underlying data must remain allocated throughout the lifetime of the device, + * as the API does not make a copy. + * + * @return CHIP_ERROR indicating the success or failure of the operation. + */ + CHIP_ERROR SetCertificationDeclaration(const ByteSpan & cd) + { + VerifyOrReturnError(!cd.empty(), CHIP_ERROR_INVALID_ARGUMENT); + mCD = cd; + return CHIP_NO_ERROR; + } +#endif // CONFIG_ENABLE_SET_CERT_DECLARATION_API + #if CHIP_DEVICE_CONFIG_ENABLE_DEVICE_INSTANCE_INFO_PROVIDER // ===== Members functions that implement the GenericDeviceInstanceInfoProvider CHIP_ERROR GetVendorName(char * buf, size_t bufSize) override; @@ -75,6 +97,11 @@ class ESP32FactoryDataProvider : public CommissionableDataProvider, CHIP_ERROR GetPartNumber(char * buf, size_t bufSize) override; CHIP_ERROR GetHardwareVersion(uint16_t & hardwareVersion) override; #endif // CHIP_DEVICE_CONFIG_ENABLE_DEVICE_INSTANCE_INFO_PROVIDER + +private: +#ifdef CONFIG_ENABLE_SET_CERT_DECLARATION_API + ByteSpan mCD; +#endif // CONFIG_ENABLE_SET_CERT_DECLARATION_API }; } // namespace DeviceLayer diff --git a/src/platform/ESP32/ESP32SecureCertDACProvider.cpp b/src/platform/ESP32/ESP32SecureCertDACProvider.cpp index 1b06224318231c..a1bdedf03e1711 100644 --- a/src/platform/ESP32/ESP32SecureCertDACProvider.cpp +++ b/src/platform/ESP32/ESP32SecureCertDACProvider.cpp @@ -55,11 +55,15 @@ CHIP_ERROR LoadKeypairFromRaw(ByteSpan privateKey, ByteSpan publicKey, Crypto::P CHIP_ERROR ESP32SecureCertDACProvider ::GetCertificationDeclaration(MutableByteSpan & outBuffer) { +#ifdef CONFIG_ENABLE_SET_CERT_DECLARATION_API + return CopySpanToMutableSpan(mCD, outBuffer); +#else size_t certSize; ReturnErrorOnFailure( ESP32Config::ReadConfigValueBin(ESP32Config::kConfigKey_CertDeclaration, outBuffer.data(), outBuffer.size(), certSize)); outBuffer.reduce_size(certSize); return CHIP_NO_ERROR; +#endif // CONFIG_ENABLE_SET_CERT_DECLARATION_API } CHIP_ERROR ESP32SecureCertDACProvider ::GetFirmwareInformation(MutableByteSpan & out_firmware_info_buffer) diff --git a/src/platform/ESP32/ESP32SecureCertDACProvider.h b/src/platform/ESP32/ESP32SecureCertDACProvider.h index 997695aec0ec74..4e09c1efa1c5c0 100644 --- a/src/platform/ESP32/ESP32SecureCertDACProvider.h +++ b/src/platform/ESP32/ESP32SecureCertDACProvider.h @@ -31,6 +31,33 @@ class ESP32SecureCertDACProvider : public Credentials::DeviceAttestationCredenti CHIP_ERROR GetDeviceAttestationCert(MutableByteSpan & outBuffer) override; CHIP_ERROR GetProductAttestationIntermediateCert(MutableByteSpan & outBuffer) override; CHIP_ERROR SignWithDeviceAttestationKey(const ByteSpan & messageToSign, MutableByteSpan & outSignBuffer) override; + +#ifdef CONFIG_ENABLE_SET_CERT_DECLARATION_API + /** + * @brief API to set the Certification Declaration (CD). + * + * The GetCertificationDeclaration() API implementation reads the CD from the NVS namespace `chip-factory`. + * Use this API to set the CD if it is stored at a different location, e.g., embedded in the firmware. + * Subsequent reads after calling this API will return the set CD. + * + * @param[in] cd ByteSpan containing the Certification Declaration. + * The underlying data must remain allocated throughout the lifetime of the device, + * as the API does not make a copy. + * + * @return CHIP_ERROR indicating the success or failure of the operation. + */ + CHIP_ERROR SetCertificationDeclaration(const ByteSpan & cd) + { + VerifyOrReturnError(!cd.empty(), CHIP_ERROR_INVALID_ARGUMENT); + mCD = cd; + return CHIP_NO_ERROR; + } +#endif // CONFIG_ENABLE_SET_CERT_DECLARATION_API + +private: +#ifdef CONFIG_ENABLE_SET_CERT_DECLARATION_API + ByteSpan mCD; +#endif // CONFIG_ENABLE_SET_CERT_DECLARATION_API }; } // namespace DeviceLayer } // namespace chip From cd815ef5921bc796eb636b1f91397666dc1f918c Mon Sep 17 00:00:00 2001 From: Shubham Patil Date: Fri, 22 Dec 2023 13:57:00 +0530 Subject: [PATCH 20/29] [ESP32] Config option for opening basic commissioning window on boot (#31158) --- config/esp32/components/chip/Kconfig | 7 +++++++ src/platform/ESP32/CHIPDevicePlatformConfig.h | 1 + 2 files changed, 8 insertions(+) diff --git a/config/esp32/components/chip/Kconfig b/config/esp32/components/chip/Kconfig index d616603c6bb03d..e0576a38051650 100644 --- a/config/esp32/components/chip/Kconfig +++ b/config/esp32/components/chip/Kconfig @@ -250,6 +250,13 @@ menu "CHIP Core" help The delay time for OTA reboot on applying. + config CHIP_ENABLE_PAIRING_AUTOSTART + bool "Open commissioning window on boot" + default y + help + Opens the commissioning window automatically at application boot time if + the node is not yet commissioned. + endmenu # "System Options" menu "Security Options" diff --git a/src/platform/ESP32/CHIPDevicePlatformConfig.h b/src/platform/ESP32/CHIPDevicePlatformConfig.h index 0c4f036f5177a4..f0f28408a3ce12 100644 --- a/src/platform/ESP32/CHIPDevicePlatformConfig.h +++ b/src/platform/ESP32/CHIPDevicePlatformConfig.h @@ -105,6 +105,7 @@ #define CHIP_DEVICE_CONFIG_ENABLE_DEVICE_INSTANCE_INFO_PROVIDER CONFIG_ENABLE_ESP32_DEVICE_INSTANCE_INFO_PROVIDER #define CHIP_DEVICE_CONFIG_DISCOVERY_TIMEOUT_SECS CONFIG_CHIP_DISCOVERY_TIMEOUT_SECS #define CHIP_DEVICE_CONFIG_ENABLE_BOTH_COMMISSIONER_AND_COMMISSIONEE CONFIG_ENABLE_ESP32_BLE_CONTROLLER +#define CHIP_DEVICE_CONFIG_ENABLE_PAIRING_AUTOSTART CONFIG_CHIP_ENABLE_PAIRING_AUTOSTART // Options for background chip task #define CHIP_DEVICE_CONFIG_ENABLE_BG_EVENT_PROCESSING CONFIG_ENABLE_BG_EVENT_PROCESSING From 1939c35ca76252752107b4d9f86bd8577935ef7e Mon Sep 17 00:00:00 2001 From: Shubham Patil Date: Fri, 22 Dec 2023 14:23:52 +0530 Subject: [PATCH 21/29] [ESP32] fix the unsafe access to chip stack in lock-app (#31171) --- examples/lock-app/esp32/main/AppTask.cpp | 6 +++--- examples/lock-app/esp32/main/include/AppTask.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/lock-app/esp32/main/AppTask.cpp b/examples/lock-app/esp32/main/AppTask.cpp index 8b251a305e809c..52650e5c2d2652 100644 --- a/examples/lock-app/esp32/main/AppTask.cpp +++ b/examples/lock-app/esp32/main/AppTask.cpp @@ -99,7 +99,7 @@ CHIP_ERROR AppTask::Init() sLockLED.Set(!BoltLockMgr().IsUnlocked()); - chip::DeviceLayer::SystemLayer().ScheduleWork(UpdateClusterState, nullptr); + chip::DeviceLayer::PlatformMgr().ScheduleWork(UpdateClusterState, reinterpret_cast(nullptr)); ConfigurationMgr().LogDeviceConfig(); @@ -424,7 +424,7 @@ void AppTask::ActionCompleted(BoltLockManager::Action_t aAction) } if (sAppTask.mSyncClusterToButtonAction) { - chip::DeviceLayer::SystemLayer().ScheduleWork(UpdateClusterState, nullptr); + chip::DeviceLayer::PlatformMgr().ScheduleWork(UpdateClusterState, reinterpret_cast(nullptr)); sAppTask.mSyncClusterToButtonAction = false; } } @@ -463,7 +463,7 @@ void AppTask::DispatchEvent(AppEvent * aEvent) } /* if unlocked then it locked it first*/ -void AppTask::UpdateClusterState(chip::System::Layer *, void * context) +void AppTask::UpdateClusterState(intptr_t context) { uint8_t newValue = !BoltLockMgr().IsUnlocked(); diff --git a/examples/lock-app/esp32/main/include/AppTask.h b/examples/lock-app/esp32/main/include/AppTask.h index 7a1aad3e221800..3c32cb8704aa0e 100644 --- a/examples/lock-app/esp32/main/include/AppTask.h +++ b/examples/lock-app/esp32/main/include/AppTask.h @@ -66,7 +66,7 @@ class AppTask static void LockActionEventHandler(AppEvent * aEvent); static void TimerEventHandler(TimerHandle_t xTimer); - static void UpdateClusterState(chip::System::Layer *, void * context); + static void UpdateClusterState(intptr_t context); void StartTimer(uint32_t aTimeoutMs); From 83c1b73f918565152be19f2d240e5b3993401c1f Mon Sep 17 00:00:00 2001 From: RJ030 <127305878+RJ030@users.noreply.github.com> Date: Fri, 22 Dec 2023 10:11:14 +0100 Subject: [PATCH 22/29] Add documentation about the usage of the --storage-directory flag. (#31172) --- docs/guides/chip_tool_guide.md | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/docs/guides/chip_tool_guide.md b/docs/guides/chip_tool_guide.md index 32ce669d538a68..31aa29353c91ab 100644 --- a/docs/guides/chip_tool_guide.md +++ b/docs/guides/chip_tool_guide.md @@ -18,6 +18,10 @@ directory. > `/tmp/chip_tool_config.ini` file. Deleting this and other `.ini` files in the > `/tmp` directory can sometimes resolve issues related to stale configuration. +> **Note:** To make the configuration persistent (since `/tmp` directory might +> be flushed at each reboot) you can change the directory where CHIP Tool caches +> its configuration by using the option `--storage-directory` +
## Building and running the CHIP Tool @@ -676,6 +680,30 @@ The following flags are available:
+##### Changing storage directory + +By default, CHIP Tool stores its configuration into the `/tmp` directory. You +can change the storage directory by using the `--storage-directory` flag. + +Usage: + +``` +--storage-directory +``` + +Here, __ is the path to the directory where the configuration is +stored. + +**Example of usage:** + +``` +$ ./chip-tool pairing ble-wifi --storage-directory +$ ./chip-tool temperaturemeasurement read measured-value --storage-directory + +``` + +
+ ### Commissioner name and ID flags All CHIP Tool commands can be used together with the following From 061ff86a22f054b40e9e243fc4673b07afd07b47 Mon Sep 17 00:00:00 2001 From: jamesharrow <93921463+jamesharrow@users.noreply.github.com> Date: Fri, 22 Dec 2023 11:06:59 +0000 Subject: [PATCH 23/29] Remove duplicate energy management files from all clusters app (#31155) * Updated CMakeLists.txt to remove duplicate energy-management files. * Updated BUILD.gn to remove duplicated files from all-clusters-common and energy-management-common * Updated BUILD.gn to remove duplicated files from all-clusters-common and energy-management-common * Restyled by gn * Updated build files to remove duplicate copies from all-clusters-common to energy-management-common * Fixed ESP32 include path * Restyled by gn * Removed DeviceEnergyManagement files from PR * Removed DeviceEnergyManagement files from PR (ameba/chip_main.cmake) --------- Co-authored-by: Restyled.io --- .../include/EVSECallbacks.h | 84 -- .../include/EnergyEvseDelegateImpl.h | 206 ----- .../include/EnergyEvseManager.h | 57 -- .../src/EnergyEvseDelegateImpl.cpp | 847 ------------------ .../src/EnergyEvseManager.cpp | 33 - .../all-clusters-app/ameba/chip_main.cmake | 6 +- examples/all-clusters-app/asr/BUILD.gn | 5 +- .../all-clusters-app/cc13x2x7_26x2x7/BUILD.gn | 5 +- .../all-clusters-app/cc13x4_26x4/BUILD.gn | 5 +- .../esp32/main/CMakeLists.txt | 1 + .../all-clusters-app/infineon/psoc6/BUILD.gn | 5 +- examples/all-clusters-app/linux/BUILD.gn | 10 +- examples/all-clusters-app/mbed/CMakeLists.txt | 6 +- .../nrfconnect/CMakeLists.txt | 6 +- examples/all-clusters-app/nxp/mw320/BUILD.gn | 5 +- .../openiotsdk/CMakeLists.txt | 6 +- .../all-clusters-app/telink/CMakeLists.txt | 6 +- examples/all-clusters-app/tizen/BUILD.gn | 10 +- .../esp32/main/CMakeLists.txt | 2 + examples/shell/shell_common/BUILD.gn | 10 +- 20 files changed, 56 insertions(+), 1259 deletions(-) delete mode 100644 examples/all-clusters-app/all-clusters-common/include/EVSECallbacks.h delete mode 100644 examples/all-clusters-app/all-clusters-common/include/EnergyEvseDelegateImpl.h delete mode 100644 examples/all-clusters-app/all-clusters-common/include/EnergyEvseManager.h delete mode 100644 examples/all-clusters-app/all-clusters-common/src/EnergyEvseDelegateImpl.cpp delete mode 100644 examples/all-clusters-app/all-clusters-common/src/EnergyEvseManager.cpp diff --git a/examples/all-clusters-app/all-clusters-common/include/EVSECallbacks.h b/examples/all-clusters-app/all-clusters-common/include/EVSECallbacks.h deleted file mode 100644 index 5bdac2f8e853d6..00000000000000 --- a/examples/all-clusters-app/all-clusters-common/include/EVSECallbacks.h +++ /dev/null @@ -1,84 +0,0 @@ -/* - * - * 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. - */ - -#pragma once - -namespace chip { -namespace app { -namespace Clusters { - -using namespace chip::app::Clusters::EnergyEvse; - -/* This callbacks mechanism is intended to allow different delegates to - * dispatch notifications that something has changed. - * - * This is not specific to the EnergyEVSE cluster, but includes DeviceEnergyManagement - * and potential future clusters. - */ -enum EVSECallbackType -{ - /* - * The State has changed (e.g. from Disabled to Charging, or vice-versa) - */ - StateChanged, - /* - * ChargeCurrent has changed - */ - ChargeCurrentChanged, - /* - * Charging Preferences have changed - */ - ChargingPreferencesChanged, - /* - * DeviceEnergyManagement has changed - */ - DeviceEnergyManagementChanged, -}; - -struct EVSECbInfo -{ - EVSECallbackType type; - - union - { - /* for type = StateChanged */ - struct - { - StateEnum state; - SupplyStateEnum supplyState; - } StateChange; - - /* for type = ChargeCurrentChanged */ - struct - { - int64_t maximumChargeCurrent; - } ChargingCurrent; - }; -}; - -typedef void (*EVSECallbackFunc)(const EVSECbInfo * cb, intptr_t arg); - -struct EVSECallbackWrapper -{ - EVSECallbackFunc handler; - intptr_t arg; -}; - -} // namespace Clusters -} // namespace app -} // namespace chip diff --git a/examples/all-clusters-app/all-clusters-common/include/EnergyEvseDelegateImpl.h b/examples/all-clusters-app/all-clusters-common/include/EnergyEvseDelegateImpl.h deleted file mode 100644 index f3c003d081fc6e..00000000000000 --- a/examples/all-clusters-app/all-clusters-common/include/EnergyEvseDelegateImpl.h +++ /dev/null @@ -1,206 +0,0 @@ -/* - * - * 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. - */ - -#pragma once - -#include "app/clusters/energy-evse-server/energy-evse-server.h" -#include - -#include -#include -#include - -using chip::Protocols::InteractionModel::Status; -namespace chip { -namespace app { -namespace Clusters { -namespace EnergyEvse { - -/** - * The application delegate. - */ - -class EnergyEvseDelegate : public EnergyEvse::Delegate -{ -public: - ~EnergyEvseDelegate(); - - /** - * @brief Called when EVSE cluster receives Disable command - */ - Status Disable() override; - - /** - * @brief Called when EVSE cluster receives EnableCharging command - * - * @param chargingEnabledUntil - * @param minimumChargeCurrent (in mA) - * @param maximumChargeCurrent (in mA) - */ - Status EnableCharging(const DataModel::Nullable & chargingEnabledUntil, const int64_t & minimumChargeCurrent, - const int64_t & maximumChargeCurrent) override; - - /** - * @brief Called when EVSE cluster receives EnableDischarging command - * - * @param dischargingEnabledUntil - * @param maximumChargeCurrent (in mA) - */ - Status EnableDischarging(const DataModel::Nullable & dischargingEnabledUntil, - const int64_t & maximumDischargeCurrent) override; - - /** - * @brief Called when EVSE cluster receives StartDiagnostics command - */ - Status StartDiagnostics() override; - - /** - * @brief Called by EVSE Hardware to register a single callback handler - */ - Status HwRegisterEvseCallbackHandler(EVSECallbackFunc handler, intptr_t arg); - - // ----------------------------------------------------------------- - // Internal API to allow an EVSE to change its internal state etc - Status HwSetMaxHardwareCurrentLimit(int64_t currentmA); - Status HwSetCircuitCapacity(int64_t currentmA); - Status HwSetCableAssemblyLimit(int64_t currentmA); - Status HwSetState(StateEnum state); - Status HwSetFault(FaultStateEnum fault); - Status HwSetRFID(ByteSpan uid); - Status HwSetVehicleID(const CharSpan & vehID); - - // ------------------------------------------------------------------ - // Get attribute methods - StateEnum GetState() override; - CHIP_ERROR SetState(StateEnum); - - SupplyStateEnum GetSupplyState() override; - CHIP_ERROR SetSupplyState(SupplyStateEnum); - - FaultStateEnum GetFaultState() override; - CHIP_ERROR SetFaultState(FaultStateEnum); - - DataModel::Nullable GetChargingEnabledUntil() override; - CHIP_ERROR SetChargingEnabledUntil(uint32_t); - - DataModel::Nullable GetDischargingEnabledUntil() override; - CHIP_ERROR SetDischargingEnabledUntil(uint32_t); - - int64_t GetCircuitCapacity() override; - CHIP_ERROR SetCircuitCapacity(int64_t); - - int64_t GetMinimumChargeCurrent() override; - CHIP_ERROR SetMinimumChargeCurrent(int64_t); - - int64_t GetMaximumChargeCurrent() override; - CHIP_ERROR SetMaximumChargeCurrent(int64_t); - - int64_t GetMaximumDischargeCurrent() override; - CHIP_ERROR SetMaximumDischargeCurrent(int64_t); - - int64_t GetUserMaximumChargeCurrent() override; - CHIP_ERROR SetUserMaximumChargeCurrent(int64_t) override; - - uint32_t GetRandomizationDelayWindow() override; - CHIP_ERROR SetRandomizationDelayWindow(uint32_t) override; - - /* PREF attributes */ - uint8_t GetNumberOfWeeklyTargets() override; - uint8_t GetNumberOfDailyTargets() override; - DataModel::Nullable GetNextChargeStartTime() override; - DataModel::Nullable GetNextChargeTargetTime() override; - DataModel::Nullable GetNextChargeRequiredEnergy() override; - DataModel::Nullable GetNextChargeTargetSoC() override; - - DataModel::Nullable GetApproximateEVEfficiency() override; - CHIP_ERROR SetApproximateEVEfficiency(uint16_t) override; - - /* SOC attributes */ - DataModel::Nullable GetStateOfCharge() override; - DataModel::Nullable GetBatteryCapacity() override; - /* PNC attributes*/ - DataModel::Nullable GetVehicleID() override; - /* Session SESS attributes */ - DataModel::Nullable GetSessionID() override; - DataModel::Nullable GetSessionDuration() override; - DataModel::Nullable GetSessionEnergyCharged() override; - DataModel::Nullable GetSessionEnergyDischarged() override; - -private: - /* Constants */ - static constexpr int DEFAULT_MIN_CHARGE_CURRENT = 6000; /* 6A */ - static constexpr int DEFAULT_USER_MAXIMUM_CHARGE_CURRENT = kMaximumChargeCurrent; /* 80A */ - static constexpr int DEFAULT_RANDOMIZATION_DELAY_WINDOW = 600; /* 600s */ - static constexpr int kMaxVehicleIDBufSize = 32; - - /* private variables for controlling the hardware - these are not attributes */ - int64_t mMaxHardwareCurrentLimit = 0; /* Hardware current limit in mA */ - int64_t mCableAssemblyCurrentLimit = 0; /* Cable limit detected when cable is plugged in, in mA */ - int64_t mMaximumChargingCurrentLimitFromCommand = 0; /* Value of current maximum limit when charging enabled */ - int64_t mActualChargingCurrentLimit = 0; - StateEnum mHwState = StateEnum::kNotPluggedIn; /* Hardware state */ - - /* Callback related */ - EVSECallbackWrapper mCallbacks = { .handler = nullptr, .arg = 0 }; /* Wrapper to allow callbacks to be registered */ - Status NotifyApplicationCurrentLimitChange(int64_t maximumChargeCurrent); - Status NotifyApplicationStateChange(); - - /** - * @brief Helper function to work out the charge limit based on conditions and settings - */ - Status ComputeMaxChargeCurrentLimit(); - - /* Attributes */ - StateEnum mState = StateEnum::kNotPluggedIn; - SupplyStateEnum mSupplyState = SupplyStateEnum::kDisabled; - FaultStateEnum mFaultState = FaultStateEnum::kNoError; - DataModel::Nullable mChargingEnabledUntil; // TODO Default to 0 to indicate disabled - DataModel::Nullable mDischargingEnabledUntil; // TODO Default to 0 to indicate disabled - int64_t mCircuitCapacity = 0; - int64_t mMinimumChargeCurrent = DEFAULT_MIN_CHARGE_CURRENT; - int64_t mMaximumChargeCurrent = 0; - int64_t mMaximumDischargeCurrent = 0; - int64_t mUserMaximumChargeCurrent = DEFAULT_USER_MAXIMUM_CHARGE_CURRENT; // TODO update spec - uint32_t mRandomizationDelayWindow = DEFAULT_RANDOMIZATION_DELAY_WINDOW; - /* PREF attributes */ - uint8_t mNumberOfWeeklyTargets = 0; - uint8_t mNumberOfDailyTargets = 1; - DataModel::Nullable mNextChargeStartTime; - DataModel::Nullable mNextChargeTargetTime; - DataModel::Nullable mNextChargeRequiredEnergy; - DataModel::Nullable mNextChargeTargetSoC; - DataModel::Nullable mApproximateEVEfficiency; - - /* SOC attributes */ - DataModel::Nullable mStateOfCharge; - DataModel::Nullable mBatteryCapacity; - - /* PNC attributes*/ - DataModel::Nullable mVehicleID; - - /* Session SESS attributes */ - DataModel::Nullable mSessionID; - DataModel::Nullable mSessionDuration; - DataModel::Nullable mSessionEnergyCharged; - DataModel::Nullable mSessionEnergyDischarged; -}; - -} // namespace EnergyEvse -} // namespace Clusters -} // namespace app -} // namespace chip diff --git a/examples/all-clusters-app/all-clusters-common/include/EnergyEvseManager.h b/examples/all-clusters-app/all-clusters-common/include/EnergyEvseManager.h deleted file mode 100644 index 9875c397990ef2..00000000000000 --- a/examples/all-clusters-app/all-clusters-common/include/EnergyEvseManager.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * - * 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. - */ - -#pragma once - -#include -#include -#include -#include - -namespace chip { -namespace app { -namespace Clusters { - -using namespace chip::app::Clusters::EnergyEvse; -class EnergyEvseManager : public Instance -{ -public: - EnergyEvseManager(EndpointId aEndpointId, EnergyEvseDelegate & aDelegate, Feature aFeature, OptionalAttributes aOptionalAttrs, - OptionalCommands aOptionalCmds) : - EnergyEvse::Instance(aEndpointId, aDelegate, aFeature, aOptionalAttrs, aOptionalCmds) - { - mDelegate = &aDelegate; - } - - // Delete copy constructor and assignment operator. - EnergyEvseManager(const EnergyEvseManager &) = delete; - EnergyEvseManager(const EnergyEvseManager &&) = delete; - EnergyEvseManager & operator=(const EnergyEvseManager &) = delete; - - CHIP_ERROR Init(); - void Shutdown(); - - EnergyEvseDelegate * GetDelegate() { return mDelegate; }; - -private: - EnergyEvseDelegate * mDelegate; -}; - -} // namespace Clusters -} // namespace app -} // namespace chip diff --git a/examples/all-clusters-app/all-clusters-common/src/EnergyEvseDelegateImpl.cpp b/examples/all-clusters-app/all-clusters-common/src/EnergyEvseDelegateImpl.cpp deleted file mode 100644 index 4cc83eaaf8a835..00000000000000 --- a/examples/all-clusters-app/all-clusters-common/src/EnergyEvseDelegateImpl.cpp +++ /dev/null @@ -1,847 +0,0 @@ -/* - * - * 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. - */ - -#include -#include -#include -#include - -using namespace chip; -using namespace chip::app; -using namespace chip::app::DataModel; -using namespace chip::app::Clusters; -using namespace chip::app::Clusters::EnergyEvse; -using namespace chip::app::Clusters::EnergyEvse::Attributes; - -using chip::app::LogEvent; -using chip::Protocols::InteractionModel::Status; - -EnergyEvseDelegate::~EnergyEvseDelegate() -{ - // TODO Fix this as part of issue #30993 refactoring - if (!mVehicleID.IsNull()) - { - ChipLogDetail(AppServer, "Freeing VehicleID"); - delete[] mVehicleID.Value().data(); - } -} - -/** - * @brief Called when EVSE cluster receives Disable command - */ -Status EnergyEvseDelegate::Disable() -{ - ChipLogProgress(AppServer, "EnergyEvseDelegate::Disable()"); - - /* Update State */ - switch (mHwState) - { - case StateEnum::kNotPluggedIn: - SetState(StateEnum::kNotPluggedIn); - break; - - case StateEnum::kPluggedInNoDemand: - SetState(StateEnum::kPluggedInNoDemand); - break; - - case StateEnum::kPluggedInDemand: - SetState(StateEnum::kPluggedInDemand); - break; - - default: - ChipLogError(AppServer, "Unexpected EVSE hardware state"); - SetState(StateEnum::kFault); - break; - } - - /* update SupplyState */ - SetSupplyState(SupplyStateEnum::kDisabled); - - /* update ChargingEnabledUntil & DischargingEnabledUntil to show 0 */ - SetChargingEnabledUntil(0); - SetDischargingEnabledUntil(0); - - /* update MinimumChargeCurrent & MaximumChargeCurrent to 0 */ - SetMinimumChargeCurrent(0); - SetMaximumChargeCurrent(0); - - /* update MaximumDischargeCurrent to 0 */ - SetMaximumDischargeCurrent(0); - - NotifyApplicationStateChange(); - // TODO: Generate events - - return Status::Success; -} - -/** - * @brief Called when EVSE cluster receives EnableCharging command - * - * @param chargingEnabledUntil (can be null to indefinite charging) - * @param minimumChargeCurrent (in mA) - * @param maximumChargeCurrent (in mA) - */ -Status EnergyEvseDelegate::EnableCharging(const DataModel::Nullable & chargingEnabledUntil, - const int64_t & minimumChargeCurrent, const int64_t & maximumChargeCurrent) -{ - ChipLogProgress(AppServer, "EnergyEvseDelegate::EnableCharging()"); - - if (maximumChargeCurrent < kMinimumChargeCurrent || maximumChargeCurrent > kMaximumChargeCurrent) - { - ChipLogError(AppServer, "Maximum Current outside limits"); - return Status::ConstraintError; - } - - if (minimumChargeCurrent < kMinimumChargeCurrent || minimumChargeCurrent > kMaximumChargeCurrent) - { - ChipLogError(AppServer, "Maximum Current outside limits"); - return Status::ConstraintError; - } - - if (minimumChargeCurrent > maximumChargeCurrent) - { - ChipLogError(AppServer, "Minium Current > Maximum Current!"); - return Status::ConstraintError; - } - - if (chargingEnabledUntil.IsNull()) - { - /* Charging enabled indefinitely */ - ChipLogError(AppServer, "Charging enabled indefinitely"); - } - else - { - /* check chargingEnabledUntil is in the future */ - ChipLogError(AppServer, "Charging enabled until: %lu", static_cast(chargingEnabledUntil.Value())); - // TODO - // if (checkChargingEnabled) - } - - /* Check current state isn't already enabled */ - - /* If charging is already enabled, check that the parameters may have - changed, these may override an existing charging command */ - switch (mHwState) - { - case StateEnum::kNotPluggedIn: - // TODO handle errors here - SetState(StateEnum::kNotPluggedIn); - break; - - case StateEnum::kPluggedInNoDemand: - // TODO handle errors here - // TODO REFACTOR per Andrei's comment in PR30857 - can we collapse this switch statement? - SetState(StateEnum::kPluggedInNoDemand); - break; - - case StateEnum::kPluggedInDemand: - /* If the EVSE is asking for demand then enable charging */ - SetState(StateEnum::kPluggedInCharging); - break; - - default: - ChipLogError(AppServer, "Unexpected EVSE hardware state"); - SetState(StateEnum::kFault); - break; - } - - /* update SupplyState to say that charging is now enabled */ - SetSupplyState(SupplyStateEnum::kChargingEnabled); - - /* If it looks ok, store the min & max charging current */ - mMaximumChargingCurrentLimitFromCommand = maximumChargeCurrent; - SetMinimumChargeCurrent(minimumChargeCurrent); - // TODO persist these to KVS - - // TODO: Generate events - - NotifyApplicationStateChange(); - - return this->ComputeMaxChargeCurrentLimit(); -} - -/** - * @brief Called when EVSE cluster receives EnableDischarging command - * - * @param dischargingEnabledUntil (can be null to indefinite discharging) - * @param maximumChargeCurrent (in mA) - */ -Status EnergyEvseDelegate::EnableDischarging(const DataModel::Nullable & dischargingEnabledUntil, - const int64_t & maximumDischargeCurrent) -{ - ChipLogProgress(AppServer, "EnergyEvseDelegate::EnableDischarging() called."); - - /* update SupplyState */ - SetSupplyState(SupplyStateEnum::kDischargingEnabled); - - // TODO: Generate events - - NotifyApplicationStateChange(); - - return Status::Success; -} - -/** - * @brief Called when EVSE cluster receives StartDiagnostics command - */ -Status EnergyEvseDelegate::StartDiagnostics() -{ - /* For EVSE manufacturers to customize */ - ChipLogProgress(AppServer, "EnergyEvseDelegate::StartDiagnostics()"); - - /* update SupplyState to indicate we are now in Diagnostics mode */ - SetSupplyState(SupplyStateEnum::kDisabledDiagnostics); - - // TODO: Generate events - - // TODO: Notify Application to implement Diagnostics - - NotifyApplicationStateChange(); - - return Status::Success; -} - -/* --------------------------------------------------------------------------- - * EVSE Hardware interface below - */ - -/** - * @brief Called by EVSE Hardware to register a callback handler mechanism - * - * This is normally called at start-up. - * - * @param EVSECallbackFunct - function pointer to call - * @param intptr_t - optional context to provide back to callback handler - */ -Status EnergyEvseDelegate::HwRegisterEvseCallbackHandler(EVSECallbackFunc handler, intptr_t arg) -{ - if (mCallbacks.handler != nullptr) - { - ChipLogError(AppServer, "Callback handler already initialized"); - return Status::Failure; - } - mCallbacks.handler = handler; - mCallbacks.arg = arg; - - return Status::Success; -} - -/** - * @brief Called by EVSE Hardware to notify the delegate of the maximum - * current limit supported by the hardware. - * - * This is normally called at start-up. - * - * @param currentmA - Maximum current limit supported by the hardware - */ -Status EnergyEvseDelegate::HwSetMaxHardwareCurrentLimit(int64_t currentmA) -{ - if (currentmA < kMinimumChargeCurrent || currentmA > kMaximumChargeCurrent) - { - return Status::ConstraintError; - } - - /* there is no attribute to store this so store in private variable */ - mMaxHardwareCurrentLimit = currentmA; - - return this->ComputeMaxChargeCurrentLimit(); -} - -/** - * @brief Called by EVSE Hardware to notify the delegate of maximum electrician - * set current limit. - * - * This is normally called at start-up when reading from DIP-switch - * settings. - * - * @param currentmA - Maximum current limit specified by electrician - */ -Status EnergyEvseDelegate::HwSetCircuitCapacity(int64_t currentmA) -{ - if (currentmA < kMinimumChargeCurrent || currentmA > kMaximumChargeCurrent) - { - return Status::ConstraintError; - } - - mCircuitCapacity = currentmA; - MatterReportingAttributeChangeCallback(mEndpointId, EnergyEvse::Id, CircuitCapacity::Id); - - return this->ComputeMaxChargeCurrentLimit(); -} - -/** - * @brief Called by EVSE Hardware to notify the delegate of the cable assembly - * current limit. - * - * This is normally called when the EV is plugged into the EVSE and the - * PP voltage is measured by the EVSE. A pull-up resistor in the cable - * causes a voltage drop. Different current limits can be indicated - * using different resistors, which results in different voltages - * measured by the EVSE. - * - * @param currentmA - Maximum current limit detected from Cable assembly - */ -Status EnergyEvseDelegate::HwSetCableAssemblyLimit(int64_t currentmA) -{ - if (currentmA < kMinimumChargeCurrent || currentmA > kMaximumChargeCurrent) - { - return Status::ConstraintError; - } - - /* there is no attribute to store this so store in private variable */ - mCableAssemblyCurrentLimit = currentmA; - - return this->ComputeMaxChargeCurrentLimit(); -} - -/** - * @brief Called by EVSE Hardware to indicate if EV is detected - * - * The only allowed states that the EVSE hardware can set are: - * kNotPluggedIn - * kPluggedInNoDemand - * kPluggedInDemand - * - * @param StateEnum - the state of the EV being plugged in and asking for demand etc - */ -Status EnergyEvseDelegate::HwSetState(StateEnum state) -{ - switch (state) - { - case StateEnum::kNotPluggedIn: - // TODO - work out logic here - mHwState = state; - break; - case StateEnum::kPluggedInNoDemand: - // TODO - work out logic here - mHwState = state; - break; - case StateEnum::kPluggedInDemand: - // TODO - work out logic here - mHwState = state; - break; - - default: - /* All other states should be managed by the Delegate */ - // TODO (assert?) - break; - } - - return Status::Success; -} - -/** - * @brief Called by EVSE Hardware to indicate a fault - * - * @param FaultStateEnum - the fault condition detected - */ -Status EnergyEvseDelegate::HwSetFault(FaultStateEnum fault) -{ - ChipLogProgress(AppServer, "EnergyEvseDelegate::Fault()"); - - if (fault == FaultStateEnum::kNoError) - { - /* Update State to previous state */ - // TODO: need to work out the logic here! - - /* Update SupplyState to previous state */ - } - else - { - /* Update State & SupplyState */ - SetState(StateEnum::kFault); - SetSupplyState(SupplyStateEnum::kDisabledError); - } - - /* Update FaultState */ - SetFaultState(fault); - - // TODO: Generate events - - return Status::Success; -} - -/** - * @brief Called by EVSE Hardware to Send a RFID event - * - * @param ByteSpan RFID tag value (max 10 octets) - */ -Status EnergyEvseDelegate::HwSetRFID(ByteSpan uid) -{ - Events::Rfid::Type event{ .uid = uid }; - EventNumber eventNumber; - CHIP_ERROR error = LogEvent(event, mEndpointId, eventNumber); - if (CHIP_NO_ERROR != error) - { - ChipLogError(Zcl, "[Notify] Unable to send notify event: %s [endpointId=%d]", error.AsString(), mEndpointId); - return Status::Failure; - } - - return Status::Success; -} - -/** - * @brief Called by EVSE Hardware to share the VehicleID - * - * This routine will make a copy of the string so the callee doesn't - * have to hold onto it forever. - * - * @param CharSpan containing up to 32 chars. - */ -Status EnergyEvseDelegate::HwSetVehicleID(const CharSpan & newValue) -{ - // TODO this code to be refactored - See Issue #30993 - if (!mVehicleID.IsNull() && newValue.data_equal(mVehicleID.Value())) - { - return Status::Success; - } - - /* create a copy of the string so the callee doesn't have to keep it */ - char * destinationBuffer = new char[kMaxVehicleIDBufSize]; - - MutableCharSpan destinationString(destinationBuffer, kMaxVehicleIDBufSize); - CHIP_ERROR err = CopyCharSpanToMutableCharSpan(newValue, destinationString); - if (err != CHIP_NO_ERROR) - { - ChipLogError(AppServer, "HwSetVehicleID - could not copy vehicleID"); - delete[] destinationBuffer; - return Status::Failure; - } - - if (!mVehicleID.IsNull()) - { - delete[] mVehicleID.Value().data(); - } - - mVehicleID = MakeNullable(static_cast(destinationString)); - - ChipLogDetail(AppServer, "VehicleID updated %.*s", static_cast(mVehicleID.Value().size()), mVehicleID.Value().data()); - MatterReportingAttributeChangeCallback(mEndpointId, EnergyEvse::Id, VehicleID::Id); - - return Status::Success; -} - -/* --------------------------------------------------------------------------- - * Functions below are private helper functions internal to the delegate - */ - -/** - * @brief Called to compute the safe charging current limit - * - * mActualChargingCurrentLimit is the minimum of: - * - MaxHardwareCurrentLimit (of the hardware) - * - CircuitCapacity (set by the electrician - less than the hardware) - * - CableAssemblyLimit (detected when the cable is inserted) - * - MaximumChargeCurrent (from charging command) - * - UserMaximumChargeCurrent (could dynamically change) - * - */ -Status EnergyEvseDelegate::ComputeMaxChargeCurrentLimit() -{ - int64_t oldValue; - - oldValue = mActualChargingCurrentLimit; - mActualChargingCurrentLimit = mMaxHardwareCurrentLimit; - mActualChargingCurrentLimit = min(mActualChargingCurrentLimit, mCircuitCapacity); - mActualChargingCurrentLimit = min(mActualChargingCurrentLimit, mCableAssemblyCurrentLimit); - mActualChargingCurrentLimit = min(mActualChargingCurrentLimit, mMaximumChargingCurrentLimitFromCommand); - mActualChargingCurrentLimit = min(mActualChargingCurrentLimit, mUserMaximumChargeCurrent); - - /* Set the actual max charging current attribute */ - mMaximumChargeCurrent = mActualChargingCurrentLimit; - - if (oldValue != mMaximumChargeCurrent) - { - ChipLogDetail(AppServer, "MaximumChargeCurrent updated to %ld", static_cast(mMaximumChargeCurrent)); - MatterReportingAttributeChangeCallback(mEndpointId, EnergyEvse::Id, MaximumChargeCurrent::Id); - - /* Call the EV Charger hardware current limit callback */ - NotifyApplicationCurrentLimitChange(mMaximumChargeCurrent); - } - return Status::Success; -} - -Status EnergyEvseDelegate::NotifyApplicationCurrentLimitChange(int64_t maximumChargeCurrent) -{ - EVSECbInfo cbInfo; - - cbInfo.type = EVSECallbackType::ChargeCurrentChanged; - cbInfo.ChargingCurrent.maximumChargeCurrent = maximumChargeCurrent; - - if (mCallbacks.handler != nullptr) - { - mCallbacks.handler(&cbInfo, mCallbacks.arg); - } - - return Status::Success; -} - -Status EnergyEvseDelegate::NotifyApplicationStateChange() -{ - EVSECbInfo cbInfo; - - cbInfo.type = EVSECallbackType::StateChanged; - cbInfo.StateChange.state = mState; - cbInfo.StateChange.supplyState = mSupplyState; - - if (mCallbacks.handler != nullptr) - { - mCallbacks.handler(&cbInfo, mCallbacks.arg); - } - - return Status::Success; -} - -/** - * Attribute methods - */ -/* State */ -StateEnum EnergyEvseDelegate::GetState() -{ - return mState; -} - -CHIP_ERROR EnergyEvseDelegate::SetState(StateEnum newValue) -{ - StateEnum oldValue = mState; - if (newValue >= StateEnum::kUnknownEnumValue) - { - return CHIP_IM_GLOBAL_STATUS(ConstraintError); - } - - mState = newValue; - if (oldValue != mState) - { - ChipLogDetail(AppServer, "State updated to %d", static_cast(mState)); - MatterReportingAttributeChangeCallback(mEndpointId, EnergyEvse::Id, State::Id); - } - - return CHIP_NO_ERROR; -} - -/* SupplyState */ -SupplyStateEnum EnergyEvseDelegate::GetSupplyState() -{ - return mSupplyState; -} - -CHIP_ERROR EnergyEvseDelegate::SetSupplyState(SupplyStateEnum newValue) -{ - SupplyStateEnum oldValue = mSupplyState; - - if (newValue >= SupplyStateEnum::kUnknownEnumValue) - { - return CHIP_IM_GLOBAL_STATUS(ConstraintError); - } - - mSupplyState = newValue; - if (oldValue != mSupplyState) - { - ChipLogDetail(AppServer, "SupplyState updated to %d", static_cast(mSupplyState)); - MatterReportingAttributeChangeCallback(mEndpointId, EnergyEvse::Id, SupplyState::Id); - } - return CHIP_NO_ERROR; -} - -/* FaultState */ -FaultStateEnum EnergyEvseDelegate::GetFaultState() -{ - return mFaultState; -} - -CHIP_ERROR EnergyEvseDelegate::SetFaultState(FaultStateEnum newValue) -{ - FaultStateEnum oldValue = mFaultState; - - if (newValue >= FaultStateEnum::kUnknownEnumValue) - { - return CHIP_IM_GLOBAL_STATUS(ConstraintError); - } - - mFaultState = newValue; - if (oldValue != mFaultState) - { - ChipLogDetail(AppServer, "FaultState updated to %d", static_cast(mFaultState)); - MatterReportingAttributeChangeCallback(mEndpointId, EnergyEvse::Id, FaultState::Id); - } - return CHIP_NO_ERROR; -} - -/* ChargingEnabledUntil */ -DataModel::Nullable EnergyEvseDelegate::GetChargingEnabledUntil() -{ - return mChargingEnabledUntil; -} - -CHIP_ERROR EnergyEvseDelegate::SetChargingEnabledUntil(uint32_t newValue) -{ - DataModel::Nullable oldValue = mChargingEnabledUntil; - - mChargingEnabledUntil = MakeNullable(newValue); - if ((oldValue.IsNull()) || (oldValue.Value() != newValue)) - { - ChipLogDetail(AppServer, "ChargingEnabledUntil updated to %lu", - static_cast(mChargingEnabledUntil.Value())); - MatterReportingAttributeChangeCallback(mEndpointId, EnergyEvse::Id, ChargingEnabledUntil::Id); - } - return CHIP_NO_ERROR; -} - -/* DischargingEnabledUntil */ -DataModel::Nullable EnergyEvseDelegate::GetDischargingEnabledUntil() -{ - return mDischargingEnabledUntil; -} - -CHIP_ERROR EnergyEvseDelegate::SetDischargingEnabledUntil(uint32_t newValue) -{ - DataModel::Nullable oldValue = mDischargingEnabledUntil; - - mDischargingEnabledUntil = MakeNullable(newValue); - if ((oldValue.IsNull()) || (oldValue.Value() != newValue)) - { - ChipLogDetail(AppServer, "DischargingEnabledUntil updated to %lu", - static_cast(mDischargingEnabledUntil.Value())); - MatterReportingAttributeChangeCallback(mEndpointId, EnergyEvse::Id, DischargingEnabledUntil::Id); - } - return CHIP_NO_ERROR; -} - -/* CircuitCapacity */ -int64_t EnergyEvseDelegate::GetCircuitCapacity() -{ - return mCircuitCapacity; -} - -CHIP_ERROR EnergyEvseDelegate::SetCircuitCapacity(int64_t newValue) -{ - int64_t oldValue = mCircuitCapacity; - - if (newValue >= kMaximumChargeCurrent) - { - return CHIP_IM_GLOBAL_STATUS(ConstraintError); - } - - mCircuitCapacity = newValue; - if (oldValue != mCircuitCapacity) - { - ChipLogDetail(AppServer, "CircuitCapacity updated to %ld", static_cast(mCircuitCapacity)); - MatterReportingAttributeChangeCallback(mEndpointId, EnergyEvse::Id, CircuitCapacity::Id); - } - return CHIP_NO_ERROR; -} - -/* MinimumChargeCurrent */ -int64_t EnergyEvseDelegate::GetMinimumChargeCurrent() -{ - return mMinimumChargeCurrent; -} - -CHIP_ERROR EnergyEvseDelegate::SetMinimumChargeCurrent(int64_t newValue) -{ - int64_t oldValue = mMinimumChargeCurrent; - - if (newValue >= kMaximumChargeCurrent) - { - return CHIP_IM_GLOBAL_STATUS(ConstraintError); - } - - mMinimumChargeCurrent = newValue; - if (oldValue != mMinimumChargeCurrent) - { - ChipLogDetail(AppServer, "MinimumChargeCurrent updated to %ld", static_cast(mMinimumChargeCurrent)); - MatterReportingAttributeChangeCallback(mEndpointId, EnergyEvse::Id, MinimumChargeCurrent::Id); - } - return CHIP_NO_ERROR; -} - -/* MaximumChargeCurrent */ -int64_t EnergyEvseDelegate::GetMaximumChargeCurrent() -{ - return mMaximumChargeCurrent; -} - -CHIP_ERROR EnergyEvseDelegate::SetMaximumChargeCurrent(int64_t newValue) -{ - int64_t oldValue = mMaximumChargeCurrent; - - if (newValue >= kMaximumChargeCurrent) - { - return CHIP_IM_GLOBAL_STATUS(ConstraintError); - } - - mMaximumChargeCurrent = newValue; - if (oldValue != mMaximumChargeCurrent) - { - ChipLogDetail(AppServer, "MaximumChargeCurrent updated to %ld", static_cast(mMaximumChargeCurrent)); - MatterReportingAttributeChangeCallback(mEndpointId, EnergyEvse::Id, MaximumChargeCurrent::Id); - } - return CHIP_NO_ERROR; -} - -/* MaximumDischargeCurrent */ -int64_t EnergyEvseDelegate::GetMaximumDischargeCurrent() -{ - return mMaximumDischargeCurrent; -} - -CHIP_ERROR EnergyEvseDelegate::SetMaximumDischargeCurrent(int64_t newValue) -{ - int64_t oldValue = mMaximumDischargeCurrent; - - if (newValue >= kMaximumChargeCurrent) - { - return CHIP_IM_GLOBAL_STATUS(ConstraintError); - } - - mMaximumDischargeCurrent = newValue; - if (oldValue != mMaximumDischargeCurrent) - { - ChipLogDetail(AppServer, "MaximumDischargeCurrent updated to %ld", static_cast(mMaximumDischargeCurrent)); - MatterReportingAttributeChangeCallback(mEndpointId, EnergyEvse::Id, MaximumDischargeCurrent::Id); - } - return CHIP_NO_ERROR; -} - -/* UserMaximumChargeCurrent */ -int64_t EnergyEvseDelegate::GetUserMaximumChargeCurrent() -{ - return mUserMaximumChargeCurrent; -} - -CHIP_ERROR EnergyEvseDelegate::SetUserMaximumChargeCurrent(int64_t newValue) -{ - if ((newValue < 0) || (newValue > kMaximumChargeCurrent)) - { - return CHIP_IM_GLOBAL_STATUS(ConstraintError); - } - - int64_t oldValue = mUserMaximumChargeCurrent; - mUserMaximumChargeCurrent = newValue; - if (oldValue != newValue) - { - ChipLogDetail(AppServer, "UserMaximumChargeCurrent updated to %ld", static_cast(mUserMaximumChargeCurrent)); - MatterReportingAttributeChangeCallback(mEndpointId, EnergyEvse::Id, UserMaximumChargeCurrent::Id); - } - - return CHIP_NO_ERROR; -} - -/* RandomizationDelayWindow */ -uint32_t EnergyEvseDelegate::GetRandomizationDelayWindow() -{ - return mRandomizationDelayWindow; -} - -CHIP_ERROR EnergyEvseDelegate::SetRandomizationDelayWindow(uint32_t newValue) -{ - uint32_t oldValue = mRandomizationDelayWindow; - if (newValue > kMaxRandomizationDelayWindow) - { - return CHIP_IM_GLOBAL_STATUS(ConstraintError); - } - - mRandomizationDelayWindow = newValue; - if (oldValue != newValue) - { - ChipLogDetail(AppServer, "RandomizationDelayWindow updated to %lu", - static_cast(mRandomizationDelayWindow)); - MatterReportingAttributeChangeCallback(mEndpointId, EnergyEvse::Id, RandomizationDelayWindow::Id); - } - return CHIP_NO_ERROR; -} - -/* PREF attributes */ -uint8_t EnergyEvseDelegate::GetNumberOfWeeklyTargets() -{ - return mNumberOfWeeklyTargets; -} -uint8_t EnergyEvseDelegate::GetNumberOfDailyTargets() -{ - return mNumberOfDailyTargets; -} -DataModel::Nullable EnergyEvseDelegate::GetNextChargeStartTime() -{ - return mNextChargeStartTime; -} -DataModel::Nullable EnergyEvseDelegate::GetNextChargeTargetTime() -{ - return mNextChargeTargetTime; -} -DataModel::Nullable EnergyEvseDelegate::GetNextChargeRequiredEnergy() -{ - return mNextChargeRequiredEnergy; -} -DataModel::Nullable EnergyEvseDelegate::GetNextChargeTargetSoC() -{ - return mNextChargeTargetSoC; -} - -/* ApproximateEVEfficiency */ -DataModel::Nullable EnergyEvseDelegate::GetApproximateEVEfficiency() -{ - return mApproximateEVEfficiency; -} - -CHIP_ERROR EnergyEvseDelegate::SetApproximateEVEfficiency(uint16_t newValue) -{ - DataModel::Nullable oldValue = mApproximateEVEfficiency; - - mApproximateEVEfficiency = MakeNullable(newValue); - if ((oldValue.IsNull()) || (oldValue.Value() != newValue)) - { - ChipLogDetail(AppServer, "ApproximateEVEfficiency updated to %d", mApproximateEVEfficiency.Value()); - MatterReportingAttributeChangeCallback(mEndpointId, EnergyEvse::Id, ApproximateEVEfficiency::Id); - } - - return CHIP_NO_ERROR; -} - -/* SOC attributes */ -DataModel::Nullable EnergyEvseDelegate::GetStateOfCharge() -{ - return mStateOfCharge; -} -DataModel::Nullable EnergyEvseDelegate::GetBatteryCapacity() -{ - return mBatteryCapacity; -} - -/* PNC attributes*/ -DataModel::Nullable EnergyEvseDelegate::GetVehicleID() -{ - return mVehicleID; -} - -/* Session SESS attributes */ -DataModel::Nullable EnergyEvseDelegate::GetSessionID() -{ - return mSessionID; -} -DataModel::Nullable EnergyEvseDelegate::GetSessionDuration() -{ - return mSessionDuration; -} -DataModel::Nullable EnergyEvseDelegate::GetSessionEnergyCharged() -{ - return mSessionEnergyCharged; -} -DataModel::Nullable EnergyEvseDelegate::GetSessionEnergyDischarged() -{ - return mSessionEnergyDischarged; -} diff --git a/examples/all-clusters-app/all-clusters-common/src/EnergyEvseManager.cpp b/examples/all-clusters-app/all-clusters-common/src/EnergyEvseManager.cpp deleted file mode 100644 index 0d84d8856212e0..00000000000000 --- a/examples/all-clusters-app/all-clusters-common/src/EnergyEvseManager.cpp +++ /dev/null @@ -1,33 +0,0 @@ -/* - * - * 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. - */ - -#include - -using namespace chip::app; -using namespace chip::app::Clusters; -using namespace chip::app::Clusters::EnergyEvse; - -CHIP_ERROR EnergyEvseManager::Init() -{ - return Instance::Init(); -} - -void EnergyEvseManager::Shutdown() -{ - Instance::Shutdown(); -} diff --git a/examples/all-clusters-app/ameba/chip_main.cmake b/examples/all-clusters-app/ameba/chip_main.cmake index f3c6a54854c475..2ba95602857620 100755 --- a/examples/all-clusters-app/ameba/chip_main.cmake +++ b/examples/all-clusters-app/ameba/chip_main.cmake @@ -156,8 +156,6 @@ list( ${chip_dir}/examples/all-clusters-app/all-clusters-common/src/bridged-actions-stub.cpp ${chip_dir}/examples/all-clusters-app/all-clusters-common/src/air-quality-instance.cpp ${chip_dir}/examples/all-clusters-app/all-clusters-common/src/concentration-measurement-instances.cpp - ${chip_dir}/examples/all-clusters-app/all-clusters-common/src/EnergyEvseDelegateImpl.cpp - ${chip_dir}/examples/all-clusters-app/all-clusters-common/src/EnergyEvseManager.cpp ${chip_dir}/examples/all-clusters-app/all-clusters-common/src/energy-evse-stub.cpp ${chip_dir}/examples/all-clusters-app/all-clusters-common/src/fan-stub.cpp ${chip_dir}/examples/all-clusters-app/all-clusters-common/src/laundry-washer-controls-delegate-impl.cpp @@ -176,6 +174,9 @@ list( ${chip_dir}/examples/all-clusters-app/ameba/main/ManualOperationCommand.cpp ${chip_dir}/examples/all-clusters-app/ameba/main/SmokeCOAlarmManager.cpp + ${chip_dir}/examples/energy-management-app/energy-management-common/src/EnergyEvseDelegateImpl.cpp + ${chip_dir}/examples/energy-management-app/energy-management-common/src/EnergyEvseManager.cpp + ${chip_dir}/examples/platform/ameba/route_hook/ameba_route_hook.c ${chip_dir}/examples/platform/ameba/route_hook/ameba_route_table.c @@ -220,6 +221,7 @@ target_include_directories( ${chip_dir}/zzz_generated/app-common ${chip_dir}/examples/all-clusters-app/all-clusters-common ${chip_dir}/examples/all-clusters-app/all-clusters-common/include + ${chip_dir}/examples/energy-management-app/energy-management-common/include ${chip_dir}/examples/all-clusters-app/ameba/main/include ${chip_dir}/examples/platform/ameba ${chip_dir}/examples/platform/ameba/route_hook diff --git a/examples/all-clusters-app/asr/BUILD.gn b/examples/all-clusters-app/asr/BUILD.gn index 75c4a3171cfd4a..4774d48e93952c 100755 --- a/examples/all-clusters-app/asr/BUILD.gn +++ b/examples/all-clusters-app/asr/BUILD.gn @@ -71,8 +71,6 @@ asr_executable("clusters_app") { output_name = "chip-asr-clusters-example.out" sources = [ - "${chip_root}/examples/all-clusters-app/all-clusters-common/src/EnergyEvseDelegateImpl.cpp", - "${chip_root}/examples/all-clusters-app/all-clusters-common/src/EnergyEvseManager.cpp", "${chip_root}/examples/all-clusters-app/all-clusters-common/src/air-quality-instance.cpp", "${chip_root}/examples/all-clusters-app/all-clusters-common/src/bridged-actions-stub.cpp", "${chip_root}/examples/all-clusters-app/all-clusters-common/src/concentration-measurement-instances.cpp", @@ -82,6 +80,8 @@ asr_executable("clusters_app") { "${chip_root}/examples/all-clusters-app/all-clusters-common/src/smco-stub.cpp", "${chip_root}/examples/all-clusters-app/all-clusters-common/src/static-supported-modes-manager.cpp", "${chip_root}/examples/all-clusters-app/all-clusters-common/src/static-supported-temperature-levels.cpp", + "${chip_root}/examples/energy-management-app/energy-management-common/src/EnergyEvseDelegateImpl.cpp", + "${chip_root}/examples/energy-management-app/energy-management-common/src/EnergyEvseManager.cpp", "${examples_plat_dir}/ButtonHandler.cpp", "${examples_plat_dir}/CHIPDeviceManager.cpp", "${examples_plat_dir}/LEDWidget.cpp", @@ -111,6 +111,7 @@ asr_executable("clusters_app") { "${examples_plat_dir}", "${asr_project_dir}/include", "${chip_root}/examples/all-clusters-app/all-clusters-common/include", + "${chip_root}/examples/energy-management-app/energy-management-common/include", "${chip_root}/src", "${chip_root}/src/lib", "${chip_root}/src/lib/support", diff --git a/examples/all-clusters-app/cc13x2x7_26x2x7/BUILD.gn b/examples/all-clusters-app/cc13x2x7_26x2x7/BUILD.gn index ad07e2c7a0da32..dec41e71dc265c 100644 --- a/examples/all-clusters-app/cc13x2x7_26x2x7/BUILD.gn +++ b/examples/all-clusters-app/cc13x2x7_26x2x7/BUILD.gn @@ -75,8 +75,6 @@ ti_simplelink_executable("all-clusters-app") { output_name = "chip-${ti_simplelink_board}-all-clusters-example.out" sources = [ - "${chip_root}/examples/all-clusters-app/all-clusters-common/src/EnergyEvseDelegateImpl.cpp", - "${chip_root}/examples/all-clusters-app/all-clusters-common/src/EnergyEvseManager.cpp", "${chip_root}/examples/all-clusters-app/all-clusters-common/src/air-quality-instance.cpp", "${chip_root}/examples/all-clusters-app/all-clusters-common/src/binding-handler.cpp", "${chip_root}/examples/all-clusters-app/all-clusters-common/src/bridged-actions-stub.cpp", @@ -87,6 +85,8 @@ ti_simplelink_executable("all-clusters-app") { "${chip_root}/examples/all-clusters-app/all-clusters-common/src/smco-stub.cpp", "${chip_root}/examples/all-clusters-app/all-clusters-common/src/static-supported-modes-manager.cpp", "${chip_root}/examples/all-clusters-app/all-clusters-common/src/static-supported-temperature-levels.cpp", + "${chip_root}/examples/energy-management-app/energy-management-common/src/EnergyEvseDelegateImpl.cpp", + "${chip_root}/examples/energy-management-app/energy-management-common/src/EnergyEvseManager.cpp", "${chip_root}/examples/providers/DeviceInfoProviderImpl.cpp", "${project_dir}/main/AppTask.cpp", "${project_dir}/main/ClusterManager.cpp", @@ -112,6 +112,7 @@ ti_simplelink_executable("all-clusters-app") { "${project_dir}", "${project_dir}/main", "${chip_root}/examples/all-clusters-app/all-clusters-common/include", + "${chip_root}/examples/energy-management-app/energy-management-common/include", "${chip_root}/examples/providers/", ] diff --git a/examples/all-clusters-app/cc13x4_26x4/BUILD.gn b/examples/all-clusters-app/cc13x4_26x4/BUILD.gn index c35afae97aabba..0fd26ca07fdc5f 100644 --- a/examples/all-clusters-app/cc13x4_26x4/BUILD.gn +++ b/examples/all-clusters-app/cc13x4_26x4/BUILD.gn @@ -78,8 +78,6 @@ ti_simplelink_executable("all-clusters-app") { output_name = "chip-${ti_simplelink_board}-all-clusters-example.out" sources = [ - "${chip_root}/examples/all-clusters-app/all-clusters-common/src/EnergyEvseDelegateImpl.cpp", - "${chip_root}/examples/all-clusters-app/all-clusters-common/src/EnergyEvseManager.cpp", "${chip_root}/examples/all-clusters-app/all-clusters-common/src/air-quality-instance.cpp", "${chip_root}/examples/all-clusters-app/all-clusters-common/src/binding-handler.cpp", "${chip_root}/examples/all-clusters-app/all-clusters-common/src/bridged-actions-stub.cpp", @@ -90,6 +88,8 @@ ti_simplelink_executable("all-clusters-app") { "${chip_root}/examples/all-clusters-app/all-clusters-common/src/smco-stub.cpp", "${chip_root}/examples/all-clusters-app/all-clusters-common/src/static-supported-modes-manager.cpp", "${chip_root}/examples/all-clusters-app/all-clusters-common/src/static-supported-temperature-levels.cpp", + "${chip_root}/examples/energy-management-app/energy-management-common/src/EnergyEvseDelegateImpl.cpp", + "${chip_root}/examples/energy-management-app/energy-management-common/src/EnergyEvseManager.cpp", "${chip_root}/examples/providers/DeviceInfoProviderImpl.cpp", "${project_dir}/main/AppTask.cpp", "${project_dir}/main/ClusterManager.cpp", @@ -116,6 +116,7 @@ ti_simplelink_executable("all-clusters-app") { "${project_dir}", "${project_dir}/main", "${chip_root}/examples/all-clusters-app/all-clusters-common/include", + "${chip_root}/examples/energy-management-app/energy-management-common/include", "${chip_root}/examples/providers/", ] diff --git a/examples/all-clusters-app/esp32/main/CMakeLists.txt b/examples/all-clusters-app/esp32/main/CMakeLists.txt index 5680634c786678..e8851aa5a4d3d5 100644 --- a/examples/all-clusters-app/esp32/main/CMakeLists.txt +++ b/examples/all-clusters-app/esp32/main/CMakeLists.txt @@ -18,6 +18,7 @@ # The list of src and include dirs must be in sync with that in all-clusters-app/esp32/main/component.mk set(PRIV_INCLUDE_DIRS_LIST "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/all-clusters-app/all-clusters-common/include" + "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/energy-management-app/energy-management-common/include" "${CMAKE_CURRENT_LIST_DIR}/include" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/providers" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/platform/esp32" diff --git a/examples/all-clusters-app/infineon/psoc6/BUILD.gn b/examples/all-clusters-app/infineon/psoc6/BUILD.gn index b99dc84405e841..f406b3ac5d6eab 100644 --- a/examples/all-clusters-app/infineon/psoc6/BUILD.gn +++ b/examples/all-clusters-app/infineon/psoc6/BUILD.gn @@ -107,8 +107,6 @@ psoc6_executable("clusters_app") { output_name = "chip-psoc6-clusters-example.out" sources = [ - "${chip_root}/examples/all-clusters-app/all-clusters-common/src/EnergyEvseDelegateImpl.cpp", - "${chip_root}/examples/all-clusters-app/all-clusters-common/src/EnergyEvseManager.cpp", "${chip_root}/examples/all-clusters-app/all-clusters-common/src/air-quality-instance.cpp", "${chip_root}/examples/all-clusters-app/all-clusters-common/src/bridged-actions-stub.cpp", "${chip_root}/examples/all-clusters-app/all-clusters-common/src/concentration-measurement-instances.cpp", @@ -118,6 +116,8 @@ psoc6_executable("clusters_app") { "${chip_root}/examples/all-clusters-app/all-clusters-common/src/smco-stub.cpp", "${chip_root}/examples/all-clusters-app/all-clusters-common/src/static-supported-modes-manager.cpp", "${chip_root}/examples/all-clusters-app/all-clusters-common/src/static-supported-temperature-levels.cpp", + "${chip_root}/examples/energy-management-app/energy-management-common/src/EnergyEvseDelegateImpl.cpp", + "${chip_root}/examples/energy-management-app/energy-management-common/src/EnergyEvseManager.cpp", "${examples_plat_dir}/LEDWidget.cpp", "${examples_plat_dir}/init_psoc6Platform.cpp", "src/AppTask.cpp", @@ -141,6 +141,7 @@ psoc6_executable("clusters_app") { "${examples_plat_dir}", "${psoc6_project_dir}/include", "${chip_root}/examples/all-clusters-app/all-clusters-common/include", + "${chip_root}/examples/energy-management-app/energy-management-common/include", ] defines = [] diff --git a/examples/all-clusters-app/linux/BUILD.gn b/examples/all-clusters-app/linux/BUILD.gn index b3eb61c29f875a..af9414529ca76e 100644 --- a/examples/all-clusters-app/linux/BUILD.gn +++ b/examples/all-clusters-app/linux/BUILD.gn @@ -21,8 +21,6 @@ import("${chip_root}/src/platform/device.gni") source_set("chip-all-clusters-common") { sources = [ - "${chip_root}/examples/all-clusters-app/all-clusters-common/src/EnergyEvseDelegateImpl.cpp", - "${chip_root}/examples/all-clusters-app/all-clusters-common/src/EnergyEvseManager.cpp", "${chip_root}/examples/all-clusters-app/all-clusters-common/src/air-quality-instance.cpp", "${chip_root}/examples/all-clusters-app/all-clusters-common/src/binding-handler.cpp", "${chip_root}/examples/all-clusters-app/all-clusters-common/src/bridged-actions-stub.cpp", @@ -41,6 +39,8 @@ source_set("chip-all-clusters-common") { "${chip_root}/examples/all-clusters-app/all-clusters-common/src/static-supported-modes-manager.cpp", "${chip_root}/examples/all-clusters-app/all-clusters-common/src/static-supported-temperature-levels.cpp", "${chip_root}/examples/all-clusters-app/all-clusters-common/src/tcc-mode.cpp", + "${chip_root}/examples/energy-management-app/energy-management-common/src/EnergyEvseDelegateImpl.cpp", + "${chip_root}/examples/energy-management-app/energy-management-common/src/EnergyEvseManager.cpp", "AllClustersCommandDelegate.cpp", "AppOptions.cpp", "WindowCoveringManager.cpp", @@ -57,8 +57,10 @@ source_set("chip-all-clusters-common") { "${chip_root}/third_party/jsoncpp", ] - include_dirs = - [ "${chip_root}/examples/all-clusters-app/all-clusters-common/include" ] + include_dirs = [ + "${chip_root}/examples/all-clusters-app/all-clusters-common/include", + "${chip_root}/examples/energy-management-app/energy-management-common/include", + ] cflags = [ "-Wconversion" ] diff --git a/examples/all-clusters-app/mbed/CMakeLists.txt b/examples/all-clusters-app/mbed/CMakeLists.txt index 79a48c85938f78..7a240a57dc8424 100644 --- a/examples/all-clusters-app/mbed/CMakeLists.txt +++ b/examples/all-clusters-app/mbed/CMakeLists.txt @@ -7,6 +7,7 @@ get_filename_component(CHIP_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/../../.. REALPATH) get_filename_component(MBED_COMMON ${CHIP_ROOT}/examples/platform/mbed REALPATH) get_filename_component(GEN_DIR ${CHIP_ROOT}/zzz_generated/ REALPATH) get_filename_component(ALL_CLUSTERS_COMMON ${CHIP_ROOT}/examples/all-clusters-app/all-clusters-common REALPATH) +get_filename_component(ENERGY_MANAGEMENT_COMMON ${CHIP_ROOT}/examples/energy-management-app/energy-management-common/ REALPATH) get_filename_component(NLIO_ROOT ${CHIP_ROOT}/third_party/nlio/repo/include REALPATH) configure_file( @@ -49,6 +50,7 @@ target_include_directories(${APP_TARGET} PRIVATE main/include/ ${MBED_COMMON}/util/include ${ALL_CLUSTERS_COMMON}/include + ${ENERGY_MANAGEMENT_COMMON}/include ${GEN_DIR}/app-common ${GEN_DIR}/all-clusters-app ${NLIO_ROOT} @@ -63,13 +65,13 @@ target_sources(${APP_TARGET} PRIVATE ${ALL_CLUSTERS_COMMON}/src/air-quality-instance.cpp ${ALL_CLUSTERS_COMMON}/src/concentration-measurement-instances.cpp ${ALL_CLUSTERS_COMMON}/src/fan-stub.cpp - ${ALL_CLUSTERS_COMMON}/src/EnergyEvseDelegateImpl.cpp - ${ALL_CLUSTERS_COMMON}/src/EnergyEvseManager.cpp ${ALL_CLUSTERS_COMMON}/src/energy-evse-stub.cpp ${ALL_CLUSTERS_COMMON}/src/resource-monitoring-delegates.cpp ${ALL_CLUSTERS_COMMON}/src/smco-stub.cpp ${ALL_CLUSTERS_COMMON}/src/static-supported-modes-manager.cpp ${ALL_CLUSTERS_COMMON}/src/static-supported-temperature-levels.cpp + ${ENERGY_MANAGEMENT_COMMON}/src/EnergyEvseDelegateImpl.cpp + ${ENERGY_MANAGEMENT_COMMON}/src/EnergyEvseManager.cpp ) chip_configure_data_model(${APP_TARGET} diff --git a/examples/all-clusters-app/nrfconnect/CMakeLists.txt b/examples/all-clusters-app/nrfconnect/CMakeLists.txt index 72b93e0647724c..f9d635bdd2c3a9 100644 --- a/examples/all-clusters-app/nrfconnect/CMakeLists.txt +++ b/examples/all-clusters-app/nrfconnect/CMakeLists.txt @@ -19,6 +19,7 @@ get_filename_component(CHIP_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/third_party/connect get_filename_component(NRFCONNECT_COMMON ${CHIP_ROOT}/examples/platform/nrfconnect REALPATH) get_filename_component(GEN_DIR ${CHIP_ROOT}/zzz_generated/ REALPATH) get_filename_component(ALL_CLUSTERS_COMMON_DIR ${CHIP_ROOT}/examples/all-clusters-app/all-clusters-common REALPATH) +get_filename_component(ENERGY_MANAGEMENT_COMMON_DIR ${CHIP_ROOT}/examples/energy-management-app/energy-management-common/ REALPATH) include(${CHIP_ROOT}/config/nrfconnect/app/check-nrfconnect-version.cmake) @@ -49,6 +50,7 @@ include(${CHIP_ROOT}/src/app/chip_data_model.cmake) target_include_directories(app PRIVATE main/include ${ALL_CLUSTERS_COMMON_DIR}/include + ${ENERGY_MANAGEMENT_COMMON_DIR}/include ${GEN_DIR}/app-common ${GEN_DIR}/all-clusters-app ${NRFCONNECT_COMMON}/util/include) @@ -61,13 +63,13 @@ target_sources(app PRIVATE ${ALL_CLUSTERS_COMMON_DIR}/src/static-supported-temperature-levels.cpp ${ALL_CLUSTERS_COMMON_DIR}/src/bridged-actions-stub.cpp ${ALL_CLUSTERS_COMMON_DIR}/src/fan-stub.cpp - ${ALL_CLUSTERS_COMMON_DIR}/src/EnergyEvseDelegateImpl.cpp - ${ALL_CLUSTERS_COMMON_DIR}/src/EnergyEvseManager.cpp ${ALL_CLUSTERS_COMMON_DIR}/src/energy-evse-stub.cpp ${ALL_CLUSTERS_COMMON_DIR}/src/binding-handler.cpp ${ALL_CLUSTERS_COMMON_DIR}/src/air-quality-instance.cpp ${ALL_CLUSTERS_COMMON_DIR}/src/concentration-measurement-instances.cpp ${ALL_CLUSTERS_COMMON_DIR}/src/resource-monitoring-delegates.cpp + ${ENERGY_MANAGEMENT_COMMON_DIR}/src/EnergyEvseDelegateImpl.cpp + ${ENERGY_MANAGEMENT_COMMON_DIR}/src/EnergyEvseManager.cpp ${NRFCONNECT_COMMON}/util/LEDWidget.cpp) chip_configure_data_model(app diff --git a/examples/all-clusters-app/nxp/mw320/BUILD.gn b/examples/all-clusters-app/nxp/mw320/BUILD.gn index ab7be5a04d64c1..89c8b05b9a842e 100644 --- a/examples/all-clusters-app/nxp/mw320/BUILD.gn +++ b/examples/all-clusters-app/nxp/mw320/BUILD.gn @@ -71,11 +71,10 @@ mw320_executable("shell_mw320") { "${chip_root}/src", "${chip_root}/src/app/util", "${chip_root}/examples/all-clusters-app/all-clusters-common/include", + "${chip_root}/examples/energy-management-app/energy-management-common/include", "${chip_root}/examples/all-clusters-app/nxp/mw320/include", ] sources = [ - "${chip_root}/examples/all-clusters-app/all-clusters-common/src/EnergyEvseDelegateImpl.cpp", - "${chip_root}/examples/all-clusters-app/all-clusters-common/src/EnergyEvseManager.cpp", "${chip_root}/examples/all-clusters-app/all-clusters-common/src/air-quality-instance.cpp", "${chip_root}/examples/all-clusters-app/all-clusters-common/src/bridged-actions-stub.cpp", "${chip_root}/examples/all-clusters-app/all-clusters-common/src/concentration-measurement-instances.cpp", @@ -85,6 +84,8 @@ mw320_executable("shell_mw320") { "${chip_root}/examples/all-clusters-app/all-clusters-common/src/smco-stub.cpp", "${chip_root}/examples/all-clusters-app/all-clusters-common/src/static-supported-modes-manager.cpp", "${chip_root}/examples/all-clusters-app/all-clusters-common/src/static-supported-temperature-levels.cpp", + "${chip_root}/examples/energy-management-app/energy-management-common/src/EnergyEvseDelegateImpl.cpp", + "${chip_root}/examples/energy-management-app/energy-management-common/src/EnergyEvseManager.cpp", "${chip_root}/src/lib/shell/streamer_mw320.cpp", "binding-handler.cpp", "include/CHIPProjectConfig.h", diff --git a/examples/all-clusters-app/openiotsdk/CMakeLists.txt b/examples/all-clusters-app/openiotsdk/CMakeLists.txt index dce8295b300cb4..6f8b679f52a52b 100644 --- a/examples/all-clusters-app/openiotsdk/CMakeLists.txt +++ b/examples/all-clusters-app/openiotsdk/CMakeLists.txt @@ -20,6 +20,7 @@ get_filename_component(CHIP_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/../../.. REALPATH) get_filename_component(OPEN_IOT_SDK_CONFIG ${CHIP_ROOT}/config/openiotsdk REALPATH) get_filename_component(OPEN_IOT_SDK_EXAMPLE_COMMON ${CHIP_ROOT}/examples/platform/openiotsdk REALPATH) get_filename_component(ALL_CLUSTERS_COMMON ${CHIP_ROOT}/examples/all-clusters-app/all-clusters-common REALPATH) +get_filename_component(ENERGY_MANAGEMENT_COMMON ${CHIP_ROOT}/examples/energy-management-app/energy-management-common/ REALPATH) list(APPEND CMAKE_MODULE_PATH ${OPEN_IOT_SDK_CONFIG}/cmake) @@ -47,6 +48,7 @@ target_include_directories(${APP_TARGET} PRIVATE main/include ${ALL_CLUSTERS_COMMON}/include + ${ENERGY_MANAGEMENT_COMMON}/include ) target_sources(${APP_TARGET} @@ -57,12 +59,12 @@ target_sources(${APP_TARGET} ${ALL_CLUSTERS_COMMON}/src/air-quality-instance.cpp ${ALL_CLUSTERS_COMMON}/src/concentration-measurement-instances.cpp ${ALL_CLUSTERS_COMMON}/src/fan-stub.cpp - ${ALL_CLUSTERS_COMMON}/src/EnergyEvseDelegateImpl.cpp - ${ALL_CLUSTERS_COMMON}/src/EnergyEvseManager.cpp ${ALL_CLUSTERS_COMMON}/src/energy-evse-stub.cpp ${ALL_CLUSTERS_COMMON}/src/resource-monitoring-delegates.cpp ${ALL_CLUSTERS_COMMON}/src/static-supported-modes-manager.cpp ${ALL_CLUSTERS_COMMON}/src/binding-handler.cpp + ${ENERGY_MANAGEMENT_COMMON}/src/EnergyEvseDelegateImpl.cpp + ${ENERGY_MANAGEMENT_COMMON}/src/EnergyEvseManager.cpp ) target_link_libraries(${APP_TARGET} diff --git a/examples/all-clusters-app/telink/CMakeLists.txt b/examples/all-clusters-app/telink/CMakeLists.txt index fa279aa4c8a90f..7448fd76c4d91f 100644 --- a/examples/all-clusters-app/telink/CMakeLists.txt +++ b/examples/all-clusters-app/telink/CMakeLists.txt @@ -19,6 +19,7 @@ get_filename_component(CHIP_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/third_party/connect get_filename_component(TELINK_COMMON ${CHIP_ROOT}/examples/platform/telink REALPATH) get_filename_component(GEN_DIR ${CHIP_ROOT}/zzz_generated/ REALPATH) get_filename_component(ALL_CLUSTERS_COMMON_DIR ${CHIP_ROOT}/examples/all-clusters-app/all-clusters-common REALPATH) +get_filename_component(ENERGY_MANAGEMENT_COMMON_DIR ${CHIP_ROOT}/examples/energy-management-app/energy-management-common/ REALPATH) if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/boards/${BOARD}.overlay") set(LOCAL_DTC_OVERLAY_FILE "${CMAKE_CURRENT_SOURCE_DIR}/boards/${BOARD}.overlay") @@ -65,6 +66,7 @@ target_compile_options(app PRIVATE -fpermissive) target_include_directories(app PRIVATE include ${ALL_CLUSTERS_COMMON_DIR}/include + ${ENERGY_MANAGEMENT_COMMON_DIR}/include ${GEN_DIR}/app-common ${GEN_DIR}/all-clusters-app ${TELINK_COMMON}/common/include @@ -84,10 +86,10 @@ target_sources(app PRIVATE ${ALL_CLUSTERS_COMMON_DIR}/src/air-quality-instance.cpp ${ALL_CLUSTERS_COMMON_DIR}/src/concentration-measurement-instances.cpp ${ALL_CLUSTERS_COMMON_DIR}/src/fan-stub.cpp - ${ALL_CLUSTERS_COMMON_DIR}/src/EnergyEvseDelegateImpl.cpp - ${ALL_CLUSTERS_COMMON_DIR}/src/EnergyEvseManager.cpp ${ALL_CLUSTERS_COMMON_DIR}/src/energy-evse-stub.cpp ${ALL_CLUSTERS_COMMON_DIR}/src/resource-monitoring-delegates.cpp + ${ENERGY_MANAGEMENT_COMMON_DIR}/src/EnergyEvseDelegateImpl.cpp + ${ENERGY_MANAGEMENT_COMMON_DIR}/src/EnergyEvseManager.cpp ${TELINK_COMMON}/common/src/mainCommon.cpp ${TELINK_COMMON}/common/src/AppTaskCommon.cpp ${TELINK_COMMON}/util/src/LEDWidget.cpp diff --git a/examples/all-clusters-app/tizen/BUILD.gn b/examples/all-clusters-app/tizen/BUILD.gn index 6960ec6aa6d516..6af51a7f176b8a 100644 --- a/examples/all-clusters-app/tizen/BUILD.gn +++ b/examples/all-clusters-app/tizen/BUILD.gn @@ -23,8 +23,6 @@ assert(chip_build_tools) source_set("chip-all-clusters-common") { sources = [ - "${chip_root}/examples/all-clusters-app/all-clusters-common/src/EnergyEvseDelegateImpl.cpp", - "${chip_root}/examples/all-clusters-app/all-clusters-common/src/EnergyEvseManager.cpp", "${chip_root}/examples/all-clusters-app/all-clusters-common/src/air-quality-instance.cpp", "${chip_root}/examples/all-clusters-app/all-clusters-common/src/binding-handler.cpp", "${chip_root}/examples/all-clusters-app/all-clusters-common/src/bridged-actions-stub.cpp", @@ -35,6 +33,8 @@ source_set("chip-all-clusters-common") { "${chip_root}/examples/all-clusters-app/all-clusters-common/src/smco-stub.cpp", "${chip_root}/examples/all-clusters-app/all-clusters-common/src/static-supported-modes-manager.cpp", "${chip_root}/examples/all-clusters-app/all-clusters-common/src/static-supported-temperature-levels.cpp", + "${chip_root}/examples/energy-management-app/energy-management-common/src/EnergyEvseDelegateImpl.cpp", + "${chip_root}/examples/energy-management-app/energy-management-common/src/EnergyEvseManager.cpp", ] deps = [ @@ -43,8 +43,10 @@ source_set("chip-all-clusters-common") { "${chip_root}/src/lib/shell:shell_core", ] - include_dirs = - [ "${chip_root}/examples/all-clusters-app/all-clusters-common/include" ] + include_dirs = [ + "${chip_root}/examples/all-clusters-app/all-clusters-common/include", + "${chip_root}/examples/energy-management-app/energy-management-common/include", + ] } executable("chip-all-clusters-app") { diff --git a/examples/all-clusters-minimal-app/esp32/main/CMakeLists.txt b/examples/all-clusters-minimal-app/esp32/main/CMakeLists.txt index 33582927c19d26..cb38515a1a8770 100644 --- a/examples/all-clusters-minimal-app/esp32/main/CMakeLists.txt +++ b/examples/all-clusters-minimal-app/esp32/main/CMakeLists.txt @@ -19,6 +19,7 @@ # The list of src and include dirs must be in sync with that in all-clusters-minimal-app/esp32/main/component.mk set(PRIV_INCLUDE_DIRS_LIST "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/all-clusters-app/all-clusters-common/include" + "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/energy-management-app/energy-management-common/include" "${CMAKE_CURRENT_LIST_DIR}/include" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/providers" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/platform/esp32" @@ -80,6 +81,7 @@ set(SRC_DIRS_LIST "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/diagnostic-logs-server" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/door-lock-server" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/occupancy-sensor-server" + "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/energy-evse-server" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/ethernet-network-diagnostics-server" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/localization-configuration-server" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/time-format-localization-server" diff --git a/examples/shell/shell_common/BUILD.gn b/examples/shell/shell_common/BUILD.gn index b870628717d8e5..a54df29c798955 100644 --- a/examples/shell/shell_common/BUILD.gn +++ b/examples/shell/shell_common/BUILD.gn @@ -64,17 +64,19 @@ static_library("shell_common") { import("${chip_root}/src/app/chip_data_model.gni") sources += [ - "${chip_root}/examples/all-clusters-app/all-clusters-common/src/EnergyEvseDelegateImpl.cpp", - "${chip_root}/examples/all-clusters-app/all-clusters-common/src/EnergyEvseManager.cpp", "${chip_root}/examples/all-clusters-app/all-clusters-common/src/bridged-actions-stub.cpp", "${chip_root}/examples/all-clusters-app/all-clusters-common/src/energy-evse-stub.cpp", "${chip_root}/examples/all-clusters-app/all-clusters-common/src/smco-stub.cpp", "${chip_root}/examples/all-clusters-app/all-clusters-common/src/static-supported-modes-manager.cpp", "${chip_root}/examples/all-clusters-app/all-clusters-common/src/static-supported-temperature-levels.cpp", + "${chip_root}/examples/energy-management-app/energy-management-common/src/EnergyEvseDelegateImpl.cpp", + "${chip_root}/examples/energy-management-app/energy-management-common/src/EnergyEvseManager.cpp", ] - include_dirs = - [ "${chip_root}/examples/all-clusters-app/all-clusters-common/include" ] + include_dirs = [ + "${chip_root}/examples/all-clusters-app/all-clusters-common/include", + "${chip_root}/examples/energy-management-app/energy-management-common/include", + ] public_deps += [ "${chip_root}/examples/all-clusters-app/all-clusters-common" ] From b096c88aab8ad3bf1165222ec947aaa333ef7bbb Mon Sep 17 00:00:00 2001 From: eahove Date: Fri, 22 Dec 2023 09:06:41 -0600 Subject: [PATCH 24/29] Laundry dryer controls cluster sdk (#30285) * Steps 1.1, 1.2 * update cluster list and build.gn This reverts commit feabe0b2fe2fafbd9dcd0a1a1f2d6cd6c2d5c9dd. run zap and update build, clusters list zap_regen_all & build chip-tool regen zap updated zap and regen updated zap and regen zap_regen_all & build chip-tool Revert "regen zap" This reverts commit f259abfaf960804273ff45a6ab3c16aaaae0622e. * controller-clusters.zap and regen_all * setting optional=false for clusters * zap_regen_all * run zap and update build, clusters list * zap_regen_all & build chip-tool * Fisrt Pass at SDK code * SDK is building and running * now registers laundry controls delegate added function definitions to override weak definitions that do nothing. * adding the cluster to preAttributeChange list * Restyled by clang-format * Restyled by gn * regenerated all zap * reverting submodule changes * regenerate_zap_all * update all-clusters zap * Updated cluster-enums.h path * Revert "run zap and update build, clusters list" This reverts commit 17642c9951b85d230ee5b1a9b4f4c7988d5b71e2. * Restyled by clang-format * update zap * Attribute fix for SelectedDrynessLevel * Added Attribute in zcl.json * Revert "Added Attribute in zcl.json" This reverts commit 4ee377fa04fb0ea942d244fcaff92a699bb398c0. * adding SupportedDrynessLevels to JSON bits * Updated zcl test json * Fix Dryer delegate init on Linux all-clusters * Restyled by clang-format * Added static assert for Enum and removed dryer from .json bits --------- Co-authored-by: Restyled.io Co-authored-by: OmAmbalkar <36728913+OmAmbalkar@users.noreply.github.com> Co-authored-by: tennessee.carmelveilleux@gmail.com --- .../all-clusters-app.matter | 33 ++++ .../all-clusters-common/all-clusters-app.zap | 141 ++++++++++++- .../laundry-dryer-controls-delegate-impl.h | 53 +++++ .../laundry-dryer-controls-delegate-impl.cpp | 40 ++++ .../esp32/main/CMakeLists.txt | 3 +- examples/all-clusters-app/esp32/main/main.cpp | 18 ++ examples/all-clusters-app/linux/BUILD.gn | 1 + .../all-clusters-app/linux/main-common.cpp | 8 + .../laundry-dryer-controls-delegate.h | 49 +++++ .../laundry-dryer-controls-server.cpp | 187 ++++++++++++++++++ .../laundry-dryer-controls-server.h | 62 ++++++ src/app/common/templates/config-data.yaml | 1 + src/app/zap_cluster_list.json | 1 + 13 files changed, 595 insertions(+), 2 deletions(-) create mode 100644 examples/all-clusters-app/all-clusters-common/include/laundry-dryer-controls-delegate-impl.h create mode 100644 examples/all-clusters-app/all-clusters-common/src/laundry-dryer-controls-delegate-impl.cpp create mode 100644 src/app/clusters/laundry-dryer-controls-server/laundry-dryer-controls-delegate.h create mode 100644 src/app/clusters/laundry-dryer-controls-server/laundry-dryer-controls-server.cpp create mode 100644 src/app/clusters/laundry-dryer-controls-server/laundry-dryer-controls-server.h 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 59090b662d6486..71bb489e6a3c21 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 @@ -2785,6 +2785,28 @@ cluster BooleanState = 69 { readonly attribute int16u clusterRevision = 65533; } +/** This cluster supports remotely monitoring and controling the different typs of + functionality available to a drying device, such as a laundry dryer. */ +cluster LaundryDryerControls = 74 { + revision 1; // NOTE: Default/not specifically set + + enum DrynessLevelEnum : enum8 { + kLow = 0; + kNormal = 1; + kExtra = 2; + kMax = 3; + } + + readonly attribute DrynessLevelEnum supportedDrynessLevels[] = 0; + attribute nullable DrynessLevelEnum selectedDrynessLevel = 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; +} + /** Attributes and commands for selecting a mode from a list of supported options. */ cluster ModeSelect = 80 { revision 2; @@ -7038,6 +7060,17 @@ endpoint 1 { ram attribute clusterRevision default = 1; } + server cluster LaundryDryerControls { + callback attribute supportedDrynessLevels; + ram attribute selectedDrynessLevel; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; + ram attribute featureMap default = 0; + ram attribute clusterRevision default = 1; + } + server cluster ModeSelect { ram attribute description default = "Coffee"; ram attribute standardNamespace default = 0; diff --git a/examples/all-clusters-app/all-clusters-common/all-clusters-app.zap b/examples/all-clusters-app/all-clusters-common/all-clusters-app.zap index 6f35331ee14640..8f1d73386c7465 100644 --- a/examples/all-clusters-app/all-clusters-common/all-clusters-app.zap +++ b/examples/all-clusters-app/all-clusters-common/all-clusters-app.zap @@ -8408,6 +8408,144 @@ } ] }, + { + "name": "Laundry Dryer Controls", + "code": 74, + "mfgCode": null, + "define": "LAUNDRY_DRYER_CONTROLS_CLUSTER", + "side": "server", + "enabled": 1, + "attributes": [ + { + "name": "SupportedDrynessLevels", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "SelectedDrynessLevel", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "DrynessLevelEnum", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "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": "", + "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": "", + "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": "", + "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": "", + "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": "Mode Select", "code": 80, @@ -22522,4 +22660,5 @@ } ], "log": [] -} \ No newline at end of file +} + diff --git a/examples/all-clusters-app/all-clusters-common/include/laundry-dryer-controls-delegate-impl.h b/examples/all-clusters-app/all-clusters-common/include/laundry-dryer-controls-delegate-impl.h new file mode 100644 index 00000000000000..898cf8806f4111 --- /dev/null +++ b/examples/all-clusters-app/all-clusters-common/include/laundry-dryer-controls-delegate-impl.h @@ -0,0 +1,53 @@ +/* + * + * 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. + */ + +#pragma once + +#include +#include +#include +#include +#include + +namespace chip { +namespace app { +namespace Clusters { +namespace LaundryDryerControls { + +/** + * The application delegate to statically define the options. + */ + +class LaundryDryerControlDelegate : public Delegate +{ + static const DrynessLevelEnum supportedDrynessLevelOptions[]; + static LaundryDryerControlDelegate instance; + +public: + CHIP_ERROR GetSupportedDrynessLevelAtIndex(size_t index, DrynessLevelEnum & supportedDrynessLevel); + + LaundryDryerControlDelegate() = default; + ~LaundryDryerControlDelegate() = default; + + static inline LaundryDryerControlDelegate & getLaundryDryerControlDelegate() { return instance; } +}; + +} // namespace LaundryDryerControls +} // namespace Clusters +} // namespace app +} // namespace chip diff --git a/examples/all-clusters-app/all-clusters-common/src/laundry-dryer-controls-delegate-impl.cpp b/examples/all-clusters-app/all-clusters-common/src/laundry-dryer-controls-delegate-impl.cpp new file mode 100644 index 00000000000000..d404680f2a87d2 --- /dev/null +++ b/examples/all-clusters-app/all-clusters-common/src/laundry-dryer-controls-delegate-impl.cpp @@ -0,0 +1,40 @@ +/* + * + * 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. + */ +#include +#include +#include + +using namespace chip; +using namespace chip::app::Clusters::LaundryDryerControls; + +const DrynessLevelEnum LaundryDryerControlDelegate::supportedDrynessLevelOptions[] = { DrynessLevelEnum::kLow, + DrynessLevelEnum::kNormal, + DrynessLevelEnum::kMax }; + +LaundryDryerControlDelegate LaundryDryerControlDelegate::instance; + +// TODO: Add EndpointId to the API so that different values per endpoint may be possible in some implementations. +CHIP_ERROR LaundryDryerControlDelegate::GetSupportedDrynessLevelAtIndex(size_t index, DrynessLevelEnum & supportedDrynessLevel) +{ + if (index >= ArraySize(supportedDrynessLevelOptions)) + { + return CHIP_ERROR_PROVIDER_LIST_EXHAUSTED; + } + supportedDrynessLevel = supportedDrynessLevelOptions[index]; + return CHIP_NO_ERROR; +} diff --git a/examples/all-clusters-app/esp32/main/CMakeLists.txt b/examples/all-clusters-app/esp32/main/CMakeLists.txt index e8851aa5a4d3d5..d1b795e47d1e99 100644 --- a/examples/all-clusters-app/esp32/main/CMakeLists.txt +++ b/examples/all-clusters-app/esp32/main/CMakeLists.txt @@ -86,7 +86,8 @@ set(SRC_DIRS_LIST "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/temperature-control-server" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/time-synchronization-server" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/dishwasher-alarm-server" - "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/laundry-washer-controls-server" + "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/laundry-washer-controls-server" + "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/laundry-dryer-controls-server" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/all-clusters-app/all-clusters-common/src" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/electrical-energy-measurement-server" ) diff --git a/examples/all-clusters-app/esp32/main/main.cpp b/examples/all-clusters-app/esp32/main/main.cpp index 9972f95b95f546..4893cf1b8f1475 100644 --- a/examples/all-clusters-app/esp32/main/main.cpp +++ b/examples/all-clusters-app/esp32/main/main.cpp @@ -133,6 +133,24 @@ static void InitServer(intptr_t context) app::Clusters::TemperatureControl::SetInstance(&sAppSupportedTemperatureLevelsDelegate); } +// #include +#include +#include + +using namespace chip::app::Clusters::LaundryWasherControls; +void emberAfLaundryWasherControlsClusterInitCallback(EndpointId endpoint) +{ + LaundryWasherControlsServer::SetDefaultDelegate(1, &LaundryWasherControlDelegate::getLaundryWasherControlDelegate()); +} + +#include +#include +using namespace chip::app::Clusters::LaundryDryerControls; +void emberAfLaundryDryerControlsClusterInitCallback(EndpointId endpoint) +{ + LaundryDryerControlsServer::SetDefaultDelegate(endpoint, &LaundryDryerControlDelegate::getLaundryDryerControlDelegate()); +} + extern "C" void app_main() { // Initialize the ESP NVS layer. diff --git a/examples/all-clusters-app/linux/BUILD.gn b/examples/all-clusters-app/linux/BUILD.gn index af9414529ca76e..6feba8becbe31b 100644 --- a/examples/all-clusters-app/linux/BUILD.gn +++ b/examples/all-clusters-app/linux/BUILD.gn @@ -29,6 +29,7 @@ source_set("chip-all-clusters-common") { "${chip_root}/examples/all-clusters-app/all-clusters-common/src/dishwasher-mode.cpp", "${chip_root}/examples/all-clusters-app/all-clusters-common/src/energy-evse-stub.cpp", "${chip_root}/examples/all-clusters-app/all-clusters-common/src/fan-stub.cpp", + "${chip_root}/examples/all-clusters-app/all-clusters-common/src/laundry-dryer-controls-delegate-impl.cpp", "${chip_root}/examples/all-clusters-app/all-clusters-common/src/laundry-washer-controls-delegate-impl.cpp", "${chip_root}/examples/all-clusters-app/all-clusters-common/src/laundry-washer-mode.cpp", "${chip_root}/examples/all-clusters-app/all-clusters-common/src/microwave-oven-mode.cpp", diff --git a/examples/all-clusters-app/linux/main-common.cpp b/examples/all-clusters-app/linux/main-common.cpp index f53b6aa68c8057..bf47dae4646b4b 100644 --- a/examples/all-clusters-app/linux/main-common.cpp +++ b/examples/all-clusters-app/linux/main-common.cpp @@ -21,6 +21,7 @@ #include "air-quality-instance.h" #include "dishwasher-mode.h" #include "include/tv-callbacks.h" +#include "laundry-dryer-controls-delegate-impl.h" #include "laundry-washer-controls-delegate-impl.h" #include "laundry-washer-mode.h" #include "microwave-oven-mode.h" @@ -33,6 +34,7 @@ #include #include #include +#include #include #include #include @@ -248,6 +250,12 @@ void emberAfLaundryWasherControlsClusterInitCallback(EndpointId endpoint) LaundryWasherControlsServer::SetDefaultDelegate(endpoint, &LaundryWasherControlDelegate::getLaundryWasherControlDelegate()); } +using namespace chip::app::Clusters::LaundryDryerControls; +void emberAfLaundryDryerControlsClusterInitCallback(EndpointId endpoint) +{ + LaundryDryerControlsServer::SetDefaultDelegate(endpoint, &LaundryDryerControlDelegate::getLaundryDryerControlDelegate()); +} + void emberAfLowPowerClusterInitCallback(EndpointId endpoint) { ChipLogProgress(NotSpecified, "Setting LowPower default delegate to global manager"); diff --git a/src/app/clusters/laundry-dryer-controls-server/laundry-dryer-controls-delegate.h b/src/app/clusters/laundry-dryer-controls-server/laundry-dryer-controls-delegate.h new file mode 100644 index 00000000000000..253ad62ca549fe --- /dev/null +++ b/src/app/clusters/laundry-dryer-controls-server/laundry-dryer-controls-delegate.h @@ -0,0 +1,49 @@ +/* + * + * 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. + */ + +#pragma once +#include +#include + +namespace chip { +namespace app { +namespace Clusters { +namespace LaundryDryerControls { + +/** @brief + * Defines methods for implementing application-specific logic for the laundry dryer controls cluster. + */ +class Delegate +{ +public: + Delegate() = default; + virtual ~Delegate() = default; + + /** + * Get the supported dryness value at the given index in the list. + * @param index The index of the supported dryness with 0 representing the first one. + * @param supportedDryness The supported dryness at the given index + * @return CHIP_ERROR_PROVIDER_LIST_EXHAUSTED if the index is out of range for the list of supported dryness. + */ + virtual CHIP_ERROR GetSupportedDrynessLevelAtIndex(size_t index, DrynessLevelEnum & supportedDryness) = 0; +}; + +} // namespace LaundryDryerControls +} // namespace Clusters +} // namespace app +} // namespace chip diff --git a/src/app/clusters/laundry-dryer-controls-server/laundry-dryer-controls-server.cpp b/src/app/clusters/laundry-dryer-controls-server/laundry-dryer-controls-server.cpp new file mode 100644 index 00000000000000..3f9e1646f1ec11 --- /dev/null +++ b/src/app/clusters/laundry-dryer-controls-server/laundry-dryer-controls-server.cpp @@ -0,0 +1,187 @@ +/** + * + * 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. + */ + +#include +#include +#include + +#include "laundry-dryer-controls-delegate.h" +#include "laundry-dryer-controls-server.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace chip; +using namespace chip::app; +using namespace chip::app::Clusters; +using namespace chip::app::Clusters::LaundryDryerControls; +using namespace chip::app::Clusters::LaundryDryerControls::Attributes; +using chip::Protocols::InteractionModel::Status; + +static constexpr size_t kLaundryDryerControlsDelegateTableSize = + EMBER_AF_LAUNDRY_DRYER_CONTROLS_CLUSTER_SERVER_ENDPOINT_COUNT + CHIP_DEVICE_CONFIG_DYNAMIC_ENDPOINT_COUNT; + +// ----------------------------------------------------------------------------- +// Delegate Implementation +// +namespace { +Delegate * gDelegateTable[kLaundryDryerControlsDelegateTableSize] = { nullptr }; +} + +namespace { +Delegate * GetDelegate(EndpointId endpoint) +{ + uint16_t ep = emberAfGetClusterServerEndpointIndex(endpoint, LaundryDryerControls::Id, + EMBER_AF_LAUNDRY_DRYER_CONTROLS_CLUSTER_SERVER_ENDPOINT_COUNT); + return (ep >= kLaundryDryerControlsDelegateTableSize ? nullptr : gDelegateTable[ep]); +} + +} // namespace + +LaundryDryerControlsServer LaundryDryerControlsServer::sInstance; + +/********************************************************** + * LaundryDryerControlsServer public methods + *********************************************************/ +void LaundryDryerControlsServer::SetDefaultDelegate(EndpointId endpoint, Delegate * delegate) +{ + uint16_t ep = emberAfGetClusterServerEndpointIndex(endpoint, LaundryDryerControls::Id, + EMBER_AF_LAUNDRY_DRYER_CONTROLS_CLUSTER_SERVER_ENDPOINT_COUNT); + // if endpoint is found + if (ep < kLaundryDryerControlsDelegateTableSize) + { + gDelegateTable[ep] = delegate; + } +} + +LaundryDryerControlsServer & LaundryDryerControlsServer::Instance() +{ + return sInstance; +} + +EmberAfStatus LaundryDryerControlsServer::SetSelectedDrynessLevel(EndpointId endpointId, DrynessLevelEnum newSelectedDrynessLevel) +{ + DataModel::Nullable selectedDrynessLevel; + EmberAfStatus res = SelectedDrynessLevel::Get(endpointId, selectedDrynessLevel); + + if ((res == EMBER_ZCL_STATUS_SUCCESS) && (selectedDrynessLevel != newSelectedDrynessLevel)) + { + res = SelectedDrynessLevel::Set(endpointId, newSelectedDrynessLevel); + } + + return res; +} + +EmberAfStatus LaundryDryerControlsServer::GetSelectedDrynessLevel(EndpointId endpointId, + DataModel::Nullable & selectedDrynessLevel) +{ + return SelectedDrynessLevel::Get(endpointId, selectedDrynessLevel); +} + +/********************************************************** + * LaundryDryerControlsServer private methods + *********************************************************/ +CHIP_ERROR LaundryDryerControlsServer::Read(const ConcreteReadAttributePath & aPath, AttributeValueEncoder & aEncoder) +{ + if (aPath.mClusterId != LaundryDryerControls::Id) + { + // We shouldn't have been called at all. + return CHIP_ERROR_INVALID_ARGUMENT; + } + switch (aPath.mAttributeId) + { + case Attributes::SupportedDrynessLevels::Id: + return ReadSupportedDrynessLevels(aPath, aEncoder); + default: + break; + } + return CHIP_NO_ERROR; +} + +CHIP_ERROR LaundryDryerControlsServer::ReadSupportedDrynessLevels(const ConcreteReadAttributePath & aPath, + AttributeValueEncoder & aEncoder) +{ + Delegate * delegate = GetDelegate(aPath.mEndpointId); + VerifyOrReturnError(delegate != nullptr, CHIP_ERROR_INCORRECT_STATE, ChipLogError(Zcl, "Delegate is nullptr")); + + return aEncoder.EncodeList([delegate](const auto & encoder) -> CHIP_ERROR { + for (uint8_t i = 0; true; i++) + { + DrynessLevelEnum supportedDrynessLevel; + auto err = delegate->GetSupportedDrynessLevelAtIndex(i, supportedDrynessLevel); + if (err == CHIP_ERROR_PROVIDER_LIST_EXHAUSTED) + { + return CHIP_NO_ERROR; + } + ReturnErrorOnFailure(err); + ReturnErrorOnFailure(encoder.Encode(supportedDrynessLevel)); + } + }); +} + +/********************************************************** + * Register LaundryDryerControlsServer + *********************************************************/ + +void MatterLaundryDryerControlsPluginServerInitCallback() +{ + LaundryDryerControlsServer & laundryDryerControlsServer = LaundryDryerControlsServer::Instance(); + registerAttributeAccessOverride(&laundryDryerControlsServer); +} + +Status MatterLaundryDryerControlsClusterServerPreAttributeChangedCallback(const chip::app::ConcreteAttributePath & attributePath, + EmberAfAttributeType attributeType, uint16_t size, + uint8_t * value) +{ + Delegate * delegate = GetDelegate(attributePath.mEndpointId); + VerifyOrDie((delegate != nullptr) && "Dryer Controls implementation requires a registered delegate for validation."); + switch (attributePath.mAttributeId) + { + case Attributes::SelectedDrynessLevel::Id: { + uint8_t drynessLevelIdx = 0; + while (true) + { + DrynessLevelEnum supportedDryness; + auto err = delegate->GetSupportedDrynessLevelAtIndex(drynessLevelIdx, supportedDryness); + if (err != CHIP_NO_ERROR) + { + // Can't find the attribute to be written in the supported list (CHIP_ERROR_PROVIDER_LIST_EXHAUSTED) + // Or can't get the correct supported list + return Status::InvalidInState; + } + static_assert(sizeof(DrynessLevelEnum) == sizeof(*value), "Enum size doesn't match parameter size"); + if (supportedDryness == static_cast(*value)) + { + // The written attribute is one of the supported item + return Status::Success; + } + drynessLevelIdx++; + } + } + } + return Status::Success; +} diff --git a/src/app/clusters/laundry-dryer-controls-server/laundry-dryer-controls-server.h b/src/app/clusters/laundry-dryer-controls-server/laundry-dryer-controls-server.h new file mode 100644 index 00000000000000..454c029e21fc52 --- /dev/null +++ b/src/app/clusters/laundry-dryer-controls-server/laundry-dryer-controls-server.h @@ -0,0 +1,62 @@ +/** + * + * 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. + */ + +#pragma once + +#include "laundry-dryer-controls-delegate.h" +#include +#include +#include + +namespace chip { +namespace app { +namespace Clusters { +namespace LaundryDryerControls { + +/** + * @brief LaundryDryerControls Server Plugin class + */ +class LaundryDryerControlsServer : public AttributeAccessInterface +{ +public: + LaundryDryerControlsServer() : AttributeAccessInterface(Optional::Missing(), LaundryDryerControls::Id) {} + static LaundryDryerControlsServer & Instance(); + + /** + * Set the default delegate of laundry dryer server at endpoint x + * @param endpoint ID of the endpoint + * @param delegate The default delegate at the endpoint + */ + static void SetDefaultDelegate(EndpointId endpoint, Delegate * delegate); + + /** + * API to set/get the SelectedDrynessLevel attribute + */ + EmberAfStatus SetSelectedDrynessLevel(EndpointId endpointId, DrynessLevelEnum newSelectedDrynessLevel); + EmberAfStatus GetSelectedDrynessLevel(EndpointId endpointId, DataModel::Nullable & selectedDrynessLevel); + +private: + CHIP_ERROR Read(const ConcreteReadAttributePath & aPath, AttributeValueEncoder & aEncoder) override; + CHIP_ERROR ReadSupportedDrynessLevels(const ConcreteReadAttributePath & aPath, AttributeValueEncoder & aEncoder); + + static LaundryDryerControlsServer sInstance; +}; + +} // namespace LaundryDryerControls +} // namespace Clusters +} // namespace app +} // namespace chip diff --git a/src/app/common/templates/config-data.yaml b/src/app/common/templates/config-data.yaml index 5586614c6d7186..8c8300d9c20e4a 100644 --- a/src/app/common/templates/config-data.yaml +++ b/src/app/common/templates/config-data.yaml @@ -77,3 +77,4 @@ ClustersWithPreAttributeChangeFunctions: - Fan Control - Thermostat - Laundry Washer Controls + - Laundry Dryer Controls diff --git a/src/app/zap_cluster_list.json b/src/app/zap_cluster_list.json index 15df401e161d4f..a7f1c8e58dca6f 100644 --- a/src/app/zap_cluster_list.json +++ b/src/app/zap_cluster_list.json @@ -288,6 +288,7 @@ "VALVE_CONFIGURATION_AND_CONTROL_CLUSTER": [], "WAKE_ON_LAN_CLUSTER": ["wake-on-lan-server"], "LAUNDRY_WASHER_CONTROLS_CLUSTER": ["laundry-washer-controls-server"], + "LAUNDRY_DRYER_CONTROLS_CLUSTER": ["laundry-dryer-controls-server"], "WIFI_NETWORK_DIAGNOSTICS_CLUSTER": ["wifi-network-diagnostics-server"], "WINDOW_COVERING_CLUSTER": ["window-covering-server"], "ZLL_COMMISSIONING_CLUSTER": [] From 70ac7e07a0a1fbecee2bef2dfc2af532d4678167 Mon Sep 17 00:00:00 2001 From: eahove Date: Fri, 22 Dec 2023 09:07:13 -0600 Subject: [PATCH 25/29] added the descriptor (#31143) --- src/app/zap-templates/zcl/data-model/chip/matter-devices.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/src/app/zap-templates/zcl/data-model/chip/matter-devices.xml b/src/app/zap-templates/zcl/data-model/chip/matter-devices.xml index f76a7bb4be5fba..85805353abb9ca 100644 --- a/src/app/zap-templates/zcl/data-model/chip/matter-devices.xml +++ b/src/app/zap-templates/zcl/data-model/chip/matter-devices.xml @@ -1979,6 +1979,7 @@ limitations under the License. Endpoint + From adf6ce5290fcde7f129214985b35741411843c03 Mon Sep 17 00:00:00 2001 From: Boris Zbarsky Date: Fri, 22 Dec 2023 13:04:25 -0500 Subject: [PATCH 26/29] Mark some RVC bits that people are trying to remove/deprecate provisional on Darwin. (#31170) See https://github.com/CHIP-Specifications/connectedhomeip-spec/pull/8637 --- .../CHIP/templates/availability.yaml | 22 ++++++++++------- .../CHIP/zap-generated/MTRBaseClusters.h | 24 +++++++++---------- .../CHIP/zap-generated/MTRClusterConstants.h | 4 ++-- .../CHIP/zap-generated/MTRClusters.h | 12 +++++----- .../zap-generated/cluster/Commands.h | 12 ++++++++++ 5 files changed, 46 insertions(+), 28 deletions(-) diff --git a/src/darwin/Framework/CHIP/templates/availability.yaml b/src/darwin/Framework/CHIP/templates/availability.yaml index a546dfed9c956d..f131b3cd09a06f 100644 --- a/src/darwin/Framework/CHIP/templates/availability.yaml +++ b/src/darwin/Framework/CHIP/templates/availability.yaml @@ -7491,6 +7491,12 @@ FanControl: # New Fan Control bits not stable yet. - AirflowDirection + RVCCleanMode: + # People are trying to deprecate this one + - OnMode + RVCRunMode: + # People are trying to deprecate this one + - OnMode commands: FanControl: # Not stable yet @@ -7543,6 +7549,14 @@ Feature: - Step - AirflowDirection + RVCRunMode: + Feature: + # People are trying to deprecate this one + - OnOff + RVCCleanMode: + Feature: + # People are trying to deprecate this one + - OnOff global attributes: - EventList # Once we actually unmark TimeSynchronization as provisional, all these bits except EventList should go away too, and we should instead @@ -7801,7 +7815,6 @@ RVCRunMode: - SupportedModes - CurrentMode - - OnMode - GeneratedCommandList - AcceptedCommandList - AttributeList @@ -7810,7 +7823,6 @@ RVCCleanMode: - SupportedModes - CurrentMode - - OnMode - GeneratedCommandList - AcceptedCommandList - AttributeList @@ -8186,12 +8198,6 @@ OptionsBitmap: - ExecuteIfOff - CoupleColorTempToLevel - RVCRunMode: - Feature: - - OnOff - RVCCleanMode: - Feature: - - OnOff Thermostat: ScheduleDayOfWeekBitmap: - Sunday diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.h b/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.h index 046e4442fa8725..8f1afd460544f8 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.h +++ b/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.h @@ -5588,13 +5588,13 @@ MTR_NEWLY_AVAILABLE reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler MTR_NEWLY_AVAILABLE; + (void)readAttributeCurrentModeWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_NEWLY_AVAILABLE; -- (void)readAttributeOnModeWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_NEWLY_AVAILABLE; -- (void)writeAttributeOnModeWithValue:(NSNumber * _Nullable)value completion:(MTRStatusCompletion)completion MTR_NEWLY_AVAILABLE; -- (void)writeAttributeOnModeWithValue:(NSNumber * _Nullable)value params:(MTRWriteParams * _Nullable)params completion:(MTRStatusCompletion)completion MTR_NEWLY_AVAILABLE; +- (void)readAttributeOnModeWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)writeAttributeOnModeWithValue:(NSNumber * _Nullable)value completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; +- (void)writeAttributeOnModeWithValue:(NSNumber * _Nullable)value params:(MTRWriteParams * _Nullable)params completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; - (void)subscribeAttributeOnModeWithParams:(MTRSubscribeParams *)params subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler MTR_NEWLY_AVAILABLE; -+ (void)readAttributeOnModeWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_NEWLY_AVAILABLE; + reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; ++ (void)readAttributeOnModeWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - (void)readAttributeGeneratedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_NEWLY_AVAILABLE; - (void)subscribeAttributeGeneratedCommandListWithParams:(MTRSubscribeParams *)params @@ -5677,13 +5677,13 @@ MTR_NEWLY_AVAILABLE reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler MTR_NEWLY_AVAILABLE; + (void)readAttributeCurrentModeWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_NEWLY_AVAILABLE; -- (void)readAttributeOnModeWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_NEWLY_AVAILABLE; -- (void)writeAttributeOnModeWithValue:(NSNumber * _Nullable)value completion:(MTRStatusCompletion)completion MTR_NEWLY_AVAILABLE; -- (void)writeAttributeOnModeWithValue:(NSNumber * _Nullable)value params:(MTRWriteParams * _Nullable)params completion:(MTRStatusCompletion)completion MTR_NEWLY_AVAILABLE; +- (void)readAttributeOnModeWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)writeAttributeOnModeWithValue:(NSNumber * _Nullable)value completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; +- (void)writeAttributeOnModeWithValue:(NSNumber * _Nullable)value params:(MTRWriteParams * _Nullable)params completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; - (void)subscribeAttributeOnModeWithParams:(MTRSubscribeParams *)params subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler MTR_NEWLY_AVAILABLE; -+ (void)readAttributeOnModeWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_NEWLY_AVAILABLE; + reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; ++ (void)readAttributeOnModeWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - (void)readAttributeGeneratedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_NEWLY_AVAILABLE; - (void)subscribeAttributeGeneratedCommandListWithParams:(MTRSubscribeParams *)params @@ -16757,7 +16757,7 @@ typedef NS_ENUM(uint8_t, MTRRVCRunModeStatusCode) { } MTR_NEWLY_AVAILABLE; typedef NS_OPTIONS(uint32_t, MTRRVCRunModeFeature) { - MTRRVCRunModeFeatureOnOff MTR_NEWLY_AVAILABLE = 0x1, + MTRRVCRunModeFeatureOnOff MTR_PROVISIONALLY_AVAILABLE = 0x1, } MTR_NEWLY_AVAILABLE; typedef NS_ENUM(uint16_t, MTRRVCCleanModeModeTag) { @@ -16771,7 +16771,7 @@ typedef NS_ENUM(uint8_t, MTRRVCCleanModeStatusCode) { } MTR_NEWLY_AVAILABLE; typedef NS_OPTIONS(uint32_t, MTRRVCCleanModeFeature) { - MTRRVCCleanModeFeatureOnOff MTR_NEWLY_AVAILABLE = 0x1, + MTRRVCCleanModeFeatureOnOff MTR_PROVISIONALLY_AVAILABLE = 0x1, } MTR_NEWLY_AVAILABLE; typedef NS_OPTIONS(uint32_t, MTRTemperatureControlFeature) { diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRClusterConstants.h b/src/darwin/Framework/CHIP/zap-generated/MTRClusterConstants.h index e2e41259e4f052..8e221a71fa9f7a 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRClusterConstants.h +++ b/src/darwin/Framework/CHIP/zap-generated/MTRClusterConstants.h @@ -2400,7 +2400,7 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { // Cluster RVCRunMode attributes MTRAttributeIDTypeClusterRVCRunModeAttributeSupportedModesID MTR_NEWLY_AVAILABLE = 0x00000000, MTRAttributeIDTypeClusterRVCRunModeAttributeCurrentModeID MTR_NEWLY_AVAILABLE = 0x00000001, - MTRAttributeIDTypeClusterRVCRunModeAttributeOnModeID MTR_NEWLY_AVAILABLE = 0x00000003, + MTRAttributeIDTypeClusterRVCRunModeAttributeOnModeID MTR_PROVISIONALLY_AVAILABLE = 0x00000003, MTRAttributeIDTypeClusterRVCRunModeAttributeGeneratedCommandListID MTR_NEWLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, MTRAttributeIDTypeClusterRVCRunModeAttributeAcceptedCommandListID MTR_NEWLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, MTRAttributeIDTypeClusterRVCRunModeAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, @@ -2411,7 +2411,7 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { // Cluster RVCCleanMode attributes MTRAttributeIDTypeClusterRVCCleanModeAttributeSupportedModesID MTR_NEWLY_AVAILABLE = 0x00000000, MTRAttributeIDTypeClusterRVCCleanModeAttributeCurrentModeID MTR_NEWLY_AVAILABLE = 0x00000001, - MTRAttributeIDTypeClusterRVCCleanModeAttributeOnModeID MTR_NEWLY_AVAILABLE = 0x00000003, + MTRAttributeIDTypeClusterRVCCleanModeAttributeOnModeID MTR_PROVISIONALLY_AVAILABLE = 0x00000003, MTRAttributeIDTypeClusterRVCCleanModeAttributeGeneratedCommandListID MTR_NEWLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, MTRAttributeIDTypeClusterRVCCleanModeAttributeAcceptedCommandListID MTR_NEWLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, MTRAttributeIDTypeClusterRVCCleanModeAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRClusters.h b/src/darwin/Framework/CHIP/zap-generated/MTRClusters.h index d9b141845086a7..9f64d2739f357a 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRClusters.h +++ b/src/darwin/Framework/CHIP/zap-generated/MTRClusters.h @@ -2619,9 +2619,9 @@ MTR_NEWLY_AVAILABLE - (NSDictionary * _Nullable)readAttributeCurrentModeWithParams:(MTRReadParams * _Nullable)params MTR_NEWLY_AVAILABLE; -- (NSDictionary * _Nullable)readAttributeOnModeWithParams:(MTRReadParams * _Nullable)params MTR_NEWLY_AVAILABLE; -- (void)writeAttributeOnModeWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs MTR_NEWLY_AVAILABLE; -- (void)writeAttributeOnModeWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs params:(MTRWriteParams * _Nullable)params MTR_NEWLY_AVAILABLE; +- (NSDictionary * _Nullable)readAttributeOnModeWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; +- (void)writeAttributeOnModeWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs MTR_PROVISIONALLY_AVAILABLE; +- (void)writeAttributeOnModeWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs params:(MTRWriteParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - (NSDictionary * _Nullable)readAttributeGeneratedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_NEWLY_AVAILABLE; @@ -2665,9 +2665,9 @@ MTR_NEWLY_AVAILABLE - (NSDictionary * _Nullable)readAttributeCurrentModeWithParams:(MTRReadParams * _Nullable)params MTR_NEWLY_AVAILABLE; -- (NSDictionary * _Nullable)readAttributeOnModeWithParams:(MTRReadParams * _Nullable)params MTR_NEWLY_AVAILABLE; -- (void)writeAttributeOnModeWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs MTR_NEWLY_AVAILABLE; -- (void)writeAttributeOnModeWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs params:(MTRWriteParams * _Nullable)params MTR_NEWLY_AVAILABLE; +- (NSDictionary * _Nullable)readAttributeOnModeWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; +- (void)writeAttributeOnModeWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs MTR_PROVISIONALLY_AVAILABLE; +- (void)writeAttributeOnModeWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs params:(MTRWriteParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - (NSDictionary * _Nullable)readAttributeGeneratedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_NEWLY_AVAILABLE; diff --git a/zzz_generated/darwin-framework-tool/zap-generated/cluster/Commands.h b/zzz_generated/darwin-framework-tool/zap-generated/cluster/Commands.h index 049ecbb65d29d5..61c9dc61e9bd56 100644 --- a/zzz_generated/darwin-framework-tool/zap-generated/cluster/Commands.h +++ b/zzz_generated/darwin-framework-tool/zap-generated/cluster/Commands.h @@ -59025,6 +59025,8 @@ class SubscribeAttributeRvcRunModeCurrentMode : public SubscribeAttribute { } }; +#if MTR_ENABLE_PROVISIONAL + /* * Attribute OnMode */ @@ -59151,6 +59153,8 @@ class SubscribeAttributeRvcRunModeOnMode : public SubscribeAttribute { } }; +#endif // MTR_ENABLE_PROVISIONAL + /* * Attribute GeneratedCommandList */ @@ -59884,6 +59888,8 @@ class SubscribeAttributeRvcCleanModeCurrentMode : public SubscribeAttribute { } }; +#if MTR_ENABLE_PROVISIONAL + /* * Attribute OnMode */ @@ -60010,6 +60016,8 @@ class SubscribeAttributeRvcCleanModeOnMode : public SubscribeAttribute { } }; +#endif // MTR_ENABLE_PROVISIONAL + /* * Attribute GeneratedCommandList */ @@ -176701,9 +176709,11 @@ void registerClusterRvcRunMode(Commands & commands) make_unique(), // make_unique(), // make_unique(), // +#if MTR_ENABLE_PROVISIONAL make_unique(), // make_unique(), // make_unique(), // +#endif // MTR_ENABLE_PROVISIONAL make_unique(), // make_unique(), // make_unique(), // @@ -176738,9 +176748,11 @@ void registerClusterRvcCleanMode(Commands & commands) make_unique(), // make_unique(), // make_unique(), // +#if MTR_ENABLE_PROVISIONAL make_unique(), // make_unique(), // make_unique(), // +#endif // MTR_ENABLE_PROVISIONAL make_unique(), // make_unique(), // make_unique(), // From 0aa3a0c272b33ea694d618c56cafaa1ba7a1ad6d Mon Sep 17 00:00:00 2001 From: Hyukjin Kwon Date: Sat, 23 Dec 2023 03:08:46 +0900 Subject: [PATCH 27/29] Minor typo fixes in README.md (#31167) --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 72d4337af2061a..1dad5ef6fe4d4f 100644 --- a/README.md +++ b/README.md @@ -210,18 +210,18 @@ The Matter repository is structured as follows: | credentials | Development and test credentials | | docs | Documentation, including guides. Visit the [Matter SDK documentation page](https://project-chip.github.io/connectedhomeip-doc/index.html) to read it. | | examples | Example firmware applications that demonstrate use of Matter | -| integrations | 3rd Party integrations | +| integrations | 3rd party integrations | | scripts | Scripts needed to work with the Matter repository | | src | Implementation of Matter | | third_party | 3rd party code used by Matter | -| zzz_generated | zap generated template code - Revolving around cluster information | -| BUILD.gn | Build file for the gn build system | +| zzz_generated | ZAP generated template code - Revolving around cluster information | +| BUILD.gn | Build file for the GN build system | | CODE_OF_CONDUCT.md | Code of conduct for Matter and contribution to it | | CONTRIBUTING.md | Guidelines for contributing to Matter | | LICENSE | Matter license file | | REVIEWERS.md | PR reviewers | | gn_build.sh | Build script for specific projects such as Android, EFR32, etc. | -| README.md | This File | +| README.md | This file | # License From 6484d4de0adad9c7605b9f1d9ae58ba69814dc3e Mon Sep 17 00:00:00 2001 From: joonhaengHeo <85541460+joonhaengHeo@users.noreply.github.com> Date: Sat, 23 Dec 2023 03:20:19 +0900 Subject: [PATCH 28/29] [Android] Implement for supporting ICD device (#31055) * Implement for supporting ICD device in Android Controller * Add exception TooManyFunctions * Restyled by google-java-format * Restyled by clang-format * Add comment * Modify typo, use static_cast * Modify comments * Add default parameter for ICD * Add java test for ICD * Remove 'p' * Restyled by google-java-format * Update comment * Restyled by google-java-format --------- Co-authored-by: Restyled.io --- .github/workflows/java-tests.yaml | 12 ++ .../chiptool/GenericChipDeviceListener.kt | 8 + .../DeviceProvisioningFragment.kt | 12 ++ .../commands/pairing/PairingCommand.kt | 14 ++ .../commands/pairing/PairingCommand.kt | 11 ++ kotlin-detect-config.yaml | 1 + .../java/AndroidDeviceControllerWrapper.cpp | 85 ++++++++++ .../java/AndroidDeviceControllerWrapper.h | 8 + src/controller/java/BUILD.gn | 1 + .../java/CHIPDeviceController-JNI.cpp | 61 ++++++- .../ChipDeviceController.java | 149 ++++++++++++++++-- .../devicecontroller/ICDRegistrationInfo.java | 88 +++++++++++ .../controller/CompletionListenerAdapter.kt | 5 + .../src/matter/controller/MatterController.kt | 9 ++ 14 files changed, 452 insertions(+), 12 deletions(-) create mode 100644 src/controller/java/src/chip/devicecontroller/ICDRegistrationInfo.java diff --git a/.github/workflows/java-tests.yaml b/.github/workflows/java-tests.yaml index 9e800ba2e7ef99..72df162e06b3b9 100644 --- a/.github/workflows/java-tests.yaml +++ b/.github/workflows/java-tests.yaml @@ -90,6 +90,7 @@ jobs: "./scripts/build/build_examples.py \ --target linux-x64-all-clusters-ipv6only-no-ble-no-wifi-tsan-clang-test \ --target linux-x64-java-matter-controller \ + --target linux-x64-lit-icd-ipv6only \ build \ " - name: Build Kotlin Matter Controller @@ -210,6 +211,17 @@ jobs: --tool-args "code --nodeid 1 --setup-payload 34970112332 --discover-once 1 --use-only-onnetwork-discovery 0 -t 1000" \ --factoryreset \ ' + - name: Run Pairing ICD Onnetwork Test + run: | + scripts/run_in_python_env.sh out/venv \ + './scripts/tests/run_java_test.py \ + --app out/linux-x64-lit-icd-ipv6only/lit-icd-app \ + --app-args "--discriminator 3840 --interface-id -1" \ + --tool-path out/linux-x64-java-matter-controller \ + --tool-cluster "pairing" \ + --tool-args "onnetwork-long --nodeid 1 --setup-pin-code 20202021 --discriminator 3840 -t 1000" \ + --factoryreset \ + ' - name: Run Pairing Onnetwork Test run: | scripts/run_in_python_env.sh out/venv \ diff --git a/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/GenericChipDeviceListener.kt b/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/GenericChipDeviceListener.kt index 1d62115547e305..12e17998fa7c15 100644 --- a/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/GenericChipDeviceListener.kt +++ b/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/GenericChipDeviceListener.kt @@ -51,4 +51,12 @@ open class GenericChipDeviceListener : ChipDeviceController.CompletionListener { override fun onOpCSRGenerationComplete(csr: ByteArray) { // No op } + + override fun onICDRegistrationInfoRequired() { + // No op + } + + override fun onICDRegistrationComplete(icdNodeId: Long, icdCounter: Long) { + // No op + } } diff --git a/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/provisioning/DeviceProvisioningFragment.kt b/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/provisioning/DeviceProvisioningFragment.kt index 999bc6bc1b5513..16a411bc5eba05 100644 --- a/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/provisioning/DeviceProvisioningFragment.kt +++ b/examples/android/CHIPTool/app/src/main/java/com/google/chip/chiptool/provisioning/DeviceProvisioningFragment.kt @@ -32,6 +32,7 @@ import androidx.lifecycle.lifecycleScope import chip.devicecontroller.AttestationInfo import chip.devicecontroller.ChipDeviceController import chip.devicecontroller.DeviceAttestationDelegate +import chip.devicecontroller.ICDRegistrationInfo import chip.devicecontroller.NetworkCredentials import com.google.chip.chiptool.ChipClient import com.google.chip.chiptool.GenericChipDeviceListener @@ -284,6 +285,17 @@ class DeviceProvisioningFragment : Fragment() { override fun onError(error: Throwable?) { Log.d(TAG, "onError: $error") } + + override fun onICDRegistrationInfoRequired() { + Log.d(TAG, "onICDRegistrationInfoRequired") + deviceController.updateCommissioningICDRegistrationInfo( + ICDRegistrationInfo.newBuilder().build() + ) + } + + override fun onICDRegistrationComplete(icdNodeId: Long, icdCounter: Long) { + Log.d(TAG, "onICDRegistrationComplete - icdNodeId : $icdNodeId, icdCounter : $icdCounter") + } } /** Callback from [DeviceProvisioningFragment] notifying any registered listeners. */ diff --git a/examples/java-matter-controller/java/src/com/matter/controller/commands/pairing/PairingCommand.kt b/examples/java-matter-controller/java/src/com/matter/controller/commands/pairing/PairingCommand.kt index 0fc62cae9187db..572b309f02b74b 100644 --- a/examples/java-matter-controller/java/src/com/matter/controller/commands/pairing/PairingCommand.kt +++ b/examples/java-matter-controller/java/src/com/matter/controller/commands/pairing/PairingCommand.kt @@ -18,6 +18,7 @@ package com.matter.controller.commands.pairing import chip.devicecontroller.ChipDeviceController +import chip.devicecontroller.ICDRegistrationInfo import chip.devicecontroller.NetworkCredentials import com.matter.controller.commands.common.CredentialsIssuer import com.matter.controller.commands.common.IPAddress @@ -178,6 +179,19 @@ abstract class PairingCommand( } } + override fun onICDRegistrationInfoRequired() { + logger.log(Level.INFO, "onICDRegistrationInfoRequired") + currentCommissioner() + .updateCommissioningICDRegistrationInfo(ICDRegistrationInfo.newBuilder().build()) + } + + override fun onICDRegistrationComplete(icdNodeId: Long, icdCounter: Long) { + logger.log( + Level.INFO, + "onICDRegistrationComplete with icdNodeId: $icdNodeId, icdCounter: $icdCounter" + ) + } + fun getNodeId(): Long { return nodeId.get() } diff --git a/examples/kotlin-matter-controller/java/src/com/matter/controller/commands/pairing/PairingCommand.kt b/examples/kotlin-matter-controller/java/src/com/matter/controller/commands/pairing/PairingCommand.kt index 96b856568ccbc5..0e84ff7ceabf41 100644 --- a/examples/kotlin-matter-controller/java/src/com/matter/controller/commands/pairing/PairingCommand.kt +++ b/examples/kotlin-matter-controller/java/src/com/matter/controller/commands/pairing/PairingCommand.kt @@ -173,6 +173,17 @@ abstract class PairingCommand( } } + override fun onICDRegistrationInfoRequired() { + logger.log(Level.INFO, "onICDRegistrationInfoRequired") + } + + override fun onICDRegistrationComplete(icdNodeId: Long, icdCounter: Long) { + logger.log( + Level.INFO, + "onICDRegistrationComplete with icdNodeId: $icdNodeId, icdCounter: $icdCounter" + ) + } + fun getNodeId(): Long { return nodeId.get() } diff --git a/kotlin-detect-config.yaml b/kotlin-detect-config.yaml index 5dcc9f99a6b3cd..4dee3c56abb918 100644 --- a/kotlin-detect-config.yaml +++ b/kotlin-detect-config.yaml @@ -300,6 +300,7 @@ complexity: - "**/src/controller/java/src/matter/tlv/TlvWriter.kt" - "**/src/controller/java/src/matter/controller/MatterControllerImpl.kt" - "**/src/controller/java/src/matter/controller/CompletionListenerAdapter.kt" + - "**/src/controller/java/src/matter/controller/MatterController.kt" - "**/src/controller/java/tests/matter/jsontlv/JsonToTlvToJsonTest.kt" - "**/src/controller/java/tests/matter/onboardingpayload/ManualCodeTest.kt" - "**/src/controller/java/tests/matter/onboardingpayload/QRCodeTest.kt" diff --git a/src/controller/java/AndroidDeviceControllerWrapper.cpp b/src/controller/java/AndroidDeviceControllerWrapper.cpp index 1a601ba8504dbc..e1579009f74175 100644 --- a/src/controller/java/AndroidDeviceControllerWrapper.cpp +++ b/src/controller/java/AndroidDeviceControllerWrapper.cpp @@ -444,6 +444,66 @@ CHIP_ERROR AndroidDeviceControllerWrapper::ApplyNetworkCredentials(chip::Control return err; } +CHIP_ERROR AndroidDeviceControllerWrapper::ApplyICDRegistrationInfo(chip::Controller::CommissioningParameters & params, + jobject icdRegistrationInfo) +{ + chip::DeviceLayer::StackUnlock unlock; + CHIP_ERROR err = CHIP_NO_ERROR; + + VerifyOrReturnError(icdRegistrationInfo != nullptr, CHIP_ERROR_INVALID_ARGUMENT); + + JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread(); + jmethodID getCheckInNodeIdMethod; + err = chip::JniReferences::GetInstance().FindMethod(env, icdRegistrationInfo, "getCheckInNodeId", "()Ljava/lang/Long;", + &getCheckInNodeIdMethod); + VerifyOrReturnError(err == CHIP_NO_ERROR, err); + jobject jCheckInNodeId = env->CallObjectMethod(icdRegistrationInfo, getCheckInNodeIdMethod); + + jmethodID getMonitoredSubjectMethod; + err = chip::JniReferences::GetInstance().FindMethod(env, icdRegistrationInfo, "getMonitoredSubject", "()Ljava/lang/Long;", + &getMonitoredSubjectMethod); + VerifyOrReturnError(err == CHIP_NO_ERROR, err); + jobject jMonitoredSubject = env->CallObjectMethod(icdRegistrationInfo, getMonitoredSubjectMethod); + + jmethodID getSymmetricKeyMethod; + err = + chip::JniReferences::GetInstance().FindMethod(env, icdRegistrationInfo, "getSymmetricKey", "()[B", &getSymmetricKeyMethod); + VerifyOrReturnError(err == CHIP_NO_ERROR, err); + jbyteArray jSymmetricKey = static_cast(env->CallObjectMethod(icdRegistrationInfo, getSymmetricKeyMethod)); + + chip::NodeId checkInNodeId = chip::kUndefinedNodeId; + if (jCheckInNodeId != nullptr) + { + checkInNodeId = static_cast(chip::JniReferences::GetInstance().LongToPrimitive(jCheckInNodeId)); + } + else + { + checkInNodeId = mController->GetNodeId(); + } + params.SetICDCheckInNodeId(checkInNodeId); + + uint64_t monitoredSubject = static_cast(checkInNodeId); + if (jMonitoredSubject != nullptr) + { + monitoredSubject = static_cast(chip::JniReferences::GetInstance().LongToPrimitive(jMonitoredSubject)); + } + params.SetICDMonitoredSubject(monitoredSubject); + + if (jSymmetricKey != nullptr) + { + JniByteArray jniSymmetricKey(env, jSymmetricKey); + VerifyOrReturnError(jniSymmetricKey.size() == sizeof(mICDSymmetricKey), CHIP_ERROR_INVALID_ARGUMENT); + memcpy(mICDSymmetricKey, jniSymmetricKey.data(), sizeof(mICDSymmetricKey)); + } + else + { + chip::Crypto::DRBG_get_bytes(mICDSymmetricKey, sizeof(mICDSymmetricKey)); + } + params.SetICDSymmetricKey(chip::ByteSpan(mICDSymmetricKey)); + + return err; +} + CHIP_ERROR AndroidDeviceControllerWrapper::UpdateCommissioningParameters(const chip::Controller::CommissioningParameters & params) { // this will wipe out any custom attestationNonce and csrNonce that was being used. @@ -814,6 +874,31 @@ void AndroidDeviceControllerWrapper::OnScanNetworksFailure(CHIP_ERROR error) CallJavaMethod("onScanNetworksFailure", static_cast(error.AsInteger())); } +void AndroidDeviceControllerWrapper::OnICDRegistrationInfoRequired() +{ + chip::DeviceLayer::StackUnlock unlock; + JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread(); + jmethodID onICDRegistrationInfoRequiredMethod; + CHIP_ERROR err = JniReferences::GetInstance().FindMethod(env, mJavaObjectRef, "onICDRegistrationInfoRequired", "()V", + &onICDRegistrationInfoRequiredMethod); + VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Controller, "Error finding Java method: %" CHIP_ERROR_FORMAT, err.Format())); + + env->CallVoidMethod(mJavaObjectRef, onICDRegistrationInfoRequiredMethod); +} + +void AndroidDeviceControllerWrapper::OnICDRegistrationComplete(chip::NodeId icdNodeId, uint32_t icdCounter) +{ + chip::DeviceLayer::StackUnlock unlock; + JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread(); + jmethodID onICDRegistrationCompleteMethod; + CHIP_ERROR err = JniReferences::GetInstance().FindMethod(env, mJavaObjectRef, "onICDRegistrationComplete", "(JJ)V", + &onICDRegistrationCompleteMethod); + VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Controller, "Error finding Java method: %" CHIP_ERROR_FORMAT, err.Format())); + + env->CallVoidMethod(mJavaObjectRef, onICDRegistrationCompleteMethod, static_cast(icdNodeId), + static_cast(icdCounter)); +} + CHIP_ERROR AndroidDeviceControllerWrapper::SyncGetKeyValue(const char * key, void * value, uint16_t & size) { ChipLogProgress(chipTool, "KVS: Getting key %s", StringOrNullMarker(key)); diff --git a/src/controller/java/AndroidDeviceControllerWrapper.h b/src/controller/java/AndroidDeviceControllerWrapper.h index d78d4803a697c0..6594c41fcdd66f 100644 --- a/src/controller/java/AndroidDeviceControllerWrapper.h +++ b/src/controller/java/AndroidDeviceControllerWrapper.h @@ -87,6 +87,11 @@ class AndroidDeviceControllerWrapper : public chip::Controller::DevicePairingDel */ CHIP_ERROR ApplyNetworkCredentials(chip::Controller::CommissioningParameters & params, jobject networkCredentials); + /** + * Convert ICD Registration Infomations from Java, and apply them to the commissioning parameters object. + */ + CHIP_ERROR ApplyICDRegistrationInfo(chip::Controller::CommissioningParameters & params, jobject icdRegistrationInfo); + /** * Update the CommissioningParameters used by the active device commissioner */ @@ -103,6 +108,8 @@ class AndroidDeviceControllerWrapper : public chip::Controller::DevicePairingDel void OnScanNetworksSuccess( const chip::app::Clusters::NetworkCommissioning::Commands::ScanNetworksResponse::DecodableType & dataResponse) override; void OnScanNetworksFailure(CHIP_ERROR error) override; + void OnICDRegistrationInfoRequired() override; + void OnICDRegistrationComplete(chip::NodeId icdNodeId, uint32_t icdCounter) override; // PersistentStorageDelegate implementation CHIP_ERROR SyncSetKeyValue(const char * key, const void * value, uint16_t size) override; @@ -242,6 +249,7 @@ class AndroidDeviceControllerWrapper : public chip::Controller::DevicePairingDel #if CHIP_DEVICE_CONFIG_DYNAMIC_SERVER OTAProviderDelegateBridge * mOtaProviderBridge = nullptr; #endif + uint8_t mICDSymmetricKey[chip::Crypto::kAES_CCM128_Key_Length]; AndroidDeviceControllerWrapper(ChipDeviceControllerPtr controller, #ifdef JAVA_MATTER_CONTROLLER_TEST diff --git a/src/controller/java/BUILD.gn b/src/controller/java/BUILD.gn index 1a3b05c73f7ce2..a538afefc744c5 100644 --- a/src/controller/java/BUILD.gn +++ b/src/controller/java/BUILD.gn @@ -444,6 +444,7 @@ android_library("java") { "src/chip/devicecontroller/DiscoveredDevice.java", "src/chip/devicecontroller/GetConnectedDeviceCallbackJni.java", "src/chip/devicecontroller/GroupKeySecurityPolicy.java", + "src/chip/devicecontroller/ICDRegistrationInfo.java", "src/chip/devicecontroller/InvokeCallback.java", "src/chip/devicecontroller/InvokeCallbackJni.java", "src/chip/devicecontroller/KeypairDelegate.java", diff --git a/src/controller/java/CHIPDeviceController-JNI.cpp b/src/controller/java/CHIPDeviceController-JNI.cpp index 93a4e239a9b9ae..ecbaa7fc91657a 100644 --- a/src/controller/java/CHIPDeviceController-JNI.cpp +++ b/src/controller/java/CHIPDeviceController-JNI.cpp @@ -627,7 +627,7 @@ JNI_METHOD(void, commissionDevice) JNI_METHOD(void, pairDevice) (JNIEnv * env, jobject self, jlong handle, jlong deviceId, jint connObj, jlong pinCode, jbyteArray csrNonce, - jobject networkCredentials) + jobject networkCredentials, jobject icdRegistrationInfo) { chip::DeviceLayer::StackLock lock; CHIP_ERROR err = CHIP_NO_ERROR; @@ -656,6 +656,13 @@ JNI_METHOD(void, pairDevice) JniByteArray jniCsrNonce(env, csrNonce); commissioningParams.SetCSRNonce(jniCsrNonce.byteSpan()); } + + commissioningParams.SetICDRegistrationStrategy(ICDRegistrationStrategy::kBeforeComplete); + if (icdRegistrationInfo != nullptr) + { + wrapper->ApplyICDRegistrationInfo(commissioningParams, icdRegistrationInfo); + } + if (wrapper->GetDeviceAttestationDelegateBridge() != nullptr) { commissioningParams.SetDeviceAttestationDelegate(wrapper->GetDeviceAttestationDelegateBridge()); @@ -671,7 +678,7 @@ JNI_METHOD(void, pairDevice) JNI_METHOD(void, pairDeviceWithAddress) (JNIEnv * env, jobject self, jlong handle, jlong deviceId, jstring address, jint port, jint discriminator, jlong pinCode, - jbyteArray csrNonce) + jbyteArray csrNonce, jobject icdRegistrationInfo) { chip::DeviceLayer::StackLock lock; CHIP_ERROR err = CHIP_NO_ERROR; @@ -699,6 +706,13 @@ JNI_METHOD(void, pairDeviceWithAddress) JniByteArray jniCsrNonce(env, csrNonce); commissioningParams.SetCSRNonce(jniCsrNonce.byteSpan()); } + + commissioningParams.SetICDRegistrationStrategy(ICDRegistrationStrategy::kBeforeComplete); + if (icdRegistrationInfo != nullptr) + { + wrapper->ApplyICDRegistrationInfo(commissioningParams, icdRegistrationInfo); + } + if (wrapper->GetDeviceAttestationDelegateBridge() != nullptr) { commissioningParams.SetDeviceAttestationDelegate(wrapper->GetDeviceAttestationDelegateBridge()); @@ -714,7 +728,7 @@ JNI_METHOD(void, pairDeviceWithAddress) JNI_METHOD(void, pairDeviceWithCode) (JNIEnv * env, jobject self, jlong handle, jlong deviceId, jstring setUpCode, jboolean discoverOnce, - jboolean useOnlyOnNetworkDiscovery, jbyteArray csrNonce, jobject networkCredentials) + jboolean useOnlyOnNetworkDiscovery, jbyteArray csrNonce, jobject networkCredentials, jobject icdRegistrationInfo) { chip::DeviceLayer::StackLock lock; CHIP_ERROR err = CHIP_NO_ERROR; @@ -748,6 +762,12 @@ JNI_METHOD(void, pairDeviceWithCode) wrapper->ApplyNetworkCredentials(commissioningParams, networkCredentials); } + commissioningParams.SetICDRegistrationStrategy(ICDRegistrationStrategy::kBeforeComplete); + if (icdRegistrationInfo != nullptr) + { + wrapper->ApplyICDRegistrationInfo(commissioningParams, icdRegistrationInfo); + } + if (wrapper->GetDeviceAttestationDelegateBridge() != nullptr) { commissioningParams.SetDeviceAttestationDelegate(wrapper->GetDeviceAttestationDelegateBridge()); @@ -899,6 +919,41 @@ JNI_METHOD(void, updateCommissioningNetworkCredentials) } } +JNI_METHOD(void, updateCommissioningICDRegistrationInfo) +(JNIEnv * env, jobject self, jlong handle, jobject icdRegistrationInfo) +{ + ChipLogProgress(Controller, "updateCommissioningICDRegistrationInfo() called"); + chip::DeviceLayer::StackLock lock; + AndroidDeviceControllerWrapper * wrapper = AndroidDeviceControllerWrapper::FromJNIHandle(handle); + + CommissioningParameters commissioningParams = wrapper->GetCommissioningParameters(); + CHIP_ERROR err = wrapper->ApplyICDRegistrationInfo(commissioningParams, icdRegistrationInfo); + if (err != CHIP_NO_ERROR) + { + ChipLogError(Controller, "ApplyICDRegistrationInfo failed. Err = %" CHIP_ERROR_FORMAT, err.Format()); + JniReferences::GetInstance().ThrowError(env, sChipDeviceControllerExceptionCls, err); + return; + } + err = wrapper->UpdateCommissioningParameters(commissioningParams); + if (err != CHIP_NO_ERROR) + { + ChipLogError(Controller, "UpdateCommissioningParameters failed. Err = %" CHIP_ERROR_FORMAT, err.Format()); + JniReferences::GetInstance().ThrowError(env, sChipDeviceControllerExceptionCls, err); + return; + } + + // Only invoke ICDRegistrationInfoReady when called in ICDRegistartionInfo stage. + if (wrapper->Controller()->GetCommissioningStage() == CommissioningStage::kICDGetRegistrationInfo) + { + err = wrapper->Controller()->ICDRegistrationInfoReady(); + if (err != CHIP_NO_ERROR) + { + ChipLogError(Controller, "ICDRegistrationInfoReady failed. Err = %" CHIP_ERROR_FORMAT, err.Format()); + JniReferences::GetInstance().ThrowError(env, sChipDeviceControllerExceptionCls, err); + } + } +} + jint GetCalendarFieldID(JNIEnv * env, const char * method) { jclass calendarCls = env->FindClass("java/util/Calendar"); diff --git a/src/controller/java/src/chip/devicecontroller/ChipDeviceController.java b/src/controller/java/src/chip/devicecontroller/ChipDeviceController.java index 846ed32a84c6b1..ba3a7091e26e5f 100644 --- a/src/controller/java/src/chip/devicecontroller/ChipDeviceController.java +++ b/src/controller/java/src/chip/devicecontroller/ChipDeviceController.java @@ -141,7 +141,28 @@ public void pairDevice( long deviceId, long setupPincode, NetworkCredentials networkCredentials) { - pairDevice(bleServer, connId, deviceId, setupPincode, null, networkCredentials); + pairDevice(bleServer, connId, deviceId, setupPincode, null, networkCredentials, null); + } + + public void pairDevice( + BluetoothGatt bleServer, + int connId, + long deviceId, + long setupPincode, + NetworkCredentials networkCredentials, + ICDRegistrationInfo registrationInfo) { + pairDevice( + bleServer, connId, deviceId, setupPincode, null, networkCredentials, registrationInfo); + } + + public void pairDevice( + BluetoothGatt bleServer, + int connId, + long deviceId, + long setupPincode, + @Nullable byte[] csrNonce, + NetworkCredentials networkCredentials) { + pairDevice(bleServer, connId, deviceId, setupPincode, csrNonce, networkCredentials, null); } /** @@ -153,6 +174,11 @@ public void pairDevice( * @param setupPincode the pincode for the device * @param csrNonce the 32-byte CSR nonce to use, or null if we want to use an internally randomly * generated CSR nonce. + * @param networkCredentials the credentials (Wi-Fi or Thread) to be provisioned + * @param icdRegistrationInfo the informations for ICD registration. For detailed information + * {@link ICDRegistrationInfo}. If this value is null when commissioning an ICD device, {@link + * CompletionListener.onICDRegistrationInfoRequired} is called to request the + * ICDRegistrationInfo value. */ public void pairDevice( BluetoothGatt bleServer, @@ -160,7 +186,8 @@ public void pairDevice( long deviceId, long setupPincode, @Nullable byte[] csrNonce, - NetworkCredentials networkCredentials) { + NetworkCredentials networkCredentials, + @Nullable ICDRegistrationInfo icdRegistrationInfo) { if (connectionId == 0) { connectionId = connId; @@ -173,7 +200,13 @@ public void pairDevice( Log.d(TAG, "Bluetooth connection added with ID: " + connectionId); Log.d(TAG, "Pairing device with ID: " + deviceId); pairDevice( - deviceControllerPtr, deviceId, connectionId, setupPincode, csrNonce, networkCredentials); + deviceControllerPtr, + deviceId, + connectionId, + setupPincode, + csrNonce, + networkCredentials, + icdRegistrationInfo); } else { Log.e(TAG, "Bluetooth connection already in use."); completionListener.onError(new Exception("Bluetooth connection already in use.")); @@ -188,7 +221,59 @@ public void pairDeviceWithAddress( long pinCode, @Nullable byte[] csrNonce) { pairDeviceWithAddress( - deviceControllerPtr, deviceId, address, port, discriminator, pinCode, csrNonce); + deviceControllerPtr, deviceId, address, port, discriminator, pinCode, csrNonce, null); + } + + /** + * Pair a device connected using IP Address. + * + * @param deviceId the node ID to assign to the device + * @param address IP Address of the connecting device + * @param port the port of the connecting device + * @param discriminator the discriminator for connecting device + * @param pinCode the pincode for connecting device + * @param csrNonce the 32-byte CSR nonce to use, or null if we want to use an internally randomly + * generated CSR nonce. + * @param icdRegistrationInfo the informations for ICD registration. For detailed information + * {@link ICDRegistrationInfo}. If this value is null when commissioning an ICD device, {@link + * CompletionListener.onICDRegistrationInfoRequired} is called to request the + * ICDRegistrationInfo value. + */ + public void pairDeviceWithAddress( + long deviceId, + String address, + int port, + int discriminator, + long pinCode, + @Nullable byte[] csrNonce, + @Nullable ICDRegistrationInfo icdRegistrationInfo) { + pairDeviceWithAddress( + deviceControllerPtr, + deviceId, + address, + port, + discriminator, + pinCode, + csrNonce, + icdRegistrationInfo); + } + + public void pairDeviceWithCode( + long deviceId, + String setupCode, + boolean discoverOnce, + boolean useOnlyOnNetworkDiscovery, + @Nullable byte[] csrNonce, + @Nullable NetworkCredentials networkCredentials) { + pairDeviceWithCode( + deviceControllerPtr, + deviceId, + setupCode, + discoverOnce, + useOnlyOnNetworkDiscovery, + csrNonce, + networkCredentials, + null); } /** @@ -202,6 +287,10 @@ public void pairDeviceWithAddress( * @param csrNonce the 32-byte CSR nonce to use, or null if we want to use an internally randomly * generated CSR nonce. * @param networkCredentials the credentials (Wi-Fi or Thread) to be provisioned + * @param icdRegistrationInfo the informations for ICD registration. For detailed information + * {@link ICDRegistrationInfo}. If this value is null when commissioning an ICD device, {@link + * CompletionListener.onICDRegistrationInfoRequired} is called to request the + * ICDRegistrationInfo value. */ public void pairDeviceWithCode( long deviceId, @@ -209,7 +298,8 @@ public void pairDeviceWithCode( boolean discoverOnce, boolean useOnlyOnNetworkDiscovery, @Nullable byte[] csrNonce, - @Nullable NetworkCredentials networkCredentials) { + @Nullable NetworkCredentials networkCredentials, + @Nullable ICDRegistrationInfo icdRegistrationInfo) { pairDeviceWithCode( deviceControllerPtr, deviceId, @@ -217,7 +307,8 @@ public void pairDeviceWithCode( discoverOnce, useOnlyOnNetworkDiscovery, csrNonce, - networkCredentials); + networkCredentials, + icdRegistrationInfo); } public void establishPaseConnection(long deviceId, int connId, long setupPincode) { @@ -325,6 +416,19 @@ public void updateCommissioningNetworkCredentials(NetworkCredentials networkCred updateCommissioningNetworkCredentials(deviceControllerPtr, networkCredentials); } + /** + * Update the ICD registration information held by the commissioner for the current commissioning + * session. + * + *

Its expected that this method will be called in response the onICDRegistrationInfoRequired + * callbacks. + * + * @param ICDRegistrationInfo the ICD registration information to use in commissioning + */ + public void updateCommissioningICDRegistrationInfo(ICDRegistrationInfo icdRegistrationInfo) { + updateCommissioningICDRegistrationInfo(deviceControllerPtr, icdRegistrationInfo); + } + public void unpairDevice(long deviceId) { unpairDevice(deviceControllerPtr, deviceId); } @@ -496,6 +600,18 @@ public void onError(Throwable error) { completionListener.onError(error); } + public void onICDRegistrationInfoRequired() { + if (completionListener != null) { + completionListener.onICDRegistrationInfoRequired(); + } + } + + public void onICDRegistrationComplete(long icdNodeId, long icdCounter) { + if (completionListener != null) { + completionListener.onICDRegistrationComplete(icdNodeId, icdCounter); + } + } + public void onNOCChainGenerationNeeded(CSRInfo csrInfo, AttestationInfo attestationInfo) { if (nocChainIssuer != null) { nocChainIssuer.onNOCChainGenerationNeeded(csrInfo, attestationInfo); @@ -1248,7 +1364,8 @@ private native void pairDevice( int connectionId, long pinCode, @Nullable byte[] csrNonce, - NetworkCredentials networkCredentials); + NetworkCredentials networkCredentials, + @Nullable ICDRegistrationInfo icdRegistrationInfo); private native void pairDeviceWithAddress( long deviceControllerPtr, @@ -1257,7 +1374,8 @@ private native void pairDeviceWithAddress( int port, int discriminator, long pinCode, - @Nullable byte[] csrNonce); + @Nullable byte[] csrNonce, + @Nullable ICDRegistrationInfo icdRegistrationInfo); private native void pairDeviceWithCode( long deviceControllerPtr, @@ -1266,7 +1384,8 @@ private native void pairDeviceWithCode( boolean discoverOnce, boolean useOnlyOnNetworkDiscovery, @Nullable byte[] csrNonce, - @Nullable NetworkCredentials networkCredentials); + @Nullable NetworkCredentials networkCredentials, + @Nullable ICDRegistrationInfo icdRegistrationInfo); private native void establishPaseConnection( long deviceControllerPtr, long deviceId, int connId, long setupPincode); @@ -1364,6 +1483,9 @@ private native void setUseJavaCallbackForNOCRequest( private native void updateCommissioningNetworkCredentials( long deviceControllerPtr, NetworkCredentials networkCredentials); + private native void updateCommissioningICDRegistrationInfo( + long deviceControllerPtr, ICDRegistrationInfo icdRegistrationInfo); + private native int onNOCChainGeneration(long deviceControllerPtr, ControllerParams params); private native int getFabricIndex(long deviceControllerPtr); @@ -1475,5 +1597,14 @@ void onReadCommissioningInfo( /** Notifies the Commissioner when the OpCSR for the Comissionee is generated. */ void onOpCSRGenerationComplete(byte[] csr); + + /** + * Notifies when the ICD registration information (ICD symmetric key, check-in node ID and + * monitored subject) is required. + */ + void onICDRegistrationInfoRequired(); + + /** Notifies when the registration flow for the ICD completes. */ + void onICDRegistrationComplete(long icdNodeId, long icdCounter); } } diff --git a/src/controller/java/src/chip/devicecontroller/ICDRegistrationInfo.java b/src/controller/java/src/chip/devicecontroller/ICDRegistrationInfo.java new file mode 100644 index 00000000000000..be978fae28fee6 --- /dev/null +++ b/src/controller/java/src/chip/devicecontroller/ICDRegistrationInfo.java @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2020-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 chip.devicecontroller; + +import javax.annotation.Nullable; + +/** Class for holding ICD registration infomation. */ +public class ICDRegistrationInfo { + @Nullable private final Long checkInNodeId; + @Nullable private final Long monitoredSubject; + @Nullable private final byte[] symmetricKey; + + private ICDRegistrationInfo(Builder builder) { + this.checkInNodeId = builder.checkInNodeId; + this.monitoredSubject = builder.monitoredSubject; + this.symmetricKey = builder.symmetricKey; + } + + /** Returns the check in node ID. */ + public Long getCheckInNodeId() { + return checkInNodeId; + } + + /** Returns the monitored subject of the ICD. */ + public Long getMonitoredSubject() { + return monitoredSubject; + } + + /** Returns the 16 bytes ICD symmetric key. */ + public byte[] getSymmetricKey() { + return symmetricKey; + } + + public static Builder newBuilder() { + return new Builder(); + } + + /** Builder for {@link ICDRegistrationInfo}. */ + public static class Builder { + @Nullable private Long checkInNodeId = null; + @Nullable private Long monitoredSubject = null; + @Nullable private byte[] symmetricKey = null; + + private Builder() {} + + /** The check-in node id for the ICD. If not set this value, node id of the commissioner. */ + public Builder setCheckInNodeId(long checkInNodeId) { + this.checkInNodeId = checkInNodeId; + return this; + } + + /** + * The monitored subject of the ICD. If not set this value, the node id used for + * icd-check-in-nodeid + */ + public Builder setMonitoredSubject(long monitoredSubject) { + this.monitoredSubject = monitoredSubject; + return this; + } + + /** + * The 16 bytes ICD symmetric key, If not set this value, this value will be randomly generated. + */ + public Builder setSymmetricKey(byte[] symmetricKey) { + this.symmetricKey = symmetricKey; + return this; + } + + public ICDRegistrationInfo build() { + return new ICDRegistrationInfo(this); + } + } +} diff --git a/src/controller/java/src/matter/controller/CompletionListenerAdapter.kt b/src/controller/java/src/matter/controller/CompletionListenerAdapter.kt index c1956154115d89..f536fae311edaf 100644 --- a/src/controller/java/src/matter/controller/CompletionListenerAdapter.kt +++ b/src/controller/java/src/matter/controller/CompletionListenerAdapter.kt @@ -49,6 +49,11 @@ class CompletionListenerAdapter(val listener: MatterController.CompletionListene override fun onOpCSRGenerationComplete(csr: ByteArray) = listener.onOpCSRGenerationComplete(csr) + override fun onICDRegistrationInfoRequired() = listener.onICDRegistrationInfoRequired() + + override fun onICDRegistrationComplete(icdNodeId: Long, icdCounter: Long) = + listener.onICDRegistrationComplete(icdNodeId, icdCounter) + override fun onError(error: Throwable) = listener.onError(error) override fun onCloseBleComplete() { diff --git a/src/controller/java/src/matter/controller/MatterController.kt b/src/controller/java/src/matter/controller/MatterController.kt index 5ac5a85020db98..1487446ba455f4 100644 --- a/src/controller/java/src/matter/controller/MatterController.kt +++ b/src/controller/java/src/matter/controller/MatterController.kt @@ -57,6 +57,15 @@ interface MatterController : Closeable, InteractionClient { /** Notifies the Commissioner when the OpCSR for the Comissionee is generated. */ fun onOpCSRGenerationComplete(csr: ByteArray) + + /** + * Notifies when the ICD registration information (ICD symmetric key, check-in node ID and + * monitored subject) is required. + */ + fun onICDRegistrationInfoRequired() + + /** Notifies when the registration flow for the ICD completes. */ + fun onICDRegistrationComplete(icdNodeId: Long, icdCounter: Long) } /** From b364ee6ea8a36a368d7b28983cadd08317db4d10 Mon Sep 17 00:00:00 2001 From: Yufeng Wang Date: Fri, 22 Dec 2023 10:32:05 -0800 Subject: [PATCH 29/29] =?UTF-8?q?[Android]=20Return=20ConnectionFailureExc?= =?UTF-8?q?eption=20which=20contains=20the=20connection=20state=E2=80=A6?= =?UTF-8?q?=20(#31149)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Return ConnectionFailureException which contains the connection state info in onConnectionFailure * Update src/app/CASESessionManager.h Co-authored-by: Boris Zbarsky * Address review comments * Allow onFailure and onSetupFailure to be null * Update src/app/CASESessionManager.cpp Co-authored-by: Boris Zbarsky * Address review comments --------- Co-authored-by: Boris Zbarsky --- src/app/CASESessionManager.cpp | 68 +++++++++++++++++- src/app/CASESessionManager.h | 65 +++++++++++++++++ src/controller/CHIPDeviceController.h | 28 +++++++- src/controller/java/AndroidCallbacks.cpp | 10 +-- src/controller/java/AndroidCallbacks.h | 4 +- .../AndroidConnectionFailureExceptions.cpp | 44 ++++++++++++ .../java/AndroidConnectionFailureExceptions.h | 47 ++++++++++++ src/controller/java/BUILD.gn | 3 + .../ConnectionFailureException.java | 71 +++++++++++++++++++ 9 files changed, 330 insertions(+), 10 deletions(-) create mode 100644 src/controller/java/AndroidConnectionFailureExceptions.cpp create mode 100644 src/controller/java/AndroidConnectionFailureExceptions.h create mode 100644 src/controller/java/src/chip/devicecontroller/ConnectionFailureException.java diff --git a/src/app/CASESessionManager.cpp b/src/app/CASESessionManager.cpp index 52c48f102672b3..382d2620fcfa6a 100644 --- a/src/app/CASESessionManager.cpp +++ b/src/app/CASESessionManager.cpp @@ -36,6 +36,56 @@ void CASESessionManager::FindOrEstablishSession(const ScopedNodeId & peerId, Cal uint8_t attemptCount, Callback::Callback * onRetry #endif // CHIP_DEVICE_CONFIG_ENABLE_AUTOMATIC_CASE_RETRIES ) +{ + FindOrEstablishSessionHelper(peerId, onConnection, onFailure, nullptr +#if CHIP_DEVICE_CONFIG_ENABLE_AUTOMATIC_CASE_RETRIES + , + attemptCount, onRetry +#endif + ); +} + +void CASESessionManager::FindOrEstablishSession(const ScopedNodeId & peerId, Callback::Callback * onConnection, + Callback::Callback * onSetupFailure +#if CHIP_DEVICE_CONFIG_ENABLE_AUTOMATIC_CASE_RETRIES + , + uint8_t attemptCount, Callback::Callback * onRetry +#endif +) +{ + FindOrEstablishSessionHelper(peerId, onConnection, nullptr, onSetupFailure +#if CHIP_DEVICE_CONFIG_ENABLE_AUTOMATIC_CASE_RETRIES + , + attemptCount, onRetry +#endif + ); +} + +void CASESessionManager::FindOrEstablishSession(const ScopedNodeId & peerId, Callback::Callback * onConnection, + nullptr_t +#if CHIP_DEVICE_CONFIG_ENABLE_AUTOMATIC_CASE_RETRIES + , + uint8_t attemptCount, Callback::Callback * onRetry +#endif +) +{ + FindOrEstablishSessionHelper(peerId, onConnection, nullptr, nullptr +#if CHIP_DEVICE_CONFIG_ENABLE_AUTOMATIC_CASE_RETRIES + , + attemptCount, onRetry +#endif + ); +} + +void CASESessionManager::FindOrEstablishSessionHelper(const ScopedNodeId & peerId, + Callback::Callback * onConnection, + Callback::Callback * onFailure, + Callback::Callback * onSetupFailure +#if CHIP_DEVICE_CONFIG_ENABLE_AUTOMATIC_CASE_RETRIES + , + uint8_t attemptCount, Callback::Callback * onRetry +#endif +) { ChipLogDetail(CASESessionManager, "FindOrEstablishSession: PeerId = [%d:" ChipLogFormatX64 "]", peerId.GetFabricIndex(), ChipLogValueX64(peerId.GetNodeId())); @@ -45,7 +95,6 @@ void CASESessionManager::FindOrEstablishSession(const ScopedNodeId & peerId, Cal if (session == nullptr) { ChipLogDetail(CASESessionManager, "FindOrEstablishSession: No existing OperationalSessionSetup instance found"); - session = mConfig.sessionSetupPool->Allocate(mConfig.sessionInitParams, mConfig.clientPool, peerId, this); if (session == nullptr) @@ -54,6 +103,13 @@ void CASESessionManager::FindOrEstablishSession(const ScopedNodeId & peerId, Cal { onFailure->mCall(onFailure->mContext, peerId, CHIP_ERROR_NO_MEMORY); } + + if (onSetupFailure != nullptr) + { + OperationalSessionSetup::ConnnectionFailureInfo failureInfo(peerId, CHIP_ERROR_NO_MEMORY, + SessionEstablishmentStage::kUnknown); + onSetupFailure->mCall(onSetupFailure->mContext, failureInfo); + } return; } } @@ -66,7 +122,15 @@ void CASESessionManager::FindOrEstablishSession(const ScopedNodeId & peerId, Cal } #endif // CHIP_DEVICE_CONFIG_ENABLE_AUTOMATIC_CASE_RETRIES - session->Connect(onConnection, onFailure); + if (onFailure != nullptr) + { + session->Connect(onConnection, onFailure); + } + + if (onSetupFailure != nullptr) + { + session->Connect(onConnection, onSetupFailure); + } } void CASESessionManager::ReleaseSessionsForFabric(FabricIndex fabricIndex) diff --git a/src/app/CASESessionManager.h b/src/app/CASESessionManager.h index 7094c88f42e104..92fb7a9ba783c7 100644 --- a/src/app/CASESessionManager.h +++ b/src/app/CASESessionManager.h @@ -87,6 +87,63 @@ class CASESessionManager : public OperationalSessionReleaseDelegate, public Sess #endif // CHIP_DEVICE_CONFIG_ENABLE_AUTOMATIC_CASE_RETRIES ); + /** + * Find an existing session for the given node ID or trigger a new session request. + * + * The caller can optionally provide `onConnection` and `onSetupFailure` + * callback objects. If provided, these will be used to inform the caller about successful or + * failed connection establishment. + * + * If the connection is already established, the `onConnection` callback will be immediately called, + * before `FindOrEstablishSession` returns. + * + * The `onSetupFailure` callback may be called before the `FindOrEstablishSession` + * call returns, for error cases that are detected synchronously. + * + * The `attemptCount` parameter can be used to automatically retry multiple times if session setup is + * not successful. + * + * @param peerId The node ID to find or establish a session with. + * @param onConnection A callback to be called upon successful connection establishment. + * @param onSetupFailure A callback to be called upon an extended device connection failure. + * @param attemptCount The number of retry attempts if session setup fails (default is 1). + * @param onRetry A callback to be called on a retry attempt (enabled by a config flag). + */ + void FindOrEstablishSession(const ScopedNodeId & peerId, Callback::Callback * onConnection, + Callback::Callback * onSetupFailure +#if CHIP_DEVICE_CONFIG_ENABLE_AUTOMATIC_CASE_RETRIES + , + uint8_t attemptCount = 1, Callback::Callback * onRetry = nullptr +#endif // CHIP_DEVICE_CONFIG_ENABLE_AUTOMATIC_CASE_RETRIES + ); + + /** + * Find an existing session for the given node ID or trigger a new session request. + * + * The caller can optionally provide `onConnection` + * callback objects. If provided, these will be used to inform the caller about successful connection establishment. + * + * If the connection is already established, the `onConnection` callback will be immediately called, + * before `FindOrEstablishSession` returns. + * + * The `attemptCount` parameter can be used to automatically retry multiple times if session setup is + * not successful. + * + * This function allows passing 'nullptr' for the error handler to compile, which is useful in scenarios where error + * handling is not needed. + * + * @param peerId The node ID to find or establish a session with. + * @param onConnection A callback to be called upon successful connection establishment. + * @param attemptCount The number of retry attempts if session setup fails (default is 1). + * @param onRetry A callback to be called on a retry attempt (enabled by a config flag). + */ + void FindOrEstablishSession(const ScopedNodeId & peerId, Callback::Callback * onConnection, nullptr_t +#if CHIP_DEVICE_CONFIG_ENABLE_AUTOMATIC_CASE_RETRIES + , + uint8_t attemptCount = 1, Callback::Callback * onRetry = nullptr +#endif // CHIP_DEVICE_CONFIG_ENABLE_AUTOMATIC_CASE_RETRIES + ); + void ReleaseSessionsForFabric(FabricIndex fabricIndex); void ReleaseAllSessions(); @@ -112,6 +169,14 @@ class CASESessionManager : public OperationalSessionReleaseDelegate, public Sess Optional FindExistingSession(const ScopedNodeId & peerId) const; + void FindOrEstablishSessionHelper(const ScopedNodeId & peerId, Callback::Callback * onConnection, + Callback::Callback * onFailure, + Callback::Callback * onSetupFailure, +#if CHIP_DEVICE_CONFIG_ENABLE_AUTOMATIC_CASE_RETRIES + uint8_t attemptCount, Callback::Callback * onRetry +#endif + ); + CASESessionManagerConfig mConfig; }; diff --git a/src/controller/CHIPDeviceController.h b/src/controller/CHIPDeviceController.h index 2007d8424b2f88..a7e6f6dac4bcb9 100644 --- a/src/controller/CHIPDeviceController.h +++ b/src/controller/CHIPDeviceController.h @@ -220,11 +220,11 @@ class DLL_EXPORT DeviceController : public AbstractDnssdDiscoveryController * This function finds the device corresponding to deviceId, and establishes * a CASE session with it. * - * Once the CASE session is successfully established the `onConnectedDevice` + * Once the CASE session is successfully established the `onConnection` * callback is called. This can happen before GetConnectedDevice returns if * there is an existing CASE session. * - * If a CASE sessions fails to be established, the `onError` callback will + * If a CASE sessions fails to be established, the `onFailure` callback will * be called. This can also happen before GetConnectedDevice returns. * * An error return from this function means that neither callback has been @@ -238,6 +238,30 @@ class DLL_EXPORT DeviceController : public AbstractDnssdDiscoveryController return CHIP_NO_ERROR; } + /** + * This function finds the device corresponding to deviceId, and establishes + * a CASE session with it. + * + * Once the CASE session is successfully established the `onConnection` + * callback is called. This can happen before GetConnectedDevice returns if + * there is an existing CASE session. + * + * If a CASE sessions fails to be established, the `onSetupFailure` callback will + * be called. This can also happen before GetConnectedDevice returns. + * + * An error return from this function means that neither callback has been + * called yet, and neither callback will be called in the future. + */ + CHIP_ERROR + GetConnectedDevice(NodeId peerNodeId, Callback::Callback * onConnection, + chip::Callback::Callback * onSetupFailure) + { + VerifyOrReturnError(mState == State::Initialized, CHIP_ERROR_INCORRECT_STATE); + mSystemState->CASESessionMgr()->FindOrEstablishSession(ScopedNodeId(peerNodeId, GetFabricIndex()), onConnection, + onSetupFailure); + return CHIP_NO_ERROR; + } + /** * @brief * Compute a PASE verifier and passcode ID for the desired setup pincode. diff --git a/src/controller/java/AndroidCallbacks.cpp b/src/controller/java/AndroidCallbacks.cpp index 85c948404343ab..b19e50b24e06f6 100644 --- a/src/controller/java/AndroidCallbacks.cpp +++ b/src/controller/java/AndroidCallbacks.cpp @@ -15,6 +15,7 @@ * limitations under the License. */ #include "AndroidCallbacks.h" +#include #include #ifdef USE_JAVA_TLV_ENCODE_DECODE #include @@ -114,7 +115,8 @@ void GetConnectedDeviceCallback::OnDeviceConnectedFn(void * context, Messaging:: VerifyOrReturn(!env->ExceptionCheck(), env->ExceptionDescribe()); } -void GetConnectedDeviceCallback::OnDeviceConnectionFailureFn(void * context, const ScopedNodeId & peerId, CHIP_ERROR error) +void GetConnectedDeviceCallback::OnDeviceConnectionFailureFn(void * context, + const OperationalSessionSetup::ConnnectionFailureInfo & failureInfo) { JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread(); VerifyOrReturn(env != nullptr, ChipLogError(Controller, "Could not get JNIEnv for current thread")); @@ -135,15 +137,15 @@ void GetConnectedDeviceCallback::OnDeviceConnectionFailureFn(void * context, con VerifyOrReturn(failureMethod != nullptr, ChipLogError(Controller, "Could not find onConnectionFailure method")); jthrowable exception; - CHIP_ERROR err = AndroidControllerExceptions::GetInstance().CreateAndroidControllerException(env, ErrorStr(error), - error.AsInteger(), exception); + CHIP_ERROR err = AndroidConnectionFailureExceptions::GetInstance().CreateAndroidConnectionFailureException( + env, failureInfo.error.Format(), failureInfo.error.AsInteger(), failureInfo.sessionStage, exception); VerifyOrReturn( err == CHIP_NO_ERROR, ChipLogError(Controller, "Unable to create AndroidControllerException on GetConnectedDeviceCallback::OnDeviceConnectionFailureFn: %s", ErrorStr(err))); DeviceLayer::StackUnlock unlock; - env->CallVoidMethod(javaCallback, failureMethod, peerId.GetNodeId(), exception); + env->CallVoidMethod(javaCallback, failureMethod, failureInfo.peerId.GetNodeId(), exception); VerifyOrReturn(!env->ExceptionCheck(), env->ExceptionDescribe()); } diff --git a/src/controller/java/AndroidCallbacks.h b/src/controller/java/AndroidCallbacks.h index b622fc3294832e..f00075258bea8f 100644 --- a/src/controller/java/AndroidCallbacks.h +++ b/src/controller/java/AndroidCallbacks.h @@ -39,10 +39,10 @@ struct GetConnectedDeviceCallback ~GetConnectedDeviceCallback(); static void OnDeviceConnectedFn(void * context, Messaging::ExchangeManager & exchangeMgr, const SessionHandle & sessionHandle); - static void OnDeviceConnectionFailureFn(void * context, const ScopedNodeId & peerId, CHIP_ERROR error); + static void OnDeviceConnectionFailureFn(void * context, const OperationalSessionSetup::ConnnectionFailureInfo & failureInfo); Callback::Callback mOnSuccess; - Callback::Callback mOnFailure; + Callback::Callback mOnFailure; JniGlobalReference mWrapperCallbackRef; JniGlobalReference mJavaCallbackRef; }; diff --git a/src/controller/java/AndroidConnectionFailureExceptions.cpp b/src/controller/java/AndroidConnectionFailureExceptions.cpp new file mode 100644 index 00000000000000..1e4bcd4a452ac1 --- /dev/null +++ b/src/controller/java/AndroidConnectionFailureExceptions.cpp @@ -0,0 +1,44 @@ +/* + * + * 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. + */ + +#include "AndroidConnectionFailureExceptions.h" + +#include +#include +#include +#include + +namespace chip { + +CHIP_ERROR AndroidConnectionFailureExceptions::CreateAndroidConnectionFailureException(JNIEnv * env, const char * message, + uint32_t errorCode, + SessionEstablishmentStage state, + jthrowable & outEx) +{ + jclass controllerExceptionCls; + CHIP_ERROR err = JniReferences::GetInstance().GetLocalClassRef(env, "chip/devicecontroller/ConnectionFailureException", + controllerExceptionCls); + VerifyOrReturnError(err == CHIP_NO_ERROR, CHIP_JNI_ERROR_TYPE_NOT_FOUND); + + jmethodID exceptionConstructor = env->GetMethodID(controllerExceptionCls, "", "(JILjava/lang/String;)V"); + outEx = static_cast(env->NewObject(controllerExceptionCls, exceptionConstructor, static_cast(errorCode), + static_cast(state), env->NewStringUTF(message))); + VerifyOrReturnError(outEx != nullptr, CHIP_JNI_ERROR_TYPE_NOT_FOUND); + return CHIP_NO_ERROR; +} + +} // namespace chip diff --git a/src/controller/java/AndroidConnectionFailureExceptions.h b/src/controller/java/AndroidConnectionFailureExceptions.h new file mode 100644 index 00000000000000..54baacac9e3326 --- /dev/null +++ b/src/controller/java/AndroidConnectionFailureExceptions.h @@ -0,0 +1,47 @@ +/* + * + * 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. + */ + +#pragma once + +#include +#include +#include + +namespace chip { +class AndroidConnectionFailureExceptions +{ +public: + AndroidConnectionFailureExceptions(const AndroidConnectionFailureExceptions &) = delete; + AndroidConnectionFailureExceptions(const AndroidConnectionFailureExceptions &&) = delete; + AndroidConnectionFailureExceptions & operator=(const AndroidConnectionFailureExceptions &) = delete; + + static AndroidConnectionFailureExceptions & GetInstance() + { + static AndroidConnectionFailureExceptions androidConnectionFailureExceptions; + return androidConnectionFailureExceptions; + } + + /** + * Creates a Java ConnectionFailureException object in outEx. + */ + CHIP_ERROR CreateAndroidConnectionFailureException(JNIEnv * env, const char * message, uint32_t errorCode, + SessionEstablishmentStage state, jthrowable & outEx); + +private: + AndroidConnectionFailureExceptions() {} +}; +} // namespace chip diff --git a/src/controller/java/BUILD.gn b/src/controller/java/BUILD.gn index a538afefc744c5..e481e74feeda1c 100644 --- a/src/controller/java/BUILD.gn +++ b/src/controller/java/BUILD.gn @@ -45,6 +45,8 @@ shared_library("jni") { "AndroidClusterExceptions.h", "AndroidCommissioningWindowOpener.cpp", "AndroidCommissioningWindowOpener.h", + "AndroidConnectionFailureExceptions.cpp", + "AndroidConnectionFailureExceptions.h", "AndroidControllerExceptions.cpp", "AndroidControllerExceptions.h", "AndroidCurrentFabricRemover.cpp", @@ -439,6 +441,7 @@ android_library("java") { "src/chip/devicecontroller/ChipCommandType.java", "src/chip/devicecontroller/ChipDeviceController.java", "src/chip/devicecontroller/ChipDeviceControllerException.java", + "src/chip/devicecontroller/ConnectionFailureException.java", "src/chip/devicecontroller/ControllerParams.java", "src/chip/devicecontroller/DeviceAttestationDelegate.java", "src/chip/devicecontroller/DiscoveredDevice.java", diff --git a/src/controller/java/src/chip/devicecontroller/ConnectionFailureException.java b/src/controller/java/src/chip/devicecontroller/ConnectionFailureException.java new file mode 100644 index 00000000000000..4b5121bdcc6331 --- /dev/null +++ b/src/controller/java/src/chip/devicecontroller/ConnectionFailureException.java @@ -0,0 +1,71 @@ +/* + * 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 chip.devicecontroller; + +@SuppressWarnings("serial") +public class ConnectionFailureException extends ChipDeviceControllerException { + public enum ConnectionState { + UNKNOWN, // Unknown state + NOT_IN_KEY_EXCHANGE, // Not currently in key exchange process + SENT_SIGMA1, // Sigma1 message sent + RECEIVED_SIGMA1, // Sigma1 message received + SENT_SIGMA2, // Sigma2 message sent + RECEIVED_SIGMA2, // Sigma2 message received + SENT_SIGMA3, // Sigma3 message sent + RECEIVED_SIGMA3 // Sigma3 message received + } + + private ConnectionState connectionState; + + public ConnectionFailureException() { + super(); + } + + public ConnectionFailureException(long errorCode, int connectionState, String message) { + super(errorCode, message); + this.connectionState = mapIntToConnectionState(connectionState); + } + + public ConnectionState getConnectionState() { + return connectionState; + } + + // Helper method to map an int to ConnectionState enum + private ConnectionState mapIntToConnectionState(int value) { + switch (value) { + case 0: + return ConnectionState.UNKNOWN; + case 1: + return ConnectionState.NOT_IN_KEY_EXCHANGE; + case 2: + return ConnectionState.SENT_SIGMA1; + case 3: + return ConnectionState.RECEIVED_SIGMA1; + case 4: + return ConnectionState.SENT_SIGMA2; + case 5: + return ConnectionState.RECEIVED_SIGMA2; + case 6: + return ConnectionState.SENT_SIGMA3; + case 7: + return ConnectionState.RECEIVED_SIGMA3; + default: + throw new IllegalArgumentException("Invalid connection state value: " + value); + } + } +}