diff --git a/.github/.wordlist.txt b/.github/.wordlist.txt index 31fe3392d52b1f..1b3866dd9cb3ad 100644 --- a/.github/.wordlist.txt +++ b/.github/.wordlist.txt @@ -1373,3 +1373,19 @@ zephyrproject Zigbee zigbeealliance zigbeethread +libshell +TestGroupDemoConfig +ACLs +AddNOC +CHIPConfig +CHIPProjectAppConfig +CaseAdminNode +DataVersion +ProxyView +ReadAttribute +WriteAttribute +kAdminister +kManage +kOperate +kView +xFFFFFFFD \ No newline at end of file diff --git a/examples/light-switch-app/efr32/README.md b/examples/light-switch-app/efr32/README.md index 5ac8b468fe23f4..b24401112e60c0 100644 --- a/examples/light-switch-app/efr32/README.md +++ b/examples/light-switch-app/efr32/README.md @@ -259,18 +259,21 @@ combination with JLinkRTTClient as follows: **Matter shell** - - 'switch on' : Sends On command to bound device + **_OnOff Cluster_** - - 'switch off' : Sends Off command to bound device + - 'switch onoff on' : Sends unicast On command to bound device + - 'switch onoff off' : Sends unicast Off command to bound device + - 'switch onoff toggle' : Sends unicast Toggle command to bound device - - 'switch toggle : Sends Toggle command to bound device + - 'switch groups onoff on' : Sends On group command to bound group + - 'switch groups onoff off' : Sends On group command to bound group + - 'switch groups onoff toggle' : Sends On group command to bound group * You can provision and control the Chip device using the python controller, - Chip tool standalone, Android or iOS app - [CHIPTool](https://github.com/project-chip/connectedhomeip/blob/master/examples/chip-tool/README.md) + standalone, Android or iOS app - Here is an example with the CHIPTool: + Here is an example with the CHIPTool for unicast commands only: ``` chip-tool pairing ble-thread 1 hex: 20202021 3840 @@ -280,6 +283,25 @@ combination with JLinkRTTClient as follows: chip-tool binding write binding '[{"fabricIndex": 1, "node": , "endpoint": 1, "cluster":6}]' 1 1 ``` + Here is an example with the CHIPTool for groups commands only: + + ``` + chip-tool pairing ble-thread 1 hex: 20202021 3840 + + chip-tool tests TestGroupDemoConfig --nodeId 1 + + chip-tool tests TestGroupDemoConfig --nodeId + + chip-tool binding write binding '[{"fabricIndex": 1, "group": 257}]' 1 1 + ``` + + To run the example with unicast and groups commands, run the group + configuration commands and replace the last one with binding this command + + ``` + chip-tool binding write binding '[{"fabricIndex": 1, "group": 257},{"fabricIndex": 1, "node": , "endpoint": 1, "cluster":6} ]' 1 1 + ``` + ### Notes - Depending on your network settings your router might not provide native ipv6 diff --git a/examples/light-switch-app/efr32/include/binding-handler.h b/examples/light-switch-app/efr32/include/binding-handler.h index 770cebb3cbe76b..367b8962771b46 100644 --- a/examples/light-switch-app/efr32/include/binding-handler.h +++ b/examples/light-switch-app/efr32/include/binding-handler.h @@ -21,12 +21,12 @@ #include "lib/core/CHIPError.h" CHIP_ERROR InitBindingHandler(); -void SwitchToggleOnOff(intptr_t context); -void SwitchOnOffOn(intptr_t context); -void SwitchOnOffOff(intptr_t context); +void SwitchWorkerFunction(intptr_t context); struct BindingCommandData { + chip::EndpointId localEndpointId = 1; chip::CommandId commandId; chip::ClusterId clusterId; + bool isGroup = false; }; diff --git a/examples/light-switch-app/efr32/src/AppTask.cpp b/examples/light-switch-app/efr32/src/AppTask.cpp index c8bdd19efcefc3..abc097b801f3ea 100644 --- a/examples/light-switch-app/efr32/src/AppTask.cpp +++ b/examples/light-switch-app/efr32/src/AppTask.cpp @@ -347,7 +347,11 @@ void AppTask::SwitchActionEventHandler(AppEvent * aEvent) { if (aEvent->Type == AppEvent::kEventType_Button) { - chip::DeviceLayer::PlatformMgr().ScheduleWork(SwitchToggleOnOff, 0); + BindingCommandData * data = Platform::New(); + data->commandId = chip::app::Clusters::OnOff::Commands::Toggle::Id; + data->clusterId = chip::app::Clusters::OnOff::Id; + + DeviceLayer::PlatformMgr().ScheduleWork(SwitchWorkerFunction, reinterpret_cast(data)); } } diff --git a/examples/light-switch-app/efr32/src/binding-handler.cpp b/examples/light-switch-app/efr32/src/binding-handler.cpp index 8373c7c0b1ef36..24fc87e5b9a7fa 100644 --- a/examples/light-switch-app/efr32/src/binding-handler.cpp +++ b/examples/light-switch-app/efr32/src/binding-handler.cpp @@ -23,9 +23,11 @@ #include "app/server/Server.h" #include "controller/InvokeInteraction.h" #include "platform/CHIPDeviceLayer.h" +#include #if defined(ENABLE_CHIP_SHELL) #include "lib/shell/Engine.h" +#include "lib/shell/commands/Help.h" #endif // ENABLE_CHIP_SHELL using namespace chip; @@ -36,11 +38,17 @@ using Shell::Engine; using Shell::shell_command_t; using Shell::streamer_get; using Shell::streamer_printf; + +Engine sShellSwitchSubCommands; +Engine sShellSwitchOnOffSubCommands; +Engine sShellSwitchGroupsSubCommands; + +Engine sShellSwitchGroupsOnOffSubCommands; #endif // defined(ENABLE_CHIP_SHELL) namespace { -void ProcessOnOffBindingCommand(CommandId commandId, const EmberBindingTableEntry & binding, DeviceProxy * peer_device) +void ProcessOnOffUnicastBindingCommand(CommandId commandId, const EmberBindingTableEntry & binding, DeviceProxy * peer_device) { auto onSuccess = [](const ConcreteCommandPath & commandPath, const StatusIB & status, const auto & dataResponse) { ChipLogProgress(NotSpecified, "OnOff command succeeds"); @@ -69,68 +77,244 @@ void ProcessOnOffBindingCommand(CommandId commandId, const EmberBindingTableEntr Controller::InvokeCommandRequest(peer_device->GetExchangeManager(), peer_device->GetSecureSession().Value(), binding.remote, offCommand, onSuccess, onFailure); break; + } +} + +void ProcessOnOffGroupBindingCommand(CommandId commandId, const EmberBindingTableEntry & binding) +{ + NodeId sourceNodeId = Server::GetInstance().GetFabricTable().FindFabricWithIndex(binding.fabricIndex)->GetNodeId(); + Messaging::ExchangeManager & exchangeMgr = Server::GetInstance().GetExchangeManager(); + + switch (commandId) + { + case Clusters::OnOff::Commands::Toggle::Id: + Clusters::OnOff::Commands::Toggle::Type toggleCommand; + Controller::InvokeGroupCommandRequest(&exchangeMgr, binding.fabricIndex, binding.groupId, sourceNodeId, toggleCommand); + break; + + case Clusters::OnOff::Commands::On::Id: + Clusters::OnOff::Commands::On::Type onCommand; + Controller::InvokeGroupCommandRequest(&exchangeMgr, binding.fabricIndex, binding.groupId, sourceNodeId, onCommand); - default: - ChipLogError(NotSpecified, "Invalid binding command data - commandId is not supported"); + break; + + case Clusters::OnOff::Commands::Off::Id: + Clusters::OnOff::Commands::Off::Type offCommand; + Controller::InvokeGroupCommandRequest(&exchangeMgr, binding.fabricIndex, binding.groupId, sourceNodeId, offCommand); break; } } void LightSwitchChangedHandler(const EmberBindingTableEntry & binding, DeviceProxy * peer_device, void * context) { - VerifyOrReturn(context != nullptr, ChipLogError(NotSpecified, "Invalid context for Light switch handler");); + VerifyOrReturn(context != nullptr, ChipLogError(NotSpecified, "OnDeviceConnectedFn: context is null")); BindingCommandData * data = static_cast(context); - if (binding.type == EMBER_MULTICAST_BINDING) + if (binding.type == EMBER_MULTICAST_BINDING && data->isGroup) { - ChipLogError(NotSpecified, "Group binding is not supported now"); + switch (data->clusterId) + { + case Clusters::OnOff::Id: + ProcessOnOffGroupBindingCommand(data->commandId, binding); + break; + } } - else if (binding.type == EMBER_UNICAST_BINDING && binding.local == 1 && - (!binding.clusterId.HasValue() || binding.clusterId.Value() == data->clusterId)) + else if (binding.type == EMBER_UNICAST_BINDING && !data->isGroup) { - switch (data->clusterId) { case Clusters::OnOff::Id: - ProcessOnOffBindingCommand(data->commandId, binding, peer_device); - break; - default: - ChipLogError(NotSpecified, "Invalid binding command data - clusterId is not supported"); + ProcessOnOffUnicastBindingCommand(data->commandId, binding, peer_device); break; } } - - Platform::Delete(data); } #ifdef ENABLE_CHIP_SHELL + +/******************************************************** + * Switch shell functions + *********************************************************/ + +CHIP_ERROR SwitchHelpHandler(int argc, char ** argv) +{ + sShellSwitchSubCommands.ForEachCommand(Shell::PrintCommandHelp, nullptr); + return CHIP_NO_ERROR; +} + CHIP_ERROR SwitchCommandHandler(int argc, char ** argv) { - if (argc == 1 && strcmp(argv[0], "on") == 0) + if (argc == 0) { - DeviceLayer::PlatformMgr().ScheduleWork(SwitchOnOffOn, 0); + return SwitchHelpHandler(argc, argv); } - else if (argc == 1 && strcmp(argv[0], "off") == 0) + + return sShellSwitchSubCommands.ExecCommand(argc, argv); +} + +/******************************************************** + * OnOff switch shell functions + *********************************************************/ + +CHIP_ERROR OnOffHelpHandler(int argc, char ** argv) +{ + sShellSwitchOnOffSubCommands.ForEachCommand(Shell::PrintCommandHelp, nullptr); + return CHIP_NO_ERROR; +} + +CHIP_ERROR OnOffSwitchCommandHandler(int argc, char ** argv) +{ + if (argc == 0) { - DeviceLayer::PlatformMgr().ScheduleWork(SwitchOnOffOff, 0); + return OnOffHelpHandler(argc, argv); } - else if (argc == 1 && strcmp(argv[0], "toggle") == 0) + + return sShellSwitchOnOffSubCommands.ExecCommand(argc, argv); +} + +CHIP_ERROR OnSwitchCommandHandler(int argc, char ** argv) +{ + BindingCommandData * data = Platform::New(); + data->commandId = Clusters::OnOff::Commands::On::Id; + data->clusterId = Clusters::OnOff::Id; + + DeviceLayer::PlatformMgr().ScheduleWork(SwitchWorkerFunction, reinterpret_cast(data)); + return CHIP_NO_ERROR; +} + +CHIP_ERROR OffSwitchCommandHandler(int argc, char ** argv) +{ + BindingCommandData * data = Platform::New(); + data->commandId = Clusters::OnOff::Commands::Off::Id; + data->clusterId = Clusters::OnOff::Id; + + DeviceLayer::PlatformMgr().ScheduleWork(SwitchWorkerFunction, reinterpret_cast(data)); + return CHIP_NO_ERROR; +} + +CHIP_ERROR ToggleSwitchCommandHandler(int argc, char ** argv) +{ + BindingCommandData * data = Platform::New(); + data->commandId = Clusters::OnOff::Commands::Toggle::Id; + data->clusterId = Clusters::OnOff::Id; + + DeviceLayer::PlatformMgr().ScheduleWork(SwitchWorkerFunction, reinterpret_cast(data)); + return CHIP_NO_ERROR; +} + +/******************************************************** + * Groups switch shell functions + *********************************************************/ + +CHIP_ERROR GroupsHelpHandler(int argc, char ** argv) +{ + sShellSwitchGroupsSubCommands.ForEachCommand(Shell::PrintCommandHelp, nullptr); + return CHIP_NO_ERROR; +} + +CHIP_ERROR GroupsSwitchCommandHandler(int argc, char ** argv) +{ + if (argc == 0) { - DeviceLayer::PlatformMgr().ScheduleWork(SwitchToggleOnOff, 0); + return GroupsHelpHandler(argc, argv); } - else + + return sShellSwitchGroupsSubCommands.ExecCommand(argc, argv); +} + +/******************************************************** + * Groups OnOff switch shell functions + *********************************************************/ + +CHIP_ERROR GroupsOnOffHelpHandler(int argc, char ** argv) +{ + sShellSwitchGroupsOnOffSubCommands.ForEachCommand(Shell::PrintCommandHelp, nullptr); + return CHIP_NO_ERROR; +} + +CHIP_ERROR GroupsOnOffSwitchCommandHandler(int argc, char ** argv) +{ + if (argc == 0) { - streamer_printf(streamer_get(), "Usage: switch [on|off|toggle]"); + return GroupsOnOffHelpHandler(argc, argv); } + + return sShellSwitchGroupsOnOffSubCommands.ExecCommand(argc, argv); +} + +CHIP_ERROR GroupOnSwitchCommandHandler(int argc, char ** argv) +{ + BindingCommandData * data = Platform::New(); + data->commandId = Clusters::OnOff::Commands::On::Id; + data->clusterId = Clusters::OnOff::Id; + data->isGroup = true; + + DeviceLayer::PlatformMgr().ScheduleWork(SwitchWorkerFunction, reinterpret_cast(data)); return CHIP_NO_ERROR; } +CHIP_ERROR GroupOffSwitchCommandHandler(int argc, char ** argv) +{ + BindingCommandData * data = Platform::New(); + data->commandId = Clusters::OnOff::Commands::Off::Id; + data->clusterId = Clusters::OnOff::Id; + data->isGroup = true; + + DeviceLayer::PlatformMgr().ScheduleWork(SwitchWorkerFunction, reinterpret_cast(data)); + return CHIP_NO_ERROR; +} + +CHIP_ERROR GroupToggleSwitchCommandHandler(int argc, char ** argv) +{ + BindingCommandData * data = Platform::New(); + data->commandId = Clusters::OnOff::Commands::Toggle::Id; + data->clusterId = Clusters::OnOff::Id; + data->isGroup = true; + + DeviceLayer::PlatformMgr().ScheduleWork(SwitchWorkerFunction, reinterpret_cast(data)); + return CHIP_NO_ERROR; +} + +/** + * @brief configures switch matter shell + * + */ static void RegisterSwitchCommands() { - static const shell_command_t sSwitchCommand = { SwitchCommandHandler, "switch", - "Switch commands. Usage: switch [on|off|toggle]" }; + static const shell_command_t sSwitchSubCommands[] = { + { &SwitchHelpHandler, "help", "Usage: switch " }, + { &OnOffSwitchCommandHandler, "onoff", " Usage: switch onoff " }, + { &GroupsSwitchCommandHandler, "groups", "Usage: switch groups " }, + + }; + + static const shell_command_t sSwitchOnOffSubCommands[] = { + { &OnOffHelpHandler, "help", "Usage : switch ononff " }, + { &OnSwitchCommandHandler, "on", "Sends on command to bound lighting app" }, + { &OffSwitchCommandHandler, "off", "Sends off command to bound lighting app" }, + { &ToggleSwitchCommandHandler, "toggle", "Sends toggle command to bound lighting app" } + }; + + static const shell_command_t sSwitchGroupsSubCommands[] = { { &GroupsHelpHandler, "help", "Usage: switch groups " }, + { &GroupsOnOffSwitchCommandHandler, "onoff", + "Usage: switch groups onoff " } }; + + static const shell_command_t sSwichGroupsOnOffSubCommands[] = { + { &GroupsOnOffHelpHandler, "help", "Usage: switch groups onoff " }, + { &GroupOnSwitchCommandHandler, "on", "Sends on command to bound group" }, + { &GroupOffSwitchCommandHandler, "off", "Sends off command to bound group" }, + { &GroupToggleSwitchCommandHandler, "toggle", "Sends toggle command to group" } + }; + + static const shell_command_t sSwitchCommand = { &SwitchCommandHandler, "switch", + "Light-switch commands. Usage: switch " }; + + sShellSwitchGroupsOnOffSubCommands.RegisterCommands(sSwichGroupsOnOffSubCommands, ArraySize(sSwichGroupsOnOffSubCommands)); + sShellSwitchOnOffSubCommands.RegisterCommands(sSwitchOnOffSubCommands, ArraySize(sSwitchOnOffSubCommands)); + sShellSwitchGroupsSubCommands.RegisterCommands(sSwitchGroupsSubCommands, ArraySize(sSwitchGroupsSubCommands)); + sShellSwitchSubCommands.RegisterCommands(sSwitchSubCommands, ArraySize(sSwitchSubCommands)); + Engine::Root().RegisterCommands(&sSwitchCommand, 1); - return; } #endif // ENABLE_CHIP_SHELL @@ -144,37 +328,18 @@ void InitBindingHandlerInternal(intptr_t arg) } // namespace -void SwitchToggleOnOff(intptr_t context) -{ - BindingCommandData * data = Platform::New(); - VerifyOrReturn(data != nullptr, ChipLogError(NotSpecified, "SwitchToggleOnOff - Out of Memory of work data")); - - data->clusterId = Clusters::OnOff::Id; - data->commandId = Clusters::OnOff::Commands::Toggle::Id; - - BindingManager::GetInstance().NotifyBoundClusterChanged(1 /* endpointId */, Clusters::OnOff::Id, static_cast(data)); -} +/******************************************************** + * Switch functions + *********************************************************/ -void SwitchOnOffOn(intptr_t context) +void SwitchWorkerFunction(intptr_t context) { - BindingCommandData * data = Platform::New(); - VerifyOrReturn(data != nullptr, ChipLogError(NotSpecified, "SwitchOnOffOn - Out of Memory of work data")); + VerifyOrReturn(context != 0, ChipLogError(NotSpecified, "SwitchWorkerFunction - Invalid work data")); - data->clusterId = Clusters::OnOff::Id; - data->commandId = Clusters::OnOff::Commands::On::Id; + BindingCommandData * data = reinterpret_cast(context); + BindingManager::GetInstance().NotifyBoundClusterChanged(data->localEndpointId, data->clusterId, static_cast(data)); - BindingManager::GetInstance().NotifyBoundClusterChanged(1 /* endpointId */, Clusters::OnOff::Id, static_cast(data)); -} - -void SwitchOnOffOff(intptr_t context) -{ - BindingCommandData * data = Platform::New(); - VerifyOrReturn(data != nullptr, ChipLogError(NotSpecified, "SwitchOnOffOff - Out of Memory of work data")); - - data->clusterId = Clusters::OnOff::Id; - data->commandId = Clusters::OnOff::Commands::Off::Id; - - BindingManager::GetInstance().NotifyBoundClusterChanged(1 /* endpointId */, Clusters::OnOff::Id, static_cast(data)); + Platform::Delete(data); } CHIP_ERROR InitBindingHandler() diff --git a/examples/light-switch-app/light-switch-common/light-switch-app.matter b/examples/light-switch-app/light-switch-common/light-switch-app.matter index f1259f8201f49f..6a3bb56e8b50f4 100644 --- a/examples/light-switch-app/light-switch-common/light-switch-app.matter +++ b/examples/light-switch-app/light-switch-common/light-switch-app.matter @@ -609,9 +609,74 @@ server cluster GeneralDiagnostics = 51 { readonly global attribute int16u clusterRevision = 65533; } -client cluster Groups = 4 { +server cluster GroupKeyManagement = 63 { + enum GroupKeySecurityPolicy : ENUM8 { + kTrustFirst = 0; + kCacheAndSync = 1; + } + + struct GroupKeyMapStruct { + fabric_idx fabricIndex = 0; + group_id groupId = 1; + INT16U groupKeySetID = 2; + } + + struct GroupInfoMapStruct { + fabric_idx fabricIndex = 0; + group_id groupId = 1; + endpoint_no endpoints[] = 2; + optional CHAR_STRING<16> groupName = 3; + } + + struct GroupKeySetStruct { + INT16U groupKeySetID = 0; + GroupKeySecurityPolicy 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 GroupKeyMapStruct groupKeyMap[] = 0; + readonly attribute GroupInfoMapStruct groupTable[] = 1; + readonly attribute int16u maxGroupsPerFabric = 2; + readonly attribute int16u maxGroupKeysPerFabric = 3; + readonly global attribute int16u clusterRevision = 65533; + + request struct KeySetReadRequest { + INT16U groupKeySetID = 0; + } + + request struct KeySetReadAllIndicesRequest { + INT16U groupKeySetIDs[] = 0; + } + + request struct KeySetRemoveRequest { + INT16U groupKeySetID = 0; + } + + request struct KeySetWriteRequest { + GroupKeySetStruct groupKeySet = 0; + } + + response struct KeySetReadAllIndicesResponse { + INT16U groupKeySetIDs[] = 0; + } + + response struct KeySetReadResponse { + GroupKeySetStruct groupKeySet = 0; + } + + command KeySetRead(KeySetReadRequest): KeySetReadResponse = 1; + command KeySetReadAllIndices(KeySetReadAllIndicesRequest): KeySetReadAllIndicesResponse = 4; + command KeySetRemove(KeySetRemoveRequest): DefaultSuccess = 3; + command KeySetWrite(KeySetWriteRequest): DefaultSuccess = 0; +} + +server cluster Groups = 4 { readonly attribute bitmap8 nameSupport = 0; - readonly global attribute attrib_id attributeList[] = 65531; readonly global attribute int16u clusterRevision = 65533; request struct AddGroupRequest { @@ -636,6 +701,27 @@ client cluster Groups = 4 { group_id groupId = 0; } + response struct AddGroupResponse { + ENUM8 status = 0; + group_id groupId = 1; + } + + response struct GetGroupMembershipResponse { + nullable INT8U capacity = 0; + group_id groupList[] = 1; + } + + response struct RemoveGroupResponse { + ENUM8 status = 0; + group_id groupId = 1; + } + + response struct ViewGroupResponse { + ENUM8 status = 0; + group_id groupId = 1; + CHAR_STRING groupName = 2; + } + command AddGroup(AddGroupRequest): AddGroupResponse = 0; command AddGroupIfIdentifying(AddGroupIfIdentifyingRequest): DefaultSuccess = 5; command GetGroupMembership(GetGroupMembershipRequest): GetGroupMembershipResponse = 2; @@ -1444,6 +1530,33 @@ server cluster ThreadNetworkDiagnostics = 53 { command ResetCounts(): DefaultSuccess = 0; } +server cluster TimeFormatLocalization = 44 { + enum CalendarType : ENUM8 { + kBuddhist = 0; + kChinese = 1; + kCoptic = 2; + kEthiopian = 3; + kGregorian = 4; + kHebrew = 5; + kIndian = 6; + kIslamic = 7; + kJapanese = 8; + kKorean = 9; + kPersian = 10; + kTaiwanese = 11; + } + + enum HourFormat : ENUM8 { + k12hr = 0; + k24hr = 1; + } + + attribute HourFormat hourFormat = 0; + attribute CalendarType activeCalendarType = 1; + readonly attribute CalendarType supportedCalendarTypes[] = 2; + readonly global attribute int16u clusterRevision = 65533; +} + server cluster UserLabel = 65 { attribute LabelStruct labelList[] = 0; readonly global attribute int16u clusterRevision = 65533; @@ -1524,6 +1637,7 @@ endpoint 0 { server cluster FixedLabel; server cluster GeneralCommissioning; server cluster GeneralDiagnostics; + server cluster GroupKeyManagement; server cluster LocalizationConfiguration; server cluster NetworkCommissioning; binding cluster OtaSoftwareUpdateProvider; @@ -1532,6 +1646,7 @@ endpoint 0 { server cluster SoftwareDiagnostics; server cluster Switch; server cluster ThreadNetworkDiagnostics; + server cluster TimeFormatLocalization; server cluster UserLabel; server cluster WiFiNetworkDiagnostics; } @@ -1540,7 +1655,7 @@ endpoint 1 { server cluster Binding; binding cluster ColorControl; server cluster Descriptor; - binding cluster Groups; + server cluster Groups; binding cluster Identify; server cluster Identify; binding cluster OnOff; diff --git a/examples/light-switch-app/light-switch-common/light-switch-app.zap b/examples/light-switch-app/light-switch-common/light-switch-app.zap index 7566fd5b3bb5d9..3282bec8ae4d90 100644 --- a/examples/light-switch-app/light-switch-common/light-switch-app.zap +++ b/examples/light-switch-app/light-switch-common/light-switch-app.zap @@ -1769,6 +1769,87 @@ } ] }, + { + "name": "Time Format Localization", + "code": 44, + "mfgCode": null, + "define": "TIME_FORMAT_LOCALIZATION_CLUSTER", + "side": "client", + "enabled": 0, + "commands": [], + "attributes": [] + }, + { + "name": "Time Format Localization", + "code": 44, + "mfgCode": null, + "define": "TIME_FORMAT_LOCALIZATION_CLUSTER", + "side": "server", + "enabled": 1, + "commands": [], + "attributes": [ + { + "name": "HourFormat", + "code": 0, + "mfgCode": null, + "side": "server", + "included": 1, + "storageOption": "NVM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ActiveCalendarType", + "code": 1, + "mfgCode": null, + "side": "server", + "included": 1, + "storageOption": "NVM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "SupportedCalendarTypes", + "code": 2, + "mfgCode": null, + "side": "server", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + } + ] + }, { "name": "General Commissioning", "code": 48, @@ -4427,6 +4508,152 @@ } ] }, + { + "name": "Group Key Management", + "code": 63, + "mfgCode": null, + "define": "GROUP_KEY_MANAGEMENT_CLUSTER", + "side": "client", + "enabled": 0, + "commands": [ + { + "name": "KeySetWrite", + "code": 0, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 0 + }, + { + "name": "KeySetRead", + "code": 1, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 0 + }, + { + "name": "KeySetRemove", + "code": 3, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 0 + }, + { + "name": "KeySetReadAllIndices", + "code": 4, + "mfgCode": null, + "source": "client", + "incoming": 1, + "outgoing": 0 + } + ], + "attributes": [] + }, + { + "name": "Group Key Management", + "code": 63, + "mfgCode": null, + "define": "GROUP_KEY_MANAGEMENT_CLUSTER", + "side": "server", + "enabled": 1, + "commands": [ + { + "name": "KeySetReadResponse", + "code": 2, + "mfgCode": null, + "source": "server", + "incoming": 0, + "outgoing": 1 + }, + { + "name": "KeySetReadAllIndicesResponse", + "code": 5, + "mfgCode": null, + "source": "server", + "incoming": 0, + "outgoing": 1 + } + ], + "attributes": [ + { + "name": "GroupKeyMap", + "code": 0, + "mfgCode": null, + "side": "server", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "GroupTable", + "code": 1, + "mfgCode": null, + "side": "server", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "MaxGroupsPerFabric", + "code": 2, + "mfgCode": null, + "side": "server", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "MaxGroupKeysPerFabric", + "code": 3, + "mfgCode": null, + "side": "server", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + } + ] + }, { "name": "Fixed Label", "code": 64, @@ -4704,7 +4931,7 @@ "mfgCode": null, "define": "GROUPS_CLUSTER", "side": "client", - "enabled": 1, + "enabled": 0, "commands": [ { "name": "AddGroup", @@ -4794,7 +5021,7 @@ "mfgCode": null, "define": "GROUPS_CLUSTER", "side": "server", - "enabled": 0, + "enabled": 1, "commands": [ { "name": "AddGroupResponse", @@ -4845,12 +5072,42 @@ "maxInterval": 65344, "reportableChange": 0 }, + { + "name": "ServerGeneratedCommandList", + "code": 65528, + "mfgCode": null, + "side": "server", + "included": 0, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClientGeneratedCommandList", + "code": 65529, + "mfgCode": null, + "side": "server", + "included": 0, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, { "name": "AttributeList", "code": 65531, "mfgCode": null, "side": "server", - "included": 1, + "included": 0, "storageOption": "External", "singleton": 0, "bounded": 0, @@ -5936,8 +6193,7 @@ "define": "BINDING_CLUSTER", "side": "client", "enabled": 0, - "commands": [ - ], + "commands": [], "attributes": [ { "name": "FeatureMap", diff --git a/src/app/CommandPathParams.h b/src/app/CommandPathParams.h index 0f432a804b1af3..27a2c1fdd10877 100644 --- a/src/app/CommandPathParams.h +++ b/src/app/CommandPathParams.h @@ -37,6 +37,20 @@ struct CommandPathParams mEndpointId(aEndpointId), mGroupId(aGroupId), mClusterId(aClusterId), mCommandId(aCommandId), mFlags(aFlags) {} + + CommandPathParams(uint16_t aId, ClusterId aClusterId, CommandId aCommandId, const BitFlags & aFlags) : + mClusterId(aClusterId), mCommandId(aCommandId), mFlags(aFlags) + { + if (aFlags == CommandPathFlags::kEndpointIdValid) + { + mEndpointId = aId; + } + else if (aFlags == CommandPathFlags::kGroupIdValid) + { + mGroupId = aId; + } + } + bool IsSamePath(const CommandPathParams & other) const { if (other.mClusterId != mClusterId || other.mCommandId != mCommandId) diff --git a/src/app/CommandSender.h b/src/app/CommandSender.h index 3b103f4c70c5d9..53edd9f3294ba0 100644 --- a/src/app/CommandSender.h +++ b/src/app/CommandSender.h @@ -135,6 +135,8 @@ class CommandSender final : public Messaging::ExchangeDelegate * Constructor. * * The callback passed in has to outlive this CommandSender object. + * If used in a groups setting, callbacks do not need to be passed. + * If callbacks are passed the only one that will be called in a group sesttings is the onDone */ CommandSender(Callback * apCallback, Messaging::ExchangeManager * apExchangeMgr, bool aIsTimedRequest = false); CHIP_ERROR PrepareCommand(const CommandPathParams & aCommandPathParams, bool aStartDataStruct = true); diff --git a/src/controller/InvokeInteraction.h b/src/controller/InvokeInteraction.h index 925ff17d75e4ee..8a7fc449afe295 100644 --- a/src/controller/InvokeInteraction.h +++ b/src/controller/InvokeInteraction.h @@ -90,6 +90,40 @@ InvokeCommandRequest(Messaging::ExchangeManager * aExchangeMgr, const SessionHan return CHIP_NO_ERROR; } +/* + * A typed group command invocation function that takes as input a cluster-object representation of a command request and + * callbacks when completed trought the done callback + * + * The RequestObjectT is generally expected to be a ClusterName::Commands::CommandName::Type struct, but any object + * that can be encoded using the DataModel::Encode machinery and exposes the GetClusterId() and GetCommandId() functions + * and a ResponseType type is expected to work. + * + * Since this sends a group command, no response will be received and all allocated rescources will be cleared before exing this + * function + */ +template +CHIP_ERROR InvokeGroupCommandRequest(Messaging::ExchangeManager * exchangeMgr, chip::FabricIndex fabric, chip::GroupId groupId, + chip::NodeId sourceNodeId, const RequestObjectT & requestCommandData) +{ + CHIP_ERROR error = CHIP_NO_ERROR; + app::CommandPathParams commandPath = { groupId, RequestObjectT::GetClusterId(), RequestObjectT::GetCommandId(), + app::CommandPathFlags::kGroupIdValid }; + Transport::OutgoingGroupSession session(groupId, fabric, sourceNodeId); + + auto commandSender = chip::Platform::MakeUnique(nullptr, exchangeMgr); + VerifyOrReturnError(commandSender != nullptr, CHIP_ERROR_NO_MEMORY); + + error = commandSender->AddRequestData(commandPath, requestCommandData); + SuccessOrExit(error); + + error = commandSender->SendGroupCommandRequest(SessionHandle(session)); + SuccessOrExit(error); + +exit: + chip::Platform::Delete(commandSender.release()); + return error; +} + template CHIP_ERROR InvokeCommandRequest(Messaging::ExchangeManager * exchangeMgr, const SessionHandle & sessionHandle, chip::EndpointId endpointId, diff --git a/zzz_generated/light-switch-app/zap-generated/CHIPClientCallbacks.h b/zzz_generated/light-switch-app/zap-generated/CHIPClientCallbacks.h index 4cb15e66e7f865..d3a44b3873d3c8 100644 --- a/zzz_generated/light-switch-app/zap-generated/CHIPClientCallbacks.h +++ b/zzz_generated/light-switch-app/zap-generated/CHIPClientCallbacks.h @@ -31,10 +31,6 @@ #include // List specific responses -void GroupsClusterAttributeListListAttributeFilter(chip::TLV::TLVReader * data, chip::Callback::Cancelable * onSuccessCallback, - chip::Callback::Cancelable * onFailureCallback); -typedef void (*GroupsAttributeListListAttributeCallback)(void * context, - const chip::app::DataModel::DecodableList & data); void IdentifyClusterAttributeListListAttributeFilter(chip::TLV::TLVReader * data, chip::Callback::Cancelable * onSuccessCallback, chip::Callback::Cancelable * onFailureCallback); typedef void (*IdentifyAttributeListListAttributeCallback)(void * context, diff --git a/zzz_generated/light-switch-app/zap-generated/CHIPClusters.h b/zzz_generated/light-switch-app/zap-generated/CHIPClusters.h index 018ec5bc99f238..8a09c364a219a2 100644 --- a/zzz_generated/light-switch-app/zap-generated/CHIPClusters.h +++ b/zzz_generated/light-switch-app/zap-generated/CHIPClusters.h @@ -37,13 +37,6 @@ class DLL_EXPORT ColorControlCluster : public ClusterBase ~ColorControlCluster() {} }; -class DLL_EXPORT GroupsCluster : public ClusterBase -{ -public: - GroupsCluster() : ClusterBase(app::Clusters::Groups::Id) {} - ~GroupsCluster() {} -}; - class DLL_EXPORT IdentifyCluster : public ClusterBase { public: diff --git a/zzz_generated/light-switch-app/zap-generated/IMClusterCommandHandler.cpp b/zzz_generated/light-switch-app/zap-generated/IMClusterCommandHandler.cpp index daf9ad6e9d5aad..b7c7ad946b2028 100644 --- a/zzz_generated/light-switch-app/zap-generated/IMClusterCommandHandler.cpp +++ b/zzz_generated/light-switch-app/zap-generated/IMClusterCommandHandler.cpp @@ -229,6 +229,152 @@ void DispatchServerCommand(CommandHandler * apCommandObj, const ConcreteCommandP } // namespace GeneralCommissioning +namespace GroupKeyManagement { + +void DispatchServerCommand(CommandHandler * apCommandObj, const ConcreteCommandPath & aCommandPath, TLV::TLVReader & aDataTlv) +{ + CHIP_ERROR TLVError = CHIP_NO_ERROR; + bool wasHandled = false; + { + switch (aCommandPath.mCommandId) + { + case Commands::KeySetRead::Id: { + Commands::KeySetRead::DecodableType commandData; + TLVError = DataModel::Decode(aDataTlv, commandData); + if (TLVError == CHIP_NO_ERROR) + { + wasHandled = emberAfGroupKeyManagementClusterKeySetReadCallback(apCommandObj, aCommandPath, commandData); + } + break; + } + case Commands::KeySetReadAllIndices::Id: { + Commands::KeySetReadAllIndices::DecodableType commandData; + TLVError = DataModel::Decode(aDataTlv, commandData); + if (TLVError == CHIP_NO_ERROR) + { + wasHandled = emberAfGroupKeyManagementClusterKeySetReadAllIndicesCallback(apCommandObj, aCommandPath, commandData); + } + break; + } + case Commands::KeySetRemove::Id: { + Commands::KeySetRemove::DecodableType commandData; + TLVError = DataModel::Decode(aDataTlv, commandData); + if (TLVError == CHIP_NO_ERROR) + { + wasHandled = emberAfGroupKeyManagementClusterKeySetRemoveCallback(apCommandObj, aCommandPath, commandData); + } + break; + } + case Commands::KeySetWrite::Id: { + Commands::KeySetWrite::DecodableType commandData; + TLVError = DataModel::Decode(aDataTlv, commandData); + if (TLVError == CHIP_NO_ERROR) + { + wasHandled = emberAfGroupKeyManagementClusterKeySetWriteCallback(apCommandObj, aCommandPath, commandData); + } + break; + } + default: { + // Unrecognized command ID, error status will apply. + apCommandObj->AddStatus(aCommandPath, Protocols::InteractionModel::Status::UnsupportedCommand); + ChipLogError(Zcl, "Unknown command " ChipLogFormatMEI " for cluster " ChipLogFormatMEI, + ChipLogValueMEI(aCommandPath.mCommandId), ChipLogValueMEI(aCommandPath.mClusterId)); + return; + } + } + } + + if (CHIP_NO_ERROR != TLVError || !wasHandled) + { + apCommandObj->AddStatus(aCommandPath, Protocols::InteractionModel::Status::InvalidCommand); + ChipLogProgress(Zcl, "Failed to dispatch command, TLVError=%" CHIP_ERROR_FORMAT, TLVError.Format()); + } +} + +} // namespace GroupKeyManagement + +namespace Groups { + +void DispatchServerCommand(CommandHandler * apCommandObj, const ConcreteCommandPath & aCommandPath, TLV::TLVReader & aDataTlv) +{ + CHIP_ERROR TLVError = CHIP_NO_ERROR; + bool wasHandled = false; + { + switch (aCommandPath.mCommandId) + { + case Commands::AddGroup::Id: { + Commands::AddGroup::DecodableType commandData; + TLVError = DataModel::Decode(aDataTlv, commandData); + if (TLVError == CHIP_NO_ERROR) + { + wasHandled = emberAfGroupsClusterAddGroupCallback(apCommandObj, aCommandPath, commandData); + } + break; + } + case Commands::AddGroupIfIdentifying::Id: { + Commands::AddGroupIfIdentifying::DecodableType commandData; + TLVError = DataModel::Decode(aDataTlv, commandData); + if (TLVError == CHIP_NO_ERROR) + { + wasHandled = emberAfGroupsClusterAddGroupIfIdentifyingCallback(apCommandObj, aCommandPath, commandData); + } + break; + } + case Commands::GetGroupMembership::Id: { + Commands::GetGroupMembership::DecodableType commandData; + TLVError = DataModel::Decode(aDataTlv, commandData); + if (TLVError == CHIP_NO_ERROR) + { + wasHandled = emberAfGroupsClusterGetGroupMembershipCallback(apCommandObj, aCommandPath, commandData); + } + break; + } + case Commands::RemoveAllGroups::Id: { + Commands::RemoveAllGroups::DecodableType commandData; + TLVError = DataModel::Decode(aDataTlv, commandData); + if (TLVError == CHIP_NO_ERROR) + { + wasHandled = emberAfGroupsClusterRemoveAllGroupsCallback(apCommandObj, aCommandPath, commandData); + } + break; + } + case Commands::RemoveGroup::Id: { + Commands::RemoveGroup::DecodableType commandData; + TLVError = DataModel::Decode(aDataTlv, commandData); + if (TLVError == CHIP_NO_ERROR) + { + wasHandled = emberAfGroupsClusterRemoveGroupCallback(apCommandObj, aCommandPath, commandData); + } + break; + } + case Commands::ViewGroup::Id: { + Commands::ViewGroup::DecodableType commandData; + TLVError = DataModel::Decode(aDataTlv, commandData); + if (TLVError == CHIP_NO_ERROR) + { + wasHandled = emberAfGroupsClusterViewGroupCallback(apCommandObj, aCommandPath, commandData); + } + break; + } + default: { + // Unrecognized command ID, error status will apply. + apCommandObj->AddStatus(aCommandPath, Protocols::InteractionModel::Status::UnsupportedCommand); + ChipLogError(Zcl, "Unknown command " ChipLogFormatMEI " for cluster " ChipLogFormatMEI, + ChipLogValueMEI(aCommandPath.mCommandId), ChipLogValueMEI(aCommandPath.mClusterId)); + return; + } + } + } + + if (CHIP_NO_ERROR != TLVError || !wasHandled) + { + apCommandObj->AddStatus(aCommandPath, Protocols::InteractionModel::Status::InvalidCommand); + ChipLogProgress(Zcl, "Failed to dispatch command, TLVError=%" CHIP_ERROR_FORMAT, TLVError.Format()); + } +} + +} // namespace Groups + namespace Identify { void DispatchServerCommand(CommandHandler * apCommandObj, const ConcreteCommandPath & aCommandPath, TLV::TLVReader & aDataTlv) @@ -650,6 +796,12 @@ void DispatchSingleClusterCommand(const ConcreteCommandPath & aCommandPath, TLV: case Clusters::GeneralCommissioning::Id: Clusters::GeneralCommissioning::DispatchServerCommand(apCommandObj, aCommandPath, aReader); break; + case Clusters::GroupKeyManagement::Id: + Clusters::GroupKeyManagement::DispatchServerCommand(apCommandObj, aCommandPath, aReader); + break; + case Clusters::Groups::Id: + Clusters::Groups::DispatchServerCommand(apCommandObj, aCommandPath, aReader); + break; case Clusters::Identify::Id: Clusters::Identify::DispatchServerCommand(apCommandObj, aCommandPath, aReader); break; diff --git a/zzz_generated/light-switch-app/zap-generated/PluginApplicationCallbacks.h b/zzz_generated/light-switch-app/zap-generated/PluginApplicationCallbacks.h index db4dcba47418f4..b14580ae36305a 100644 --- a/zzz_generated/light-switch-app/zap-generated/PluginApplicationCallbacks.h +++ b/zzz_generated/light-switch-app/zap-generated/PluginApplicationCallbacks.h @@ -33,7 +33,8 @@ MatterFixedLabelPluginServerInitCallback(); \ MatterGeneralCommissioningPluginServerInitCallback(); \ MatterGeneralDiagnosticsPluginServerInitCallback(); \ - MatterGroupsPluginClientInitCallback(); \ + MatterGroupKeyManagementPluginServerInitCallback(); \ + MatterGroupsPluginServerInitCallback(); \ MatterIdentifyPluginClientInitCallback(); \ MatterIdentifyPluginServerInitCallback(); \ MatterLocalizationConfigurationPluginServerInitCallback(); \ @@ -46,5 +47,6 @@ MatterSoftwareDiagnosticsPluginServerInitCallback(); \ MatterSwitchPluginServerInitCallback(); \ MatterThreadNetworkDiagnosticsPluginServerInitCallback(); \ + MatterTimeFormatLocalizationPluginServerInitCallback(); \ MatterUserLabelPluginServerInitCallback(); \ MatterWiFiNetworkDiagnosticsPluginServerInitCallback(); diff --git a/zzz_generated/light-switch-app/zap-generated/callback-stub.cpp b/zzz_generated/light-switch-app/zap-generated/callback-stub.cpp index 9b14564287cd5d..38bbf64fb6e20b 100644 --- a/zzz_generated/light-switch-app/zap-generated/callback-stub.cpp +++ b/zzz_generated/light-switch-app/zap-generated/callback-stub.cpp @@ -62,6 +62,9 @@ void emberAfClusterInitCallback(EndpointId endpoint, ClusterId clusterId) case ZCL_GENERAL_DIAGNOSTICS_CLUSTER_ID: emberAfGeneralDiagnosticsClusterInitCallback(endpoint); break; + case ZCL_GROUP_KEY_MANAGEMENT_CLUSTER_ID: + emberAfGroupKeyManagementClusterInitCallback(endpoint); + break; case ZCL_GROUPS_CLUSTER_ID: emberAfGroupsClusterInitCallback(endpoint); break; @@ -98,6 +101,9 @@ void emberAfClusterInitCallback(EndpointId endpoint, ClusterId clusterId) case ZCL_THREAD_NETWORK_DIAGNOSTICS_CLUSTER_ID: emberAfThreadNetworkDiagnosticsClusterInitCallback(endpoint); break; + case ZCL_TIME_FORMAT_LOCALIZATION_CLUSTER_ID: + emberAfTimeFormatLocalizationClusterInitCallback(endpoint); + break; case ZCL_USER_LABEL_CLUSTER_ID: emberAfUserLabelClusterInitCallback(endpoint); break; @@ -165,6 +171,11 @@ void __attribute__((weak)) emberAfGeneralDiagnosticsClusterInitCallback(Endpoint // To prevent warning (void) endpoint; } +void __attribute__((weak)) emberAfGroupKeyManagementClusterInitCallback(EndpointId endpoint) +{ + // To prevent warning + (void) endpoint; +} void __attribute__((weak)) emberAfGroupsClusterInitCallback(EndpointId endpoint) { // To prevent warning @@ -225,6 +236,11 @@ void __attribute__((weak)) emberAfThreadNetworkDiagnosticsClusterInitCallback(En // To prevent warning (void) endpoint; } +void __attribute__((weak)) emberAfTimeFormatLocalizationClusterInitCallback(EndpointId endpoint) +{ + // To prevent warning + (void) endpoint; +} void __attribute__((weak)) emberAfUserLabelClusterInitCallback(EndpointId endpoint) { // To prevent warning diff --git a/zzz_generated/light-switch-app/zap-generated/endpoint_config.h b/zzz_generated/light-switch-app/zap-generated/endpoint_config.h index 673c493d8336e0..ceffc5a811407b 100644 --- a/zzz_generated/light-switch-app/zap-generated/endpoint_config.h +++ b/zzz_generated/light-switch-app/zap-generated/endpoint_config.h @@ -500,19 +500,19 @@ } // This is an array of EmberAfAttributeMinMaxValue structures. -#define GENERATED_MIN_MAX_DEFAULT_COUNT 1 +#define GENERATED_MIN_MAX_DEFAULT_COUNT 2 #define GENERATED_MIN_MAX_DEFAULTS \ { \ \ - /* Endpoint: 1, Cluster: Identify (server) */ \ - { \ - (uint16_t) 0x0, (uint16_t) 0x0, (uint16_t) 0xFE \ - } /* identify time */ \ + /* Endpoint: 0, Cluster: Time Format Localization (server) */ \ + { (uint16_t) 0x0, (uint16_t) 0x0, (uint16_t) 0x1 }, /* HourFormat */ \ + \ + /* Endpoint: 1, Cluster: Identify (server) */ { (uint16_t) 0x0, (uint16_t) 0x0, (uint16_t) 0xFE } /* identify time */ \ } #define ZAP_ATTRIBUTE_MASK(mask) ATTRIBUTE_MASK_##mask // This is an array of EmberAfAttributeMetadata structures. -#define GENERATED_ATTRIBUTE_COUNT 184 +#define GENERATED_ATTRIBUTE_COUNT 195 #define GENERATED_ATTRIBUTES \ { \ \ @@ -589,6 +589,16 @@ { 0x00000001, ZAP_TYPE(CHAR_STRING), 36, ZAP_ATTRIBUTE_MASK(WRITABLE), ZAP_EMPTY_DEFAULT() }, /* ActiveLocale */ \ { 0x00000002, ZAP_TYPE(ARRAY), 0, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE), ZAP_EMPTY_DEFAULT() }, /* SupportedLocales */ \ \ + /* Endpoint: 0, Cluster: Time Format Localization (server) */ \ + { 0x00000000, ZAP_TYPE(ENUM8), 1, \ + ZAP_ATTRIBUTE_MASK(MIN_MAX) | ZAP_ATTRIBUTE_MASK(TOKENIZE) | ZAP_ATTRIBUTE_MASK(WRITABLE), \ + ZAP_MIN_MAX_DEFAULTS_INDEX(0) }, /* HourFormat */ \ + { 0x00000001, ZAP_TYPE(ENUM8), 1, ZAP_ATTRIBUTE_MASK(TOKENIZE) | ZAP_ATTRIBUTE_MASK(WRITABLE), \ + ZAP_EMPTY_DEFAULT() }, /* ActiveCalendarType */ \ + { 0x00000002, ZAP_TYPE(ARRAY), 0, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE), \ + ZAP_EMPTY_DEFAULT() }, /* SupportedCalendarTypes */ \ + { 0x0000FFFD, ZAP_TYPE(INT16U), 2, 0, ZAP_SIMPLE_DEFAULT(1) }, /* ClusterRevision */ \ + \ /* Endpoint: 0, Cluster: General Commissioning (server) */ \ { 0x00000000, ZAP_TYPE(INT64U), 8, ZAP_ATTRIBUTE_MASK(WRITABLE), ZAP_LONG_DEFAULTS_INDEX(0) }, /* Breadcrumb */ \ { 0x00000001, ZAP_TYPE(STRUCT), 0, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE), \ @@ -749,6 +759,16 @@ ZAP_EMPTY_DEFAULT() }, /* CurrentFabricIndex */ \ { 0x0000FFFD, ZAP_TYPE(INT16U), 2, 0, ZAP_SIMPLE_DEFAULT(0x0001) }, /* ClusterRevision */ \ \ + /* Endpoint: 0, Cluster: Group Key Management (server) */ \ + { 0x00000000, ZAP_TYPE(ARRAY), 0, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE) | ZAP_ATTRIBUTE_MASK(WRITABLE), \ + ZAP_EMPTY_DEFAULT() }, /* GroupKeyMap */ \ + { 0x00000001, ZAP_TYPE(ARRAY), 0, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE), ZAP_EMPTY_DEFAULT() }, /* GroupTable */ \ + { 0x00000002, ZAP_TYPE(INT16U), 0, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE), \ + ZAP_EMPTY_DEFAULT() }, /* MaxGroupsPerFabric */ \ + { 0x00000003, ZAP_TYPE(INT16U), 0, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE), \ + ZAP_EMPTY_DEFAULT() }, /* MaxGroupKeysPerFabric */ \ + { 0x0000FFFD, ZAP_TYPE(INT16U), 2, 0, ZAP_SIMPLE_DEFAULT(1) }, /* ClusterRevision */ \ + \ /* Endpoint: 0, Cluster: Fixed Label (server) */ \ { 0x00000000, ZAP_TYPE(ARRAY), 0, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE), ZAP_EMPTY_DEFAULT() }, /* label list */ \ { 0x0000FFFD, ZAP_TYPE(INT16U), 2, 0, ZAP_SIMPLE_DEFAULT(1) }, /* ClusterRevision */ \ @@ -760,10 +780,14 @@ \ /* Endpoint: 1, Cluster: Identify (server) */ \ { 0x00000000, ZAP_TYPE(INT16U), 2, ZAP_ATTRIBUTE_MASK(MIN_MAX) | ZAP_ATTRIBUTE_MASK(WRITABLE), \ - ZAP_MIN_MAX_DEFAULTS_INDEX(0) }, /* identify time */ \ + ZAP_MIN_MAX_DEFAULTS_INDEX(1) }, /* identify time */ \ { 0x00000001, ZAP_TYPE(ENUM8), 1, 0, ZAP_SIMPLE_DEFAULT(0x0) }, /* identify type */ \ { 0x0000FFFD, ZAP_TYPE(INT16U), 2, 0, ZAP_SIMPLE_DEFAULT(2) }, /* ClusterRevision */ \ \ + /* Endpoint: 1, Cluster: Groups (server) */ \ + { 0x00000000, ZAP_TYPE(BITMAP8), 1, 0, ZAP_EMPTY_DEFAULT() }, /* name support */ \ + { 0x0000FFFD, ZAP_TYPE(INT16U), 2, 0, ZAP_SIMPLE_DEFAULT(3) }, /* ClusterRevision */ \ + \ /* Endpoint: 1, Cluster: Descriptor (server) */ \ { 0x00000000, ZAP_TYPE(ARRAY), 0, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE), ZAP_EMPTY_DEFAULT() }, /* device list */ \ { 0x00000001, ZAP_TYPE(ARRAY), 0, ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE), ZAP_EMPTY_DEFAULT() }, /* server list */ \ @@ -791,9 +815,16 @@ (EmberAfGenericClusterFunction) emberAfLocalizationConfigurationClusterServerInitCallback, \ (EmberAfGenericClusterFunction) MatterLocalizationConfigurationClusterServerPreAttributeChangedCallback, \ }; \ + const EmberAfGenericClusterFunction chipFuncArrayTimeFormatLocalizationServer[] = { \ + (EmberAfGenericClusterFunction) emberAfTimeFormatLocalizationClusterServerInitCallback, \ + (EmberAfGenericClusterFunction) MatterTimeFormatLocalizationClusterServerPreAttributeChangedCallback, \ + }; \ const EmberAfGenericClusterFunction chipFuncArrayIdentifyServer[] = { \ (EmberAfGenericClusterFunction) emberAfIdentifyClusterServerInitCallback, \ (EmberAfGenericClusterFunction) MatterIdentifyClusterServerAttributeChangedCallback, \ + }; \ + const EmberAfGenericClusterFunction chipFuncArrayGroupsServer[] = { \ + (EmberAfGenericClusterFunction) emberAfGroupsClusterServerInitCallback, \ }; // clang-format off @@ -869,6 +900,17 @@ 0x00000005 /* CSRResponse */, \ 0x00000008 /* NOCResponse */, \ chip::kInvalidCommandId /* end of list */, \ + /* Endpoint: 0, Cluster: Group Key Management (server) */\ + /* client_generated */ \ + 0x00000000 /* KeySetWrite */, \ + 0x00000001 /* KeySetRead */, \ + 0x00000003 /* KeySetRemove */, \ + 0x00000004 /* KeySetReadAllIndices */, \ + chip::kInvalidCommandId /* end of list */, \ + /* server_generated */ \ + 0x00000002 /* KeySetReadResponse */, \ + 0x00000005 /* KeySetReadAllIndicesResponse */, \ + chip::kInvalidCommandId /* end of list */, \ /* Endpoint: 1, Cluster: Identify (server) */\ /* client_generated */ \ 0x00000000 /* Identify */, \ @@ -878,12 +920,27 @@ /* server_generated */ \ 0x00000000 /* IdentifyQueryResponse */, \ chip::kInvalidCommandId /* end of list */, \ + /* Endpoint: 1, Cluster: Groups (server) */\ + /* client_generated */ \ + 0x00000000 /* AddGroup */, \ + 0x00000001 /* ViewGroup */, \ + 0x00000002 /* GetGroupMembership */, \ + 0x00000003 /* RemoveGroup */, \ + 0x00000004 /* RemoveAllGroups */, \ + 0x00000005 /* AddGroupIfIdentifying */, \ + chip::kInvalidCommandId /* end of list */, \ + /* server_generated */ \ + 0x00000000 /* AddGroupResponse */, \ + 0x00000001 /* ViewGroupResponse */, \ + 0x00000002 /* GetGroupMembershipResponse */, \ + 0x00000003 /* RemoveGroupResponse */, \ + chip::kInvalidCommandId /* end of list */, \ } // clang-format on #define ZAP_CLUSTER_MASK(mask) CLUSTER_MASK_##mask -#define GENERATED_CLUSTER_COUNT 28 +#define GENERATED_CLUSTER_COUNT 30 // clang-format off #define GENERATED_CLUSTERS { \ @@ -964,10 +1021,21 @@ .clientGeneratedCommandList = nullptr ,\ .serverGeneratedCommandList = nullptr ,\ },\ + { \ + /* Endpoint: 0, Cluster: Time Format Localization (server) */ \ + .clusterId = 0x0000002C, \ + .attributes = ZAP_ATTRIBUTE_INDEX(37), \ + .attributeCount = 4, \ + .clusterSize = 4, \ + .mask = ZAP_CLUSTER_MASK(SERVER) | ZAP_CLUSTER_MASK(INIT_FUNCTION) | ZAP_CLUSTER_MASK(PRE_ATTRIBUTE_CHANGED_FUNCTION), \ + .functions = chipFuncArrayTimeFormatLocalizationServer, \ + .clientGeneratedCommandList = nullptr ,\ + .serverGeneratedCommandList = nullptr ,\ + },\ { \ /* Endpoint: 0, Cluster: General Commissioning (server) */ \ .clusterId = 0x00000030, \ - .attributes = ZAP_ATTRIBUTE_INDEX(37), \ + .attributes = ZAP_ATTRIBUTE_INDEX(41), \ .attributeCount = 6, \ .clusterSize = 16, \ .mask = ZAP_CLUSTER_MASK(SERVER), \ @@ -978,7 +1046,7 @@ { \ /* Endpoint: 0, Cluster: Network Commissioning (server) */ \ .clusterId = 0x00000031, \ - .attributes = ZAP_ATTRIBUTE_INDEX(43), \ + .attributes = ZAP_ATTRIBUTE_INDEX(47), \ .attributeCount = 10, \ .clusterSize = 48, \ .mask = ZAP_CLUSTER_MASK(SERVER), \ @@ -989,7 +1057,7 @@ { \ /* Endpoint: 0, Cluster: Diagnostic Logs (server) */ \ .clusterId = 0x00000032, \ - .attributes = ZAP_ATTRIBUTE_INDEX(53), \ + .attributes = ZAP_ATTRIBUTE_INDEX(57), \ .attributeCount = 0, \ .clusterSize = 0, \ .mask = ZAP_CLUSTER_MASK(SERVER), \ @@ -1000,7 +1068,7 @@ { \ /* Endpoint: 0, Cluster: General Diagnostics (server) */ \ .clusterId = 0x00000033, \ - .attributes = ZAP_ATTRIBUTE_INDEX(53), \ + .attributes = ZAP_ATTRIBUTE_INDEX(57), \ .attributeCount = 9, \ .clusterSize = 17, \ .mask = ZAP_CLUSTER_MASK(SERVER), \ @@ -1011,7 +1079,7 @@ { \ /* Endpoint: 0, Cluster: Software Diagnostics (server) */ \ .clusterId = 0x00000034, \ - .attributes = ZAP_ATTRIBUTE_INDEX(62), \ + .attributes = ZAP_ATTRIBUTE_INDEX(66), \ .attributeCount = 6, \ .clusterSize = 30, \ .mask = ZAP_CLUSTER_MASK(SERVER), \ @@ -1022,7 +1090,7 @@ { \ /* Endpoint: 0, Cluster: Thread Network Diagnostics (server) */ \ .clusterId = 0x00000035, \ - .attributes = ZAP_ATTRIBUTE_INDEX(68), \ + .attributes = ZAP_ATTRIBUTE_INDEX(72), \ .attributeCount = 65, \ .clusterSize = 247, \ .mask = ZAP_CLUSTER_MASK(SERVER), \ @@ -1033,7 +1101,7 @@ { \ /* Endpoint: 0, Cluster: WiFi Network Diagnostics (server) */ \ .clusterId = 0x00000036, \ - .attributes = ZAP_ATTRIBUTE_INDEX(133), \ + .attributes = ZAP_ATTRIBUTE_INDEX(137), \ .attributeCount = 15, \ .clusterSize = 58, \ .mask = ZAP_CLUSTER_MASK(SERVER), \ @@ -1044,7 +1112,7 @@ { \ /* Endpoint: 0, Cluster: Ethernet Network Diagnostics (server) */ \ .clusterId = 0x00000037, \ - .attributes = ZAP_ATTRIBUTE_INDEX(148), \ + .attributes = ZAP_ATTRIBUTE_INDEX(152), \ .attributeCount = 11, \ .clusterSize = 57, \ .mask = ZAP_CLUSTER_MASK(SERVER), \ @@ -1055,7 +1123,7 @@ { \ /* Endpoint: 0, Cluster: Switch (server) */ \ .clusterId = 0x0000003B, \ - .attributes = ZAP_ATTRIBUTE_INDEX(159), \ + .attributes = ZAP_ATTRIBUTE_INDEX(163), \ .attributeCount = 0, \ .clusterSize = 0, \ .mask = ZAP_CLUSTER_MASK(SERVER), \ @@ -1066,7 +1134,7 @@ { \ /* Endpoint: 0, Cluster: AdministratorCommissioning (server) */ \ .clusterId = 0x0000003C, \ - .attributes = ZAP_ATTRIBUTE_INDEX(159), \ + .attributes = ZAP_ATTRIBUTE_INDEX(163), \ .attributeCount = 4, \ .clusterSize = 2, \ .mask = ZAP_CLUSTER_MASK(SERVER), \ @@ -1077,7 +1145,7 @@ { \ /* Endpoint: 0, Cluster: Operational Credentials (server) */ \ .clusterId = 0x0000003E, \ - .attributes = ZAP_ATTRIBUTE_INDEX(163), \ + .attributes = ZAP_ATTRIBUTE_INDEX(167), \ .attributeCount = 7, \ .clusterSize = 4, \ .mask = ZAP_CLUSTER_MASK(SERVER), \ @@ -1085,10 +1153,21 @@ .clientGeneratedCommandList = ZAP_GENERATED_COMMANDS_INDEX( 33 ) ,\ .serverGeneratedCommandList = ZAP_GENERATED_COMMANDS_INDEX( 43 ) ,\ },\ + { \ + /* Endpoint: 0, Cluster: Group Key Management (server) */ \ + .clusterId = 0x0000003F, \ + .attributes = ZAP_ATTRIBUTE_INDEX(174), \ + .attributeCount = 5, \ + .clusterSize = 2, \ + .mask = ZAP_CLUSTER_MASK(SERVER), \ + .functions = NULL, \ + .clientGeneratedCommandList = ZAP_GENERATED_COMMANDS_INDEX( 48 ) ,\ + .serverGeneratedCommandList = ZAP_GENERATED_COMMANDS_INDEX( 53 ) ,\ + },\ { \ /* Endpoint: 0, Cluster: Fixed Label (server) */ \ .clusterId = 0x00000040, \ - .attributes = ZAP_ATTRIBUTE_INDEX(170), \ + .attributes = ZAP_ATTRIBUTE_INDEX(179), \ .attributeCount = 2, \ .clusterSize = 2, \ .mask = ZAP_CLUSTER_MASK(SERVER), \ @@ -1099,7 +1178,7 @@ { \ /* Endpoint: 0, Cluster: User Label (server) */ \ .clusterId = 0x00000041, \ - .attributes = ZAP_ATTRIBUTE_INDEX(172), \ + .attributes = ZAP_ATTRIBUTE_INDEX(181), \ .attributeCount = 2, \ .clusterSize = 2, \ .mask = ZAP_CLUSTER_MASK(SERVER), \ @@ -1110,7 +1189,7 @@ { \ /* Endpoint: 1, Cluster: Identify (client) */ \ .clusterId = 0x00000003, \ - .attributes = ZAP_ATTRIBUTE_INDEX(174), \ + .attributes = ZAP_ATTRIBUTE_INDEX(183), \ .attributeCount = 0, \ .clusterSize = 0, \ .mask = ZAP_CLUSTER_MASK(CLIENT), \ @@ -1121,29 +1200,29 @@ { \ /* Endpoint: 1, Cluster: Identify (server) */ \ .clusterId = 0x00000003, \ - .attributes = ZAP_ATTRIBUTE_INDEX(174), \ + .attributes = ZAP_ATTRIBUTE_INDEX(183), \ .attributeCount = 3, \ .clusterSize = 5, \ .mask = ZAP_CLUSTER_MASK(SERVER) | ZAP_CLUSTER_MASK(INIT_FUNCTION) | ZAP_CLUSTER_MASK(ATTRIBUTE_CHANGED_FUNCTION), \ .functions = chipFuncArrayIdentifyServer, \ - .clientGeneratedCommandList = ZAP_GENERATED_COMMANDS_INDEX( 48 ) ,\ - .serverGeneratedCommandList = ZAP_GENERATED_COMMANDS_INDEX( 52 ) ,\ + .clientGeneratedCommandList = ZAP_GENERATED_COMMANDS_INDEX( 56 ) ,\ + .serverGeneratedCommandList = ZAP_GENERATED_COMMANDS_INDEX( 60 ) ,\ },\ { \ - /* Endpoint: 1, Cluster: Groups (client) */ \ + /* Endpoint: 1, Cluster: Groups (server) */ \ .clusterId = 0x00000004, \ - .attributes = ZAP_ATTRIBUTE_INDEX(177), \ - .attributeCount = 0, \ - .clusterSize = 0, \ - .mask = ZAP_CLUSTER_MASK(CLIENT), \ - .functions = NULL, \ - .clientGeneratedCommandList = nullptr ,\ - .serverGeneratedCommandList = nullptr ,\ + .attributes = ZAP_ATTRIBUTE_INDEX(186), \ + .attributeCount = 2, \ + .clusterSize = 3, \ + .mask = ZAP_CLUSTER_MASK(SERVER) | ZAP_CLUSTER_MASK(INIT_FUNCTION), \ + .functions = chipFuncArrayGroupsServer, \ + .clientGeneratedCommandList = ZAP_GENERATED_COMMANDS_INDEX( 62 ) ,\ + .serverGeneratedCommandList = ZAP_GENERATED_COMMANDS_INDEX( 69 ) ,\ },\ { \ /* Endpoint: 1, Cluster: Scenes (client) */ \ .clusterId = 0x00000005, \ - .attributes = ZAP_ATTRIBUTE_INDEX(177), \ + .attributes = ZAP_ATTRIBUTE_INDEX(188), \ .attributeCount = 0, \ .clusterSize = 0, \ .mask = ZAP_CLUSTER_MASK(CLIENT), \ @@ -1154,7 +1233,7 @@ { \ /* Endpoint: 1, Cluster: On/Off (client) */ \ .clusterId = 0x00000006, \ - .attributes = ZAP_ATTRIBUTE_INDEX(177), \ + .attributes = ZAP_ATTRIBUTE_INDEX(188), \ .attributeCount = 0, \ .clusterSize = 0, \ .mask = ZAP_CLUSTER_MASK(CLIENT), \ @@ -1165,7 +1244,7 @@ { \ /* Endpoint: 1, Cluster: Descriptor (server) */ \ .clusterId = 0x0000001D, \ - .attributes = ZAP_ATTRIBUTE_INDEX(177), \ + .attributes = ZAP_ATTRIBUTE_INDEX(188), \ .attributeCount = 5, \ .clusterSize = 0, \ .mask = ZAP_CLUSTER_MASK(SERVER), \ @@ -1176,7 +1255,7 @@ { \ /* Endpoint: 1, Cluster: Binding (server) */ \ .clusterId = 0x0000001E, \ - .attributes = ZAP_ATTRIBUTE_INDEX(182), \ + .attributes = ZAP_ATTRIBUTE_INDEX(193), \ .attributeCount = 2, \ .clusterSize = 2, \ .mask = ZAP_CLUSTER_MASK(SERVER), \ @@ -1187,7 +1266,7 @@ { \ /* Endpoint: 1, Cluster: Color Control (client) */ \ .clusterId = 0x00000300, \ - .attributes = ZAP_ATTRIBUTE_INDEX(184), \ + .attributes = ZAP_ATTRIBUTE_INDEX(195), \ .attributeCount = 0, \ .clusterSize = 0, \ .mask = ZAP_CLUSTER_MASK(CLIENT), \ @@ -1201,12 +1280,12 @@ #define ZAP_CLUSTER_INDEX(index) (&generatedClusters[index]) -#define ZAP_FIXED_ENDPOINT_DATA_VERSION_COUNT 22 +#define ZAP_FIXED_ENDPOINT_DATA_VERSION_COUNT 25 // This is an array of EmberAfEndpointType structures. #define GENERATED_ENDPOINT_TYPES \ { \ - { ZAP_CLUSTER_INDEX(0), 20, 567 }, { ZAP_CLUSTER_INDEX(20), 8, 7 }, \ + { ZAP_CLUSTER_INDEX(0), 22, 573 }, { ZAP_CLUSTER_INDEX(22), 8, 10 }, \ } // Largest attribute size is needed for various buffers @@ -1218,7 +1297,7 @@ static_assert(ATTRIBUTE_LARGEST <= CHIP_CONFIG_MAX_ATTRIBUTE_STORE_ELEMENT_SIZE, #define ATTRIBUTE_SINGLETONS_SIZE (39) // Total size of attribute storage -#define ATTRIBUTE_MAX_SIZE (574) +#define ATTRIBUTE_MAX_SIZE (583) // Number of fixed endpoints #define FIXED_ENDPOINT_COUNT (2) diff --git a/zzz_generated/light-switch-app/zap-generated/gen_config.h b/zzz_generated/light-switch-app/zap-generated/gen_config.h index fa99ab59bba46c..14dec40c8f55a9 100644 --- a/zzz_generated/light-switch-app/zap-generated/gen_config.h +++ b/zzz_generated/light-switch-app/zap-generated/gen_config.h @@ -40,7 +40,8 @@ #define EMBER_AF_FIXED_LABEL_CLUSTER_SERVER_ENDPOINT_COUNT (1) #define EMBER_AF_GENERAL_COMMISSIONING_CLUSTER_SERVER_ENDPOINT_COUNT (1) #define EMBER_AF_GENERAL_DIAGNOSTICS_CLUSTER_SERVER_ENDPOINT_COUNT (1) -#define EMBER_AF_GROUPS_CLUSTER_CLIENT_ENDPOINT_COUNT (1) +#define EMBER_AF_GROUP_KEY_MANAGEMENT_CLUSTER_SERVER_ENDPOINT_COUNT (1) +#define EMBER_AF_GROUPS_CLUSTER_SERVER_ENDPOINT_COUNT (1) #define EMBER_AF_IDENTIFY_CLUSTER_CLIENT_ENDPOINT_COUNT (1) #define EMBER_AF_IDENTIFY_CLUSTER_SERVER_ENDPOINT_COUNT (1) #define EMBER_AF_LOCALIZATION_CONFIGURATION_CLUSTER_SERVER_ENDPOINT_COUNT (1) @@ -53,6 +54,7 @@ #define EMBER_AF_SOFTWARE_DIAGNOSTICS_CLUSTER_SERVER_ENDPOINT_COUNT (1) #define EMBER_AF_SWITCH_CLUSTER_SERVER_ENDPOINT_COUNT (1) #define EMBER_AF_THREAD_NETWORK_DIAGNOSTICS_CLUSTER_SERVER_ENDPOINT_COUNT (1) +#define EMBER_AF_TIME_FORMAT_LOCALIZATION_CLUSTER_SERVER_ENDPOINT_COUNT (1) #define EMBER_AF_USER_LABEL_CLUSTER_SERVER_ENDPOINT_COUNT (1) #define EMBER_AF_WIFI_NETWORK_DIAGNOSTICS_CLUSTER_SERVER_ENDPOINT_COUNT (1) @@ -112,9 +114,15 @@ #define EMBER_AF_PLUGIN_GENERAL_DIAGNOSTICS_SERVER #define EMBER_AF_PLUGIN_GENERAL_DIAGNOSTICS -// Use this macro to check if the client side of the Groups cluster is included -#define ZCL_USING_GROUPS_CLUSTER_CLIENT -#define EMBER_AF_PLUGIN_GROUPS_CLIENT +// Use this macro to check if the server side of the Group Key Management cluster is included +#define ZCL_USING_GROUP_KEY_MANAGEMENT_CLUSTER_SERVER +#define EMBER_AF_PLUGIN_GROUP_KEY_MANAGEMENT_SERVER +#define EMBER_AF_PLUGIN_GROUP_KEY_MANAGEMENT + +// Use this macro to check if the server side of the Groups cluster is included +#define ZCL_USING_GROUPS_CLUSTER_SERVER +#define EMBER_AF_PLUGIN_GROUPS_SERVER +#define EMBER_AF_PLUGIN_GROUPS // Use this macro to check if the client side of the Identify cluster is included #define ZCL_USING_IDENTIFY_CLUSTER_CLIENT @@ -172,6 +180,11 @@ #define EMBER_AF_PLUGIN_THREAD_NETWORK_DIAGNOSTICS_SERVER #define EMBER_AF_PLUGIN_THREAD_NETWORK_DIAGNOSTICS +// Use this macro to check if the server side of the Time Format Localization cluster is included +#define ZCL_USING_TIME_FORMAT_LOCALIZATION_CLUSTER_SERVER +#define EMBER_AF_PLUGIN_TIME_FORMAT_LOCALIZATION_SERVER +#define EMBER_AF_PLUGIN_TIME_FORMAT_LOCALIZATION + // Use this macro to check if the server side of the User Label cluster is included #define ZCL_USING_USER_LABEL_CLUSTER_SERVER #define EMBER_AF_PLUGIN_USER_LABEL_SERVER