From b81370b28a13b4fd5ea5af31fae557c99efd7915 Mon Sep 17 00:00:00 2001 From: Rob Bultman Date: Fri, 24 May 2024 16:55:59 -0400 Subject: [PATCH 01/10] Remove provisionality for oven op-state and oven mode clusters (#33550) * Remove oven provisionality * Commit after regen --- .../all-clusters-common/all-clusters-app.matter | 4 ++-- .../zcl/data-model/chip/operational-state-oven-cluster.xml | 2 +- .../zap-templates/zcl/data-model/chip/oven-mode-cluster.xml | 2 +- src/controller/data_model/controller-clusters.matter | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) 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 59e79389113b79..03e3cc6ca3fe20 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 @@ -2609,7 +2609,7 @@ cluster BooleanState = 69 { } /** This cluster supports remotely monitoring and, where supported, changing the operational state of an Oven. */ -provisional cluster OvenCavityOperationalState = 72 { +cluster OvenCavityOperationalState = 72 { revision 1; enum ErrorStateEnum : enum8 { @@ -2675,7 +2675,7 @@ provisional cluster OvenCavityOperationalState = 72 { } /** Attributes and commands for selecting a mode from a list of supported options. */ -provisional cluster OvenMode = 73 { +cluster OvenMode = 73 { revision 1; enum ModeTag : enum16 { diff --git a/src/app/zap-templates/zcl/data-model/chip/operational-state-oven-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/operational-state-oven-cluster.xml index f121b6357d605b..83f2fc8b7984d4 100644 --- a/src/app/zap-templates/zcl/data-model/chip/operational-state-oven-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/operational-state-oven-cluster.xml @@ -16,7 +16,7 @@ limitations under the License. --> - + Appliances Oven Cavity Operational State 0x0048 diff --git a/src/app/zap-templates/zcl/data-model/chip/oven-mode-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/oven-mode-cluster.xml index 2508b4741602b3..41f95e81cdd248 100644 --- a/src/app/zap-templates/zcl/data-model/chip/oven-mode-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/oven-mode-cluster.xml @@ -30,7 +30,7 @@ limitations under the License. - + General Oven Mode 0x0049 diff --git a/src/controller/data_model/controller-clusters.matter b/src/controller/data_model/controller-clusters.matter index c559d1d0e9b129..dcc22df982b9e5 100644 --- a/src/controller/data_model/controller-clusters.matter +++ b/src/controller/data_model/controller-clusters.matter @@ -2804,7 +2804,7 @@ provisional cluster Timer = 71 { } /** This cluster supports remotely monitoring and, where supported, changing the operational state of an Oven. */ -provisional cluster OvenCavityOperationalState = 72 { +cluster OvenCavityOperationalState = 72 { revision 1; enum ErrorStateEnum : enum8 { @@ -2870,7 +2870,7 @@ provisional cluster OvenCavityOperationalState = 72 { } /** Attributes and commands for selecting a mode from a list of supported options. */ -provisional cluster OvenMode = 73 { +cluster OvenMode = 73 { revision 1; enum ModeTag : enum16 { From 3e93ba6e7a1830ff20623b1f892d5e6540fbb2e7 Mon Sep 17 00:00:00 2001 From: Boris Zbarsky Date: Fri, 24 May 2024 17:34:19 -0400 Subject: [PATCH 02/10] Improve our various round-trip timeout computations. (#33587) We had a few issues: 1) Our "round-trip timeout" only accounted for one side of the round-trip needing to do MRP retransmits. So if the sender retried a few times, the last retry finally got through, then the response had to be retried a well, the sender would time out the exchange before the response was received. The fix here is to add the MRP backoff times for both the initial message and the response. 2) ReadClient could end up timing out a subscription before the server had actually given up on receiving a StatusReport in response to its ReportData, in situations where the server ended up doing MRP retries and the last MRP retry took a few seconds to get through the network. The fix here is to just estimate how long the server will be waiting for the StatusReport and not time out the subscription until then; at that point even if the server did in fact send its report on time, it will have dropped the subscription on its end. --- src/app/OperationalSessionSetup.cpp | 5 +++ src/app/ReadClient.cpp | 32 ++++++++++--------- .../Framework/CHIPTests/MTRControllerTests.m | 4 +++ .../CHIPTests/MTRPerControllerStorageTests.m | 4 +++ src/protocols/secure_channel/CASESession.cpp | 31 +++++++++++++----- src/transport/GroupSession.h | 14 ++++++++ src/transport/SecureSession.h | 21 ++++++++++++ src/transport/Session.cpp | 5 ++- src/transport/Session.h | 16 +++++++++- src/transport/UnauthenticatedSessionTable.h | 21 ++++++++++++ 10 files changed, 128 insertions(+), 25 deletions(-) diff --git a/src/app/OperationalSessionSetup.cpp b/src/app/OperationalSessionSetup.cpp index 5733a423702226..9197a2edbddf70 100644 --- a/src/app/OperationalSessionSetup.cpp +++ b/src/app/OperationalSessionSetup.cpp @@ -792,6 +792,11 @@ CHIP_ERROR OperationalSessionSetup::ScheduleSessionSetupReattempt(System::Clock: // but in practice for old devices BUSY often sends some hardcoded value // that tells us nothing about when the other side will decide it has // timed out. + // + // Unfortunately, we do not have the MRP config for the other side here, + // but in practice if the other side is using its local config to + // compute Sigma2 response timeouts, then it's also returning useful + // values with BUSY, so we will wait long enough. auto additionalTimeout = CASESession::ComputeSigma2ResponseTimeout(GetLocalMRPConfig().ValueOr(GetDefaultMRPConfig())); actualTimerDelay += additionalTimeout; } diff --git a/src/app/ReadClient.cpp b/src/app/ReadClient.cpp index e8ada20a428c70..bb058e091858c7 100644 --- a/src/app/ReadClient.cpp +++ b/src/app/ReadClient.cpp @@ -938,24 +938,26 @@ CHIP_ERROR ReadClient::ComputeLivenessCheckTimerTimeout(System::Clock::Timeout * // // To calculate the duration we're willing to wait for a report to come to us, we take into account the maximum interval of - // the subscription AND the time it takes for the report to make it to us in the worst case. This latter bit involves - // computing the Ack timeout from the publisher for the ReportData message being sent to us using our IDLE interval as the - // basis for that computation. + // the subscription AND the time it takes for the report to make it to us in the worst case. // - // Make sure to use the retransmission computation that includes backoff. For purposes of that computation, treat us as - // active now (since we are right now sending/receiving messages), and use the default "how long are we guaranteed to stay - // active" threshold for now. + // We have no way to estimate what the network latency will be, but we do know the other side will time out its ReportData + // after its computed round-trip timeout plus the processing time it gives us (app::kExpectedIMProcessingTime). Once it + // times out, assuming it sent the report at all, there's no point in us thinking we still have a subscription. // - // TODO: We need to find a good home for this logic that will correctly compute this based on transport. For now, this will - // suffice since we don't use TCP as a transport currently and subscriptions over BLE aren't really a thing. + // We can't use ComputeRoundTripTimeout() on the session for two reasons: we want the roundtrip timeout from the point of + // view of the peer, not us, and we want to start off with the assumption the peer will likely have, which is that we are + // idle, whereas ComputeRoundTripTimeout() uses the current activity state of the peer. // - const auto & localMRPConfig = GetLocalMRPConfig(); - const auto & defaultMRPConfig = GetDefaultMRPConfig(); - const auto & ourMrpConfig = localMRPConfig.ValueOr(defaultMRPConfig); - auto publisherTransmissionTimeout = - GetRetransmissionTimeout(ourMrpConfig.mActiveRetransTimeout, ourMrpConfig.mIdleRetransTimeout, - System::SystemClock().GetMonotonicTimestamp(), ourMrpConfig.mActiveThresholdTime); - *aTimeout = System::Clock::Seconds16(mMaxInterval) + publisherTransmissionTimeout; + // So recompute the round-trip timeout directly. Assume MRP, since in practice that is likely what is happening. + auto & peerMRPConfig = mReadPrepareParams.mSessionHolder->GetRemoteMRPConfig(); + // Peer will assume we are idle (hence we pass kZero to GetMessageReceiptTimeout()), but will assume we treat it as active + // for the response, so to match the retransmission timeout computation for the message back to the peeer, we should treat + // it as active. + auto roundTripTimeout = mReadPrepareParams.mSessionHolder->GetMessageReceiptTimeout(System::Clock::kZero) + + kExpectedIMProcessingTime + + GetRetransmissionTimeout(peerMRPConfig.mActiveRetransTimeout, peerMRPConfig.mIdleRetransTimeout, + System::SystemClock().GetMonotonicTimestamp(), peerMRPConfig.mActiveThresholdTime); + *aTimeout = System::Clock::Seconds16(mMaxInterval) + roundTripTimeout; return CHIP_NO_ERROR; } diff --git a/src/darwin/Framework/CHIPTests/MTRControllerTests.m b/src/darwin/Framework/CHIPTests/MTRControllerTests.m index b5ca63135703b3..436a0df230e3d9 100644 --- a/src/darwin/Framework/CHIPTests/MTRControllerTests.m +++ b/src/darwin/Framework/CHIPTests/MTRControllerTests.m @@ -1557,6 +1557,10 @@ - (void)testSetMRPParameters // Can be called before starting the factory XCTAssertFalse(MTRDeviceControllerFactory.sharedInstance.running); MTRSetMessageReliabilityParameters(@2000, @2000, @2000, @2000); + + // Now reset back to the default state, so timings in other tests are not + // affected. + MTRSetMessageReliabilityParameters(nil, nil, nil, nil); } @end diff --git a/src/darwin/Framework/CHIPTests/MTRPerControllerStorageTests.m b/src/darwin/Framework/CHIPTests/MTRPerControllerStorageTests.m index 868e81ef85774e..c5e39276323891 100644 --- a/src/darwin/Framework/CHIPTests/MTRPerControllerStorageTests.m +++ b/src/darwin/Framework/CHIPTests/MTRPerControllerStorageTests.m @@ -2140,6 +2140,10 @@ - (void)testSetMRPParametersWithRunningController XCTAssertTrue(controller.running); MTRSetMessageReliabilityParameters(@2000, @2000, @2000, @2000); [controller shutdown]; + + // Now reset back to the default state, so timings in other tests are not + // affected. + MTRSetMessageReliabilityParameters(nil, nil, nil, nil); } // TODO: This might also want to go in a separate test file, with some shared setup for commissioning devices per test diff --git a/src/protocols/secure_channel/CASESession.cpp b/src/protocols/secure_channel/CASESession.cpp index ccc2bc2188d176..b0642a966890fd 100644 --- a/src/protocols/secure_channel/CASESession.cpp +++ b/src/protocols/secure_channel/CASESession.cpp @@ -2362,21 +2362,36 @@ CHIP_ERROR CASESession::OnMessageReceived(ExchangeContext * ec, const PayloadHea return err; } -System::Clock::Timeout CASESession::ComputeSigma1ResponseTimeout(const ReliableMessageProtocolConfig & remoteMrpConfig) +namespace { +System::Clock::Timeout ComputeRoundTripTimeout(ExchangeContext::Timeout serverProcessingTime, + const ReliableMessageProtocolConfig & remoteMrpConfig) { + // TODO: This is duplicating logic from Session::ComputeRoundTripTimeout. Unfortunately, it's called by + // consumers who do not have a session. + const auto & maybeLocalMRPConfig = GetLocalMRPConfig(); + const auto & defaultMRRPConfig = GetDefaultMRPConfig(); + const auto & localMRPConfig = maybeLocalMRPConfig.ValueOr(defaultMRRPConfig); return GetRetransmissionTimeout(remoteMrpConfig.mActiveRetransTimeout, remoteMrpConfig.mIdleRetransTimeout, - // Assume peer is idle, since that's what we - // will assume for our initial message. + // Assume peer is idle, as a worst-case assumption (probably true for + // Sigma1, since that will be our initial message on the session, but less + // so for Sigma2). System::Clock::kZero, remoteMrpConfig.mActiveThresholdTime) + - kExpectedSigma1ProcessingTime; + serverProcessingTime + + GetRetransmissionTimeout(localMRPConfig.mActiveRetransTimeout, localMRPConfig.mIdleRetransTimeout, + // Peer will assume we are active, since it's + // responding to our message. + System::SystemClock().GetMonotonicTimestamp(), localMRPConfig.mActiveThresholdTime); +} +} // anonymous namespace + +System::Clock::Timeout CASESession::ComputeSigma1ResponseTimeout(const ReliableMessageProtocolConfig & remoteMrpConfig) +{ + return ComputeRoundTripTimeout(kExpectedSigma1ProcessingTime, remoteMrpConfig); } System::Clock::Timeout CASESession::ComputeSigma2ResponseTimeout(const ReliableMessageProtocolConfig & remoteMrpConfig) { - return GetRetransmissionTimeout(remoteMrpConfig.mActiveRetransTimeout, remoteMrpConfig.mIdleRetransTimeout, - // Assume peer is idle, as a worst-case assumption. - System::Clock::kZero, remoteMrpConfig.mActiveThresholdTime) + - kExpectedHighProcessingTime; + return ComputeRoundTripTimeout(kExpectedHighProcessingTime, remoteMrpConfig); } bool CASESession::InvokeBackgroundWorkWatchdog() diff --git a/src/transport/GroupSession.h b/src/transport/GroupSession.h index f20ff069ab029f..1c5ffecd2be3c9 100644 --- a/src/transport/GroupSession.h +++ b/src/transport/GroupSession.h @@ -75,6 +75,13 @@ class IncomingGroupSession : public Session, public ReferenceCounted Date: Fri, 24 May 2024 21:12:15 -0700 Subject: [PATCH 03/10] Fixes and additions of some of the bounds checks in SystemPacketBuffer::New() (#33411) * Fixes and additions of some of the bounds checks in SystemPacketBuffer::New(). With the data length types changed to size_t, the bounds checks for the lengths need to be appropriately modified so that we ensure that overflow does not happen and the buffer allocation is performed correctly as requested by the caller of the API. * Apply suggestions from code review Co-authored-by: Boris Zbarsky --------- Co-authored-by: Boris Zbarsky --- src/system/SystemPacketBuffer.cpp | 66 ++++++++++++++++++++++--------- 1 file changed, 47 insertions(+), 19 deletions(-) diff --git a/src/system/SystemPacketBuffer.cpp b/src/system/SystemPacketBuffer.cpp index 59e1e822901db0..f8dda8b01ab84e 100644 --- a/src/system/SystemPacketBuffer.cpp +++ b/src/system/SystemPacketBuffer.cpp @@ -508,37 +508,64 @@ void PacketBuffer::AddRef() PacketBufferHandle PacketBufferHandle::New(size_t aAvailableSize, uint16_t aReservedSize) { - // Adding three 16-bit-int sized numbers together will never overflow - // assuming int is at least 32 bits. - static_assert(INT_MAX >= INT32_MAX, "int is not big enough"); + // Sanity check for kStructureSize to ensure that it matches the PacketBuffer size. static_assert(PacketBuffer::kStructureSize == sizeof(PacketBuffer), "PacketBuffer size mismatch"); - static_assert(PacketBuffer::kStructureSize < UINT16_MAX, "Check for overflow more carefully"); - static_assert(SIZE_MAX >= INT_MAX, "Our additions might not fit in size_t"); - static_assert(PacketBuffer::kMaxSizeWithoutReserve <= UINT32_MAX, "PacketBuffer may have size not fitting uint32_t"); + // Setting a static upper bound on kStructureSize to ensure the summation of all the sizes does not overflow. + static_assert(PacketBuffer::kStructureSize <= UINT16_MAX, "kStructureSize should not exceed UINT16_MAX."); + // Setting a static upper bound on the maximum buffer size allocation for regular sized messages (not large). + static_assert(PacketBuffer::kMaxSizeWithoutReserve <= UINT16_MAX, "kMaxSizeWithoutReserve should not exceed UINT16_MAX."); + + // Ensure that aAvailableSize is bound within a max and is not big enough to cause overflow during + // subsequent addition of all the sizes. + if (aAvailableSize > UINT32_MAX) + { + ChipLogError(chipSystemLayer, + "PacketBuffer: AvailableSize of a buffer cannot exceed UINT32_MAX. aAvailableSize = 0x" ChipLogFormatX64, + ChipLogValueX64(static_cast(aAvailableSize))); + return PacketBufferHandle(); + } + + // Cast all to uint64_t and add. This cannot overflow because we have + // ensured that the maximal value of the summation is + // UINT32_MAX + UINT16_MAX + UINT16_MAX, which should always fit in + // a uint64_t variable. + uint64_t sumOfSizes = static_cast(aAvailableSize) + static_cast(aReservedSize) + + static_cast(PacketBuffer::kStructureSize); + uint64_t sumOfAvailAndReserved = static_cast(aAvailableSize) + static_cast(aReservedSize); + + // Ensure that the sum fits in a size_t so that casting into size_t variables, + // viz., lBlockSize and lAllocSize, is safe. + if (!CanCastTo(sumOfSizes)) + { + ChipLogError(chipSystemLayer, + "PacketBuffer: Sizes of allocation request are invalid. (aAvailableSize = " ChipLogFormatX64 + ", aReservedSize = " ChipLogFormatX64 ")", + ChipLogValueX64(static_cast(aAvailableSize)), ChipLogValueX64(static_cast(aReservedSize))); + return PacketBufferHandle(); + } + #if CHIP_SYSTEM_CONFIG_USE_LWIP // LwIP based APIs have a maximum buffer size of UINT16_MAX. Ensure that // limit is met during allocation. - VerifyOrDieWithMsg(aAvailableSize + aReservedSize < UINT16_MAX, chipSystemLayer, - "LwIP based systems can handle only up to UINT16_MAX!"); + VerifyOrDieWithMsg(sumOfAvailAndReserved < UINT16_MAX, chipSystemLayer, "LwIP based systems can handle only up to UINT16_MAX!"); #endif // CHIP_SYSTEM_CONFIG_USE_LWIP - // When `aAvailableSize` fits in uint16_t (as tested below) and size_t is at least 32 bits (as asserted above), - // these additions will not overflow. - const size_t lAllocSize = aReservedSize + aAvailableSize; - const size_t lBlockSize = PacketBuffer::kStructureSize + lAllocSize; + // sumOfAvailAndReserved is no larger than sumOfSizes, which we checked can be cast to + // size_t. + const size_t lAllocSize = static_cast(sumOfAvailAndReserved); PacketBuffer * lPacket; CHIP_SYSTEM_FAULT_INJECT(FaultInjection::kFault_PacketBufferNew, return PacketBufferHandle()); - // TODO: Change the max to a lower value - if (aAvailableSize > UINT32_MAX || lAllocSize > PacketBuffer::kMaxSizeWithoutReserve || lBlockSize > UINT32_MAX) + if (lAllocSize > PacketBuffer::kMaxSizeWithoutReserve) { - ChipLogError(chipSystemLayer, "PacketBuffer: allocation too large."); + ChipLogError(chipSystemLayer, "PacketBuffer: allocation exceeding buffer capacity limits."); return PacketBufferHandle(); } #if CHIP_SYSTEM_CONFIG_USE_LWIP - + // This cast is safe because lAllocSize is no larger than + // kMaxSizeWithoutReserve, which fits in uint16_t. lPacket = static_cast( pbuf_alloc(PBUF_RAW, static_cast(lAllocSize), CHIP_SYSTEM_PACKETBUFFER_LWIP_PBUF_TYPE)); @@ -546,7 +573,6 @@ PacketBufferHandle PacketBufferHandle::New(size_t aAvailableSize, uint16_t aRese #elif CHIP_SYSTEM_PACKETBUFFER_FROM_CHIP_POOL - static_cast(lBlockSize); #if !CHIP_SYSTEM_CONFIG_NO_LOCKING && CHIP_SYSTEM_CONFIG_FREERTOS_LOCKING if (!sBufferPoolMutex.isInitialized()) { @@ -565,8 +591,10 @@ PacketBufferHandle PacketBufferHandle::New(size_t aAvailableSize, uint16_t aRese UNLOCK_BUF_POOL(); #elif CHIP_SYSTEM_PACKETBUFFER_FROM_CHIP_HEAP - - lPacket = reinterpret_cast(chip::Platform::MemoryAlloc(lBlockSize)); + // sumOfSizes is essentially (kStructureSize + lAllocSize) which we already + // checked to fit in a size_t. + const size_t lBlockSize = static_cast(sumOfSizes); + lPacket = reinterpret_cast(chip::Platform::MemoryAlloc(lBlockSize)); SYSTEM_STATS_INCREMENT(chip::System::Stats::kSystemLayer_NumPacketBufs); #else From 42510baf9cf8d6a04b3f2796e020ba024e11a38c Mon Sep 17 00:00:00 2001 From: Erwin Pan Date: Mon, 27 May 2024 22:27:46 +0800 Subject: [PATCH 04/10] [Chef] Add 2 Generic Switch devices and RPC Actions for Testing (#33255) * Add RPC Event Service draft * Commit the draft to add_event in post attr change Commit the draft to add_event in post attribute change callback * Add PreAttributeChangeCallback * Support write events as string through RPC * Revert Chef stubs.cpp to not using AttributeDelegate * RPC can call delegate to SwitchManager/EventHandler * Rmove ununsed RPC command delegate * Rename RPC Event to RPC Actions * Simplify RPC code by setting transparent subscribe * Chef RPC Actions Draft done. TBD: Debug Optimize Error code Confirm timer is ms * Fix timer bug, remove unused comments * Add Latching Switch taglist to Descriptor Cluster * Cross platform built on ESP32/nRFConnect done And also enable the ApplicationInit * Update Generic Switch 1 * Add 2nd Generic Switch * Add chef/common/chef-descriptor-namespace.h * Remote printf * Remove TODO * Remove unused comments * Restyled by whitespace * Restyled by clang-format * Fix according to PR comments https://github.com/project-chip/connectedhomeip/pull/33255 * Restyled by clang-format * Fix compilation issues * Remove unused debugging codes --------- Co-authored-by: Restyled.io --- .../chef/common/chef-descriptor-namespace.h | 51 + .../chef/common/chef-rpc-actions-worker.cpp | 158 + .../chef/common/chef-rpc-actions-worker.h | 79 + .../clusters/switch/SwitchEventHandler.cpp | 82 + .../clusters/switch/SwitchEventHandler.h | 80 + .../common/clusters/switch/SwitchManager.cpp | 172 + examples/chef/common/stubs.cpp | 10 + .../rootnode_genericswitch_2dfff6e516.matter | 1498 +++++++++ .../rootnode_genericswitch_2dfff6e516.zap | 2804 +++++++++++++++++ .../rootnode_genericswitch_9866e35d0b.matter | 285 +- .../rootnode_genericswitch_9866e35d0b.zap | 345 +- examples/chef/esp32/main/CMakeLists.txt | 1 + examples/chef/esp32/main/main.cpp | 6 + examples/chef/linux/BUILD.gn | 5 + examples/chef/linux/main.cpp | 4 - examples/chef/nrfconnect/CMakeLists.txt | 2 + examples/chef/nrfconnect/main.cpp | 9 + examples/common/pigweed/BUILD.gn | 8 + .../pigweed/protos/actions_service.options | 1 + .../pigweed/protos/actions_service.proto | 30 + .../common/pigweed/rpc_console/py/BUILD.gn | 1 + .../rpc_console/py/chip_rpc/console.py | 2 + .../common/pigweed/rpc_services/Actions.h | 127 + examples/platform/esp32/Rpc.cpp | 27 + examples/platform/esp32/Rpc.h | 12 + examples/platform/linux/Rpc.cpp | 23 + examples/platform/linux/Rpc.h | 15 + examples/platform/nrfconnect/Rpc.cpp | 31 + examples/platform/nrfconnect/Rpc.h | 12 + 29 files changed, 5872 insertions(+), 8 deletions(-) create mode 100644 examples/chef/common/chef-descriptor-namespace.h create mode 100644 examples/chef/common/chef-rpc-actions-worker.cpp create mode 100644 examples/chef/common/chef-rpc-actions-worker.h create mode 100644 examples/chef/common/clusters/switch/SwitchEventHandler.cpp create mode 100644 examples/chef/common/clusters/switch/SwitchEventHandler.h create mode 100644 examples/chef/common/clusters/switch/SwitchManager.cpp create mode 100644 examples/chef/devices/rootnode_genericswitch_2dfff6e516.matter create mode 100644 examples/chef/devices/rootnode_genericswitch_2dfff6e516.zap create mode 100644 examples/common/pigweed/protos/actions_service.options create mode 100644 examples/common/pigweed/protos/actions_service.proto create mode 100644 examples/common/pigweed/rpc_services/Actions.h diff --git a/examples/chef/common/chef-descriptor-namespace.h b/examples/chef/common/chef-descriptor-namespace.h new file mode 100644 index 00000000000000..e7e8e85df5a551 --- /dev/null +++ b/examples/chef/common/chef-descriptor-namespace.h @@ -0,0 +1,51 @@ +/* + * + * Copyright (c) 2024 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +// Please refer to https://github.com/CHIP-Specifications/connectedhomeip-spec/blob/master/src/namespaces +constexpr const uint8_t kNamespaceCommonLevel = 5; +// Common Number Namespace: 5, tag 0 (Low) +constexpr const uint8_t kTagCommonLow = 0; +// Common Number Namespace: 5, tag 1 (Medium) +constexpr const uint8_t kTagCommonMedium = 1; +// Common Number Namespace: 5, tag 2 (High) +constexpr const uint8_t kTagCommonHigh = 2; + +constexpr const uint8_t kNamespaceCommonNumber = 7; +// Common Number Namespace: 7, tag 0 (Zero) +constexpr const uint8_t kTagCommonZero = 0; +// Common Number Namespace: 7, tag 1 (One) +constexpr const uint8_t kTagCommonOne = 1; +// Common Number Namespace: 7, tag 2 (Two) +constexpr const uint8_t kTagCommonTwo = 2; + +constexpr const uint8_t kNamespacePosition = 8; +// Common Position Namespace: 8, tag: 0 (Left) +constexpr const uint8_t kTagPositionLeft = 0; +// Common Position Namespace: 8, tag: 1 (Right) +constexpr const uint8_t kTagPositionRight = 1; +// Common Position Namespace: 8, tag: 2 (Top) +constexpr const uint8_t kTagPositionTop = 2; +// Common Position Namespace: 8, tag: 3 (Bottom) +constexpr const uint8_t kTagPositionBottom = 3; +// Common Position Namespace: 8, tag: 4 (Middle) +constexpr const uint8_t kTagPositionMiddle = 4; +// Common Position Namespace: 8, tag: 5 (Row) +constexpr const uint8_t kTagPositionRow = 5; +// Common Position Namespace: 8, tag: 6 (Column) +constexpr const uint8_t kTagPositionColumn = 6; diff --git a/examples/chef/common/chef-rpc-actions-worker.cpp b/examples/chef/common/chef-rpc-actions-worker.cpp new file mode 100644 index 00000000000000..98bba768e7f4d8 --- /dev/null +++ b/examples/chef/common/chef-rpc-actions-worker.cpp @@ -0,0 +1,158 @@ +/* + * + * Copyright (c) 2024 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "chef-rpc-actions-worker.h" +#include +#include +#include +#include +#include +#include +#include + +using chip::app::DataModel::Nullable; + +using namespace chip; +using namespace chip::app; +using namespace chip::app::Clusters; +using namespace chip::rpc; + +static std::map gActionsDelegateMap{}; + +ActionsDelegate * RpcFindActionsDelegate(ClusterId clusterId) +{ + if (gActionsDelegateMap.find(clusterId) != gActionsDelegateMap.end()) + { + return gActionsDelegateMap[clusterId]; + } + + return nullptr; +} + +static void RpcActionsTaskCallback(System::Layer * systemLayer, void * data) +{ + ChefRpcActionsWorker * worker = (ChefRpcActionsWorker *) data; + + worker->ProcessActionQueue(); +} + +bool ChefRpcActionsCallback(EndpointId endpointId, ClusterId clusterId, uint8_t type, uint32_t delayMs, uint32_t actionId, + std::vector args) +{ + ActionTask task(endpointId, clusterId, static_cast(type), delayMs, actionId, args); + + return ChefRpcActionsWorker::Instance().EnqueueAction(task); +} + +bool ChefRpcActionsWorker::EnqueueAction(ActionTask task) +{ + bool kickTimer = false; + + if (queue.empty()) + { + kickTimer = true; // kick timer when the first task is adding to the queue + } + + queue.push(task); + + if (kickTimer) + { + (void) DeviceLayer::SystemLayer().StartTimer(System::Clock::Milliseconds32(task.delayMs), RpcActionsTaskCallback, this); + } + return true; +} + +void ChefRpcActionsWorker::ProcessActionQueue() +{ + // Dequeue the first item + ActionTask task = queue.front(); + queue.pop(); + + ActionsDelegate * delegate = RpcFindActionsDelegate(task.clusterId); + if (nullptr == delegate) + { + ChipLogError(NotSpecified, + "Cannot run action due to not finding delegate: endpointId=%d, clusterId=%04lx, attributeId=%04lx", + task.endpointId, static_cast(task.clusterId), static_cast(task.actionId)); + return; + } + + ActionType type = static_cast(task.type); + + switch (type) + { + case ActionType::WRITE_ATTRIBUTE: { + ChipLogProgress(NotSpecified, "Writing Attribute: endpointId=%d, clusterId=%04lx, attributeId=%04lx, args.size=%lu", + task.endpointId, static_cast(task.clusterId), static_cast(task.actionId), + static_cast(task.args.size())); + delegate->AttributeWriteHandler(task.endpointId, static_cast(task.actionId), task.args); + } + break; + case ActionType::RUN_COMMAND: { + ChipLogProgress(NotSpecified, "Running Command: endpointId=%d, clusterId=%04lx, commandId=%04lx, args.size=%lu", + task.endpointId, static_cast(task.clusterId), static_cast(task.actionId), + static_cast(task.args.size())); + delegate->CommandHandler(task.endpointId, static_cast(task.actionId), task.args); + } + break; + case ActionType::EMIT_EVENT: { + ChipLogProgress(NotSpecified, "Emitting Event: endpointId=%d, clusterId=%04lx, eventIdId=%04lx, args.size=%lu", + task.endpointId, static_cast(task.clusterId), static_cast(task.actionId), + static_cast(task.args.size())); + delegate->EventHandler(task.endpointId, static_cast(task.actionId), task.args); + } + break; + default: + break; + } + + if (queue.empty()) + { + // Return due to no more actions in queue + return; + } + + // Run next action + task = queue.front(); + ChipLogProgress(NotSpecified, "StartTimer: endpointId=%d, clusterId=%04lx, eventIdId=%04lx, task.delyMs=%lu", task.endpointId, + static_cast(task.clusterId), static_cast(task.actionId), + static_cast(task.delayMs)); + (void) DeviceLayer::SystemLayer().StartTimer(System::Clock::Milliseconds32(task.delayMs), RpcActionsTaskCallback, this); +} + +void ChefRpcActionsWorker::RegisterRpcActionsDelegate(ClusterId clusterId, ActionsDelegate * delegate) +{ + // Register by cluster + if (nullptr == RpcFindActionsDelegate(clusterId)) + { + gActionsDelegateMap[clusterId] = delegate; + return; + } +} + +ChefRpcActionsWorker::ChefRpcActionsWorker() +{ + chip::rpc::SubscribeActions(ChefRpcActionsCallback); +} + +static ChefRpcActionsWorker instance; + +ChefRpcActionsWorker & ChefRpcActionsWorker::Instance() +{ + return instance; +} diff --git a/examples/chef/common/chef-rpc-actions-worker.h b/examples/chef/common/chef-rpc-actions-worker.h new file mode 100644 index 00000000000000..3ca16f4c8a716e --- /dev/null +++ b/examples/chef/common/chef-rpc-actions-worker.h @@ -0,0 +1,79 @@ +/* + * + * Copyright (c) 2024 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include +#include +#include +#include +#include +#include + +#include "Rpc.h" + +namespace chip { +namespace app { + +class ActionsDelegate +{ +public: + ActionsDelegate(ClusterId clusterId) : mClusterId(clusterId){}; + + virtual ~ActionsDelegate() = default; + + virtual void AttributeWriteHandler(chip::EndpointId endpointId, chip::AttributeId attributeId, std::vector args) = 0; + virtual void CommandHandler(chip::EndpointId endpointId, chip::CommandId commandId, std::vector args) = 0; + virtual void EventHandler(chip::EndpointId endpointId, chip::EventId eventId, std::vector args) = 0; + +protected: + ClusterId mClusterId; +}; + +struct ActionTask +{ + chip::EndpointId endpointId; + chip::ClusterId clusterId; + chip::rpc::ActionType type; // Aligned with Storage buf + uint32_t delayMs; + uint32_t actionId; + std::vector args; + ActionTask(chip::EndpointId endpoint, chip::ClusterId cluster, chip::rpc::ActionType actionType, uint32_t delay, uint32_t id, + std::vector arg) : + endpointId(endpoint), + clusterId(cluster), type(actionType), delayMs(delay), actionId(id), args(arg){}; + ~ActionTask(){}; +}; + +class ChefRpcActionsWorker +{ +public: + static ChefRpcActionsWorker & Instance(); + + ChefRpcActionsWorker(); + + bool EnqueueAction(ActionTask task); + void ProcessActionQueue(); + void RegisterRpcActionsDelegate(ClusterId clusterId, ActionsDelegate * delegate); + +private: + std::queue queue; +}; + +} // namespace app +} // namespace chip diff --git a/examples/chef/common/clusters/switch/SwitchEventHandler.cpp b/examples/chef/common/clusters/switch/SwitchEventHandler.cpp new file mode 100644 index 00000000000000..dd32e2b907bb5a --- /dev/null +++ b/examples/chef/common/clusters/switch/SwitchEventHandler.cpp @@ -0,0 +1,82 @@ +/* + * + * Copyright (c) 2022 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#ifdef MATTER_DM_PLUGIN_SWITCH_SERVER +#include +#include +#include +#include + +#include "SwitchEventHandler.h" + +using namespace chip; +using namespace chip::app; +using namespace chip::app::Clusters; +using namespace chip::app::Clusters::Switch; +using namespace chip::DeviceLayer; + +void SwitchEventHandler::OnSwitchLatched(EndpointId endpointId, uint8_t newPosition) +{ + ChipLogDetail(NotSpecified, "%s: endpointId=%d, newPosition=%d", __func__, endpointId, newPosition); + + Clusters::SwitchServer::Instance().OnSwitchLatch(endpointId, newPosition); +} + +void SwitchEventHandler::OnInitialPress(EndpointId endpointId, uint8_t newPosition) +{ + ChipLogDetail(NotSpecified, "%s: endpointId=%d, newPosition=%d", __func__, endpointId, newPosition); + + Clusters::SwitchServer::Instance().OnInitialPress(endpointId, newPosition); +} + +void SwitchEventHandler::OnLongPress(EndpointId endpointId, uint8_t newPosition) +{ + ChipLogDetail(NotSpecified, "%s: endpointId=%d, newPosition=%d", __func__, endpointId, newPosition); + + Clusters::SwitchServer::Instance().OnLongPress(endpointId, newPosition); +} + +void SwitchEventHandler::OnShortRelease(EndpointId endpointId, uint8_t previousPosition) +{ + ChipLogDetail(NotSpecified, "%s: endpointId=%d, previousPosition=%d", __func__, endpointId, previousPosition); + + Clusters::SwitchServer::Instance().OnShortRelease(endpointId, previousPosition); +} + +void SwitchEventHandler::OnLongRelease(EndpointId endpointId, uint8_t previousPosition) +{ + ChipLogDetail(NotSpecified, "%s: endpointId=%d, previousPosition=%d", __func__, endpointId, previousPosition); + + Clusters::SwitchServer::Instance().OnLongRelease(endpointId, previousPosition); +} + +void SwitchEventHandler::OnMultiPressOngoing(EndpointId endpointId, uint8_t newPosition, uint8_t count) +{ + ChipLogDetail(NotSpecified, "%s: endpointId=%d, newPosition=%d, count=%d", __func__, endpointId, newPosition, count); + + Clusters::SwitchServer::Instance().OnMultiPressOngoing(endpointId, newPosition, count); +} + +void SwitchEventHandler::OnMultiPressComplete(EndpointId endpointId, uint8_t previousPosition, uint8_t count) +{ + ChipLogDetail(NotSpecified, "%s: endpointId=%d, previousPosition=%d, count=%d", __func__, endpointId, previousPosition, count); + + Clusters::SwitchServer::Instance().OnMultiPressComplete(endpointId, previousPosition, count); +} +#endif // MATTER_DM_PLUGIN_SWITCH_SERVER diff --git a/examples/chef/common/clusters/switch/SwitchEventHandler.h b/examples/chef/common/clusters/switch/SwitchEventHandler.h new file mode 100644 index 00000000000000..1648e19cc829c5 --- /dev/null +++ b/examples/chef/common/clusters/switch/SwitchEventHandler.h @@ -0,0 +1,80 @@ +/* + * + * Copyright (c) 2022 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 + +namespace chip { +namespace app { +namespace Clusters { + +namespace Switch { + +class SwitchEventHandler +{ +public: + SwitchEventHandler(){}; + + /** + * Should be called when the latching switch is moved to a new position. + */ + void OnSwitchLatched(EndpointId endpointId, uint8_t newPosition); + + /** + * Should be called when the momentary switch starts to be pressed. + */ + void OnInitialPress(EndpointId endpointId, uint8_t newPosition); + + /** + * Should be called when the momentary switch has been pressed for a "long" time. + */ + void OnLongPress(EndpointId endpointId, uint8_t newPosition); + + /** + * Should be called when the momentary switch has been released. + */ + void OnShortRelease(EndpointId endpointId, uint8_t previousPosition); + + /** + * Should be called when the momentary switch has been released after having been pressed for a long time. + */ + void OnLongRelease(EndpointId endpointId, uint8_t previousPosition); + + /** + * Should be called to indicate how many times the momentary switch has been pressed in a multi-press + * sequence, during that sequence. + */ + void OnMultiPressOngoing(EndpointId endpointId, uint8_t newPosition, uint8_t count); + + /** + * Should be called to indicate how many times the momentary switch has been pressed in a multi-press + * sequence, after it has been detected that the sequence has ended. + */ + void OnMultiPressComplete(EndpointId endpointId, uint8_t previousPosition, uint8_t count); + +private: +}; + +} // namespace Switch +} // namespace Clusters +} // namespace app +} // namespace chip diff --git a/examples/chef/common/clusters/switch/SwitchManager.cpp b/examples/chef/common/clusters/switch/SwitchManager.cpp new file mode 100644 index 00000000000000..45d39dd4bce1a4 --- /dev/null +++ b/examples/chef/common/clusters/switch/SwitchManager.cpp @@ -0,0 +1,172 @@ +/* + * + * Copyright (c) 2022 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. + */ + +#ifdef MATTER_DM_PLUGIN_SWITCH_SERVER +#include "SwitchEventHandler.h" +#include +#include +#include +#include +#include +#include + +#include "chef-descriptor-namespace.h" +#include "chef-rpc-actions-worker.h" + +using namespace chip; +using namespace chip::app; +using namespace chip::app::Clusters; +using namespace chip::app::Clusters::Switch; +using namespace chip::DeviceLayer; + +using namespace chip::rpc; +using namespace chip::app; + +class SwitchActionsDelegate : public chip::app::ActionsDelegate +{ +public: + SwitchActionsDelegate(ClusterId clusterId, SwitchEventHandler * eventHandler) : + ActionsDelegate(clusterId), mEventHandler(eventHandler){}; + ~SwitchActionsDelegate() override{}; + + void AttributeWriteHandler(chip::EndpointId endpointId, chip::AttributeId attributeId, std::vector args) override; + void CommandHandler(chip::EndpointId endpointId, chip::AttributeId attributeId, std::vector args) override{}; + void EventHandler(chip::EndpointId endpointId, chip::EventId eventId, std::vector args) override; + +private: + SwitchEventHandler * mEventHandler; +}; + +void SwitchActionsDelegate::AttributeWriteHandler(chip::EndpointId endpointId, chip::AttributeId attributeId, + std::vector args) +{ + if (args.empty()) + { + ChipLogError(NotSpecified, "Queue is empty "); + return; + } + + switch (attributeId) + { + case Switch::Attributes::NumberOfPositions::Id: { + uint8_t data = static_cast(args[0]); + app::Clusters::Switch::Attributes::NumberOfPositions::Set(endpointId, data); + } + break; + case Switch::Attributes::CurrentPosition::Id: { + uint8_t data = static_cast(args[0]); + app::Clusters::Switch::Attributes::CurrentPosition::Set(endpointId, data); + } + break; + case Switch::Attributes::MultiPressMax::Id: { + uint8_t data = static_cast(args[0]); + app::Clusters::Switch::Attributes::MultiPressMax::Set(endpointId, data); + } + break; + default: + break; + } +} + +void SwitchActionsDelegate::EventHandler(chip::EndpointId endpointId, chip::EventId eventId, std::vector args) +{ + if (args.empty()) + { + ChipLogError(NotSpecified, "Queue is empty "); + return; + } + switch (eventId) + { + case Events::SwitchLatched::Id: { + uint8_t newPosition = static_cast(args[0]); + mEventHandler->OnSwitchLatched(endpointId, newPosition); + } + break; + case Events::InitialPress::Id: { + uint8_t newPosition = static_cast(args[0]); + mEventHandler->OnInitialPress(endpointId, newPosition); + } + break; + case Events::LongPress::Id: { + uint8_t newPosition = static_cast(args[0]); + mEventHandler->OnLongPress(endpointId, newPosition); + } + break; + case Events::ShortRelease::Id: { + uint8_t previousPosition = static_cast(args[0]); + mEventHandler->OnShortRelease(endpointId, previousPosition); + } + break; + case Events::LongRelease::Id: { + uint8_t previousPosition = static_cast(args[0]); + mEventHandler->OnLongRelease(endpointId, previousPosition); + } + break; + case Events::MultiPressOngoing::Id: { + if (args.size() < 2) + { + ChipLogError(NotSpecified, "MultiPressOngoing has too few arguments"); + return; + } + uint8_t newPosition = static_cast(args[0]); + uint8_t currentNumberOfPressesCounted = static_cast(args[1]); + mEventHandler->OnMultiPressOngoing(endpointId, newPosition, currentNumberOfPressesCounted); + } + break; + case Events::MultiPressComplete::Id: { + if (args.size() < 2) + { + ChipLogError(NotSpecified, "MultiPressComplete has too few arguments"); + return; + } + uint8_t previousPosition = static_cast(args[0]); + uint8_t totalNumberOfPressesCounted = static_cast(args[1]); + mEventHandler->OnMultiPressComplete(endpointId, previousPosition, totalNumberOfPressesCounted); + } + break; + default: + break; + } +}; + +const Clusters::Descriptor::Structs::SemanticTagStruct::Type gLatchingSwitch[] = { + { .namespaceID = kNamespaceCommonLevel, + .tag = kTagCommonLow, + .label = chip::Optional>( + { chip::app::DataModel::MakeNullable(chip::CharSpan("Low", 3)) }) }, + { .namespaceID = kNamespaceCommonLevel, + .tag = kTagCommonMedium, + .label = chip::Optional>( + { chip::app::DataModel::MakeNullable(chip::CharSpan("Medium", 6)) }) }, + { .namespaceID = kNamespaceCommonLevel, + .tag = kTagCommonHigh, + .label = chip::Optional>( + { chip::app::DataModel::MakeNullable(chip::CharSpan("High", 4)) }) } +}; + +static SwitchEventHandler * gSwitchEventHandler = new SwitchEventHandler(); +static SwitchActionsDelegate * gSwitchActionsDelegate = new SwitchActionsDelegate(Clusters::Switch::Id, gSwitchEventHandler); + +void emberAfSwitchClusterInitCallback(EndpointId endpointId) +{ + ChipLogProgress(Zcl, "Chef: emberAfSwitchClusterInitCallback"); + + ChefRpcActionsWorker::Instance().RegisterRpcActionsDelegate(Clusters::Switch::Id, gSwitchActionsDelegate); + SetTagList(/* endpoint= */ 1, Span(gLatchingSwitch)); +} +#endif // MATTER_DM_PLUGIN_SWITCH_SERVER diff --git a/examples/chef/common/stubs.cpp b/examples/chef/common/stubs.cpp index 5756aaa35b7e26..437dfe9e6221be 100644 --- a/examples/chef/common/stubs.cpp +++ b/examples/chef/common/stubs.cpp @@ -236,6 +236,16 @@ void emberAfWakeOnLanClusterInitCallback(EndpointId endpoint) } #endif +void ApplicationInit() +{ + ChipLogProgress(NotSpecified, "Chef Application Init !!!") +} + +void ApplicationShutdown() +{ + ChipLogProgress(NotSpecified, "Chef Application Down !!!") +} + // No-op function, used to force linking this file, // instead of the weak functions from other files extern "C" void chef_include_stubs_impl(void) {} diff --git a/examples/chef/devices/rootnode_genericswitch_2dfff6e516.matter b/examples/chef/devices/rootnode_genericswitch_2dfff6e516.matter new file mode 100644 index 00000000000000..89319a4b61b4e2 --- /dev/null +++ b/examples/chef/devices/rootnode_genericswitch_2dfff6e516.matter @@ -0,0 +1,1498 @@ +// This IDL was generated automatically by ZAP. +// It is for view/code review purposes only. + +/** Attributes and commands for putting a device into Identification mode (e.g. flashing a light). */ +cluster Identify = 3 { + revision 4; + + enum EffectIdentifierEnum : enum8 { + kBlink = 0; + kBreathe = 1; + kOkay = 2; + kChannelChange = 11; + kFinishEffect = 254; + kStopEffect = 255; + } + + enum EffectVariantEnum : enum8 { + kDefault = 0; + } + + enum IdentifyTypeEnum : enum8 { + kNone = 0; + kLightOutput = 1; + kVisibleIndicator = 2; + kAudibleBeep = 3; + kDisplay = 4; + kActuator = 5; + } + + attribute int16u identifyTime = 0; + readonly attribute IdentifyTypeEnum identifyType = 1; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + request struct IdentifyRequest { + int16u identifyTime = 0; + } + + request struct TriggerEffectRequest { + EffectIdentifierEnum effectIdentifier = 0; + EffectVariantEnum effectVariant = 1; + } + + /** Command description for Identify */ + command access(invoke: manage) Identify(IdentifyRequest): DefaultSuccess = 0; + /** Command description for TriggerEffect */ + command access(invoke: manage) TriggerEffect(TriggerEffectRequest): DefaultSuccess = 64; +} + +/** The Descriptor Cluster is meant to replace the support from the Zigbee Device Object (ZDO) for describing a node, its endpoints and clusters. */ +cluster Descriptor = 29 { + revision 2; + + bitmap Feature : bitmap32 { + kTagList = 0x1; + } + + struct DeviceTypeStruct { + devtype_id deviceType = 0; + int16u revision = 1; + } + + struct SemanticTagStruct { + nullable vendor_id mfgCode = 0; + enum8 namespaceID = 1; + enum8 tag = 2; + optional nullable char_string label = 3; + } + + readonly attribute DeviceTypeStruct deviceTypeList[] = 0; + readonly attribute cluster_id serverList[] = 1; + readonly attribute cluster_id clientList[] = 2; + readonly attribute endpoint_no partsList[] = 3; + readonly attribute optional SemanticTagStruct tagList[] = 4; + 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; +} + +/** The Access Control Cluster exposes a data model view of a + Node's Access Control List (ACL), which codifies the rules used to manage + and enforce Access Control for the Node's endpoints and their associated + cluster instances. */ +cluster AccessControl = 31 { + revision 1; // NOTE: Default/not specifically set + + enum AccessControlEntryAuthModeEnum : enum8 { + kPASE = 1; + kCASE = 2; + kGroup = 3; + } + + enum AccessControlEntryPrivilegeEnum : enum8 { + kView = 1; + kProxyView = 2; + kOperate = 3; + kManage = 4; + kAdminister = 5; + } + + enum ChangeTypeEnum : enum8 { + kChanged = 0; + kAdded = 1; + kRemoved = 2; + } + + struct AccessControlTargetStruct { + nullable cluster_id cluster = 0; + nullable endpoint_no endpoint = 1; + nullable devtype_id deviceType = 2; + } + + fabric_scoped struct AccessControlEntryStruct { + fabric_sensitive AccessControlEntryPrivilegeEnum privilege = 1; + fabric_sensitive AccessControlEntryAuthModeEnum authMode = 2; + nullable fabric_sensitive int64u subjects[] = 3; + nullable fabric_sensitive AccessControlTargetStruct targets[] = 4; + fabric_idx fabricIndex = 254; + } + + fabric_scoped struct AccessControlExtensionStruct { + fabric_sensitive octet_string<128> data = 1; + fabric_idx fabricIndex = 254; + } + + fabric_sensitive info event access(read: administer) AccessControlEntryChanged = 0 { + nullable node_id adminNodeID = 1; + nullable int16u adminPasscodeID = 2; + ChangeTypeEnum changeType = 3; + nullable AccessControlEntryStruct latestValue = 4; + fabric_idx fabricIndex = 254; + } + + fabric_sensitive info event access(read: administer) AccessControlExtensionChanged = 1 { + nullable node_id adminNodeID = 1; + nullable int16u adminPasscodeID = 2; + ChangeTypeEnum changeType = 3; + nullable AccessControlExtensionStruct latestValue = 4; + fabric_idx fabricIndex = 254; + } + + attribute access(read: administer, write: administer) AccessControlEntryStruct acl[] = 0; + attribute access(read: administer, write: administer) optional AccessControlExtensionStruct extension[] = 1; + readonly attribute int16u subjectsPerAccessControlEntry = 2; + readonly attribute int16u targetsPerAccessControlEntry = 3; + readonly attribute int16u accessControlEntriesPerFabric = 4; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; +} + +/** This cluster provides attributes and events for determining basic information about Nodes, which supports both + Commissioning and operational determination of Node characteristics, such as Vendor ID, Product ID and serial number, + which apply to the whole Node. Also allows setting user device information such as location. */ +cluster BasicInformation = 40 { + revision 3; + + enum ColorEnum : enum8 { + kBlack = 0; + kNavy = 1; + kGreen = 2; + kTeal = 3; + kMaroon = 4; + kPurple = 5; + kOlive = 6; + kGray = 7; + kBlue = 8; + kLime = 9; + kAqua = 10; + kRed = 11; + kFuchsia = 12; + kYellow = 13; + kWhite = 14; + kNickel = 15; + kChrome = 16; + kBrass = 17; + kCopper = 18; + kSilver = 19; + kGold = 20; + } + + enum ProductFinishEnum : enum8 { + kOther = 0; + kMatte = 1; + kSatin = 2; + kPolished = 3; + kRugged = 4; + kFabric = 5; + } + + struct CapabilityMinimaStruct { + int16u caseSessionsPerFabric = 0; + int16u subscriptionsPerFabric = 1; + } + + struct ProductAppearanceStruct { + ProductFinishEnum finish = 0; + nullable ColorEnum primaryColor = 1; + } + + critical event StartUp = 0 { + int32u softwareVersion = 0; + } + + critical event ShutDown = 1 { + } + + info event Leave = 2 { + fabric_idx fabricIndex = 0; + } + + info event ReachableChanged = 3 { + boolean reachableNewValue = 0; + } + + readonly attribute int16u dataModelRevision = 0; + readonly attribute char_string<32> vendorName = 1; + readonly attribute vendor_id vendorID = 2; + readonly attribute char_string<32> productName = 3; + readonly attribute int16u productID = 4; + attribute access(write: manage) char_string<32> nodeLabel = 5; + attribute access(write: administer) char_string<2> location = 6; + readonly attribute int16u hardwareVersion = 7; + readonly attribute char_string<64> hardwareVersionString = 8; + readonly attribute int32u softwareVersion = 9; + readonly attribute char_string<64> softwareVersionString = 10; + readonly attribute optional char_string<16> manufacturingDate = 11; + readonly attribute optional char_string<32> partNumber = 12; + readonly attribute optional long_char_string<256> productURL = 13; + readonly attribute optional char_string<64> productLabel = 14; + readonly attribute optional char_string<32> serialNumber = 15; + attribute access(write: manage) optional boolean localConfigDisabled = 16; + readonly attribute optional boolean reachable = 17; + readonly attribute optional char_string<32> uniqueID = 18; + readonly attribute CapabilityMinimaStruct capabilityMinima = 19; + readonly attribute optional ProductAppearanceStruct productAppearance = 20; + readonly attribute int32u specificationVersion = 21; + readonly attribute int16u maxPathsPerInvoke = 22; + 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; + + command MfgSpecificPing(): DefaultSuccess = 0; +} + +/** This cluster is used to describe the configuration and capabilities of a physical power source that provides power to the Node. */ +cluster PowerSource = 47 { + revision 1; // NOTE: Default/not specifically set + + enum BatApprovedChemistryEnum : enum16 { + kUnspecified = 0; + kAlkaline = 1; + kLithiumCarbonFluoride = 2; + kLithiumChromiumOxide = 3; + kLithiumCopperOxide = 4; + kLithiumIronDisulfide = 5; + kLithiumManganeseDioxide = 6; + kLithiumThionylChloride = 7; + kMagnesium = 8; + kMercuryOxide = 9; + kNickelOxyhydride = 10; + kSilverOxide = 11; + kZincAir = 12; + kZincCarbon = 13; + kZincChloride = 14; + kZincManganeseDioxide = 15; + kLeadAcid = 16; + kLithiumCobaltOxide = 17; + kLithiumIon = 18; + kLithiumIonPolymer = 19; + kLithiumIronPhosphate = 20; + kLithiumSulfur = 21; + kLithiumTitanate = 22; + kNickelCadmium = 23; + kNickelHydrogen = 24; + kNickelIron = 25; + kNickelMetalHydride = 26; + kNickelZinc = 27; + kSilverZinc = 28; + kSodiumIon = 29; + kSodiumSulfur = 30; + kZincBromide = 31; + kZincCerium = 32; + } + + enum BatChargeFaultEnum : enum8 { + kUnspecified = 0; + kAmbientTooHot = 1; + kAmbientTooCold = 2; + kBatteryTooHot = 3; + kBatteryTooCold = 4; + kBatteryAbsent = 5; + kBatteryOverVoltage = 6; + kBatteryUnderVoltage = 7; + kChargerOverVoltage = 8; + kChargerUnderVoltage = 9; + kSafetyTimeout = 10; + } + + enum BatChargeLevelEnum : enum8 { + kOK = 0; + kWarning = 1; + kCritical = 2; + } + + enum BatChargeStateEnum : enum8 { + kUnknown = 0; + kIsCharging = 1; + kIsAtFullCharge = 2; + kIsNotCharging = 3; + } + + enum BatCommonDesignationEnum : enum16 { + kUnspecified = 0; + kAAA = 1; + kAA = 2; + kC = 3; + kD = 4; + k4v5 = 5; + k6v0 = 6; + k9v0 = 7; + k12AA = 8; + kAAAA = 9; + kA = 10; + kB = 11; + kF = 12; + kN = 13; + kNo6 = 14; + kSubC = 15; + kA23 = 16; + kA27 = 17; + kBA5800 = 18; + kDuplex = 19; + k4SR44 = 20; + k523 = 21; + k531 = 22; + k15v0 = 23; + k22v5 = 24; + k30v0 = 25; + k45v0 = 26; + k67v5 = 27; + kJ = 28; + kCR123A = 29; + kCR2 = 30; + k2CR5 = 31; + kCRP2 = 32; + kCRV3 = 33; + kSR41 = 34; + kSR43 = 35; + kSR44 = 36; + kSR45 = 37; + kSR48 = 38; + kSR54 = 39; + kSR55 = 40; + kSR57 = 41; + kSR58 = 42; + kSR59 = 43; + kSR60 = 44; + kSR63 = 45; + kSR64 = 46; + kSR65 = 47; + kSR66 = 48; + kSR67 = 49; + kSR68 = 50; + kSR69 = 51; + kSR516 = 52; + kSR731 = 53; + kSR712 = 54; + kLR932 = 55; + kA5 = 56; + kA10 = 57; + kA13 = 58; + kA312 = 59; + kA675 = 60; + kAC41E = 61; + k10180 = 62; + k10280 = 63; + k10440 = 64; + k14250 = 65; + k14430 = 66; + k14500 = 67; + k14650 = 68; + k15270 = 69; + k16340 = 70; + kRCR123A = 71; + k17500 = 72; + k17670 = 73; + k18350 = 74; + k18500 = 75; + k18650 = 76; + k19670 = 77; + k25500 = 78; + k26650 = 79; + k32600 = 80; + } + + enum BatFaultEnum : enum8 { + kUnspecified = 0; + kOverTemp = 1; + kUnderTemp = 2; + } + + enum BatReplaceabilityEnum : enum8 { + kUnspecified = 0; + kNotReplaceable = 1; + kUserReplaceable = 2; + kFactoryReplaceable = 3; + } + + enum PowerSourceStatusEnum : enum8 { + kUnspecified = 0; + kActive = 1; + kStandby = 2; + kUnavailable = 3; + } + + enum WiredCurrentTypeEnum : enum8 { + kAC = 0; + kDC = 1; + } + + enum WiredFaultEnum : enum8 { + kUnspecified = 0; + kOverVoltage = 1; + kUnderVoltage = 2; + } + + bitmap Feature : bitmap32 { + kWired = 0x1; + kBattery = 0x2; + kRechargeable = 0x4; + kReplaceable = 0x8; + } + + struct BatChargeFaultChangeType { + BatChargeFaultEnum current[] = 0; + BatChargeFaultEnum previous[] = 1; + } + + struct BatFaultChangeType { + BatFaultEnum current[] = 0; + BatFaultEnum previous[] = 1; + } + + struct WiredFaultChangeType { + WiredFaultEnum current[] = 0; + WiredFaultEnum previous[] = 1; + } + + info event WiredFaultChange = 0 { + WiredFaultEnum current[] = 0; + WiredFaultEnum previous[] = 1; + } + + info event BatFaultChange = 1 { + BatFaultEnum current[] = 0; + BatFaultEnum previous[] = 1; + } + + info event BatChargeFaultChange = 2 { + BatChargeFaultEnum current[] = 0; + BatChargeFaultEnum previous[] = 1; + } + + readonly attribute PowerSourceStatusEnum status = 0; + readonly attribute int8u order = 1; + readonly attribute char_string<60> description = 2; + readonly attribute optional nullable int32u wiredAssessedInputVoltage = 3; + readonly attribute optional nullable int16u wiredAssessedInputFrequency = 4; + readonly attribute optional WiredCurrentTypeEnum wiredCurrentType = 5; + readonly attribute optional nullable int32u wiredAssessedCurrent = 6; + readonly attribute optional int32u wiredNominalVoltage = 7; + readonly attribute optional int32u wiredMaximumCurrent = 8; + readonly attribute optional boolean wiredPresent = 9; + readonly attribute optional WiredFaultEnum activeWiredFaults[] = 10; + readonly attribute optional nullable int32u batVoltage = 11; + readonly attribute optional nullable int8u batPercentRemaining = 12; + readonly attribute optional nullable int32u batTimeRemaining = 13; + readonly attribute optional BatChargeLevelEnum batChargeLevel = 14; + readonly attribute optional boolean batReplacementNeeded = 15; + readonly attribute optional BatReplaceabilityEnum batReplaceability = 16; + readonly attribute optional boolean batPresent = 17; + readonly attribute optional BatFaultEnum activeBatFaults[] = 18; + readonly attribute optional char_string<60> batReplacementDescription = 19; + readonly attribute optional BatCommonDesignationEnum batCommonDesignation = 20; + readonly attribute optional char_string<20> batANSIDesignation = 21; + readonly attribute optional char_string<20> batIECDesignation = 22; + readonly attribute optional BatApprovedChemistryEnum batApprovedChemistry = 23; + readonly attribute optional int32u batCapacity = 24; + readonly attribute optional int8u batQuantity = 25; + readonly attribute optional BatChargeStateEnum batChargeState = 26; + readonly attribute optional nullable int32u batTimeToFullCharge = 27; + readonly attribute optional boolean batFunctionalWhileCharging = 28; + readonly attribute optional nullable int32u batChargingCurrent = 29; + readonly attribute optional BatChargeFaultEnum activeBatChargeFaults[] = 30; + readonly attribute endpoint_no endpointList[] = 31; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; +} + +/** This cluster is used to manage global aspects of the Commissioning flow. */ +cluster GeneralCommissioning = 48 { + revision 1; // NOTE: Default/not specifically set + + enum CommissioningErrorEnum : enum8 { + kOK = 0; + kValueOutsideRange = 1; + kInvalidAuthentication = 2; + kNoFailSafe = 3; + kBusyWithOtherAdmin = 4; + } + + enum RegulatoryLocationTypeEnum : enum8 { + kIndoor = 0; + kOutdoor = 1; + kIndoorOutdoor = 2; + } + + struct BasicCommissioningInfo { + int16u failSafeExpiryLengthSeconds = 0; + int16u maxCumulativeFailsafeSeconds = 1; + } + + attribute access(write: administer) int64u breadcrumb = 0; + readonly attribute BasicCommissioningInfo basicCommissioningInfo = 1; + readonly attribute RegulatoryLocationTypeEnum regulatoryConfig = 2; + readonly attribute RegulatoryLocationTypeEnum locationCapability = 3; + readonly attribute boolean supportsConcurrentConnection = 4; + 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 ArmFailSafeRequest { + int16u expiryLengthSeconds = 0; + int64u breadcrumb = 1; + } + + response struct ArmFailSafeResponse = 1 { + CommissioningErrorEnum errorCode = 0; + char_string<128> debugText = 1; + } + + request struct SetRegulatoryConfigRequest { + RegulatoryLocationTypeEnum newRegulatoryConfig = 0; + char_string<2> countryCode = 1; + int64u breadcrumb = 2; + } + + response struct SetRegulatoryConfigResponse = 3 { + CommissioningErrorEnum errorCode = 0; + char_string debugText = 1; + } + + response struct CommissioningCompleteResponse = 5 { + CommissioningErrorEnum errorCode = 0; + char_string debugText = 1; + } + + /** Arm the persistent fail-safe timer with an expiry time of now + ExpiryLengthSeconds using device clock */ + command access(invoke: administer) ArmFailSafe(ArmFailSafeRequest): ArmFailSafeResponse = 0; + /** Set the regulatory configuration to be used during commissioning */ + command access(invoke: administer) SetRegulatoryConfig(SetRegulatoryConfigRequest): SetRegulatoryConfigResponse = 2; + /** Signals the Server that the Client has successfully completed all steps of Commissioning/Recofiguration needed during fail-safe period. */ + fabric command access(invoke: administer) CommissioningComplete(): CommissioningCompleteResponse = 4; +} + +/** Functionality to configure, enable, disable network credentials and access on a Matter device. */ +cluster NetworkCommissioning = 49 { + revision 1; // NOTE: Default/not specifically set + + enum NetworkCommissioningStatusEnum : enum8 { + kSuccess = 0; + kOutOfRange = 1; + kBoundsExceeded = 2; + kNetworkIDNotFound = 3; + kDuplicateNetworkID = 4; + kNetworkNotFound = 5; + kRegulatoryError = 6; + kAuthFailure = 7; + kUnsupportedSecurity = 8; + kOtherConnectionFailure = 9; + kIPV6Failed = 10; + kIPBindFailed = 11; + kUnknownError = 12; + } + + enum WiFiBandEnum : enum8 { + k2G4 = 0; + k3G65 = 1; + k5G = 2; + k6G = 3; + k60G = 4; + k1G = 5; + } + + bitmap Feature : bitmap32 { + kWiFiNetworkInterface = 0x1; + kThreadNetworkInterface = 0x2; + kEthernetNetworkInterface = 0x4; + kPerDeviceCredentials = 0x8; + } + + bitmap ThreadCapabilitiesBitmap : bitmap16 { + kIsBorderRouterCapable = 0x1; + kIsRouterCapable = 0x2; + kIsSleepyEndDeviceCapable = 0x4; + kIsFullThreadDevice = 0x8; + kIsSynchronizedSleepyEndDeviceCapable = 0x10; + } + + bitmap WiFiSecurityBitmap : bitmap8 { + kUnencrypted = 0x1; + kWEP = 0x2; + kWPAPersonal = 0x4; + kWPA2Personal = 0x8; + kWPA3Personal = 0x10; + kWPA3MatterPDC = 0x20; + } + + struct NetworkInfoStruct { + octet_string<32> networkID = 0; + boolean connected = 1; + optional nullable octet_string<20> networkIdentifier = 2; + optional nullable octet_string<20> clientIdentifier = 3; + } + + struct ThreadInterfaceScanResultStruct { + int16u panId = 0; + int64u extendedPanId = 1; + char_string<16> networkName = 2; + int16u channel = 3; + int8u version = 4; + octet_string<8> extendedAddress = 5; + int8s rssi = 6; + int8u lqi = 7; + } + + struct WiFiInterfaceScanResultStruct { + WiFiSecurityBitmap security = 0; + octet_string<32> ssid = 1; + octet_string<6> bssid = 2; + int16u channel = 3; + WiFiBandEnum wiFiBand = 4; + int8s rssi = 5; + } + + readonly attribute access(read: administer) int8u maxNetworks = 0; + readonly attribute access(read: administer) NetworkInfoStruct networks[] = 1; + readonly attribute optional int8u scanMaxTimeSeconds = 2; + readonly attribute optional int8u connectMaxTimeSeconds = 3; + attribute access(write: administer) boolean interfaceEnabled = 4; + readonly attribute access(read: administer) nullable NetworkCommissioningStatusEnum lastNetworkingStatus = 5; + readonly attribute access(read: administer) nullable octet_string<32> lastNetworkID = 6; + readonly attribute access(read: administer) nullable int32s lastConnectErrorValue = 7; + readonly attribute optional WiFiBandEnum supportedWiFiBands[] = 8; + readonly attribute optional ThreadCapabilitiesBitmap supportedThreadFeatures = 9; + readonly attribute optional int16u threadVersion = 10; + 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 ScanNetworksRequest { + optional nullable octet_string<32> ssid = 0; + optional int64u breadcrumb = 1; + } + + response struct ScanNetworksResponse = 1 { + NetworkCommissioningStatusEnum networkingStatus = 0; + optional char_string debugText = 1; + optional WiFiInterfaceScanResultStruct wiFiScanResults[] = 2; + optional ThreadInterfaceScanResultStruct threadScanResults[] = 3; + } + + request struct AddOrUpdateWiFiNetworkRequest { + octet_string<32> ssid = 0; + octet_string<64> credentials = 1; + optional int64u breadcrumb = 2; + optional octet_string<140> networkIdentity = 3; + optional octet_string<20> clientIdentifier = 4; + optional octet_string<32> possessionNonce = 5; + } + + request struct AddOrUpdateThreadNetworkRequest { + octet_string<254> operationalDataset = 0; + optional int64u breadcrumb = 1; + } + + request struct RemoveNetworkRequest { + octet_string<32> networkID = 0; + optional int64u breadcrumb = 1; + } + + response struct NetworkConfigResponse = 5 { + NetworkCommissioningStatusEnum networkingStatus = 0; + optional char_string<512> debugText = 1; + optional int8u networkIndex = 2; + optional octet_string<140> clientIdentity = 3; + optional octet_string<64> possessionSignature = 4; + } + + request struct ConnectNetworkRequest { + octet_string<32> networkID = 0; + optional int64u breadcrumb = 1; + } + + response struct ConnectNetworkResponse = 7 { + NetworkCommissioningStatusEnum networkingStatus = 0; + optional char_string debugText = 1; + nullable int32s errorValue = 2; + } + + request struct ReorderNetworkRequest { + octet_string<32> networkID = 0; + int8u networkIndex = 1; + optional int64u breadcrumb = 2; + } + + request struct QueryIdentityRequest { + octet_string<20> keyIdentifier = 0; + optional octet_string<32> possessionNonce = 1; + } + + response struct QueryIdentityResponse = 10 { + octet_string<140> identity = 0; + optional octet_string<64> possessionSignature = 1; + } + + /** Detemine the set of networks the device sees as available. */ + command access(invoke: administer) ScanNetworks(ScanNetworksRequest): ScanNetworksResponse = 0; + /** Add or update the credentials for a given Wi-Fi network. */ + command access(invoke: administer) AddOrUpdateWiFiNetwork(AddOrUpdateWiFiNetworkRequest): NetworkConfigResponse = 2; + /** Add or update the credentials for a given Thread network. */ + command access(invoke: administer) AddOrUpdateThreadNetwork(AddOrUpdateThreadNetworkRequest): NetworkConfigResponse = 3; + /** Remove the definition of a given network (including its credentials). */ + command access(invoke: administer) RemoveNetwork(RemoveNetworkRequest): NetworkConfigResponse = 4; + /** Connect to the specified network, using previously-defined credentials. */ + command access(invoke: administer) ConnectNetwork(ConnectNetworkRequest): ConnectNetworkResponse = 6; + /** Modify the order in which networks will be presented in the Networks attribute. */ + command access(invoke: administer) ReorderNetwork(ReorderNetworkRequest): NetworkConfigResponse = 8; + /** Retrieve details about and optionally proof of possession of a network client identity. */ + command access(invoke: administer) QueryIdentity(QueryIdentityRequest): QueryIdentityResponse = 9; +} + +/** The cluster provides commands for retrieving unstructured diagnostic logs from a Node that may be used to aid in diagnostics. */ +cluster DiagnosticLogs = 50 { + revision 1; // NOTE: Default/not specifically set + + enum IntentEnum : enum8 { + kEndUserSupport = 0; + kNetworkDiag = 1; + kCrashLogs = 2; + } + + enum StatusEnum : enum8 { + kSuccess = 0; + kExhausted = 1; + kNoLogs = 2; + kBusy = 3; + kDenied = 4; + } + + enum TransferProtocolEnum : enum8 { + kResponsePayload = 0; + kBDX = 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 RetrieveLogsRequestRequest { + IntentEnum intent = 0; + TransferProtocolEnum requestedProtocol = 1; + optional char_string<32> transferFileDesignator = 2; + } + + response struct RetrieveLogsResponse = 1 { + StatusEnum status = 0; + long_octet_string logContent = 1; + optional epoch_us UTCTimeStamp = 2; + optional systime_us timeSinceBoot = 3; + } + + /** Retrieving diagnostic logs from a Node */ + command RetrieveLogsRequest(RetrieveLogsRequestRequest): RetrieveLogsResponse = 0; +} + +/** The General Diagnostics Cluster, along with other diagnostics clusters, provide a means to acquire standardized diagnostics metrics that MAY be used by a Node to assist a user or Administrative Node in diagnosing potential problems. */ +cluster GeneralDiagnostics = 51 { + revision 2; + + enum BootReasonEnum : enum8 { + kUnspecified = 0; + kPowerOnReboot = 1; + kBrownOutReset = 2; + kSoftwareWatchdogReset = 3; + kHardwareWatchdogReset = 4; + kSoftwareUpdateCompleted = 5; + kSoftwareReset = 6; + } + + enum HardwareFaultEnum : enum8 { + kUnspecified = 0; + kRadio = 1; + kSensor = 2; + kResettableOverTemp = 3; + kNonResettableOverTemp = 4; + kPowerSource = 5; + kVisualDisplayFault = 6; + kAudioOutputFault = 7; + kUserInterfaceFault = 8; + kNonVolatileMemoryError = 9; + kTamperDetected = 10; + } + + enum InterfaceTypeEnum : enum8 { + kUnspecified = 0; + kWiFi = 1; + kEthernet = 2; + kCellular = 3; + kThread = 4; + } + + enum NetworkFaultEnum : enum8 { + kUnspecified = 0; + kHardwareFailure = 1; + kNetworkJammed = 2; + kConnectionFailed = 3; + } + + enum RadioFaultEnum : enum8 { + kUnspecified = 0; + kWiFiFault = 1; + kCellularFault = 2; + kThreadFault = 3; + kNFCFault = 4; + kBLEFault = 5; + kEthernetFault = 6; + } + + bitmap Feature : bitmap32 { + kDataModelTest = 0x1; + } + + struct NetworkInterface { + char_string<32> name = 0; + boolean isOperational = 1; + nullable boolean offPremiseServicesReachableIPv4 = 2; + nullable boolean offPremiseServicesReachableIPv6 = 3; + octet_string<8> hardwareAddress = 4; + octet_string IPv4Addresses[] = 5; + octet_string IPv6Addresses[] = 6; + InterfaceTypeEnum type = 7; + } + + critical event HardwareFaultChange = 0 { + HardwareFaultEnum current[] = 0; + HardwareFaultEnum previous[] = 1; + } + + critical event RadioFaultChange = 1 { + RadioFaultEnum current[] = 0; + RadioFaultEnum previous[] = 1; + } + + critical event NetworkFaultChange = 2 { + NetworkFaultEnum current[] = 0; + NetworkFaultEnum previous[] = 1; + } + + critical event BootReason = 3 { + BootReasonEnum bootReason = 0; + } + + readonly attribute NetworkInterface networkInterfaces[] = 0; + readonly attribute int16u rebootCount = 1; + readonly attribute optional int64u upTime = 2; + readonly attribute optional int32u totalOperationalHours = 3; + readonly attribute optional BootReasonEnum bootReason = 4; + readonly attribute optional HardwareFaultEnum activeHardwareFaults[] = 5; + readonly attribute optional RadioFaultEnum activeRadioFaults[] = 6; + readonly attribute optional NetworkFaultEnum activeNetworkFaults[] = 7; + readonly attribute boolean testEventTriggersEnabled = 8; + 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 TestEventTriggerRequest { + octet_string<16> enableKey = 0; + int64u eventTrigger = 1; + } + + response struct TimeSnapshotResponse = 2 { + systime_ms systemTimeMs = 0; + nullable posix_ms posixTimeMs = 1; + } + + request struct PayloadTestRequestRequest { + octet_string<16> enableKey = 0; + int8u value = 1; + int16u count = 2; + } + + response struct PayloadTestResponse = 4 { + octet_string payload = 0; + } + + /** Provide a means for certification tests to trigger some test-plan-specific events */ + command access(invoke: manage) TestEventTrigger(TestEventTriggerRequest): DefaultSuccess = 0; + /** Take a snapshot of system time and epoch time. */ + command TimeSnapshot(): TimeSnapshotResponse = 1; + /** Request a variable length payload response. */ + command PayloadTestRequest(PayloadTestRequestRequest): PayloadTestResponse = 3; +} + +/** This cluster exposes interactions with a switch device, for the purpose of using those interactions by other devices. +Two types of switch devices are supported: latching switch (e.g. rocker switch) and momentary switch (e.g. push button), distinguished with their feature flags. +Interactions with the switch device are exposed as attributes (for the latching switch) and as events (for both types of switches). An interested party MAY subscribe to these attributes/events and thus be informed of the interactions, and can perform actions based on this, for example by sending commands to perform an action such as controlling a light or a window shade. */ +cluster Switch = 59 { + revision 1; + + bitmap Feature : bitmap32 { + kLatchingSwitch = 0x1; + kMomentarySwitch = 0x2; + kMomentarySwitchRelease = 0x4; + kMomentarySwitchLongPress = 0x8; + kMomentarySwitchMultiPress = 0x10; + } + + info event SwitchLatched = 0 { + int8u newPosition = 0; + } + + info event InitialPress = 1 { + int8u newPosition = 0; + } + + info event LongPress = 2 { + int8u newPosition = 0; + } + + info event ShortRelease = 3 { + int8u previousPosition = 0; + } + + info event LongRelease = 4 { + int8u previousPosition = 0; + } + + info event MultiPressOngoing = 5 { + int8u newPosition = 0; + int8u currentNumberOfPressesCounted = 1; + } + + info event MultiPressComplete = 6 { + int8u previousPosition = 0; + int8u totalNumberOfPressesCounted = 1; + } + + readonly attribute int8u numberOfPositions = 0; + readonly attribute int8u currentPosition = 1; + readonly attribute optional int8u multiPressMax = 2; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; +} + +/** Commands to trigger a Node to allow a new Administrator to commission it. */ +cluster AdministratorCommissioning = 60 { + revision 1; // NOTE: Default/not specifically set + + enum CommissioningWindowStatusEnum : enum8 { + kWindowNotOpen = 0; + kEnhancedWindowOpen = 1; + kBasicWindowOpen = 2; + } + + enum StatusCode : enum8 { + kBusy = 2; + kPAKEParameterError = 3; + kWindowNotOpen = 4; + } + + bitmap Feature : bitmap32 { + kBasic = 0x1; + } + + readonly attribute CommissioningWindowStatusEnum windowStatus = 0; + readonly attribute nullable fabric_idx adminFabricIndex = 1; + readonly attribute nullable vendor_id adminVendorId = 2; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + request struct OpenCommissioningWindowRequest { + int16u commissioningTimeout = 0; + octet_string PAKEPasscodeVerifier = 1; + int16u discriminator = 2; + int32u iterations = 3; + octet_string<32> salt = 4; + } + + request struct OpenBasicCommissioningWindowRequest { + int16u commissioningTimeout = 0; + } + + /** This command is used by a current Administrator to instruct a Node to go into commissioning mode using enhanced commissioning method. */ + timed command access(invoke: administer) OpenCommissioningWindow(OpenCommissioningWindowRequest): DefaultSuccess = 0; + /** This command is used by a current Administrator to instruct a Node to go into commissioning mode using basic commissioning method, if the node supports it. */ + timed command access(invoke: administer) OpenBasicCommissioningWindow(OpenBasicCommissioningWindowRequest): DefaultSuccess = 1; + /** This command is used by a current Administrator to instruct a Node to revoke any active Open Commissioning Window or Open Basic Commissioning Window command. */ + timed command access(invoke: administer) RevokeCommissioning(): DefaultSuccess = 2; +} + +/** This cluster is used to add or remove Operational Credentials on a Commissionee or Node, as well as manage the associated Fabrics. */ +cluster OperationalCredentials = 62 { + revision 1; // NOTE: Default/not specifically set + + enum CertificateChainTypeEnum : enum8 { + kDACCertificate = 1; + kPAICertificate = 2; + } + + enum NodeOperationalCertStatusEnum : enum8 { + kOK = 0; + kInvalidPublicKey = 1; + kInvalidNodeOpId = 2; + kInvalidNOC = 3; + kMissingCsr = 4; + kTableFull = 5; + kInvalidAdminSubject = 6; + kFabricConflict = 9; + kLabelConflict = 10; + kInvalidFabricIndex = 11; + } + + fabric_scoped struct FabricDescriptorStruct { + octet_string<65> rootPublicKey = 1; + vendor_id vendorID = 2; + fabric_id fabricID = 3; + node_id nodeID = 4; + char_string<32> label = 5; + fabric_idx fabricIndex = 254; + } + + fabric_scoped struct NOCStruct { + fabric_sensitive octet_string noc = 1; + nullable fabric_sensitive octet_string icac = 2; + fabric_idx fabricIndex = 254; + } + + readonly attribute access(read: administer) NOCStruct NOCs[] = 0; + readonly attribute FabricDescriptorStruct fabrics[] = 1; + readonly attribute int8u supportedFabrics = 2; + readonly attribute int8u commissionedFabrics = 3; + readonly attribute octet_string trustedRootCertificates[] = 4; + readonly attribute int8u currentFabricIndex = 5; + 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 AttestationRequestRequest { + octet_string<32> attestationNonce = 0; + } + + response struct AttestationResponse = 1 { + octet_string<900> attestationElements = 0; + octet_string<64> attestationSignature = 1; + } + + request struct CertificateChainRequestRequest { + CertificateChainTypeEnum certificateType = 0; + } + + response struct CertificateChainResponse = 3 { + octet_string<600> certificate = 0; + } + + request struct CSRRequestRequest { + octet_string<32> CSRNonce = 0; + optional boolean isForUpdateNOC = 1; + } + + response struct CSRResponse = 5 { + octet_string NOCSRElements = 0; + octet_string attestationSignature = 1; + } + + request struct AddNOCRequest { + octet_string<400> NOCValue = 0; + optional octet_string<400> ICACValue = 1; + octet_string<16> IPKValue = 2; + int64u caseAdminSubject = 3; + vendor_id adminVendorId = 4; + } + + request struct UpdateNOCRequest { + octet_string NOCValue = 0; + optional octet_string ICACValue = 1; + } + + response struct NOCResponse = 8 { + NodeOperationalCertStatusEnum statusCode = 0; + optional fabric_idx fabricIndex = 1; + optional char_string<128> debugText = 2; + } + + request struct UpdateFabricLabelRequest { + char_string<32> label = 0; + } + + request struct RemoveFabricRequest { + fabric_idx fabricIndex = 0; + } + + request struct AddTrustedRootCertificateRequest { + octet_string rootCACertificate = 0; + } + + /** Sender is requesting attestation information from the receiver. */ + command access(invoke: administer) AttestationRequest(AttestationRequestRequest): AttestationResponse = 0; + /** Sender is requesting a device attestation certificate from the receiver. */ + command access(invoke: administer) CertificateChainRequest(CertificateChainRequestRequest): CertificateChainResponse = 2; + /** Sender is requesting a certificate signing request (CSR) from the receiver. */ + command access(invoke: administer) CSRRequest(CSRRequestRequest): CSRResponse = 4; + /** Sender is requesting to add the new node operational certificates. */ + command access(invoke: administer) AddNOC(AddNOCRequest): NOCResponse = 6; + /** Sender is requesting to update the node operational certificates. */ + fabric command access(invoke: administer) UpdateNOC(UpdateNOCRequest): NOCResponse = 7; + /** This command SHALL be used by an Administrative Node to set the user-visible Label field for a given Fabric, as reflected by entries in the Fabrics attribute. */ + fabric command access(invoke: administer) UpdateFabricLabel(UpdateFabricLabelRequest): NOCResponse = 9; + /** This command is used by Administrative Nodes to remove a given fabric index and delete all associated fabric-scoped data. */ + command access(invoke: administer) RemoveFabric(RemoveFabricRequest): NOCResponse = 10; + /** This command SHALL add a Trusted Root CA Certificate, provided as its CHIP Certificate representation. */ + command access(invoke: administer) AddTrustedRootCertificate(AddTrustedRootCertificateRequest): DefaultSuccess = 11; +} + +/** The Group Key Management Cluster is the mechanism by which group keys are managed. */ +cluster GroupKeyManagement = 63 { + revision 1; // NOTE: Default/not specifically set + + enum GroupKeySecurityPolicyEnum : enum8 { + kTrustFirst = 0; + kCacheAndSync = 1; + } + + bitmap Feature : bitmap32 { + kCacheAndSync = 0x1; + } + + fabric_scoped struct GroupInfoMapStruct { + group_id groupId = 1; + endpoint_no endpoints[] = 2; + optional char_string<16> groupName = 3; + fabric_idx fabricIndex = 254; + } + + fabric_scoped struct GroupKeyMapStruct { + group_id groupId = 1; + int16u groupKeySetID = 2; + fabric_idx fabricIndex = 254; + } + + struct GroupKeySetStruct { + int16u groupKeySetID = 0; + GroupKeySecurityPolicyEnum groupKeySecurityPolicy = 1; + nullable octet_string<16> epochKey0 = 2; + nullable epoch_us epochStartTime0 = 3; + nullable octet_string<16> epochKey1 = 4; + nullable epoch_us epochStartTime1 = 5; + nullable octet_string<16> epochKey2 = 6; + nullable epoch_us epochStartTime2 = 7; + } + + attribute access(write: manage) GroupKeyMapStruct groupKeyMap[] = 0; + readonly attribute GroupInfoMapStruct groupTable[] = 1; + readonly attribute int16u maxGroupsPerFabric = 2; + readonly attribute int16u maxGroupKeysPerFabric = 3; + 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 KeySetWriteRequest { + GroupKeySetStruct groupKeySet = 0; + } + + request struct KeySetReadRequest { + int16u groupKeySetID = 0; + } + + response struct KeySetReadResponse = 2 { + GroupKeySetStruct groupKeySet = 0; + } + + request struct KeySetRemoveRequest { + int16u groupKeySetID = 0; + } + + response struct KeySetReadAllIndicesResponse = 5 { + int16u groupKeySetIDs[] = 0; + } + + /** Write a new set of keys for the given key set id. */ + fabric command access(invoke: administer) KeySetWrite(KeySetWriteRequest): DefaultSuccess = 0; + /** Read the keys for a given key set id. */ + fabric command access(invoke: administer) KeySetRead(KeySetReadRequest): KeySetReadResponse = 1; + /** Revoke a Root Key from a Group */ + fabric command access(invoke: administer) KeySetRemove(KeySetRemoveRequest): DefaultSuccess = 3; + /** Return the list of Group Key Sets associated with the accessing fabric */ + fabric command access(invoke: administer) KeySetReadAllIndices(): KeySetReadAllIndicesResponse = 4; +} + +endpoint 0 { + device type ma_rootdevice = 22, version 1; + + + server cluster Descriptor { + callback attribute deviceTypeList; + callback attribute serverList; + callback attribute clientList; + callback attribute partsList; + callback attribute featureMap; + callback attribute clusterRevision; + } + + server cluster AccessControl { + emits event AccessControlEntryChanged; + emits event AccessControlExtensionChanged; + callback attribute acl; + callback attribute extension; + callback attribute subjectsPerAccessControlEntry; + callback attribute targetsPerAccessControlEntry; + callback attribute accessControlEntriesPerFabric; + callback attribute attributeList; + ram attribute featureMap default = 0; + callback attribute clusterRevision; + } + + server cluster BasicInformation { + emits event StartUp; + emits event ShutDown; + emits event Leave; + callback attribute dataModelRevision; + callback attribute vendorName; + callback attribute vendorID; + callback attribute productName; + callback attribute productID; + persist attribute nodeLabel; + callback attribute location; + callback attribute hardwareVersion; + callback attribute hardwareVersionString; + callback attribute softwareVersion; + callback attribute softwareVersionString; + callback attribute manufacturingDate; + callback attribute partNumber; + callback attribute productURL; + callback attribute productLabel; + callback attribute serialNumber; + persist attribute localConfigDisabled default = 0; + callback attribute uniqueID; + callback attribute capabilityMinima; + callback attribute specificationVersion; + callback attribute maxPathsPerInvoke; + ram attribute featureMap default = 0; + ram attribute clusterRevision default = 3; + } + + server cluster GeneralCommissioning { + ram attribute breadcrumb default = 0x0000000000000000; + callback attribute basicCommissioningInfo; + callback attribute regulatoryConfig; + callback attribute locationCapability; + callback attribute supportsConcurrentConnection; + ram attribute featureMap default = 0; + ram attribute clusterRevision default = 0x0001; + + handle command ArmFailSafe; + handle command ArmFailSafeResponse; + handle command SetRegulatoryConfig; + handle command SetRegulatoryConfigResponse; + handle command CommissioningComplete; + handle command CommissioningCompleteResponse; + } + + server cluster NetworkCommissioning { + ram attribute maxNetworks; + callback attribute networks; + ram attribute scanMaxTimeSeconds; + ram attribute connectMaxTimeSeconds; + ram attribute interfaceEnabled; + ram attribute lastNetworkingStatus; + ram attribute lastNetworkID; + ram attribute lastConnectErrorValue; + ram attribute featureMap default = 1; + ram attribute clusterRevision default = 0x0001; + + handle command ScanNetworks; + handle command ScanNetworksResponse; + handle command AddOrUpdateWiFiNetwork; + handle command AddOrUpdateThreadNetwork; + handle command RemoveNetwork; + handle command NetworkConfigResponse; + handle command ConnectNetwork; + handle command ConnectNetworkResponse; + handle command ReorderNetwork; + } + + server cluster DiagnosticLogs { + ram attribute featureMap default = 0; + ram attribute clusterRevision default = 1; + + handle command RetrieveLogsRequest; + } + + server cluster GeneralDiagnostics { + emits event BootReason; + callback attribute networkInterfaces; + callback attribute rebootCount; + callback attribute upTime; + callback attribute totalOperationalHours; + callback attribute bootReason; + callback attribute activeHardwareFaults; + callback attribute activeRadioFaults; + callback attribute activeNetworkFaults; + callback attribute testEventTriggersEnabled default = false; + callback attribute featureMap; + callback attribute clusterRevision; + + handle command TestEventTrigger; + handle command TimeSnapshot; + handle command TimeSnapshotResponse; + } + + server cluster AdministratorCommissioning { + callback attribute windowStatus; + callback attribute adminFabricIndex; + callback attribute adminVendorId; + ram attribute featureMap default = 0; + ram attribute clusterRevision default = 0x0001; + + handle command OpenCommissioningWindow; + handle command OpenBasicCommissioningWindow; + handle command RevokeCommissioning; + } + + server cluster OperationalCredentials { + callback attribute NOCs; + callback attribute fabrics; + callback attribute supportedFabrics; + callback attribute commissionedFabrics; + callback attribute trustedRootCertificates; + callback attribute currentFabricIndex; + ram attribute featureMap default = 0; + ram attribute clusterRevision default = 0x0001; + + handle command AttestationRequest; + handle command AttestationResponse; + handle command CertificateChainRequest; + handle command CertificateChainResponse; + handle command CSRRequest; + handle command CSRResponse; + handle command AddNOC; + handle command UpdateNOC; + handle command NOCResponse; + handle command UpdateFabricLabel; + handle command RemoveFabric; + handle command AddTrustedRootCertificate; + } + + server cluster GroupKeyManagement { + callback attribute groupKeyMap; + callback attribute groupTable; + callback attribute maxGroupsPerFabric; + callback attribute maxGroupKeysPerFabric; + callback attribute featureMap; + callback attribute clusterRevision; + + handle command KeySetWrite; + handle command KeySetRead; + handle command KeySetReadResponse; + handle command KeySetRemove; + handle command KeySetReadAllIndices; + handle command KeySetReadAllIndicesResponse; + } +} +endpoint 1 { + device type ma_powersource = 17, version 1; + device type ma_genericswitch = 15, version 1; + + + server cluster Identify { + ram attribute identifyTime default = 0x0; + ram attribute identifyType default = 0x00; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; + ram attribute featureMap default = 0; + ram attribute clusterRevision default = 4; + + handle command Identify; + handle command TriggerEffect; + } + + server cluster Descriptor { + callback attribute deviceTypeList; + callback attribute serverList; + callback attribute clientList; + callback attribute partsList; + callback attribute tagList; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; + callback attribute featureMap; + callback attribute clusterRevision; + } + + server cluster PowerSource { + persist attribute status default = 1; + persist attribute order default = 1; + persist attribute description default = "Battery"; + persist attribute batVoltage; + persist attribute batPercentRemaining default = 100; + persist attribute batTimeRemaining; + persist attribute batChargeLevel; + ram attribute batReplacementNeeded; + ram attribute batReplaceability; + ram attribute batPresent; + ram attribute batReplacementDescription; + persist attribute batQuantity default = 1; + callback attribute endpointList; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; + ram attribute featureMap default = 0x0A; + ram attribute clusterRevision default = 1; + } + + server cluster Switch { + emits event InitialPress; + emits event LongPress; + emits event ShortRelease; + emits event LongRelease; + persist attribute numberOfPositions default = 3; + persist attribute currentPosition default = 0; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; + ram attribute featureMap default = 0xE; + ram attribute clusterRevision default = 1; + } +} + + diff --git a/examples/chef/devices/rootnode_genericswitch_2dfff6e516.zap b/examples/chef/devices/rootnode_genericswitch_2dfff6e516.zap new file mode 100644 index 00000000000000..1f84a7aab45a71 --- /dev/null +++ b/examples/chef/devices/rootnode_genericswitch_2dfff6e516.zap @@ -0,0 +1,2804 @@ +{ + "fileFormat": 2, + "featureLevel": 102, + "creator": "zap", + "keyValuePairs": [ + { + "key": "commandDiscovery", + "value": "1" + }, + { + "key": "defaultResponsePolicy", + "value": "always" + }, + { + "key": "manufacturerCodes", + "value": "0x1002" + } + ], + "package": [ + { + "pathRelativity": "relativeToZap", + "path": "../../../src/app/zap-templates/zcl/zcl.json", + "type": "zcl-properties", + "category": "matter", + "version": 1, + "description": "Matter SDK ZCL data" + }, + { + "pathRelativity": "relativeToZap", + "path": "../../../src/app/zap-templates/app-templates.json", + "type": "gen-templates-json", + "category": "matter", + "version": "chip-v1" + } + ], + "endpointTypes": [ + { + "id": 1, + "name": "MA-rootdevice", + "deviceTypeRef": { + "code": 22, + "profileId": 259, + "label": "MA-rootdevice", + "name": "MA-rootdevice" + }, + "deviceTypes": [ + { + "code": 22, + "profileId": 259, + "label": "MA-rootdevice", + "name": "MA-rootdevice" + } + ], + "deviceVersions": [ + 1 + ], + "deviceIdentifiers": [ + 22 + ], + "deviceTypeName": "MA-rootdevice", + "deviceTypeCode": 22, + "deviceTypeProfileId": 259, + "clusters": [ + { + "name": "Descriptor", + "code": 29, + "mfgCode": null, + "define": "DESCRIPTOR_CLUSTER", + "side": "server", + "enabled": 1, + "attributes": [ + { + "name": "DeviceTypeList", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ServerList", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClientList", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "PartsList", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + } + ] + }, + { + "name": "Access Control", + "code": 31, + "mfgCode": null, + "define": "ACCESS_CONTROL_CLUSTER", + "side": "server", + "enabled": 1, + "attributes": [ + { + "name": "ACL", + "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": "Extension", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "SubjectsPerAccessControlEntry", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "TargetsPerAccessControlEntry", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AccessControlEntriesPerFabric", + "code": 4, + "mfgCode": null, + "side": "server", + "type": "int16u", + "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": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + } + ], + "events": [ + { + "name": "AccessControlEntryChanged", + "code": 0, + "mfgCode": null, + "side": "server", + "included": 1 + }, + { + "name": "AccessControlExtensionChanged", + "code": 1, + "mfgCode": null, + "side": "server", + "included": 1 + } + ] + }, + { + "name": "Basic Information", + "code": 40, + "mfgCode": null, + "define": "BASIC_INFORMATION_CLUSTER", + "side": "server", + "enabled": 1, + "attributes": [ + { + "name": "DataModelRevision", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "VendorName", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "VendorID", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "vendor_id", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "ProductName", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "ProductID", + "code": 4, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "NodeLabel", + "code": 5, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "NVM", + "singleton": 1, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "Location", + "code": 6, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "HardwareVersion", + "code": 7, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "HardwareVersionString", + "code": 8, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "SoftwareVersion", + "code": 9, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "SoftwareVersionString", + "code": 10, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "ManufacturingDate", + "code": 11, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "PartNumber", + "code": 12, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "ProductURL", + "code": 13, + "mfgCode": null, + "side": "server", + "type": "long_char_string", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "ProductLabel", + "code": 14, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "SerialNumber", + "code": 15, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "LocalConfigDisabled", + "code": 16, + "mfgCode": null, + "side": "server", + "type": "boolean", + "included": 1, + "storageOption": "NVM", + "singleton": 1, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "UniqueID", + "code": 18, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "CapabilityMinima", + "code": 19, + "mfgCode": null, + "side": "server", + "type": "CapabilityMinimaStruct", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "SpecificationVersion", + "code": 21, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "MaxPathsPerInvoke", + "code": 22, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 1, + "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": 1, + "bounded": 0, + "defaultValue": "3", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ], + "events": [ + { + "name": "StartUp", + "code": 0, + "mfgCode": null, + "side": "server", + "included": 1 + }, + { + "name": "ShutDown", + "code": 1, + "mfgCode": null, + "side": "server", + "included": 1 + }, + { + "name": "Leave", + "code": 2, + "mfgCode": null, + "side": "server", + "included": 1 + } + ] + }, + { + "name": "General Commissioning", + "code": 48, + "mfgCode": null, + "define": "GENERAL_COMMISSIONING_CLUSTER", + "side": "server", + "enabled": 1, + "commands": [ + { + "name": "ArmFailSafe", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "ArmFailSafeResponse", + "code": 1, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "SetRegulatoryConfig", + "code": 2, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "SetRegulatoryConfigResponse", + "code": 3, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "CommissioningComplete", + "code": 4, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "CommissioningCompleteResponse", + "code": 5, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + } + ], + "attributes": [ + { + "name": "Breadcrumb", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "int64u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x0000000000000000", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "BasicCommissioningInfo", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "BasicCommissioningInfo", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "RegulatoryConfig", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "RegulatoryLocationTypeEnum", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "LocationCapability", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "RegulatoryLocationTypeEnum", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "SupportsConcurrentConnection", + "code": 4, + "mfgCode": null, + "side": "server", + "type": "boolean", + "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": "0x0001", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, + { + "name": "Network Commissioning", + "code": 49, + "mfgCode": null, + "define": "NETWORK_COMMISSIONING_CLUSTER", + "side": "server", + "enabled": 1, + "commands": [ + { + "name": "ScanNetworks", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "ScanNetworksResponse", + "code": 1, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "AddOrUpdateWiFiNetwork", + "code": 2, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "AddOrUpdateThreadNetwork", + "code": 3, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "RemoveNetwork", + "code": 4, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "NetworkConfigResponse", + "code": 5, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "ConnectNetwork", + "code": 6, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "ConnectNetworkResponse", + "code": 7, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "ReorderNetwork", + "code": 8, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + } + ], + "attributes": [ + { + "name": "MaxNetworks", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "Networks", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ScanMaxTimeSeconds", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ConnectMaxTimeSeconds", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "InterfaceEnabled", + "code": 4, + "mfgCode": null, + "side": "server", + "type": "boolean", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "LastNetworkingStatus", + "code": 5, + "mfgCode": null, + "side": "server", + "type": "NetworkCommissioningStatusEnum", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "LastNetworkID", + "code": 6, + "mfgCode": null, + "side": "server", + "type": "octet_string", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "LastConnectErrorValue", + "code": 7, + "mfgCode": null, + "side": "server", + "type": "int32s", + "included": 1, + "storageOption": "RAM", + "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": "1", + "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": "0x0001", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, + { + "name": "Diagnostic Logs", + "code": 50, + "mfgCode": null, + "define": "DIAGNOSTIC_LOGS_CLUSTER", + "side": "server", + "enabled": 1, + "commands": [ + { + "name": "RetrieveLogsRequest", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + } + ], + "attributes": [ + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + } + ] + }, + { + "name": "General Diagnostics", + "code": 51, + "mfgCode": null, + "define": "GENERAL_DIAGNOSTICS_CLUSTER", + "side": "server", + "enabled": 1, + "commands": [ + { + "name": "TestEventTrigger", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "TimeSnapshot", + "code": 1, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "TimeSnapshotResponse", + "code": 2, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + } + ], + "attributes": [ + { + "name": "NetworkInterfaces", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "RebootCount", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "UpTime", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "int64u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "TotalOperationalHours", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "BootReason", + "code": 4, + "mfgCode": null, + "side": "server", + "type": "BootReasonEnum", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ActiveHardwareFaults", + "code": 5, + "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": "ActiveRadioFaults", + "code": 6, + "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": "ActiveNetworkFaults", + "code": 7, + "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": "TestEventTriggersEnabled", + "code": 8, + "mfgCode": null, + "side": "server", + "type": "boolean", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "false", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ], + "events": [ + { + "name": "BootReason", + "code": 3, + "mfgCode": null, + "side": "server", + "included": 1 + } + ] + }, + { + "name": "Administrator Commissioning", + "code": 60, + "mfgCode": null, + "define": "ADMINISTRATOR_COMMISSIONING_CLUSTER", + "side": "server", + "enabled": 1, + "commands": [ + { + "name": "OpenCommissioningWindow", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "OpenBasicCommissioningWindow", + "code": 1, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "RevokeCommissioning", + "code": 2, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + } + ], + "attributes": [ + { + "name": "WindowStatus", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "CommissioningWindowStatusEnum", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AdminFabricIndex", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "fabric_idx", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AdminVendorId", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "vendor_id", + "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": "0x0001", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, + { + "name": "Operational Credentials", + "code": 62, + "mfgCode": null, + "define": "OPERATIONAL_CREDENTIALS_CLUSTER", + "side": "server", + "enabled": 1, + "commands": [ + { + "name": "AttestationRequest", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "AttestationResponse", + "code": 1, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "CertificateChainRequest", + "code": 2, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "CertificateChainResponse", + "code": 3, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "CSRRequest", + "code": 4, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "CSRResponse", + "code": 5, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "AddNOC", + "code": 6, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "UpdateNOC", + "code": 7, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "NOCResponse", + "code": 8, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "UpdateFabricLabel", + "code": 9, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "RemoveFabric", + "code": 10, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "AddTrustedRootCertificate", + "code": 11, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + } + ], + "attributes": [ + { + "name": "NOCs", + "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": "Fabrics", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "SupportedFabrics", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "CommissionedFabrics", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "TrustedRootCertificates", + "code": 4, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "CurrentFabricIndex", + "code": 5, + "mfgCode": null, + "side": "server", + "type": "int8u", + "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": "0x0001", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, + { + "name": "Group Key Management", + "code": 63, + "mfgCode": null, + "define": "GROUP_KEY_MANAGEMENT_CLUSTER", + "side": "server", + "enabled": 1, + "commands": [ + { + "name": "KeySetWrite", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "KeySetRead", + "code": 1, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "KeySetReadResponse", + "code": 2, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "KeySetRemove", + "code": 3, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "KeySetReadAllIndices", + "code": 4, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "KeySetReadAllIndicesResponse", + "code": 5, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + } + ], + "attributes": [ + { + "name": "GroupKeyMap", + "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": "GroupTable", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "MaxGroupsPerFabric", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "MaxGroupKeysPerFabric", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + } + ] + } + ] + }, + { + "id": 2, + "name": "Anonymous Endpoint Type", + "deviceTypeRef": { + "code": 15, + "profileId": 259, + "label": "MA-genericswitch", + "name": "MA-genericswitch" + }, + "deviceTypes": [ + { + "code": 15, + "profileId": 259, + "label": "MA-genericswitch", + "name": "MA-genericswitch" + }, + { + "code": 17, + "profileId": 259, + "label": "MA-powersource", + "name": "MA-powersource" + } + ], + "deviceVersions": [ + 1, + 1 + ], + "deviceIdentifiers": [ + 15, + 17 + ], + "deviceTypeName": "MA-genericswitch", + "deviceTypeCode": 15, + "deviceTypeProfileId": 259, + "clusters": [ + { + "name": "Identify", + "code": 3, + "mfgCode": null, + "define": "IDENTIFY_CLUSTER", + "side": "server", + "enabled": 1, + "commands": [ + { + "name": "Identify", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "TriggerEffect", + "code": 64, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + } + ], + "attributes": [ + { + "name": "IdentifyTime", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "IdentifyType", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "IdentifyTypeEnum", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x00", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "GeneratedCommandList", + "code": 65528, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AcceptedCommandList", + "code": 65529, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "EventList", + "code": 65530, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AttributeList", + "code": 65531, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "4", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + } + ] + }, + { + "name": "Descriptor", + "code": 29, + "mfgCode": null, + "define": "DESCRIPTOR_CLUSTER", + "side": "server", + "enabled": 1, + "attributes": [ + { + "name": "DeviceTypeList", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ServerList", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClientList", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "PartsList", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "TagList", + "code": 4, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "GeneratedCommandList", + "code": 65528, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AcceptedCommandList", + "code": 65529, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "EventList", + "code": 65530, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AttributeList", + "code": 65531, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + } + ] + }, + { + "name": "Power Source", + "code": 47, + "mfgCode": null, + "define": "POWER_SOURCE_CLUSTER", + "side": "server", + "enabled": 1, + "attributes": [ + { + "name": "Status", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "PowerSourceStatusEnum", + "included": 1, + "storageOption": "NVM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "Order", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "NVM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "Description", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "NVM", + "singleton": 0, + "bounded": 0, + "defaultValue": "Battery", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "BatVoltage", + "code": 11, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "NVM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "BatPercentRemaining", + "code": 12, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "NVM", + "singleton": 0, + "bounded": 0, + "defaultValue": "100", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "BatTimeRemaining", + "code": 13, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "NVM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "BatChargeLevel", + "code": 14, + "mfgCode": null, + "side": "server", + "type": "BatChargeLevelEnum", + "included": 1, + "storageOption": "NVM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "BatReplacementNeeded", + "code": 15, + "mfgCode": null, + "side": "server", + "type": "boolean", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "BatReplaceability", + "code": 16, + "mfgCode": null, + "side": "server", + "type": "BatReplaceabilityEnum", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "BatPresent", + "code": 17, + "mfgCode": null, + "side": "server", + "type": "boolean", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "BatReplacementDescription", + "code": 19, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "BatQuantity", + "code": 25, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "NVM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "EndpointList", + "code": 31, + "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": "0x0A", + "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": "Switch", + "code": 59, + "mfgCode": null, + "define": "SWITCH_CLUSTER", + "side": "server", + "enabled": 1, + "attributes": [ + { + "name": "NumberOfPositions", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "NVM", + "singleton": 0, + "bounded": 0, + "defaultValue": "3", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "CurrentPosition", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "NVM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "GeneratedCommandList", + "code": 65528, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AcceptedCommandList", + "code": 65529, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "EventList", + "code": 65530, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AttributeList", + "code": 65531, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0xE", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + } + ], + "events": [ + { + "name": "InitialPress", + "code": 1, + "mfgCode": null, + "side": "server", + "included": 1 + }, + { + "name": "LongPress", + "code": 2, + "mfgCode": null, + "side": "server", + "included": 1 + }, + { + "name": "ShortRelease", + "code": 3, + "mfgCode": null, + "side": "server", + "included": 1 + }, + { + "name": "LongRelease", + "code": 4, + "mfgCode": null, + "side": "server", + "included": 1 + } + ] + } + ] + } + ], + "endpoints": [ + { + "endpointTypeName": "MA-rootdevice", + "endpointTypeIndex": 0, + "profileId": 259, + "endpointId": 0, + "networkId": 0, + "parentEndpointIdentifier": null + }, + { + "endpointTypeName": "Anonymous Endpoint Type", + "endpointTypeIndex": 1, + "profileId": 259, + "endpointId": 1, + "networkId": 0, + "parentEndpointIdentifier": null + } + ] +} \ No newline at end of file diff --git a/examples/chef/devices/rootnode_genericswitch_9866e35d0b.matter b/examples/chef/devices/rootnode_genericswitch_9866e35d0b.matter index 8e2d0166cc44a9..cda268e6d211f0 100644 --- a/examples/chef/devices/rootnode_genericswitch_9866e35d0b.matter +++ b/examples/chef/devices/rootnode_genericswitch_9866e35d0b.matter @@ -256,6 +256,265 @@ cluster BasicInformation = 40 { command MfgSpecificPing(): DefaultSuccess = 0; } +/** This cluster is used to describe the configuration and capabilities of a physical power source that provides power to the Node. */ +cluster PowerSource = 47 { + revision 1; // NOTE: Default/not specifically set + + enum BatApprovedChemistryEnum : enum16 { + kUnspecified = 0; + kAlkaline = 1; + kLithiumCarbonFluoride = 2; + kLithiumChromiumOxide = 3; + kLithiumCopperOxide = 4; + kLithiumIronDisulfide = 5; + kLithiumManganeseDioxide = 6; + kLithiumThionylChloride = 7; + kMagnesium = 8; + kMercuryOxide = 9; + kNickelOxyhydride = 10; + kSilverOxide = 11; + kZincAir = 12; + kZincCarbon = 13; + kZincChloride = 14; + kZincManganeseDioxide = 15; + kLeadAcid = 16; + kLithiumCobaltOxide = 17; + kLithiumIon = 18; + kLithiumIonPolymer = 19; + kLithiumIronPhosphate = 20; + kLithiumSulfur = 21; + kLithiumTitanate = 22; + kNickelCadmium = 23; + kNickelHydrogen = 24; + kNickelIron = 25; + kNickelMetalHydride = 26; + kNickelZinc = 27; + kSilverZinc = 28; + kSodiumIon = 29; + kSodiumSulfur = 30; + kZincBromide = 31; + kZincCerium = 32; + } + + enum BatChargeFaultEnum : enum8 { + kUnspecified = 0; + kAmbientTooHot = 1; + kAmbientTooCold = 2; + kBatteryTooHot = 3; + kBatteryTooCold = 4; + kBatteryAbsent = 5; + kBatteryOverVoltage = 6; + kBatteryUnderVoltage = 7; + kChargerOverVoltage = 8; + kChargerUnderVoltage = 9; + kSafetyTimeout = 10; + } + + enum BatChargeLevelEnum : enum8 { + kOK = 0; + kWarning = 1; + kCritical = 2; + } + + enum BatChargeStateEnum : enum8 { + kUnknown = 0; + kIsCharging = 1; + kIsAtFullCharge = 2; + kIsNotCharging = 3; + } + + enum BatCommonDesignationEnum : enum16 { + kUnspecified = 0; + kAAA = 1; + kAA = 2; + kC = 3; + kD = 4; + k4v5 = 5; + k6v0 = 6; + k9v0 = 7; + k12AA = 8; + kAAAA = 9; + kA = 10; + kB = 11; + kF = 12; + kN = 13; + kNo6 = 14; + kSubC = 15; + kA23 = 16; + kA27 = 17; + kBA5800 = 18; + kDuplex = 19; + k4SR44 = 20; + k523 = 21; + k531 = 22; + k15v0 = 23; + k22v5 = 24; + k30v0 = 25; + k45v0 = 26; + k67v5 = 27; + kJ = 28; + kCR123A = 29; + kCR2 = 30; + k2CR5 = 31; + kCRP2 = 32; + kCRV3 = 33; + kSR41 = 34; + kSR43 = 35; + kSR44 = 36; + kSR45 = 37; + kSR48 = 38; + kSR54 = 39; + kSR55 = 40; + kSR57 = 41; + kSR58 = 42; + kSR59 = 43; + kSR60 = 44; + kSR63 = 45; + kSR64 = 46; + kSR65 = 47; + kSR66 = 48; + kSR67 = 49; + kSR68 = 50; + kSR69 = 51; + kSR516 = 52; + kSR731 = 53; + kSR712 = 54; + kLR932 = 55; + kA5 = 56; + kA10 = 57; + kA13 = 58; + kA312 = 59; + kA675 = 60; + kAC41E = 61; + k10180 = 62; + k10280 = 63; + k10440 = 64; + k14250 = 65; + k14430 = 66; + k14500 = 67; + k14650 = 68; + k15270 = 69; + k16340 = 70; + kRCR123A = 71; + k17500 = 72; + k17670 = 73; + k18350 = 74; + k18500 = 75; + k18650 = 76; + k19670 = 77; + k25500 = 78; + k26650 = 79; + k32600 = 80; + } + + enum BatFaultEnum : enum8 { + kUnspecified = 0; + kOverTemp = 1; + kUnderTemp = 2; + } + + enum BatReplaceabilityEnum : enum8 { + kUnspecified = 0; + kNotReplaceable = 1; + kUserReplaceable = 2; + kFactoryReplaceable = 3; + } + + enum PowerSourceStatusEnum : enum8 { + kUnspecified = 0; + kActive = 1; + kStandby = 2; + kUnavailable = 3; + } + + enum WiredCurrentTypeEnum : enum8 { + kAC = 0; + kDC = 1; + } + + enum WiredFaultEnum : enum8 { + kUnspecified = 0; + kOverVoltage = 1; + kUnderVoltage = 2; + } + + bitmap Feature : bitmap32 { + kWired = 0x1; + kBattery = 0x2; + kRechargeable = 0x4; + kReplaceable = 0x8; + } + + struct BatChargeFaultChangeType { + BatChargeFaultEnum current[] = 0; + BatChargeFaultEnum previous[] = 1; + } + + struct BatFaultChangeType { + BatFaultEnum current[] = 0; + BatFaultEnum previous[] = 1; + } + + struct WiredFaultChangeType { + WiredFaultEnum current[] = 0; + WiredFaultEnum previous[] = 1; + } + + info event WiredFaultChange = 0 { + WiredFaultEnum current[] = 0; + WiredFaultEnum previous[] = 1; + } + + info event BatFaultChange = 1 { + BatFaultEnum current[] = 0; + BatFaultEnum previous[] = 1; + } + + info event BatChargeFaultChange = 2 { + BatChargeFaultEnum current[] = 0; + BatChargeFaultEnum previous[] = 1; + } + + readonly attribute PowerSourceStatusEnum status = 0; + readonly attribute int8u order = 1; + readonly attribute char_string<60> description = 2; + readonly attribute optional nullable int32u wiredAssessedInputVoltage = 3; + readonly attribute optional nullable int16u wiredAssessedInputFrequency = 4; + readonly attribute optional WiredCurrentTypeEnum wiredCurrentType = 5; + readonly attribute optional nullable int32u wiredAssessedCurrent = 6; + readonly attribute optional int32u wiredNominalVoltage = 7; + readonly attribute optional int32u wiredMaximumCurrent = 8; + readonly attribute optional boolean wiredPresent = 9; + readonly attribute optional WiredFaultEnum activeWiredFaults[] = 10; + readonly attribute optional nullable int32u batVoltage = 11; + readonly attribute optional nullable int8u batPercentRemaining = 12; + readonly attribute optional nullable int32u batTimeRemaining = 13; + readonly attribute optional BatChargeLevelEnum batChargeLevel = 14; + readonly attribute optional boolean batReplacementNeeded = 15; + readonly attribute optional BatReplaceabilityEnum batReplaceability = 16; + readonly attribute optional boolean batPresent = 17; + readonly attribute optional BatFaultEnum activeBatFaults[] = 18; + readonly attribute optional char_string<60> batReplacementDescription = 19; + readonly attribute optional BatCommonDesignationEnum batCommonDesignation = 20; + readonly attribute optional char_string<20> batANSIDesignation = 21; + readonly attribute optional char_string<20> batIECDesignation = 22; + readonly attribute optional BatApprovedChemistryEnum batApprovedChemistry = 23; + readonly attribute optional int32u batCapacity = 24; + readonly attribute optional int8u batQuantity = 25; + readonly attribute optional BatChargeStateEnum batChargeState = 26; + readonly attribute optional nullable int32u batTimeToFullCharge = 27; + readonly attribute optional boolean batFunctionalWhileCharging = 28; + readonly attribute optional nullable int32u batChargingCurrent = 29; + readonly attribute optional BatChargeFaultEnum activeBatChargeFaults[] = 30; + readonly attribute endpoint_no endpointList[] = 31; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; +} + /** This cluster is used to manage global aspects of the Commissioning flow. */ cluster GeneralCommissioning = 48 { revision 1; // NOTE: Default/not specifically set @@ -1166,6 +1425,7 @@ endpoint 0 { } } endpoint 1 { + device type ma_powersource = 17, version 1; device type ma_genericswitch = 15, version 1; @@ -1188,6 +1448,7 @@ endpoint 1 { callback attribute serverList; callback attribute clientList; callback attribute partsList; + callback attribute tagList; callback attribute generatedCommandList; callback attribute acceptedCommandList; callback attribute eventList; @@ -1196,9 +1457,31 @@ endpoint 1 { callback attribute clusterRevision; } + server cluster PowerSource { + persist attribute status default = 1; + persist attribute order default = 1; + persist attribute description default = "Battery"; + persist attribute batVoltage; + persist attribute batPercentRemaining default = 100; + persist attribute batTimeRemaining; + persist attribute batChargeLevel default = 0; + ram attribute batReplacementNeeded; + ram attribute batReplaceability; + ram attribute batPresent; + ram attribute batReplacementDescription; + persist attribute batQuantity default = 1; + callback attribute endpointList; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; + ram attribute featureMap default = 0x0A; + ram attribute clusterRevision default = 1; + } + server cluster Switch { emits event SwitchLatched; - persist attribute numberOfPositions default = 2; + persist attribute numberOfPositions default = 5; persist attribute currentPosition default = 0; callback attribute generatedCommandList; callback attribute acceptedCommandList; diff --git a/examples/chef/devices/rootnode_genericswitch_9866e35d0b.zap b/examples/chef/devices/rootnode_genericswitch_9866e35d0b.zap index 172c6d31772296..8e62878f7a4e40 100644 --- a/examples/chef/devices/rootnode_genericswitch_9866e35d0b.zap +++ b/examples/chef/devices/rootnode_genericswitch_9866e35d0b.zap @@ -1,6 +1,6 @@ { "fileFormat": 2, - "featureLevel": 100, + "featureLevel": 102, "creator": "zap", "keyValuePairs": [ { @@ -29,6 +29,7 @@ "pathRelativity": "relativeToZap", "path": "../../../src/app/zap-templates/app-templates.json", "type": "gen-templates-json", + "category": "matter", "version": "chip-v1" } ], @@ -1935,13 +1936,21 @@ "profileId": 259, "label": "MA-genericswitch", "name": "MA-genericswitch" + }, + { + "code": 17, + "profileId": 259, + "label": "MA-powersource", + "name": "MA-powersource" } ], "deviceVersions": [ + 1, 1 ], "deviceIdentifiers": [ - 15 + 15, + 17 ], "deviceTypeName": "MA-genericswitch", "deviceTypeCode": 15, @@ -2175,6 +2184,22 @@ "maxInterval": 65534, "reportableChange": 0 }, + { + "name": "TagList", + "code": 4, + "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, @@ -2273,6 +2298,320 @@ } ] }, + { + "name": "Power Source", + "code": 47, + "mfgCode": null, + "define": "POWER_SOURCE_CLUSTER", + "side": "server", + "enabled": 1, + "attributes": [ + { + "name": "Status", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "PowerSourceStatusEnum", + "included": 1, + "storageOption": "NVM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "Order", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "NVM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "Description", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "NVM", + "singleton": 0, + "bounded": 0, + "defaultValue": "Battery", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "BatVoltage", + "code": 11, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "NVM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "BatPercentRemaining", + "code": 12, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "NVM", + "singleton": 0, + "bounded": 0, + "defaultValue": "100", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "BatTimeRemaining", + "code": 13, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "NVM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "BatChargeLevel", + "code": 14, + "mfgCode": null, + "side": "server", + "type": "BatChargeLevelEnum", + "included": 1, + "storageOption": "NVM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "BatReplacementNeeded", + "code": 15, + "mfgCode": null, + "side": "server", + "type": "boolean", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "BatReplaceability", + "code": 16, + "mfgCode": null, + "side": "server", + "type": "BatReplaceabilityEnum", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "BatPresent", + "code": 17, + "mfgCode": null, + "side": "server", + "type": "boolean", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "BatReplacementDescription", + "code": 19, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "BatQuantity", + "code": 25, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "NVM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "EndpointList", + "code": 31, + "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": "0x0A", + "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": "Switch", "code": 59, @@ -2291,7 +2630,7 @@ "storageOption": "NVM", "singleton": 0, "bounded": 0, - "defaultValue": "2", + "defaultValue": "5", "reportable": 1, "minInterval": 1, "maxInterval": 65534, diff --git a/examples/chef/esp32/main/CMakeLists.txt b/examples/chef/esp32/main/CMakeLists.txt index ac436a7919637b..c6b37a0675fa4c 100644 --- a/examples/chef/esp32/main/CMakeLists.txt +++ b/examples/chef/esp32/main/CMakeLists.txt @@ -70,6 +70,7 @@ set(SRC_DIRS_LIST "${CMAKE_SOURCE_DIR}/../common/clusters/low-power/" "${CMAKE_SOURCE_DIR}/../common/clusters/media-input/" "${CMAKE_SOURCE_DIR}/../common/clusters/media-playback/" + "${CMAKE_SOURCE_DIR}/../common/clusters/switch/" "${CMAKE_SOURCE_DIR}/../common/clusters/target-navigator/" "${CMAKE_SOURCE_DIR}/../common/clusters/wake-on-lan/" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/zzz_generated/app-common/app-common/zap-generated/attributes" diff --git a/examples/chef/esp32/main/main.cpp b/examples/chef/esp32/main/main.cpp index c5f29dc0f847d8..b61fcf22bc1d19 100644 --- a/examples/chef/esp32/main/main.cpp +++ b/examples/chef/esp32/main/main.cpp @@ -152,6 +152,8 @@ void printQRCode() app::Clusters::NetworkCommissioning::Instance sWiFiNetworkCommissioningInstance(0 /* Endpoint Id */, &(NetworkCommissioning::ESPWiFiDriver::GetInstance())); +extern void ApplicationInit(); + void InitServer(intptr_t) { // Start IM server @@ -172,6 +174,10 @@ void InitServer(intptr_t) // Register a function to receive events from the CHIP device layer. Note that calls to // this function will happen on the CHIP event loop thread, not the app_main thread. PlatformMgr().AddEventHandler(DeviceEventCallback, reinterpret_cast(nullptr)); + + // Application code should always be initialised after the initialisation of + // server. + ApplicationInit(); } extern "C" void app_main(void) diff --git a/examples/chef/linux/BUILD.gn b/examples/chef/linux/BUILD.gn index 264ced698b62e8..ce0bed596850ef 100644 --- a/examples/chef/linux/BUILD.gn +++ b/examples/chef/linux/BUILD.gn @@ -47,6 +47,7 @@ executable("${sample_name}") { "${project_dir}/common/chef-laundry-washer-mode.cpp", "${project_dir}/common/chef-operational-state-delegate-impl.cpp", "${project_dir}/common/chef-resource-monitoring-delegates.cpp", + "${project_dir}/common/chef-rpc-actions-worker.cpp", "${project_dir}/common/chef-rvc-mode-delegate.cpp", "${project_dir}/common/chef-rvc-operational-state-delegate.cpp", "${project_dir}/common/clusters/audio-output/AudioOutputManager.cpp", @@ -58,6 +59,8 @@ executable("${sample_name}") { "${project_dir}/common/clusters/low-power/LowPowerManager.cpp", "${project_dir}/common/clusters/media-input/MediaInputManager.cpp", "${project_dir}/common/clusters/media-playback/MediaPlaybackManager.cpp", + "${project_dir}/common/clusters/switch/SwitchEventHandler.cpp", + "${project_dir}/common/clusters/switch/SwitchManager.cpp", "${project_dir}/common/clusters/target-navigator/TargetNavigatorManager.cpp", "${project_dir}/common/clusters/wake-on-lan/WakeOnLanManager.cpp", "${project_dir}/common/stubs.cpp", @@ -80,6 +83,7 @@ executable("${sample_name}") { if (chip_enable_pw_rpc) { defines = [ "PW_RPC_ENABLED", + "PW_RPC_ACTIONS_SERVICE=1", "PW_RPC_ATTRIBUTE_SERVICE=1", "PW_RPC_BOOLEAN_STATE_SERVICE=1", "PW_RPC_BUTTON_SERVICE=1", @@ -107,6 +111,7 @@ executable("${sample_name}") { "$dir_pw_trace_tokenized", "$dir_pw_trace_tokenized:trace_rpc_service", "${chip_root}/config/linux/lib/pw_rpc:pw_rpc", + "${chip_root}/examples/common/pigweed:actions_service.nanopb_rpc", "${chip_root}/examples/common/pigweed:attributes_service.nanopb_rpc", "${chip_root}/examples/common/pigweed:boolean_state_service.nanopb_rpc", "${chip_root}/examples/common/pigweed:button_service.nanopb_rpc", diff --git a/examples/chef/linux/main.cpp b/examples/chef/linux/main.cpp index d799b4da3b53e6..7f54490eccf0de 100644 --- a/examples/chef/linux/main.cpp +++ b/examples/chef/linux/main.cpp @@ -29,10 +29,6 @@ using namespace chip::Shell; using namespace chip::app; using namespace chip::app::Clusters; -void ApplicationInit() {} - -void ApplicationShutdown() {} - int main(int argc, char * argv[]) { if (ChipLinuxAppInit(argc, argv) != 0) diff --git a/examples/chef/nrfconnect/CMakeLists.txt b/examples/chef/nrfconnect/CMakeLists.txt index 0e943cd90719f3..a22f6b6972bb15 100644 --- a/examples/chef/nrfconnect/CMakeLists.txt +++ b/examples/chef/nrfconnect/CMakeLists.txt @@ -99,6 +99,8 @@ target_sources(app PRIVATE ${CHEF}/common/clusters/low-power/LowPowerManager.cpp ${CHEF}/common/clusters/media-input/MediaInputManager.cpp ${CHEF}/common/clusters/media-playback/MediaPlaybackManager.cpp + ${CHEF}/common/clusters/switch/SwitchEventHandler.cpp + ${CHEF}/common/clusters/switch/SwitchManager.cpp ${CHEF}/common/clusters/target-navigator/TargetNavigatorManager.cpp ${CHEF}/common/clusters/wake-on-lan/WakeOnLanManager.cpp ${CHEF}/common/stubs.cpp diff --git a/examples/chef/nrfconnect/main.cpp b/examples/chef/nrfconnect/main.cpp index c79694e2e792a7..ca9d25655e3d52 100644 --- a/examples/chef/nrfconnect/main.cpp +++ b/examples/chef/nrfconnect/main.cpp @@ -64,6 +64,13 @@ chip::Crypto::PSAOperationalKeystore sPSAOperationalKeystore{}; #endif } // namespace +extern void ApplicationInit(); + +void InitServer(intptr_t) +{ + ApplicationInit(); +} + int main() { CHIP_ERROR err = CHIP_NO_ERROR; @@ -168,6 +175,8 @@ int main() cmd_app_server_init(); #endif + chip::DeviceLayer::PlatformMgr().ScheduleWork(InitServer); + #if CONFIG_CHIP_LIB_SHELL Engine::Root().RunMainLoop(); #endif diff --git a/examples/common/pigweed/BUILD.gn b/examples/common/pigweed/BUILD.gn index e056f2ef228a8a..c0178e419a1d5d 100644 --- a/examples/common/pigweed/BUILD.gn +++ b/examples/common/pigweed/BUILD.gn @@ -35,6 +35,14 @@ pw_proto_library("echo_service") { prefix = "echo_service" } +pw_proto_library("actions_service") { + sources = [ "protos/actions_service.proto" ] + inputs = [ "protos/actions_service.options" ] + deps = [ "$dir_pw_protobuf:common_protos" ] + strip_prefix = "protos" + prefix = "actions_service" +} + pw_proto_library("attributes_service") { sources = [ "protos/attributes_service.proto" ] inputs = [ "protos/attributes_service.options" ] diff --git a/examples/common/pigweed/protos/actions_service.options b/examples/common/pigweed/protos/actions_service.options new file mode 100644 index 00000000000000..24ce3e80648ae6 --- /dev/null +++ b/examples/common/pigweed/protos/actions_service.options @@ -0,0 +1 @@ +chip.rpc.ActionsRequest.actions max_count:16 // max action size diff --git a/examples/common/pigweed/protos/actions_service.proto b/examples/common/pigweed/protos/actions_service.proto new file mode 100644 index 00000000000000..dbf3a99ceb32ac --- /dev/null +++ b/examples/common/pigweed/protos/actions_service.proto @@ -0,0 +1,30 @@ +syntax = "proto3"; + +package chip.rpc; + +import 'pw_protobuf_protos/common.proto'; + +enum ActionType { + WRITE_ATTRIBUTE = 0x00; // Write an cluster Attribute + RUN_COMMAND = 0x01; // Run a cluster Command + EMIT_EVENT = 0x02; // Emit a cluster Events +} + +message Action { + ActionType type = 1; // ActionType above + uint32 delayMs = 2; // Delay and run action after xx ms + uint32 actionId = 3; // Align with Cluster Attribute/Event/Command ID + optional uint32 arg1 = 4; // 1st attribute + optional uint32 arg2 = 5; // 2nd attribute + optional uint32 arg3 = 6; // 3rd attribute +} + +message ActionsRequest { + uint32 endpoint_id = 1; + uint32 cluster_id = 2; + repeated Action actions = 3; // Actions including Attribute Write / Event / Command +} + +service Actions { + rpc Set(ActionsRequest) returns (pw.protobuf.Empty){} +} diff --git a/examples/common/pigweed/rpc_console/py/BUILD.gn b/examples/common/pigweed/rpc_console/py/BUILD.gn index a050fb64747302..a03dc980872739 100644 --- a/examples/common/pigweed/rpc_console/py/BUILD.gn +++ b/examples/common/pigweed/rpc_console/py/BUILD.gn @@ -39,6 +39,7 @@ pw_python_package("chip_rpc") { "$dir_pw_rpc/py", "$dir_pw_system/py", "$dir_pw_tokenizer/py", + "${chip_root}/examples/common/pigweed:actions_service.python", "${chip_root}/examples/common/pigweed:attributes_service.python", "${chip_root}/examples/common/pigweed:boolean_state_service.python", "${chip_root}/examples/common/pigweed:button_service.python", diff --git a/examples/common/pigweed/rpc_console/py/chip_rpc/console.py b/examples/common/pigweed/rpc_console/py/chip_rpc/console.py index f5ed5b5ab4d582..1591722bfdbeab 100644 --- a/examples/common/pigweed/rpc_console/py/chip_rpc/console.py +++ b/examples/common/pigweed/rpc_console/py/chip_rpc/console.py @@ -46,6 +46,7 @@ # Protos # isort: off +from actions_service import actions_service_pb2 from attributes_service import attributes_service_pb2 from boolean_state_service import boolean_state_service_pb2 from button_service import button_service_pb2 @@ -128,6 +129,7 @@ def show_console(device: str, baudrate: int, # "set_wakeup_fd only works in main thread of the main interpreter" use_ipython=True, compiled_protos=[ + actions_service_pb2, attributes_service_pb2, boolean_state_service_pb2, button_service_pb2, diff --git a/examples/common/pigweed/rpc_services/Actions.h b/examples/common/pigweed/rpc_services/Actions.h new file mode 100644 index 00000000000000..a2cbba0cb49a7a --- /dev/null +++ b/examples/common/pigweed/rpc_services/Actions.h @@ -0,0 +1,127 @@ +/* + * + * Copyright (c) 2024 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include +#include +#include +#include + +#include "actions_service/actions_service.rpc.pb.h" +#include "app/util/attribute-storage.h" +#include "pigweed/rpc_services/internal/StatusUtils.h" +#include +#include +#include + +namespace chip { +namespace rpc { + +class Actions final : public pw_rpc::nanopb::Actions::Service +{ + /* + * RPC Actions Service is a debugging interface for writting Attributes, emitting Events, or + * running Commands batchwisely. Each action will be execute one by one according to the + * delayed time in ms. + * + * An Action is a abstract type of Attribute, Command, Event + * type : this defines the action is either a Attribute, Command, or Event + * delayMs : this define the relative delayed time in ms after last action + * actionId : this defines the ID of Attribute, Command or Event + * arg1, arg2, arg3 : it has up to 3 optional arguments which could be mapped to Attribute/Command/Event aruments + * + * An Action Request is composed of a batch of Actions + * + * The usage of Actions Service: + * 1. Create an Action Request by protos.chip.rpc.ActionsWrite + * 2. Append Actions one by one to the action request + * 3. After all action added to the request, call rpcs.chip.rpc.Actions.Set to execute that + * + * e.g. In rpc_console: + * + * # Init a RPC Action request which is for endpoint 1 and Switch Cluster (0x003B) + * In [1]: request=protos.chip.rpc.ActionsWrite(endpoint_id=1, cluster_id=int("0x003B", 16)) + * + * # Add an action to write attribute id 0x1 (CurrentPosition) with data 2 after 1000 ms (meaning right away) + * In [2]: request.actions.append(protos.chip.rpc.Action(type=protos.chip.rpc.ActionType.WRITE_ATTRIBUTE, delayMs=1000, + * actionId=1, arg1=2)) + * + * # Define the follow action to emit an event id 0x1 (InitialPress) with data 2 (NewPosition) after 1000 ms + * In [3]: message.actions.append(protos.chip.rpc.Action(type=protos.chip.rpc.ActionType.EMIT_EVENT, delayMs=1000, + * actionId=1, arg1=2)) + * + * # Define the follow action to emit an event id 0x2 (LongPress) with data 2 (NewPosition) after 2000 ms + * In [4]: message.actions.append(protos.chip.rpc.Action(type=protos.chip.rpc.ActionType.EMIT_EVENT, delayMs=2000, + * actionId=2, arg1=2)) + * + * # Define an action to write attribute id 0x1 (CurrentPosition) with data 0 after 2000 ms (meaning button bouncing back) + * In [5]: message.actions.append(protos.chip.rpc.Action(type=protos.chip.rpc.ActionType.WRITE_ATTRIBUTE, delayMs=2000, + * actionId=1, arg1=0)) + * + * # Define the follow action to emit an event id 0x4 (LongRelease) with data 2 (PreviousPosition) after 1000 ms + * In [6]: message.actions.append(protos.chip.rpc.Action(type=protos.chip.rpc.ActionType.EMIT_EVENT, delayMs=1000, + * actionId=4, arg1=2)) + * + * # Set the actions to device + * In [7]: rpcs.chip.rpc.Actions.Set(message, pw_rpc_timeout_s=10000) + * + */ +public: + enum class Type : uint8_t + { + Attribute = 0, + Command = 1, + Event = 2, + }; + + ::pw::Status Set(const chip_rpc_ActionsRequest & request, ::pw_protobuf_Empty & response) + + { + DeviceLayer::StackLock lock; + ChipLogProgress(NotSpecified, " request.endpoint_id=%d, request.cluster_id=%d", request.endpoint_id, request.cluster_id); + + for (int i = 0; i < request.actions_count; i++) + { + chip_rpc_Action action = request.actions[i]; + std::vector args; + if (action.has_arg1) + args.push_back(action.arg1); + if (action.has_arg2) + args.push_back(action.arg2); + if (action.has_arg3) + args.push_back(action.arg3); + + mActionsSubscribeCallback(request.endpoint_id, request.cluster_id, static_cast(action.type), action.delayMs, + action.actionId, args); + } + + return pw::OkStatus(); + } + + using RpcActionsSubscribeCallback = bool (*)(EndpointId endpointId, ClusterId clusterId, uint8_t type, uint32_t delayMs, + uint32_t actionId, std::vector args); + + void SubscribeActions(RpcActionsSubscribeCallback subscriber) { mActionsSubscribeCallback = subscriber; }; + +private: + RpcActionsSubscribeCallback mActionsSubscribeCallback; +}; + +} // namespace rpc +} // namespace chip diff --git a/examples/platform/esp32/Rpc.cpp b/examples/platform/esp32/Rpc.cpp index 61efb842f089b7..a3b61830b5a46a 100644 --- a/examples/platform/esp32/Rpc.cpp +++ b/examples/platform/esp32/Rpc.cpp @@ -52,6 +52,10 @@ #include "pigweed/rpc_services/Device.h" #endif // defined(PW_RPC_DEVICE_SERVICE) && PW_RPC_DEVICE_SERVICE +#if defined(PW_RPC_EVENT_SERVICE) && PW_RPC_EVENT_SERVICE +#include "pigweed/rpc_services/Event.h" +#endif // defined(PW_RPC_EVENT_SERVICE) && PW_RPC_EVENT_SERVICE + #if defined(PW_RPC_LIGHTING_SERVICE) && PW_RPC_LIGHTING_SERVICE #include "pigweed/rpc_services/Lighting.h" #endif // defined(PW_RPC_LIGHTING_SERVICE) && PW_RPC_LIGHTING_SERVICE @@ -275,6 +279,10 @@ static TaskHandle_t sRpcTaskHandle; StaticTask_t sRpcTaskBuffer; StackType_t sRpcTaskStack[RPC_TASK_STACK_SIZE]; +#if defined(PW_RPC_ACTIONS_SERVICE) && PW_RPC_ACTIONS_SERVICE +Actions actions_service; +#endif // defined(PW_RPC_ACTIONS_SERVICE) && PW_RPC_ACTIONS_SERVICE + #if defined(PW_RPC_ATTRIBUTE_SERVICE) && PW_RPC_ATTRIBUTE_SERVICE Attributes attributes_service; #endif // defined(PW_RPC_ATTRIBUTE_SERVICE) && PW_RPC_ATTRIBUTE_SERVICE @@ -295,6 +303,10 @@ Descriptor descriptor_service; Esp32Device device_service; #endif // defined(PW_RPC_DEVICE_SERVICE) && PW_RPC_DEVICE_SERVICE +#if defined(PW_RPC_EVENT_SERVICE) && PW_RPC_EVENT_SERVICE +Event event_service; +#endif // defined(PW_RPC_EVENT_SERVICE) && PW_RPC_EVENT_SERVICE + #if defined(PW_RPC_LIGHTING_SERVICE) && PW_RPC_LIGHTING_SERVICE Lighting lighting_service; #endif // defined(PW_RPC_LIGHTING_SERVICE) && PW_RPC_LIGHTING_SERVICE @@ -313,6 +325,10 @@ Esp32WiFi wifi_service; void RegisterServices(pw::rpc::Server & server) { +#if defined(PW_RPC_ACTIONS_SERVICE) && PW_RPC_ACTIONS_SERVICE + server.RegisterService(actions_service); +#endif // defined(PW_RPC_ACTIONS_SERVICE) && PW_RPC_ACTIONS_SERVICE + #if defined(PW_RPC_ATTRIBUTE_SERVICE) && PW_RPC_ATTRIBUTE_SERVICE server.RegisterService(attributes_service); #endif // defined(PW_RPC_ATTRIBUTE_SERVICE) && PW_RPC_ATTRIBUTE_SERVICE @@ -333,6 +349,10 @@ void RegisterServices(pw::rpc::Server & server) server.RegisterService(device_service); #endif // defined(PW_RPC_DEVICE_SERVICE) && PW_RPC_DEVICE_SERVICE +#if defined(PW_RPC_EVENT_SERVICE) && PW_RPC_EVENT_SERVICE + server.RegisterService(event_service); +#endif // defined(PW_RPC_EVENT_SERVICE) && PW_RPC_EVENT_SERVICE + #if defined(PW_RPC_LIGHTING_SERVICE) && PW_RPC_LIGHTING_SERVICE server.RegisterService(lighting_service); #endif // defined(PW_RPC_LIGHTING_SERVICE) && PW_RPC_LIGHTING_SERVICE @@ -353,6 +373,13 @@ void RegisterServices(pw::rpc::Server & server) } // namespace +#if defined(PW_RPC_ACTIONS_SERVICE) && PW_RPC_ACTIONS_SERVICE +void SubscribeActions(RpcActionsSubscribeCallback subscriber) +{ + actions_service.SubscribeActions(subscriber); +} +#endif // defined(PW_RPC_ACTIONS_SERVICE) && PW_RPC_ACTIONS_SERVICE + void RunRpcService(void *) { Start(RegisterServices, &logger_mutex); diff --git a/examples/platform/esp32/Rpc.h b/examples/platform/esp32/Rpc.h index 9b73e5cafca96b..ff1a5f319ac975 100644 --- a/examples/platform/esp32/Rpc.h +++ b/examples/platform/esp32/Rpc.h @@ -20,6 +20,18 @@ namespace chip { namespace rpc { +enum class ActionType : uint8_t +{ + WRITE_ATTRIBUTE = 0x00, // Write an cluster Attribute + RUN_COMMAND = 0x01, // Run a cluster Command + EMIT_EVENT = 0x02, // Emit a cluster Events +}; + +using RpcActionsSubscribeCallback = bool (*)(EndpointId endpointId, ClusterId clusterId, uint8_t type, uint32_t delayMs, + uint32_t actionId, std::vector args); + +void SubscribeActions(RpcActionsSubscribeCallback subscriber); + void Init(); } // namespace rpc diff --git a/examples/platform/linux/Rpc.cpp b/examples/platform/linux/Rpc.cpp index da6b73b9135c13..6e20e2aecf61b9 100644 --- a/examples/platform/linux/Rpc.cpp +++ b/examples/platform/linux/Rpc.cpp @@ -20,8 +20,16 @@ #include "pw_rpc_system_server/rpc_server.h" #include "pw_rpc_system_server/socket.h" +#include #include +#include "Rpc.h" +#include + +#if defined(PW_RPC_ACTIONS_SERVICE) && PW_RPC_ACTIONS_SERVICE +#include "pigweed/rpc_services/Actions.h" +#endif // defined(PW_RPC_ACTIONS_SERVICE) && PW_RPC_ACTIONS_SERVICE + #if defined(PW_RPC_ATTRIBUTE_SERVICE) && PW_RPC_ATTRIBUTE_SERVICE #include "pigweed/rpc_services/Attributes.h" #endif // defined(PW_RPC_ATTRIBUTE_SERVICE) && PW_RPC_ATTRIBUTE_SERVICE @@ -68,6 +76,10 @@ namespace chip { namespace rpc { namespace { +#if defined(PW_RPC_ACTIONS_SERVICE) && PW_RPC_ACTIONS_SERVICE +Actions actions_service; +#endif // defined(PW_RPC_ACTIONS_SERVICE) && PW_RPC_ACTIONS_SERVICE + #if defined(PW_RPC_ATTRIBUTE_SERVICE) && PW_RPC_ATTRIBUTE_SERVICE Attributes attributes_service; #endif // defined(PW_RPC_ATTRIBUTE_SERVICE) && PW_RPC_ATTRIBUTE_SERVICE @@ -94,6 +106,10 @@ pw::trace::TraceService trace_service(pw::trace::GetTokenizedTracer()); void RegisterServices(pw::rpc::Server & server) { +#if defined(PW_RPC_ACTIONS_SERVICE) && PW_RPC_ACTIONS_SERVICE + server.RegisterService(actions_service); +#endif // defined(PW_RPC_ACTIONS_SERVICE) && PW_RPC_ACTIONS_SERVICE + #if defined(PW_RPC_ATTRIBUTE_SERVICE) && PW_RPC_ATTRIBUTE_SERVICE server.RegisterService(attributes_service); #endif // defined(PW_RPC_ATTRIBUTE_SERVICE) && PW_RPC_ATTRIBUTE_SERVICE @@ -122,6 +138,13 @@ void RegisterServices(pw::rpc::Server & server) } // namespace +#if defined(PW_RPC_ACTIONS_SERVICE) && PW_RPC_ACTIONS_SERVICE +void SubscribeActions(RpcActionsSubscribeCallback subscriber) +{ + actions_service.SubscribeActions(subscriber); +} +#endif // defined(PW_RPC_ACTIONS_SERVICE) && PW_RPC_ACTIONS_SERVICE + void RunRpcService() { pw::rpc::system_server::Init(); diff --git a/examples/platform/linux/Rpc.h b/examples/platform/linux/Rpc.h index fbcfc6ed63f4f2..51f3f2e473bacb 100644 --- a/examples/platform/linux/Rpc.h +++ b/examples/platform/linux/Rpc.h @@ -18,9 +18,24 @@ #pragma once +#include +#include + namespace chip { namespace rpc { +enum class ActionType : uint8_t +{ + WRITE_ATTRIBUTE = 0x00, // Write an cluster Attribute + RUN_COMMAND = 0x01, // Run a cluster Command + EMIT_EVENT = 0x02, // Emit a cluster Events +}; + +using RpcActionsSubscribeCallback = bool (*)(EndpointId endpointId, ClusterId clusterId, uint8_t type, uint32_t delayMs, + uint32_t actionId, std::vector args); + +void SubscribeActions(RpcActionsSubscribeCallback subscriber); + int Init(uint16_t rpcServerPort); } // namespace rpc diff --git a/examples/platform/nrfconnect/Rpc.cpp b/examples/platform/nrfconnect/Rpc.cpp index 8b47215d6a0680..510b0ac8ac4c64 100644 --- a/examples/platform/nrfconnect/Rpc.cpp +++ b/examples/platform/nrfconnect/Rpc.cpp @@ -28,6 +28,10 @@ LOG_MODULE_DECLARE(app, CONFIG_CHIP_APP_LOG_LEVEL); +#if defined(PW_RPC_ACTIONS_SERVICE) && PW_RPC_ACTIONS_SERVICE +#include "pigweed/rpc_services/Actions.h" +#endif // defined(PW_RPC_ACTIONS_SERVICE) && PW_RPC_ACTIONS_SERVICE + #if defined(PW_RPC_ATTRIBUTE_SERVICE) && PW_RPC_ATTRIBUTE_SERVICE #include "pigweed/rpc_services/Attributes.h" #endif // defined(PW_RPC_ATTRIBUTE_SERVICE) && PW_RPC_ATTRIBUTE_SERVICE @@ -48,6 +52,10 @@ LOG_MODULE_DECLARE(app, CONFIG_CHIP_APP_LOG_LEVEL); #include "pigweed/rpc_services/Device.h" #endif // defined(PW_RPC_DEVICE_SERVICE) && PW_RPC_DEVICE_SERVICE +#if defined(PW_RPC_EVENT_SERVICE) && PW_RPC_EVENT_SERVICE +#include "pigweed/rpc_services/Event.h" +#endif // defined(PW_RPC_EVENT_SERVICE) && PW_RPC_EVENT_SERVICE + #if defined(PW_RPC_LIGHTING_SERVICE) && PW_RPC_LIGHTING_SERVICE #include "pigweed/rpc_services/Lighting.h" #endif // defined(PW_RPC_LIGHTING_SERVICE) && PW_RPC_LIGHTING_SERVICE @@ -85,6 +93,10 @@ size_t pw_trace_GetTraceTimeTicksPerSecond() namespace chip { namespace rpc { +#if defined(PW_RPC_ACTIONS_SERVICE) && PW_RPC_ACTIONS_SERVICE +Actions actions_service; +#endif // defined(PW_RPC_ACTIONS_SERVICE) && PW_RPC_ACTIONS_SERVICE + #if defined(PW_RPC_DEVICE_SERVICE) && PW_RPC_DEVICE_SERVICE namespace { @@ -159,6 +171,10 @@ Descriptor descriptor_service; NrfDevice device_service; #endif // defined(PW_RPC_DEVICE_SERVICE) && PW_RPC_DEVICE_SERVICE +#if defined(PW_RPC_EVENT_SERVICE) && PW_RPC_EVENT_SERVICE +Event event_service; +#endif // defined(PW_RPC_EVENT_SERVICE) && PW_RPC_EVENT_SERVICE + #if defined(PW_RPC_LIGHTING_SERVICE) && PW_RPC_LIGHTING_SERVICE Lighting lighting_service; #endif // defined(PW_RPC_LIGHTING_SERVICE) && PW_RPC_LIGHTING_SERVICE @@ -181,6 +197,10 @@ pw::trace::TraceService trace_service(pw::trace::GetTokenizedTracer()); void RegisterServices(pw::rpc::Server & server) { +#if defined(PW_RPC_ACTIONS_SERVICE) && PW_RPC_ACTIONS_SERVICE + server.RegisterService(actions_service); +#endif // defined(PW_RPC_ACTIONS_SERVICE) && PW_RPC_ACTIONS_SERVICE + #if defined(PW_RPC_ATTRIBUTE_SERVICE) && PW_RPC_ATTRIBUTE_SERVICE server.RegisterService(attributes_service); #endif // defined(PW_RPC_ATTRIBUTE_SERVICE) && PW_RPC_ATTRIBUTE_SERVICE @@ -201,6 +221,10 @@ void RegisterServices(pw::rpc::Server & server) server.RegisterService(device_service); #endif // defined(PW_RPC_DEVICE_SERVICE) && PW_RPC_DEVICE_SERVICE +#if defined(PW_RPC_EVENT_SERVICE) && PW_RPC_EVENT_SERVICE + server.RegisterService(event_service); +#endif // defined(PW_RPC_EVENT_SERVICE) && PW_RPC_EVENT_SERVICE + #if defined(PW_RPC_LIGHTING_SERVICE) && PW_RPC_LIGHTING_SERVICE server.RegisterService(lighting_service); #endif // defined(PW_RPC_LIGHTING_SERVICE) && PW_RPC_LIGHTING_SERVICE @@ -225,6 +249,13 @@ void RegisterServices(pw::rpc::Server & server) } // namespace +#if defined(PW_RPC_ACTIONS_SERVICE) && PW_RPC_ACTIONS_SERVICE +void SubscribeActions(RpcActionsSubscribeCallback subscriber) +{ + actions_service.SubscribeActions(subscriber); +} +#endif // defined(PW_RPC_ACTIONS_SERVICE) && PW_RPC_ACTIONS_SERVICE + void RunRpcService(void *, void *, void *) { Start(RegisterServices, &logger_mutex); diff --git a/examples/platform/nrfconnect/Rpc.h b/examples/platform/nrfconnect/Rpc.h index f0aeaf45b61fba..40efcb0750ca2b 100644 --- a/examples/platform/nrfconnect/Rpc.h +++ b/examples/platform/nrfconnect/Rpc.h @@ -23,6 +23,18 @@ namespace chip { namespace rpc { +enum class ActionType : uint8_t +{ + WRITE_ATTRIBUTE = 0x00, // Write an cluster Attribute + RUN_COMMAND = 0x01, // Run a cluster Command + EMIT_EVENT = 0x02, // Emit a cluster Events +}; + +using RpcActionsSubscribeCallback = bool (*)(EndpointId endpointId, ClusterId clusterId, uint8_t type, uint32_t delayMs, + uint32_t actionId, std::vector args); + +void SubscribeActions(RpcActionsSubscribeCallback subscriber); + class NrfButton; void RunRpcService(void *, void *, void *); From 6b8368981061fc0b606c99ec9858065f0d215054 Mon Sep 17 00:00:00 2001 From: Andrei Litvin Date: Mon, 27 May 2024 12:42:06 -0400 Subject: [PATCH 05/10] Use AddResponse instead of AddResponseData when no error checking is performed (#33598) Co-authored-by: Andrei Litvin --- .../tv-app/android/java/ContentAppCommandDelegate.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/tv-app/android/java/ContentAppCommandDelegate.cpp b/examples/tv-app/android/java/ContentAppCommandDelegate.cpp index a4a8d09396ae53..199ec7761be0c8 100644 --- a/examples/tv-app/android/java/ContentAppCommandDelegate.cpp +++ b/examples/tv-app/android/java/ContentAppCommandDelegate.cpp @@ -197,7 +197,7 @@ void ContentAppCommandDelegate::FormatResponseData(CommandHandlerInterface::Hand } else { - handlerContext.mCommandHandler.AddResponseData(handlerContext.mRequestPath, launchResponse); + handlerContext.mCommandHandler.AddResponse(handlerContext.mRequestPath, launchResponse); } break; } @@ -211,7 +211,7 @@ void ContentAppCommandDelegate::FormatResponseData(CommandHandlerInterface::Hand } else { - handlerContext.mCommandHandler.AddResponseData(handlerContext.mRequestPath, navigateTargetResponse); + handlerContext.mCommandHandler.AddResponse(handlerContext.mRequestPath, navigateTargetResponse); } break; } @@ -225,7 +225,7 @@ void ContentAppCommandDelegate::FormatResponseData(CommandHandlerInterface::Hand } else { - handlerContext.mCommandHandler.AddResponseData(handlerContext.mRequestPath, playbackResponse); + handlerContext.mCommandHandler.AddResponse(handlerContext.mRequestPath, playbackResponse); } break; } @@ -244,7 +244,7 @@ void ContentAppCommandDelegate::FormatResponseData(CommandHandlerInterface::Hand } else { - handlerContext.mCommandHandler.AddResponseData(handlerContext.mRequestPath, getSetupPINresponse); + handlerContext.mCommandHandler.AddResponse(handlerContext.mRequestPath, getSetupPINresponse); } break; } From 16d6475ef81f890371ab0d1b1f7e42ea4318d13a Mon Sep 17 00:00:00 2001 From: Andrei Litvin Date: Mon, 27 May 2024 21:21:43 -0400 Subject: [PATCH 06/10] Minimize API surface that is templated for `CommandHandler` (#33620) * Define a EncodeToTLV inteface for the command handler * Slight documentation update * Comments update --- src/app/CommandHandler.h | 92 ++++++++++++++++++++++++++++++---------- 1 file changed, 70 insertions(+), 22 deletions(-) diff --git a/src/app/CommandHandler.h b/src/app/CommandHandler.h index cce19879a6c8a9..96b7af873554ed 100644 --- a/src/app/CommandHandler.h +++ b/src/app/CommandHandler.h @@ -57,6 +57,32 @@ namespace chip { namespace app { +/// Defines an abstract class of something that can be encoded +/// into a TLV with a given data tag +class EncoderToTLV +{ +public: + virtual ~EncoderToTLV() = default; + + virtual CHIP_ERROR Encode(TLV::TLVWriter &, TLV::Tag tag) = 0; +}; + +/// An `EncoderToTLV` the uses `DataModel::Encode` to encode things. +/// +/// Generally useful to encode things like ::Commands::::Type +/// structures. +template +class DataModelEncoderToTLV : public EncoderToTLV +{ +public: + DataModelEncoderToTLV(const T & value) : mValue(value) {} + + virtual CHIP_ERROR Encode(TLV::TLVWriter & writer, TLV::Tag tag) { return DataModel::Encode(writer, tag, mValue); } + +private: + const T & mValue; +}; + class CommandHandler { public: @@ -325,14 +351,37 @@ class CommandHandler * @param [in] aRequestCommandPath the concrete path of the command we are * responding to. * @param [in] aData the data for the response. + * + * NOTE: this is a convenience function for `AddResponseDataViaEncoder` */ template - CHIP_ERROR AddResponseData(const ConcreteCommandPath & aRequestCommandPath, const CommandData & aData) + inline CHIP_ERROR AddResponseData(const ConcreteCommandPath & aRequestCommandPath, const CommandData & aData) + { + DataModelEncoderToTLV encoder(aData); + return AddResponseDataViaEncoder(aRequestCommandPath, CommandData::GetCommandId(), encoder); + } + + /** + * API for adding a data response. The encoded is generally expected to encode + * a ClusterName::Commands::CommandName::Type struct, but any + * object should work. + * + * @param [in] aRequestCommandPath the concrete path of the command we are + * responding to. + * @param [in] commandId the command whose content is being encoded. + * @param [in] encoder - an encoder that places the command data structure for `commandId` + * into a TLV Writer. + * + * Most applications are likely to use `AddResponseData` as a more convenient + * one-call that auto-sets command ID and creates the underlying encoders. + */ + CHIP_ERROR AddResponseDataViaEncoder(const ConcreteCommandPath & aRequestCommandPath, CommandId commandId, + EncoderToTLV & encoder) { // Return early when response should not be sent out. VerifyOrReturnValue(ResponsesAccepted(), CHIP_NO_ERROR); - - return TryAddingResponse([&]() -> CHIP_ERROR { return TryAddResponseData(aRequestCommandPath, aData); }); + return TryAddingResponse( + [&]() -> CHIP_ERROR { return TryAddResponseDataViaEncoder(aRequestCommandPath, commandId, encoder); }); } /** @@ -350,9 +399,21 @@ class CommandHandler * @param [in] aData the data for the response. */ template - void AddResponse(const ConcreteCommandPath & aRequestCommandPath, const CommandData & aData) + inline void AddResponse(const ConcreteCommandPath & aRequestCommandPath, const CommandData & aData) { - if (AddResponseData(aRequestCommandPath, aData) != CHIP_NO_ERROR) + DataModelEncoderToTLV encoder(aData); + return AddResponseViaEncoder(aRequestCommandPath, CommandData::GetCommandId(), encoder); + } + + /** + * API for adding a response with a given encoder of TLV data. + * + * The encoder would generally encode a ClusterName::Commands::CommandName::Type with + * the corresponding `GetCommandId` call. + */ + void AddResponseViaEncoder(const ConcreteCommandPath & aRequestCommandPath, CommandId commandId, EncoderToTLV & encoder) + { + if (AddResponseDataViaEncoder(aRequestCommandPath, commandId, encoder) != CHIP_NO_ERROR) { AddStatus(aRequestCommandPath, Protocols::InteractionModel::Status::Failure); } @@ -630,7 +691,6 @@ class CommandHandler return PrepareInvokeResponseCommand(aResponseCommandPath, prepareParams); } - // TODO(#31627): It would be awesome if we could remove this template all together. /** * If this function fails, it may leave our TLV buffer in an inconsistent state. * Callers should snapshot as needed before calling this function, and roll back @@ -640,26 +700,14 @@ class CommandHandler * responding to. * @param [in] aData the data for the response. */ - template - CHIP_ERROR TryAddResponseData(const ConcreteCommandPath & aRequestCommandPath, const CommandData & aData) + CHIP_ERROR TryAddResponseDataViaEncoder(const ConcreteCommandPath & aRequestCommandPath, CommandId commandId, + EncoderToTLV & encoder) { - // This method, templated with CommandData, captures all the components needs - // from CommandData with as little code as possible. - // - // Previously, non-essential code was unnecessarily templated, leading to - // compilation and duplication N times. By isolating only the code segments - // that genuinely require templating, minimizes duplicate compiled code. - ConcreteCommandPath responseCommandPath = { aRequestCommandPath.mEndpointId, aRequestCommandPath.mClusterId, - CommandData::GetCommandId() }; + ConcreteCommandPath responseCommandPath = { aRequestCommandPath.mEndpointId, aRequestCommandPath.mClusterId, commandId }; ReturnErrorOnFailure(TryAddResponseDataPreEncode(aRequestCommandPath, responseCommandPath)); TLV::TLVWriter * writer = GetCommandDataIBTLVWriter(); VerifyOrReturnError(writer != nullptr, CHIP_ERROR_INCORRECT_STATE); - ReturnErrorOnFailure(DataModel::Encode(*writer, TLV::ContextTag(CommandDataIB::Tag::kFields), aData)); - - // FinishCommand technically should be refactored out as it is not a command that needs templating. - // But, because there is only a single function call, keeping it here takes less code. If there is - // ever more code between DataModel::Encode and the end of this function, it should be broken out into - // TryAddResponseDataPostEncode. + ReturnErrorOnFailure(encoder.Encode(*writer, TLV::ContextTag(CommandDataIB::Tag::kFields))); return FinishCommand(/* aEndDataStruct = */ false); } From b9eee2802ecfe6c9be96c2b9ef3e6c845c7954e9 Mon Sep 17 00:00:00 2001 From: Arkadiusz Bokowy Date: Tue, 28 May 2024 15:16:41 +0200 Subject: [PATCH 07/10] [Tizen] Add libatomic.so to QEMU Docker image (#33631) --- integrations/docker/images/base/chip-build/version | 2 +- .../docker/images/stage-3/chip-build-tizen-qemu/Dockerfile | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/integrations/docker/images/base/chip-build/version b/integrations/docker/images/base/chip-build/version index 9a59e96c18355c..05ab2a03dbdb4f 100644 --- a/integrations/docker/images/base/chip-build/version +++ b/integrations/docker/images/base/chip-build/version @@ -1 +1 @@ -52 : [NXP] Update K32W0 SDK to 2.6.14 \ No newline at end of file +53 : [Tizen] Add libatomic.so to QEMU Docker image diff --git a/integrations/docker/images/stage-3/chip-build-tizen-qemu/Dockerfile b/integrations/docker/images/stage-3/chip-build-tizen-qemu/Dockerfile index ff63e5c1940a01..8c38d19c1b3ed8 100644 --- a/integrations/docker/images/stage-3/chip-build-tizen-qemu/Dockerfile +++ b/integrations/docker/images/stage-3/chip-build-tizen-qemu/Dockerfile @@ -84,6 +84,7 @@ RUN set -x \ # Add extra libraries to the root image && guestfish --rw -a $TIZEN_IOT_IMAGE_ROOT -m /dev/sda copy-in \ $TIZEN_SDK_TOOLCHAIN/arm-tizen-linux-gnueabi/lib/libasan.so.* \ + $TIZEN_SDK_TOOLCHAIN/arm-tizen-linux-gnueabi/lib/libatomic.so.* \ $TIZEN_SDK_TOOLCHAIN/arm-tizen-linux-gnueabi/lib/libubsan.so.* \ $TIZEN_SDK_SYSROOT/usr/lib/libbluetooth-api.so.* \ $TIZEN_SDK_SYSROOT/usr/lib/libcapi-network-bluetooth.so.* \ From 4dac5367c3f20c0c3d6ea1f428b375bdfec0e0d7 Mon Sep 17 00:00:00 2001 From: Karsten Sperling <113487422+ksperling-apple@users.noreply.github.com> Date: Wed, 29 May 2024 01:44:55 +1200 Subject: [PATCH 08/10] Linux: Guard mallinfo() use behind check for __GLIBC__ (#33626) * Linux: Guard mallinfo() use behind check for __GLIBC__ * Use positive checks for __GLIBC__ rather than ifndef --- .../Linux/DiagnosticDataProviderImpl.cpp | 22 +++++++++++-------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/src/platform/Linux/DiagnosticDataProviderImpl.cpp b/src/platform/Linux/DiagnosticDataProviderImpl.cpp index 5ee5558064afeb..bebe5827163fa9 100644 --- a/src/platform/Linux/DiagnosticDataProviderImpl.cpp +++ b/src/platform/Linux/DiagnosticDataProviderImpl.cpp @@ -74,8 +74,10 @@ enum class WiFiStatsCountType kWiFiOverrunCount }; +#if defined(__GLIBC__) // Static variable to store the maximum heap size static size_t maxHeapHighWatermark = 0; +#endif CHIP_ERROR GetEthernetStatsCount(EthernetStatsCountType type, uint64_t & count) { @@ -223,9 +225,7 @@ DiagnosticDataProviderImpl & DiagnosticDataProviderImpl::GetDefaultInstance() CHIP_ERROR DiagnosticDataProviderImpl::GetCurrentHeapFree(uint64_t & currentHeapFree) { -#ifndef __GLIBC__ - return CHIP_ERROR_NOT_IMPLEMENTED; -#else +#if defined(__GLIBC__) struct mallinfo mallocInfo = mallinfo(); // Get the current amount of heap memory, in bytes, that are not being utilized @@ -233,14 +233,14 @@ CHIP_ERROR DiagnosticDataProviderImpl::GetCurrentHeapFree(uint64_t & currentHeap currentHeapFree = mallocInfo.fordblks; return CHIP_NO_ERROR; +#else + return CHIP_ERROR_NOT_IMPLEMENTED; #endif } CHIP_ERROR DiagnosticDataProviderImpl::GetCurrentHeapUsed(uint64_t & currentHeapUsed) { -#ifndef __GLIBC__ - return CHIP_ERROR_NOT_IMPLEMENTED; -#else +#if defined(__GLIBC__) struct mallinfo mallocInfo = mallinfo(); // Get the current amount of heap memory, in bytes, that are being used by @@ -253,14 +253,14 @@ CHIP_ERROR DiagnosticDataProviderImpl::GetCurrentHeapUsed(uint64_t & currentHeap maxHeapHighWatermark = currentHeapUsed; } return CHIP_NO_ERROR; +#else + return CHIP_ERROR_NOT_IMPLEMENTED; #endif } CHIP_ERROR DiagnosticDataProviderImpl::GetCurrentHeapHighWatermark(uint64_t & currentHeapHighWatermark) { -#ifndef __GLIBC__ - return CHIP_ERROR_NOT_IMPLEMENTED; -#else +#if defined(__GLIBC__) struct mallinfo mallocInfo = mallinfo(); // The usecase of this function is embedded devices,on which we would need to intercept @@ -279,6 +279,8 @@ CHIP_ERROR DiagnosticDataProviderImpl::GetCurrentHeapHighWatermark(uint64_t & cu currentHeapHighWatermark = maxHeapHighWatermark; return CHIP_NO_ERROR; +#else + return CHIP_ERROR_NOT_IMPLEMENTED; #endif } @@ -287,10 +289,12 @@ CHIP_ERROR DiagnosticDataProviderImpl::ResetWatermarks() // If implemented, the server SHALL set the value of the CurrentHeapHighWatermark attribute to the // value of the CurrentHeapUsed. +#if defined(__GLIBC__) // Get the current amount of heap memory, in bytes, that are being used by // the current running program and reset the max heap high watermark to current heap amount. struct mallinfo mallocInfo = mallinfo(); maxHeapHighWatermark = mallocInfo.uordblks; +#endif return CHIP_NO_ERROR; } From c7b4965356abe49439348548259199a8daec3e05 Mon Sep 17 00:00:00 2001 From: jamesharrow <93921463+jamesharrow@users.noreply.github.com> Date: Tue, 28 May 2024 14:45:33 +0100 Subject: [PATCH 09/10] Remove provisional from evse, evse mode, epm, eem, power topology (#33558) * XML file changes to remove apiMaturity="provisional" for clusters and features which are approved in Matter 1.3 * Removed stray text. * Updated after regen_all --- .../all-clusters-app.matter | 10 ++-- .../energy-management-app.matter | 10 ++-- .../electrical-energy-measurement-cluster.xml | 10 ++-- .../electrical-power-measurement-cluster.xml | 10 ++-- .../data-model/chip/energy-evse-cluster.xml | 60 +++++++++---------- .../chip/energy-evse-mode-cluster.xml | 2 +- .../chip/power-topology-cluster.xml | 2 +- .../data_model/controller-clusters.matter | 10 ++-- 8 files changed, 57 insertions(+), 57 deletions(-) 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 03e3cc6ca3fe20..719293ab5f877a 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 @@ -3876,7 +3876,7 @@ cluster ValveConfigurationAndControl = 129 { } /** This cluster provides a mechanism for querying data about electrical power as measured by the server. */ -provisional cluster ElectricalPowerMeasurement = 144 { +cluster ElectricalPowerMeasurement = 144 { revision 1; enum MeasurementTypeEnum : enum16 { @@ -3981,7 +3981,7 @@ provisional cluster ElectricalPowerMeasurement = 144 { } /** This cluster provides a mechanism for querying data about the electrical energy imported or provided by the server. */ -provisional cluster ElectricalEnergyMeasurement = 145 { +cluster ElectricalEnergyMeasurement = 145 { revision 1; enum MeasurementTypeEnum : enum16 { @@ -4278,7 +4278,7 @@ provisional cluster DeviceEnergyManagement = 152 { } /** Electric Vehicle Supply Equipment (EVSE) is equipment used to charge an Electric Vehicle (EV) or Plug-In Hybrid Electric Vehicle. This cluster provides an interface to the functionality of Electric Vehicle Supply Equipment (EVSE) management. */ -provisional cluster EnergyEvse = 153 { +cluster EnergyEvse = 153 { revision 2; enum EnergyTransferStoppedReasonEnum : enum8 { @@ -4490,7 +4490,7 @@ provisional cluster EnergyPreference = 155 { } /** The Power Topology Cluster provides a mechanism for expressing how power is flowing between endpoints. */ -provisional cluster PowerTopology = 156 { +cluster PowerTopology = 156 { revision 1; bitmap Feature : bitmap32 { @@ -4511,7 +4511,7 @@ provisional cluster PowerTopology = 156 { } /** Attributes and commands for selecting a mode from a list of supported options. */ -provisional cluster EnergyEvseMode = 157 { +cluster EnergyEvseMode = 157 { revision 1; enum ModeTag : enum16 { diff --git a/examples/energy-management-app/energy-management-common/energy-management-app.matter b/examples/energy-management-app/energy-management-common/energy-management-app.matter index ea4e5db21a0b18..68db2eea271ec3 100644 --- a/examples/energy-management-app/energy-management-common/energy-management-app.matter +++ b/examples/energy-management-app/energy-management-common/energy-management-app.matter @@ -1237,7 +1237,7 @@ cluster GroupKeyManagement = 63 { } /** This cluster provides a mechanism for querying data about electrical power as measured by the server. */ -provisional cluster ElectricalPowerMeasurement = 144 { +cluster ElectricalPowerMeasurement = 144 { revision 1; enum MeasurementTypeEnum : enum16 { @@ -1342,7 +1342,7 @@ provisional cluster ElectricalPowerMeasurement = 144 { } /** This cluster provides a mechanism for querying data about the electrical energy imported or provided by the server. */ -provisional cluster ElectricalEnergyMeasurement = 145 { +cluster ElectricalEnergyMeasurement = 145 { revision 1; enum MeasurementTypeEnum : enum16 { @@ -1639,7 +1639,7 @@ provisional cluster DeviceEnergyManagement = 152 { } /** Electric Vehicle Supply Equipment (EVSE) is equipment used to charge an Electric Vehicle (EV) or Plug-In Hybrid Electric Vehicle. This cluster provides an interface to the functionality of Electric Vehicle Supply Equipment (EVSE) management. */ -provisional cluster EnergyEvse = 153 { +cluster EnergyEvse = 153 { revision 2; enum EnergyTransferStoppedReasonEnum : enum8 { @@ -1817,7 +1817,7 @@ provisional cluster EnergyEvse = 153 { } /** The Power Topology Cluster provides a mechanism for expressing how power is flowing between endpoints. */ -provisional cluster PowerTopology = 156 { +cluster PowerTopology = 156 { revision 1; bitmap Feature : bitmap32 { @@ -1838,7 +1838,7 @@ provisional cluster PowerTopology = 156 { } /** Attributes and commands for selecting a mode from a list of supported options. */ -provisional cluster EnergyEvseMode = 157 { +cluster EnergyEvseMode = 157 { revision 1; enum ModeTag : enum16 { diff --git a/src/app/zap-templates/zcl/data-model/chip/electrical-energy-measurement-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/electrical-energy-measurement-cluster.xml index 0a4039badf7c97..eb05052538d2de 100644 --- a/src/app/zap-templates/zcl/data-model/chip/electrical-energy-measurement-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/electrical-energy-measurement-cluster.xml @@ -16,7 +16,7 @@ limitations under the License. --> - + Electrical Energy Measurement Measurement & Sensing 0x0091 @@ -52,25 +52,25 @@ limitations under the License. PeriodicEnergyExported CumulativeEnergyReset - + CumulativeEnergyMeasured - + PeriodicEnergyMeasured - + - + diff --git a/src/app/zap-templates/zcl/data-model/chip/electrical-power-measurement-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/electrical-power-measurement-cluster.xml index 69be8e08570f39..7f49a643d1b1f9 100644 --- a/src/app/zap-templates/zcl/data-model/chip/electrical-power-measurement-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/electrical-power-measurement-cluster.xml @@ -16,7 +16,7 @@ limitations under the License. --> - + Electrical Power Measurement Measurement & Sensing 0x0090 @@ -82,18 +82,18 @@ limitations under the License. PowerFactor NeutralCurrent - + MeasurementPeriodRanges - + - + @@ -107,7 +107,7 @@ limitations under the License. - + diff --git a/src/app/zap-templates/zcl/data-model/chip/energy-evse-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/energy-evse-cluster.xml index cbc0882ac1b3ac..5c22b8e93be8da 100644 --- a/src/app/zap-templates/zcl/data-model/chip/energy-evse-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/energy-evse-cluster.xml @@ -14,7 +14,7 @@ limitations under the License. - + @@ -25,7 +25,7 @@ limitations under the License. - + @@ -34,7 +34,7 @@ limitations under the License. - + @@ -55,7 +55,7 @@ limitations under the License. - + @@ -86,7 +86,7 @@ limitations under the License. - + Energy EVSE Energy Management 0x0099 @@ -177,7 +177,7 @@ limitations under the License. Allows a client to disable the EVSE from charging and discharging. - + @@ -188,7 +188,7 @@ limitations under the License. Allows a client to enable the EVSE to discharge an EV. - + Allows a client to put the EVSE into a self-diagnostics mode. @@ -205,41 +205,41 @@ limitations under the License. The GetTargetsResponse is sent in response to the GetTargets Command. - + EVConnected - + - + EVNotDetected - - - - + + + + - + EnergyTransferStarted - - - + + + - + EnergyTransferStopped - - - - + + + + - + Fault - - - - + + + + - + RFID - + diff --git a/src/app/zap-templates/zcl/data-model/chip/energy-evse-mode-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/energy-evse-mode-cluster.xml index 22e5562ed33f7f..c4b702b701d174 100644 --- a/src/app/zap-templates/zcl/data-model/chip/energy-evse-mode-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/energy-evse-mode-cluster.xml @@ -24,7 +24,7 @@ limitations under the License. - + General Energy EVSE Mode 0x009D diff --git a/src/app/zap-templates/zcl/data-model/chip/power-topology-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/power-topology-cluster.xml index 2fdddcbe3560da..3bca0bd43ee8af 100644 --- a/src/app/zap-templates/zcl/data-model/chip/power-topology-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/power-topology-cluster.xml @@ -17,7 +17,7 @@ limitations under the License. - + Measurement & Sensing Power Topology 0x009C diff --git a/src/controller/data_model/controller-clusters.matter b/src/controller/data_model/controller-clusters.matter index dcc22df982b9e5..cd310219ea88d2 100644 --- a/src/controller/data_model/controller-clusters.matter +++ b/src/controller/data_model/controller-clusters.matter @@ -4112,7 +4112,7 @@ cluster ValveConfigurationAndControl = 129 { } /** This cluster provides a mechanism for querying data about electrical power as measured by the server. */ -provisional cluster ElectricalPowerMeasurement = 144 { +cluster ElectricalPowerMeasurement = 144 { revision 1; enum MeasurementTypeEnum : enum16 { @@ -4217,7 +4217,7 @@ provisional cluster ElectricalPowerMeasurement = 144 { } /** This cluster provides a mechanism for querying data about the electrical energy imported or provided by the server. */ -provisional cluster ElectricalEnergyMeasurement = 145 { +cluster ElectricalEnergyMeasurement = 145 { revision 1; enum MeasurementTypeEnum : enum16 { @@ -4803,7 +4803,7 @@ provisional cluster DeviceEnergyManagement = 152 { } /** Electric Vehicle Supply Equipment (EVSE) is equipment used to charge an Electric Vehicle (EV) or Plug-In Hybrid Electric Vehicle. This cluster provides an interface to the functionality of Electric Vehicle Supply Equipment (EVSE) management. */ -provisional cluster EnergyEvse = 153 { +cluster EnergyEvse = 153 { revision 2; enum EnergyTransferStoppedReasonEnum : enum8 { @@ -5015,7 +5015,7 @@ provisional cluster EnergyPreference = 155 { } /** The Power Topology Cluster provides a mechanism for expressing how power is flowing between endpoints. */ -provisional cluster PowerTopology = 156 { +cluster PowerTopology = 156 { revision 1; bitmap Feature : bitmap32 { @@ -5036,7 +5036,7 @@ provisional cluster PowerTopology = 156 { } /** Attributes and commands for selecting a mode from a list of supported options. */ -provisional cluster EnergyEvseMode = 157 { +cluster EnergyEvseMode = 157 { revision 1; enum ModeTag : enum16 { From 533df0c7ab1b9d7b7bb41e4ab119985c0bfe43ca Mon Sep 17 00:00:00 2001 From: Boris Zbarsky Date: Tue, 28 May 2024 10:19:41 -0400 Subject: [PATCH 10/10] Fix test by making darwin-framework-tool use the same command timeout as chip-tool. (#33633) The commands now take a bit longer to time out on the exchange level, so we were hitting the test timeout. --- .../commands/clusters/ModelCommandBridge.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/darwin-framework-tool/commands/clusters/ModelCommandBridge.h b/examples/darwin-framework-tool/commands/clusters/ModelCommandBridge.h index 447d2c2ae5ccf6..2deb7cfb4cac5e 100644 --- a/examples/darwin-framework-tool/commands/clusters/ModelCommandBridge.h +++ b/examples/darwin-framework-tool/commands/clusters/ModelCommandBridge.h @@ -38,7 +38,7 @@ class ModelCommand : public CHIPCommandBridge /////////// CHIPCommand Interface ///////// CHIP_ERROR RunCommand() override; - chip::System::Clock::Timeout GetWaitDuration() const override { return chip::System::Clock::Seconds16(10); } + chip::System::Clock::Timeout GetWaitDuration() const override { return chip::System::Clock::Seconds16(20); } virtual CHIP_ERROR SendCommand(MTRBaseDevice * _Nonnull device, chip::EndpointId endPointId) = 0;