text: /*
   *
   *    Copyright (c) 2021 Project CHIP Authors
   *
   *    Licensed under the Apache License, Version 2.0 (the "License");
   *    you may not use this file except in compliance with the License.
   *    You may obtain a copy of the License at
   *
   *        http://www.apache.org/licenses/LICENSE-2.0
   *
   *    Unless required by applicable law or agreed to in writing, software
   *    distributed under the License is distributed on an "AS IS" BASIS,
   *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   *    See the License for the specific language governing permissions and
   *    limitations under the License.
   */
  
  // THIS FILE IS GENERATED BY ZAP
  
  #include <cinttypes>
  #include <cstdint>
  
  #include "app/common/gen/af-structs.h"
  #include "app/common/gen/callback.h"
  #include "app/common/gen/ids/Clusters.h"
  #include "app/common/gen/ids/Commands.h"
  #include "app/util/util.h"
  
  #include <app/InteractionModelEngine.h>
  
  // Currently we need some work to keep compatible with ember lib.
  #include <app/util/ember-compatibility-functions.h>
  
  namespace chip {
  namespace app {
  
  // Cluster specific command parsing
  
  namespace clusters {
  
  namespace BarrierControl {
  
  void DispatchServerCommand(app::CommandHandler * apCommandObj, CommandId aCommandId, EndpointId aEndpointId,
                             TLV::TLVReader & aDataTlv)
  {
      // We are using TLVUnpackError and TLVError here since both of them can be CHIP_END_OF_TLV
      // When TLVError is CHIP_END_OF_TLV, it means we have iterated all of the items, which is not a real error.
      // Any error value TLVUnpackError means we have received an illegal value.
      // The following variables are used for all commands to save code size.
      CHIP_ERROR TLVError          = CHIP_NO_ERROR;
      CHIP_ERROR TLVUnpackError    = CHIP_NO_ERROR;
      uint32_t validArgumentCount  = 0;
      uint32_t expectArgumentCount = 0;
      uint32_t currentDecodeTagId  = 0;
      bool wasHandled              = false;
      {
          switch (aCommandId)
          {
          case Clusters::BarrierControl::Commands::Ids::BarrierControlGoToPercent: {
              expectArgumentCount = 1;
              uint8_t percentOpen;
              bool argExists[1];
  
              memset(argExists, 0, sizeof argExists);
  
              while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR)
              {
                  // Since call to aDataTlv.Next() is CHIP_NO_ERROR, the read head always points to an element.
                  // Skip this element if it is not a ContextTag, not consider it as an error if other values are valid.
                  if (!TLV::IsContextTag(aDataTlv.GetTag()))
                  {
                      continue;
                  }
                  currentDecodeTagId = TLV::TagNumFromTag(aDataTlv.GetTag());
                  if (currentDecodeTagId < 1)
                  {
                      if (argExists[currentDecodeTagId])
                      {
                          ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
                          TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
                          break;
                      }
                      else
                      {
                          argExists[currentDecodeTagId] = true;
                          validArgumentCount++;
                      }
                  }
                  switch (currentDecodeTagId)
                  {
                  case 0:
                      TLVUnpackError = aDataTlv.Get(percentOpen);
                      break;
                  default:
                      // Unsupported tag, ignore it.
                      ChipLogProgress(Zcl, "Unknown TLV tag during processing.");
                      break;
                  }
                  if (CHIP_NO_ERROR != TLVUnpackError)
                  {
                      break;
                  }
              }
  
              if (CHIP_END_OF_TLV == TLVError)
              {
                  // CHIP_END_OF_TLV means we have iterated all items in the structure, which is not a real error.
                  TLVError = CHIP_NO_ERROR;
              }
  
              if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 1 == validArgumentCount)
              {
                  wasHandled = emberAfBarrierControlClusterBarrierControlGoToPercentCallback(aEndpointId, apCommandObj, percentOpen);
              }
              break;
          }
          case Clusters::BarrierControl::Commands::Ids::BarrierControlStop: {
  
              wasHandled = emberAfBarrierControlClusterBarrierControlStopCallback(aEndpointId, apCommandObj);
              break;
          }
          default: {
              // Unrecognized command ID, error status will apply.
              chip::app::CommandPathParams returnStatusParam = { aEndpointId,
                                                                 0, // GroupId
                                                                 Clusters::BarrierControl::Id, aCommandId,
                                                                 (chip::app::CommandPathFlags::kEndpointIdValid) };
              apCommandObj->AddStatusCode(returnStatusParam, Protocols::SecureChannel::GeneralStatusCode::kNotFound,
                                          Protocols::SecureChannel::Id,
                                          Protocols::InteractionModel::ProtocolCode::UnsupportedCommand);
              ChipLogError(Zcl, "Unknown command %" PRIx32 " for cluster %" PRIx32, aCommandId, Clusters::BarrierControl::Id);
              return;
          }
          }
      }
  
      if (CHIP_NO_ERROR != TLVError || CHIP_NO_ERROR != TLVUnpackError || expectArgumentCount != validArgumentCount || !wasHandled)
      {
          chip::app::CommandPathParams returnStatusParam = { aEndpointId,
                                                             0, // GroupId
                                                             Clusters::BarrierControl::Id, aCommandId,
                                                             (chip::app::CommandPathFlags::kEndpointIdValid) };
          apCommandObj->AddStatusCode(returnStatusParam, Protocols::SecureChannel::GeneralStatusCode::kBadRequest,
                                      Protocols::SecureChannel::Id, Protocols::InteractionModel::ProtocolCode::InvalidCommand);
          ChipLogProgress(Zcl,
                          "Failed to dispatch command, %" PRIu32 "/%" PRIu32 " arguments parsed, TLVError=%" CHIP_ERROR_FORMAT
                          ", UnpackError=%" CHIP_ERROR_FORMAT " (last decoded tag = %" PRIu32,
                          validArgumentCount, expectArgumentCount, ChipError::FormatError(TLVError),
                          ChipError::FormatError(TLVUnpackError), currentDecodeTagId);
          // A command with no arguments would never write currentDecodeTagId.  If
          // progress logging is also disabled, it would look unused.  Silence that
          // warning.
          UNUSED_VAR(currentDecodeTagId);
      }
  }
  
  } // namespace BarrierControl
  
  namespace Basic {
  
  void DispatchServerCommand(app::CommandHandler * apCommandObj, CommandId aCommandId, EndpointId aEndpointId,
                             TLV::TLVReader & aDataTlv)
  {
      // We are using TLVUnpackError and TLVError here since both of them can be CHIP_END_OF_TLV
      // When TLVError is CHIP_END_OF_TLV, it means we have iterated all of the items, which is not a real error.
      // Any error value TLVUnpackError means we have received an illegal value.
      // The following variables are used for all commands to save code size.
      CHIP_ERROR TLVError          = CHIP_NO_ERROR;
      CHIP_ERROR TLVUnpackError    = CHIP_NO_ERROR;
      uint32_t validArgumentCount  = 0;
      uint32_t expectArgumentCount = 0;
      uint32_t currentDecodeTagId  = 0;
      bool wasHandled              = false;
      {
          switch (aCommandId)
          {
          default: {
              // Unrecognized command ID, error status will apply.
              chip::app::CommandPathParams returnStatusParam = { aEndpointId,
                                                                 0, // GroupId
                                                                 Clusters::Basic::Id, aCommandId,
                                                                 (chip::app::CommandPathFlags::kEndpointIdValid) };
              apCommandObj->AddStatusCode(returnStatusParam, Protocols::SecureChannel::GeneralStatusCode::kNotFound,
                                          Protocols::SecureChannel::Id,
                                          Protocols::InteractionModel::ProtocolCode::UnsupportedCommand);
              ChipLogError(Zcl, "Unknown command %" PRIx32 " for cluster %" PRIx32, aCommandId, Clusters::Basic::Id);
              return;
          }
          }
      }
  
      if (CHIP_NO_ERROR != TLVError || CHIP_NO_ERROR != TLVUnpackError || expectArgumentCount != validArgumentCount || !wasHandled)
      {
          chip::app::CommandPathParams returnStatusParam = { aEndpointId,
                                                             0, // GroupId
                                                             Clusters::Basic::Id, aCommandId,
                                                             (chip::app::CommandPathFlags::kEndpointIdValid) };
          apCommandObj->AddStatusCode(returnStatusParam, Protocols::SecureChannel::GeneralStatusCode::kBadRequest,
                                      Protocols::SecureChannel::Id, Protocols::InteractionModel::ProtocolCode::InvalidCommand);
          ChipLogProgress(Zcl,
                          "Failed to dispatch command, %" PRIu32 "/%" PRIu32 " arguments parsed, TLVError=%" CHIP_ERROR_FORMAT
                          ", UnpackError=%" CHIP_ERROR_FORMAT " (last decoded tag = %" PRIu32,
                          validArgumentCount, expectArgumentCount, ChipError::FormatError(TLVError),
                          ChipError::FormatError(TLVUnpackError), currentDecodeTagId);
          // A command with no arguments would never write currentDecodeTagId.  If
          // progress logging is also disabled, it would look unused.  Silence that
          // warning.
          UNUSED_VAR(currentDecodeTagId);
      }
  }
  
  } // namespace Basic
  
  namespace Binding {
  
  void DispatchServerCommand(app::CommandHandler * apCommandObj, CommandId aCommandId, EndpointId aEndpointId,
                             TLV::TLVReader & aDataTlv)
  {
      // We are using TLVUnpackError and TLVError here since both of them can be CHIP_END_OF_TLV
      // When TLVError is CHIP_END_OF_TLV, it means we have iterated all of the items, which is not a real error.
      // Any error value TLVUnpackError means we have received an illegal value.
      // The following variables are used for all commands to save code size.
      CHIP_ERROR TLVError          = CHIP_NO_ERROR;
      CHIP_ERROR TLVUnpackError    = CHIP_NO_ERROR;
      uint32_t validArgumentCount  = 0;
      uint32_t expectArgumentCount = 0;
      uint32_t currentDecodeTagId  = 0;
      bool wasHandled              = false;
      {
          switch (aCommandId)
          {
          case Clusters::Binding::Commands::Ids::Bind: {
              expectArgumentCount = 4;
              chip::NodeId nodeId;
              chip::GroupId groupId;
              chip::EndpointId endpointId;
              chip::ClusterId clusterId;
              bool argExists[4];
  
              memset(argExists, 0, sizeof argExists);
  
              while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR)
              {
                  // Since call to aDataTlv.Next() is CHIP_NO_ERROR, the read head always points to an element.
                  // Skip this element if it is not a ContextTag, not consider it as an error if other values are valid.
                  if (!TLV::IsContextTag(aDataTlv.GetTag()))
                  {
                      continue;
                  }
                  currentDecodeTagId = TLV::TagNumFromTag(aDataTlv.GetTag());
                  if (currentDecodeTagId < 4)
                  {
                      if (argExists[currentDecodeTagId])
                      {
                          ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
                          TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
                          break;
                      }
                      else
                      {
                          argExists[currentDecodeTagId] = true;
                          validArgumentCount++;
                      }
                  }
                  switch (currentDecodeTagId)
                  {
                  case 0:
                      TLVUnpackError = aDataTlv.Get(nodeId);
                      break;
                  case 1:
                      TLVUnpackError = aDataTlv.Get(groupId);
                      break;
                  case 2:
                      TLVUnpackError = aDataTlv.Get(endpointId);
                      break;
                  case 3:
                      TLVUnpackError = aDataTlv.Get(clusterId);
                      break;
                  default:
                      // Unsupported tag, ignore it.
                      ChipLogProgress(Zcl, "Unknown TLV tag during processing.");
                      break;
                  }
                  if (CHIP_NO_ERROR != TLVUnpackError)
                  {
                      break;
                  }
              }
  
              if (CHIP_END_OF_TLV == TLVError)
              {
                  // CHIP_END_OF_TLV means we have iterated all items in the structure, which is not a real error.
                  TLVError = CHIP_NO_ERROR;
              }
  
              if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 4 == validArgumentCount)
              {
                  wasHandled = emberAfBindingClusterBindCallback(aEndpointId, apCommandObj, nodeId, groupId, endpointId, clusterId);
              }
              break;
          }
          case Clusters::Binding::Commands::Ids::Unbind: {
              expectArgumentCount = 4;
              chip::NodeId nodeId;
              chip::GroupId groupId;
              chip::EndpointId endpointId;
              chip::ClusterId clusterId;
              bool argExists[4];
  
              memset(argExists, 0, sizeof argExists);
  
              while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR)
              {
                  // Since call to aDataTlv.Next() is CHIP_NO_ERROR, the read head always points to an element.
                  // Skip this element if it is not a ContextTag, not consider it as an error if other values are valid.
                  if (!TLV::IsContextTag(aDataTlv.GetTag()))
                  {
                      continue;
                  }
                  currentDecodeTagId = TLV::TagNumFromTag(aDataTlv.GetTag());
                  if (currentDecodeTagId < 4)
                  {
                      if (argExists[currentDecodeTagId])
                      {
                          ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
                          TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
                          break;
                      }
                      else
                      {
                          argExists[currentDecodeTagId] = true;
                          validArgumentCount++;
                      }
                  }
                  switch (currentDecodeTagId)
                  {
                  case 0:
                      TLVUnpackError = aDataTlv.Get(nodeId);
                      break;
                  case 1:
                      TLVUnpackError = aDataTlv.Get(groupId);
                      break;
                  case 2:
                      TLVUnpackError = aDataTlv.Get(endpointId);
                      break;
                  case 3:
                      TLVUnpackError = aDataTlv.Get(clusterId);
                      break;
                  default:
                      // Unsupported tag, ignore it.
                      ChipLogProgress(Zcl, "Unknown TLV tag during processing.");
                      break;
                  }
                  if (CHIP_NO_ERROR != TLVUnpackError)
                  {
                      break;
                  }
              }
  
              if (CHIP_END_OF_TLV == TLVError)
              {
                  // CHIP_END_OF_TLV means we have iterated all items in the structure, which is not a real error.
                  TLVError = CHIP_NO_ERROR;
              }
  
              if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 4 == validArgumentCount)
              {
                  wasHandled = emberAfBindingClusterUnbindCallback(aEndpointId, apCommandObj, nodeId, groupId, endpointId, clusterId);
              }
              break;
          }
          default: {
              // Unrecognized command ID, error status will apply.
              chip::app::CommandPathParams returnStatusParam = { aEndpointId,
                                                                 0, // GroupId
                                                                 Clusters::Binding::Id, aCommandId,
                                                                 (chip::app::CommandPathFlags::kEndpointIdValid) };
              apCommandObj->AddStatusCode(returnStatusParam, Protocols::SecureChannel::GeneralStatusCode::kNotFound,
                                          Protocols::SecureChannel::Id,
                                          Protocols::InteractionModel::ProtocolCode::UnsupportedCommand);
              ChipLogError(Zcl, "Unknown command %" PRIx32 " for cluster %" PRIx32, aCommandId, Clusters::Binding::Id);
              return;
          }
          }
      }
  
      if (CHIP_NO_ERROR != TLVError || CHIP_NO_ERROR != TLVUnpackError || expectArgumentCount != validArgumentCount || !wasHandled)
      {
          chip::app::CommandPathParams returnStatusParam = { aEndpointId,
                                                             0, // GroupId
                                                             Clusters::Binding::Id, aCommandId,
                                                             (chip::app::CommandPathFlags::kEndpointIdValid) };
          apCommandObj->AddStatusCode(returnStatusParam, Protocols::SecureChannel::GeneralStatusCode::kBadRequest,
                                      Protocols::SecureChannel::Id, Protocols::InteractionModel::ProtocolCode::InvalidCommand);
          ChipLogProgress(Zcl,
                          "Failed to dispatch command, %" PRIu32 "/%" PRIu32 " arguments parsed, TLVError=%" CHIP_ERROR_FORMAT
                          ", UnpackError=%" CHIP_ERROR_FORMAT " (last decoded tag = %" PRIu32,
                          validArgumentCount, expectArgumentCount, ChipError::FormatError(TLVError),
                          ChipError::FormatError(TLVUnpackError), currentDecodeTagId);
          // A command with no arguments would never write currentDecodeTagId.  If
          // progress logging is also disabled, it would look unused.  Silence that
          // warning.
          UNUSED_VAR(currentDecodeTagId);
      }
  }
  
  } // namespace Binding
  
  namespace ColorControl {
  
  void DispatchServerCommand(app::CommandHandler * apCommandObj, CommandId aCommandId, EndpointId aEndpointId,
                             TLV::TLVReader & aDataTlv)
  {
      // We are using TLVUnpackError and TLVError here since both of them can be CHIP_END_OF_TLV
      // When TLVError is CHIP_END_OF_TLV, it means we have iterated all of the items, which is not a real error.
      // Any error value TLVUnpackError means we have received an illegal value.
      // The following variables are used for all commands to save code size.
      CHIP_ERROR TLVError          = CHIP_NO_ERROR;
      CHIP_ERROR TLVUnpackError    = CHIP_NO_ERROR;
      uint32_t validArgumentCount  = 0;
      uint32_t expectArgumentCount = 0;
      uint32_t currentDecodeTagId  = 0;
      bool wasHandled              = false;
      {
          switch (aCommandId)
          {
          case Clusters::ColorControl::Commands::Ids::ColorLoopSet: {
              expectArgumentCount = 7;
              uint8_t updateFlags;
              uint8_t action;
              uint8_t direction;
              uint16_t time;
              uint16_t startHue;
              uint8_t optionsMask;
              uint8_t optionsOverride;
              bool argExists[7];
  
              memset(argExists, 0, sizeof argExists);
  
              while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR)
              {
                  // Since call to aDataTlv.Next() is CHIP_NO_ERROR, the read head always points to an element.
                  // Skip this element if it is not a ContextTag, not consider it as an error if other values are valid.
                  if (!TLV::IsContextTag(aDataTlv.GetTag()))
                  {
                      continue;
                  }
                  currentDecodeTagId = TLV::TagNumFromTag(aDataTlv.GetTag());
                  if (currentDecodeTagId < 7)
                  {
                      if (argExists[currentDecodeTagId])
                      {
                          ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
                          TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
                          break;
                      }
                      else
                      {
                          argExists[currentDecodeTagId] = true;
                          validArgumentCount++;
                      }
                  }
                  switch (currentDecodeTagId)
                  {
                  case 0:
                      TLVUnpackError = aDataTlv.Get(updateFlags);
                      break;
                  case 1:
                      TLVUnpackError = aDataTlv.Get(action);
                      break;
                  case 2:
                      TLVUnpackError = aDataTlv.Get(direction);
                      break;
                  case 3:
                      TLVUnpackError = aDataTlv.Get(time);
                      break;
                  case 4:
                      TLVUnpackError = aDataTlv.Get(startHue);
                      break;
                  case 5:
                      TLVUnpackError = aDataTlv.Get(optionsMask);
                      break;
                  case 6:
                      TLVUnpackError = aDataTlv.Get(optionsOverride);
                      break;
                  default:
                      // Unsupported tag, ignore it.
                      ChipLogProgress(Zcl, "Unknown TLV tag during processing.");
                      break;
                  }
                  if (CHIP_NO_ERROR != TLVUnpackError)
                  {
                      break;
                  }
              }
  
              if (CHIP_END_OF_TLV == TLVError)
              {
                  // CHIP_END_OF_TLV means we have iterated all items in the structure, which is not a real error.
                  TLVError = CHIP_NO_ERROR;
              }
  
              if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 7 == validArgumentCount)
              {
                  wasHandled = emberAfColorControlClusterColorLoopSetCallback(
                      aEndpointId, apCommandObj, updateFlags, action, direction, time, startHue, optionsMask, optionsOverride);
              }
              break;
          }
          case Clusters::ColorControl::Commands::Ids::EnhancedMoveHue: {
              expectArgumentCount = 4;
              uint8_t moveMode;
              uint16_t rate;
              uint8_t optionsMask;
              uint8_t optionsOverride;
              bool argExists[4];
  
              memset(argExists, 0, sizeof argExists);
  
              while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR)
              {
                  // Since call to aDataTlv.Next() is CHIP_NO_ERROR, the read head always points to an element.
                  // Skip this element if it is not a ContextTag, not consider it as an error if other values are valid.
                  if (!TLV::IsContextTag(aDataTlv.GetTag()))
                  {
                      continue;
                  }
                  currentDecodeTagId = TLV::TagNumFromTag(aDataTlv.GetTag());
                  if (currentDecodeTagId < 4)
                  {
                      if (argExists[currentDecodeTagId])
                      {
                          ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
                          TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
                          break;
                      }
                      else
                      {
                          argExists[currentDecodeTagId] = true;
                          validArgumentCount++;
                      }
                  }
                  switch (currentDecodeTagId)
                  {
                  case 0:
                      TLVUnpackError = aDataTlv.Get(moveMode);
                      break;
                  case 1:
                      TLVUnpackError = aDataTlv.Get(rate);
                      break;
                  case 2:
                      TLVUnpackError = aDataTlv.Get(optionsMask);
                      break;
                  case 3:
                      TLVUnpackError = aDataTlv.Get(optionsOverride);
                      break;
                  default:
                      // Unsupported tag, ignore it.
                      ChipLogProgress(Zcl, "Unknown TLV tag during processing.");
                      break;
                  }
                  if (CHIP_NO_ERROR != TLVUnpackError)
                  {
                      break;
                  }
              }
  
              if (CHIP_END_OF_TLV == TLVError)
              {
                  // CHIP_END_OF_TLV means we have iterated all items in the structure, which is not a real error.
                  TLVError = CHIP_NO_ERROR;
              }
  
              if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 4 == validArgumentCount)
              {
                  wasHandled = emberAfColorControlClusterEnhancedMoveHueCallback(aEndpointId, apCommandObj, moveMode, rate,
                                                                                 optionsMask, optionsOverride);
              }
              break;
          }
          case Clusters::ColorControl::Commands::Ids::EnhancedMoveToHue: {
              expectArgumentCount = 5;
              uint16_t enhancedHue;
              uint8_t direction;
              uint16_t transitionTime;
              uint8_t optionsMask;
              uint8_t optionsOverride;
              bool argExists[5];
  
              memset(argExists, 0, sizeof argExists);
  
              while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR)
              {
                  // Since call to aDataTlv.Next() is CHIP_NO_ERROR, the read head always points to an element.
                  // Skip this element if it is not a ContextTag, not consider it as an error if other values are valid.
                  if (!TLV::IsContextTag(aDataTlv.GetTag()))
                  {
                      continue;
                  }
                  currentDecodeTagId = TLV::TagNumFromTag(aDataTlv.GetTag());
                  if (currentDecodeTagId < 5)
                  {
                      if (argExists[currentDecodeTagId])
                      {
                          ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
                          TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
                          break;
                      }
                      else
                      {
                          argExists[currentDecodeTagId] = true;
                          validArgumentCount++;
                      }
                  }
                  switch (currentDecodeTagId)
                  {
                  case 0:
                      TLVUnpackError = aDataTlv.Get(enhancedHue);
                      break;
                  case 1:
                      TLVUnpackError = aDataTlv.Get(direction);
                      break;
                  case 2:
                      TLVUnpackError = aDataTlv.Get(transitionTime);
                      break;
                  case 3:
                      TLVUnpackError = aDataTlv.Get(optionsMask);
                      break;
                  case 4:
                      TLVUnpackError = aDataTlv.Get(optionsOverride);
                      break;
                  default:
                      // Unsupported tag, ignore it.
                      ChipLogProgress(Zcl, "Unknown TLV tag during processing.");
                      break;
                  }
                  if (CHIP_NO_ERROR != TLVUnpackError)
                  {
                      break;
                  }
              }
  
              if (CHIP_END_OF_TLV == TLVError)
              {
                  // CHIP_END_OF_TLV means we have iterated all items in the structure, which is not a real error.
                  TLVError = CHIP_NO_ERROR;
              }
  
              if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 5 == validArgumentCount)
              {
                  wasHandled = emberAfColorControlClusterEnhancedMoveToHueCallback(aEndpointId, apCommandObj, enhancedHue, direction,
                                                                                   transitionTime, optionsMask, optionsOverride);
              }
              break;
          }
          case Clusters::ColorControl::Commands::Ids::EnhancedMoveToHueAndSaturation: {
              expectArgumentCount = 5;
              uint16_t enhancedHue;
              uint8_t saturation;
              uint16_t transitionTime;
              uint8_t optionsMask;
              uint8_t optionsOverride;
              bool argExists[5];
  
              memset(argExists, 0, sizeof argExists);
  
              while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR)
              {
                  // Since call to aDataTlv.Next() is CHIP_NO_ERROR, the read head always points to an element.
                  // Skip this element if it is not a ContextTag, not consider it as an error if other values are valid.
                  if (!TLV::IsContextTag(aDataTlv.GetTag()))
                  {
                      continue;
                  }
                  currentDecodeTagId = TLV::TagNumFromTag(aDataTlv.GetTag());
                  if (currentDecodeTagId < 5)
                  {
                      if (argExists[currentDecodeTagId])
                      {
                          ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
                          TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
                          break;
                      }
                      else
                      {
                          argExists[currentDecodeTagId] = true;
                          validArgumentCount++;
                      }
                  }
                  switch (currentDecodeTagId)
                  {
                  case 0:
                      TLVUnpackError = aDataTlv.Get(enhancedHue);
                      break;
                  case 1:
                      TLVUnpackError = aDataTlv.Get(saturation);
                      break;
                  case 2:
                      TLVUnpackError = aDataTlv.Get(transitionTime);
                      break;
                  case 3:
                      TLVUnpackError = aDataTlv.Get(optionsMask);
                      break;
                  case 4:
                      TLVUnpackError = aDataTlv.Get(optionsOverride);
                      break;
                  default:
                      // Unsupported tag, ignore it.
                      ChipLogProgress(Zcl, "Unknown TLV tag during processing.");
                      break;
                  }
                  if (CHIP_NO_ERROR != TLVUnpackError)
                  {
                      break;
                  }
              }
  
              if (CHIP_END_OF_TLV == TLVError)
              {
                  // CHIP_END_OF_TLV means we have iterated all items in the structure, which is not a real error.
                  TLVError = CHIP_NO_ERROR;
              }
  
              if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 5 == validArgumentCount)
              {
                  wasHandled = emberAfColorControlClusterEnhancedMoveToHueAndSaturationCallback(
                      aEndpointId, apCommandObj, enhancedHue, saturation, transitionTime, optionsMask, optionsOverride);
              }
              break;
          }
          case Clusters::ColorControl::Commands::Ids::EnhancedStepHue: {
              expectArgumentCount = 5;
              uint8_t stepMode;
              uint16_t stepSize;
              uint16_t transitionTime;
              uint8_t optionsMask;
              uint8_t optionsOverride;
              bool argExists[5];
  
              memset(argExists, 0, sizeof argExists);
  
              while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR)
              {
                  // Since call to aDataTlv.Next() is CHIP_NO_ERROR, the read head always points to an element.
                  // Skip this element if it is not a ContextTag, not consider it as an error if other values are valid.
                  if (!TLV::IsContextTag(aDataTlv.GetTag()))
                  {
                      continue;
                  }
                  currentDecodeTagId = TLV::TagNumFromTag(aDataTlv.GetTag());
                  if (currentDecodeTagId < 5)
                  {
                      if (argExists[currentDecodeTagId])
                      {
                          ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
                          TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
                          break;
                      }
                      else
                      {
                          argExists[currentDecodeTagId] = true;
                          validArgumentCount++;
                      }
                  }
                  switch (currentDecodeTagId)
                  {
                  case 0:
                      TLVUnpackError = aDataTlv.Get(stepMode);
                      break;
                  case 1:
                      TLVUnpackError = aDataTlv.Get(stepSize);
                      break;
                  case 2:
                      TLVUnpackError = aDataTlv.Get(transitionTime);
                      break;
                  case 3:
                      TLVUnpackError = aDataTlv.Get(optionsMask);
                      break;
                  case 4:
                      TLVUnpackError = aDataTlv.Get(optionsOverride);
                      break;
                  default:
                      // Unsupported tag, ignore it.
                      ChipLogProgress(Zcl, "Unknown TLV tag during processing.");
                      break;
                  }
                  if (CHIP_NO_ERROR != TLVUnpackError)
                  {
                      break;
                  }
              }
  
              if (CHIP_END_OF_TLV == TLVError)
              {
                  // CHIP_END_OF_TLV means we have iterated all items in the structure, which is not a real error.
                  TLVError = CHIP_NO_ERROR;
              }
  
              if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 5 == validArgumentCount)
              {
                  wasHandled = emberAfColorControlClusterEnhancedStepHueCallback(aEndpointId, apCommandObj, stepMode, stepSize,
                                                                                 transitionTime, optionsMask, optionsOverride);
              }
              break;
          }
          case Clusters::ColorControl::Commands::Ids::MoveColor: {
              expectArgumentCount = 4;
              int16_t rateX;
              int16_t rateY;
              uint8_t optionsMask;
              uint8_t optionsOverride;
              bool argExists[4];
  
              memset(argExists, 0, sizeof argExists);
  
              while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR)
              {
                  // Since call to aDataTlv.Next() is CHIP_NO_ERROR, the read head always points to an element.
                  // Skip this element if it is not a ContextTag, not consider it as an error if other values are valid.
                  if (!TLV::IsContextTag(aDataTlv.GetTag()))
                  {
                      continue;
                  }
                  currentDecodeTagId = TLV::TagNumFromTag(aDataTlv.GetTag());
                  if (currentDecodeTagId < 4)
                  {
                      if (argExists[currentDecodeTagId])
                      {
                          ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
                          TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
                          break;
                      }
                      else
                      {
                          argExists[currentDecodeTagId] = true;
                          validArgumentCount++;
                      }
                  }
                  switch (currentDecodeTagId)
                  {
                  case 0:
                      TLVUnpackError = aDataTlv.Get(rateX);
                      break;
                  case 1:
                      TLVUnpackError = aDataTlv.Get(rateY);
                      break;
                  case 2:
                      TLVUnpackError = aDataTlv.Get(optionsMask);
                      break;
                  case 3:
                      TLVUnpackError = aDataTlv.Get(optionsOverride);
                      break;
                  default:
                      // Unsupported tag, ignore it.
                      ChipLogProgress(Zcl, "Unknown TLV tag during processing.");
                      break;
                  }
                  if (CHIP_NO_ERROR != TLVUnpackError)
                  {
                      break;
                  }
              }
  
              if (CHIP_END_OF_TLV == TLVError)
              {
                  // CHIP_END_OF_TLV means we have iterated all items in the structure, which is not a real error.
                  TLVError = CHIP_NO_ERROR;
              }
  
              if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 4 == validArgumentCount)
              {
                  wasHandled = emberAfColorControlClusterMoveColorCallback(aEndpointId, apCommandObj, rateX, rateY, optionsMask,
                                                                           optionsOverride);
              }
              break;
          }
          case Clusters::ColorControl::Commands::Ids::MoveColorTemperature: {
              expectArgumentCount = 6;
              uint8_t moveMode;
              uint16_t rate;
              uint16_t colorTemperatureMinimum;
              uint16_t colorTemperatureMaximum;
              uint8_t optionsMask;
              uint8_t optionsOverride;
              bool argExists[6];
  
              memset(argExists, 0, sizeof argExists);
  
              while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR)
              {
                  // Since call to aDataTlv.Next() is CHIP_NO_ERROR, the read head always points to an element.
                  // Skip this element if it is not a ContextTag, not consider it as an error if other values are valid.
                  if (!TLV::IsContextTag(aDataTlv.GetTag()))
                  {
                      continue;
                  }
                  currentDecodeTagId = TLV::TagNumFromTag(aDataTlv.GetTag());
                  if (currentDecodeTagId < 6)
                  {
                      if (argExists[currentDecodeTagId])
                      {
                          ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
                          TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
                          break;
                      }
                      else
                      {
                          argExists[currentDecodeTagId] = true;
                          validArgumentCount++;
                      }
                  }
                  switch (currentDecodeTagId)
                  {
                  case 0:
                      TLVUnpackError = aDataTlv.Get(moveMode);
                      break;
                  case 1:
                      TLVUnpackError = aDataTlv.Get(rate);
                      break;
                  case 2:
                      TLVUnpackError = aDataTlv.Get(colorTemperatureMinimum);
                      break;
                  case 3:
                      TLVUnpackError = aDataTlv.Get(colorTemperatureMaximum);
                      break;
                  case 4:
                      TLVUnpackError = aDataTlv.Get(optionsMask);
                      break;
                  case 5:
                      TLVUnpackError = aDataTlv.Get(optionsOverride);
                      break;
                  default:
                      // Unsupported tag, ignore it.
                      ChipLogProgress(Zcl, "Unknown TLV tag during processing.");
                      break;
                  }
                  if (CHIP_NO_ERROR != TLVUnpackError)
                  {
                      break;
                  }
              }
  
              if (CHIP_END_OF_TLV == TLVError)
              {
                  // CHIP_END_OF_TLV means we have iterated all items in the structure, which is not a real error.
                  TLVError = CHIP_NO_ERROR;
              }
  
              if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 6 == validArgumentCount)
              {
                  wasHandled = emberAfColorControlClusterMoveColorTemperatureCallback(
                      aEndpointId, apCommandObj, moveMode, rate, colorTemperatureMinimum, colorTemperatureMaximum, optionsMask,
                      optionsOverride);
              }
              break;
          }
          case Clusters::ColorControl::Commands::Ids::MoveHue: {
              expectArgumentCount = 4;
              uint8_t moveMode;
              uint8_t rate;
              uint8_t optionsMask;
              uint8_t optionsOverride;
              bool argExists[4];
  
              memset(argExists, 0, sizeof argExists);
  
              while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR)
              {
                  // Since call to aDataTlv.Next() is CHIP_NO_ERROR, the read head always points to an element.
                  // Skip this element if it is not a ContextTag, not consider it as an error if other values are valid.
                  if (!TLV::IsContextTag(aDataTlv.GetTag()))
                  {
                      continue;
                  }
                  currentDecodeTagId = TLV::TagNumFromTag(aDataTlv.GetTag());
                  if (currentDecodeTagId < 4)
                  {
                      if (argExists[currentDecodeTagId])
                      {
                          ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
                          TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
                          break;
                      }
                      else
                      {
                          argExists[currentDecodeTagId] = true;
                          validArgumentCount++;
                      }
                  }
                  switch (currentDecodeTagId)
                  {
                  case 0:
                      TLVUnpackError = aDataTlv.Get(moveMode);
                      break;
                  case 1:
                      TLVUnpackError = aDataTlv.Get(rate);
                      break;
                  case 2:
                      TLVUnpackError = aDataTlv.Get(optionsMask);
                      break;
                  case 3:
                      TLVUnpackError = aDataTlv.Get(optionsOverride);
                      break;
                  default:
                      // Unsupported tag, ignore it.
                      ChipLogProgress(Zcl, "Unknown TLV tag during processing.");
                      break;
                  }
                  if (CHIP_NO_ERROR != TLVUnpackError)
                  {
                      break;
                  }
              }
  
              if (CHIP_END_OF_TLV == TLVError)
              {
                  // CHIP_END_OF_TLV means we have iterated all items in the structure, which is not a real error.
                  TLVError = CHIP_NO_ERROR;
              }
  
              if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 4 == validArgumentCount)
              {
                  wasHandled = emberAfColorControlClusterMoveHueCallback(aEndpointId, apCommandObj, moveMode, rate, optionsMask,
                                                                         optionsOverride);
              }
              break;
          }
          case Clusters::ColorControl::Commands::Ids::MoveSaturation: {
              expectArgumentCount = 4;
              uint8_t moveMode;
              uint8_t rate;
              uint8_t optionsMask;
              uint8_t optionsOverride;
              bool argExists[4];
  
              memset(argExists, 0, sizeof argExists);
  
              while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR)
              {
                  // Since call to aDataTlv.Next() is CHIP_NO_ERROR, the read head always points to an element.
                  // Skip this element if it is not a ContextTag, not consider it as an error if other values are valid.
                  if (!TLV::IsContextTag(aDataTlv.GetTag()))
                  {
                      continue;
                  }
                  currentDecodeTagId = TLV::TagNumFromTag(aDataTlv.GetTag());
                  if (currentDecodeTagId < 4)
                  {
                      if (argExists[currentDecodeTagId])
                      {
                          ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
                          TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
                          break;
                      }
                      else
                      {
                          argExists[currentDecodeTagId] = true;
                          validArgumentCount++;
                      }
                  }
                  switch (currentDecodeTagId)
                  {
                  case 0:
                      TLVUnpackError = aDataTlv.Get(moveMode);
                      break;
                  case 1:
                      TLVUnpackError = aDataTlv.Get(rate);
                      break;
                  case 2:
                      TLVUnpackError = aDataTlv.Get(optionsMask);
                      break;
                  case 3:
                      TLVUnpackError = aDataTlv.Get(optionsOverride);
                      break;
                  default:
                      // Unsupported tag, ignore it.
                      ChipLogProgress(Zcl, "Unknown TLV tag during processing.");
                      break;
                  }
                  if (CHIP_NO_ERROR != TLVUnpackError)
                  {
                      break;
                  }
              }
  
              if (CHIP_END_OF_TLV == TLVError)
              {
                  // CHIP_END_OF_TLV means we have iterated all items in the structure, which is not a real error.
                  TLVError = CHIP_NO_ERROR;
              }
  
              if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 4 == validArgumentCount)
              {
                  wasHandled = emberAfColorControlClusterMoveSaturationCallback(aEndpointId, apCommandObj, moveMode, rate,
                                                                                optionsMask, optionsOverride);
              }
              break;
          }
          case Clusters::ColorControl::Commands::Ids::MoveToColor: {
              expectArgumentCount = 5;
              uint16_t colorX;
              uint16_t colorY;
              uint16_t transitionTime;
              uint8_t optionsMask;
              uint8_t optionsOverride;
              bool argExists[5];
  
              memset(argExists, 0, sizeof argExists);
  
              while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR)
              {
                  // Since call to aDataTlv.Next() is CHIP_NO_ERROR, the read head always points to an element.
                  // Skip this element if it is not a ContextTag, not consider it as an error if other values are valid.
                  if (!TLV::IsContextTag(aDataTlv.GetTag()))
                  {
                      continue;
                  }
                  currentDecodeTagId = TLV::TagNumFromTag(aDataTlv.GetTag());
                  if (currentDecodeTagId < 5)
                  {
                      if (argExists[currentDecodeTagId])
                      {
                          ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
                          TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
                          break;
                      }
                      else
                      {
                          argExists[currentDecodeTagId] = true;
                          validArgumentCount++;
                      }
                  }
                  switch (currentDecodeTagId)
                  {
                  case 0:
                      TLVUnpackError = aDataTlv.Get(colorX);
                      break;
                  case 1:
                      TLVUnpackError = aDataTlv.Get(colorY);
                      break;
                  case 2:
                      TLVUnpackError = aDataTlv.Get(transitionTime);
                      break;
                  case 3:
                      TLVUnpackError = aDataTlv.Get(optionsMask);
                      break;
                  case 4:
                      TLVUnpackError = aDataTlv.Get(optionsOverride);
                      break;
                  default:
                      // Unsupported tag, ignore it.
                      ChipLogProgress(Zcl, "Unknown TLV tag during processing.");
                      break;
                  }
                  if (CHIP_NO_ERROR != TLVUnpackError)
                  {
                      break;
                  }
              }
  
              if (CHIP_END_OF_TLV == TLVError)
              {
                  // CHIP_END_OF_TLV means we have iterated all items in the structure, which is not a real error.
                  TLVError = CHIP_NO_ERROR;
              }
  
              if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 5 == validArgumentCount)
              {
                  wasHandled = emberAfColorControlClusterMoveToColorCallback(aEndpointId, apCommandObj, colorX, colorY,
                                                                             transitionTime, optionsMask, optionsOverride);
              }
              break;
          }
          case Clusters::ColorControl::Commands::Ids::MoveToColorTemperature: {
              expectArgumentCount = 4;
              uint16_t colorTemperature;
              uint16_t transitionTime;
              uint8_t optionsMask;
              uint8_t optionsOverride;
              bool argExists[4];
  
              memset(argExists, 0, sizeof argExists);
  
              while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR)
              {
                  // Since call to aDataTlv.Next() is CHIP_NO_ERROR, the read head always points to an element.
                  // Skip this element if it is not a ContextTag, not consider it as an error if other values are valid.
                  if (!TLV::IsContextTag(aDataTlv.GetTag()))
                  {
                      continue;
                  }
                  currentDecodeTagId = TLV::TagNumFromTag(aDataTlv.GetTag());
                  if (currentDecodeTagId < 4)
                  {
                      if (argExists[currentDecodeTagId])
                      {
                          ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
                          TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
                          break;
                      }
                      else
                      {
                          argExists[currentDecodeTagId] = true;
                          validArgumentCount++;
                      }
                  }
                  switch (currentDecodeTagId)
                  {
                  case 0:
                      TLVUnpackError = aDataTlv.Get(colorTemperature);
                      break;
                  case 1:
                      TLVUnpackError = aDataTlv.Get(transitionTime);
                      break;
                  case 2:
                      TLVUnpackError = aDataTlv.Get(optionsMask);
                      break;
                  case 3:
                      TLVUnpackError = aDataTlv.Get(optionsOverride);
                      break;
                  default:
                      // Unsupported tag, ignore it.
                      ChipLogProgress(Zcl, "Unknown TLV tag during processing.");
                      break;
                  }
                  if (CHIP_NO_ERROR != TLVUnpackError)
                  {
                      break;
                  }
              }
  
              if (CHIP_END_OF_TLV == TLVError)
              {
                  // CHIP_END_OF_TLV means we have iterated all items in the structure, which is not a real error.
                  TLVError = CHIP_NO_ERROR;
              }
  
              if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 4 == validArgumentCount)
              {
                  wasHandled = emberAfColorControlClusterMoveToColorTemperatureCallback(aEndpointId, apCommandObj, colorTemperature,
                                                                                        transitionTime, optionsMask, optionsOverride);
              }
              break;
          }
          case Clusters::ColorControl::Commands::Ids::MoveToHue: {
              expectArgumentCount = 5;
              uint8_t hue;
              uint8_t direction;
              uint16_t transitionTime;
              uint8_t optionsMask;
              uint8_t optionsOverride;
              bool argExists[5];
  
              memset(argExists, 0, sizeof argExists);
  
              while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR)
              {
                  // Since call to aDataTlv.Next() is CHIP_NO_ERROR, the read head always points to an element.
                  // Skip this element if it is not a ContextTag, not consider it as an error if other values are valid.
                  if (!TLV::IsContextTag(aDataTlv.GetTag()))
                  {
                      continue;
                  }
                  currentDecodeTagId = TLV::TagNumFromTag(aDataTlv.GetTag());
                  if (currentDecodeTagId < 5)
                  {
                      if (argExists[currentDecodeTagId])
                      {
                          ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
                          TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
                          break;
                      }
                      else
                      {
                          argExists[currentDecodeTagId] = true;
                          validArgumentCount++;
                      }
                  }
                  switch (currentDecodeTagId)
                  {
                  case 0:
                      TLVUnpackError = aDataTlv.Get(hue);
                      break;
                  case 1:
                      TLVUnpackError = aDataTlv.Get(direction);
                      break;
                  case 2:
                      TLVUnpackError = aDataTlv.Get(transitionTime);
                      break;
                  case 3:
                      TLVUnpackError = aDataTlv.Get(optionsMask);
                      break;
                  case 4:
                      TLVUnpackError = aDataTlv.Get(optionsOverride);
                      break;
                  default:
                      // Unsupported tag, ignore it.
                      ChipLogProgress(Zcl, "Unknown TLV tag during processing.");
                      break;
                  }
                  if (CHIP_NO_ERROR != TLVUnpackError)
                  {
                      break;
                  }
              }
  
              if (CHIP_END_OF_TLV == TLVError)
              {
                  // CHIP_END_OF_TLV means we have iterated all items in the structure, which is not a real error.
                  TLVError = CHIP_NO_ERROR;
              }
  
              if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 5 == validArgumentCount)
              {
                  wasHandled = emberAfColorControlClusterMoveToHueCallback(aEndpointId, apCommandObj, hue, direction, transitionTime,
                                                                           optionsMask, optionsOverride);
              }
              break;
          }
          case Clusters::ColorControl::Commands::Ids::MoveToHueAndSaturation: {
              expectArgumentCount = 5;
              uint8_t hue;
              uint8_t saturation;
              uint16_t transitionTime;
              uint8_t optionsMask;
              uint8_t optionsOverride;
              bool argExists[5];
  
              memset(argExists, 0, sizeof argExists);
  
              while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR)
              {
                  // Since call to aDataTlv.Next() is CHIP_NO_ERROR, the read head always points to an element.
                  // Skip this element if it is not a ContextTag, not consider it as an error if other values are valid.
                  if (!TLV::IsContextTag(aDataTlv.GetTag()))
                  {
                      continue;
                  }
                  currentDecodeTagId = TLV::TagNumFromTag(aDataTlv.GetTag());
                  if (currentDecodeTagId < 5)
                  {
                      if (argExists[currentDecodeTagId])
                      {
                          ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
                          TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
                          break;
                      }
                      else
                      {
                          argExists[currentDecodeTagId] = true;
                          validArgumentCount++;
                      }
                  }
                  switch (currentDecodeTagId)
                  {
                  case 0:
                      TLVUnpackError = aDataTlv.Get(hue);
                      break;
                  case 1:
                      TLVUnpackError = aDataTlv.Get(saturation);
                      break;
                  case 2:
                      TLVUnpackError = aDataTlv.Get(transitionTime);
                      break;
                  case 3:
                      TLVUnpackError = aDataTlv.Get(optionsMask);
                      break;
                  case 4:
                      TLVUnpackError = aDataTlv.Get(optionsOverride);
                      break;
                  default:
                      // Unsupported tag, ignore it.
                      ChipLogProgress(Zcl, "Unknown TLV tag during processing.");
                      break;
                  }
                  if (CHIP_NO_ERROR != TLVUnpackError)
                  {
                      break;
                  }
              }
  
              if (CHIP_END_OF_TLV == TLVError)
              {
                  // CHIP_END_OF_TLV means we have iterated all items in the structure, which is not a real error.
                  TLVError = CHIP_NO_ERROR;
              }
  
              if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 5 == validArgumentCount)
              {
                  wasHandled = emberAfColorControlClusterMoveToHueAndSaturationCallback(aEndpointId, apCommandObj, hue, saturation,
                                                                                        transitionTime, optionsMask, optionsOverride);
              }
              break;
          }
          case Clusters::ColorControl::Commands::Ids::MoveToSaturation: {
              expectArgumentCount = 4;
              uint8_t saturation;
              uint16_t transitionTime;
              uint8_t optionsMask;
              uint8_t optionsOverride;
              bool argExists[4];
  
              memset(argExists, 0, sizeof argExists);
  
              while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR)
              {
                  // Since call to aDataTlv.Next() is CHIP_NO_ERROR, the read head always points to an element.
                  // Skip this element if it is not a ContextTag, not consider it as an error if other values are valid.
                  if (!TLV::IsContextTag(aDataTlv.GetTag()))
                  {
                      continue;
                  }
                  currentDecodeTagId = TLV::TagNumFromTag(aDataTlv.GetTag());
                  if (currentDecodeTagId < 4)
                  {
                      if (argExists[currentDecodeTagId])
                      {
                          ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
                          TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
                          break;
                      }
                      else
                      {
                          argExists[currentDecodeTagId] = true;
                          validArgumentCount++;
                      }
                  }
                  switch (currentDecodeTagId)
                  {
                  case 0:
                      TLVUnpackError = aDataTlv.Get(saturation);
                      break;
                  case 1:
                      TLVUnpackError = aDataTlv.Get(transitionTime);
                      break;
                  case 2:
                      TLVUnpackError = aDataTlv.Get(optionsMask);
                      break;
                  case 3:
                      TLVUnpackError = aDataTlv.Get(optionsOverride);
                      break;
                  default:
                      // Unsupported tag, ignore it.
                      ChipLogProgress(Zcl, "Unknown TLV tag during processing.");
                      break;
                  }
                  if (CHIP_NO_ERROR != TLVUnpackError)
                  {
                      break;
                  }
              }
  
              if (CHIP_END_OF_TLV == TLVError)
              {
                  // CHIP_END_OF_TLV means we have iterated all items in the structure, which is not a real error.
                  TLVError = CHIP_NO_ERROR;
              }
  
              if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 4 == validArgumentCount)
              {
                  wasHandled = emberAfColorControlClusterMoveToSaturationCallback(aEndpointId, apCommandObj, saturation,
                                                                                  transitionTime, optionsMask, optionsOverride);
              }
              break;
          }
          case Clusters::ColorControl::Commands::Ids::StepColor: {
              expectArgumentCount = 5;
              int16_t stepX;
              int16_t stepY;
              uint16_t transitionTime;
              uint8_t optionsMask;
              uint8_t optionsOverride;
              bool argExists[5];
  
              memset(argExists, 0, sizeof argExists);
  
              while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR)
              {
                  // Since call to aDataTlv.Next() is CHIP_NO_ERROR, the read head always points to an element.
                  // Skip this element if it is not a ContextTag, not consider it as an error if other values are valid.
                  if (!TLV::IsContextTag(aDataTlv.GetTag()))
                  {
                      continue;
                  }
                  currentDecodeTagId = TLV::TagNumFromTag(aDataTlv.GetTag());
                  if (currentDecodeTagId < 5)
                  {
                      if (argExists[currentDecodeTagId])
                      {
                          ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
                          TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
                          break;
                      }
                      else
                      {
                          argExists[currentDecodeTagId] = true;
                          validArgumentCount++;
                      }
                  }
                  switch (currentDecodeTagId)
                  {
                  case 0:
                      TLVUnpackError = aDataTlv.Get(stepX);
                      break;
                  case 1:
                      TLVUnpackError = aDataTlv.Get(stepY);
                      break;
                  case 2:
                      TLVUnpackError = aDataTlv.Get(transitionTime);
                      break;
                  case 3:
                      TLVUnpackError = aDataTlv.Get(optionsMask);
                      break;
                  case 4:
                      TLVUnpackError = aDataTlv.Get(optionsOverride);
                      break;
                  default:
                      // Unsupported tag, ignore it.
                      ChipLogProgress(Zcl, "Unknown TLV tag during processing.");
                      break;
                  }
                  if (CHIP_NO_ERROR != TLVUnpackError)
                  {
                      break;
                  }
              }
  
              if (CHIP_END_OF_TLV == TLVError)
              {
                  // CHIP_END_OF_TLV means we have iterated all items in the structure, which is not a real error.
                  TLVError = CHIP_NO_ERROR;
              }
  
              if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 5 == validArgumentCount)
              {
                  wasHandled = emberAfColorControlClusterStepColorCallback(aEndpointId, apCommandObj, stepX, stepY, transitionTime,
                                                                           optionsMask, optionsOverride);
              }
              break;
          }
          case Clusters::ColorControl::Commands::Ids::StepColorTemperature: {
              expectArgumentCount = 7;
              uint8_t stepMode;
              uint16_t stepSize;
              uint16_t transitionTime;
              uint16_t colorTemperatureMinimum;
              uint16_t colorTemperatureMaximum;
              uint8_t optionsMask;
              uint8_t optionsOverride;
              bool argExists[7];
  
              memset(argExists, 0, sizeof argExists);
  
              while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR)
              {
                  // Since call to aDataTlv.Next() is CHIP_NO_ERROR, the read head always points to an element.
                  // Skip this element if it is not a ContextTag, not consider it as an error if other values are valid.
                  if (!TLV::IsContextTag(aDataTlv.GetTag()))
                  {
                      continue;
                  }
                  currentDecodeTagId = TLV::TagNumFromTag(aDataTlv.GetTag());
                  if (currentDecodeTagId < 7)
                  {
                      if (argExists[currentDecodeTagId])
                      {
                          ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
                          TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
                          break;
                      }
                      else
                      {
                          argExists[currentDecodeTagId] = true;
                          validArgumentCount++;
                      }
                  }
                  switch (currentDecodeTagId)
                  {
                  case 0:
                      TLVUnpackError = aDataTlv.Get(stepMode);
                      break;
                  case 1:
                      TLVUnpackError = aDataTlv.Get(stepSize);
                      break;
                  case 2:
                      TLVUnpackError = aDataTlv.Get(transitionTime);
                      break;
                  case 3:
                      TLVUnpackError = aDataTlv.Get(colorTemperatureMinimum);
                      break;
                  case 4:
                      TLVUnpackError = aDataTlv.Get(colorTemperatureMaximum);
                      break;
                  case 5:
                      TLVUnpackError = aDataTlv.Get(optionsMask);
                      break;
                  case 6:
                      TLVUnpackError = aDataTlv.Get(optionsOverride);
                      break;
                  default:
                      // Unsupported tag, ignore it.
                      ChipLogProgress(Zcl, "Unknown TLV tag during processing.");
                      break;
                  }
                  if (CHIP_NO_ERROR != TLVUnpackError)
                  {
                      break;
                  }
              }
  
              if (CHIP_END_OF_TLV == TLVError)
              {
                  // CHIP_END_OF_TLV means we have iterated all items in the structure, which is not a real error.
                  TLVError = CHIP_NO_ERROR;
              }
  
              if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 7 == validArgumentCount)
              {
                  wasHandled = emberAfColorControlClusterStepColorTemperatureCallback(
                      aEndpointId, apCommandObj, stepMode, stepSize, transitionTime, colorTemperatureMinimum, colorTemperatureMaximum,
                      optionsMask, optionsOverride);
              }
              break;
          }
          case Clusters::ColorControl::Commands::Ids::StepHue: {
              expectArgumentCount = 5;
              uint8_t stepMode;
              uint8_t stepSize;
              uint8_t transitionTime;
              uint8_t optionsMask;
              uint8_t optionsOverride;
              bool argExists[5];
  
              memset(argExists, 0, sizeof argExists);
  
              while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR)
              {
                  // Since call to aDataTlv.Next() is CHIP_NO_ERROR, the read head always points to an element.
                  // Skip this element if it is not a ContextTag, not consider it as an error if other values are valid.
                  if (!TLV::IsContextTag(aDataTlv.GetTag()))
                  {
                      continue;
                  }
                  currentDecodeTagId = TLV::TagNumFromTag(aDataTlv.GetTag());
                  if (currentDecodeTagId < 5)
                  {
                      if (argExists[currentDecodeTagId])
                      {
                          ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
                          TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
                          break;
                      }
                      else
                      {
                          argExists[currentDecodeTagId] = true;
                          validArgumentCount++;
                      }
                  }
                  switch (currentDecodeTagId)
                  {
                  case 0:
                      TLVUnpackError = aDataTlv.Get(stepMode);
                      break;
                  case 1:
                      TLVUnpackError = aDataTlv.Get(stepSize);
                      break;
                  case 2:
                      TLVUnpackError = aDataTlv.Get(transitionTime);
                      break;
                  case 3:
                      TLVUnpackError = aDataTlv.Get(optionsMask);
                      break;
                  case 4:
                      TLVUnpackError = aDataTlv.Get(optionsOverride);
                      break;
                  default:
                      // Unsupported tag, ignore it.
                      ChipLogProgress(Zcl, "Unknown TLV tag during processing.");
                      break;
                  }
                  if (CHIP_NO_ERROR != TLVUnpackError)
                  {
                      break;
                  }
              }
  
              if (CHIP_END_OF_TLV == TLVError)
              {
                  // CHIP_END_OF_TLV means we have iterated all items in the structure, which is not a real error.
                  TLVError = CHIP_NO_ERROR;
              }
  
              if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 5 == validArgumentCount)
              {
                  wasHandled = emberAfColorControlClusterStepHueCallback(aEndpointId, apCommandObj, stepMode, stepSize,
                                                                         transitionTime, optionsMask, optionsOverride);
              }
              break;
          }
          case Clusters::ColorControl::Commands::Ids::StepSaturation: {
              expectArgumentCount = 5;
              uint8_t stepMode;
              uint8_t stepSize;
              uint8_t transitionTime;
              uint8_t optionsMask;
              uint8_t optionsOverride;
              bool argExists[5];
  
              memset(argExists, 0, sizeof argExists);
  
              while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR)
              {
                  // Since call to aDataTlv.Next() is CHIP_NO_ERROR, the read head always points to an element.
                  // Skip this element if it is not a ContextTag, not consider it as an error if other values are valid.
                  if (!TLV::IsContextTag(aDataTlv.GetTag()))
                  {
                      continue;
                  }
                  currentDecodeTagId = TLV::TagNumFromTag(aDataTlv.GetTag());
                  if (currentDecodeTagId < 5)
                  {
                      if (argExists[currentDecodeTagId])
                      {
                          ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
                          TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
                          break;
                      }
                      else
                      {
                          argExists[currentDecodeTagId] = true;
                          validArgumentCount++;
                      }
                  }
                  switch (currentDecodeTagId)
                  {
                  case 0:
                      TLVUnpackError = aDataTlv.Get(stepMode);
                      break;
                  case 1:
                      TLVUnpackError = aDataTlv.Get(stepSize);
                      break;
                  case 2:
                      TLVUnpackError = aDataTlv.Get(transitionTime);
                      break;
                  case 3:
                      TLVUnpackError = aDataTlv.Get(optionsMask);
                      break;
                  case 4:
                      TLVUnpackError = aDataTlv.Get(optionsOverride);
                      break;
                  default:
                      // Unsupported tag, ignore it.
                      ChipLogProgress(Zcl, "Unknown TLV tag during processing.");
                      break;
                  }
                  if (CHIP_NO_ERROR != TLVUnpackError)
                  {
                      break;
                  }
              }
  
              if (CHIP_END_OF_TLV == TLVError)
              {
                  // CHIP_END_OF_TLV means we have iterated all items in the structure, which is not a real error.
                  TLVError = CHIP_NO_ERROR;
              }
  
              if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 5 == validArgumentCount)
              {
                  wasHandled = emberAfColorControlClusterStepSaturationCallback(aEndpointId, apCommandObj, stepMode, stepSize,
                                                                                transitionTime, optionsMask, optionsOverride);
              }
              break;
          }
          case Clusters::ColorControl::Commands::Ids::StopMoveStep: {
              expectArgumentCount = 2;
              uint8_t optionsMask;
              uint8_t optionsOverride;
              bool argExists[2];
  
              memset(argExists, 0, sizeof argExists);
  
              while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR)
              {
                  // Since call to aDataTlv.Next() is CHIP_NO_ERROR, the read head always points to an element.
                  // Skip this element if it is not a ContextTag, not consider it as an error if other values are valid.
                  if (!TLV::IsContextTag(aDataTlv.GetTag()))
                  {
                      continue;
                  }
                  currentDecodeTagId = TLV::TagNumFromTag(aDataTlv.GetTag());
                  if (currentDecodeTagId < 2)
                  {
                      if (argExists[currentDecodeTagId])
                      {
                          ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
                          TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
                          break;
                      }
                      else
                      {
                          argExists[currentDecodeTagId] = true;
                          validArgumentCount++;
                      }
                  }
                  switch (currentDecodeTagId)
                  {
                  case 0:
                      TLVUnpackError = aDataTlv.Get(optionsMask);
                      break;
                  case 1:
                      TLVUnpackError = aDataTlv.Get(optionsOverride);
                      break;
                  default:
                      // Unsupported tag, ignore it.
                      ChipLogProgress(Zcl, "Unknown TLV tag during processing.");
                      break;
                  }
                  if (CHIP_NO_ERROR != TLVUnpackError)
                  {
                      break;
                  }
              }
  
              if (CHIP_END_OF_TLV == TLVError)
              {
                  // CHIP_END_OF_TLV means we have iterated all items in the structure, which is not a real error.
                  TLVError = CHIP_NO_ERROR;
              }
  
              if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 2 == validArgumentCount)
              {
                  wasHandled =
                      emberAfColorControlClusterStopMoveStepCallback(aEndpointId, apCommandObj, optionsMask, optionsOverride);
              }
              break;
          }
          default: {
              // Unrecognized command ID, error status will apply.
              chip::app::CommandPathParams returnStatusParam = { aEndpointId,
                                                                 0, // GroupId
                                                                 Clusters::ColorControl::Id, aCommandId,
                                                                 (chip::app::CommandPathFlags::kEndpointIdValid) };
              apCommandObj->AddStatusCode(returnStatusParam, Protocols::SecureChannel::GeneralStatusCode::kNotFound,
                                          Protocols::SecureChannel::Id,
                                          Protocols::InteractionModel::ProtocolCode::UnsupportedCommand);
              ChipLogError(Zcl, "Unknown command %" PRIx32 " for cluster %" PRIx32, aCommandId, Clusters::ColorControl::Id);
              return;
          }
          }
      }
  
      if (CHIP_NO_ERROR != TLVError || CHIP_NO_ERROR != TLVUnpackError || expectArgumentCount != validArgumentCount || !wasHandled)
      {
          chip::app::CommandPathParams returnStatusParam = { aEndpointId,
                                                             0, // GroupId
                                                             Clusters::ColorControl::Id, aCommandId,
                                                             (chip::app::CommandPathFlags::kEndpointIdValid) };
          apCommandObj->AddStatusCode(returnStatusParam, Protocols::SecureChannel::GeneralStatusCode::kBadRequest,
                                      Protocols::SecureChannel::Id, Protocols::InteractionModel::ProtocolCode::InvalidCommand);
          ChipLogProgress(Zcl,
                          "Failed to dispatch command, %" PRIu32 "/%" PRIu32 " arguments parsed, TLVError=%" CHIP_ERROR_FORMAT
                          ", UnpackError=%" CHIP_ERROR_FORMAT " (last decoded tag = %" PRIu32,
                          validArgumentCount, expectArgumentCount, ChipError::FormatError(TLVError),
                          ChipError::FormatError(TLVUnpackError), currentDecodeTagId);
          // A command with no arguments would never write currentDecodeTagId.  If
          // progress logging is also disabled, it would look unused.  Silence that
          // warning.
          UNUSED_VAR(currentDecodeTagId);
      }
  }
  
  } // namespace ColorControl
  
  namespace DiagnosticLogs {
  
  void DispatchServerCommand(app::CommandHandler * apCommandObj, CommandId aCommandId, EndpointId aEndpointId,
                             TLV::TLVReader & aDataTlv)
  {
      // We are using TLVUnpackError and TLVError here since both of them can be CHIP_END_OF_TLV
      // When TLVError is CHIP_END_OF_TLV, it means we have iterated all of the items, which is not a real error.
      // Any error value TLVUnpackError means we have received an illegal value.
      // The following variables are used for all commands to save code size.
      CHIP_ERROR TLVError          = CHIP_NO_ERROR;
      CHIP_ERROR TLVUnpackError    = CHIP_NO_ERROR;
      uint32_t validArgumentCount  = 0;
      uint32_t expectArgumentCount = 0;
      uint32_t currentDecodeTagId  = 0;
      bool wasHandled              = false;
      {
          switch (aCommandId)
          {
          case Clusters::DiagnosticLogs::Commands::Ids::RetrieveLogsRequest: {
              expectArgumentCount = 3;
              uint8_t intent;
              uint8_t requestedProtocol;
              chip::ByteSpan transferFileDesignator;
              bool argExists[3];
  
              memset(argExists, 0, sizeof argExists);
  
              while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR)
              {
                  // Since call to aDataTlv.Next() is CHIP_NO_ERROR, the read head always points to an element.
                  // Skip this element if it is not a ContextTag, not consider it as an error if other values are valid.
                  if (!TLV::IsContextTag(aDataTlv.GetTag()))
                  {
                      continue;
                  }
                  currentDecodeTagId = TLV::TagNumFromTag(aDataTlv.GetTag());
                  if (currentDecodeTagId < 3)
                  {
                      if (argExists[currentDecodeTagId])
                      {
                          ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
                          TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
                          break;
                      }
                      else
                      {
                          argExists[currentDecodeTagId] = true;
                          validArgumentCount++;
                      }
                  }
                  switch (currentDecodeTagId)
                  {
                  case 0:
                      TLVUnpackError = aDataTlv.Get(intent);
                      break;
                  case 1:
                      TLVUnpackError = aDataTlv.Get(requestedProtocol);
                      break;
                  case 2: {
                      const uint8_t * data   = nullptr;
                      TLVUnpackError         = aDataTlv.GetDataPtr(data);
                      transferFileDesignator = chip::ByteSpan(data, aDataTlv.GetLength());
                  }
                  break;
                  default:
                      // Unsupported tag, ignore it.
                      ChipLogProgress(Zcl, "Unknown TLV tag during processing.");
                      break;
                  }
                  if (CHIP_NO_ERROR != TLVUnpackError)
                  {
                      break;
                  }
              }
  
              if (CHIP_END_OF_TLV == TLVError)
              {
                  // CHIP_END_OF_TLV means we have iterated all items in the structure, which is not a real error.
                  TLVError = CHIP_NO_ERROR;
              }
  
              if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 3 == validArgumentCount)
              {
                  wasHandled = emberAfDiagnosticLogsClusterRetrieveLogsRequestCallback(aEndpointId, apCommandObj, intent,
                                                                                       requestedProtocol, transferFileDesignator);
              }
              break;
          }
          default: {
              // Unrecognized command ID, error status will apply.
              chip::app::CommandPathParams returnStatusParam = { aEndpointId,
                                                                 0, // GroupId
                                                                 Clusters::DiagnosticLogs::Id, aCommandId,
                                                                 (chip::app::CommandPathFlags::kEndpointIdValid) };
              apCommandObj->AddStatusCode(returnStatusParam, Protocols::SecureChannel::GeneralStatusCode::kNotFound,
                                          Protocols::SecureChannel::Id,
                                          Protocols::InteractionModel::ProtocolCode::UnsupportedCommand);
              ChipLogError(Zcl, "Unknown command %" PRIx32 " for cluster %" PRIx32, aCommandId, Clusters::DiagnosticLogs::Id);
              return;
          }
          }
      }
  
      if (CHIP_NO_ERROR != TLVError || CHIP_NO_ERROR != TLVUnpackError || expectArgumentCount != validArgumentCount || !wasHandled)
      {
          chip::app::CommandPathParams returnStatusParam = { aEndpointId,
                                                             0, // GroupId
                                                             Clusters::DiagnosticLogs::Id, aCommandId,
                                                             (chip::app::CommandPathFlags::kEndpointIdValid) };
          apCommandObj->AddStatusCode(returnStatusParam, Protocols::SecureChannel::GeneralStatusCode::kBadRequest,
                                      Protocols::SecureChannel::Id, Protocols::InteractionModel::ProtocolCode::InvalidCommand);
          ChipLogProgress(Zcl,
                          "Failed to dispatch command, %" PRIu32 "/%" PRIu32 " arguments parsed, TLVError=%" CHIP_ERROR_FORMAT
                          ", UnpackError=%" CHIP_ERROR_FORMAT " (last decoded tag = %" PRIu32,
                          validArgumentCount, expectArgumentCount, ChipError::FormatError(TLVError),
                          ChipError::FormatError(TLVUnpackError), currentDecodeTagId);
          // A command with no arguments would never write currentDecodeTagId.  If
          // progress logging is also disabled, it would look unused.  Silence that
          // warning.
          UNUSED_VAR(currentDecodeTagId);
      }
  }
  
  } // namespace DiagnosticLogs
  
  namespace DoorLock {
  
  void DispatchServerCommand(app::CommandHandler * apCommandObj, CommandId aCommandId, EndpointId aEndpointId,
                             TLV::TLVReader & aDataTlv)
  {
      // We are using TLVUnpackError and TLVError here since both of them can be CHIP_END_OF_TLV
      // When TLVError is CHIP_END_OF_TLV, it means we have iterated all of the items, which is not a real error.
      // Any error value TLVUnpackError means we have received an illegal value.
      // The following variables are used for all commands to save code size.
      CHIP_ERROR TLVError          = CHIP_NO_ERROR;
      CHIP_ERROR TLVUnpackError    = CHIP_NO_ERROR;
      uint32_t validArgumentCount  = 0;
      uint32_t expectArgumentCount = 0;
      uint32_t currentDecodeTagId  = 0;
      bool wasHandled              = false;
      {
          switch (aCommandId)
          {
          case Clusters::DoorLock::Commands::Ids::ClearAllPins: {
  
              wasHandled = emberAfDoorLockClusterClearAllPinsCallback(aEndpointId, apCommandObj);
              break;
          }
          case Clusters::DoorLock::Commands::Ids::ClearAllRfids: {
  
              wasHandled = emberAfDoorLockClusterClearAllRfidsCallback(aEndpointId, apCommandObj);
              break;
          }
          case Clusters::DoorLock::Commands::Ids::ClearHolidaySchedule: {
              expectArgumentCount = 1;
              uint8_t scheduleId;
              bool argExists[1];
  
              memset(argExists, 0, sizeof argExists);
  
              while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR)
              {
                  // Since call to aDataTlv.Next() is CHIP_NO_ERROR, the read head always points to an element.
                  // Skip this element if it is not a ContextTag, not consider it as an error if other values are valid.
                  if (!TLV::IsContextTag(aDataTlv.GetTag()))
                  {
                      continue;
                  }
                  currentDecodeTagId = TLV::TagNumFromTag(aDataTlv.GetTag());
                  if (currentDecodeTagId < 1)
                  {
                      if (argExists[currentDecodeTagId])
                      {
                          ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
                          TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
                          break;
                      }
                      else
                      {
                          argExists[currentDecodeTagId] = true;
                          validArgumentCount++;
                      }
                  }
                  switch (currentDecodeTagId)
                  {
                  case 0:
                      TLVUnpackError = aDataTlv.Get(scheduleId);
                      break;
                  default:
                      // Unsupported tag, ignore it.
                      ChipLogProgress(Zcl, "Unknown TLV tag during processing.");
                      break;
                  }
                  if (CHIP_NO_ERROR != TLVUnpackError)
                  {
                      break;
                  }
              }
  
              if (CHIP_END_OF_TLV == TLVError)
              {
                  // CHIP_END_OF_TLV means we have iterated all items in the structure, which is not a real error.
                  TLVError = CHIP_NO_ERROR;
              }
  
              if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 1 == validArgumentCount)
              {
                  wasHandled = emberAfDoorLockClusterClearHolidayScheduleCallback(aEndpointId, apCommandObj, scheduleId);
              }
              break;
          }
          case Clusters::DoorLock::Commands::Ids::ClearPin: {
              expectArgumentCount = 1;
              uint16_t userId;
              bool argExists[1];
  
              memset(argExists, 0, sizeof argExists);
  
              while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR)
              {
                  // Since call to aDataTlv.Next() is CHIP_NO_ERROR, the read head always points to an element.
                  // Skip this element if it is not a ContextTag, not consider it as an error if other values are valid.
                  if (!TLV::IsContextTag(aDataTlv.GetTag()))
                  {
                      continue;
                  }
                  currentDecodeTagId = TLV::TagNumFromTag(aDataTlv.GetTag());
                  if (currentDecodeTagId < 1)
                  {
                      if (argExists[currentDecodeTagId])
                      {
                          ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
                          TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
                          break;
                      }
                      else
                      {
                          argExists[currentDecodeTagId] = true;
                          validArgumentCount++;
                      }
                  }
                  switch (currentDecodeTagId)
                  {
                  case 0:
                      TLVUnpackError = aDataTlv.Get(userId);
                      break;
                  default:
                      // Unsupported tag, ignore it.
                      ChipLogProgress(Zcl, "Unknown TLV tag during processing.");
                      break;
                  }
                  if (CHIP_NO_ERROR != TLVUnpackError)
                  {
                      break;
                  }
              }
  
              if (CHIP_END_OF_TLV == TLVError)
              {
                  // CHIP_END_OF_TLV means we have iterated all items in the structure, which is not a real error.
                  TLVError = CHIP_NO_ERROR;
              }
  
              if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 1 == validArgumentCount)
              {
                  wasHandled = emberAfDoorLockClusterClearPinCallback(aEndpointId, apCommandObj, userId);
              }
              break;
          }
          case Clusters::DoorLock::Commands::Ids::ClearRfid: {
              expectArgumentCount = 1;
              uint16_t userId;
              bool argExists[1];
  
              memset(argExists, 0, sizeof argExists);
  
              while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR)
              {
                  // Since call to aDataTlv.Next() is CHIP_NO_ERROR, the read head always points to an element.
                  // Skip this element if it is not a ContextTag, not consider it as an error if other values are valid.
                  if (!TLV::IsContextTag(aDataTlv.GetTag()))
                  {
                      continue;
                  }
                  currentDecodeTagId = TLV::TagNumFromTag(aDataTlv.GetTag());
                  if (currentDecodeTagId < 1)
                  {
                      if (argExists[currentDecodeTagId])
                      {
                          ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
                          TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
                          break;
                      }
                      else
                      {
                          argExists[currentDecodeTagId] = true;
                          validArgumentCount++;
                      }
                  }
                  switch (currentDecodeTagId)
                  {
                  case 0:
                      TLVUnpackError = aDataTlv.Get(userId);
                      break;
                  default:
                      // Unsupported tag, ignore it.
                      ChipLogProgress(Zcl, "Unknown TLV tag during processing.");
                      break;
                  }
                  if (CHIP_NO_ERROR != TLVUnpackError)
                  {
                      break;
                  }
              }
  
              if (CHIP_END_OF_TLV == TLVError)
              {
                  // CHIP_END_OF_TLV means we have iterated all items in the structure, which is not a real error.
                  TLVError = CHIP_NO_ERROR;
              }
  
              if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 1 == validArgumentCount)
              {
                  wasHandled = emberAfDoorLockClusterClearRfidCallback(aEndpointId, apCommandObj, userId);
              }
              break;
          }
          case Clusters::DoorLock::Commands::Ids::ClearWeekdaySchedule: {
              expectArgumentCount = 2;
              uint8_t scheduleId;
              uint16_t userId;
              bool argExists[2];
  
              memset(argExists, 0, sizeof argExists);
  
              while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR)
              {
                  // Since call to aDataTlv.Next() is CHIP_NO_ERROR, the read head always points to an element.
                  // Skip this element if it is not a ContextTag, not consider it as an error if other values are valid.
                  if (!TLV::IsContextTag(aDataTlv.GetTag()))
                  {
                      continue;
                  }
                  currentDecodeTagId = TLV::TagNumFromTag(aDataTlv.GetTag());
                  if (currentDecodeTagId < 2)
                  {
                      if (argExists[currentDecodeTagId])
                      {
                          ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
                          TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
                          break;
                      }
                      else
                      {
                          argExists[currentDecodeTagId] = true;
                          validArgumentCount++;
                      }
                  }
                  switch (currentDecodeTagId)
                  {
                  case 0:
                      TLVUnpackError = aDataTlv.Get(scheduleId);
                      break;
                  case 1:
                      TLVUnpackError = aDataTlv.Get(userId);
                      break;
                  default:
                      // Unsupported tag, ignore it.
                      ChipLogProgress(Zcl, "Unknown TLV tag during processing.");
                      break;
                  }
                  if (CHIP_NO_ERROR != TLVUnpackError)
                  {
                      break;
                  }
              }
  
              if (CHIP_END_OF_TLV == TLVError)
              {
                  // CHIP_END_OF_TLV means we have iterated all items in the structure, which is not a real error.
                  TLVError = CHIP_NO_ERROR;
              }
  
              if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 2 == validArgumentCount)
              {
                  wasHandled = emberAfDoorLockClusterClearWeekdayScheduleCallback(aEndpointId, apCommandObj, scheduleId, userId);
              }
              break;
          }
          case Clusters::DoorLock::Commands::Ids::ClearYeardaySchedule: {
              expectArgumentCount = 2;
              uint8_t scheduleId;
              uint16_t userId;
              bool argExists[2];
  
              memset(argExists, 0, sizeof argExists);
  
              while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR)
              {
                  // Since call to aDataTlv.Next() is CHIP_NO_ERROR, the read head always points to an element.
                  // Skip this element if it is not a ContextTag, not consider it as an error if other values are valid.
                  if (!TLV::IsContextTag(aDataTlv.GetTag()))
                  {
                      continue;
                  }
                  currentDecodeTagId = TLV::TagNumFromTag(aDataTlv.GetTag());
                  if (currentDecodeTagId < 2)
                  {
                      if (argExists[currentDecodeTagId])
                      {
                          ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
                          TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
                          break;
                      }
                      else
                      {
                          argExists[currentDecodeTagId] = true;
                          validArgumentCount++;
                      }
                  }
                  switch (currentDecodeTagId)
                  {
                  case 0:
                      TLVUnpackError = aDataTlv.Get(scheduleId);
                      break;
                  case 1:
                      TLVUnpackError = aDataTlv.Get(userId);
                      break;
                  default:
                      // Unsupported tag, ignore it.
                      ChipLogProgress(Zcl, "Unknown TLV tag during processing.");
                      break;
                  }
                  if (CHIP_NO_ERROR != TLVUnpackError)
                  {
                      break;
                  }
              }
  
              if (CHIP_END_OF_TLV == TLVError)
              {
                  // CHIP_END_OF_TLV means we have iterated all items in the structure, which is not a real error.
                  TLVError = CHIP_NO_ERROR;
              }
  
              if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 2 == validArgumentCount)
              {
                  wasHandled = emberAfDoorLockClusterClearYeardayScheduleCallback(aEndpointId, apCommandObj, scheduleId, userId);
              }
              break;
          }
          case Clusters::DoorLock::Commands::Ids::GetHolidaySchedule: {
              expectArgumentCount = 1;
              uint8_t scheduleId;
              bool argExists[1];
  
              memset(argExists, 0, sizeof argExists);
  
              while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR)
              {
                  // Since call to aDataTlv.Next() is CHIP_NO_ERROR, the read head always points to an element.
                  // Skip this element if it is not a ContextTag, not consider it as an error if other values are valid.
                  if (!TLV::IsContextTag(aDataTlv.GetTag()))
                  {
                      continue;
                  }
                  currentDecodeTagId = TLV::TagNumFromTag(aDataTlv.GetTag());
                  if (currentDecodeTagId < 1)
                  {
                      if (argExists[currentDecodeTagId])
                      {
                          ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
                          TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
                          break;
                      }
                      else
                      {
                          argExists[currentDecodeTagId] = true;
                          validArgumentCount++;
                      }
                  }
                  switch (currentDecodeTagId)
                  {
                  case 0:
                      TLVUnpackError = aDataTlv.Get(scheduleId);
                      break;
                  default:
                      // Unsupported tag, ignore it.
                      ChipLogProgress(Zcl, "Unknown TLV tag during processing.");
                      break;
                  }
                  if (CHIP_NO_ERROR != TLVUnpackError)
                  {
                      break;
                  }
              }
  
              if (CHIP_END_OF_TLV == TLVError)
              {
                  // CHIP_END_OF_TLV means we have iterated all items in the structure, which is not a real error.
                  TLVError = CHIP_NO_ERROR;
              }
  
              if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 1 == validArgumentCount)
              {
                  wasHandled = emberAfDoorLockClusterGetHolidayScheduleCallback(aEndpointId, apCommandObj, scheduleId);
              }
              break;
          }
          case Clusters::DoorLock::Commands::Ids::GetLogRecord: {
              expectArgumentCount = 1;
              uint16_t logIndex;
              bool argExists[1];
  
              memset(argExists, 0, sizeof argExists);
  
              while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR)
              {
                  // Since call to aDataTlv.Next() is CHIP_NO_ERROR, the read head always points to an element.
                  // Skip this element if it is not a ContextTag, not consider it as an error if other values are valid.
                  if (!TLV::IsContextTag(aDataTlv.GetTag()))
                  {
                      continue;
                  }
                  currentDecodeTagId = TLV::TagNumFromTag(aDataTlv.GetTag());
                  if (currentDecodeTagId < 1)
                  {
                      if (argExists[currentDecodeTagId])
                      {
                          ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
                          TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
                          break;
                      }
                      else
                      {
                          argExists[currentDecodeTagId] = true;
                          validArgumentCount++;
                      }
                  }
                  switch (currentDecodeTagId)
                  {
                  case 0:
                      TLVUnpackError = aDataTlv.Get(logIndex);
                      break;
                  default:
                      // Unsupported tag, ignore it.
                      ChipLogProgress(Zcl, "Unknown TLV tag during processing.");
                      break;
                  }
                  if (CHIP_NO_ERROR != TLVUnpackError)
                  {
                      break;
                  }
              }
  
              if (CHIP_END_OF_TLV == TLVError)
              {
                  // CHIP_END_OF_TLV means we have iterated all items in the structure, which is not a real error.
                  TLVError = CHIP_NO_ERROR;
              }
  
              if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 1 == validArgumentCount)
              {
                  wasHandled = emberAfDoorLockClusterGetLogRecordCallback(aEndpointId, apCommandObj, logIndex);
              }
              break;
          }
          case Clusters::DoorLock::Commands::Ids::GetPin: {
              expectArgumentCount = 1;
              uint16_t userId;
              bool argExists[1];
  
              memset(argExists, 0, sizeof argExists);
  
              while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR)
              {
                  // Since call to aDataTlv.Next() is CHIP_NO_ERROR, the read head always points to an element.
                  // Skip this element if it is not a ContextTag, not consider it as an error if other values are valid.
                  if (!TLV::IsContextTag(aDataTlv.GetTag()))
                  {
                      continue;
                  }
                  currentDecodeTagId = TLV::TagNumFromTag(aDataTlv.GetTag());
                  if (currentDecodeTagId < 1)
                  {
                      if (argExists[currentDecodeTagId])
                      {
                          ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
                          TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
                          break;
                      }
                      else
                      {
                          argExists[currentDecodeTagId] = true;
                          validArgumentCount++;
                      }
                  }
                  switch (currentDecodeTagId)
                  {
                  case 0:
                      TLVUnpackError = aDataTlv.Get(userId);
                      break;
                  default:
                      // Unsupported tag, ignore it.
                      ChipLogProgress(Zcl, "Unknown TLV tag during processing.");
                      break;
                  }
                  if (CHIP_NO_ERROR != TLVUnpackError)
                  {
                      break;
                  }
              }
  
              if (CHIP_END_OF_TLV == TLVError)
              {
                  // CHIP_END_OF_TLV means we have iterated all items in the structure, which is not a real error.
                  TLVError = CHIP_NO_ERROR;
              }
  
              if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 1 == validArgumentCount)
              {
                  wasHandled = emberAfDoorLockClusterGetPinCallback(aEndpointId, apCommandObj, userId);
              }
              break;
          }
          case Clusters::DoorLock::Commands::Ids::GetRfid: {
              expectArgumentCount = 1;
              uint16_t userId;
              bool argExists[1];
  
              memset(argExists, 0, sizeof argExists);
  
              while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR)
              {
                  // Since call to aDataTlv.Next() is CHIP_NO_ERROR, the read head always points to an element.
                  // Skip this element if it is not a ContextTag, not consider it as an error if other values are valid.
                  if (!TLV::IsContextTag(aDataTlv.GetTag()))
                  {
                      continue;
                  }
                  currentDecodeTagId = TLV::TagNumFromTag(aDataTlv.GetTag());
                  if (currentDecodeTagId < 1)
                  {
                      if (argExists[currentDecodeTagId])
                      {
                          ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
                          TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
                          break;
                      }
                      else
                      {
                          argExists[currentDecodeTagId] = true;
                          validArgumentCount++;
                      }
                  }
                  switch (currentDecodeTagId)
                  {
                  case 0:
                      TLVUnpackError = aDataTlv.Get(userId);
                      break;
                  default:
                      // Unsupported tag, ignore it.
                      ChipLogProgress(Zcl, "Unknown TLV tag during processing.");
                      break;
                  }
                  if (CHIP_NO_ERROR != TLVUnpackError)
                  {
                      break;
                  }
              }
  
              if (CHIP_END_OF_TLV == TLVError)
              {
                  // CHIP_END_OF_TLV means we have iterated all items in the structure, which is not a real error.
                  TLVError = CHIP_NO_ERROR;
              }
  
              if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 1 == validArgumentCount)
              {
                  wasHandled = emberAfDoorLockClusterGetRfidCallback(aEndpointId, apCommandObj, userId);
              }
              break;
          }
          case Clusters::DoorLock::Commands::Ids::GetUserType: {
              expectArgumentCount = 1;
              uint16_t userId;
              bool argExists[1];
  
              memset(argExists, 0, sizeof argExists);
  
              while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR)
              {
                  // Since call to aDataTlv.Next() is CHIP_NO_ERROR, the read head always points to an element.
                  // Skip this element if it is not a ContextTag, not consider it as an error if other values are valid.
                  if (!TLV::IsContextTag(aDataTlv.GetTag()))
                  {
                      continue;
                  }
                  currentDecodeTagId = TLV::TagNumFromTag(aDataTlv.GetTag());
                  if (currentDecodeTagId < 1)
                  {
                      if (argExists[currentDecodeTagId])
                      {
                          ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
                          TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
                          break;
                      }
                      else
                      {
                          argExists[currentDecodeTagId] = true;
                          validArgumentCount++;
                      }
                  }
                  switch (currentDecodeTagId)
                  {
                  case 0:
                      TLVUnpackError = aDataTlv.Get(userId);
                      break;
                  default:
                      // Unsupported tag, ignore it.
                      ChipLogProgress(Zcl, "Unknown TLV tag during processing.");
                      break;
                  }
                  if (CHIP_NO_ERROR != TLVUnpackError)
                  {
                      break;
                  }
              }
  
              if (CHIP_END_OF_TLV == TLVError)
              {
                  // CHIP_END_OF_TLV means we have iterated all items in the structure, which is not a real error.
                  TLVError = CHIP_NO_ERROR;
              }
  
              if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 1 == validArgumentCount)
              {
                  wasHandled = emberAfDoorLockClusterGetUserTypeCallback(aEndpointId, apCommandObj, userId);
              }
              break;
          }
          case Clusters::DoorLock::Commands::Ids::GetWeekdaySchedule: {
              expectArgumentCount = 2;
              uint8_t scheduleId;
              uint16_t userId;
              bool argExists[2];
  
              memset(argExists, 0, sizeof argExists);
  
              while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR)
              {
                  // Since call to aDataTlv.Next() is CHIP_NO_ERROR, the read head always points to an element.
                  // Skip this element if it is not a ContextTag, not consider it as an error if other values are valid.
                  if (!TLV::IsContextTag(aDataTlv.GetTag()))
                  {
                      continue;
                  }
                  currentDecodeTagId = TLV::TagNumFromTag(aDataTlv.GetTag());
                  if (currentDecodeTagId < 2)
                  {
                      if (argExists[currentDecodeTagId])
                      {
                          ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
                          TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
                          break;
                      }
                      else
                      {
                          argExists[currentDecodeTagId] = true;
                          validArgumentCount++;
                      }
                  }
                  switch (currentDecodeTagId)
                  {
                  case 0:
                      TLVUnpackError = aDataTlv.Get(scheduleId);
                      break;
                  case 1:
                      TLVUnpackError = aDataTlv.Get(userId);
                      break;
                  default:
                      // Unsupported tag, ignore it.
                      ChipLogProgress(Zcl, "Unknown TLV tag during processing.");
                      break;
                  }
                  if (CHIP_NO_ERROR != TLVUnpackError)
                  {
                      break;
                  }
              }
  
              if (CHIP_END_OF_TLV == TLVError)
              {
                  // CHIP_END_OF_TLV means we have iterated all items in the structure, which is not a real error.
                  TLVError = CHIP_NO_ERROR;
              }
  
              if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 2 == validArgumentCount)
              {
                  wasHandled = emberAfDoorLockClusterGetWeekdayScheduleCallback(aEndpointId, apCommandObj, scheduleId, userId);
              }
              break;
          }
          case Clusters::DoorLock::Commands::Ids::GetYeardaySchedule: {
              expectArgumentCount = 2;
              uint8_t scheduleId;
              uint16_t userId;
              bool argExists[2];
  
              memset(argExists, 0, sizeof argExists);
  
              while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR)
              {
                  // Since call to aDataTlv.Next() is CHIP_NO_ERROR, the read head always points to an element.
                  // Skip this element if it is not a ContextTag, not consider it as an error if other values are valid.
                  if (!TLV::IsContextTag(aDataTlv.GetTag()))
                  {
                      continue;
                  }
                  currentDecodeTagId = TLV::TagNumFromTag(aDataTlv.GetTag());
                  if (currentDecodeTagId < 2)
                  {
                      if (argExists[currentDecodeTagId])
                      {
                          ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
                          TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
                          break;
                      }
                      else
                      {
                          argExists[currentDecodeTagId] = true;
                          validArgumentCount++;
                      }
                  }
                  switch (currentDecodeTagId)
                  {
                  case 0:
                      TLVUnpackError = aDataTlv.Get(scheduleId);
                      break;
                  case 1:
                      TLVUnpackError = aDataTlv.Get(userId);
                      break;
                  default:
                      // Unsupported tag, ignore it.
                      ChipLogProgress(Zcl, "Unknown TLV tag during processing.");
                      break;
                  }
                  if (CHIP_NO_ERROR != TLVUnpackError)
                  {
                      break;
                  }
              }
  
              if (CHIP_END_OF_TLV == TLVError)
              {
                  // CHIP_END_OF_TLV means we have iterated all items in the structure, which is not a real error.
                  TLVError = CHIP_NO_ERROR;
              }
  
              if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 2 == validArgumentCount)
              {
                  wasHandled = emberAfDoorLockClusterGetYeardayScheduleCallback(aEndpointId, apCommandObj, scheduleId, userId);
              }
              break;
          }
          case Clusters::DoorLock::Commands::Ids::LockDoor: {
              expectArgumentCount = 1;
              const uint8_t * PIN;
              bool argExists[1];
  
              memset(argExists, 0, sizeof argExists);
  
              while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR)
              {
                  // Since call to aDataTlv.Next() is CHIP_NO_ERROR, the read head always points to an element.
                  // Skip this element if it is not a ContextTag, not consider it as an error if other values are valid.
                  if (!TLV::IsContextTag(aDataTlv.GetTag()))
                  {
                      continue;
                  }
                  currentDecodeTagId = TLV::TagNumFromTag(aDataTlv.GetTag());
                  if (currentDecodeTagId < 1)
                  {
                      if (argExists[currentDecodeTagId])
                      {
                          ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
                          TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
                          break;
                      }
                      else
                      {
                          argExists[currentDecodeTagId] = true;
                          validArgumentCount++;
                      }
                  }
                  switch (currentDecodeTagId)
                  {
                  case 0:
                      // TODO(#5542): The cluster handlers should accept a ByteSpan for all string types.
                      TLVUnpackError = aDataTlv.GetDataPtr(PIN);
                      break;
                  default:
                      // Unsupported tag, ignore it.
                      ChipLogProgress(Zcl, "Unknown TLV tag during processing.");
                      break;
                  }
                  if (CHIP_NO_ERROR != TLVUnpackError)
                  {
                      break;
                  }
              }
  
              if (CHIP_END_OF_TLV == TLVError)
              {
                  // CHIP_END_OF_TLV means we have iterated all items in the structure, which is not a real error.
                  TLVError = CHIP_NO_ERROR;
              }
  
              if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 1 == validArgumentCount)
              {
                  wasHandled = emberAfDoorLockClusterLockDoorCallback(aEndpointId, apCommandObj, const_cast<uint8_t *>(PIN));
              }
              break;
          }
          case Clusters::DoorLock::Commands::Ids::SetHolidaySchedule: {
              expectArgumentCount = 4;
              uint8_t scheduleId;
              uint32_t localStartTime;
              uint32_t localEndTime;
              uint8_t operatingModeDuringHoliday;
              bool argExists[4];
  
              memset(argExists, 0, sizeof argExists);
  
              while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR)
              {
                  // Since call to aDataTlv.Next() is CHIP_NO_ERROR, the read head always points to an element.
                  // Skip this element if it is not a ContextTag, not consider it as an error if other values are valid.
                  if (!TLV::IsContextTag(aDataTlv.GetTag()))
                  {
                      continue;
                  }
                  currentDecodeTagId = TLV::TagNumFromTag(aDataTlv.GetTag());
                  if (currentDecodeTagId < 4)
                  {
                      if (argExists[currentDecodeTagId])
                      {
                          ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
                          TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
                          break;
                      }
                      else
                      {
                          argExists[currentDecodeTagId] = true;
                          validArgumentCount++;
                      }
                  }
                  switch (currentDecodeTagId)
                  {
                  case 0:
                      TLVUnpackError = aDataTlv.Get(scheduleId);
                      break;
                  case 1:
                      TLVUnpackError = aDataTlv.Get(localStartTime);
                      break;
                  case 2:
                      TLVUnpackError = aDataTlv.Get(localEndTime);
                      break;
                  case 3:
                      TLVUnpackError = aDataTlv.Get(operatingModeDuringHoliday);
                      break;
                  default:
                      // Unsupported tag, ignore it.
                      ChipLogProgress(Zcl, "Unknown TLV tag during processing.");
                      break;
                  }
                  if (CHIP_NO_ERROR != TLVUnpackError)
                  {
                      break;
                  }
              }
  
              if (CHIP_END_OF_TLV == TLVError)
              {
                  // CHIP_END_OF_TLV means we have iterated all items in the structure, which is not a real error.
                  TLVError = CHIP_NO_ERROR;
              }
  
              if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 4 == validArgumentCount)
              {
                  wasHandled = emberAfDoorLockClusterSetHolidayScheduleCallback(aEndpointId, apCommandObj, scheduleId, localStartTime,
                                                                                localEndTime, operatingModeDuringHoliday);
              }
              break;
          }
          case Clusters::DoorLock::Commands::Ids::SetPin: {
              expectArgumentCount = 4;
              uint16_t userId;
              uint8_t userStatus;
              uint8_t userType;
              const uint8_t * pin;
              bool argExists[4];
  
              memset(argExists, 0, sizeof argExists);
  
              while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR)
              {
                  // Since call to aDataTlv.Next() is CHIP_NO_ERROR, the read head always points to an element.
                  // Skip this element if it is not a ContextTag, not consider it as an error if other values are valid.
                  if (!TLV::IsContextTag(aDataTlv.GetTag()))
                  {
                      continue;
                  }
                  currentDecodeTagId = TLV::TagNumFromTag(aDataTlv.GetTag());
                  if (currentDecodeTagId < 4)
                  {
                      if (argExists[currentDecodeTagId])
                      {
                          ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
                          TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
                          break;
                      }
                      else
                      {
                          argExists[currentDecodeTagId] = true;
                          validArgumentCount++;
                      }
                  }
                  switch (currentDecodeTagId)
                  {
                  case 0:
                      TLVUnpackError = aDataTlv.Get(userId);
                      break;
                  case 1:
                      TLVUnpackError = aDataTlv.Get(userStatus);
                      break;
                  case 2:
                      TLVUnpackError = aDataTlv.Get(userType);
                      break;
                  case 3:
                      // TODO(#5542): The cluster handlers should accept a ByteSpan for all string types.
                      TLVUnpackError = aDataTlv.GetDataPtr(pin);
                      break;
                  default:
                      // Unsupported tag, ignore it.
                      ChipLogProgress(Zcl, "Unknown TLV tag during processing.");
                      break;
                  }
                  if (CHIP_NO_ERROR != TLVUnpackError)
                  {
                      break;
                  }
              }
  
              if (CHIP_END_OF_TLV == TLVError)
              {
                  // CHIP_END_OF_TLV means we have iterated all items in the structure, which is not a real error.
                  TLVError = CHIP_NO_ERROR;
              }
  
              if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 4 == validArgumentCount)
              {
                  wasHandled = emberAfDoorLockClusterSetPinCallback(aEndpointId, apCommandObj, userId, userStatus, userType,
                                                                    const_cast<uint8_t *>(pin));
              }
              break;
          }
          case Clusters::DoorLock::Commands::Ids::SetRfid: {
              expectArgumentCount = 4;
              uint16_t userId;
              uint8_t userStatus;
              uint8_t userType;
              const uint8_t * id;
              bool argExists[4];
  
              memset(argExists, 0, sizeof argExists);
  
              while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR)
              {
                  // Since call to aDataTlv.Next() is CHIP_NO_ERROR, the read head always points to an element.
                  // Skip this element if it is not a ContextTag, not consider it as an error if other values are valid.
                  if (!TLV::IsContextTag(aDataTlv.GetTag()))
                  {
                      continue;
                  }
                  currentDecodeTagId = TLV::TagNumFromTag(aDataTlv.GetTag());
                  if (currentDecodeTagId < 4)
                  {
                      if (argExists[currentDecodeTagId])
                      {
                          ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
                          TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
                          break;
                      }
                      else
                      {
                          argExists[currentDecodeTagId] = true;
                          validArgumentCount++;
                      }
                  }
                  switch (currentDecodeTagId)
                  {
                  case 0:
                      TLVUnpackError = aDataTlv.Get(userId);
                      break;
                  case 1:
                      TLVUnpackError = aDataTlv.Get(userStatus);
                      break;
                  case 2:
                      TLVUnpackError = aDataTlv.Get(userType);
                      break;
                  case 3:
                      // TODO(#5542): The cluster handlers should accept a ByteSpan for all string types.
                      TLVUnpackError = aDataTlv.GetDataPtr(id);
                      break;
                  default:
                      // Unsupported tag, ignore it.
                      ChipLogProgress(Zcl, "Unknown TLV tag during processing.");
                      break;
                  }
                  if (CHIP_NO_ERROR != TLVUnpackError)
                  {
                      break;
                  }
              }
  
              if (CHIP_END_OF_TLV == TLVError)
              {
                  // CHIP_END_OF_TLV means we have iterated all items in the structure, which is not a real error.
                  TLVError = CHIP_NO_ERROR;
              }
  
              if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 4 == validArgumentCount)
              {
                  wasHandled = emberAfDoorLockClusterSetRfidCallback(aEndpointId, apCommandObj, userId, userStatus, userType,
                                                                     const_cast<uint8_t *>(id));
              }
              break;
          }
          case Clusters::DoorLock::Commands::Ids::SetUserType: {
              expectArgumentCount = 2;
              uint16_t userId;
              uint8_t userType;
              bool argExists[2];
  
              memset(argExists, 0, sizeof argExists);
  
              while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR)
              {
                  // Since call to aDataTlv.Next() is CHIP_NO_ERROR, the read head always points to an element.
                  // Skip this element if it is not a ContextTag, not consider it as an error if other values are valid.
                  if (!TLV::IsContextTag(aDataTlv.GetTag()))
                  {
                      continue;
                  }
                  currentDecodeTagId = TLV::TagNumFromTag(aDataTlv.GetTag());
                  if (currentDecodeTagId < 2)
                  {
                      if (argExists[currentDecodeTagId])
                      {
                          ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
                          TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
                          break;
                      }
                      else
                      {
                          argExists[currentDecodeTagId] = true;
                          validArgumentCount++;
                      }
                  }
                  switch (currentDecodeTagId)
                  {
                  case 0:
                      TLVUnpackError = aDataTlv.Get(userId);
                      break;
                  case 1:
                      TLVUnpackError = aDataTlv.Get(userType);
                      break;
                  default:
                      // Unsupported tag, ignore it.
                      ChipLogProgress(Zcl, "Unknown TLV tag during processing.");
                      break;
                  }
                  if (CHIP_NO_ERROR != TLVUnpackError)
                  {
                      break;
                  }
              }
  
              if (CHIP_END_OF_TLV == TLVError)
              {
                  // CHIP_END_OF_TLV means we have iterated all items in the structure, which is not a real error.
                  TLVError = CHIP_NO_ERROR;
              }
  
              if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 2 == validArgumentCount)
              {
                  wasHandled = emberAfDoorLockClusterSetUserTypeCallback(aEndpointId, apCommandObj, userId, userType);
              }
              break;
          }
          case Clusters::DoorLock::Commands::Ids::SetWeekdaySchedule: {
              expectArgumentCount = 7;
              uint8_t scheduleId;
              uint16_t userId;
              uint8_t daysMask;
              uint8_t startHour;
              uint8_t startMinute;
              uint8_t endHour;
              uint8_t endMinute;
              bool argExists[7];
  
              memset(argExists, 0, sizeof argExists);
  
              while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR)
              {
                  // Since call to aDataTlv.Next() is CHIP_NO_ERROR, the read head always points to an element.
                  // Skip this element if it is not a ContextTag, not consider it as an error if other values are valid.
                  if (!TLV::IsContextTag(aDataTlv.GetTag()))
                  {
                      continue;
                  }
                  currentDecodeTagId = TLV::TagNumFromTag(aDataTlv.GetTag());
                  if (currentDecodeTagId < 7)
                  {
                      if (argExists[currentDecodeTagId])
                      {
                          ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
                          TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
                          break;
                      }
                      else
                      {
                          argExists[currentDecodeTagId] = true;
                          validArgumentCount++;
                      }
                  }
                  switch (currentDecodeTagId)
                  {
                  case 0:
                      TLVUnpackError = aDataTlv.Get(scheduleId);
                      break;
                  case 1:
                      TLVUnpackError = aDataTlv.Get(userId);
                      break;
                  case 2:
                      TLVUnpackError = aDataTlv.Get(daysMask);
                      break;
                  case 3:
                      TLVUnpackError = aDataTlv.Get(startHour);
                      break;
                  case 4:
                      TLVUnpackError = aDataTlv.Get(startMinute);
                      break;
                  case 5:
                      TLVUnpackError = aDataTlv.Get(endHour);
                      break;
                  case 6:
                      TLVUnpackError = aDataTlv.Get(endMinute);
                      break;
                  default:
                      // Unsupported tag, ignore it.
                      ChipLogProgress(Zcl, "Unknown TLV tag during processing.");
                      break;
                  }
                  if (CHIP_NO_ERROR != TLVUnpackError)
                  {
                      break;
                  }
              }
  
              if (CHIP_END_OF_TLV == TLVError)
              {
                  // CHIP_END_OF_TLV means we have iterated all items in the structure, which is not a real error.
                  TLVError = CHIP_NO_ERROR;
              }
  
              if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 7 == validArgumentCount)
              {
                  wasHandled = emberAfDoorLockClusterSetWeekdayScheduleCallback(aEndpointId, apCommandObj, scheduleId, userId,
                                                                                daysMask, startHour, startMinute, endHour, endMinute);
              }
              break;
          }
          case Clusters::DoorLock::Commands::Ids::SetYeardaySchedule: {
              expectArgumentCount = 4;
              uint8_t scheduleId;
              uint16_t userId;
              uint32_t localStartTime;
              uint32_t localEndTime;
              bool argExists[4];
  
              memset(argExists, 0, sizeof argExists);
  
              while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR)
              {
                  // Since call to aDataTlv.Next() is CHIP_NO_ERROR, the read head always points to an element.
                  // Skip this element if it is not a ContextTag, not consider it as an error if other values are valid.
                  if (!TLV::IsContextTag(aDataTlv.GetTag()))
                  {
                      continue;
                  }
                  currentDecodeTagId = TLV::TagNumFromTag(aDataTlv.GetTag());
                  if (currentDecodeTagId < 4)
                  {
                      if (argExists[currentDecodeTagId])
                      {
                          ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
                          TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
                          break;
                      }
                      else
                      {
                          argExists[currentDecodeTagId] = true;
                          validArgumentCount++;
                      }
                  }
                  switch (currentDecodeTagId)
                  {
                  case 0:
                      TLVUnpackError = aDataTlv.Get(scheduleId);
                      break;
                  case 1:
                      TLVUnpackError = aDataTlv.Get(userId);
                      break;
                  case 2:
                      TLVUnpackError = aDataTlv.Get(localStartTime);
                      break;
                  case 3:
                      TLVUnpackError = aDataTlv.Get(localEndTime);
                      break;
                  default:
                      // Unsupported tag, ignore it.
                      ChipLogProgress(Zcl, "Unknown TLV tag during processing.");
                      break;
                  }
                  if (CHIP_NO_ERROR != TLVUnpackError)
                  {
                      break;
                  }
              }
  
              if (CHIP_END_OF_TLV == TLVError)
              {
                  // CHIP_END_OF_TLV means we have iterated all items in the structure, which is not a real error.
                  TLVError = CHIP_NO_ERROR;
              }
  
              if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 4 == validArgumentCount)
              {
                  wasHandled = emberAfDoorLockClusterSetYeardayScheduleCallback(aEndpointId, apCommandObj, scheduleId, userId,
                                                                                localStartTime, localEndTime);
              }
              break;
          }
          case Clusters::DoorLock::Commands::Ids::UnlockDoor: {
              expectArgumentCount = 1;
              const uint8_t * PIN;
              bool argExists[1];
  
              memset(argExists, 0, sizeof argExists);
  
              while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR)
              {
                  // Since call to aDataTlv.Next() is CHIP_NO_ERROR, the read head always points to an element.
                  // Skip this element if it is not a ContextTag, not consider it as an error if other values are valid.
                  if (!TLV::IsContextTag(aDataTlv.GetTag()))
                  {
                      continue;
                  }
                  currentDecodeTagId = TLV::TagNumFromTag(aDataTlv.GetTag());
                  if (currentDecodeTagId < 1)
                  {
                      if (argExists[currentDecodeTagId])
                      {
                          ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
                          TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
                          break;
                      }
                      else
                      {
                          argExists[currentDecodeTagId] = true;
                          validArgumentCount++;
                      }
                  }
                  switch (currentDecodeTagId)
                  {
                  case 0:
                      // TODO(#5542): The cluster handlers should accept a ByteSpan for all string types.
                      TLVUnpackError = aDataTlv.GetDataPtr(PIN);
                      break;
                  default:
                      // Unsupported tag, ignore it.
                      ChipLogProgress(Zcl, "Unknown TLV tag during processing.");
                      break;
                  }
                  if (CHIP_NO_ERROR != TLVUnpackError)
                  {
                      break;
                  }
              }
  
              if (CHIP_END_OF_TLV == TLVError)
              {
                  // CHIP_END_OF_TLV means we have iterated all items in the structure, which is not a real error.
                  TLVError = CHIP_NO_ERROR;
              }
  
              if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 1 == validArgumentCount)
              {
                  wasHandled = emberAfDoorLockClusterUnlockDoorCallback(aEndpointId, apCommandObj, const_cast<uint8_t *>(PIN));
              }
              break;
          }
          case Clusters::DoorLock::Commands::Ids::UnlockWithTimeout: {
              expectArgumentCount = 2;
              uint16_t timeoutInSeconds;
              const uint8_t * pin;
              bool argExists[2];
  
              memset(argExists, 0, sizeof argExists);
  
              while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR)
              {
                  // Since call to aDataTlv.Next() is CHIP_NO_ERROR, the read head always points to an element.
                  // Skip this element if it is not a ContextTag, not consider it as an error if other values are valid.
                  if (!TLV::IsContextTag(aDataTlv.GetTag()))
                  {
                      continue;
                  }
                  currentDecodeTagId = TLV::TagNumFromTag(aDataTlv.GetTag());
                  if (currentDecodeTagId < 2)
                  {
                      if (argExists[currentDecodeTagId])
                      {
                          ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
                          TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
                          break;
                      }
                      else
                      {
                          argExists[currentDecodeTagId] = true;
                          validArgumentCount++;
                      }
                  }
                  switch (currentDecodeTagId)
                  {
                  case 0:
                      TLVUnpackError = aDataTlv.Get(timeoutInSeconds);
                      break;
                  case 1:
                      // TODO(#5542): The cluster handlers should accept a ByteSpan for all string types.
                      TLVUnpackError = aDataTlv.GetDataPtr(pin);
                      break;
                  default:
                      // Unsupported tag, ignore it.
                      ChipLogProgress(Zcl, "Unknown TLV tag during processing.");
                      break;
                  }
                  if (CHIP_NO_ERROR != TLVUnpackError)
                  {
                      break;
                  }
              }
  
              if (CHIP_END_OF_TLV == TLVError)
              {
                  // CHIP_END_OF_TLV means we have iterated all items in the structure, which is not a real error.
                  TLVError = CHIP_NO_ERROR;
              }
  
              if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 2 == validArgumentCount)
              {
                  wasHandled = emberAfDoorLockClusterUnlockWithTimeoutCallback(aEndpointId, apCommandObj, timeoutInSeconds,
                                                                               const_cast<uint8_t *>(pin));
              }
              break;
          }
          default: {
              // Unrecognized command ID, error status will apply.
              chip::app::CommandPathParams returnStatusParam = { aEndpointId,
                                                                 0, // GroupId
                                                                 Clusters::DoorLock::Id, aCommandId,
                                                                 (chip::app::CommandPathFlags::kEndpointIdValid) };
              apCommandObj->AddStatusCode(returnStatusParam, Protocols::SecureChannel::GeneralStatusCode::kNotFound,
                                          Protocols::SecureChannel::Id,
                                          Protocols::InteractionModel::ProtocolCode::UnsupportedCommand);
              ChipLogError(Zcl, "Unknown command %" PRIx32 " for cluster %" PRIx32, aCommandId, Clusters::DoorLock::Id);
              return;
          }
          }
      }
  
      if (CHIP_NO_ERROR != TLVError || CHIP_NO_ERROR != TLVUnpackError || expectArgumentCount != validArgumentCount || !wasHandled)
      {
          chip::app::CommandPathParams returnStatusParam = { aEndpointId,
                                                             0, // GroupId
                                                             Clusters::DoorLock::Id, aCommandId,
                                                             (chip::app::CommandPathFlags::kEndpointIdValid) };
          apCommandObj->AddStatusCode(returnStatusParam, Protocols::SecureChannel::GeneralStatusCode::kBadRequest,
                                      Protocols::SecureChannel::Id, Protocols::InteractionModel::ProtocolCode::InvalidCommand);
          ChipLogProgress(Zcl,
                          "Failed to dispatch command, %" PRIu32 "/%" PRIu32 " arguments parsed, TLVError=%" CHIP_ERROR_FORMAT
                          ", UnpackError=%" CHIP_ERROR_FORMAT " (last decoded tag = %" PRIu32,
                          validArgumentCount, expectArgumentCount, ChipError::FormatError(TLVError),
                          ChipError::FormatError(TLVUnpackError), currentDecodeTagId);
          // A command with no arguments would never write currentDecodeTagId.  If
          // progress logging is also disabled, it would look unused.  Silence that
          // warning.
          UNUSED_VAR(currentDecodeTagId);
      }
  }
  
  } // namespace DoorLock
  
  namespace EthernetNetworkDiagnostics {
  
  void DispatchServerCommand(app::CommandHandler * apCommandObj, CommandId aCommandId, EndpointId aEndpointId,
                             TLV::TLVReader & aDataTlv)
  {
      // We are using TLVUnpackError and TLVError here since both of them can be CHIP_END_OF_TLV
      // When TLVError is CHIP_END_OF_TLV, it means we have iterated all of the items, which is not a real error.
      // Any error value TLVUnpackError means we have received an illegal value.
      // The following variables are used for all commands to save code size.
      CHIP_ERROR TLVError          = CHIP_NO_ERROR;
      CHIP_ERROR TLVUnpackError    = CHIP_NO_ERROR;
      uint32_t validArgumentCount  = 0;
      uint32_t expectArgumentCount = 0;
      uint32_t currentDecodeTagId  = 0;
      bool wasHandled              = false;
      {
          switch (aCommandId)
          {
          case Clusters::EthernetNetworkDiagnostics::Commands::Ids::ResetCounts: {
  
              wasHandled = emberAfEthernetNetworkDiagnosticsClusterResetCountsCallback(aEndpointId, apCommandObj);
              break;
          }
          default: {
              // Unrecognized command ID, error status will apply.
              chip::app::CommandPathParams returnStatusParam = { aEndpointId,
                                                                 0, // GroupId
                                                                 Clusters::EthernetNetworkDiagnostics::Id, aCommandId,
                                                                 (chip::app::CommandPathFlags::kEndpointIdValid) };
              apCommandObj->AddStatusCode(returnStatusParam, Protocols::SecureChannel::GeneralStatusCode::kNotFound,
                                          Protocols::SecureChannel::Id,
                                          Protocols::InteractionModel::ProtocolCode::UnsupportedCommand);
              ChipLogError(Zcl, "Unknown command %" PRIx32 " for cluster %" PRIx32, aCommandId,
                           Clusters::EthernetNetworkDiagnostics::Id);
              return;
          }
          }
      }
  
      if (CHIP_NO_ERROR != TLVError || CHIP_NO_ERROR != TLVUnpackError || expectArgumentCount != validArgumentCount || !wasHandled)
      {
          chip::app::CommandPathParams returnStatusParam = { aEndpointId,
                                                             0, // GroupId
                                                             Clusters::EthernetNetworkDiagnostics::Id, aCommandId,
                                                             (chip::app::CommandPathFlags::kEndpointIdValid) };
          apCommandObj->AddStatusCode(returnStatusParam, Protocols::SecureChannel::GeneralStatusCode::kBadRequest,
                                      Protocols::SecureChannel::Id, Protocols::InteractionModel::ProtocolCode::InvalidCommand);
          ChipLogProgress(Zcl,
                          "Failed to dispatch command, %" PRIu32 "/%" PRIu32 " arguments parsed, TLVError=%" CHIP_ERROR_FORMAT
                          ", UnpackError=%" CHIP_ERROR_FORMAT " (last decoded tag = %" PRIu32,
                          validArgumentCount, expectArgumentCount, ChipError::FormatError(TLVError),
                          ChipError::FormatError(TLVUnpackError), currentDecodeTagId);
          // A command with no arguments would never write currentDecodeTagId.  If
          // progress logging is also disabled, it would look unused.  Silence that
          // warning.
          UNUSED_VAR(currentDecodeTagId);
      }
  }
  
  } // namespace EthernetNetworkDiagnostics
  
  namespace GeneralCommissioning {
  
  void DispatchServerCommand(app::CommandHandler * apCommandObj, CommandId aCommandId, EndpointId aEndpointId,
                             TLV::TLVReader & aDataTlv)
  {
      // We are using TLVUnpackError and TLVError here since both of them can be CHIP_END_OF_TLV
      // When TLVError is CHIP_END_OF_TLV, it means we have iterated all of the items, which is not a real error.
      // Any error value TLVUnpackError means we have received an illegal value.
      // The following variables are used for all commands to save code size.
      CHIP_ERROR TLVError          = CHIP_NO_ERROR;
      CHIP_ERROR TLVUnpackError    = CHIP_NO_ERROR;
      uint32_t validArgumentCount  = 0;
      uint32_t expectArgumentCount = 0;
      uint32_t currentDecodeTagId  = 0;
      bool wasHandled              = false;
      {
          switch (aCommandId)
          {
          case Clusters::GeneralCommissioning::Commands::Ids::ArmFailSafe: {
              expectArgumentCount = 3;
              uint16_t expiryLengthSeconds;
              uint64_t breadcrumb;
              uint32_t timeoutMs;
              bool argExists[3];
  
              memset(argExists, 0, sizeof argExists);
  
              while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR)
              {
                  // Since call to aDataTlv.Next() is CHIP_NO_ERROR, the read head always points to an element.
                  // Skip this element if it is not a ContextTag, not consider it as an error if other values are valid.
                  if (!TLV::IsContextTag(aDataTlv.GetTag()))
                  {
                      continue;
                  }
                  currentDecodeTagId = TLV::TagNumFromTag(aDataTlv.GetTag());
                  if (currentDecodeTagId < 3)
                  {
                      if (argExists[currentDecodeTagId])
                      {
                          ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
                          TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
                          break;
                      }
                      else
                      {
                          argExists[currentDecodeTagId] = true;
                          validArgumentCount++;
                      }
                  }
                  switch (currentDecodeTagId)
                  {
                  case 0:
                      TLVUnpackError = aDataTlv.Get(expiryLengthSeconds);
                      break;
                  case 1:
                      TLVUnpackError = aDataTlv.Get(breadcrumb);
                      break;
                  case 2:
                      TLVUnpackError = aDataTlv.Get(timeoutMs);
                      break;
                  default:
                      // Unsupported tag, ignore it.
                      ChipLogProgress(Zcl, "Unknown TLV tag during processing.");
                      break;
                  }
                  if (CHIP_NO_ERROR != TLVUnpackError)
                  {
                      break;
                  }
              }
  
              if (CHIP_END_OF_TLV == TLVError)
              {
                  // CHIP_END_OF_TLV means we have iterated all items in the structure, which is not a real error.
                  TLVError = CHIP_NO_ERROR;
              }
  
              if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 3 == validArgumentCount)
              {
                  wasHandled = emberAfGeneralCommissioningClusterArmFailSafeCallback(aEndpointId, apCommandObj, expiryLengthSeconds,
                                                                                     breadcrumb, timeoutMs);
              }
              break;
          }
          case Clusters::GeneralCommissioning::Commands::Ids::CommissioningComplete: {
  
              wasHandled = emberAfGeneralCommissioningClusterCommissioningCompleteCallback(aEndpointId, apCommandObj);
              break;
          }
          case Clusters::GeneralCommissioning::Commands::Ids::SetRegulatoryConfig: {
              expectArgumentCount = 4;
              uint8_t location;
              const uint8_t * countryCode;
              uint64_t breadcrumb;
              uint32_t timeoutMs;
              bool argExists[4];
  
              memset(argExists, 0, sizeof argExists);
  
              while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR)
              {
                  // Since call to aDataTlv.Next() is CHIP_NO_ERROR, the read head always points to an element.
                  // Skip this element if it is not a ContextTag, not consider it as an error if other values are valid.
                  if (!TLV::IsContextTag(aDataTlv.GetTag()))
                  {
                      continue;
                  }
                  currentDecodeTagId = TLV::TagNumFromTag(aDataTlv.GetTag());
                  if (currentDecodeTagId < 4)
                  {
                      if (argExists[currentDecodeTagId])
                      {
                          ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
                          TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
                          break;
                      }
                      else
                      {
                          argExists[currentDecodeTagId] = true;
                          validArgumentCount++;
                      }
                  }
                  switch (currentDecodeTagId)
                  {
                  case 0:
                      TLVUnpackError = aDataTlv.Get(location);
                      break;
                  case 1:
                      // TODO(#5542): The cluster handlers should accept a ByteSpan for all string types.
                      TLVUnpackError = aDataTlv.GetDataPtr(countryCode);
                      break;
                  case 2:
                      TLVUnpackError = aDataTlv.Get(breadcrumb);
                      break;
                  case 3:
                      TLVUnpackError = aDataTlv.Get(timeoutMs);
                      break;
                  default:
                      // Unsupported tag, ignore it.
                      ChipLogProgress(Zcl, "Unknown TLV tag during processing.");
                      break;
                  }
                  if (CHIP_NO_ERROR != TLVUnpackError)
                  {
                      break;
                  }
              }
  
              if (CHIP_END_OF_TLV == TLVError)
              {
                  // CHIP_END_OF_TLV means we have iterated all items in the structure, which is not a real error.
                  TLVError = CHIP_NO_ERROR;
              }
  
              if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 4 == validArgumentCount)
              {
                  wasHandled = emberAfGeneralCommissioningClusterSetRegulatoryConfigCallback(
                      aEndpointId, apCommandObj, location, const_cast<uint8_t *>(countryCode), breadcrumb, timeoutMs);
              }
              break;
          }
          default: {
              // Unrecognized command ID, error status will apply.
              chip::app::CommandPathParams returnStatusParam = { aEndpointId,
                                                                 0, // GroupId
                                                                 Clusters::GeneralCommissioning::Id, aCommandId,
                                                                 (chip::app::CommandPathFlags::kEndpointIdValid) };
              apCommandObj->AddStatusCode(returnStatusParam, Protocols::SecureChannel::GeneralStatusCode::kNotFound,
                                          Protocols::SecureChannel::Id,
                                          Protocols::InteractionModel::ProtocolCode::UnsupportedCommand);
              ChipLogError(Zcl, "Unknown command %" PRIx32 " for cluster %" PRIx32, aCommandId, Clusters::GeneralCommissioning::Id);
              return;
          }
          }
      }
  
      if (CHIP_NO_ERROR != TLVError || CHIP_NO_ERROR != TLVUnpackError || expectArgumentCount != validArgumentCount || !wasHandled)
      {
          chip::app::CommandPathParams returnStatusParam = { aEndpointId,
                                                             0, // GroupId
                                                             Clusters::GeneralCommissioning::Id, aCommandId,
                                                             (chip::app::CommandPathFlags::kEndpointIdValid) };
          apCommandObj->AddStatusCode(returnStatusParam, Protocols::SecureChannel::GeneralStatusCode::kBadRequest,
                                      Protocols::SecureChannel::Id, Protocols::InteractionModel::ProtocolCode::InvalidCommand);
          ChipLogProgress(Zcl,
                          "Failed to dispatch command, %" PRIu32 "/%" PRIu32 " arguments parsed, TLVError=%" CHIP_ERROR_FORMAT
                          ", UnpackError=%" CHIP_ERROR_FORMAT " (last decoded tag = %" PRIu32,
                          validArgumentCount, expectArgumentCount, ChipError::FormatError(TLVError),
                          ChipError::FormatError(TLVUnpackError), currentDecodeTagId);
          // A command with no arguments would never write currentDecodeTagId.  If
          // progress logging is also disabled, it would look unused.  Silence that
          // warning.
          UNUSED_VAR(currentDecodeTagId);
      }
  }
  
  } // namespace GeneralCommissioning
  
  namespace Groups {
  
  void DispatchServerCommand(app::CommandHandler * apCommandObj, CommandId aCommandId, EndpointId aEndpointId,
                             TLV::TLVReader & aDataTlv)
  {
      // We are using TLVUnpackError and TLVError here since both of them can be CHIP_END_OF_TLV
      // When TLVError is CHIP_END_OF_TLV, it means we have iterated all of the items, which is not a real error.
      // Any error value TLVUnpackError means we have received an illegal value.
      // The following variables are used for all commands to save code size.
      CHIP_ERROR TLVError          = CHIP_NO_ERROR;
      CHIP_ERROR TLVUnpackError    = CHIP_NO_ERROR;
      uint32_t validArgumentCount  = 0;
      uint32_t expectArgumentCount = 0;
      uint32_t currentDecodeTagId  = 0;
      bool wasHandled              = false;
      {
          switch (aCommandId)
          {
          case Clusters::Groups::Commands::Ids::AddGroup: {
              expectArgumentCount = 2;
              uint16_t groupId;
              const uint8_t * groupName;
              bool argExists[2];
  
              memset(argExists, 0, sizeof argExists);
  
              while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR)
              {
                  // Since call to aDataTlv.Next() is CHIP_NO_ERROR, the read head always points to an element.
                  // Skip this element if it is not a ContextTag, not consider it as an error if other values are valid.
                  if (!TLV::IsContextTag(aDataTlv.GetTag()))
                  {
                      continue;
                  }
                  currentDecodeTagId = TLV::TagNumFromTag(aDataTlv.GetTag());
                  if (currentDecodeTagId < 2)
                  {
                      if (argExists[currentDecodeTagId])
                      {
                          ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
                          TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
                          break;
                      }
                      else
                      {
                          argExists[currentDecodeTagId] = true;
                          validArgumentCount++;
                      }
                  }
                  switch (currentDecodeTagId)
                  {
                  case 0:
                      TLVUnpackError = aDataTlv.Get(groupId);
                      break;
                  case 1:
                      // TODO(#5542): The cluster handlers should accept a ByteSpan for all string types.
                      TLVUnpackError = aDataTlv.GetDataPtr(groupName);
                      break;
                  default:
                      // Unsupported tag, ignore it.
                      ChipLogProgress(Zcl, "Unknown TLV tag during processing.");
                      break;
                  }
                  if (CHIP_NO_ERROR != TLVUnpackError)
                  {
                      break;
                  }
              }
  
              if (CHIP_END_OF_TLV == TLVError)
              {
                  // CHIP_END_OF_TLV means we have iterated all items in the structure, which is not a real error.
                  TLVError = CHIP_NO_ERROR;
              }
  
              if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 2 == validArgumentCount)
              {
                  wasHandled =
                      emberAfGroupsClusterAddGroupCallback(aEndpointId, apCommandObj, groupId, const_cast<uint8_t *>(groupName));
              }
              break;
          }
          case Clusters::Groups::Commands::Ids::AddGroupIfIdentifying: {
              expectArgumentCount = 2;
              uint16_t groupId;
              const uint8_t * groupName;
              bool argExists[2];
  
              memset(argExists, 0, sizeof argExists);
  
              while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR)
              {
                  // Since call to aDataTlv.Next() is CHIP_NO_ERROR, the read head always points to an element.
                  // Skip this element if it is not a ContextTag, not consider it as an error if other values are valid.
                  if (!TLV::IsContextTag(aDataTlv.GetTag()))
                  {
                      continue;
                  }
                  currentDecodeTagId = TLV::TagNumFromTag(aDataTlv.GetTag());
                  if (currentDecodeTagId < 2)
                  {
                      if (argExists[currentDecodeTagId])
                      {
                          ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
                          TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
                          break;
                      }
                      else
                      {
                          argExists[currentDecodeTagId] = true;
                          validArgumentCount++;
                      }
                  }
                  switch (currentDecodeTagId)
                  {
                  case 0:
                      TLVUnpackError = aDataTlv.Get(groupId);
                      break;
                  case 1:
                      // TODO(#5542): The cluster handlers should accept a ByteSpan for all string types.
                      TLVUnpackError = aDataTlv.GetDataPtr(groupName);
                      break;
                  default:
                      // Unsupported tag, ignore it.
                      ChipLogProgress(Zcl, "Unknown TLV tag during processing.");
                      break;
                  }
                  if (CHIP_NO_ERROR != TLVUnpackError)
                  {
                      break;
                  }
              }
  
              if (CHIP_END_OF_TLV == TLVError)
              {
                  // CHIP_END_OF_TLV means we have iterated all items in the structure, which is not a real error.
                  TLVError = CHIP_NO_ERROR;
              }
  
              if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 2 == validArgumentCount)
              {
                  wasHandled = emberAfGroupsClusterAddGroupIfIdentifyingCallback(aEndpointId, apCommandObj, groupId,
                                                                                 const_cast<uint8_t *>(groupName));
              }
              break;
          }
          case Clusters::Groups::Commands::Ids::GetGroupMembership: {
              expectArgumentCount = 2;
              uint8_t groupCount;
              /* TYPE WARNING: array array defaults to */ uint8_t * groupList;
              bool argExists[2];
  
              memset(argExists, 0, sizeof argExists);
  
              while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR)
              {
                  // Since call to aDataTlv.Next() is CHIP_NO_ERROR, the read head always points to an element.
                  // Skip this element if it is not a ContextTag, not consider it as an error if other values are valid.
                  if (!TLV::IsContextTag(aDataTlv.GetTag()))
                  {
                      continue;
                  }
                  currentDecodeTagId = TLV::TagNumFromTag(aDataTlv.GetTag());
                  if (currentDecodeTagId < 2)
                  {
                      if (argExists[currentDecodeTagId])
                      {
                          ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
                          TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
                          break;
                      }
                      else
                      {
                          argExists[currentDecodeTagId] = true;
                          validArgumentCount++;
                      }
                  }
                  switch (currentDecodeTagId)
                  {
                  case 0:
                      TLVUnpackError = aDataTlv.Get(groupCount);
                      break;
                  case 1:
                      // Just for compatibility, we will add array type support in IM later.
                      TLVUnpackError = aDataTlv.GetDataPtr(const_cast<const uint8_t *&>(groupList));
                      break;
                  default:
                      // Unsupported tag, ignore it.
                      ChipLogProgress(Zcl, "Unknown TLV tag during processing.");
                      break;
                  }
                  if (CHIP_NO_ERROR != TLVUnpackError)
                  {
                      break;
                  }
              }
  
              if (CHIP_END_OF_TLV == TLVError)
              {
                  // CHIP_END_OF_TLV means we have iterated all items in the structure, which is not a real error.
                  TLVError = CHIP_NO_ERROR;
              }
  
              if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 2 == validArgumentCount)
              {
                  wasHandled = emberAfGroupsClusterGetGroupMembershipCallback(aEndpointId, apCommandObj, groupCount, groupList);
              }
              break;
          }
          case Clusters::Groups::Commands::Ids::RemoveAllGroups: {
  
              wasHandled = emberAfGroupsClusterRemoveAllGroupsCallback(aEndpointId, apCommandObj);
              break;
          }
          case Clusters::Groups::Commands::Ids::RemoveGroup: {
              expectArgumentCount = 1;
              uint16_t groupId;
              bool argExists[1];
  
              memset(argExists, 0, sizeof argExists);
  
              while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR)
              {
                  // Since call to aDataTlv.Next() is CHIP_NO_ERROR, the read head always points to an element.
                  // Skip this element if it is not a ContextTag, not consider it as an error if other values are valid.
                  if (!TLV::IsContextTag(aDataTlv.GetTag()))
                  {
                      continue;
                  }
                  currentDecodeTagId = TLV::TagNumFromTag(aDataTlv.GetTag());
                  if (currentDecodeTagId < 1)
                  {
                      if (argExists[currentDecodeTagId])
                      {
                          ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
                          TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
                          break;
                      }
                      else
                      {
                          argExists[currentDecodeTagId] = true;
                          validArgumentCount++;
                      }
                  }
                  switch (currentDecodeTagId)
                  {
                  case 0:
                      TLVUnpackError = aDataTlv.Get(groupId);
                      break;
                  default:
                      // Unsupported tag, ignore it.
                      ChipLogProgress(Zcl, "Unknown TLV tag during processing.");
                      break;
                  }
                  if (CHIP_NO_ERROR != TLVUnpackError)
                  {
                      break;
                  }
              }
  
              if (CHIP_END_OF_TLV == TLVError)
              {
                  // CHIP_END_OF_TLV means we have iterated all items in the structure, which is not a real error.
                  TLVError = CHIP_NO_ERROR;
              }
  
              if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 1 == validArgumentCount)
              {
                  wasHandled = emberAfGroupsClusterRemoveGroupCallback(aEndpointId, apCommandObj, groupId);
              }
              break;
          }
          case Clusters::Groups::Commands::Ids::ViewGroup: {
              expectArgumentCount = 1;
              uint16_t groupId;
              bool argExists[1];
  
              memset(argExists, 0, sizeof argExists);
  
              while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR)
              {
                  // Since call to aDataTlv.Next() is CHIP_NO_ERROR, the read head always points to an element.
                  // Skip this element if it is not a ContextTag, not consider it as an error if other values are valid.
                  if (!TLV::IsContextTag(aDataTlv.GetTag()))
                  {
                      continue;
                  }
                  currentDecodeTagId = TLV::TagNumFromTag(aDataTlv.GetTag());
                  if (currentDecodeTagId < 1)
                  {
                      if (argExists[currentDecodeTagId])
                      {
                          ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
                          TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
                          break;
                      }
                      else
                      {
                          argExists[currentDecodeTagId] = true;
                          validArgumentCount++;
                      }
                  }
                  switch (currentDecodeTagId)
                  {
                  case 0:
                      TLVUnpackError = aDataTlv.Get(groupId);
                      break;
                  default:
                      // Unsupported tag, ignore it.
                      ChipLogProgress(Zcl, "Unknown TLV tag during processing.");
                      break;
                  }
                  if (CHIP_NO_ERROR != TLVUnpackError)
                  {
                      break;
                  }
              }
  
              if (CHIP_END_OF_TLV == TLVError)
              {
                  // CHIP_END_OF_TLV means we have iterated all items in the structure, which is not a real error.
                  TLVError = CHIP_NO_ERROR;
              }
  
              if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 1 == validArgumentCount)
              {
                  wasHandled = emberAfGroupsClusterViewGroupCallback(aEndpointId, apCommandObj, groupId);
              }
              break;
          }
          default: {
              // Unrecognized command ID, error status will apply.
              chip::app::CommandPathParams returnStatusParam = { aEndpointId,
                                                                 0, // GroupId
                                                                 Clusters::Groups::Id, aCommandId,
                                                                 (chip::app::CommandPathFlags::kEndpointIdValid) };
              apCommandObj->AddStatusCode(returnStatusParam, Protocols::SecureChannel::GeneralStatusCode::kNotFound,
                                          Protocols::SecureChannel::Id,
                                          Protocols::InteractionModel::ProtocolCode::UnsupportedCommand);
              ChipLogError(Zcl, "Unknown command %" PRIx32 " for cluster %" PRIx32, aCommandId, Clusters::Groups::Id);
              return;
          }
          }
      }
  
      if (CHIP_NO_ERROR != TLVError || CHIP_NO_ERROR != TLVUnpackError || expectArgumentCount != validArgumentCount || !wasHandled)
      {
          chip::app::CommandPathParams returnStatusParam = { aEndpointId,
                                                             0, // GroupId
                                                             Clusters::Groups::Id, aCommandId,
                                                             (chip::app::CommandPathFlags::kEndpointIdValid) };
          apCommandObj->AddStatusCode(returnStatusParam, Protocols::SecureChannel::GeneralStatusCode::kBadRequest,
                                      Protocols::SecureChannel::Id, Protocols::InteractionModel::ProtocolCode::InvalidCommand);
          ChipLogProgress(Zcl,
                          "Failed to dispatch command, %" PRIu32 "/%" PRIu32 " arguments parsed, TLVError=%" CHIP_ERROR_FORMAT
                          ", UnpackError=%" CHIP_ERROR_FORMAT " (last decoded tag = %" PRIu32,
                          validArgumentCount, expectArgumentCount, ChipError::FormatError(TLVError),
                          ChipError::FormatError(TLVUnpackError), currentDecodeTagId);
          // A command with no arguments would never write currentDecodeTagId.  If
          // progress logging is also disabled, it would look unused.  Silence that
          // warning.
          UNUSED_VAR(currentDecodeTagId);
      }
  }
  
  } // namespace Groups
  
  namespace IasZone {
  
  void DispatchServerCommand(app::CommandHandler * apCommandObj, CommandId aCommandId, EndpointId aEndpointId,
                             TLV::TLVReader & aDataTlv)
  {
      // We are using TLVUnpackError and TLVError here since both of them can be CHIP_END_OF_TLV
      // When TLVError is CHIP_END_OF_TLV, it means we have iterated all of the items, which is not a real error.
      // Any error value TLVUnpackError means we have received an illegal value.
      // The following variables are used for all commands to save code size.
      CHIP_ERROR TLVError          = CHIP_NO_ERROR;
      CHIP_ERROR TLVUnpackError    = CHIP_NO_ERROR;
      uint32_t validArgumentCount  = 0;
      uint32_t expectArgumentCount = 0;
      uint32_t currentDecodeTagId  = 0;
      bool wasHandled              = false;
      {
          switch (aCommandId)
          {
          case Clusters::IasZone::Commands::Ids::ZoneEnrollResponse: {
              expectArgumentCount = 2;
              uint8_t enrollResponseCode;
              uint8_t zoneId;
              bool argExists[2];
  
              memset(argExists, 0, sizeof argExists);
  
              while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR)
              {
                  // Since call to aDataTlv.Next() is CHIP_NO_ERROR, the read head always points to an element.
                  // Skip this element if it is not a ContextTag, not consider it as an error if other values are valid.
                  if (!TLV::IsContextTag(aDataTlv.GetTag()))
                  {
                      continue;
                  }
                  currentDecodeTagId = TLV::TagNumFromTag(aDataTlv.GetTag());
                  if (currentDecodeTagId < 2)
                  {
                      if (argExists[currentDecodeTagId])
                      {
                          ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
                          TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
                          break;
                      }
                      else
                      {
                          argExists[currentDecodeTagId] = true;
                          validArgumentCount++;
                      }
                  }
                  switch (currentDecodeTagId)
                  {
                  case 0:
                      TLVUnpackError = aDataTlv.Get(enrollResponseCode);
                      break;
                  case 1:
                      TLVUnpackError = aDataTlv.Get(zoneId);
                      break;
                  default:
                      // Unsupported tag, ignore it.
                      ChipLogProgress(Zcl, "Unknown TLV tag during processing.");
                      break;
                  }
                  if (CHIP_NO_ERROR != TLVUnpackError)
                  {
                      break;
                  }
              }
  
              if (CHIP_END_OF_TLV == TLVError)
              {
                  // CHIP_END_OF_TLV means we have iterated all items in the structure, which is not a real error.
                  TLVError = CHIP_NO_ERROR;
              }
  
              if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 2 == validArgumentCount)
              {
                  wasHandled = emberAfIasZoneClusterZoneEnrollResponseCallback(aEndpointId, apCommandObj, enrollResponseCode, zoneId);
              }
              break;
          }
          default: {
              // Unrecognized command ID, error status will apply.
              chip::app::CommandPathParams returnStatusParam = { aEndpointId,
                                                                 0, // GroupId
                                                                 Clusters::IasZone::Id, aCommandId,
                                                                 (chip::app::CommandPathFlags::kEndpointIdValid) };
              apCommandObj->AddStatusCode(returnStatusParam, Protocols::SecureChannel::GeneralStatusCode::kNotFound,
                                          Protocols::SecureChannel::Id,
                                          Protocols::InteractionModel::ProtocolCode::UnsupportedCommand);
              ChipLogError(Zcl, "Unknown command %" PRIx32 " for cluster %" PRIx32, aCommandId, Clusters::IasZone::Id);
              return;
          }
          }
      }
  
      if (CHIP_NO_ERROR != TLVError || CHIP_NO_ERROR != TLVUnpackError || expectArgumentCount != validArgumentCount || !wasHandled)
      {
          chip::app::CommandPathParams returnStatusParam = { aEndpointId,
                                                             0, // GroupId
                                                             Clusters::IasZone::Id, aCommandId,
                                                             (chip::app::CommandPathFlags::kEndpointIdValid) };
          apCommandObj->AddStatusCode(returnStatusParam, Protocols::SecureChannel::GeneralStatusCode::kBadRequest,
                                      Protocols::SecureChannel::Id, Protocols::InteractionModel::ProtocolCode::InvalidCommand);
          ChipLogProgress(Zcl,
                          "Failed to dispatch command, %" PRIu32 "/%" PRIu32 " arguments parsed, TLVError=%" CHIP_ERROR_FORMAT
                          ", UnpackError=%" CHIP_ERROR_FORMAT " (last decoded tag = %" PRIu32,
                          validArgumentCount, expectArgumentCount, ChipError::FormatError(TLVError),
                          ChipError::FormatError(TLVUnpackError), currentDecodeTagId);
          // A command with no arguments would never write currentDecodeTagId.  If
          // progress logging is also disabled, it would look unused.  Silence that
          // warning.
          UNUSED_VAR(currentDecodeTagId);
      }
  }
  
  } // namespace IasZone
  
  namespace Identify {
  
  void DispatchServerCommand(app::CommandHandler * apCommandObj, CommandId aCommandId, EndpointId aEndpointId,
                             TLV::TLVReader & aDataTlv)
  {
      // We are using TLVUnpackError and TLVError here since both of them can be CHIP_END_OF_TLV
      // When TLVError is CHIP_END_OF_TLV, it means we have iterated all of the items, which is not a real error.
      // Any error value TLVUnpackError means we have received an illegal value.
      // The following variables are used for all commands to save code size.
      CHIP_ERROR TLVError          = CHIP_NO_ERROR;
      CHIP_ERROR TLVUnpackError    = CHIP_NO_ERROR;
      uint32_t validArgumentCount  = 0;
      uint32_t expectArgumentCount = 0;
      uint32_t currentDecodeTagId  = 0;
      bool wasHandled              = false;
      {
          switch (aCommandId)
          {
          case Clusters::Identify::Commands::Ids::Identify: {
              expectArgumentCount = 1;
              uint16_t identifyTime;
              bool argExists[1];
  
              memset(argExists, 0, sizeof argExists);
  
              while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR)
              {
                  // Since call to aDataTlv.Next() is CHIP_NO_ERROR, the read head always points to an element.
                  // Skip this element if it is not a ContextTag, not consider it as an error if other values are valid.
                  if (!TLV::IsContextTag(aDataTlv.GetTag()))
                  {
                      continue;
                  }
                  currentDecodeTagId = TLV::TagNumFromTag(aDataTlv.GetTag());
                  if (currentDecodeTagId < 1)
                  {
                      if (argExists[currentDecodeTagId])
                      {
                          ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
                          TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
                          break;
                      }
                      else
                      {
                          argExists[currentDecodeTagId] = true;
                          validArgumentCount++;
                      }
                  }
                  switch (currentDecodeTagId)
                  {
                  case 0:
                      TLVUnpackError = aDataTlv.Get(identifyTime);
                      break;
                  default:
                      // Unsupported tag, ignore it.
                      ChipLogProgress(Zcl, "Unknown TLV tag during processing.");
                      break;
                  }
                  if (CHIP_NO_ERROR != TLVUnpackError)
                  {
                      break;
                  }
              }
  
              if (CHIP_END_OF_TLV == TLVError)
              {
                  // CHIP_END_OF_TLV means we have iterated all items in the structure, which is not a real error.
                  TLVError = CHIP_NO_ERROR;
              }
  
              if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 1 == validArgumentCount)
              {
                  wasHandled = emberAfIdentifyClusterIdentifyCallback(aEndpointId, apCommandObj, identifyTime);
              }
              break;
          }
          case Clusters::Identify::Commands::Ids::IdentifyQuery: {
  
              wasHandled = emberAfIdentifyClusterIdentifyQueryCallback(aEndpointId, apCommandObj);
              break;
          }
          default: {
              // Unrecognized command ID, error status will apply.
              chip::app::CommandPathParams returnStatusParam = { aEndpointId,
                                                                 0, // GroupId
                                                                 Clusters::Identify::Id, aCommandId,
                                                                 (chip::app::CommandPathFlags::kEndpointIdValid) };
              apCommandObj->AddStatusCode(returnStatusParam, Protocols::SecureChannel::GeneralStatusCode::kNotFound,
                                          Protocols::SecureChannel::Id,
                                          Protocols::InteractionModel::ProtocolCode::UnsupportedCommand);
              ChipLogError(Zcl, "Unknown command %" PRIx32 " for cluster %" PRIx32, aCommandId, Clusters::Identify::Id);
              return;
          }
          }
      }
  
      if (CHIP_NO_ERROR != TLVError || CHIP_NO_ERROR != TLVUnpackError || expectArgumentCount != validArgumentCount || !wasHandled)
      {
          chip::app::CommandPathParams returnStatusParam = { aEndpointId,
                                                             0, // GroupId
                                                             Clusters::Identify::Id, aCommandId,
                                                             (chip::app::CommandPathFlags::kEndpointIdValid) };
          apCommandObj->AddStatusCode(returnStatusParam, Protocols::SecureChannel::GeneralStatusCode::kBadRequest,
                                      Protocols::SecureChannel::Id, Protocols::InteractionModel::ProtocolCode::InvalidCommand);
          ChipLogProgress(Zcl,
                          "Failed to dispatch command, %" PRIu32 "/%" PRIu32 " arguments parsed, TLVError=%" CHIP_ERROR_FORMAT
                          ", UnpackError=%" CHIP_ERROR_FORMAT " (last decoded tag = %" PRIu32,
                          validArgumentCount, expectArgumentCount, ChipError::FormatError(TLVError),
                          ChipError::FormatError(TLVUnpackError), currentDecodeTagId);
          // A command with no arguments would never write currentDecodeTagId.  If
          // progress logging is also disabled, it would look unused.  Silence that
          // warning.
          UNUSED_VAR(currentDecodeTagId);
      }
  }
  
  } // namespace Identify
  
  namespace LevelControl {
  
  void DispatchServerCommand(app::CommandHandler * apCommandObj, CommandId aCommandId, EndpointId aEndpointId,
                             TLV::TLVReader & aDataTlv)
  {
      // We are using TLVUnpackError and TLVError here since both of them can be CHIP_END_OF_TLV
      // When TLVError is CHIP_END_OF_TLV, it means we have iterated all of the items, which is not a real error.
      // Any error value TLVUnpackError means we have received an illegal value.
      // The following variables are used for all commands to save code size.
      CHIP_ERROR TLVError          = CHIP_NO_ERROR;
      CHIP_ERROR TLVUnpackError    = CHIP_NO_ERROR;
      uint32_t validArgumentCount  = 0;
      uint32_t expectArgumentCount = 0;
      uint32_t currentDecodeTagId  = 0;
      bool wasHandled              = false;
      {
          switch (aCommandId)
          {
          case Clusters::LevelControl::Commands::Ids::Move: {
              expectArgumentCount = 4;
              uint8_t moveMode;
              uint8_t rate;
              uint8_t optionMask;
              uint8_t optionOverride;
              bool argExists[4];
  
              memset(argExists, 0, sizeof argExists);
  
              while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR)
              {
                  // Since call to aDataTlv.Next() is CHIP_NO_ERROR, the read head always points to an element.
                  // Skip this element if it is not a ContextTag, not consider it as an error if other values are valid.
                  if (!TLV::IsContextTag(aDataTlv.GetTag()))
                  {
                      continue;
                  }
                  currentDecodeTagId = TLV::TagNumFromTag(aDataTlv.GetTag());
                  if (currentDecodeTagId < 4)
                  {
                      if (argExists[currentDecodeTagId])
                      {
                          ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
                          TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
                          break;
                      }
                      else
                      {
                          argExists[currentDecodeTagId] = true;
                          validArgumentCount++;
                      }
                  }
                  switch (currentDecodeTagId)
                  {
                  case 0:
                      TLVUnpackError = aDataTlv.Get(moveMode);
                      break;
                  case 1:
                      TLVUnpackError = aDataTlv.Get(rate);
                      break;
                  case 2:
                      TLVUnpackError = aDataTlv.Get(optionMask);
                      break;
                  case 3:
                      TLVUnpackError = aDataTlv.Get(optionOverride);
                      break;
                  default:
                      // Unsupported tag, ignore it.
                      ChipLogProgress(Zcl, "Unknown TLV tag during processing.");
                      break;
                  }
                  if (CHIP_NO_ERROR != TLVUnpackError)
                  {
                      break;
                  }
              }
  
              if (CHIP_END_OF_TLV == TLVError)
              {
                  // CHIP_END_OF_TLV means we have iterated all items in the structure, which is not a real error.
                  TLVError = CHIP_NO_ERROR;
              }
  
              if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 4 == validArgumentCount)
              {
                  wasHandled =
                      emberAfLevelControlClusterMoveCallback(aEndpointId, apCommandObj, moveMode, rate, optionMask, optionOverride);
              }
              break;
          }
          case Clusters::LevelControl::Commands::Ids::MoveToLevel: {
              expectArgumentCount = 4;
              uint8_t level;
              uint16_t transitionTime;
              uint8_t optionMask;
              uint8_t optionOverride;
              bool argExists[4];
  
              memset(argExists, 0, sizeof argExists);
  
              while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR)
              {
                  // Since call to aDataTlv.Next() is CHIP_NO_ERROR, the read head always points to an element.
                  // Skip this element if it is not a ContextTag, not consider it as an error if other values are valid.
                  if (!TLV::IsContextTag(aDataTlv.GetTag()))
                  {
                      continue;
                  }
                  currentDecodeTagId = TLV::TagNumFromTag(aDataTlv.GetTag());
                  if (currentDecodeTagId < 4)
                  {
                      if (argExists[currentDecodeTagId])
                      {
                          ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
                          TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
                          break;
                      }
                      else
                      {
                          argExists[currentDecodeTagId] = true;
                          validArgumentCount++;
                      }
                  }
                  switch (currentDecodeTagId)
                  {
                  case 0:
                      TLVUnpackError = aDataTlv.Get(level);
                      break;
                  case 1:
                      TLVUnpackError = aDataTlv.Get(transitionTime);
                      break;
                  case 2:
                      TLVUnpackError = aDataTlv.Get(optionMask);
                      break;
                  case 3:
                      TLVUnpackError = aDataTlv.Get(optionOverride);
                      break;
                  default:
                      // Unsupported tag, ignore it.
                      ChipLogProgress(Zcl, "Unknown TLV tag during processing.");
                      break;
                  }
                  if (CHIP_NO_ERROR != TLVUnpackError)
                  {
                      break;
                  }
              }
  
              if (CHIP_END_OF_TLV == TLVError)
              {
                  // CHIP_END_OF_TLV means we have iterated all items in the structure, which is not a real error.
                  TLVError = CHIP_NO_ERROR;
              }
  
              if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 4 == validArgumentCount)
              {
                  wasHandled = emberAfLevelControlClusterMoveToLevelCallback(aEndpointId, apCommandObj, level, transitionTime,
                                                                             optionMask, optionOverride);
              }
              break;
          }
          case Clusters::LevelControl::Commands::Ids::MoveToLevelWithOnOff: {
              expectArgumentCount = 2;
              uint8_t level;
              uint16_t transitionTime;
              bool argExists[2];
  
              memset(argExists, 0, sizeof argExists);
  
              while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR)
              {
                  // Since call to aDataTlv.Next() is CHIP_NO_ERROR, the read head always points to an element.
                  // Skip this element if it is not a ContextTag, not consider it as an error if other values are valid.
                  if (!TLV::IsContextTag(aDataTlv.GetTag()))
                  {
                      continue;
                  }
                  currentDecodeTagId = TLV::TagNumFromTag(aDataTlv.GetTag());
                  if (currentDecodeTagId < 2)
                  {
                      if (argExists[currentDecodeTagId])
                      {
                          ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
                          TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
                          break;
                      }
                      else
                      {
                          argExists[currentDecodeTagId] = true;
                          validArgumentCount++;
                      }
                  }
                  switch (currentDecodeTagId)
                  {
                  case 0:
                      TLVUnpackError = aDataTlv.Get(level);
                      break;
                  case 1:
                      TLVUnpackError = aDataTlv.Get(transitionTime);
                      break;
                  default:
                      // Unsupported tag, ignore it.
                      ChipLogProgress(Zcl, "Unknown TLV tag during processing.");
                      break;
                  }
                  if (CHIP_NO_ERROR != TLVUnpackError)
                  {
                      break;
                  }
              }
  
              if (CHIP_END_OF_TLV == TLVError)
              {
                  // CHIP_END_OF_TLV means we have iterated all items in the structure, which is not a real error.
                  TLVError = CHIP_NO_ERROR;
              }
  
              if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 2 == validArgumentCount)
              {
                  wasHandled =
                      emberAfLevelControlClusterMoveToLevelWithOnOffCallback(aEndpointId, apCommandObj, level, transitionTime);
              }
              break;
          }
          case Clusters::LevelControl::Commands::Ids::MoveWithOnOff: {
              expectArgumentCount = 2;
              uint8_t moveMode;
              uint8_t rate;
              bool argExists[2];
  
              memset(argExists, 0, sizeof argExists);
  
              while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR)
              {
                  // Since call to aDataTlv.Next() is CHIP_NO_ERROR, the read head always points to an element.
                  // Skip this element if it is not a ContextTag, not consider it as an error if other values are valid.
                  if (!TLV::IsContextTag(aDataTlv.GetTag()))
                  {
                      continue;
                  }
                  currentDecodeTagId = TLV::TagNumFromTag(aDataTlv.GetTag());
                  if (currentDecodeTagId < 2)
                  {
                      if (argExists[currentDecodeTagId])
                      {
                          ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
                          TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
                          break;
                      }
                      else
                      {
                          argExists[currentDecodeTagId] = true;
                          validArgumentCount++;
                      }
                  }
                  switch (currentDecodeTagId)
                  {
                  case 0:
                      TLVUnpackError = aDataTlv.Get(moveMode);
                      break;
                  case 1:
                      TLVUnpackError = aDataTlv.Get(rate);
                      break;
                  default:
                      // Unsupported tag, ignore it.
                      ChipLogProgress(Zcl, "Unknown TLV tag during processing.");
                      break;
                  }
                  if (CHIP_NO_ERROR != TLVUnpackError)
                  {
                      break;
                  }
              }
  
              if (CHIP_END_OF_TLV == TLVError)
              {
                  // CHIP_END_OF_TLV means we have iterated all items in the structure, which is not a real error.
                  TLVError = CHIP_NO_ERROR;
              }
  
              if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 2 == validArgumentCount)
              {
                  wasHandled = emberAfLevelControlClusterMoveWithOnOffCallback(aEndpointId, apCommandObj, moveMode, rate);
              }
              break;
          }
          case Clusters::LevelControl::Commands::Ids::Step: {
              expectArgumentCount = 5;
              uint8_t stepMode;
              uint8_t stepSize;
              uint16_t transitionTime;
              uint8_t optionMask;
              uint8_t optionOverride;
              bool argExists[5];
  
              memset(argExists, 0, sizeof argExists);
  
              while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR)
              {
                  // Since call to aDataTlv.Next() is CHIP_NO_ERROR, the read head always points to an element.
                  // Skip this element if it is not a ContextTag, not consider it as an error if other values are valid.
                  if (!TLV::IsContextTag(aDataTlv.GetTag()))
                  {
                      continue;
                  }
                  currentDecodeTagId = TLV::TagNumFromTag(aDataTlv.GetTag());
                  if (currentDecodeTagId < 5)
                  {
                      if (argExists[currentDecodeTagId])
                      {
                          ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
                          TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
                          break;
                      }
                      else
                      {
                          argExists[currentDecodeTagId] = true;
                          validArgumentCount++;
                      }
                  }
                  switch (currentDecodeTagId)
                  {
                  case 0:
                      TLVUnpackError = aDataTlv.Get(stepMode);
                      break;
                  case 1:
                      TLVUnpackError = aDataTlv.Get(stepSize);
                      break;
                  case 2:
                      TLVUnpackError = aDataTlv.Get(transitionTime);
                      break;
                  case 3:
                      TLVUnpackError = aDataTlv.Get(optionMask);
                      break;
                  case 4:
                      TLVUnpackError = aDataTlv.Get(optionOverride);
                      break;
                  default:
                      // Unsupported tag, ignore it.
                      ChipLogProgress(Zcl, "Unknown TLV tag during processing.");
                      break;
                  }
                  if (CHIP_NO_ERROR != TLVUnpackError)
                  {
                      break;
                  }
              }
  
              if (CHIP_END_OF_TLV == TLVError)
              {
                  // CHIP_END_OF_TLV means we have iterated all items in the structure, which is not a real error.
                  TLVError = CHIP_NO_ERROR;
              }
  
              if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 5 == validArgumentCount)
              {
                  wasHandled = emberAfLevelControlClusterStepCallback(aEndpointId, apCommandObj, stepMode, stepSize, transitionTime,
                                                                      optionMask, optionOverride);
              }
              break;
          }
          case Clusters::LevelControl::Commands::Ids::StepWithOnOff: {
              expectArgumentCount = 3;
              uint8_t stepMode;
              uint8_t stepSize;
              uint16_t transitionTime;
              bool argExists[3];
  
              memset(argExists, 0, sizeof argExists);
  
              while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR)
              {
                  // Since call to aDataTlv.Next() is CHIP_NO_ERROR, the read head always points to an element.
                  // Skip this element if it is not a ContextTag, not consider it as an error if other values are valid.
                  if (!TLV::IsContextTag(aDataTlv.GetTag()))
                  {
                      continue;
                  }
                  currentDecodeTagId = TLV::TagNumFromTag(aDataTlv.GetTag());
                  if (currentDecodeTagId < 3)
                  {
                      if (argExists[currentDecodeTagId])
                      {
                          ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
                          TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
                          break;
                      }
                      else
                      {
                          argExists[currentDecodeTagId] = true;
                          validArgumentCount++;
                      }
                  }
                  switch (currentDecodeTagId)
                  {
                  case 0:
                      TLVUnpackError = aDataTlv.Get(stepMode);
                      break;
                  case 1:
                      TLVUnpackError = aDataTlv.Get(stepSize);
                      break;
                  case 2:
                      TLVUnpackError = aDataTlv.Get(transitionTime);
                      break;
                  default:
                      // Unsupported tag, ignore it.
                      ChipLogProgress(Zcl, "Unknown TLV tag during processing.");
                      break;
                  }
                  if (CHIP_NO_ERROR != TLVUnpackError)
                  {
                      break;
                  }
              }
  
              if (CHIP_END_OF_TLV == TLVError)
              {
                  // CHIP_END_OF_TLV means we have iterated all items in the structure, which is not a real error.
                  TLVError = CHIP_NO_ERROR;
              }
  
              if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 3 == validArgumentCount)
              {
                  wasHandled =
                      emberAfLevelControlClusterStepWithOnOffCallback(aEndpointId, apCommandObj, stepMode, stepSize, transitionTime);
              }
              break;
          }
          case Clusters::LevelControl::Commands::Ids::Stop: {
              expectArgumentCount = 2;
              uint8_t optionMask;
              uint8_t optionOverride;
              bool argExists[2];
  
              memset(argExists, 0, sizeof argExists);
  
              while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR)
              {
                  // Since call to aDataTlv.Next() is CHIP_NO_ERROR, the read head always points to an element.
                  // Skip this element if it is not a ContextTag, not consider it as an error if other values are valid.
                  if (!TLV::IsContextTag(aDataTlv.GetTag()))
                  {
                      continue;
                  }
                  currentDecodeTagId = TLV::TagNumFromTag(aDataTlv.GetTag());
                  if (currentDecodeTagId < 2)
                  {
                      if (argExists[currentDecodeTagId])
                      {
                          ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
                          TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
                          break;
                      }
                      else
                      {
                          argExists[currentDecodeTagId] = true;
                          validArgumentCount++;
                      }
                  }
                  switch (currentDecodeTagId)
                  {
                  case 0:
                      TLVUnpackError = aDataTlv.Get(optionMask);
                      break;
                  case 1:
                      TLVUnpackError = aDataTlv.Get(optionOverride);
                      break;
                  default:
                      // Unsupported tag, ignore it.
                      ChipLogProgress(Zcl, "Unknown TLV tag during processing.");
                      break;
                  }
                  if (CHIP_NO_ERROR != TLVUnpackError)
                  {
                      break;
                  }
              }
  
              if (CHIP_END_OF_TLV == TLVError)
              {
                  // CHIP_END_OF_TLV means we have iterated all items in the structure, which is not a real error.
                  TLVError = CHIP_NO_ERROR;
              }
  
              if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 2 == validArgumentCount)
              {
                  wasHandled = emberAfLevelControlClusterStopCallback(aEndpointId, apCommandObj, optionMask, optionOverride);
              }
              break;
          }
          case Clusters::LevelControl::Commands::Ids::StopWithOnOff: {
  
              wasHandled = emberAfLevelControlClusterStopWithOnOffCallback(aEndpointId, apCommandObj);
              break;
          }
          default: {
              // Unrecognized command ID, error status will apply.
              chip::app::CommandPathParams returnStatusParam = { aEndpointId,
                                                                 0, // GroupId
                                                                 Clusters::LevelControl::Id, aCommandId,
                                                                 (chip::app::CommandPathFlags::kEndpointIdValid) };
              apCommandObj->AddStatusCode(returnStatusParam, Protocols::SecureChannel::GeneralStatusCode::kNotFound,
                                          Protocols::SecureChannel::Id,
                                          Protocols::InteractionModel::ProtocolCode::UnsupportedCommand);
              ChipLogError(Zcl, "Unknown command %" PRIx32 " for cluster %" PRIx32, aCommandId, Clusters::LevelControl::Id);
              return;
          }
          }
      }
  
      if (CHIP_NO_ERROR != TLVError || CHIP_NO_ERROR != TLVUnpackError || expectArgumentCount != validArgumentCount || !wasHandled)
      {
          chip::app::CommandPathParams returnStatusParam = { aEndpointId,
                                                             0, // GroupId
                                                             Clusters::LevelControl::Id, aCommandId,
                                                             (chip::app::CommandPathFlags::kEndpointIdValid) };
          apCommandObj->AddStatusCode(returnStatusParam, Protocols::SecureChannel::GeneralStatusCode::kBadRequest,
                                      Protocols::SecureChannel::Id, Protocols::InteractionModel::ProtocolCode::InvalidCommand);
          ChipLogProgress(Zcl,
                          "Failed to dispatch command, %" PRIu32 "/%" PRIu32 " arguments parsed, TLVError=%" CHIP_ERROR_FORMAT
                          ", UnpackError=%" CHIP_ERROR_FORMAT " (last decoded tag = %" PRIu32,
                          validArgumentCount, expectArgumentCount, ChipError::FormatError(TLVError),
                          ChipError::FormatError(TLVUnpackError), currentDecodeTagId);
          // A command with no arguments would never write currentDecodeTagId.  If
          // progress logging is also disabled, it would look unused.  Silence that
          // warning.
          UNUSED_VAR(currentDecodeTagId);
      }
  }
  
  } // namespace LevelControl
  
  namespace LowPower {
  
  void DispatchServerCommand(app::CommandHandler * apCommandObj, CommandId aCommandId, EndpointId aEndpointId,
                             TLV::TLVReader & aDataTlv)
  {
      // We are using TLVUnpackError and TLVError here since both of them can be CHIP_END_OF_TLV
      // When TLVError is CHIP_END_OF_TLV, it means we have iterated all of the items, which is not a real error.
      // Any error value TLVUnpackError means we have received an illegal value.
      // The following variables are used for all commands to save code size.
      CHIP_ERROR TLVError          = CHIP_NO_ERROR;
      CHIP_ERROR TLVUnpackError    = CHIP_NO_ERROR;
      uint32_t validArgumentCount  = 0;
      uint32_t expectArgumentCount = 0;
      uint32_t currentDecodeTagId  = 0;
      bool wasHandled              = false;
      {
          switch (aCommandId)
          {
          case Clusters::LowPower::Commands::Ids::Sleep: {
  
              wasHandled = emberAfLowPowerClusterSleepCallback(aEndpointId, apCommandObj);
              break;
          }
          default: {
              // Unrecognized command ID, error status will apply.
              chip::app::CommandPathParams returnStatusParam = { aEndpointId,
                                                                 0, // GroupId
                                                                 Clusters::LowPower::Id, aCommandId,
                                                                 (chip::app::CommandPathFlags::kEndpointIdValid) };
              apCommandObj->AddStatusCode(returnStatusParam, Protocols::SecureChannel::GeneralStatusCode::kNotFound,
                                          Protocols::SecureChannel::Id,
                                          Protocols::InteractionModel::ProtocolCode::UnsupportedCommand);
              ChipLogError(Zcl, "Unknown command %" PRIx32 " for cluster %" PRIx32, aCommandId, Clusters::LowPower::Id);
              return;
          }
          }
      }
  
      if (CHIP_NO_ERROR != TLVError || CHIP_NO_ERROR != TLVUnpackError || expectArgumentCount != validArgumentCount || !wasHandled)
      {
          chip::app::CommandPathParams returnStatusParam = { aEndpointId,
                                                             0, // GroupId
                                                             Clusters::LowPower::Id, aCommandId,
                                                             (chip::app::CommandPathFlags::kEndpointIdValid) };
          apCommandObj->AddStatusCode(returnStatusParam, Protocols::SecureChannel::GeneralStatusCode::kBadRequest,
                                      Protocols::SecureChannel::Id, Protocols::InteractionModel::ProtocolCode::InvalidCommand);
          ChipLogProgress(Zcl,
                          "Failed to dispatch command, %" PRIu32 "/%" PRIu32 " arguments parsed, TLVError=%" CHIP_ERROR_FORMAT
                          ", UnpackError=%" CHIP_ERROR_FORMAT " (last decoded tag = %" PRIu32,
                          validArgumentCount, expectArgumentCount, ChipError::FormatError(TLVError),
                          ChipError::FormatError(TLVUnpackError), currentDecodeTagId);
          // A command with no arguments would never write currentDecodeTagId.  If
          // progress logging is also disabled, it would look unused.  Silence that
          // warning.
          UNUSED_VAR(currentDecodeTagId);
      }
  }
  
  } // namespace LowPower
  
  namespace NetworkCommissioning {
  
  void DispatchServerCommand(app::CommandHandler * apCommandObj, CommandId aCommandId, EndpointId aEndpointId,
                             TLV::TLVReader & aDataTlv)
  {
      // We are using TLVUnpackError and TLVError here since both of them can be CHIP_END_OF_TLV
      // When TLVError is CHIP_END_OF_TLV, it means we have iterated all of the items, which is not a real error.
      // Any error value TLVUnpackError means we have received an illegal value.
      // The following variables are used for all commands to save code size.
      CHIP_ERROR TLVError          = CHIP_NO_ERROR;
      CHIP_ERROR TLVUnpackError    = CHIP_NO_ERROR;
      uint32_t validArgumentCount  = 0;
      uint32_t expectArgumentCount = 0;
      uint32_t currentDecodeTagId  = 0;
      bool wasHandled              = false;
      {
          switch (aCommandId)
          {
          case Clusters::NetworkCommissioning::Commands::Ids::AddThreadNetwork: {
              expectArgumentCount = 3;
              chip::ByteSpan operationalDataset;
              uint64_t breadcrumb;
              uint32_t timeoutMs;
              bool argExists[3];
  
              memset(argExists, 0, sizeof argExists);
  
              while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR)
              {
                  // Since call to aDataTlv.Next() is CHIP_NO_ERROR, the read head always points to an element.
                  // Skip this element if it is not a ContextTag, not consider it as an error if other values are valid.
                  if (!TLV::IsContextTag(aDataTlv.GetTag()))
                  {
                      continue;
                  }
                  currentDecodeTagId = TLV::TagNumFromTag(aDataTlv.GetTag());
                  if (currentDecodeTagId < 3)
                  {
                      if (argExists[currentDecodeTagId])
                      {
                          ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
                          TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
                          break;
                      }
                      else
                      {
                          argExists[currentDecodeTagId] = true;
                          validArgumentCount++;
                      }
                  }
                  switch (currentDecodeTagId)
                  {
                  case 0: {
                      const uint8_t * data = nullptr;
                      TLVUnpackError       = aDataTlv.GetDataPtr(data);
                      operationalDataset   = chip::ByteSpan(data, aDataTlv.GetLength());
                  }
                  break;
                  case 1:
                      TLVUnpackError = aDataTlv.Get(breadcrumb);
                      break;
                  case 2:
                      TLVUnpackError = aDataTlv.Get(timeoutMs);
                      break;
                  default:
                      // Unsupported tag, ignore it.
                      ChipLogProgress(Zcl, "Unknown TLV tag during processing.");
                      break;
                  }
                  if (CHIP_NO_ERROR != TLVUnpackError)
                  {
                      break;
                  }
              }
  
              if (CHIP_END_OF_TLV == TLVError)
              {
                  // CHIP_END_OF_TLV means we have iterated all items in the structure, which is not a real error.
                  TLVError = CHIP_NO_ERROR;
              }
  
              if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 3 == validArgumentCount)
              {
                  wasHandled = emberAfNetworkCommissioningClusterAddThreadNetworkCallback(aEndpointId, apCommandObj,
                                                                                          operationalDataset, breadcrumb, timeoutMs);
              }
              break;
          }
          case Clusters::NetworkCommissioning::Commands::Ids::AddWiFiNetwork: {
              expectArgumentCount = 4;
              chip::ByteSpan ssid;
              chip::ByteSpan credentials;
              uint64_t breadcrumb;
              uint32_t timeoutMs;
              bool argExists[4];
  
              memset(argExists, 0, sizeof argExists);
  
              while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR)
              {
                  // Since call to aDataTlv.Next() is CHIP_NO_ERROR, the read head always points to an element.
                  // Skip this element if it is not a ContextTag, not consider it as an error if other values are valid.
                  if (!TLV::IsContextTag(aDataTlv.GetTag()))
                  {
                      continue;
                  }
                  currentDecodeTagId = TLV::TagNumFromTag(aDataTlv.GetTag());
                  if (currentDecodeTagId < 4)
                  {
                      if (argExists[currentDecodeTagId])
                      {
                          ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
                          TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
                          break;
                      }
                      else
                      {
                          argExists[currentDecodeTagId] = true;
                          validArgumentCount++;
                      }
                  }
                  switch (currentDecodeTagId)
                  {
                  case 0: {
                      const uint8_t * data = nullptr;
                      TLVUnpackError       = aDataTlv.GetDataPtr(data);
                      ssid                 = chip::ByteSpan(data, aDataTlv.GetLength());
                  }
                  break;
                  case 1: {
                      const uint8_t * data = nullptr;
                      TLVUnpackError       = aDataTlv.GetDataPtr(data);
                      credentials          = chip::ByteSpan(data, aDataTlv.GetLength());
                  }
                  break;
                  case 2:
                      TLVUnpackError = aDataTlv.Get(breadcrumb);
                      break;
                  case 3:
                      TLVUnpackError = aDataTlv.Get(timeoutMs);
                      break;
                  default:
                      // Unsupported tag, ignore it.
                      ChipLogProgress(Zcl, "Unknown TLV tag during processing.");
                      break;
                  }
                  if (CHIP_NO_ERROR != TLVUnpackError)
                  {
                      break;
                  }
              }
  
              if (CHIP_END_OF_TLV == TLVError)
              {
                  // CHIP_END_OF_TLV means we have iterated all items in the structure, which is not a real error.
                  TLVError = CHIP_NO_ERROR;
              }
  
              if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 4 == validArgumentCount)
              {
                  wasHandled = emberAfNetworkCommissioningClusterAddWiFiNetworkCallback(aEndpointId, apCommandObj, ssid, credentials,
                                                                                        breadcrumb, timeoutMs);
              }
              break;
          }
          case Clusters::NetworkCommissioning::Commands::Ids::DisableNetwork: {
              expectArgumentCount = 3;
              chip::ByteSpan networkID;
              uint64_t breadcrumb;
              uint32_t timeoutMs;
              bool argExists[3];
  
              memset(argExists, 0, sizeof argExists);
  
              while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR)
              {
                  // Since call to aDataTlv.Next() is CHIP_NO_ERROR, the read head always points to an element.
                  // Skip this element if it is not a ContextTag, not consider it as an error if other values are valid.
                  if (!TLV::IsContextTag(aDataTlv.GetTag()))
                  {
                      continue;
                  }
                  currentDecodeTagId = TLV::TagNumFromTag(aDataTlv.GetTag());
                  if (currentDecodeTagId < 3)
                  {
                      if (argExists[currentDecodeTagId])
                      {
                          ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
                          TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
                          break;
                      }
                      else
                      {
                          argExists[currentDecodeTagId] = true;
                          validArgumentCount++;
                      }
                  }
                  switch (currentDecodeTagId)
                  {
                  case 0: {
                      const uint8_t * data = nullptr;
                      TLVUnpackError       = aDataTlv.GetDataPtr(data);
                      networkID            = chip::ByteSpan(data, aDataTlv.GetLength());
                  }
                  break;
                  case 1:
                      TLVUnpackError = aDataTlv.Get(breadcrumb);
                      break;
                  case 2:
                      TLVUnpackError = aDataTlv.Get(timeoutMs);
                      break;
                  default:
                      // Unsupported tag, ignore it.
                      ChipLogProgress(Zcl, "Unknown TLV tag during processing.");
                      break;
                  }
                  if (CHIP_NO_ERROR != TLVUnpackError)
                  {
                      break;
                  }
              }
  
              if (CHIP_END_OF_TLV == TLVError)
              {
                  // CHIP_END_OF_TLV means we have iterated all items in the structure, which is not a real error.
                  TLVError = CHIP_NO_ERROR;
              }
  
              if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 3 == validArgumentCount)
              {
                  wasHandled = emberAfNetworkCommissioningClusterDisableNetworkCallback(aEndpointId, apCommandObj, networkID,
                                                                                        breadcrumb, timeoutMs);
              }
              break;
          }
          case Clusters::NetworkCommissioning::Commands::Ids::EnableNetwork: {
              expectArgumentCount = 3;
              chip::ByteSpan networkID;
              uint64_t breadcrumb;
              uint32_t timeoutMs;
              bool argExists[3];
  
              memset(argExists, 0, sizeof argExists);
  
              while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR)
              {
                  // Since call to aDataTlv.Next() is CHIP_NO_ERROR, the read head always points to an element.
                  // Skip this element if it is not a ContextTag, not consider it as an error if other values are valid.
                  if (!TLV::IsContextTag(aDataTlv.GetTag()))
                  {
                      continue;
                  }
                  currentDecodeTagId = TLV::TagNumFromTag(aDataTlv.GetTag());
                  if (currentDecodeTagId < 3)
                  {
                      if (argExists[currentDecodeTagId])
                      {
                          ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
                          TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
                          break;
                      }
                      else
                      {
                          argExists[currentDecodeTagId] = true;
                          validArgumentCount++;
                      }
                  }
                  switch (currentDecodeTagId)
                  {
                  case 0: {
                      const uint8_t * data = nullptr;
                      TLVUnpackError       = aDataTlv.GetDataPtr(data);
                      networkID            = chip::ByteSpan(data, aDataTlv.GetLength());
                  }
                  break;
                  case 1:
                      TLVUnpackError = aDataTlv.Get(breadcrumb);
                      break;
                  case 2:
                      TLVUnpackError = aDataTlv.Get(timeoutMs);
                      break;
                  default:
                      // Unsupported tag, ignore it.
                      ChipLogProgress(Zcl, "Unknown TLV tag during processing.");
                      break;
                  }
                  if (CHIP_NO_ERROR != TLVUnpackError)
                  {
                      break;
                  }
              }
  
              if (CHIP_END_OF_TLV == TLVError)
              {
                  // CHIP_END_OF_TLV means we have iterated all items in the structure, which is not a real error.
                  TLVError = CHIP_NO_ERROR;
              }
  
              if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 3 == validArgumentCount)
              {
                  wasHandled = emberAfNetworkCommissioningClusterEnableNetworkCallback(aEndpointId, apCommandObj, networkID,
                                                                                       breadcrumb, timeoutMs);
              }
              break;
          }
          case Clusters::NetworkCommissioning::Commands::Ids::GetLastNetworkCommissioningResult: {
              expectArgumentCount = 1;
              uint32_t timeoutMs;
              bool argExists[1];
  
              memset(argExists, 0, sizeof argExists);
  
              while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR)
              {
                  // Since call to aDataTlv.Next() is CHIP_NO_ERROR, the read head always points to an element.
                  // Skip this element if it is not a ContextTag, not consider it as an error if other values are valid.
                  if (!TLV::IsContextTag(aDataTlv.GetTag()))
                  {
                      continue;
                  }
                  currentDecodeTagId = TLV::TagNumFromTag(aDataTlv.GetTag());
                  if (currentDecodeTagId < 1)
                  {
                      if (argExists[currentDecodeTagId])
                      {
                          ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
                          TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
                          break;
                      }
                      else
                      {
                          argExists[currentDecodeTagId] = true;
                          validArgumentCount++;
                      }
                  }
                  switch (currentDecodeTagId)
                  {
                  case 0:
                      TLVUnpackError = aDataTlv.Get(timeoutMs);
                      break;
                  default:
                      // Unsupported tag, ignore it.
                      ChipLogProgress(Zcl, "Unknown TLV tag during processing.");
                      break;
                  }
                  if (CHIP_NO_ERROR != TLVUnpackError)
                  {
                      break;
                  }
              }
  
              if (CHIP_END_OF_TLV == TLVError)
              {
                  // CHIP_END_OF_TLV means we have iterated all items in the structure, which is not a real error.
                  TLVError = CHIP_NO_ERROR;
              }
  
              if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 1 == validArgumentCount)
              {
                  wasHandled = emberAfNetworkCommissioningClusterGetLastNetworkCommissioningResultCallback(aEndpointId, apCommandObj,
                                                                                                           timeoutMs);
              }
              break;
          }
          case Clusters::NetworkCommissioning::Commands::Ids::RemoveNetwork: {
              expectArgumentCount = 3;
              chip::ByteSpan NetworkID;
              uint64_t Breadcrumb;
              uint32_t TimeoutMs;
              bool argExists[3];
  
              memset(argExists, 0, sizeof argExists);
  
              while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR)
              {
                  // Since call to aDataTlv.Next() is CHIP_NO_ERROR, the read head always points to an element.
                  // Skip this element if it is not a ContextTag, not consider it as an error if other values are valid.
                  if (!TLV::IsContextTag(aDataTlv.GetTag()))
                  {
                      continue;
                  }
                  currentDecodeTagId = TLV::TagNumFromTag(aDataTlv.GetTag());
                  if (currentDecodeTagId < 3)
                  {
                      if (argExists[currentDecodeTagId])
                      {
                          ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
                          TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
                          break;
                      }
                      else
                      {
                          argExists[currentDecodeTagId] = true;
                          validArgumentCount++;
                      }
                  }
                  switch (currentDecodeTagId)
                  {
                  case 0: {
                      const uint8_t * data = nullptr;
                      TLVUnpackError       = aDataTlv.GetDataPtr(data);
                      NetworkID            = chip::ByteSpan(data, aDataTlv.GetLength());
                  }
                  break;
                  case 1:
                      TLVUnpackError = aDataTlv.Get(Breadcrumb);
                      break;
                  case 2:
                      TLVUnpackError = aDataTlv.Get(TimeoutMs);
                      break;
                  default:
                      // Unsupported tag, ignore it.
                      ChipLogProgress(Zcl, "Unknown TLV tag during processing.");
                      break;
                  }
                  if (CHIP_NO_ERROR != TLVUnpackError)
                  {
                      break;
                  }
              }
  
              if (CHIP_END_OF_TLV == TLVError)
              {
                  // CHIP_END_OF_TLV means we have iterated all items in the structure, which is not a real error.
                  TLVError = CHIP_NO_ERROR;
              }
  
              if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 3 == validArgumentCount)
              {
                  wasHandled = emberAfNetworkCommissioningClusterRemoveNetworkCallback(aEndpointId, apCommandObj, NetworkID,
                                                                                       Breadcrumb, TimeoutMs);
              }
              break;
          }
          case Clusters::NetworkCommissioning::Commands::Ids::ScanNetworks: {
              expectArgumentCount = 3;
              chip::ByteSpan ssid;
              uint64_t breadcrumb;
              uint32_t timeoutMs;
              bool argExists[3];
  
              memset(argExists, 0, sizeof argExists);
  
              while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR)
              {
                  // Since call to aDataTlv.Next() is CHIP_NO_ERROR, the read head always points to an element.
                  // Skip this element if it is not a ContextTag, not consider it as an error if other values are valid.
                  if (!TLV::IsContextTag(aDataTlv.GetTag()))
                  {
                      continue;
                  }
                  currentDecodeTagId = TLV::TagNumFromTag(aDataTlv.GetTag());
                  if (currentDecodeTagId < 3)
                  {
                      if (argExists[currentDecodeTagId])
                      {
                          ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
                          TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
                          break;
                      }
                      else
                      {
                          argExists[currentDecodeTagId] = true;
                          validArgumentCount++;
                      }
                  }
                  switch (currentDecodeTagId)
                  {
                  case 0: {
                      const uint8_t * data = nullptr;
                      TLVUnpackError       = aDataTlv.GetDataPtr(data);
                      ssid                 = chip::ByteSpan(data, aDataTlv.GetLength());
                  }
                  break;
                  case 1:
                      TLVUnpackError = aDataTlv.Get(breadcrumb);
                      break;
                  case 2:
                      TLVUnpackError = aDataTlv.Get(timeoutMs);
                      break;
                  default:
                      // Unsupported tag, ignore it.
                      ChipLogProgress(Zcl, "Unknown TLV tag during processing.");
                      break;
                  }
                  if (CHIP_NO_ERROR != TLVUnpackError)
                  {
                      break;
                  }
              }
  
              if (CHIP_END_OF_TLV == TLVError)
              {
                  // CHIP_END_OF_TLV means we have iterated all items in the structure, which is not a real error.
                  TLVError = CHIP_NO_ERROR;
              }
  
              if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 3 == validArgumentCount)
              {
                  wasHandled =
                      emberAfNetworkCommissioningClusterScanNetworksCallback(aEndpointId, apCommandObj, ssid, breadcrumb, timeoutMs);
              }
              break;
          }
          case Clusters::NetworkCommissioning::Commands::Ids::UpdateThreadNetwork: {
              expectArgumentCount = 3;
              chip::ByteSpan operationalDataset;
              uint64_t breadcrumb;
              uint32_t timeoutMs;
              bool argExists[3];
  
              memset(argExists, 0, sizeof argExists);
  
              while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR)
              {
                  // Since call to aDataTlv.Next() is CHIP_NO_ERROR, the read head always points to an element.
                  // Skip this element if it is not a ContextTag, not consider it as an error if other values are valid.
                  if (!TLV::IsContextTag(aDataTlv.GetTag()))
                  {
                      continue;
                  }
                  currentDecodeTagId = TLV::TagNumFromTag(aDataTlv.GetTag());
                  if (currentDecodeTagId < 3)
                  {
                      if (argExists[currentDecodeTagId])
                      {
                          ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
                          TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
                          break;
                      }
                      else
                      {
                          argExists[currentDecodeTagId] = true;
                          validArgumentCount++;
                      }
                  }
                  switch (currentDecodeTagId)
                  {
                  case 0: {
                      const uint8_t * data = nullptr;
                      TLVUnpackError       = aDataTlv.GetDataPtr(data);
                      operationalDataset   = chip::ByteSpan(data, aDataTlv.GetLength());
                  }
                  break;
                  case 1:
                      TLVUnpackError = aDataTlv.Get(breadcrumb);
                      break;
                  case 2:
                      TLVUnpackError = aDataTlv.Get(timeoutMs);
                      break;
                  default:
                      // Unsupported tag, ignore it.
                      ChipLogProgress(Zcl, "Unknown TLV tag during processing.");
                      break;
                  }
                  if (CHIP_NO_ERROR != TLVUnpackError)
                  {
                      break;
                  }
              }
  
              if (CHIP_END_OF_TLV == TLVError)
              {
                  // CHIP_END_OF_TLV means we have iterated all items in the structure, which is not a real error.
                  TLVError = CHIP_NO_ERROR;
              }
  
              if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 3 == validArgumentCount)
              {
                  wasHandled = emberAfNetworkCommissioningClusterUpdateThreadNetworkCallback(
                      aEndpointId, apCommandObj, operationalDataset, breadcrumb, timeoutMs);
              }
              break;
          }
          case Clusters::NetworkCommissioning::Commands::Ids::UpdateWiFiNetwork: {
              expectArgumentCount = 4;
              chip::ByteSpan ssid;
              chip::ByteSpan credentials;
              uint64_t breadcrumb;
              uint32_t timeoutMs;
              bool argExists[4];
  
              memset(argExists, 0, sizeof argExists);
  
              while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR)
              {
                  // Since call to aDataTlv.Next() is CHIP_NO_ERROR, the read head always points to an element.
                  // Skip this element if it is not a ContextTag, not consider it as an error if other values are valid.
                  if (!TLV::IsContextTag(aDataTlv.GetTag()))
                  {
                      continue;
                  }
                  currentDecodeTagId = TLV::TagNumFromTag(aDataTlv.GetTag());
                  if (currentDecodeTagId < 4)
                  {
                      if (argExists[currentDecodeTagId])
                      {
                          ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
                          TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
                          break;
                      }
                      else
                      {
                          argExists[currentDecodeTagId] = true;
                          validArgumentCount++;
                      }
                  }
                  switch (currentDecodeTagId)
                  {
                  case 0: {
                      const uint8_t * data = nullptr;
                      TLVUnpackError       = aDataTlv.GetDataPtr(data);
                      ssid                 = chip::ByteSpan(data, aDataTlv.GetLength());
                  }
                  break;
                  case 1: {
                      const uint8_t * data = nullptr;
                      TLVUnpackError       = aDataTlv.GetDataPtr(data);
                      credentials          = chip::ByteSpan(data, aDataTlv.GetLength());
                  }
                  break;
                  case 2:
                      TLVUnpackError = aDataTlv.Get(breadcrumb);
                      break;
                  case 3:
                      TLVUnpackError = aDataTlv.Get(timeoutMs);
                      break;
                  default:
                      // Unsupported tag, ignore it.
                      ChipLogProgress(Zcl, "Unknown TLV tag during processing.");
                      break;
                  }
                  if (CHIP_NO_ERROR != TLVUnpackError)
                  {
                      break;
                  }
              }
  
              if (CHIP_END_OF_TLV == TLVError)
              {
                  // CHIP_END_OF_TLV means we have iterated all items in the structure, which is not a real error.
                  TLVError = CHIP_NO_ERROR;
              }
  
              if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 4 == validArgumentCount)
              {
                  wasHandled = emberAfNetworkCommissioningClusterUpdateWiFiNetworkCallback(aEndpointId, apCommandObj, ssid,
                                                                                           credentials, breadcrumb, timeoutMs);
              }
              break;
          }
          default: {
              // Unrecognized command ID, error status will apply.
              chip::app::CommandPathParams returnStatusParam = { aEndpointId,
                                                                 0, // GroupId
                                                                 Clusters::NetworkCommissioning::Id, aCommandId,
                                                                 (chip::app::CommandPathFlags::kEndpointIdValid) };
              apCommandObj->AddStatusCode(returnStatusParam, Protocols::SecureChannel::GeneralStatusCode::kNotFound,
                                          Protocols::SecureChannel::Id,
                                          Protocols::InteractionModel::ProtocolCode::UnsupportedCommand);
              ChipLogError(Zcl, "Unknown command %" PRIx32 " for cluster %" PRIx32, aCommandId, Clusters::NetworkCommissioning::Id);
              return;
          }
          }
      }
  
      if (CHIP_NO_ERROR != TLVError || CHIP_NO_ERROR != TLVUnpackError || expectArgumentCount != validArgumentCount || !wasHandled)
      {
          chip::app::CommandPathParams returnStatusParam = { aEndpointId,
                                                             0, // GroupId
                                                             Clusters::NetworkCommissioning::Id, aCommandId,
                                                             (chip::app::CommandPathFlags::kEndpointIdValid) };
          apCommandObj->AddStatusCode(returnStatusParam, Protocols::SecureChannel::GeneralStatusCode::kBadRequest,
                                      Protocols::SecureChannel::Id, Protocols::InteractionModel::ProtocolCode::InvalidCommand);
          ChipLogProgress(Zcl,
                          "Failed to dispatch command, %" PRIu32 "/%" PRIu32 " arguments parsed, TLVError=%" CHIP_ERROR_FORMAT
                          ", UnpackError=%" CHIP_ERROR_FORMAT " (last decoded tag = %" PRIu32,
                          validArgumentCount, expectArgumentCount, ChipError::FormatError(TLVError),
                          ChipError::FormatError(TLVUnpackError), currentDecodeTagId);
          // A command with no arguments would never write currentDecodeTagId.  If
          // progress logging is also disabled, it would look unused.  Silence that
          // warning.
          UNUSED_VAR(currentDecodeTagId);
      }
  }
  
  } // namespace NetworkCommissioning
  
  namespace OtaSoftwareUpdateProvider {
  
  void DispatchServerCommand(app::CommandHandler * apCommandObj, CommandId aCommandId, EndpointId aEndpointId,
                             TLV::TLVReader & aDataTlv)
  {
      // We are using TLVUnpackError and TLVError here since both of them can be CHIP_END_OF_TLV
      // When TLVError is CHIP_END_OF_TLV, it means we have iterated all of the items, which is not a real error.
      // Any error value TLVUnpackError means we have received an illegal value.
      // The following variables are used for all commands to save code size.
      CHIP_ERROR TLVError          = CHIP_NO_ERROR;
      CHIP_ERROR TLVUnpackError    = CHIP_NO_ERROR;
      uint32_t validArgumentCount  = 0;
      uint32_t expectArgumentCount = 0;
      uint32_t currentDecodeTagId  = 0;
      bool wasHandled              = false;
      {
          switch (aCommandId)
          {
          case Clusters::OtaSoftwareUpdateProvider::Commands::Ids::ApplyUpdateRequest: {
              expectArgumentCount = 2;
              chip::ByteSpan updateToken;
              uint32_t newVersion;
              bool argExists[2];
  
              memset(argExists, 0, sizeof argExists);
  
              while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR)
              {
                  // Since call to aDataTlv.Next() is CHIP_NO_ERROR, the read head always points to an element.
                  // Skip this element if it is not a ContextTag, not consider it as an error if other values are valid.
                  if (!TLV::IsContextTag(aDataTlv.GetTag()))
                  {
                      continue;
                  }
                  currentDecodeTagId = TLV::TagNumFromTag(aDataTlv.GetTag());
                  if (currentDecodeTagId < 2)
                  {
                      if (argExists[currentDecodeTagId])
                      {
                          ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
                          TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
                          break;
                      }
                      else
                      {
                          argExists[currentDecodeTagId] = true;
                          validArgumentCount++;
                      }
                  }
                  switch (currentDecodeTagId)
                  {
                  case 0: {
                      const uint8_t * data = nullptr;
                      TLVUnpackError       = aDataTlv.GetDataPtr(data);
                      updateToken          = chip::ByteSpan(data, aDataTlv.GetLength());
                  }
                  break;
                  case 1:
                      TLVUnpackError = aDataTlv.Get(newVersion);
                      break;
                  default:
                      // Unsupported tag, ignore it.
                      ChipLogProgress(Zcl, "Unknown TLV tag during processing.");
                      break;
                  }
                  if (CHIP_NO_ERROR != TLVUnpackError)
                  {
                      break;
                  }
              }
  
              if (CHIP_END_OF_TLV == TLVError)
              {
                  // CHIP_END_OF_TLV means we have iterated all items in the structure, which is not a real error.
                  TLVError = CHIP_NO_ERROR;
              }
  
              if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 2 == validArgumentCount)
              {
                  wasHandled = emberAfOtaSoftwareUpdateProviderClusterApplyUpdateRequestCallback(aEndpointId, apCommandObj,
                                                                                                 updateToken, newVersion);
              }
              break;
          }
          case Clusters::OtaSoftwareUpdateProvider::Commands::Ids::NotifyUpdateApplied: {
              expectArgumentCount = 2;
              chip::ByteSpan updateToken;
              uint32_t currentVersion;
              bool argExists[2];
  
              memset(argExists, 0, sizeof argExists);
  
              while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR)
              {
                  // Since call to aDataTlv.Next() is CHIP_NO_ERROR, the read head always points to an element.
                  // Skip this element if it is not a ContextTag, not consider it as an error if other values are valid.
                  if (!TLV::IsContextTag(aDataTlv.GetTag()))
                  {
                      continue;
                  }
                  currentDecodeTagId = TLV::TagNumFromTag(aDataTlv.GetTag());
                  if (currentDecodeTagId < 2)
                  {
                      if (argExists[currentDecodeTagId])
                      {
                          ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
                          TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
                          break;
                      }
                      else
                      {
                          argExists[currentDecodeTagId] = true;
                          validArgumentCount++;
                      }
                  }
                  switch (currentDecodeTagId)
                  {
                  case 0: {
                      const uint8_t * data = nullptr;
                      TLVUnpackError       = aDataTlv.GetDataPtr(data);
                      updateToken          = chip::ByteSpan(data, aDataTlv.GetLength());
                  }
                  break;
                  case 1:
                      TLVUnpackError = aDataTlv.Get(currentVersion);
                      break;
                  default:
                      // Unsupported tag, ignore it.
                      ChipLogProgress(Zcl, "Unknown TLV tag during processing.");
                      break;
                  }
                  if (CHIP_NO_ERROR != TLVUnpackError)
                  {
                      break;
                  }
              }
  
              if (CHIP_END_OF_TLV == TLVError)
              {
                  // CHIP_END_OF_TLV means we have iterated all items in the structure, which is not a real error.
                  TLVError = CHIP_NO_ERROR;
              }
  
              if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 2 == validArgumentCount)
              {
                  wasHandled = emberAfOtaSoftwareUpdateProviderClusterNotifyUpdateAppliedCallback(aEndpointId, apCommandObj,
                                                                                                  updateToken, currentVersion);
              }
              break;
          }
          case Clusters::OtaSoftwareUpdateProvider::Commands::Ids::QueryImage: {
              expectArgumentCount = 9;
              uint16_t vendorId;
              uint16_t productId;
              uint16_t imageType;
              uint16_t hardwareVersion;
              uint32_t currentVersion;
              /* TYPE WARNING: array array defaults to */ uint8_t * protocolsSupported;
              const uint8_t * location;
              uint8_t requestorCanConsent;
              chip::ByteSpan metadataForProvider;
              bool argExists[9];
  
              memset(argExists, 0, sizeof argExists);
  
              while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR)
              {
                  // Since call to aDataTlv.Next() is CHIP_NO_ERROR, the read head always points to an element.
                  // Skip this element if it is not a ContextTag, not consider it as an error if other values are valid.
                  if (!TLV::IsContextTag(aDataTlv.GetTag()))
                  {
                      continue;
                  }
                  currentDecodeTagId = TLV::TagNumFromTag(aDataTlv.GetTag());
                  if (currentDecodeTagId < 9)
                  {
                      if (argExists[currentDecodeTagId])
                      {
                          ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
                          TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
                          break;
                      }
                      else
                      {
                          argExists[currentDecodeTagId] = true;
                          validArgumentCount++;
                      }
                  }
                  switch (currentDecodeTagId)
                  {
                  case 0:
                      TLVUnpackError = aDataTlv.Get(vendorId);
                      break;
                  case 1:
                      TLVUnpackError = aDataTlv.Get(productId);
                      break;
                  case 2:
                      TLVUnpackError = aDataTlv.Get(imageType);
                      break;
                  case 3:
                      TLVUnpackError = aDataTlv.Get(hardwareVersion);
                      break;
                  case 4:
                      TLVUnpackError = aDataTlv.Get(currentVersion);
                      break;
                  case 5:
                      // Just for compatibility, we will add array type support in IM later.
                      TLVUnpackError = aDataTlv.GetDataPtr(const_cast<const uint8_t *&>(protocolsSupported));
                      break;
                  case 6:
                      // TODO(#5542): The cluster handlers should accept a ByteSpan for all string types.
                      TLVUnpackError = aDataTlv.GetDataPtr(location);
                      break;
                  case 7:
                      TLVUnpackError = aDataTlv.Get(requestorCanConsent);
                      break;
                  case 8: {
                      const uint8_t * data = nullptr;
                      TLVUnpackError       = aDataTlv.GetDataPtr(data);
                      metadataForProvider  = chip::ByteSpan(data, aDataTlv.GetLength());
                  }
                  break;
                  default:
                      // Unsupported tag, ignore it.
                      ChipLogProgress(Zcl, "Unknown TLV tag during processing.");
                      break;
                  }
                  if (CHIP_NO_ERROR != TLVUnpackError)
                  {
                      break;
                  }
              }
  
              if (CHIP_END_OF_TLV == TLVError)
              {
                  // CHIP_END_OF_TLV means we have iterated all items in the structure, which is not a real error.
                  TLVError = CHIP_NO_ERROR;
              }
  
              if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 9 == validArgumentCount)
              {
                  wasHandled = emberAfOtaSoftwareUpdateProviderClusterQueryImageCallback(
                      aEndpointId, apCommandObj, vendorId, productId, imageType, hardwareVersion, currentVersion, protocolsSupported,
                      const_cast<uint8_t *>(location), requestorCanConsent, metadataForProvider);
              }
              break;
          }
          default: {
              // Unrecognized command ID, error status will apply.
              chip::app::CommandPathParams returnStatusParam = { aEndpointId,
                                                                 0, // GroupId
                                                                 Clusters::OtaSoftwareUpdateProvider::Id, aCommandId,
                                                                 (chip::app::CommandPathFlags::kEndpointIdValid) };
              apCommandObj->AddStatusCode(returnStatusParam, Protocols::SecureChannel::GeneralStatusCode::kNotFound,
                                          Protocols::SecureChannel::Id,
                                          Protocols::InteractionModel::ProtocolCode::UnsupportedCommand);
              ChipLogError(Zcl, "Unknown command %" PRIx32 " for cluster %" PRIx32, aCommandId,
                           Clusters::OtaSoftwareUpdateProvider::Id);
              return;
          }
          }
      }
  
      if (CHIP_NO_ERROR != TLVError || CHIP_NO_ERROR != TLVUnpackError || expectArgumentCount != validArgumentCount || !wasHandled)
      {
          chip::app::CommandPathParams returnStatusParam = { aEndpointId,
                                                             0, // GroupId
                                                             Clusters::OtaSoftwareUpdateProvider::Id, aCommandId,
                                                             (chip::app::CommandPathFlags::kEndpointIdValid) };
          apCommandObj->AddStatusCode(returnStatusParam, Protocols::SecureChannel::GeneralStatusCode::kBadRequest,
                                      Protocols::SecureChannel::Id, Protocols::InteractionModel::ProtocolCode::InvalidCommand);
          ChipLogProgress(Zcl,
                          "Failed to dispatch command, %" PRIu32 "/%" PRIu32 " arguments parsed, TLVError=%" CHIP_ERROR_FORMAT
                          ", UnpackError=%" CHIP_ERROR_FORMAT " (last decoded tag = %" PRIu32,
                          validArgumentCount, expectArgumentCount, ChipError::FormatError(TLVError),
                          ChipError::FormatError(TLVUnpackError), currentDecodeTagId);
          // A command with no arguments would never write currentDecodeTagId.  If
          // progress logging is also disabled, it would look unused.  Silence that
          // warning.
          UNUSED_VAR(currentDecodeTagId);
      }
  }
  
  } // namespace OtaSoftwareUpdateProvider
  
  namespace OnOff {
  
  void DispatchServerCommand(app::CommandHandler * apCommandObj, CommandId aCommandId, EndpointId aEndpointId,
                             TLV::TLVReader & aDataTlv)
  {
      // We are using TLVUnpackError and TLVError here since both of them can be CHIP_END_OF_TLV
      // When TLVError is CHIP_END_OF_TLV, it means we have iterated all of the items, which is not a real error.
      // Any error value TLVUnpackError means we have received an illegal value.
      // The following variables are used for all commands to save code size.
      CHIP_ERROR TLVError          = CHIP_NO_ERROR;
      CHIP_ERROR TLVUnpackError    = CHIP_NO_ERROR;
      uint32_t validArgumentCount  = 0;
      uint32_t expectArgumentCount = 0;
      uint32_t currentDecodeTagId  = 0;
      bool wasHandled              = false;
      {
          switch (aCommandId)
          {
          case Clusters::OnOff::Commands::Ids::Off: {
  
              wasHandled = emberAfOnOffClusterOffCallback(aEndpointId, apCommandObj);
              break;
          }
          case Clusters::OnOff::Commands::Ids::On: {
  
              wasHandled = emberAfOnOffClusterOnCallback(aEndpointId, apCommandObj);
              break;
          }
          case Clusters::OnOff::Commands::Ids::Toggle: {
  
              wasHandled = emberAfOnOffClusterToggleCallback(aEndpointId, apCommandObj);
              break;
          }
          default: {
              // Unrecognized command ID, error status will apply.
              chip::app::CommandPathParams returnStatusParam = { aEndpointId,
                                                                 0, // GroupId
                                                                 Clusters::OnOff::Id, aCommandId,
                                                                 (chip::app::CommandPathFlags::kEndpointIdValid) };
              apCommandObj->AddStatusCode(returnStatusParam, Protocols::SecureChannel::GeneralStatusCode::kNotFound,
                                          Protocols::SecureChannel::Id,
                                          Protocols::InteractionModel::ProtocolCode::UnsupportedCommand);
              ChipLogError(Zcl, "Unknown command %" PRIx32 " for cluster %" PRIx32, aCommandId, Clusters::OnOff::Id);
              return;
          }
          }
      }
  
      if (CHIP_NO_ERROR != TLVError || CHIP_NO_ERROR != TLVUnpackError || expectArgumentCount != validArgumentCount || !wasHandled)
      {
          chip::app::CommandPathParams returnStatusParam = { aEndpointId,
                                                             0, // GroupId
                                                             Clusters::OnOff::Id, aCommandId,
                                                             (chip::app::CommandPathFlags::kEndpointIdValid) };
          apCommandObj->AddStatusCode(returnStatusParam, Protocols::SecureChannel::GeneralStatusCode::kBadRequest,
                                      Protocols::SecureChannel::Id, Protocols::InteractionModel::ProtocolCode::InvalidCommand);
          ChipLogProgress(Zcl,
                          "Failed to dispatch command, %" PRIu32 "/%" PRIu32 " arguments parsed, TLVError=%" CHIP_ERROR_FORMAT
                          ", UnpackError=%" CHIP_ERROR_FORMAT " (last decoded tag = %" PRIu32,
                          validArgumentCount, expectArgumentCount, ChipError::FormatError(TLVError),
                          ChipError::FormatError(TLVUnpackError), currentDecodeTagId);
          // A command with no arguments would never write currentDecodeTagId.  If
          // progress logging is also disabled, it would look unused.  Silence that
          // warning.
          UNUSED_VAR(currentDecodeTagId);
      }
  }
  
  } // namespace OnOff
  
  namespace OperationalCredentials {
  
  void DispatchServerCommand(app::CommandHandler * apCommandObj, CommandId aCommandId, EndpointId aEndpointId,
                             TLV::TLVReader & aDataTlv)
  {
      // We are using TLVUnpackError and TLVError here since both of them can be CHIP_END_OF_TLV
      // When TLVError is CHIP_END_OF_TLV, it means we have iterated all of the items, which is not a real error.
      // Any error value TLVUnpackError means we have received an illegal value.
      // The following variables are used for all commands to save code size.
      CHIP_ERROR TLVError          = CHIP_NO_ERROR;
      CHIP_ERROR TLVUnpackError    = CHIP_NO_ERROR;
      uint32_t validArgumentCount  = 0;
      uint32_t expectArgumentCount = 0;
      uint32_t currentDecodeTagId  = 0;
      bool wasHandled              = false;
      {
          switch (aCommandId)
          {
          case Clusters::OperationalCredentials::Commands::Ids::AddNOC: {
              expectArgumentCount = 4;
              chip::ByteSpan NOCArray;
              chip::ByteSpan IPKValue;
              chip::NodeId CaseAdminNode;
              uint16_t AdminVendorId;
              bool argExists[4];
  
              memset(argExists, 0, sizeof argExists);
  
              while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR)
              {
                  // Since call to aDataTlv.Next() is CHIP_NO_ERROR, the read head always points to an element.
                  // Skip this element if it is not a ContextTag, not consider it as an error if other values are valid.
                  if (!TLV::IsContextTag(aDataTlv.GetTag()))
                  {
                      continue;
                  }
                  currentDecodeTagId = TLV::TagNumFromTag(aDataTlv.GetTag());
                  if (currentDecodeTagId < 4)
                  {
                      if (argExists[currentDecodeTagId])
                      {
                          ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
                          TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
                          break;
                      }
                      else
                      {
                          argExists[currentDecodeTagId] = true;
                          validArgumentCount++;
                      }
                  }
                  switch (currentDecodeTagId)
                  {
                  case 0: {
                      const uint8_t * data = nullptr;
                      TLVUnpackError       = aDataTlv.GetDataPtr(data);
                      NOCArray             = chip::ByteSpan(data, aDataTlv.GetLength());
                  }
                  break;
                  case 1: {
                      const uint8_t * data = nullptr;
                      TLVUnpackError       = aDataTlv.GetDataPtr(data);
                      IPKValue             = chip::ByteSpan(data, aDataTlv.GetLength());
                  }
                  break;
                  case 2:
                      TLVUnpackError = aDataTlv.Get(CaseAdminNode);
                      break;
                  case 3:
                      TLVUnpackError = aDataTlv.Get(AdminVendorId);
                      break;
                  default:
                      // Unsupported tag, ignore it.
                      ChipLogProgress(Zcl, "Unknown TLV tag during processing.");
                      break;
                  }
                  if (CHIP_NO_ERROR != TLVUnpackError)
                  {
                      break;
                  }
              }
  
              if (CHIP_END_OF_TLV == TLVError)
              {
                  // CHIP_END_OF_TLV means we have iterated all items in the structure, which is not a real error.
                  TLVError = CHIP_NO_ERROR;
              }
  
              if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 4 == validArgumentCount)
              {
                  wasHandled = emberAfOperationalCredentialsClusterAddNOCCallback(aEndpointId, apCommandObj, NOCArray, IPKValue,
                                                                                  CaseAdminNode, AdminVendorId);
              }
              break;
          }
          case Clusters::OperationalCredentials::Commands::Ids::AddTrustedRootCertificate: {
              expectArgumentCount = 1;
              chip::ByteSpan RootCertificate;
              bool argExists[1];
  
              memset(argExists, 0, sizeof argExists);
  
              while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR)
              {
                  // Since call to aDataTlv.Next() is CHIP_NO_ERROR, the read head always points to an element.
                  // Skip this element if it is not a ContextTag, not consider it as an error if other values are valid.
                  if (!TLV::IsContextTag(aDataTlv.GetTag()))
                  {
                      continue;
                  }
                  currentDecodeTagId = TLV::TagNumFromTag(aDataTlv.GetTag());
                  if (currentDecodeTagId < 1)
                  {
                      if (argExists[currentDecodeTagId])
                      {
                          ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
                          TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
                          break;
                      }
                      else
                      {
                          argExists[currentDecodeTagId] = true;
                          validArgumentCount++;
                      }
                  }
                  switch (currentDecodeTagId)
                  {
                  case 0: {
                      const uint8_t * data = nullptr;
                      TLVUnpackError       = aDataTlv.GetDataPtr(data);
                      RootCertificate      = chip::ByteSpan(data, aDataTlv.GetLength());
                  }
                  break;
                  default:
                      // Unsupported tag, ignore it.
                      ChipLogProgress(Zcl, "Unknown TLV tag during processing.");
                      break;
                  }
                  if (CHIP_NO_ERROR != TLVUnpackError)
                  {
                      break;
                  }
              }
  
              if (CHIP_END_OF_TLV == TLVError)
              {
                  // CHIP_END_OF_TLV means we have iterated all items in the structure, which is not a real error.
                  TLVError = CHIP_NO_ERROR;
              }
  
              if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 1 == validArgumentCount)
              {
                  wasHandled = emberAfOperationalCredentialsClusterAddTrustedRootCertificateCallback(aEndpointId, apCommandObj,
                                                                                                     RootCertificate);
              }
              break;
          }
          case Clusters::OperationalCredentials::Commands::Ids::OpCSRRequest: {
              expectArgumentCount = 1;
              chip::ByteSpan CSRNonce;
              bool argExists[1];
  
              memset(argExists, 0, sizeof argExists);
  
              while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR)
              {
                  // Since call to aDataTlv.Next() is CHIP_NO_ERROR, the read head always points to an element.
                  // Skip this element if it is not a ContextTag, not consider it as an error if other values are valid.
                  if (!TLV::IsContextTag(aDataTlv.GetTag()))
                  {
                      continue;
                  }
                  currentDecodeTagId = TLV::TagNumFromTag(aDataTlv.GetTag());
                  if (currentDecodeTagId < 1)
                  {
                      if (argExists[currentDecodeTagId])
                      {
                          ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
                          TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
                          break;
                      }
                      else
                      {
                          argExists[currentDecodeTagId] = true;
                          validArgumentCount++;
                      }
                  }
                  switch (currentDecodeTagId)
                  {
                  case 0: {
                      const uint8_t * data = nullptr;
                      TLVUnpackError       = aDataTlv.GetDataPtr(data);
                      CSRNonce             = chip::ByteSpan(data, aDataTlv.GetLength());
                  }
                  break;
                  default:
                      // Unsupported tag, ignore it.
                      ChipLogProgress(Zcl, "Unknown TLV tag during processing.");
                      break;
                  }
                  if (CHIP_NO_ERROR != TLVUnpackError)
                  {
                      break;
                  }
              }
  
              if (CHIP_END_OF_TLV == TLVError)
              {
                  // CHIP_END_OF_TLV means we have iterated all items in the structure, which is not a real error.
                  TLVError = CHIP_NO_ERROR;
              }
  
              if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 1 == validArgumentCount)
              {
                  wasHandled = emberAfOperationalCredentialsClusterOpCSRRequestCallback(aEndpointId, apCommandObj, CSRNonce);
              }
              break;
          }
          case Clusters::OperationalCredentials::Commands::Ids::RemoveAllFabrics: {
  
              wasHandled = emberAfOperationalCredentialsClusterRemoveAllFabricsCallback(aEndpointId, apCommandObj);
              break;
          }
          case Clusters::OperationalCredentials::Commands::Ids::RemoveFabric: {
              expectArgumentCount = 3;
              chip::FabricId FabricId;
              chip::NodeId NodeId;
              uint16_t VendorId;
              bool argExists[3];
  
              memset(argExists, 0, sizeof argExists);
  
              while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR)
              {
                  // Since call to aDataTlv.Next() is CHIP_NO_ERROR, the read head always points to an element.
                  // Skip this element if it is not a ContextTag, not consider it as an error if other values are valid.
                  if (!TLV::IsContextTag(aDataTlv.GetTag()))
                  {
                      continue;
                  }
                  currentDecodeTagId = TLV::TagNumFromTag(aDataTlv.GetTag());
                  if (currentDecodeTagId < 3)
                  {
                      if (argExists[currentDecodeTagId])
                      {
                          ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
                          TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
                          break;
                      }
                      else
                      {
                          argExists[currentDecodeTagId] = true;
                          validArgumentCount++;
                      }
                  }
                  switch (currentDecodeTagId)
                  {
                  case 0:
                      TLVUnpackError = aDataTlv.Get(FabricId);
                      break;
                  case 1:
                      TLVUnpackError = aDataTlv.Get(NodeId);
                      break;
                  case 2:
                      TLVUnpackError = aDataTlv.Get(VendorId);
                      break;
                  default:
                      // Unsupported tag, ignore it.
                      ChipLogProgress(Zcl, "Unknown TLV tag during processing.");
                      break;
                  }
                  if (CHIP_NO_ERROR != TLVUnpackError)
                  {
                      break;
                  }
              }
  
              if (CHIP_END_OF_TLV == TLVError)
              {
                  // CHIP_END_OF_TLV means we have iterated all items in the structure, which is not a real error.
                  TLVError = CHIP_NO_ERROR;
              }
  
              if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 3 == validArgumentCount)
              {
                  wasHandled =
                      emberAfOperationalCredentialsClusterRemoveFabricCallback(aEndpointId, apCommandObj, FabricId, NodeId, VendorId);
              }
              break;
          }
          case Clusters::OperationalCredentials::Commands::Ids::RemoveTrustedRootCertificate: {
              expectArgumentCount = 1;
              chip::ByteSpan TrustedRootIdentifier;
              bool argExists[1];
  
              memset(argExists, 0, sizeof argExists);
  
              while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR)
              {
                  // Since call to aDataTlv.Next() is CHIP_NO_ERROR, the read head always points to an element.
                  // Skip this element if it is not a ContextTag, not consider it as an error if other values are valid.
                  if (!TLV::IsContextTag(aDataTlv.GetTag()))
                  {
                      continue;
                  }
                  currentDecodeTagId = TLV::TagNumFromTag(aDataTlv.GetTag());
                  if (currentDecodeTagId < 1)
                  {
                      if (argExists[currentDecodeTagId])
                      {
                          ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
                          TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
                          break;
                      }
                      else
                      {
                          argExists[currentDecodeTagId] = true;
                          validArgumentCount++;
                      }
                  }
                  switch (currentDecodeTagId)
                  {
                  case 0: {
                      const uint8_t * data  = nullptr;
                      TLVUnpackError        = aDataTlv.GetDataPtr(data);
                      TrustedRootIdentifier = chip::ByteSpan(data, aDataTlv.GetLength());
                  }
                  break;
                  default:
                      // Unsupported tag, ignore it.
                      ChipLogProgress(Zcl, "Unknown TLV tag during processing.");
                      break;
                  }
                  if (CHIP_NO_ERROR != TLVUnpackError)
                  {
                      break;
                  }
              }
  
              if (CHIP_END_OF_TLV == TLVError)
              {
                  // CHIP_END_OF_TLV means we have iterated all items in the structure, which is not a real error.
                  TLVError = CHIP_NO_ERROR;
              }
  
              if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 1 == validArgumentCount)
              {
                  wasHandled = emberAfOperationalCredentialsClusterRemoveTrustedRootCertificateCallback(aEndpointId, apCommandObj,
                                                                                                        TrustedRootIdentifier);
              }
              break;
          }
          case Clusters::OperationalCredentials::Commands::Ids::SetFabric: {
              expectArgumentCount = 1;
              uint16_t VendorId;
              bool argExists[1];
  
              memset(argExists, 0, sizeof argExists);
  
              while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR)
              {
                  // Since call to aDataTlv.Next() is CHIP_NO_ERROR, the read head always points to an element.
                  // Skip this element if it is not a ContextTag, not consider it as an error if other values are valid.
                  if (!TLV::IsContextTag(aDataTlv.GetTag()))
                  {
                      continue;
                  }
                  currentDecodeTagId = TLV::TagNumFromTag(aDataTlv.GetTag());
                  if (currentDecodeTagId < 1)
                  {
                      if (argExists[currentDecodeTagId])
                      {
                          ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
                          TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
                          break;
                      }
                      else
                      {
                          argExists[currentDecodeTagId] = true;
                          validArgumentCount++;
                      }
                  }
                  switch (currentDecodeTagId)
                  {
                  case 0:
                      TLVUnpackError = aDataTlv.Get(VendorId);
                      break;
                  default:
                      // Unsupported tag, ignore it.
                      ChipLogProgress(Zcl, "Unknown TLV tag during processing.");
                      break;
                  }
                  if (CHIP_NO_ERROR != TLVUnpackError)
                  {
                      break;
                  }
              }
  
              if (CHIP_END_OF_TLV == TLVError)
              {
                  // CHIP_END_OF_TLV means we have iterated all items in the structure, which is not a real error.
                  TLVError = CHIP_NO_ERROR;
              }
  
              if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 1 == validArgumentCount)
              {
                  wasHandled = emberAfOperationalCredentialsClusterSetFabricCallback(aEndpointId, apCommandObj, VendorId);
              }
              break;
          }
          case Clusters::OperationalCredentials::Commands::Ids::UpdateFabricLabel: {
              expectArgumentCount = 1;
              const uint8_t * Label;
              bool argExists[1];
  
              memset(argExists, 0, sizeof argExists);
  
              while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR)
              {
                  // Since call to aDataTlv.Next() is CHIP_NO_ERROR, the read head always points to an element.
                  // Skip this element if it is not a ContextTag, not consider it as an error if other values are valid.
                  if (!TLV::IsContextTag(aDataTlv.GetTag()))
                  {
                      continue;
                  }
                  currentDecodeTagId = TLV::TagNumFromTag(aDataTlv.GetTag());
                  if (currentDecodeTagId < 1)
                  {
                      if (argExists[currentDecodeTagId])
                      {
                          ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
                          TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
                          break;
                      }
                      else
                      {
                          argExists[currentDecodeTagId] = true;
                          validArgumentCount++;
                      }
                  }
                  switch (currentDecodeTagId)
                  {
                  case 0:
                      // TODO(#5542): The cluster handlers should accept a ByteSpan for all string types.
                      TLVUnpackError = aDataTlv.GetDataPtr(Label);
                      break;
                  default:
                      // Unsupported tag, ignore it.
                      ChipLogProgress(Zcl, "Unknown TLV tag during processing.");
                      break;
                  }
                  if (CHIP_NO_ERROR != TLVUnpackError)
                  {
                      break;
                  }
              }
  
              if (CHIP_END_OF_TLV == TLVError)
              {
                  // CHIP_END_OF_TLV means we have iterated all items in the structure, which is not a real error.
                  TLVError = CHIP_NO_ERROR;
              }
  
              if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 1 == validArgumentCount)
              {
                  wasHandled = emberAfOperationalCredentialsClusterUpdateFabricLabelCallback(aEndpointId, apCommandObj,
                                                                                             const_cast<uint8_t *>(Label));
              }
              break;
          }
          default: {
              // Unrecognized command ID, error status will apply.
              chip::app::CommandPathParams returnStatusParam = { aEndpointId,
                                                                 0, // GroupId
                                                                 Clusters::OperationalCredentials::Id, aCommandId,
                                                                 (chip::app::CommandPathFlags::kEndpointIdValid) };
              apCommandObj->AddStatusCode(returnStatusParam, Protocols::SecureChannel::GeneralStatusCode::kNotFound,
                                          Protocols::SecureChannel::Id,
                                          Protocols::InteractionModel::ProtocolCode::UnsupportedCommand);
              ChipLogError(Zcl, "Unknown command %" PRIx32 " for cluster %" PRIx32, aCommandId, Clusters::OperationalCredentials::Id);
              return;
          }
          }
      }
  
      if (CHIP_NO_ERROR != TLVError || CHIP_NO_ERROR != TLVUnpackError || expectArgumentCount != validArgumentCount || !wasHandled)
      {
          chip::app::CommandPathParams returnStatusParam = { aEndpointId,
                                                             0, // GroupId
                                                             Clusters::OperationalCredentials::Id, aCommandId,
                                                             (chip::app::CommandPathFlags::kEndpointIdValid) };
          apCommandObj->AddStatusCode(returnStatusParam, Protocols::SecureChannel::GeneralStatusCode::kBadRequest,
                                      Protocols::SecureChannel::Id, Protocols::InteractionModel::ProtocolCode::InvalidCommand);
          ChipLogProgress(Zcl,
                          "Failed to dispatch command, %" PRIu32 "/%" PRIu32 " arguments parsed, TLVError=%" CHIP_ERROR_FORMAT
                          ", UnpackError=%" CHIP_ERROR_FORMAT " (last decoded tag = %" PRIu32,
                          validArgumentCount, expectArgumentCount, ChipError::FormatError(TLVError),
                          ChipError::FormatError(TLVUnpackError), currentDecodeTagId);
          // A command with no arguments would never write currentDecodeTagId.  If
          // progress logging is also disabled, it would look unused.  Silence that
          // warning.
          UNUSED_VAR(currentDecodeTagId);
      }
  }
  
  } // namespace OperationalCredentials
  
  namespace Scenes {
  
  void DispatchServerCommand(app::CommandHandler * apCommandObj, CommandId aCommandId, EndpointId aEndpointId,
                             TLV::TLVReader & aDataTlv)
  {
      // We are using TLVUnpackError and TLVError here since both of them can be CHIP_END_OF_TLV
      // When TLVError is CHIP_END_OF_TLV, it means we have iterated all of the items, which is not a real error.
      // Any error value TLVUnpackError means we have received an illegal value.
      // The following variables are used for all commands to save code size.
      CHIP_ERROR TLVError          = CHIP_NO_ERROR;
      CHIP_ERROR TLVUnpackError    = CHIP_NO_ERROR;
      uint32_t validArgumentCount  = 0;
      uint32_t expectArgumentCount = 0;
      uint32_t currentDecodeTagId  = 0;
      bool wasHandled              = false;
      {
          switch (aCommandId)
          {
          case Clusters::Scenes::Commands::Ids::AddScene: {
              expectArgumentCount = 5;
              uint16_t groupId;
              uint8_t sceneId;
              uint16_t transitionTime;
              const uint8_t * sceneName;
              /* TYPE WARNING: array array defaults to */ uint8_t * extensionFieldSets;
              bool argExists[5];
  
              memset(argExists, 0, sizeof argExists);
  
              while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR)
              {
                  // Since call to aDataTlv.Next() is CHIP_NO_ERROR, the read head always points to an element.
                  // Skip this element if it is not a ContextTag, not consider it as an error if other values are valid.
                  if (!TLV::IsContextTag(aDataTlv.GetTag()))
                  {
                      continue;
                  }
                  currentDecodeTagId = TLV::TagNumFromTag(aDataTlv.GetTag());
                  if (currentDecodeTagId < 5)
                  {
                      if (argExists[currentDecodeTagId])
                      {
                          ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
                          TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
                          break;
                      }
                      else
                      {
                          argExists[currentDecodeTagId] = true;
                          validArgumentCount++;
                      }
                  }
                  switch (currentDecodeTagId)
                  {
                  case 0:
                      TLVUnpackError = aDataTlv.Get(groupId);
                      break;
                  case 1:
                      TLVUnpackError = aDataTlv.Get(sceneId);
                      break;
                  case 2:
                      TLVUnpackError = aDataTlv.Get(transitionTime);
                      break;
                  case 3:
                      // TODO(#5542): The cluster handlers should accept a ByteSpan for all string types.
                      TLVUnpackError = aDataTlv.GetDataPtr(sceneName);
                      break;
                  case 4:
                      // Just for compatibility, we will add array type support in IM later.
                      TLVUnpackError = aDataTlv.GetDataPtr(const_cast<const uint8_t *&>(extensionFieldSets));
                      break;
                  default:
                      // Unsupported tag, ignore it.
                      ChipLogProgress(Zcl, "Unknown TLV tag during processing.");
                      break;
                  }
                  if (CHIP_NO_ERROR != TLVUnpackError)
                  {
                      break;
                  }
              }
  
              if (CHIP_END_OF_TLV == TLVError)
              {
                  // CHIP_END_OF_TLV means we have iterated all items in the structure, which is not a real error.
                  TLVError = CHIP_NO_ERROR;
              }
  
              if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 5 == validArgumentCount)
              {
                  wasHandled = emberAfScenesClusterAddSceneCallback(aEndpointId, apCommandObj, groupId, sceneId, transitionTime,
                                                                    const_cast<uint8_t *>(sceneName), extensionFieldSets);
              }
              break;
          }
          case Clusters::Scenes::Commands::Ids::GetSceneMembership: {
              expectArgumentCount = 1;
              uint16_t groupId;
              bool argExists[1];
  
              memset(argExists, 0, sizeof argExists);
  
              while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR)
              {
                  // Since call to aDataTlv.Next() is CHIP_NO_ERROR, the read head always points to an element.
                  // Skip this element if it is not a ContextTag, not consider it as an error if other values are valid.
                  if (!TLV::IsContextTag(aDataTlv.GetTag()))
                  {
                      continue;
                  }
                  currentDecodeTagId = TLV::TagNumFromTag(aDataTlv.GetTag());
                  if (currentDecodeTagId < 1)
                  {
                      if (argExists[currentDecodeTagId])
                      {
                          ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
                          TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
                          break;
                      }
                      else
                      {
                          argExists[currentDecodeTagId] = true;
                          validArgumentCount++;
                      }
                  }
                  switch (currentDecodeTagId)
                  {
                  case 0:
                      TLVUnpackError = aDataTlv.Get(groupId);
                      break;
                  default:
                      // Unsupported tag, ignore it.
                      ChipLogProgress(Zcl, "Unknown TLV tag during processing.");
                      break;
                  }
                  if (CHIP_NO_ERROR != TLVUnpackError)
                  {
                      break;
                  }
              }
  
              if (CHIP_END_OF_TLV == TLVError)
              {
                  // CHIP_END_OF_TLV means we have iterated all items in the structure, which is not a real error.
                  TLVError = CHIP_NO_ERROR;
              }
  
              if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 1 == validArgumentCount)
              {
                  wasHandled = emberAfScenesClusterGetSceneMembershipCallback(aEndpointId, apCommandObj, groupId);
              }
              break;
          }
          case Clusters::Scenes::Commands::Ids::RecallScene: {
              expectArgumentCount = 3;
              uint16_t groupId;
              uint8_t sceneId;
              uint16_t transitionTime;
              bool argExists[3];
  
              memset(argExists, 0, sizeof argExists);
  
              while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR)
              {
                  // Since call to aDataTlv.Next() is CHIP_NO_ERROR, the read head always points to an element.
                  // Skip this element if it is not a ContextTag, not consider it as an error if other values are valid.
                  if (!TLV::IsContextTag(aDataTlv.GetTag()))
                  {
                      continue;
                  }
                  currentDecodeTagId = TLV::TagNumFromTag(aDataTlv.GetTag());
                  if (currentDecodeTagId < 3)
                  {
                      if (argExists[currentDecodeTagId])
                      {
                          ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
                          TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
                          break;
                      }
                      else
                      {
                          argExists[currentDecodeTagId] = true;
                          validArgumentCount++;
                      }
                  }
                  switch (currentDecodeTagId)
                  {
                  case 0:
                      TLVUnpackError = aDataTlv.Get(groupId);
                      break;
                  case 1:
                      TLVUnpackError = aDataTlv.Get(sceneId);
                      break;
                  case 2:
                      TLVUnpackError = aDataTlv.Get(transitionTime);
                      break;
                  default:
                      // Unsupported tag, ignore it.
                      ChipLogProgress(Zcl, "Unknown TLV tag during processing.");
                      break;
                  }
                  if (CHIP_NO_ERROR != TLVUnpackError)
                  {
                      break;
                  }
              }
  
              if (CHIP_END_OF_TLV == TLVError)
              {
                  // CHIP_END_OF_TLV means we have iterated all items in the structure, which is not a real error.
                  TLVError = CHIP_NO_ERROR;
              }
  
              if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 3 == validArgumentCount)
              {
                  wasHandled = emberAfScenesClusterRecallSceneCallback(aEndpointId, apCommandObj, groupId, sceneId, transitionTime);
              }
              break;
          }
          case Clusters::Scenes::Commands::Ids::RemoveAllScenes: {
              expectArgumentCount = 1;
              uint16_t groupId;
              bool argExists[1];
  
              memset(argExists, 0, sizeof argExists);
  
              while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR)
              {
                  // Since call to aDataTlv.Next() is CHIP_NO_ERROR, the read head always points to an element.
                  // Skip this element if it is not a ContextTag, not consider it as an error if other values are valid.
                  if (!TLV::IsContextTag(aDataTlv.GetTag()))
                  {
                      continue;
                  }
                  currentDecodeTagId = TLV::TagNumFromTag(aDataTlv.GetTag());
                  if (currentDecodeTagId < 1)
                  {
                      if (argExists[currentDecodeTagId])
                      {
                          ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
                          TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
                          break;
                      }
                      else
                      {
                          argExists[currentDecodeTagId] = true;
                          validArgumentCount++;
                      }
                  }
                  switch (currentDecodeTagId)
                  {
                  case 0:
                      TLVUnpackError = aDataTlv.Get(groupId);
                      break;
                  default:
                      // Unsupported tag, ignore it.
                      ChipLogProgress(Zcl, "Unknown TLV tag during processing.");
                      break;
                  }
                  if (CHIP_NO_ERROR != TLVUnpackError)
                  {
                      break;
                  }
              }
  
              if (CHIP_END_OF_TLV == TLVError)
              {
                  // CHIP_END_OF_TLV means we have iterated all items in the structure, which is not a real error.
                  TLVError = CHIP_NO_ERROR;
              }
  
              if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 1 == validArgumentCount)
              {
                  wasHandled = emberAfScenesClusterRemoveAllScenesCallback(aEndpointId, apCommandObj, groupId);
              }
              break;
          }
          case Clusters::Scenes::Commands::Ids::RemoveScene: {
              expectArgumentCount = 2;
              uint16_t groupId;
              uint8_t sceneId;
              bool argExists[2];
  
              memset(argExists, 0, sizeof argExists);
  
              while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR)
              {
                  // Since call to aDataTlv.Next() is CHIP_NO_ERROR, the read head always points to an element.
                  // Skip this element if it is not a ContextTag, not consider it as an error if other values are valid.
                  if (!TLV::IsContextTag(aDataTlv.GetTag()))
                  {
                      continue;
                  }
                  currentDecodeTagId = TLV::TagNumFromTag(aDataTlv.GetTag());
                  if (currentDecodeTagId < 2)
                  {
                      if (argExists[currentDecodeTagId])
                      {
                          ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
                          TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
                          break;
                      }
                      else
                      {
                          argExists[currentDecodeTagId] = true;
                          validArgumentCount++;
                      }
                  }
                  switch (currentDecodeTagId)
                  {
                  case 0:
                      TLVUnpackError = aDataTlv.Get(groupId);
                      break;
                  case 1:
                      TLVUnpackError = aDataTlv.Get(sceneId);
                      break;
                  default:
                      // Unsupported tag, ignore it.
                      ChipLogProgress(Zcl, "Unknown TLV tag during processing.");
                      break;
                  }
                  if (CHIP_NO_ERROR != TLVUnpackError)
                  {
                      break;
                  }
              }
  
              if (CHIP_END_OF_TLV == TLVError)
              {
                  // CHIP_END_OF_TLV means we have iterated all items in the structure, which is not a real error.
                  TLVError = CHIP_NO_ERROR;
              }
  
              if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 2 == validArgumentCount)
              {
                  wasHandled = emberAfScenesClusterRemoveSceneCallback(aEndpointId, apCommandObj, groupId, sceneId);
              }
              break;
          }
          case Clusters::Scenes::Commands::Ids::StoreScene: {
              expectArgumentCount = 2;
              uint16_t groupId;
              uint8_t sceneId;
              bool argExists[2];
  
              memset(argExists, 0, sizeof argExists);
  
              while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR)
              {
                  // Since call to aDataTlv.Next() is CHIP_NO_ERROR, the read head always points to an element.
                  // Skip this element if it is not a ContextTag, not consider it as an error if other values are valid.
                  if (!TLV::IsContextTag(aDataTlv.GetTag()))
                  {
                      continue;
                  }
                  currentDecodeTagId = TLV::TagNumFromTag(aDataTlv.GetTag());
                  if (currentDecodeTagId < 2)
                  {
                      if (argExists[currentDecodeTagId])
                      {
                          ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
                          TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
                          break;
                      }
                      else
                      {
                          argExists[currentDecodeTagId] = true;
                          validArgumentCount++;
                      }
                  }
                  switch (currentDecodeTagId)
                  {
                  case 0:
                      TLVUnpackError = aDataTlv.Get(groupId);
                      break;
                  case 1:
                      TLVUnpackError = aDataTlv.Get(sceneId);
                      break;
                  default:
                      // Unsupported tag, ignore it.
                      ChipLogProgress(Zcl, "Unknown TLV tag during processing.");
                      break;
                  }
                  if (CHIP_NO_ERROR != TLVUnpackError)
                  {
                      break;
                  }
              }
  
              if (CHIP_END_OF_TLV == TLVError)
              {
                  // CHIP_END_OF_TLV means we have iterated all items in the structure, which is not a real error.
                  TLVError = CHIP_NO_ERROR;
              }
  
              if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 2 == validArgumentCount)
              {
                  wasHandled = emberAfScenesClusterStoreSceneCallback(aEndpointId, apCommandObj, groupId, sceneId);
              }
              break;
          }
          case Clusters::Scenes::Commands::Ids::ViewScene: {
              expectArgumentCount = 2;
              uint16_t groupId;
              uint8_t sceneId;
              bool argExists[2];
  
              memset(argExists, 0, sizeof argExists);
  
              while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR)
              {
                  // Since call to aDataTlv.Next() is CHIP_NO_ERROR, the read head always points to an element.
                  // Skip this element if it is not a ContextTag, not consider it as an error if other values are valid.
                  if (!TLV::IsContextTag(aDataTlv.GetTag()))
                  {
                      continue;
                  }
                  currentDecodeTagId = TLV::TagNumFromTag(aDataTlv.GetTag());
                  if (currentDecodeTagId < 2)
                  {
                      if (argExists[currentDecodeTagId])
                      {
                          ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
                          TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
                          break;
                      }
                      else
                      {
                          argExists[currentDecodeTagId] = true;
                          validArgumentCount++;
                      }
                  }
                  switch (currentDecodeTagId)
                  {
                  case 0:
                      TLVUnpackError = aDataTlv.Get(groupId);
                      break;
                  case 1:
                      TLVUnpackError = aDataTlv.Get(sceneId);
                      break;
                  default:
                      // Unsupported tag, ignore it.
                      ChipLogProgress(Zcl, "Unknown TLV tag during processing.");
                      break;
                  }
                  if (CHIP_NO_ERROR != TLVUnpackError)
                  {
                      break;
                  }
              }
  
              if (CHIP_END_OF_TLV == TLVError)
              {
                  // CHIP_END_OF_TLV means we have iterated all items in the structure, which is not a real error.
                  TLVError = CHIP_NO_ERROR;
              }
  
              if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 2 == validArgumentCount)
              {
                  wasHandled = emberAfScenesClusterViewSceneCallback(aEndpointId, apCommandObj, groupId, sceneId);
              }
              break;
          }
          default: {
              // Unrecognized command ID, error status will apply.
              chip::app::CommandPathParams returnStatusParam = { aEndpointId,
                                                                 0, // GroupId
                                                                 Clusters::Scenes::Id, aCommandId,
                                                                 (chip::app::CommandPathFlags::kEndpointIdValid) };
              apCommandObj->AddStatusCode(returnStatusParam, Protocols::SecureChannel::GeneralStatusCode::kNotFound,
                                          Protocols::SecureChannel::Id,
                                          Protocols::InteractionModel::ProtocolCode::UnsupportedCommand);
              ChipLogError(Zcl, "Unknown command %" PRIx32 " for cluster %" PRIx32, aCommandId, Clusters::Scenes::Id);
              return;
          }
          }
      }
  
      if (CHIP_NO_ERROR != TLVError || CHIP_NO_ERROR != TLVUnpackError || expectArgumentCount != validArgumentCount || !wasHandled)
      {
          chip::app::CommandPathParams returnStatusParam = { aEndpointId,
                                                             0, // GroupId
                                                             Clusters::Scenes::Id, aCommandId,
                                                             (chip::app::CommandPathFlags::kEndpointIdValid) };
          apCommandObj->AddStatusCode(returnStatusParam, Protocols::SecureChannel::GeneralStatusCode::kBadRequest,
                                      Protocols::SecureChannel::Id, Protocols::InteractionModel::ProtocolCode::InvalidCommand);
          ChipLogProgress(Zcl,
                          "Failed to dispatch command, %" PRIu32 "/%" PRIu32 " arguments parsed, TLVError=%" CHIP_ERROR_FORMAT
                          ", UnpackError=%" CHIP_ERROR_FORMAT " (last decoded tag = %" PRIu32,
                          validArgumentCount, expectArgumentCount, ChipError::FormatError(TLVError),
                          ChipError::FormatError(TLVUnpackError), currentDecodeTagId);
          // A command with no arguments would never write currentDecodeTagId.  If
          // progress logging is also disabled, it would look unused.  Silence that
          // warning.
          UNUSED_VAR(currentDecodeTagId);
      }
  }
  
  } // namespace Scenes
  
  namespace SoftwareDiagnostics {
  
  void DispatchServerCommand(app::CommandHandler * apCommandObj, CommandId aCommandId, EndpointId aEndpointId,
                             TLV::TLVReader & aDataTlv)
  {
      // We are using TLVUnpackError and TLVError here since both of them can be CHIP_END_OF_TLV
      // When TLVError is CHIP_END_OF_TLV, it means we have iterated all of the items, which is not a real error.
      // Any error value TLVUnpackError means we have received an illegal value.
      // The following variables are used for all commands to save code size.
      CHIP_ERROR TLVError          = CHIP_NO_ERROR;
      CHIP_ERROR TLVUnpackError    = CHIP_NO_ERROR;
      uint32_t validArgumentCount  = 0;
      uint32_t expectArgumentCount = 0;
      uint32_t currentDecodeTagId  = 0;
      bool wasHandled              = false;
      {
          switch (aCommandId)
          {
          case Clusters::SoftwareDiagnostics::Commands::Ids::ResetWatermarks: {
  
              wasHandled = emberAfSoftwareDiagnosticsClusterResetWatermarksCallback(aEndpointId, apCommandObj);
              break;
          }
          default: {
              // Unrecognized command ID, error status will apply.
              chip::app::CommandPathParams returnStatusParam = { aEndpointId,
                                                                 0, // GroupId
                                                                 Clusters::SoftwareDiagnostics::Id, aCommandId,
                                                                 (chip::app::CommandPathFlags::kEndpointIdValid) };
              apCommandObj->AddStatusCode(returnStatusParam, Protocols::SecureChannel::GeneralStatusCode::kNotFound,
                                          Protocols::SecureChannel::Id,
                                          Protocols::InteractionModel::ProtocolCode::UnsupportedCommand);
              ChipLogError(Zcl, "Unknown command %" PRIx32 " for cluster %" PRIx32, aCommandId, Clusters::SoftwareDiagnostics::Id);
              return;
          }
          }
      }
  
      if (CHIP_NO_ERROR != TLVError || CHIP_NO_ERROR != TLVUnpackError || expectArgumentCount != validArgumentCount || !wasHandled)
      {
          chip::app::CommandPathParams returnStatusParam = { aEndpointId,
                                                             0, // GroupId
                                                             Clusters::SoftwareDiagnostics::Id, aCommandId,
                                                             (chip::app::CommandPathFlags::kEndpointIdValid) };
          apCommandObj->AddStatusCode(returnStatusParam, Protocols::SecureChannel::GeneralStatusCode::kBadRequest,
                                      Protocols::SecureChannel::Id, Protocols::InteractionModel::ProtocolCode::InvalidCommand);
          ChipLogProgress(Zcl,
                          "Failed to dispatch command, %" PRIu32 "/%" PRIu32 " arguments parsed, TLVError=%" CHIP_ERROR_FORMAT
                          ", UnpackError=%" CHIP_ERROR_FORMAT " (last decoded tag = %" PRIu32,
                          validArgumentCount, expectArgumentCount, ChipError::FormatError(TLVError),
                          ChipError::FormatError(TLVUnpackError), currentDecodeTagId);
          // A command with no arguments would never write currentDecodeTagId.  If
          // progress logging is also disabled, it would look unused.  Silence that
          // warning.
          UNUSED_VAR(currentDecodeTagId);
      }
  }
  
  } // namespace SoftwareDiagnostics
  
  namespace TestCluster {
  
  void DispatchServerCommand(app::CommandHandler * apCommandObj, CommandId aCommandId, EndpointId aEndpointId,
                             TLV::TLVReader & aDataTlv)
  {
      // We are using TLVUnpackError and TLVError here since both of them can be CHIP_END_OF_TLV
      // When TLVError is CHIP_END_OF_TLV, it means we have iterated all of the items, which is not a real error.
      // Any error value TLVUnpackError means we have received an illegal value.
      // The following variables are used for all commands to save code size.
      CHIP_ERROR TLVError          = CHIP_NO_ERROR;
      CHIP_ERROR TLVUnpackError    = CHIP_NO_ERROR;
      uint32_t validArgumentCount  = 0;
      uint32_t expectArgumentCount = 0;
      uint32_t currentDecodeTagId  = 0;
      bool wasHandled              = false;
      {
          switch (aCommandId)
          {
          case Clusters::TestCluster::Commands::Ids::Test: {
  
              wasHandled = emberAfTestClusterClusterTestCallback(aEndpointId, apCommandObj);
              break;
          }
          case Clusters::TestCluster::Commands::Ids::TestAddArguments: {
              expectArgumentCount = 2;
              uint8_t arg1;
              uint8_t arg2;
              bool argExists[2];
  
              memset(argExists, 0, sizeof argExists);
  
              while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR)
              {
                  // Since call to aDataTlv.Next() is CHIP_NO_ERROR, the read head always points to an element.
                  // Skip this element if it is not a ContextTag, not consider it as an error if other values are valid.
                  if (!TLV::IsContextTag(aDataTlv.GetTag()))
                  {
                      continue;
                  }
                  currentDecodeTagId = TLV::TagNumFromTag(aDataTlv.GetTag());
                  if (currentDecodeTagId < 2)
                  {
                      if (argExists[currentDecodeTagId])
                      {
                          ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
                          TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
                          break;
                      }
                      else
                      {
                          argExists[currentDecodeTagId] = true;
                          validArgumentCount++;
                      }
                  }
                  switch (currentDecodeTagId)
                  {
                  case 0:
                      TLVUnpackError = aDataTlv.Get(arg1);
                      break;
                  case 1:
                      TLVUnpackError = aDataTlv.Get(arg2);
                      break;
                  default:
                      // Unsupported tag, ignore it.
                      ChipLogProgress(Zcl, "Unknown TLV tag during processing.");
                      break;
                  }
                  if (CHIP_NO_ERROR != TLVUnpackError)
                  {
                      break;
                  }
              }
  
              if (CHIP_END_OF_TLV == TLVError)
              {
                  // CHIP_END_OF_TLV means we have iterated all items in the structure, which is not a real error.
                  TLVError = CHIP_NO_ERROR;
              }
  
              if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 2 == validArgumentCount)
              {
                  wasHandled = emberAfTestClusterClusterTestAddArgumentsCallback(aEndpointId, apCommandObj, arg1, arg2);
              }
              break;
          }
          case Clusters::TestCluster::Commands::Ids::TestNotHandled: {
  
              wasHandled = emberAfTestClusterClusterTestNotHandledCallback(aEndpointId, apCommandObj);
              break;
          }
          case Clusters::TestCluster::Commands::Ids::TestSpecific: {
  
              wasHandled = emberAfTestClusterClusterTestSpecificCallback(aEndpointId, apCommandObj);
              break;
          }
          default: {
              // Unrecognized command ID, error status will apply.
              chip::app::CommandPathParams returnStatusParam = { aEndpointId,
                                                                 0, // GroupId
                                                                 Clusters::TestCluster::Id, aCommandId,
                                                                 (chip::app::CommandPathFlags::kEndpointIdValid) };
              apCommandObj->AddStatusCode(returnStatusParam, Protocols::SecureChannel::GeneralStatusCode::kNotFound,
                                          Protocols::SecureChannel::Id,
                                          Protocols::InteractionModel::ProtocolCode::UnsupportedCommand);
              ChipLogError(Zcl, "Unknown command %" PRIx32 " for cluster %" PRIx32, aCommandId, Clusters::TestCluster::Id);
              return;
          }
          }
      }
  
      if (CHIP_NO_ERROR != TLVError || CHIP_NO_ERROR != TLVUnpackError || expectArgumentCount != validArgumentCount || !wasHandled)
      {
          chip::app::CommandPathParams returnStatusParam = { aEndpointId,
                                                             0, // GroupId
                                                             Clusters::TestCluster::Id, aCommandId,
                                                             (chip::app::CommandPathFlags::kEndpointIdValid) };
          apCommandObj->AddStatusCode(returnStatusParam, Protocols::SecureChannel::GeneralStatusCode::kBadRequest,
                                      Protocols::SecureChannel::Id, Protocols::InteractionModel::ProtocolCode::InvalidCommand);
          ChipLogProgress(Zcl,
                          "Failed to dispatch command, %" PRIu32 "/%" PRIu32 " arguments parsed, TLVError=%" CHIP_ERROR_FORMAT
                          ", UnpackError=%" CHIP_ERROR_FORMAT " (last decoded tag = %" PRIu32,
                          validArgumentCount, expectArgumentCount, ChipError::FormatError(TLVError),
                          ChipError::FormatError(TLVUnpackError), currentDecodeTagId);
          // A command with no arguments would never write currentDecodeTagId.  If
          // progress logging is also disabled, it would look unused.  Silence that
          // warning.
          UNUSED_VAR(currentDecodeTagId);
      }
  }
  
  } // namespace TestCluster
  
  namespace ThreadNetworkDiagnostics {
  
  void DispatchServerCommand(app::CommandHandler * apCommandObj, CommandId aCommandId, EndpointId aEndpointId,
                             TLV::TLVReader & aDataTlv)
  {
      // We are using TLVUnpackError and TLVError here since both of them can be CHIP_END_OF_TLV
      // When TLVError is CHIP_END_OF_TLV, it means we have iterated all of the items, which is not a real error.
      // Any error value TLVUnpackError means we have received an illegal value.
      // The following variables are used for all commands to save code size.
      CHIP_ERROR TLVError          = CHIP_NO_ERROR;
      CHIP_ERROR TLVUnpackError    = CHIP_NO_ERROR;
      uint32_t validArgumentCount  = 0;
      uint32_t expectArgumentCount = 0;
      uint32_t currentDecodeTagId  = 0;
      bool wasHandled              = false;
      {
          switch (aCommandId)
          {
          case Clusters::ThreadNetworkDiagnostics::Commands::Ids::ResetCounts: {
  
              wasHandled = emberAfThreadNetworkDiagnosticsClusterResetCountsCallback(aEndpointId, apCommandObj);
              break;
          }
          default: {
              // Unrecognized command ID, error status will apply.
              chip::app::CommandPathParams returnStatusParam = { aEndpointId,
                                                                 0, // GroupId
                                                                 Clusters::ThreadNetworkDiagnostics::Id, aCommandId,
                                                                 (chip::app::CommandPathFlags::kEndpointIdValid) };
              apCommandObj->AddStatusCode(returnStatusParam, Protocols::SecureChannel::GeneralStatusCode::kNotFound,
                                          Protocols::SecureChannel::Id,
                                          Protocols::InteractionModel::ProtocolCode::UnsupportedCommand);
              ChipLogError(Zcl, "Unknown command %" PRIx32 " for cluster %" PRIx32, aCommandId,
                           Clusters::ThreadNetworkDiagnostics::Id);
              return;
          }
          }
      }
  
      if (CHIP_NO_ERROR != TLVError || CHIP_NO_ERROR != TLVUnpackError || expectArgumentCount != validArgumentCount || !wasHandled)
      {
          chip::app::CommandPathParams returnStatusParam = { aEndpointId,
                                                             0, // GroupId
                                                             Clusters::ThreadNetworkDiagnostics::Id, aCommandId,
                                                             (chip::app::CommandPathFlags::kEndpointIdValid) };
          apCommandObj->AddStatusCode(returnStatusParam, Protocols::SecureChannel::GeneralStatusCode::kBadRequest,
                                      Protocols::SecureChannel::Id, Protocols::InteractionModel::ProtocolCode::InvalidCommand);
          ChipLogProgress(Zcl,
                          "Failed to dispatch command, %" PRIu32 "/%" PRIu32 " arguments parsed, TLVError=%" CHIP_ERROR_FORMAT
                          ", UnpackError=%" CHIP_ERROR_FORMAT " (last decoded tag = %" PRIu32,
                          validArgumentCount, expectArgumentCount, ChipError::FormatError(TLVError),
                          ChipError::FormatError(TLVUnpackError), currentDecodeTagId);
          // A command with no arguments would never write currentDecodeTagId.  If
          // progress logging is also disabled, it would look unused.  Silence that
          // warning.
          UNUSED_VAR(currentDecodeTagId);
      }
  }
  
  } // namespace ThreadNetworkDiagnostics
  
  namespace WiFiNetworkDiagnostics {
  
  void DispatchServerCommand(app::CommandHandler * apCommandObj, CommandId aCommandId, EndpointId aEndpointId,
                             TLV::TLVReader & aDataTlv)
  {
      // We are using TLVUnpackError and TLVError here since both of them can be CHIP_END_OF_TLV
      // When TLVError is CHIP_END_OF_TLV, it means we have iterated all of the items, which is not a real error.
      // Any error value TLVUnpackError means we have received an illegal value.
      // The following variables are used for all commands to save code size.
      CHIP_ERROR TLVError          = CHIP_NO_ERROR;
      CHIP_ERROR TLVUnpackError    = CHIP_NO_ERROR;
      uint32_t validArgumentCount  = 0;
      uint32_t expectArgumentCount = 0;
      uint32_t currentDecodeTagId  = 0;
      bool wasHandled              = false;
      {
          switch (aCommandId)
          {
          case Clusters::WiFiNetworkDiagnostics::Commands::Ids::ResetCounts: {
  
              wasHandled = emberAfWiFiNetworkDiagnosticsClusterResetCountsCallback(aEndpointId, apCommandObj);
              break;
          }
          default: {
              // Unrecognized command ID, error status will apply.
              chip::app::CommandPathParams returnStatusParam = { aEndpointId,
                                                                 0, // GroupId
                                                                 Clusters::WiFiNetworkDiagnostics::Id, aCommandId,
                                                                 (chip::app::CommandPathFlags::kEndpointIdValid) };
              apCommandObj->AddStatusCode(returnStatusParam, Protocols::SecureChannel::GeneralStatusCode::kNotFound,
                                          Protocols::SecureChannel::Id,
                                          Protocols::InteractionModel::ProtocolCode::UnsupportedCommand);
              ChipLogError(Zcl, "Unknown command %" PRIx32 " for cluster %" PRIx32, aCommandId, Clusters::WiFiNetworkDiagnostics::Id);
              return;
          }
          }
      }
  
      if (CHIP_NO_ERROR != TLVError || CHIP_NO_ERROR != TLVUnpackError || expectArgumentCount != validArgumentCount || !wasHandled)
      {
          chip::app::CommandPathParams returnStatusParam = { aEndpointId,
                                                             0, // GroupId
                                                             Clusters::WiFiNetworkDiagnostics::Id, aCommandId,
                                                             (chip::app::CommandPathFlags::kEndpointIdValid) };
          apCommandObj->AddStatusCode(returnStatusParam, Protocols::SecureChannel::GeneralStatusCode::kBadRequest,
                                      Protocols::SecureChannel::Id, Protocols::InteractionModel::ProtocolCode::InvalidCommand);
          ChipLogProgress(Zcl,
                          "Failed to dispatch command, %" PRIu32 "/%" PRIu32 " arguments parsed, TLVError=%" CHIP_ERROR_FORMAT
                          ", UnpackError=%" CHIP_ERROR_FORMAT " (last decoded tag = %" PRIu32,
                          validArgumentCount, expectArgumentCount, ChipError::FormatError(TLVError),
                          ChipError::FormatError(TLVUnpackError), currentDecodeTagId);
          // A command with no arguments would never write currentDecodeTagId.  If
          // progress logging is also disabled, it would look unused.  Silence that
          // warning.
          UNUSED_VAR(currentDecodeTagId);
      }
  }
  
  } // namespace WiFiNetworkDiagnostics
  
  } // namespace clusters
  
  void DispatchSingleClusterCommand(chip::ClusterId aClusterId, chip::CommandId aCommandId, chip::EndpointId aEndPointId,
                                    chip::TLV::TLVReader & aReader, CommandHandler * apCommandObj)
  {
      ChipLogDetail(Zcl, "Received Cluster Command: Cluster=%" PRIx32 " Command=%" PRIx32 " Endpoint=%" PRIx16, aClusterId,
                    aCommandId, aEndPointId);
      Compatibility::SetupEmberAfObjects(apCommandObj, aClusterId, aCommandId, aEndPointId);
      TLV::TLVType dataTlvType;
      SuccessOrExit(aReader.EnterContainer(dataTlvType));
      switch (aClusterId)
      {
      case Clusters::BarrierControl::Id:
          clusters::BarrierControl::DispatchServerCommand(apCommandObj, aCommandId, aEndPointId, aReader);
          break;
      case Clusters::Basic::Id:
          clusters::Basic::DispatchServerCommand(apCommandObj, aCommandId, aEndPointId, aReader);
          break;
      case Clusters::Binding::Id:
          clusters::Binding::DispatchServerCommand(apCommandObj, aCommandId, aEndPointId, aReader);
          break;
      case Clusters::ColorControl::Id:
          clusters::ColorControl::DispatchServerCommand(apCommandObj, aCommandId, aEndPointId, aReader);
          break;
      case Clusters::DiagnosticLogs::Id:
          clusters::DiagnosticLogs::DispatchServerCommand(apCommandObj, aCommandId, aEndPointId, aReader);
          break;
      case Clusters::DoorLock::Id:
          clusters::DoorLock::DispatchServerCommand(apCommandObj, aCommandId, aEndPointId, aReader);
          break;
      case Clusters::EthernetNetworkDiagnostics::Id:
          clusters::EthernetNetworkDiagnostics::DispatchServerCommand(apCommandObj, aCommandId, aEndPointId, aReader);
          break;
      case Clusters::GeneralCommissioning::Id:
          clusters::GeneralCommissioning::DispatchServerCommand(apCommandObj, aCommandId, aEndPointId, aReader);
          break;
      case Clusters::Groups::Id:
          clusters::Groups::DispatchServerCommand(apCommandObj, aCommandId, aEndPointId, aReader);
          break;
      case Clusters::IasZone::Id:
          clusters::IasZone::DispatchServerCommand(apCommandObj, aCommandId, aEndPointId, aReader);
          break;
      case Clusters::Identify::Id:
          clusters::Identify::DispatchServerCommand(apCommandObj, aCommandId, aEndPointId, aReader);
          break;
      case Clusters::LevelControl::Id:
          clusters::LevelControl::DispatchServerCommand(apCommandObj, aCommandId, aEndPointId, aReader);
          break;
      case Clusters::LowPower::Id:
          clusters::LowPower::DispatchServerCommand(apCommandObj, aCommandId, aEndPointId, aReader);
          break;
      case Clusters::NetworkCommissioning::Id:
          clusters::NetworkCommissioning::DispatchServerCommand(apCommandObj, aCommandId, aEndPointId, aReader);
          break;
      case Clusters::OtaSoftwareUpdateProvider::Id:
          clusters::OtaSoftwareUpdateProvider::DispatchServerCommand(apCommandObj, aCommandId, aEndPointId, aReader);
          break;
      case Clusters::OnOff::Id:
          clusters::OnOff::DispatchServerCommand(apCommandObj, aCommandId, aEndPointId, aReader);
          break;
      case Clusters::OperationalCredentials::Id:
          clusters::OperationalCredentials::DispatchServerCommand(apCommandObj, aCommandId, aEndPointId, aReader);
          break;
      case Clusters::Scenes::Id:
          clusters::Scenes::DispatchServerCommand(apCommandObj, aCommandId, aEndPointId, aReader);
          break;
      case Clusters::SoftwareDiagnostics::Id:
          clusters::SoftwareDiagnostics::DispatchServerCommand(apCommandObj, aCommandId, aEndPointId, aReader);
          break;
      case Clusters::TestCluster::Id:
          clusters::TestCluster::DispatchServerCommand(apCommandObj, aCommandId, aEndPointId, aReader);
          break;
      case Clusters::ThreadNetworkDiagnostics::Id:
          clusters::ThreadNetworkDiagnostics::DispatchServerCommand(apCommandObj, aCommandId, aEndPointId, aReader);
          break;
      case Clusters::WiFiNetworkDiagnostics::Id:
          clusters::WiFiNetworkDiagnostics::DispatchServerCommand(apCommandObj, aCommandId, aEndPointId, aReader);
          break;
      default:
          // Unrecognized cluster ID, error status will apply.
          chip::app::CommandPathParams returnStatusParam = { aEndPointId,
                                                             0, // GroupId
                                                             aClusterId, aCommandId,
                                                             (chip::app::CommandPathFlags::kEndpointIdValid) };
          apCommandObj->AddStatusCode(returnStatusParam, Protocols::SecureChannel::GeneralStatusCode::kNotFound,
                                      Protocols::SecureChannel::Id, Protocols::InteractionModel::ProtocolCode::InvalidCommand);
          ChipLogError(Zcl, "Unknown cluster %" PRIx32, aClusterId);
          break;
      }
  exit:
      Compatibility::ResetEmberAfObjects();
      aReader.ExitContainer(dataTlvType);
  }
  
  void DispatchSingleClusterResponseCommand(chip::ClusterId aClusterId, chip::CommandId aCommandId, chip::EndpointId aEndPointId,
                                            chip::TLV::TLVReader & aReader, CommandSender * apCommandObj)
  {
      ChipLogDetail(Zcl, "Received Cluster Command: Cluster=%" PRIx32 " Command=%" PRIx32 " Endpoint=%" PRIx16, aClusterId,
                    aCommandId, aEndPointId);
      Compatibility::SetupEmberAfObjects(apCommandObj, aClusterId, aCommandId, aEndPointId);
      TLV::TLVType dataTlvType;
      SuccessOrExit(aReader.EnterContainer(dataTlvType));
      switch (aClusterId)
      {
      default:
          // Unrecognized cluster ID, error status will apply.
          chip::app::CommandPathParams returnStatusParam = { aEndPointId,
                                                             0, // GroupId
                                                             aClusterId, aCommandId,
                                                             (chip::app::CommandPathFlags::kEndpointIdValid) };
          apCommandObj->AddStatusCode(returnStatusParam, Protocols::SecureChannel::GeneralStatusCode::kNotFound,
                                      Protocols::SecureChannel::Id, Protocols::InteractionModel::ProtocolCode::InvalidCommand);
          ChipLogError(Zcl, "Unknown cluster %" PRIx32, aClusterId);
          break;
      }
  exit:
      Compatibility::ResetEmberAfObjects();
      aReader.ExitContainer(dataTlvType);
  }
  
  } // namespace app
  } // namespace chip
  