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/util/util.h"
  #include <app-common/zap-generated/af-structs.h>
  #include <app-common/zap-generated/callback.h>
  #include <app-common/zap-generated/ids/Clusters.h>
  #include <app-common/zap-generated/ids/Commands.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 {
  
  namespace {
  void ReportCommandUnsupported(Command * aCommandObj, EndpointId aEndpointId, ClusterId aClusterId, CommandId aCommandId)
  {
      CommandPathParams returnStatusParam = { aEndpointId,
                                              0, // GroupId
                                              aClusterId, aCommandId, (CommandPathFlags::kEndpointIdValid) };
      aCommandObj->AddStatusCode(returnStatusParam, Protocols::SecureChannel::GeneralStatusCode::kNotFound,
                                 Protocols::SecureChannel::Id, Protocols::InteractionModel::ProtocolCode::UnsupportedCommand);
      ChipLogError(Zcl, "Unknown command " ChipLogFormatMEI " for cluster " ChipLogFormatMEI, ChipLogValueMEI(aCommandId),
                   ChipLogValueMEI(aClusterId));
  }
  } // anonymous namespace
  
  // Cluster specific command parsing
  
  namespace clusters {
  
  namespace AccountLogin {
  
  void DispatchClientCommand(CommandSender * 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::AccountLogin::Commands::Ids::GetSetupPINResponse: {
              expectArgumentCount = 1;
              const uint8_t * setupPIN;
              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(setupPIN);
                      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 = emberAfAccountLoginClusterGetSetupPINResponseCallback(aEndpointId, apCommandObj,
                                                                                     const_cast<uint8_t *>(setupPIN));
              }
              break;
          }
          default: {
              // Unrecognized command ID, error status will apply.
              ReportCommandUnsupported(apCommandObj, aEndpointId, Clusters::AccountLogin::Id, aCommandId);
              return;
          }
          }
      }
  
      if (CHIP_NO_ERROR != TLVError || CHIP_NO_ERROR != TLVUnpackError || expectArgumentCount != validArgumentCount || !wasHandled)
      {
          CommandPathParams returnStatusParam = { aEndpointId,
                                                  0, // GroupId
                                                  Clusters::AccountLogin::Id, aCommandId, (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, TLVError.Format(), TLVUnpackError.Format(), 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 AccountLogin
  
  namespace ApplicationLauncher {
  
  void DispatchClientCommand(CommandSender * 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::ApplicationLauncher::Commands::Ids::LaunchAppResponse: {
              expectArgumentCount = 2;
              uint8_t status;
              const uint8_t * data;
              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(status);
                      break;
                  case 1:
                      // TODO(#5542): The cluster handlers should accept a ByteSpan for all string types.
                      TLVUnpackError = aDataTlv.GetDataPtr(data);
                      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 = emberAfApplicationLauncherClusterLaunchAppResponseCallback(aEndpointId, apCommandObj, status,
                                                                                          const_cast<uint8_t *>(data));
              }
              break;
          }
          default: {
              // Unrecognized command ID, error status will apply.
              ReportCommandUnsupported(apCommandObj, aEndpointId, Clusters::ApplicationLauncher::Id, aCommandId);
              return;
          }
          }
      }
  
      if (CHIP_NO_ERROR != TLVError || CHIP_NO_ERROR != TLVUnpackError || expectArgumentCount != validArgumentCount || !wasHandled)
      {
          CommandPathParams returnStatusParam = { aEndpointId,
                                                  0, // GroupId
                                                  Clusters::ApplicationLauncher::Id, aCommandId,
                                                  (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, TLVError.Format(), TLVUnpackError.Format(), 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 ApplicationLauncher
  
  namespace ContentLauncher {
  
  void DispatchClientCommand(CommandSender * 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::ContentLauncher::Commands::Ids::LaunchContentResponse: {
              expectArgumentCount = 2;
              const uint8_t * data;
              uint8_t contentLaunchStatus;
              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:
                      // TODO(#5542): The cluster handlers should accept a ByteSpan for all string types.
                      TLVUnpackError = aDataTlv.GetDataPtr(data);
                      break;
                  case 1:
                      TLVUnpackError = aDataTlv.Get(contentLaunchStatus);
                      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 = emberAfContentLauncherClusterLaunchContentResponseCallback(
                      aEndpointId, apCommandObj, const_cast<uint8_t *>(data), contentLaunchStatus);
              }
              break;
          }
          case Clusters::ContentLauncher::Commands::Ids::LaunchURLResponse: {
              expectArgumentCount = 2;
              const uint8_t * data;
              uint8_t contentLaunchStatus;
              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:
                      // TODO(#5542): The cluster handlers should accept a ByteSpan for all string types.
                      TLVUnpackError = aDataTlv.GetDataPtr(data);
                      break;
                  case 1:
                      TLVUnpackError = aDataTlv.Get(contentLaunchStatus);
                      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 = emberAfContentLauncherClusterLaunchURLResponseCallback(
                      aEndpointId, apCommandObj, const_cast<uint8_t *>(data), contentLaunchStatus);
              }
              break;
          }
          default: {
              // Unrecognized command ID, error status will apply.
              ReportCommandUnsupported(apCommandObj, aEndpointId, Clusters::ContentLauncher::Id, aCommandId);
              return;
          }
          }
      }
  
      if (CHIP_NO_ERROR != TLVError || CHIP_NO_ERROR != TLVUnpackError || expectArgumentCount != validArgumentCount || !wasHandled)
      {
          CommandPathParams returnStatusParam = { aEndpointId,
                                                  0, // GroupId
                                                  Clusters::ContentLauncher::Id, aCommandId, (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, TLVError.Format(), TLVUnpackError.Format(), 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 ContentLauncher
  
  namespace DoorLock {
  
  void DispatchClientCommand(CommandSender * 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::ClearAllPinsResponse: {
              expectArgumentCount = 1;
              uint8_t status;
              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(status);
                      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 = emberAfDoorLockClusterClearAllPinsResponseCallback(aEndpointId, apCommandObj, status);
              }
              break;
          }
          case Clusters::DoorLock::Commands::Ids::ClearAllRfidsResponse: {
              expectArgumentCount = 1;
              uint8_t status;
              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(status);
                      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 = emberAfDoorLockClusterClearAllRfidsResponseCallback(aEndpointId, apCommandObj, status);
              }
              break;
          }
          case Clusters::DoorLock::Commands::Ids::ClearHolidayScheduleResponse: {
              expectArgumentCount = 1;
              uint8_t status;
              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(status);
                      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 = emberAfDoorLockClusterClearHolidayScheduleResponseCallback(aEndpointId, apCommandObj, status);
              }
              break;
          }
          case Clusters::DoorLock::Commands::Ids::ClearPinResponse: {
              expectArgumentCount = 1;
              uint8_t status;
              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(status);
                      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 = emberAfDoorLockClusterClearPinResponseCallback(aEndpointId, apCommandObj, status);
              }
              break;
          }
          case Clusters::DoorLock::Commands::Ids::ClearRfidResponse: {
              expectArgumentCount = 1;
              uint8_t status;
              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(status);
                      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 = emberAfDoorLockClusterClearRfidResponseCallback(aEndpointId, apCommandObj, status);
              }
              break;
          }
          case Clusters::DoorLock::Commands::Ids::ClearWeekdayScheduleResponse: {
              expectArgumentCount = 1;
              uint8_t status;
              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(status);
                      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 = emberAfDoorLockClusterClearWeekdayScheduleResponseCallback(aEndpointId, apCommandObj, status);
              }
              break;
          }
          case Clusters::DoorLock::Commands::Ids::ClearYeardayScheduleResponse: {
              expectArgumentCount = 1;
              uint8_t status;
              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(status);
                      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 = emberAfDoorLockClusterClearYeardayScheduleResponseCallback(aEndpointId, apCommandObj, status);
              }
              break;
          }
          case Clusters::DoorLock::Commands::Ids::GetHolidayScheduleResponse: {
              expectArgumentCount = 5;
              uint8_t scheduleId;
              uint8_t status;
              uint32_t localStartTime;
              uint32_t localEndTime;
              uint8_t operatingModeDuringHoliday;
              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(scheduleId);
                      break;
                  case 1:
                      TLVUnpackError = aDataTlv.Get(status);
                      break;
                  case 2:
                      TLVUnpackError = aDataTlv.Get(localStartTime);
                      break;
                  case 3:
                      TLVUnpackError = aDataTlv.Get(localEndTime);
                      break;
                  case 4:
                      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 && 5 == validArgumentCount)
              {
                  wasHandled = emberAfDoorLockClusterGetHolidayScheduleResponseCallback(
                      aEndpointId, apCommandObj, scheduleId, status, localStartTime, localEndTime, operatingModeDuringHoliday);
              }
              break;
          }
          case Clusters::DoorLock::Commands::Ids::GetLogRecordResponse: {
              expectArgumentCount = 7;
              uint16_t logEntryId;
              uint32_t timestamp;
              uint8_t eventType;
              uint8_t source;
              uint8_t eventIdOrAlarmCode;
              uint16_t userId;
              const uint8_t * pin;
              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(logEntryId);
                      break;
                  case 1:
                      TLVUnpackError = aDataTlv.Get(timestamp);
                      break;
                  case 2:
                      TLVUnpackError = aDataTlv.Get(eventType);
                      break;
                  case 3:
                      TLVUnpackError = aDataTlv.Get(source);
                      break;
                  case 4:
                      TLVUnpackError = aDataTlv.Get(eventIdOrAlarmCode);
                      break;
                  case 5:
                      TLVUnpackError = aDataTlv.Get(userId);
                      break;
                  case 6:
                      // 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 && 7 == validArgumentCount)
              {
                  wasHandled = emberAfDoorLockClusterGetLogRecordResponseCallback(aEndpointId, apCommandObj, logEntryId, timestamp,
                                                                                  eventType, source, eventIdOrAlarmCode, userId,
                                                                                  const_cast<uint8_t *>(pin));
              }
              break;
          }
          case Clusters::DoorLock::Commands::Ids::GetPinResponse: {
              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 = emberAfDoorLockClusterGetPinResponseCallback(aEndpointId, apCommandObj, userId, userStatus, userType,
                                                                            const_cast<uint8_t *>(pin));
              }
              break;
          }
          case Clusters::DoorLock::Commands::Ids::GetRfidResponse: {
              expectArgumentCount = 4;
              uint16_t userId;
              uint8_t userStatus;
              uint8_t userType;
              const uint8_t * rfid;
              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(rfid);
                      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 = emberAfDoorLockClusterGetRfidResponseCallback(aEndpointId, apCommandObj, userId, userStatus, userType,
                                                                             const_cast<uint8_t *>(rfid));
              }
              break;
          }
          case Clusters::DoorLock::Commands::Ids::GetUserTypeResponse: {
              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 = emberAfDoorLockClusterGetUserTypeResponseCallback(aEndpointId, apCommandObj, userId, userType);
              }
              break;
          }
          case Clusters::DoorLock::Commands::Ids::GetWeekdayScheduleResponse: {
              expectArgumentCount = 8;
              uint8_t scheduleId;
              uint16_t userId;
              uint8_t status;
              uint8_t daysMask;
              uint8_t startHour;
              uint8_t startMinute;
              uint8_t endHour;
              uint8_t endMinute;
              bool argExists[8];
  
              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 < 8)
                  {
                      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(status);
                      break;
                  case 3:
                      TLVUnpackError = aDataTlv.Get(daysMask);
                      break;
                  case 4:
                      TLVUnpackError = aDataTlv.Get(startHour);
                      break;
                  case 5:
                      TLVUnpackError = aDataTlv.Get(startMinute);
                      break;
                  case 6:
                      TLVUnpackError = aDataTlv.Get(endHour);
                      break;
                  case 7:
                      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 && 8 == validArgumentCount)
              {
                  wasHandled = emberAfDoorLockClusterGetWeekdayScheduleResponseCallback(
                      aEndpointId, apCommandObj, scheduleId, userId, status, daysMask, startHour, startMinute, endHour, endMinute);
              }
              break;
          }
          case Clusters::DoorLock::Commands::Ids::GetYeardayScheduleResponse: {
              expectArgumentCount = 5;
              uint8_t scheduleId;
              uint16_t userId;
              uint8_t status;
              uint32_t localStartTime;
              uint32_t localEndTime;
              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(scheduleId);
                      break;
                  case 1:
                      TLVUnpackError = aDataTlv.Get(userId);
                      break;
                  case 2:
                      TLVUnpackError = aDataTlv.Get(status);
                      break;
                  case 3:
                      TLVUnpackError = aDataTlv.Get(localStartTime);
                      break;
                  case 4:
                      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 && 5 == validArgumentCount)
              {
                  wasHandled = emberAfDoorLockClusterGetYeardayScheduleResponseCallback(aEndpointId, apCommandObj, scheduleId, userId,
                                                                                        status, localStartTime, localEndTime);
              }
              break;
          }
          case Clusters::DoorLock::Commands::Ids::LockDoorResponse: {
              expectArgumentCount = 1;
              uint8_t status;
              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(status);
                      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 = emberAfDoorLockClusterLockDoorResponseCallback(aEndpointId, apCommandObj, status);
              }
              break;
          }
          case Clusters::DoorLock::Commands::Ids::SetHolidayScheduleResponse: {
              expectArgumentCount = 1;
              uint8_t status;
              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(status);
                      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 = emberAfDoorLockClusterSetHolidayScheduleResponseCallback(aEndpointId, apCommandObj, status);
              }
              break;
          }
          case Clusters::DoorLock::Commands::Ids::SetPinResponse: {
              expectArgumentCount = 1;
              uint8_t status;
              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(status);
                      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 = emberAfDoorLockClusterSetPinResponseCallback(aEndpointId, apCommandObj, status);
              }
              break;
          }
          case Clusters::DoorLock::Commands::Ids::SetRfidResponse: {
              expectArgumentCount = 1;
              uint8_t status;
              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(status);
                      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 = emberAfDoorLockClusterSetRfidResponseCallback(aEndpointId, apCommandObj, status);
              }
              break;
          }
          case Clusters::DoorLock::Commands::Ids::SetUserTypeResponse: {
              expectArgumentCount = 1;
              uint8_t status;
              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(status);
                      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 = emberAfDoorLockClusterSetUserTypeResponseCallback(aEndpointId, apCommandObj, status);
              }
              break;
          }
          case Clusters::DoorLock::Commands::Ids::SetWeekdayScheduleResponse: {
              expectArgumentCount = 1;
              uint8_t status;
              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(status);
                      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 = emberAfDoorLockClusterSetWeekdayScheduleResponseCallback(aEndpointId, apCommandObj, status);
              }
              break;
          }
          case Clusters::DoorLock::Commands::Ids::SetYeardayScheduleResponse: {
              expectArgumentCount = 1;
              uint8_t status;
              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(status);
                      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 = emberAfDoorLockClusterSetYeardayScheduleResponseCallback(aEndpointId, apCommandObj, status);
              }
              break;
          }
          case Clusters::DoorLock::Commands::Ids::UnlockDoorResponse: {
              expectArgumentCount = 1;
              uint8_t status;
              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(status);
                      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 = emberAfDoorLockClusterUnlockDoorResponseCallback(aEndpointId, apCommandObj, status);
              }
              break;
          }
          case Clusters::DoorLock::Commands::Ids::UnlockWithTimeoutResponse: {
              expectArgumentCount = 1;
              uint8_t status;
              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(status);
                      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 = emberAfDoorLockClusterUnlockWithTimeoutResponseCallback(aEndpointId, apCommandObj, status);
              }
              break;
          }
          default: {
              // Unrecognized command ID, error status will apply.
              ReportCommandUnsupported(apCommandObj, aEndpointId, Clusters::DoorLock::Id, aCommandId);
              return;
          }
          }
      }
  
      if (CHIP_NO_ERROR != TLVError || CHIP_NO_ERROR != TLVUnpackError || expectArgumentCount != validArgumentCount || !wasHandled)
      {
          CommandPathParams returnStatusParam = { aEndpointId,
                                                  0, // GroupId
                                                  Clusters::DoorLock::Id, aCommandId, (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, TLVError.Format(), TLVUnpackError.Format(), 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 GeneralCommissioning {
  
  void DispatchClientCommand(CommandSender * 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::ArmFailSafeResponse: {
              expectArgumentCount = 2;
              uint8_t errorCode;
              const uint8_t * debugText;
              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(errorCode);
                      break;
                  case 1:
                      // TODO(#5542): The cluster handlers should accept a ByteSpan for all string types.
                      TLVUnpackError = aDataTlv.GetDataPtr(debugText);
                      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 = emberAfGeneralCommissioningClusterArmFailSafeResponseCallback(aEndpointId, apCommandObj, errorCode,
                                                                                             const_cast<uint8_t *>(debugText));
              }
              break;
          }
          case Clusters::GeneralCommissioning::Commands::Ids::CommissioningCompleteResponse: {
              expectArgumentCount = 2;
              uint8_t errorCode;
              const uint8_t * debugText;
              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(errorCode);
                      break;
                  case 1:
                      // TODO(#5542): The cluster handlers should accept a ByteSpan for all string types.
                      TLVUnpackError = aDataTlv.GetDataPtr(debugText);
                      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 = emberAfGeneralCommissioningClusterCommissioningCompleteResponseCallback(
                      aEndpointId, apCommandObj, errorCode, const_cast<uint8_t *>(debugText));
              }
              break;
          }
          case Clusters::GeneralCommissioning::Commands::Ids::SetRegulatoryConfigResponse: {
              expectArgumentCount = 2;
              uint8_t errorCode;
              const uint8_t * debugText;
              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(errorCode);
                      break;
                  case 1:
                      // TODO(#5542): The cluster handlers should accept a ByteSpan for all string types.
                      TLVUnpackError = aDataTlv.GetDataPtr(debugText);
                      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 = emberAfGeneralCommissioningClusterSetRegulatoryConfigResponseCallback(
                      aEndpointId, apCommandObj, errorCode, const_cast<uint8_t *>(debugText));
              }
              break;
          }
          default: {
              // Unrecognized command ID, error status will apply.
              ReportCommandUnsupported(apCommandObj, aEndpointId, Clusters::GeneralCommissioning::Id, aCommandId);
              return;
          }
          }
      }
  
      if (CHIP_NO_ERROR != TLVError || CHIP_NO_ERROR != TLVUnpackError || expectArgumentCount != validArgumentCount || !wasHandled)
      {
          CommandPathParams returnStatusParam = { aEndpointId,
                                                  0, // GroupId
                                                  Clusters::GeneralCommissioning::Id, aCommandId,
                                                  (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, TLVError.Format(), TLVUnpackError.Format(), 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 DispatchClientCommand(CommandSender * 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::AddGroupResponse: {
              expectArgumentCount = 2;
              uint8_t status;
              uint16_t groupId;
              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(status);
                      break;
                  case 1:
                      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 && 2 == validArgumentCount)
              {
                  wasHandled = emberAfGroupsClusterAddGroupResponseCallback(aEndpointId, apCommandObj, status, groupId);
              }
              break;
          }
          case Clusters::Groups::Commands::Ids::GetGroupMembershipResponse: {
              expectArgumentCount = 3;
              uint8_t capacity;
              uint8_t groupCount;
              /* TYPE WARNING: array array defaults to */ uint8_t * groupList;
              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(capacity);
                      break;
                  case 1:
                      TLVUnpackError = aDataTlv.Get(groupCount);
                      break;
                  case 2:
                      // 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 && 3 == validArgumentCount)
              {
                  wasHandled = emberAfGroupsClusterGetGroupMembershipResponseCallback(aEndpointId, apCommandObj, capacity, groupCount,
                                                                                      groupList);
              }
              break;
          }
          case Clusters::Groups::Commands::Ids::RemoveGroupResponse: {
              expectArgumentCount = 2;
              uint8_t status;
              uint16_t groupId;
              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(status);
                      break;
                  case 1:
                      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 && 2 == validArgumentCount)
              {
                  wasHandled = emberAfGroupsClusterRemoveGroupResponseCallback(aEndpointId, apCommandObj, status, groupId);
              }
              break;
          }
          case Clusters::Groups::Commands::Ids::ViewGroupResponse: {
              expectArgumentCount = 3;
              uint8_t status;
              uint16_t groupId;
              const uint8_t * groupName;
              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(status);
                      break;
                  case 1:
                      TLVUnpackError = aDataTlv.Get(groupId);
                      break;
                  case 2:
                      // 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 && 3 == validArgumentCount)
              {
                  wasHandled = emberAfGroupsClusterViewGroupResponseCallback(aEndpointId, apCommandObj, status, groupId,
                                                                             const_cast<uint8_t *>(groupName));
              }
              break;
          }
          default: {
              // Unrecognized command ID, error status will apply.
              ReportCommandUnsupported(apCommandObj, aEndpointId, Clusters::Groups::Id, aCommandId);
              return;
          }
          }
      }
  
      if (CHIP_NO_ERROR != TLVError || CHIP_NO_ERROR != TLVUnpackError || expectArgumentCount != validArgumentCount || !wasHandled)
      {
          CommandPathParams returnStatusParam = { aEndpointId,
                                                  0, // GroupId
                                                  Clusters::Groups::Id, aCommandId, (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, TLVError.Format(), TLVUnpackError.Format(), 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 Identify {
  
  void DispatchClientCommand(CommandSender * 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::IdentifyQueryResponse: {
              expectArgumentCount = 1;
              uint16_t timeout;
              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(timeout);
                      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 = emberAfIdentifyClusterIdentifyQueryResponseCallback(aEndpointId, apCommandObj, timeout);
              }
              break;
          }
          default: {
              // Unrecognized command ID, error status will apply.
              ReportCommandUnsupported(apCommandObj, aEndpointId, Clusters::Identify::Id, aCommandId);
              return;
          }
          }
      }
  
      if (CHIP_NO_ERROR != TLVError || CHIP_NO_ERROR != TLVUnpackError || expectArgumentCount != validArgumentCount || !wasHandled)
      {
          CommandPathParams returnStatusParam = { aEndpointId,
                                                  0, // GroupId
                                                  Clusters::Identify::Id, aCommandId, (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, TLVError.Format(), TLVUnpackError.Format(), 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 KeypadInput {
  
  void DispatchClientCommand(CommandSender * 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::KeypadInput::Commands::Ids::SendKeyResponse: {
              expectArgumentCount = 1;
              uint8_t status;
              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(status);
                      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 = emberAfKeypadInputClusterSendKeyResponseCallback(aEndpointId, apCommandObj, status);
              }
              break;
          }
          default: {
              // Unrecognized command ID, error status will apply.
              ReportCommandUnsupported(apCommandObj, aEndpointId, Clusters::KeypadInput::Id, aCommandId);
              return;
          }
          }
      }
  
      if (CHIP_NO_ERROR != TLVError || CHIP_NO_ERROR != TLVUnpackError || expectArgumentCount != validArgumentCount || !wasHandled)
      {
          CommandPathParams returnStatusParam = { aEndpointId,
                                                  0, // GroupId
                                                  Clusters::KeypadInput::Id, aCommandId, (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, TLVError.Format(), TLVUnpackError.Format(), 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 KeypadInput
  
  namespace MediaPlayback {
  
  void DispatchClientCommand(CommandSender * 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::MediaPlayback::Commands::Ids::MediaFastForwardResponse: {
              expectArgumentCount = 1;
              uint8_t mediaPlaybackStatus;
              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(mediaPlaybackStatus);
                      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 =
                      emberAfMediaPlaybackClusterMediaFastForwardResponseCallback(aEndpointId, apCommandObj, mediaPlaybackStatus);
              }
              break;
          }
          case Clusters::MediaPlayback::Commands::Ids::MediaNextResponse: {
              expectArgumentCount = 1;
              uint8_t mediaPlaybackStatus;
              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(mediaPlaybackStatus);
                      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 = emberAfMediaPlaybackClusterMediaNextResponseCallback(aEndpointId, apCommandObj, mediaPlaybackStatus);
              }
              break;
          }
          case Clusters::MediaPlayback::Commands::Ids::MediaPauseResponse: {
              expectArgumentCount = 1;
              uint8_t mediaPlaybackStatus;
              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(mediaPlaybackStatus);
                      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 = emberAfMediaPlaybackClusterMediaPauseResponseCallback(aEndpointId, apCommandObj, mediaPlaybackStatus);
              }
              break;
          }
          case Clusters::MediaPlayback::Commands::Ids::MediaPlayResponse: {
              expectArgumentCount = 1;
              uint8_t mediaPlaybackStatus;
              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(mediaPlaybackStatus);
                      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 = emberAfMediaPlaybackClusterMediaPlayResponseCallback(aEndpointId, apCommandObj, mediaPlaybackStatus);
              }
              break;
          }
          case Clusters::MediaPlayback::Commands::Ids::MediaPreviousResponse: {
              expectArgumentCount = 1;
              uint8_t mediaPlaybackStatus;
              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(mediaPlaybackStatus);
                      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 =
                      emberAfMediaPlaybackClusterMediaPreviousResponseCallback(aEndpointId, apCommandObj, mediaPlaybackStatus);
              }
              break;
          }
          case Clusters::MediaPlayback::Commands::Ids::MediaRewindResponse: {
              expectArgumentCount = 1;
              uint8_t mediaPlaybackStatus;
              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(mediaPlaybackStatus);
                      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 = emberAfMediaPlaybackClusterMediaRewindResponseCallback(aEndpointId, apCommandObj, mediaPlaybackStatus);
              }
              break;
          }
          case Clusters::MediaPlayback::Commands::Ids::MediaSeekResponse: {
              expectArgumentCount = 1;
              uint8_t mediaPlaybackStatus;
              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(mediaPlaybackStatus);
                      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 = emberAfMediaPlaybackClusterMediaSeekResponseCallback(aEndpointId, apCommandObj, mediaPlaybackStatus);
              }
              break;
          }
          case Clusters::MediaPlayback::Commands::Ids::MediaSkipBackwardResponse: {
              expectArgumentCount = 1;
              uint8_t mediaPlaybackStatus;
              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(mediaPlaybackStatus);
                      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 =
                      emberAfMediaPlaybackClusterMediaSkipBackwardResponseCallback(aEndpointId, apCommandObj, mediaPlaybackStatus);
              }
              break;
          }
          case Clusters::MediaPlayback::Commands::Ids::MediaSkipForwardResponse: {
              expectArgumentCount = 1;
              uint8_t mediaPlaybackStatus;
              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(mediaPlaybackStatus);
                      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 =
                      emberAfMediaPlaybackClusterMediaSkipForwardResponseCallback(aEndpointId, apCommandObj, mediaPlaybackStatus);
              }
              break;
          }
          case Clusters::MediaPlayback::Commands::Ids::MediaStartOverResponse: {
              expectArgumentCount = 1;
              uint8_t mediaPlaybackStatus;
              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(mediaPlaybackStatus);
                      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 =
                      emberAfMediaPlaybackClusterMediaStartOverResponseCallback(aEndpointId, apCommandObj, mediaPlaybackStatus);
              }
              break;
          }
          case Clusters::MediaPlayback::Commands::Ids::MediaStopResponse: {
              expectArgumentCount = 1;
              uint8_t mediaPlaybackStatus;
              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(mediaPlaybackStatus);
                      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 = emberAfMediaPlaybackClusterMediaStopResponseCallback(aEndpointId, apCommandObj, mediaPlaybackStatus);
              }
              break;
          }
          default: {
              // Unrecognized command ID, error status will apply.
              ReportCommandUnsupported(apCommandObj, aEndpointId, Clusters::MediaPlayback::Id, aCommandId);
              return;
          }
          }
      }
  
      if (CHIP_NO_ERROR != TLVError || CHIP_NO_ERROR != TLVUnpackError || expectArgumentCount != validArgumentCount || !wasHandled)
      {
          CommandPathParams returnStatusParam = { aEndpointId,
                                                  0, // GroupId
                                                  Clusters::MediaPlayback::Id, aCommandId, (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, TLVError.Format(), TLVUnpackError.Format(), 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 MediaPlayback
  
  namespace NetworkCommissioning {
  
  void DispatchClientCommand(CommandSender * 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::AddThreadNetworkResponse: {
              expectArgumentCount = 2;
              uint8_t errorCode;
              const uint8_t * debugText;
              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(errorCode);
                      break;
                  case 1:
                      // TODO(#5542): The cluster handlers should accept a ByteSpan for all string types.
                      TLVUnpackError = aDataTlv.GetDataPtr(debugText);
                      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 = emberAfNetworkCommissioningClusterAddThreadNetworkResponseCallback(
                      aEndpointId, apCommandObj, errorCode, const_cast<uint8_t *>(debugText));
              }
              break;
          }
          case Clusters::NetworkCommissioning::Commands::Ids::AddWiFiNetworkResponse: {
              expectArgumentCount = 2;
              uint8_t errorCode;
              const uint8_t * debugText;
              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(errorCode);
                      break;
                  case 1:
                      // TODO(#5542): The cluster handlers should accept a ByteSpan for all string types.
                      TLVUnpackError = aDataTlv.GetDataPtr(debugText);
                      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 = emberAfNetworkCommissioningClusterAddWiFiNetworkResponseCallback(aEndpointId, apCommandObj, errorCode,
                                                                                                const_cast<uint8_t *>(debugText));
              }
              break;
          }
          case Clusters::NetworkCommissioning::Commands::Ids::DisableNetworkResponse: {
              expectArgumentCount = 2;
              uint8_t errorCode;
              const uint8_t * debugText;
              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(errorCode);
                      break;
                  case 1:
                      // TODO(#5542): The cluster handlers should accept a ByteSpan for all string types.
                      TLVUnpackError = aDataTlv.GetDataPtr(debugText);
                      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 = emberAfNetworkCommissioningClusterDisableNetworkResponseCallback(aEndpointId, apCommandObj, errorCode,
                                                                                                const_cast<uint8_t *>(debugText));
              }
              break;
          }
          case Clusters::NetworkCommissioning::Commands::Ids::EnableNetworkResponse: {
              expectArgumentCount = 2;
              uint8_t errorCode;
              const uint8_t * debugText;
              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(errorCode);
                      break;
                  case 1:
                      // TODO(#5542): The cluster handlers should accept a ByteSpan for all string types.
                      TLVUnpackError = aDataTlv.GetDataPtr(debugText);
                      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 = emberAfNetworkCommissioningClusterEnableNetworkResponseCallback(aEndpointId, apCommandObj, errorCode,
                                                                                               const_cast<uint8_t *>(debugText));
              }
              break;
          }
          case Clusters::NetworkCommissioning::Commands::Ids::RemoveNetworkResponse: {
              expectArgumentCount = 2;
              uint8_t errorCode;
              const uint8_t * debugText;
              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(errorCode);
                      break;
                  case 1:
                      // TODO(#5542): The cluster handlers should accept a ByteSpan for all string types.
                      TLVUnpackError = aDataTlv.GetDataPtr(debugText);
                      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 = emberAfNetworkCommissioningClusterRemoveNetworkResponseCallback(aEndpointId, apCommandObj, errorCode,
                                                                                               const_cast<uint8_t *>(debugText));
              }
              break;
          }
          case Clusters::NetworkCommissioning::Commands::Ids::ScanNetworksResponse: {
              expectArgumentCount = 4;
              uint8_t errorCode;
              const uint8_t * debugText;
              /* TYPE WARNING: array array defaults to */ uint8_t * wifiScanResults;
              /* TYPE WARNING: array array defaults to */ uint8_t * threadScanResults;
              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(errorCode);
                      break;
                  case 1:
                      // TODO(#5542): The cluster handlers should accept a ByteSpan for all string types.
                      TLVUnpackError = aDataTlv.GetDataPtr(debugText);
                      break;
                  case 2:
                      // Just for compatibility, we will add array type support in IM later.
                      TLVUnpackError = aDataTlv.GetDataPtr(const_cast<const uint8_t *&>(wifiScanResults));
                      break;
                  case 3:
                      // Just for compatibility, we will add array type support in IM later.
                      TLVUnpackError = aDataTlv.GetDataPtr(const_cast<const uint8_t *&>(threadScanResults));
                      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 = emberAfNetworkCommissioningClusterScanNetworksResponseCallback(
                      aEndpointId, apCommandObj, errorCode, const_cast<uint8_t *>(debugText), wifiScanResults, threadScanResults);
              }
              break;
          }
          case Clusters::NetworkCommissioning::Commands::Ids::UpdateThreadNetworkResponse: {
              expectArgumentCount = 2;
              uint8_t errorCode;
              const uint8_t * debugText;
              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(errorCode);
                      break;
                  case 1:
                      // TODO(#5542): The cluster handlers should accept a ByteSpan for all string types.
                      TLVUnpackError = aDataTlv.GetDataPtr(debugText);
                      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 = emberAfNetworkCommissioningClusterUpdateThreadNetworkResponseCallback(
                      aEndpointId, apCommandObj, errorCode, const_cast<uint8_t *>(debugText));
              }
              break;
          }
          case Clusters::NetworkCommissioning::Commands::Ids::UpdateWiFiNetworkResponse: {
              expectArgumentCount = 2;
              uint8_t errorCode;
              const uint8_t * debugText;
              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(errorCode);
                      break;
                  case 1:
                      // TODO(#5542): The cluster handlers should accept a ByteSpan for all string types.
                      TLVUnpackError = aDataTlv.GetDataPtr(debugText);
                      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 = emberAfNetworkCommissioningClusterUpdateWiFiNetworkResponseCallback(
                      aEndpointId, apCommandObj, errorCode, const_cast<uint8_t *>(debugText));
              }
              break;
          }
          default: {
              // Unrecognized command ID, error status will apply.
              ReportCommandUnsupported(apCommandObj, aEndpointId, Clusters::NetworkCommissioning::Id, aCommandId);
              return;
          }
          }
      }
  
      if (CHIP_NO_ERROR != TLVError || CHIP_NO_ERROR != TLVUnpackError || expectArgumentCount != validArgumentCount || !wasHandled)
      {
          CommandPathParams returnStatusParam = { aEndpointId,
                                                  0, // GroupId
                                                  Clusters::NetworkCommissioning::Id, aCommandId,
                                                  (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, TLVError.Format(), TLVUnpackError.Format(), 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 DispatchClientCommand(CommandSender * 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::ApplyUpdateRequestResponse: {
              expectArgumentCount = 2;
              uint8_t action;
              uint32_t delayedActionTime;
              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(action);
                      break;
                  case 1:
                      TLVUnpackError = aDataTlv.Get(delayedActionTime);
                      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 = emberAfOtaSoftwareUpdateProviderClusterApplyUpdateRequestResponseCallback(aEndpointId, apCommandObj,
                                                                                                         action, delayedActionTime);
              }
              break;
          }
          case Clusters::OtaSoftwareUpdateProvider::Commands::Ids::QueryImageResponse: {
              expectArgumentCount = 7;
              uint8_t status;
              uint32_t delayedActionTime;
              const uint8_t * imageURI;
              uint32_t softwareVersion;
              chip::ByteSpan updateToken;
              bool userConsentNeeded;
              chip::ByteSpan metadataForRequestor;
              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(status);
                      break;
                  case 1:
                      TLVUnpackError = aDataTlv.Get(delayedActionTime);
                      break;
                  case 2:
                      // TODO(#5542): The cluster handlers should accept a ByteSpan for all string types.
                      TLVUnpackError = aDataTlv.GetDataPtr(imageURI);
                      break;
                  case 3:
                      TLVUnpackError = aDataTlv.Get(softwareVersion);
                      break;
                  case 4:
                      TLVUnpackError = aDataTlv.Get(updateToken);
                      break;
                  case 5:
                      TLVUnpackError = aDataTlv.Get(userConsentNeeded);
                      break;
                  case 6:
                      TLVUnpackError = aDataTlv.Get(metadataForRequestor);
                      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 = emberAfOtaSoftwareUpdateProviderClusterQueryImageResponseCallback(
                      aEndpointId, apCommandObj, status, delayedActionTime, const_cast<uint8_t *>(imageURI), softwareVersion,
                      updateToken, userConsentNeeded, metadataForRequestor);
              }
              break;
          }
          default: {
              // Unrecognized command ID, error status will apply.
              ReportCommandUnsupported(apCommandObj, aEndpointId, Clusters::OtaSoftwareUpdateProvider::Id, aCommandId);
              return;
          }
          }
      }
  
      if (CHIP_NO_ERROR != TLVError || CHIP_NO_ERROR != TLVUnpackError || expectArgumentCount != validArgumentCount || !wasHandled)
      {
          CommandPathParams returnStatusParam = { aEndpointId,
                                                  0, // GroupId
                                                  Clusters::OtaSoftwareUpdateProvider::Id, aCommandId,
                                                  (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, TLVError.Format(), TLVUnpackError.Format(), 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 OperationalCredentials {
  
  void DispatchClientCommand(CommandSender * 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::NOCResponse: {
              expectArgumentCount = 3;
              uint8_t StatusCode;
              uint8_t FabricIndex;
              chip::ByteSpan DebugText;
              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(StatusCode);
                      break;
                  case 1:
                      TLVUnpackError = aDataTlv.Get(FabricIndex);
                      break;
                  case 2:
                      TLVUnpackError = aDataTlv.Get(DebugText);
                      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 = emberAfOperationalCredentialsClusterNOCResponseCallback(aEndpointId, apCommandObj, StatusCode,
                                                                                       FabricIndex, DebugText);
              }
              break;
          }
          case Clusters::OperationalCredentials::Commands::Ids::OpCSRResponse: {
              expectArgumentCount = 2;
              chip::ByteSpan NOCSRElements;
              chip::ByteSpan AttestationSignature;
              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(NOCSRElements);
                      break;
                  case 1:
                      TLVUnpackError = aDataTlv.Get(AttestationSignature);
                      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 = emberAfOperationalCredentialsClusterOpCSRResponseCallback(aEndpointId, apCommandObj, NOCSRElements,
                                                                                         AttestationSignature);
              }
              break;
          }
          default: {
              // Unrecognized command ID, error status will apply.
              ReportCommandUnsupported(apCommandObj, aEndpointId, Clusters::OperationalCredentials::Id, aCommandId);
              return;
          }
          }
      }
  
      if (CHIP_NO_ERROR != TLVError || CHIP_NO_ERROR != TLVUnpackError || expectArgumentCount != validArgumentCount || !wasHandled)
      {
          CommandPathParams returnStatusParam = { aEndpointId,
                                                  0, // GroupId
                                                  Clusters::OperationalCredentials::Id, aCommandId,
                                                  (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, TLVError.Format(), TLVUnpackError.Format(), 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 DispatchClientCommand(CommandSender * 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::AddSceneResponse: {
              expectArgumentCount = 3;
              uint8_t status;
              uint16_t groupId;
              uint8_t sceneId;
              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(status);
                      break;
                  case 1:
                      TLVUnpackError = aDataTlv.Get(groupId);
                      break;
                  case 2:
                      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 && 3 == validArgumentCount)
              {
                  wasHandled = emberAfScenesClusterAddSceneResponseCallback(aEndpointId, apCommandObj, status, groupId, sceneId);
              }
              break;
          }
          case Clusters::Scenes::Commands::Ids::GetSceneMembershipResponse: {
              expectArgumentCount = 5;
              uint8_t status;
              uint8_t capacity;
              uint16_t groupId;
              uint8_t sceneCount;
              /* TYPE WARNING: array array defaults to */ uint8_t * sceneList;
              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(status);
                      break;
                  case 1:
                      TLVUnpackError = aDataTlv.Get(capacity);
                      break;
                  case 2:
                      TLVUnpackError = aDataTlv.Get(groupId);
                      break;
                  case 3:
                      TLVUnpackError = aDataTlv.Get(sceneCount);
                      break;
                  case 4:
                      // Just for compatibility, we will add array type support in IM later.
                      TLVUnpackError = aDataTlv.GetDataPtr(const_cast<const uint8_t *&>(sceneList));
                      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 = emberAfScenesClusterGetSceneMembershipResponseCallback(aEndpointId, apCommandObj, status, capacity,
                                                                                      groupId, sceneCount, sceneList);
              }
              break;
          }
          case Clusters::Scenes::Commands::Ids::RemoveAllScenesResponse: {
              expectArgumentCount = 2;
              uint8_t status;
              uint16_t groupId;
              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(status);
                      break;
                  case 1:
                      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 && 2 == validArgumentCount)
              {
                  wasHandled = emberAfScenesClusterRemoveAllScenesResponseCallback(aEndpointId, apCommandObj, status, groupId);
              }
              break;
          }
          case Clusters::Scenes::Commands::Ids::RemoveSceneResponse: {
              expectArgumentCount = 3;
              uint8_t status;
              uint16_t groupId;
              uint8_t sceneId;
              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(status);
                      break;
                  case 1:
                      TLVUnpackError = aDataTlv.Get(groupId);
                      break;
                  case 2:
                      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 && 3 == validArgumentCount)
              {
                  wasHandled = emberAfScenesClusterRemoveSceneResponseCallback(aEndpointId, apCommandObj, status, groupId, sceneId);
              }
              break;
          }
          case Clusters::Scenes::Commands::Ids::StoreSceneResponse: {
              expectArgumentCount = 3;
              uint8_t status;
              uint16_t groupId;
              uint8_t sceneId;
              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(status);
                      break;
                  case 1:
                      TLVUnpackError = aDataTlv.Get(groupId);
                      break;
                  case 2:
                      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 && 3 == validArgumentCount)
              {
                  wasHandled = emberAfScenesClusterStoreSceneResponseCallback(aEndpointId, apCommandObj, status, groupId, sceneId);
              }
              break;
          }
          case Clusters::Scenes::Commands::Ids::ViewSceneResponse: {
              expectArgumentCount = 6;
              uint8_t status;
              uint16_t groupId;
              uint8_t sceneId;
              uint16_t transitionTime;
              const uint8_t * sceneName;
              /* TYPE WARNING: array array defaults to */ uint8_t * extensionFieldSets;
              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(status);
                      break;
                  case 1:
                      TLVUnpackError = aDataTlv.Get(groupId);
                      break;
                  case 2:
                      TLVUnpackError = aDataTlv.Get(sceneId);
                      break;
                  case 3:
                      TLVUnpackError = aDataTlv.Get(transitionTime);
                      break;
                  case 4:
                      // TODO(#5542): The cluster handlers should accept a ByteSpan for all string types.
                      TLVUnpackError = aDataTlv.GetDataPtr(sceneName);
                      break;
                  case 5:
                      // 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 && 6 == validArgumentCount)
              {
                  wasHandled = emberAfScenesClusterViewSceneResponseCallback(aEndpointId, apCommandObj, status, groupId, sceneId,
                                                                             transitionTime, const_cast<uint8_t *>(sceneName),
                                                                             extensionFieldSets);
              }
              break;
          }
          default: {
              // Unrecognized command ID, error status will apply.
              ReportCommandUnsupported(apCommandObj, aEndpointId, Clusters::Scenes::Id, aCommandId);
              return;
          }
          }
      }
  
      if (CHIP_NO_ERROR != TLVError || CHIP_NO_ERROR != TLVUnpackError || expectArgumentCount != validArgumentCount || !wasHandled)
      {
          CommandPathParams returnStatusParam = { aEndpointId,
                                                  0, // GroupId
                                                  Clusters::Scenes::Id, aCommandId, (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, TLVError.Format(), TLVUnpackError.Format(), 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 TvChannel {
  
  void DispatchClientCommand(CommandSender * 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::TvChannel::Commands::Ids::ChangeChannelResponse: {
              expectArgumentCount = 2;
              /* TYPE WARNING: array array defaults to */ uint8_t * ChannelMatch;
              uint8_t ErrorType;
              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:
                      // Just for compatibility, we will add array type support in IM later.
                      TLVUnpackError = aDataTlv.GetDataPtr(const_cast<const uint8_t *&>(ChannelMatch));
                      break;
                  case 1:
                      TLVUnpackError = aDataTlv.Get(ErrorType);
                      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 =
                      emberAfTvChannelClusterChangeChannelResponseCallback(aEndpointId, apCommandObj, ChannelMatch, ErrorType);
              }
              break;
          }
          default: {
              // Unrecognized command ID, error status will apply.
              ReportCommandUnsupported(apCommandObj, aEndpointId, Clusters::TvChannel::Id, aCommandId);
              return;
          }
          }
      }
  
      if (CHIP_NO_ERROR != TLVError || CHIP_NO_ERROR != TLVUnpackError || expectArgumentCount != validArgumentCount || !wasHandled)
      {
          CommandPathParams returnStatusParam = { aEndpointId,
                                                  0, // GroupId
                                                  Clusters::TvChannel::Id, aCommandId, (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, TLVError.Format(), TLVUnpackError.Format(), 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 TvChannel
  
  namespace TargetNavigator {
  
  void DispatchClientCommand(CommandSender * 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::TargetNavigator::Commands::Ids::NavigateTargetResponse: {
              expectArgumentCount = 2;
              uint8_t status;
              const uint8_t * data;
              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(status);
                      break;
                  case 1:
                      // TODO(#5542): The cluster handlers should accept a ByteSpan for all string types.
                      TLVUnpackError = aDataTlv.GetDataPtr(data);
                      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 = emberAfTargetNavigatorClusterNavigateTargetResponseCallback(aEndpointId, apCommandObj, status,
                                                                                           const_cast<uint8_t *>(data));
              }
              break;
          }
          default: {
              // Unrecognized command ID, error status will apply.
              ReportCommandUnsupported(apCommandObj, aEndpointId, Clusters::TargetNavigator::Id, aCommandId);
              return;
          }
          }
      }
  
      if (CHIP_NO_ERROR != TLVError || CHIP_NO_ERROR != TLVUnpackError || expectArgumentCount != validArgumentCount || !wasHandled)
      {
          CommandPathParams returnStatusParam = { aEndpointId,
                                                  0, // GroupId
                                                  Clusters::TargetNavigator::Id, aCommandId, (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, TLVError.Format(), TLVUnpackError.Format(), 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 TargetNavigator
  
  namespace TestCluster {
  
  void DispatchClientCommand(CommandSender * 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::TestAddArgumentsResponse: {
              expectArgumentCount = 1;
              uint8_t returnValue;
              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(returnValue);
                      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 = emberAfTestClusterClusterTestAddArgumentsResponseCallback(aEndpointId, apCommandObj, returnValue);
              }
              break;
          }
          case Clusters::TestCluster::Commands::Ids::TestSpecificResponse: {
              expectArgumentCount = 1;
              uint8_t returnValue;
              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(returnValue);
                      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 = emberAfTestClusterClusterTestSpecificResponseCallback(aEndpointId, apCommandObj, returnValue);
              }
              break;
          }
          default: {
              // Unrecognized command ID, error status will apply.
              ReportCommandUnsupported(apCommandObj, aEndpointId, Clusters::TestCluster::Id, aCommandId);
              return;
          }
          }
      }
  
      if (CHIP_NO_ERROR != TLVError || CHIP_NO_ERROR != TLVUnpackError || expectArgumentCount != validArgumentCount || !wasHandled)
      {
          CommandPathParams returnStatusParam = { aEndpointId,
                                                  0, // GroupId
                                                  Clusters::TestCluster::Id, aCommandId, (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, TLVError.Format(), TLVUnpackError.Format(), 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 clusters
  
  void DispatchSingleClusterCommand(ClusterId aClusterId, CommandId aCommandId, EndpointId aEndPointId, TLV::TLVReader & aReader,
                                    CommandHandler * apCommandObj)
  {
      ChipLogDetail(Zcl, "Received Cluster Command: Cluster=" ChipLogFormatMEI " Command=" ChipLogFormatMEI " Endpoint=%" PRIx16,
                    ChipLogValueMEI(aClusterId), ChipLogValueMEI(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.
          CommandPathParams returnStatusParam = { aEndPointId,
                                                  0, // GroupId
                                                  aClusterId, aCommandId, (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(ClusterId aClusterId, CommandId aCommandId, EndpointId aEndPointId,
                                            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)
      {
      case Clusters::AccountLogin::Id:
          clusters::AccountLogin::DispatchClientCommand(apCommandObj, aCommandId, aEndPointId, aReader);
          break;
      case Clusters::ApplicationLauncher::Id:
          clusters::ApplicationLauncher::DispatchClientCommand(apCommandObj, aCommandId, aEndPointId, aReader);
          break;
      case Clusters::ContentLauncher::Id:
          clusters::ContentLauncher::DispatchClientCommand(apCommandObj, aCommandId, aEndPointId, aReader);
          break;
      case Clusters::DoorLock::Id:
          clusters::DoorLock::DispatchClientCommand(apCommandObj, aCommandId, aEndPointId, aReader);
          break;
      case Clusters::GeneralCommissioning::Id:
          clusters::GeneralCommissioning::DispatchClientCommand(apCommandObj, aCommandId, aEndPointId, aReader);
          break;
      case Clusters::Groups::Id:
          clusters::Groups::DispatchClientCommand(apCommandObj, aCommandId, aEndPointId, aReader);
          break;
      case Clusters::Identify::Id:
          clusters::Identify::DispatchClientCommand(apCommandObj, aCommandId, aEndPointId, aReader);
          break;
      case Clusters::KeypadInput::Id:
          clusters::KeypadInput::DispatchClientCommand(apCommandObj, aCommandId, aEndPointId, aReader);
          break;
      case Clusters::MediaPlayback::Id:
          clusters::MediaPlayback::DispatchClientCommand(apCommandObj, aCommandId, aEndPointId, aReader);
          break;
      case Clusters::NetworkCommissioning::Id:
          clusters::NetworkCommissioning::DispatchClientCommand(apCommandObj, aCommandId, aEndPointId, aReader);
          break;
      case Clusters::OtaSoftwareUpdateProvider::Id:
          clusters::OtaSoftwareUpdateProvider::DispatchClientCommand(apCommandObj, aCommandId, aEndPointId, aReader);
          break;
      case Clusters::OperationalCredentials::Id:
          clusters::OperationalCredentials::DispatchClientCommand(apCommandObj, aCommandId, aEndPointId, aReader);
          break;
      case Clusters::Scenes::Id:
          clusters::Scenes::DispatchClientCommand(apCommandObj, aCommandId, aEndPointId, aReader);
          break;
      case Clusters::TvChannel::Id:
          clusters::TvChannel::DispatchClientCommand(apCommandObj, aCommandId, aEndPointId, aReader);
          break;
      case Clusters::TargetNavigator::Id:
          clusters::TargetNavigator::DispatchClientCommand(apCommandObj, aCommandId, aEndPointId, aReader);
          break;
      case Clusters::TestCluster::Id:
          clusters::TestCluster::DispatchClientCommand(apCommandObj, aCommandId, aEndPointId, aReader);
          break;
      default:
          // Unrecognized cluster ID, error status will apply.
          CommandPathParams returnStatusParam = { aEndPointId,
                                                  0, // GroupId
                                                  aClusterId, aCommandId, (CommandPathFlags::kEndpointIdValid) };
          apCommandObj->AddStatusCode(returnStatusParam, Protocols::SecureChannel::GeneralStatusCode::kNotFound,
                                      Protocols::SecureChannel::Id, Protocols::InteractionModel::ProtocolCode::InvalidCommand);
          ChipLogError(Zcl, "Unknown cluster " ChipLogFormatMEI, ChipLogValueMEI(aClusterId));
          break;
      }
  exit:
      Compatibility::ResetEmberAfObjects();
      aReader.ExitContainer(dataTlvType);
  }
  
  } // namespace app
  } // namespace chip
  