blob: a634a043c0444d22ec9227da874e951a22329281 [file] [log] [blame]
/*
*
* 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 "af-structs.h"
#include "app/util/util.h"
#include "call-command-handler.h"
#include "callback.h"
#include "cluster-id.h"
#include "command-id.h"
#include <app/InteractionModelEngine.h>
// Currently we need some work to keep compatible with ember lib.
#include <app/util/ember-compatibility-functions.h>
namespace chip {
namespace app {
// Cluster specific command parsing
namespace clusters {
namespace DoorLock {
void DispatchClientCommand(app::Command * apCommandObj, CommandId aCommandId, EndpointId aEndpointId, TLV::TLVReader & aDataTlv)
{
{
switch (aCommandId)
{
case ZCL_CLEAR_ALL_PINS_RESPONSE_COMMAND_ID: {
// 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.
CHIP_ERROR TLVError = CHIP_NO_ERROR;
CHIP_ERROR TLVUnpackError = CHIP_NO_ERROR;
uint8_t status;
bool statusExists = false;
uint32_t validArgumentCount = 0;
while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR)
{
switch (TLV::TagNumFromTag(aDataTlv.GetTag()))
{
case 0:
if (statusExists)
{
ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
break;
}
TLVUnpackError = aDataTlv.Get(status);
if (CHIP_NO_ERROR == TLVUnpackError)
{
statusExists = true;
validArgumentCount++;
}
break;
default:
// Unsupported tag, ignore it.
ChipLogProgress(Zcl, "Unknown TLV tag during processing.");
break;
}
if (TLVUnpackError != CHIP_NO_ERROR)
{
ChipLogProgress(Zcl, "Failed to decode TLV data with tag %" PRIx32 ": %" PRId32,
TLV::TagNumFromTag(aDataTlv.GetTag()), 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;
}
else
{
ChipLogProgress(Zcl, "Failed to decode TLV data: %" PRId32, TLVError);
}
// TODO(#5590) We should encode a response of status code for invalid TLV.
if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 1 == validArgumentCount)
{
// TODO(#5098) We should pass the Command Object and EndpointId to the cluster callbacks.
emberAfDoorLockClusterClearAllPinsResponseCallback(apCommandObj, status);
}
else
{
apCommandObj->AddStatusCode(nullptr, Protocols::SecureChannel::GeneralStatusCode::kBadRequest,
Protocols::SecureChannel::Id, Protocols::SecureChannel::kProtocolCodeGeneralFailure);
ChipLogProgress(
Zcl, "Failed to dispatch command, %d/%" PRIu32 " arguments parsed, TLVError=%" PRIu32 ", UnpackError=%" PRIu32,
1, validArgumentCount, TLVError, TLVUnpackError);
}
break;
}
case ZCL_CLEAR_ALL_RFIDS_RESPONSE_COMMAND_ID: {
// 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.
CHIP_ERROR TLVError = CHIP_NO_ERROR;
CHIP_ERROR TLVUnpackError = CHIP_NO_ERROR;
uint8_t status;
bool statusExists = false;
uint32_t validArgumentCount = 0;
while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR)
{
switch (TLV::TagNumFromTag(aDataTlv.GetTag()))
{
case 0:
if (statusExists)
{
ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
break;
}
TLVUnpackError = aDataTlv.Get(status);
if (CHIP_NO_ERROR == TLVUnpackError)
{
statusExists = true;
validArgumentCount++;
}
break;
default:
// Unsupported tag, ignore it.
ChipLogProgress(Zcl, "Unknown TLV tag during processing.");
break;
}
if (TLVUnpackError != CHIP_NO_ERROR)
{
ChipLogProgress(Zcl, "Failed to decode TLV data with tag %" PRIx32 ": %" PRId32,
TLV::TagNumFromTag(aDataTlv.GetTag()), 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;
}
else
{
ChipLogProgress(Zcl, "Failed to decode TLV data: %" PRId32, TLVError);
}
// TODO(#5590) We should encode a response of status code for invalid TLV.
if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 1 == validArgumentCount)
{
// TODO(#5098) We should pass the Command Object and EndpointId to the cluster callbacks.
emberAfDoorLockClusterClearAllRfidsResponseCallback(apCommandObj, status);
}
else
{
apCommandObj->AddStatusCode(nullptr, Protocols::SecureChannel::GeneralStatusCode::kBadRequest,
Protocols::SecureChannel::Id, Protocols::SecureChannel::kProtocolCodeGeneralFailure);
ChipLogProgress(
Zcl, "Failed to dispatch command, %d/%" PRIu32 " arguments parsed, TLVError=%" PRIu32 ", UnpackError=%" PRIu32,
1, validArgumentCount, TLVError, TLVUnpackError);
}
break;
}
case ZCL_CLEAR_HOLIDAY_SCHEDULE_RESPONSE_COMMAND_ID: {
// 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.
CHIP_ERROR TLVError = CHIP_NO_ERROR;
CHIP_ERROR TLVUnpackError = CHIP_NO_ERROR;
uint8_t status;
bool statusExists = false;
uint32_t validArgumentCount = 0;
while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR)
{
switch (TLV::TagNumFromTag(aDataTlv.GetTag()))
{
case 0:
if (statusExists)
{
ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
break;
}
TLVUnpackError = aDataTlv.Get(status);
if (CHIP_NO_ERROR == TLVUnpackError)
{
statusExists = true;
validArgumentCount++;
}
break;
default:
// Unsupported tag, ignore it.
ChipLogProgress(Zcl, "Unknown TLV tag during processing.");
break;
}
if (TLVUnpackError != CHIP_NO_ERROR)
{
ChipLogProgress(Zcl, "Failed to decode TLV data with tag %" PRIx32 ": %" PRId32,
TLV::TagNumFromTag(aDataTlv.GetTag()), 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;
}
else
{
ChipLogProgress(Zcl, "Failed to decode TLV data: %" PRId32, TLVError);
}
// TODO(#5590) We should encode a response of status code for invalid TLV.
if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 1 == validArgumentCount)
{
// TODO(#5098) We should pass the Command Object and EndpointId to the cluster callbacks.
emberAfDoorLockClusterClearHolidayScheduleResponseCallback(apCommandObj, status);
}
else
{
apCommandObj->AddStatusCode(nullptr, Protocols::SecureChannel::GeneralStatusCode::kBadRequest,
Protocols::SecureChannel::Id, Protocols::SecureChannel::kProtocolCodeGeneralFailure);
ChipLogProgress(
Zcl, "Failed to dispatch command, %d/%" PRIu32 " arguments parsed, TLVError=%" PRIu32 ", UnpackError=%" PRIu32,
1, validArgumentCount, TLVError, TLVUnpackError);
}
break;
}
case ZCL_CLEAR_PIN_RESPONSE_COMMAND_ID: {
// 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.
CHIP_ERROR TLVError = CHIP_NO_ERROR;
CHIP_ERROR TLVUnpackError = CHIP_NO_ERROR;
uint8_t status;
bool statusExists = false;
uint32_t validArgumentCount = 0;
while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR)
{
switch (TLV::TagNumFromTag(aDataTlv.GetTag()))
{
case 0:
if (statusExists)
{
ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
break;
}
TLVUnpackError = aDataTlv.Get(status);
if (CHIP_NO_ERROR == TLVUnpackError)
{
statusExists = true;
validArgumentCount++;
}
break;
default:
// Unsupported tag, ignore it.
ChipLogProgress(Zcl, "Unknown TLV tag during processing.");
break;
}
if (TLVUnpackError != CHIP_NO_ERROR)
{
ChipLogProgress(Zcl, "Failed to decode TLV data with tag %" PRIx32 ": %" PRId32,
TLV::TagNumFromTag(aDataTlv.GetTag()), 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;
}
else
{
ChipLogProgress(Zcl, "Failed to decode TLV data: %" PRId32, TLVError);
}
// TODO(#5590) We should encode a response of status code for invalid TLV.
if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 1 == validArgumentCount)
{
// TODO(#5098) We should pass the Command Object and EndpointId to the cluster callbacks.
emberAfDoorLockClusterClearPinResponseCallback(apCommandObj, status);
}
else
{
apCommandObj->AddStatusCode(nullptr, Protocols::SecureChannel::GeneralStatusCode::kBadRequest,
Protocols::SecureChannel::Id, Protocols::SecureChannel::kProtocolCodeGeneralFailure);
ChipLogProgress(
Zcl, "Failed to dispatch command, %d/%" PRIu32 " arguments parsed, TLVError=%" PRIu32 ", UnpackError=%" PRIu32,
1, validArgumentCount, TLVError, TLVUnpackError);
}
break;
}
case ZCL_CLEAR_RFID_RESPONSE_COMMAND_ID: {
// 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.
CHIP_ERROR TLVError = CHIP_NO_ERROR;
CHIP_ERROR TLVUnpackError = CHIP_NO_ERROR;
uint8_t status;
bool statusExists = false;
uint32_t validArgumentCount = 0;
while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR)
{
switch (TLV::TagNumFromTag(aDataTlv.GetTag()))
{
case 0:
if (statusExists)
{
ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
break;
}
TLVUnpackError = aDataTlv.Get(status);
if (CHIP_NO_ERROR == TLVUnpackError)
{
statusExists = true;
validArgumentCount++;
}
break;
default:
// Unsupported tag, ignore it.
ChipLogProgress(Zcl, "Unknown TLV tag during processing.");
break;
}
if (TLVUnpackError != CHIP_NO_ERROR)
{
ChipLogProgress(Zcl, "Failed to decode TLV data with tag %" PRIx32 ": %" PRId32,
TLV::TagNumFromTag(aDataTlv.GetTag()), 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;
}
else
{
ChipLogProgress(Zcl, "Failed to decode TLV data: %" PRId32, TLVError);
}
// TODO(#5590) We should encode a response of status code for invalid TLV.
if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 1 == validArgumentCount)
{
// TODO(#5098) We should pass the Command Object and EndpointId to the cluster callbacks.
emberAfDoorLockClusterClearRfidResponseCallback(apCommandObj, status);
}
else
{
apCommandObj->AddStatusCode(nullptr, Protocols::SecureChannel::GeneralStatusCode::kBadRequest,
Protocols::SecureChannel::Id, Protocols::SecureChannel::kProtocolCodeGeneralFailure);
ChipLogProgress(
Zcl, "Failed to dispatch command, %d/%" PRIu32 " arguments parsed, TLVError=%" PRIu32 ", UnpackError=%" PRIu32,
1, validArgumentCount, TLVError, TLVUnpackError);
}
break;
}
case ZCL_CLEAR_WEEKDAY_SCHEDULE_RESPONSE_COMMAND_ID: {
// 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.
CHIP_ERROR TLVError = CHIP_NO_ERROR;
CHIP_ERROR TLVUnpackError = CHIP_NO_ERROR;
uint8_t status;
bool statusExists = false;
uint32_t validArgumentCount = 0;
while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR)
{
switch (TLV::TagNumFromTag(aDataTlv.GetTag()))
{
case 0:
if (statusExists)
{
ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
break;
}
TLVUnpackError = aDataTlv.Get(status);
if (CHIP_NO_ERROR == TLVUnpackError)
{
statusExists = true;
validArgumentCount++;
}
break;
default:
// Unsupported tag, ignore it.
ChipLogProgress(Zcl, "Unknown TLV tag during processing.");
break;
}
if (TLVUnpackError != CHIP_NO_ERROR)
{
ChipLogProgress(Zcl, "Failed to decode TLV data with tag %" PRIx32 ": %" PRId32,
TLV::TagNumFromTag(aDataTlv.GetTag()), 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;
}
else
{
ChipLogProgress(Zcl, "Failed to decode TLV data: %" PRId32, TLVError);
}
// TODO(#5590) We should encode a response of status code for invalid TLV.
if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 1 == validArgumentCount)
{
// TODO(#5098) We should pass the Command Object and EndpointId to the cluster callbacks.
emberAfDoorLockClusterClearWeekdayScheduleResponseCallback(apCommandObj, status);
}
else
{
apCommandObj->AddStatusCode(nullptr, Protocols::SecureChannel::GeneralStatusCode::kBadRequest,
Protocols::SecureChannel::Id, Protocols::SecureChannel::kProtocolCodeGeneralFailure);
ChipLogProgress(
Zcl, "Failed to dispatch command, %d/%" PRIu32 " arguments parsed, TLVError=%" PRIu32 ", UnpackError=%" PRIu32,
1, validArgumentCount, TLVError, TLVUnpackError);
}
break;
}
case ZCL_CLEAR_YEARDAY_SCHEDULE_RESPONSE_COMMAND_ID: {
// 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.
CHIP_ERROR TLVError = CHIP_NO_ERROR;
CHIP_ERROR TLVUnpackError = CHIP_NO_ERROR;
uint8_t status;
bool statusExists = false;
uint32_t validArgumentCount = 0;
while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR)
{
switch (TLV::TagNumFromTag(aDataTlv.GetTag()))
{
case 0:
if (statusExists)
{
ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
break;
}
TLVUnpackError = aDataTlv.Get(status);
if (CHIP_NO_ERROR == TLVUnpackError)
{
statusExists = true;
validArgumentCount++;
}
break;
default:
// Unsupported tag, ignore it.
ChipLogProgress(Zcl, "Unknown TLV tag during processing.");
break;
}
if (TLVUnpackError != CHIP_NO_ERROR)
{
ChipLogProgress(Zcl, "Failed to decode TLV data with tag %" PRIx32 ": %" PRId32,
TLV::TagNumFromTag(aDataTlv.GetTag()), 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;
}
else
{
ChipLogProgress(Zcl, "Failed to decode TLV data: %" PRId32, TLVError);
}
// TODO(#5590) We should encode a response of status code for invalid TLV.
if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 1 == validArgumentCount)
{
// TODO(#5098) We should pass the Command Object and EndpointId to the cluster callbacks.
emberAfDoorLockClusterClearYeardayScheduleResponseCallback(apCommandObj, status);
}
else
{
apCommandObj->AddStatusCode(nullptr, Protocols::SecureChannel::GeneralStatusCode::kBadRequest,
Protocols::SecureChannel::Id, Protocols::SecureChannel::kProtocolCodeGeneralFailure);
ChipLogProgress(
Zcl, "Failed to dispatch command, %d/%" PRIu32 " arguments parsed, TLVError=%" PRIu32 ", UnpackError=%" PRIu32,
1, validArgumentCount, TLVError, TLVUnpackError);
}
break;
}
case ZCL_GET_HOLIDAY_SCHEDULE_RESPONSE_COMMAND_ID: {
// 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.
CHIP_ERROR TLVError = CHIP_NO_ERROR;
CHIP_ERROR TLVUnpackError = CHIP_NO_ERROR;
uint8_t scheduleId;
bool scheduleIdExists = false;
uint8_t status;
bool statusExists = false;
uint32_t localStartTime;
bool localStartTimeExists = false;
uint32_t localEndTime;
bool localEndTimeExists = false;
uint8_t operatingModeDuringHoliday;
bool operatingModeDuringHolidayExists = false;
uint32_t validArgumentCount = 0;
while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR)
{
switch (TLV::TagNumFromTag(aDataTlv.GetTag()))
{
case 0:
if (scheduleIdExists)
{
ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
break;
}
TLVUnpackError = aDataTlv.Get(scheduleId);
if (CHIP_NO_ERROR == TLVUnpackError)
{
scheduleIdExists = true;
validArgumentCount++;
}
break;
case 1:
if (statusExists)
{
ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
break;
}
TLVUnpackError = aDataTlv.Get(status);
if (CHIP_NO_ERROR == TLVUnpackError)
{
statusExists = true;
validArgumentCount++;
}
break;
case 2:
if (localStartTimeExists)
{
ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
break;
}
TLVUnpackError = aDataTlv.Get(localStartTime);
if (CHIP_NO_ERROR == TLVUnpackError)
{
localStartTimeExists = true;
validArgumentCount++;
}
break;
case 3:
if (localEndTimeExists)
{
ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
break;
}
TLVUnpackError = aDataTlv.Get(localEndTime);
if (CHIP_NO_ERROR == TLVUnpackError)
{
localEndTimeExists = true;
validArgumentCount++;
}
break;
case 4:
if (operatingModeDuringHolidayExists)
{
ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
break;
}
TLVUnpackError = aDataTlv.Get(operatingModeDuringHoliday);
if (CHIP_NO_ERROR == TLVUnpackError)
{
operatingModeDuringHolidayExists = true;
validArgumentCount++;
}
break;
default:
// Unsupported tag, ignore it.
ChipLogProgress(Zcl, "Unknown TLV tag during processing.");
break;
}
if (TLVUnpackError != CHIP_NO_ERROR)
{
ChipLogProgress(Zcl, "Failed to decode TLV data with tag %" PRIx32 ": %" PRId32,
TLV::TagNumFromTag(aDataTlv.GetTag()), 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;
}
else
{
ChipLogProgress(Zcl, "Failed to decode TLV data: %" PRId32, TLVError);
}
// TODO(#5590) We should encode a response of status code for invalid TLV.
if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 5 == validArgumentCount)
{
// TODO(#5098) We should pass the Command Object and EndpointId to the cluster callbacks.
emberAfDoorLockClusterGetHolidayScheduleResponseCallback(apCommandObj, scheduleId, status, localStartTime,
localEndTime, operatingModeDuringHoliday);
}
else
{
apCommandObj->AddStatusCode(nullptr, Protocols::SecureChannel::GeneralStatusCode::kBadRequest,
Protocols::SecureChannel::Id, Protocols::SecureChannel::kProtocolCodeGeneralFailure);
ChipLogProgress(
Zcl, "Failed to dispatch command, %d/%" PRIu32 " arguments parsed, TLVError=%" PRIu32 ", UnpackError=%" PRIu32,
5, validArgumentCount, TLVError, TLVUnpackError);
}
break;
}
case ZCL_GET_LOG_RECORD_RESPONSE_COMMAND_ID: {
// 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.
CHIP_ERROR TLVError = CHIP_NO_ERROR;
CHIP_ERROR TLVUnpackError = CHIP_NO_ERROR;
uint16_t logEntryId;
bool logEntryIdExists = false;
uint32_t timestamp;
bool timestampExists = false;
uint8_t eventType;
bool eventTypeExists = false;
uint8_t source;
bool sourceExists = false;
uint8_t eventIdOrAlarmCode;
bool eventIdOrAlarmCodeExists = false;
uint16_t userId;
bool userIdExists = false;
const uint8_t * pin;
bool pinExists = false;
uint32_t validArgumentCount = 0;
while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR)
{
switch (TLV::TagNumFromTag(aDataTlv.GetTag()))
{
case 0:
if (logEntryIdExists)
{
ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
break;
}
TLVUnpackError = aDataTlv.Get(logEntryId);
if (CHIP_NO_ERROR == TLVUnpackError)
{
logEntryIdExists = true;
validArgumentCount++;
}
break;
case 1:
if (timestampExists)
{
ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
break;
}
TLVUnpackError = aDataTlv.Get(timestamp);
if (CHIP_NO_ERROR == TLVUnpackError)
{
timestampExists = true;
validArgumentCount++;
}
break;
case 2:
if (eventTypeExists)
{
ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
break;
}
TLVUnpackError = aDataTlv.Get(eventType);
if (CHIP_NO_ERROR == TLVUnpackError)
{
eventTypeExists = true;
validArgumentCount++;
}
break;
case 3:
if (sourceExists)
{
ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
break;
}
TLVUnpackError = aDataTlv.Get(source);
if (CHIP_NO_ERROR == TLVUnpackError)
{
sourceExists = true;
validArgumentCount++;
}
break;
case 4:
if (eventIdOrAlarmCodeExists)
{
ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
break;
}
TLVUnpackError = aDataTlv.Get(eventIdOrAlarmCode);
if (CHIP_NO_ERROR == TLVUnpackError)
{
eventIdOrAlarmCodeExists = true;
validArgumentCount++;
}
break;
case 5:
if (userIdExists)
{
ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
break;
}
TLVUnpackError = aDataTlv.Get(userId);
if (CHIP_NO_ERROR == TLVUnpackError)
{
userIdExists = true;
validArgumentCount++;
}
break;
case 6:
if (pinExists)
{
ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
break;
}
// TODO(#5542): The cluster handlers should accept a ByteSpan for all string types.
TLVUnpackError = aDataTlv.GetDataPtr(pin);
if (CHIP_NO_ERROR == TLVUnpackError)
{
pinExists = true;
validArgumentCount++;
}
break;
default:
// Unsupported tag, ignore it.
ChipLogProgress(Zcl, "Unknown TLV tag during processing.");
break;
}
if (TLVUnpackError != CHIP_NO_ERROR)
{
ChipLogProgress(Zcl, "Failed to decode TLV data with tag %" PRIx32 ": %" PRId32,
TLV::TagNumFromTag(aDataTlv.GetTag()), 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;
}
else
{
ChipLogProgress(Zcl, "Failed to decode TLV data: %" PRId32, TLVError);
}
// TODO(#5590) We should encode a response of status code for invalid TLV.
if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 7 == validArgumentCount)
{
// TODO(#5098) We should pass the Command Object and EndpointId to the cluster callbacks.
emberAfDoorLockClusterGetLogRecordResponseCallback(apCommandObj, logEntryId, timestamp, eventType, source,
eventIdOrAlarmCode, userId, const_cast<uint8_t *>(pin));
}
else
{
apCommandObj->AddStatusCode(nullptr, Protocols::SecureChannel::GeneralStatusCode::kBadRequest,
Protocols::SecureChannel::Id, Protocols::SecureChannel::kProtocolCodeGeneralFailure);
ChipLogProgress(
Zcl, "Failed to dispatch command, %d/%" PRIu32 " arguments parsed, TLVError=%" PRIu32 ", UnpackError=%" PRIu32,
7, validArgumentCount, TLVError, TLVUnpackError);
}
break;
}
case ZCL_GET_PIN_RESPONSE_COMMAND_ID: {
// 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.
CHIP_ERROR TLVError = CHIP_NO_ERROR;
CHIP_ERROR TLVUnpackError = CHIP_NO_ERROR;
uint16_t userId;
bool userIdExists = false;
uint8_t userStatus;
bool userStatusExists = false;
uint8_t userType;
bool userTypeExists = false;
const uint8_t * pin;
bool pinExists = false;
uint32_t validArgumentCount = 0;
while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR)
{
switch (TLV::TagNumFromTag(aDataTlv.GetTag()))
{
case 0:
if (userIdExists)
{
ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
break;
}
TLVUnpackError = aDataTlv.Get(userId);
if (CHIP_NO_ERROR == TLVUnpackError)
{
userIdExists = true;
validArgumentCount++;
}
break;
case 1:
if (userStatusExists)
{
ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
break;
}
TLVUnpackError = aDataTlv.Get(userStatus);
if (CHIP_NO_ERROR == TLVUnpackError)
{
userStatusExists = true;
validArgumentCount++;
}
break;
case 2:
if (userTypeExists)
{
ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
break;
}
TLVUnpackError = aDataTlv.Get(userType);
if (CHIP_NO_ERROR == TLVUnpackError)
{
userTypeExists = true;
validArgumentCount++;
}
break;
case 3:
if (pinExists)
{
ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
break;
}
// TODO(#5542): The cluster handlers should accept a ByteSpan for all string types.
TLVUnpackError = aDataTlv.GetDataPtr(pin);
if (CHIP_NO_ERROR == TLVUnpackError)
{
pinExists = true;
validArgumentCount++;
}
break;
default:
// Unsupported tag, ignore it.
ChipLogProgress(Zcl, "Unknown TLV tag during processing.");
break;
}
if (TLVUnpackError != CHIP_NO_ERROR)
{
ChipLogProgress(Zcl, "Failed to decode TLV data with tag %" PRIx32 ": %" PRId32,
TLV::TagNumFromTag(aDataTlv.GetTag()), 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;
}
else
{
ChipLogProgress(Zcl, "Failed to decode TLV data: %" PRId32, TLVError);
}
// TODO(#5590) We should encode a response of status code for invalid TLV.
if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 4 == validArgumentCount)
{
// TODO(#5098) We should pass the Command Object and EndpointId to the cluster callbacks.
emberAfDoorLockClusterGetPinResponseCallback(apCommandObj, userId, userStatus, userType,
const_cast<uint8_t *>(pin));
}
else
{
apCommandObj->AddStatusCode(nullptr, Protocols::SecureChannel::GeneralStatusCode::kBadRequest,
Protocols::SecureChannel::Id, Protocols::SecureChannel::kProtocolCodeGeneralFailure);
ChipLogProgress(
Zcl, "Failed to dispatch command, %d/%" PRIu32 " arguments parsed, TLVError=%" PRIu32 ", UnpackError=%" PRIu32,
4, validArgumentCount, TLVError, TLVUnpackError);
}
break;
}
case ZCL_GET_RFID_RESPONSE_COMMAND_ID: {
// 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.
CHIP_ERROR TLVError = CHIP_NO_ERROR;
CHIP_ERROR TLVUnpackError = CHIP_NO_ERROR;
uint16_t userId;
bool userIdExists = false;
uint8_t userStatus;
bool userStatusExists = false;
uint8_t userType;
bool userTypeExists = false;
const uint8_t * rfid;
bool rfidExists = false;
uint32_t validArgumentCount = 0;
while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR)
{
switch (TLV::TagNumFromTag(aDataTlv.GetTag()))
{
case 0:
if (userIdExists)
{
ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
break;
}
TLVUnpackError = aDataTlv.Get(userId);
if (CHIP_NO_ERROR == TLVUnpackError)
{
userIdExists = true;
validArgumentCount++;
}
break;
case 1:
if (userStatusExists)
{
ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
break;
}
TLVUnpackError = aDataTlv.Get(userStatus);
if (CHIP_NO_ERROR == TLVUnpackError)
{
userStatusExists = true;
validArgumentCount++;
}
break;
case 2:
if (userTypeExists)
{
ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
break;
}
TLVUnpackError = aDataTlv.Get(userType);
if (CHIP_NO_ERROR == TLVUnpackError)
{
userTypeExists = true;
validArgumentCount++;
}
break;
case 3:
if (rfidExists)
{
ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
break;
}
// TODO(#5542): The cluster handlers should accept a ByteSpan for all string types.
TLVUnpackError = aDataTlv.GetDataPtr(rfid);
if (CHIP_NO_ERROR == TLVUnpackError)
{
rfidExists = true;
validArgumentCount++;
}
break;
default:
// Unsupported tag, ignore it.
ChipLogProgress(Zcl, "Unknown TLV tag during processing.");
break;
}
if (TLVUnpackError != CHIP_NO_ERROR)
{
ChipLogProgress(Zcl, "Failed to decode TLV data with tag %" PRIx32 ": %" PRId32,
TLV::TagNumFromTag(aDataTlv.GetTag()), 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;
}
else
{
ChipLogProgress(Zcl, "Failed to decode TLV data: %" PRId32, TLVError);
}
// TODO(#5590) We should encode a response of status code for invalid TLV.
if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 4 == validArgumentCount)
{
// TODO(#5098) We should pass the Command Object and EndpointId to the cluster callbacks.
emberAfDoorLockClusterGetRfidResponseCallback(apCommandObj, userId, userStatus, userType,
const_cast<uint8_t *>(rfid));
}
else
{
apCommandObj->AddStatusCode(nullptr, Protocols::SecureChannel::GeneralStatusCode::kBadRequest,
Protocols::SecureChannel::Id, Protocols::SecureChannel::kProtocolCodeGeneralFailure);
ChipLogProgress(
Zcl, "Failed to dispatch command, %d/%" PRIu32 " arguments parsed, TLVError=%" PRIu32 ", UnpackError=%" PRIu32,
4, validArgumentCount, TLVError, TLVUnpackError);
}
break;
}
case ZCL_GET_USER_TYPE_RESPONSE_COMMAND_ID: {
// 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.
CHIP_ERROR TLVError = CHIP_NO_ERROR;
CHIP_ERROR TLVUnpackError = CHIP_NO_ERROR;
uint16_t userId;
bool userIdExists = false;
uint8_t userType;
bool userTypeExists = false;
uint32_t validArgumentCount = 0;
while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR)
{
switch (TLV::TagNumFromTag(aDataTlv.GetTag()))
{
case 0:
if (userIdExists)
{
ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
break;
}
TLVUnpackError = aDataTlv.Get(userId);
if (CHIP_NO_ERROR == TLVUnpackError)
{
userIdExists = true;
validArgumentCount++;
}
break;
case 1:
if (userTypeExists)
{
ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
break;
}
TLVUnpackError = aDataTlv.Get(userType);
if (CHIP_NO_ERROR == TLVUnpackError)
{
userTypeExists = true;
validArgumentCount++;
}
break;
default:
// Unsupported tag, ignore it.
ChipLogProgress(Zcl, "Unknown TLV tag during processing.");
break;
}
if (TLVUnpackError != CHIP_NO_ERROR)
{
ChipLogProgress(Zcl, "Failed to decode TLV data with tag %" PRIx32 ": %" PRId32,
TLV::TagNumFromTag(aDataTlv.GetTag()), 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;
}
else
{
ChipLogProgress(Zcl, "Failed to decode TLV data: %" PRId32, TLVError);
}
// TODO(#5590) We should encode a response of status code for invalid TLV.
if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 2 == validArgumentCount)
{
// TODO(#5098) We should pass the Command Object and EndpointId to the cluster callbacks.
emberAfDoorLockClusterGetUserTypeResponseCallback(apCommandObj, userId, userType);
}
else
{
apCommandObj->AddStatusCode(nullptr, Protocols::SecureChannel::GeneralStatusCode::kBadRequest,
Protocols::SecureChannel::Id, Protocols::SecureChannel::kProtocolCodeGeneralFailure);
ChipLogProgress(
Zcl, "Failed to dispatch command, %d/%" PRIu32 " arguments parsed, TLVError=%" PRIu32 ", UnpackError=%" PRIu32,
2, validArgumentCount, TLVError, TLVUnpackError);
}
break;
}
case ZCL_GET_WEEKDAY_SCHEDULE_RESPONSE_COMMAND_ID: {
// 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.
CHIP_ERROR TLVError = CHIP_NO_ERROR;
CHIP_ERROR TLVUnpackError = CHIP_NO_ERROR;
uint8_t scheduleId;
bool scheduleIdExists = false;
uint16_t userId;
bool userIdExists = false;
uint8_t status;
bool statusExists = false;
uint8_t daysMask;
bool daysMaskExists = false;
uint8_t startHour;
bool startHourExists = false;
uint8_t startMinute;
bool startMinuteExists = false;
uint8_t endHour;
bool endHourExists = false;
uint8_t endMinute;
bool endMinuteExists = false;
uint32_t validArgumentCount = 0;
while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR)
{
switch (TLV::TagNumFromTag(aDataTlv.GetTag()))
{
case 0:
if (scheduleIdExists)
{
ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
break;
}
TLVUnpackError = aDataTlv.Get(scheduleId);
if (CHIP_NO_ERROR == TLVUnpackError)
{
scheduleIdExists = true;
validArgumentCount++;
}
break;
case 1:
if (userIdExists)
{
ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
break;
}
TLVUnpackError = aDataTlv.Get(userId);
if (CHIP_NO_ERROR == TLVUnpackError)
{
userIdExists = true;
validArgumentCount++;
}
break;
case 2:
if (statusExists)
{
ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
break;
}
TLVUnpackError = aDataTlv.Get(status);
if (CHIP_NO_ERROR == TLVUnpackError)
{
statusExists = true;
validArgumentCount++;
}
break;
case 3:
if (daysMaskExists)
{
ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
break;
}
TLVUnpackError = aDataTlv.Get(daysMask);
if (CHIP_NO_ERROR == TLVUnpackError)
{
daysMaskExists = true;
validArgumentCount++;
}
break;
case 4:
if (startHourExists)
{
ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
break;
}
TLVUnpackError = aDataTlv.Get(startHour);
if (CHIP_NO_ERROR == TLVUnpackError)
{
startHourExists = true;
validArgumentCount++;
}
break;
case 5:
if (startMinuteExists)
{
ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
break;
}
TLVUnpackError = aDataTlv.Get(startMinute);
if (CHIP_NO_ERROR == TLVUnpackError)
{
startMinuteExists = true;
validArgumentCount++;
}
break;
case 6:
if (endHourExists)
{
ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
break;
}
TLVUnpackError = aDataTlv.Get(endHour);
if (CHIP_NO_ERROR == TLVUnpackError)
{
endHourExists = true;
validArgumentCount++;
}
break;
case 7:
if (endMinuteExists)
{
ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
break;
}
TLVUnpackError = aDataTlv.Get(endMinute);
if (CHIP_NO_ERROR == TLVUnpackError)
{
endMinuteExists = true;
validArgumentCount++;
}
break;
default:
// Unsupported tag, ignore it.
ChipLogProgress(Zcl, "Unknown TLV tag during processing.");
break;
}
if (TLVUnpackError != CHIP_NO_ERROR)
{
ChipLogProgress(Zcl, "Failed to decode TLV data with tag %" PRIx32 ": %" PRId32,
TLV::TagNumFromTag(aDataTlv.GetTag()), 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;
}
else
{
ChipLogProgress(Zcl, "Failed to decode TLV data: %" PRId32, TLVError);
}
// TODO(#5590) We should encode a response of status code for invalid TLV.
if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 8 == validArgumentCount)
{
// TODO(#5098) We should pass the Command Object and EndpointId to the cluster callbacks.
emberAfDoorLockClusterGetWeekdayScheduleResponseCallback(apCommandObj, scheduleId, userId, status, daysMask,
startHour, startMinute, endHour, endMinute);
}
else
{
apCommandObj->AddStatusCode(nullptr, Protocols::SecureChannel::GeneralStatusCode::kBadRequest,
Protocols::SecureChannel::Id, Protocols::SecureChannel::kProtocolCodeGeneralFailure);
ChipLogProgress(
Zcl, "Failed to dispatch command, %d/%" PRIu32 " arguments parsed, TLVError=%" PRIu32 ", UnpackError=%" PRIu32,
8, validArgumentCount, TLVError, TLVUnpackError);
}
break;
}
case ZCL_GET_YEARDAY_SCHEDULE_RESPONSE_COMMAND_ID: {
// 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.
CHIP_ERROR TLVError = CHIP_NO_ERROR;
CHIP_ERROR TLVUnpackError = CHIP_NO_ERROR;
uint8_t scheduleId;
bool scheduleIdExists = false;
uint16_t userId;
bool userIdExists = false;
uint8_t status;
bool statusExists = false;
uint32_t localStartTime;
bool localStartTimeExists = false;
uint32_t localEndTime;
bool localEndTimeExists = false;
uint32_t validArgumentCount = 0;
while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR)
{
switch (TLV::TagNumFromTag(aDataTlv.GetTag()))
{
case 0:
if (scheduleIdExists)
{
ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
break;
}
TLVUnpackError = aDataTlv.Get(scheduleId);
if (CHIP_NO_ERROR == TLVUnpackError)
{
scheduleIdExists = true;
validArgumentCount++;
}
break;
case 1:
if (userIdExists)
{
ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
break;
}
TLVUnpackError = aDataTlv.Get(userId);
if (CHIP_NO_ERROR == TLVUnpackError)
{
userIdExists = true;
validArgumentCount++;
}
break;
case 2:
if (statusExists)
{
ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
break;
}
TLVUnpackError = aDataTlv.Get(status);
if (CHIP_NO_ERROR == TLVUnpackError)
{
statusExists = true;
validArgumentCount++;
}
break;
case 3:
if (localStartTimeExists)
{
ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
break;
}
TLVUnpackError = aDataTlv.Get(localStartTime);
if (CHIP_NO_ERROR == TLVUnpackError)
{
localStartTimeExists = true;
validArgumentCount++;
}
break;
case 4:
if (localEndTimeExists)
{
ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
break;
}
TLVUnpackError = aDataTlv.Get(localEndTime);
if (CHIP_NO_ERROR == TLVUnpackError)
{
localEndTimeExists = true;
validArgumentCount++;
}
break;
default:
// Unsupported tag, ignore it.
ChipLogProgress(Zcl, "Unknown TLV tag during processing.");
break;
}
if (TLVUnpackError != CHIP_NO_ERROR)
{
ChipLogProgress(Zcl, "Failed to decode TLV data with tag %" PRIx32 ": %" PRId32,
TLV::TagNumFromTag(aDataTlv.GetTag()), 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;
}
else
{
ChipLogProgress(Zcl, "Failed to decode TLV data: %" PRId32, TLVError);
}
// TODO(#5590) We should encode a response of status code for invalid TLV.
if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 5 == validArgumentCount)
{
// TODO(#5098) We should pass the Command Object and EndpointId to the cluster callbacks.
emberAfDoorLockClusterGetYeardayScheduleResponseCallback(apCommandObj, scheduleId, userId, status, localStartTime,
localEndTime);
}
else
{
apCommandObj->AddStatusCode(nullptr, Protocols::SecureChannel::GeneralStatusCode::kBadRequest,
Protocols::SecureChannel::Id, Protocols::SecureChannel::kProtocolCodeGeneralFailure);
ChipLogProgress(
Zcl, "Failed to dispatch command, %d/%" PRIu32 " arguments parsed, TLVError=%" PRIu32 ", UnpackError=%" PRIu32,
5, validArgumentCount, TLVError, TLVUnpackError);
}
break;
}
case ZCL_LOCK_DOOR_RESPONSE_COMMAND_ID: {
// 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.
CHIP_ERROR TLVError = CHIP_NO_ERROR;
CHIP_ERROR TLVUnpackError = CHIP_NO_ERROR;
uint8_t status;
bool statusExists = false;
uint32_t validArgumentCount = 0;
while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR)
{
switch (TLV::TagNumFromTag(aDataTlv.GetTag()))
{
case 0:
if (statusExists)
{
ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
break;
}
TLVUnpackError = aDataTlv.Get(status);
if (CHIP_NO_ERROR == TLVUnpackError)
{
statusExists = true;
validArgumentCount++;
}
break;
default:
// Unsupported tag, ignore it.
ChipLogProgress(Zcl, "Unknown TLV tag during processing.");
break;
}
if (TLVUnpackError != CHIP_NO_ERROR)
{
ChipLogProgress(Zcl, "Failed to decode TLV data with tag %" PRIx32 ": %" PRId32,
TLV::TagNumFromTag(aDataTlv.GetTag()), 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;
}
else
{
ChipLogProgress(Zcl, "Failed to decode TLV data: %" PRId32, TLVError);
}
// TODO(#5590) We should encode a response of status code for invalid TLV.
if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 1 == validArgumentCount)
{
// TODO(#5098) We should pass the Command Object and EndpointId to the cluster callbacks.
emberAfDoorLockClusterLockDoorResponseCallback(apCommandObj, status);
}
else
{
apCommandObj->AddStatusCode(nullptr, Protocols::SecureChannel::GeneralStatusCode::kBadRequest,
Protocols::SecureChannel::Id, Protocols::SecureChannel::kProtocolCodeGeneralFailure);
ChipLogProgress(
Zcl, "Failed to dispatch command, %d/%" PRIu32 " arguments parsed, TLVError=%" PRIu32 ", UnpackError=%" PRIu32,
1, validArgumentCount, TLVError, TLVUnpackError);
}
break;
}
case ZCL_SET_HOLIDAY_SCHEDULE_RESPONSE_COMMAND_ID: {
// 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.
CHIP_ERROR TLVError = CHIP_NO_ERROR;
CHIP_ERROR TLVUnpackError = CHIP_NO_ERROR;
uint8_t status;
bool statusExists = false;
uint32_t validArgumentCount = 0;
while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR)
{
switch (TLV::TagNumFromTag(aDataTlv.GetTag()))
{
case 0:
if (statusExists)
{
ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
break;
}
TLVUnpackError = aDataTlv.Get(status);
if (CHIP_NO_ERROR == TLVUnpackError)
{
statusExists = true;
validArgumentCount++;
}
break;
default:
// Unsupported tag, ignore it.
ChipLogProgress(Zcl, "Unknown TLV tag during processing.");
break;
}
if (TLVUnpackError != CHIP_NO_ERROR)
{
ChipLogProgress(Zcl, "Failed to decode TLV data with tag %" PRIx32 ": %" PRId32,
TLV::TagNumFromTag(aDataTlv.GetTag()), 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;
}
else
{
ChipLogProgress(Zcl, "Failed to decode TLV data: %" PRId32, TLVError);
}
// TODO(#5590) We should encode a response of status code for invalid TLV.
if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 1 == validArgumentCount)
{
// TODO(#5098) We should pass the Command Object and EndpointId to the cluster callbacks.
emberAfDoorLockClusterSetHolidayScheduleResponseCallback(apCommandObj, status);
}
else
{
apCommandObj->AddStatusCode(nullptr, Protocols::SecureChannel::GeneralStatusCode::kBadRequest,
Protocols::SecureChannel::Id, Protocols::SecureChannel::kProtocolCodeGeneralFailure);
ChipLogProgress(
Zcl, "Failed to dispatch command, %d/%" PRIu32 " arguments parsed, TLVError=%" PRIu32 ", UnpackError=%" PRIu32,
1, validArgumentCount, TLVError, TLVUnpackError);
}
break;
}
case ZCL_SET_PIN_RESPONSE_COMMAND_ID: {
// 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.
CHIP_ERROR TLVError = CHIP_NO_ERROR;
CHIP_ERROR TLVUnpackError = CHIP_NO_ERROR;
uint8_t status;
bool statusExists = false;
uint32_t validArgumentCount = 0;
while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR)
{
switch (TLV::TagNumFromTag(aDataTlv.GetTag()))
{
case 0:
if (statusExists)
{
ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
break;
}
TLVUnpackError = aDataTlv.Get(status);
if (CHIP_NO_ERROR == TLVUnpackError)
{
statusExists = true;
validArgumentCount++;
}
break;
default:
// Unsupported tag, ignore it.
ChipLogProgress(Zcl, "Unknown TLV tag during processing.");
break;
}
if (TLVUnpackError != CHIP_NO_ERROR)
{
ChipLogProgress(Zcl, "Failed to decode TLV data with tag %" PRIx32 ": %" PRId32,
TLV::TagNumFromTag(aDataTlv.GetTag()), 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;
}
else
{
ChipLogProgress(Zcl, "Failed to decode TLV data: %" PRId32, TLVError);
}
// TODO(#5590) We should encode a response of status code for invalid TLV.
if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 1 == validArgumentCount)
{
// TODO(#5098) We should pass the Command Object and EndpointId to the cluster callbacks.
emberAfDoorLockClusterSetPinResponseCallback(apCommandObj, status);
}
else
{
apCommandObj->AddStatusCode(nullptr, Protocols::SecureChannel::GeneralStatusCode::kBadRequest,
Protocols::SecureChannel::Id, Protocols::SecureChannel::kProtocolCodeGeneralFailure);
ChipLogProgress(
Zcl, "Failed to dispatch command, %d/%" PRIu32 " arguments parsed, TLVError=%" PRIu32 ", UnpackError=%" PRIu32,
1, validArgumentCount, TLVError, TLVUnpackError);
}
break;
}
case ZCL_SET_RFID_RESPONSE_COMMAND_ID: {
// 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.
CHIP_ERROR TLVError = CHIP_NO_ERROR;
CHIP_ERROR TLVUnpackError = CHIP_NO_ERROR;
uint8_t status;
bool statusExists = false;
uint32_t validArgumentCount = 0;
while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR)
{
switch (TLV::TagNumFromTag(aDataTlv.GetTag()))
{
case 0:
if (statusExists)
{
ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
break;
}
TLVUnpackError = aDataTlv.Get(status);
if (CHIP_NO_ERROR == TLVUnpackError)
{
statusExists = true;
validArgumentCount++;
}
break;
default:
// Unsupported tag, ignore it.
ChipLogProgress(Zcl, "Unknown TLV tag during processing.");
break;
}
if (TLVUnpackError != CHIP_NO_ERROR)
{
ChipLogProgress(Zcl, "Failed to decode TLV data with tag %" PRIx32 ": %" PRId32,
TLV::TagNumFromTag(aDataTlv.GetTag()), 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;
}
else
{
ChipLogProgress(Zcl, "Failed to decode TLV data: %" PRId32, TLVError);
}
// TODO(#5590) We should encode a response of status code for invalid TLV.
if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 1 == validArgumentCount)
{
// TODO(#5098) We should pass the Command Object and EndpointId to the cluster callbacks.
emberAfDoorLockClusterSetRfidResponseCallback(apCommandObj, status);
}
else
{
apCommandObj->AddStatusCode(nullptr, Protocols::SecureChannel::GeneralStatusCode::kBadRequest,
Protocols::SecureChannel::Id, Protocols::SecureChannel::kProtocolCodeGeneralFailure);
ChipLogProgress(
Zcl, "Failed to dispatch command, %d/%" PRIu32 " arguments parsed, TLVError=%" PRIu32 ", UnpackError=%" PRIu32,
1, validArgumentCount, TLVError, TLVUnpackError);
}
break;
}
case ZCL_SET_USER_TYPE_RESPONSE_COMMAND_ID: {
// 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.
CHIP_ERROR TLVError = CHIP_NO_ERROR;
CHIP_ERROR TLVUnpackError = CHIP_NO_ERROR;
uint8_t status;
bool statusExists = false;
uint32_t validArgumentCount = 0;
while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR)
{
switch (TLV::TagNumFromTag(aDataTlv.GetTag()))
{
case 0:
if (statusExists)
{
ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
break;
}
TLVUnpackError = aDataTlv.Get(status);
if (CHIP_NO_ERROR == TLVUnpackError)
{
statusExists = true;
validArgumentCount++;
}
break;
default:
// Unsupported tag, ignore it.
ChipLogProgress(Zcl, "Unknown TLV tag during processing.");
break;
}
if (TLVUnpackError != CHIP_NO_ERROR)
{
ChipLogProgress(Zcl, "Failed to decode TLV data with tag %" PRIx32 ": %" PRId32,
TLV::TagNumFromTag(aDataTlv.GetTag()), 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;
}
else
{
ChipLogProgress(Zcl, "Failed to decode TLV data: %" PRId32, TLVError);
}
// TODO(#5590) We should encode a response of status code for invalid TLV.
if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 1 == validArgumentCount)
{
// TODO(#5098) We should pass the Command Object and EndpointId to the cluster callbacks.
emberAfDoorLockClusterSetUserTypeResponseCallback(apCommandObj, status);
}
else
{
apCommandObj->AddStatusCode(nullptr, Protocols::SecureChannel::GeneralStatusCode::kBadRequest,
Protocols::SecureChannel::Id, Protocols::SecureChannel::kProtocolCodeGeneralFailure);
ChipLogProgress(
Zcl, "Failed to dispatch command, %d/%" PRIu32 " arguments parsed, TLVError=%" PRIu32 ", UnpackError=%" PRIu32,
1, validArgumentCount, TLVError, TLVUnpackError);
}
break;
}
case ZCL_SET_WEEKDAY_SCHEDULE_RESPONSE_COMMAND_ID: {
// 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.
CHIP_ERROR TLVError = CHIP_NO_ERROR;
CHIP_ERROR TLVUnpackError = CHIP_NO_ERROR;
uint8_t status;
bool statusExists = false;
uint32_t validArgumentCount = 0;
while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR)
{
switch (TLV::TagNumFromTag(aDataTlv.GetTag()))
{
case 0:
if (statusExists)
{
ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
break;
}
TLVUnpackError = aDataTlv.Get(status);
if (CHIP_NO_ERROR == TLVUnpackError)
{
statusExists = true;
validArgumentCount++;
}
break;
default:
// Unsupported tag, ignore it.
ChipLogProgress(Zcl, "Unknown TLV tag during processing.");
break;
}
if (TLVUnpackError != CHIP_NO_ERROR)
{
ChipLogProgress(Zcl, "Failed to decode TLV data with tag %" PRIx32 ": %" PRId32,
TLV::TagNumFromTag(aDataTlv.GetTag()), 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;
}
else
{
ChipLogProgress(Zcl, "Failed to decode TLV data: %" PRId32, TLVError);
}
// TODO(#5590) We should encode a response of status code for invalid TLV.
if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 1 == validArgumentCount)
{
// TODO(#5098) We should pass the Command Object and EndpointId to the cluster callbacks.
emberAfDoorLockClusterSetWeekdayScheduleResponseCallback(apCommandObj, status);
}
else
{
apCommandObj->AddStatusCode(nullptr, Protocols::SecureChannel::GeneralStatusCode::kBadRequest,
Protocols::SecureChannel::Id, Protocols::SecureChannel::kProtocolCodeGeneralFailure);
ChipLogProgress(
Zcl, "Failed to dispatch command, %d/%" PRIu32 " arguments parsed, TLVError=%" PRIu32 ", UnpackError=%" PRIu32,
1, validArgumentCount, TLVError, TLVUnpackError);
}
break;
}
case ZCL_SET_YEARDAY_SCHEDULE_RESPONSE_COMMAND_ID: {
// 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.
CHIP_ERROR TLVError = CHIP_NO_ERROR;
CHIP_ERROR TLVUnpackError = CHIP_NO_ERROR;
uint8_t status;
bool statusExists = false;
uint32_t validArgumentCount = 0;
while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR)
{
switch (TLV::TagNumFromTag(aDataTlv.GetTag()))
{
case 0:
if (statusExists)
{
ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
break;
}
TLVUnpackError = aDataTlv.Get(status);
if (CHIP_NO_ERROR == TLVUnpackError)
{
statusExists = true;
validArgumentCount++;
}
break;
default:
// Unsupported tag, ignore it.
ChipLogProgress(Zcl, "Unknown TLV tag during processing.");
break;
}
if (TLVUnpackError != CHIP_NO_ERROR)
{
ChipLogProgress(Zcl, "Failed to decode TLV data with tag %" PRIx32 ": %" PRId32,
TLV::TagNumFromTag(aDataTlv.GetTag()), 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;
}
else
{
ChipLogProgress(Zcl, "Failed to decode TLV data: %" PRId32, TLVError);
}
// TODO(#5590) We should encode a response of status code for invalid TLV.
if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 1 == validArgumentCount)
{
// TODO(#5098) We should pass the Command Object and EndpointId to the cluster callbacks.
emberAfDoorLockClusterSetYeardayScheduleResponseCallback(apCommandObj, status);
}
else
{
apCommandObj->AddStatusCode(nullptr, Protocols::SecureChannel::GeneralStatusCode::kBadRequest,
Protocols::SecureChannel::Id, Protocols::SecureChannel::kProtocolCodeGeneralFailure);
ChipLogProgress(
Zcl, "Failed to dispatch command, %d/%" PRIu32 " arguments parsed, TLVError=%" PRIu32 ", UnpackError=%" PRIu32,
1, validArgumentCount, TLVError, TLVUnpackError);
}
break;
}
case ZCL_UNLOCK_DOOR_RESPONSE_COMMAND_ID: {
// 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.
CHIP_ERROR TLVError = CHIP_NO_ERROR;
CHIP_ERROR TLVUnpackError = CHIP_NO_ERROR;
uint8_t status;
bool statusExists = false;
uint32_t validArgumentCount = 0;
while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR)
{
switch (TLV::TagNumFromTag(aDataTlv.GetTag()))
{
case 0:
if (statusExists)
{
ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
break;
}
TLVUnpackError = aDataTlv.Get(status);
if (CHIP_NO_ERROR == TLVUnpackError)
{
statusExists = true;
validArgumentCount++;
}
break;
default:
// Unsupported tag, ignore it.
ChipLogProgress(Zcl, "Unknown TLV tag during processing.");
break;
}
if (TLVUnpackError != CHIP_NO_ERROR)
{
ChipLogProgress(Zcl, "Failed to decode TLV data with tag %" PRIx32 ": %" PRId32,
TLV::TagNumFromTag(aDataTlv.GetTag()), 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;
}
else
{
ChipLogProgress(Zcl, "Failed to decode TLV data: %" PRId32, TLVError);
}
// TODO(#5590) We should encode a response of status code for invalid TLV.
if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 1 == validArgumentCount)
{
// TODO(#5098) We should pass the Command Object and EndpointId to the cluster callbacks.
emberAfDoorLockClusterUnlockDoorResponseCallback(apCommandObj, status);
}
else
{
apCommandObj->AddStatusCode(nullptr, Protocols::SecureChannel::GeneralStatusCode::kBadRequest,
Protocols::SecureChannel::Id, Protocols::SecureChannel::kProtocolCodeGeneralFailure);
ChipLogProgress(
Zcl, "Failed to dispatch command, %d/%" PRIu32 " arguments parsed, TLVError=%" PRIu32 ", UnpackError=%" PRIu32,
1, validArgumentCount, TLVError, TLVUnpackError);
}
break;
}
case ZCL_UNLOCK_WITH_TIMEOUT_RESPONSE_COMMAND_ID: {
// 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.
CHIP_ERROR TLVError = CHIP_NO_ERROR;
CHIP_ERROR TLVUnpackError = CHIP_NO_ERROR;
uint8_t status;
bool statusExists = false;
uint32_t validArgumentCount = 0;
while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR)
{
switch (TLV::TagNumFromTag(aDataTlv.GetTag()))
{
case 0:
if (statusExists)
{
ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
break;
}
TLVUnpackError = aDataTlv.Get(status);
if (CHIP_NO_ERROR == TLVUnpackError)
{
statusExists = true;
validArgumentCount++;
}
break;
default:
// Unsupported tag, ignore it.
ChipLogProgress(Zcl, "Unknown TLV tag during processing.");
break;
}
if (TLVUnpackError != CHIP_NO_ERROR)
{
ChipLogProgress(Zcl, "Failed to decode TLV data with tag %" PRIx32 ": %" PRId32,
TLV::TagNumFromTag(aDataTlv.GetTag()), 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;
}
else
{
ChipLogProgress(Zcl, "Failed to decode TLV data: %" PRId32, TLVError);
}
// TODO(#5590) We should encode a response of status code for invalid TLV.
if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 1 == validArgumentCount)
{
// TODO(#5098) We should pass the Command Object and EndpointId to the cluster callbacks.
emberAfDoorLockClusterUnlockWithTimeoutResponseCallback(apCommandObj, status);
}
else
{
apCommandObj->AddStatusCode(nullptr, Protocols::SecureChannel::GeneralStatusCode::kBadRequest,
Protocols::SecureChannel::Id, Protocols::SecureChannel::kProtocolCodeGeneralFailure);
ChipLogProgress(
Zcl, "Failed to dispatch command, %d/%" PRIu32 " arguments parsed, TLVError=%" PRIu32 ", UnpackError=%" PRIu32,
1, validArgumentCount, TLVError, TLVUnpackError);
}
break;
}
default: {
// Unrecognized command ID, error status will apply.
apCommandObj->AddStatusCode(nullptr, Protocols::SecureChannel::GeneralStatusCode::kNotFound,
Protocols::SecureChannel::Id, Protocols::SecureChannel::kProtocolCodeGeneralFailure);
ChipLogError(Zcl, "Unknown command %" PRIx16 " for cluster %" PRIx16, aCommandId, ZCL_DOOR_LOCK_CLUSTER_ID);
break;
}
}
}
}
} // namespace DoorLock
namespace GeneralCommissioning {
void DispatchClientCommand(app::Command * apCommandObj, CommandId aCommandId, EndpointId aEndpointId, TLV::TLVReader & aDataTlv)
{
{
switch (aCommandId)
{
case ZCL_ARM_FAIL_SAFE_RESPONSE_COMMAND_ID: {
// 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.
CHIP_ERROR TLVError = CHIP_NO_ERROR;
CHIP_ERROR TLVUnpackError = CHIP_NO_ERROR;
uint8_t errorCode;
bool errorCodeExists = false;
const uint8_t * debugText;
bool debugTextExists = false;
uint32_t validArgumentCount = 0;
while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR)
{
switch (TLV::TagNumFromTag(aDataTlv.GetTag()))
{
case 0:
if (errorCodeExists)
{
ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
break;
}
TLVUnpackError = aDataTlv.Get(errorCode);
if (CHIP_NO_ERROR == TLVUnpackError)
{
errorCodeExists = true;
validArgumentCount++;
}
break;
case 1:
if (debugTextExists)
{
ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
break;
}
// TODO(#5542): The cluster handlers should accept a ByteSpan for all string types.
TLVUnpackError = aDataTlv.GetDataPtr(debugText);
if (CHIP_NO_ERROR == TLVUnpackError)
{
debugTextExists = true;
validArgumentCount++;
}
break;
default:
// Unsupported tag, ignore it.
ChipLogProgress(Zcl, "Unknown TLV tag during processing.");
break;
}
if (TLVUnpackError != CHIP_NO_ERROR)
{
ChipLogProgress(Zcl, "Failed to decode TLV data with tag %" PRIx32 ": %" PRId32,
TLV::TagNumFromTag(aDataTlv.GetTag()), 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;
}
else
{
ChipLogProgress(Zcl, "Failed to decode TLV data: %" PRId32, TLVError);
}
// TODO(#5590) We should encode a response of status code for invalid TLV.
if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 2 == validArgumentCount)
{
// TODO(#5098) We should pass the Command Object and EndpointId to the cluster callbacks.
emberAfGeneralCommissioningClusterArmFailSafeResponseCallback(apCommandObj, errorCode,
const_cast<uint8_t *>(debugText));
}
else
{
apCommandObj->AddStatusCode(nullptr, Protocols::SecureChannel::GeneralStatusCode::kBadRequest,
Protocols::SecureChannel::Id, Protocols::SecureChannel::kProtocolCodeGeneralFailure);
ChipLogProgress(
Zcl, "Failed to dispatch command, %d/%" PRIu32 " arguments parsed, TLVError=%" PRIu32 ", UnpackError=%" PRIu32,
2, validArgumentCount, TLVError, TLVUnpackError);
}
break;
}
case ZCL_SET_REGULATORY_CONFIG_RESPONSE_COMMAND_ID: {
// 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.
CHIP_ERROR TLVError = CHIP_NO_ERROR;
CHIP_ERROR TLVUnpackError = CHIP_NO_ERROR;
uint8_t errorCode;
bool errorCodeExists = false;
const uint8_t * debugText;
bool debugTextExists = false;
uint32_t validArgumentCount = 0;
while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR)
{
switch (TLV::TagNumFromTag(aDataTlv.GetTag()))
{
case 0:
if (errorCodeExists)
{
ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
break;
}
TLVUnpackError = aDataTlv.Get(errorCode);
if (CHIP_NO_ERROR == TLVUnpackError)
{
errorCodeExists = true;
validArgumentCount++;
}
break;
case 1:
if (debugTextExists)
{
ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
break;
}
// TODO(#5542): The cluster handlers should accept a ByteSpan for all string types.
TLVUnpackError = aDataTlv.GetDataPtr(debugText);
if (CHIP_NO_ERROR == TLVUnpackError)
{
debugTextExists = true;
validArgumentCount++;
}
break;
default:
// Unsupported tag, ignore it.
ChipLogProgress(Zcl, "Unknown TLV tag during processing.");
break;
}
if (TLVUnpackError != CHIP_NO_ERROR)
{
ChipLogProgress(Zcl, "Failed to decode TLV data with tag %" PRIx32 ": %" PRId32,
TLV::TagNumFromTag(aDataTlv.GetTag()), 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;
}
else
{
ChipLogProgress(Zcl, "Failed to decode TLV data: %" PRId32, TLVError);
}
// TODO(#5590) We should encode a response of status code for invalid TLV.
if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 2 == validArgumentCount)
{
// TODO(#5098) We should pass the Command Object and EndpointId to the cluster callbacks.
emberAfGeneralCommissioningClusterSetRegulatoryConfigResponseCallback(apCommandObj, errorCode,
const_cast<uint8_t *>(debugText));
}
else
{
apCommandObj->AddStatusCode(nullptr, Protocols::SecureChannel::GeneralStatusCode::kBadRequest,
Protocols::SecureChannel::Id, Protocols::SecureChannel::kProtocolCodeGeneralFailure);
ChipLogProgress(
Zcl, "Failed to dispatch command, %d/%" PRIu32 " arguments parsed, TLVError=%" PRIu32 ", UnpackError=%" PRIu32,
2, validArgumentCount, TLVError, TLVUnpackError);
}
break;
}
default: {
// Unrecognized command ID, error status will apply.
apCommandObj->AddStatusCode(nullptr, Protocols::SecureChannel::GeneralStatusCode::kNotFound,
Protocols::SecureChannel::Id, Protocols::SecureChannel::kProtocolCodeGeneralFailure);
ChipLogError(Zcl, "Unknown command %" PRIx16 " for cluster %" PRIx16, aCommandId, ZCL_GENERAL_COMMISSIONING_CLUSTER_ID);
break;
}
}
}
}
} // namespace GeneralCommissioning
namespace Groups {
void DispatchClientCommand(app::Command * apCommandObj, CommandId aCommandId, EndpointId aEndpointId, TLV::TLVReader & aDataTlv)
{
{
switch (aCommandId)
{
case ZCL_ADD_GROUP_RESPONSE_COMMAND_ID: {
// 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.
CHIP_ERROR TLVError = CHIP_NO_ERROR;
CHIP_ERROR TLVUnpackError = CHIP_NO_ERROR;
uint8_t status;
bool statusExists = false;
uint16_t groupId;
bool groupIdExists = false;
uint32_t validArgumentCount = 0;
while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR)
{
switch (TLV::TagNumFromTag(aDataTlv.GetTag()))
{
case 0:
if (statusExists)
{
ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
break;
}
TLVUnpackError = aDataTlv.Get(status);
if (CHIP_NO_ERROR == TLVUnpackError)
{
statusExists = true;
validArgumentCount++;
}
break;
case 1:
if (groupIdExists)
{
ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
break;
}
TLVUnpackError = aDataTlv.Get(groupId);
if (CHIP_NO_ERROR == TLVUnpackError)
{
groupIdExists = true;
validArgumentCount++;
}
break;
default:
// Unsupported tag, ignore it.
ChipLogProgress(Zcl, "Unknown TLV tag during processing.");
break;
}
if (TLVUnpackError != CHIP_NO_ERROR)
{
ChipLogProgress(Zcl, "Failed to decode TLV data with tag %" PRIx32 ": %" PRId32,
TLV::TagNumFromTag(aDataTlv.GetTag()), 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;
}
else
{
ChipLogProgress(Zcl, "Failed to decode TLV data: %" PRId32, TLVError);
}
// TODO(#5590) We should encode a response of status code for invalid TLV.
if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 2 == validArgumentCount)
{
// TODO(#5098) We should pass the Command Object and EndpointId to the cluster callbacks.
emberAfGroupsClusterAddGroupResponseCallback(apCommandObj, status, groupId);
}
else
{
apCommandObj->AddStatusCode(nullptr, Protocols::SecureChannel::GeneralStatusCode::kBadRequest,
Protocols::SecureChannel::Id, Protocols::SecureChannel::kProtocolCodeGeneralFailure);
ChipLogProgress(
Zcl, "Failed to dispatch command, %d/%" PRIu32 " arguments parsed, TLVError=%" PRIu32 ", UnpackError=%" PRIu32,
2, validArgumentCount, TLVError, TLVUnpackError);
}
break;
}
case ZCL_GET_GROUP_MEMBERSHIP_RESPONSE_COMMAND_ID: {
// 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.
CHIP_ERROR TLVError = CHIP_NO_ERROR;
CHIP_ERROR TLVUnpackError = CHIP_NO_ERROR;
uint8_t capacity;
bool capacityExists = false;
uint8_t groupCount;
bool groupCountExists = false;
/* TYPE WARNING: array array defaults to */ uint8_t * groupList;
bool groupListExists = false;
uint32_t validArgumentCount = 0;
while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR)
{
switch (TLV::TagNumFromTag(aDataTlv.GetTag()))
{
case 0:
if (capacityExists)
{
ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
break;
}
TLVUnpackError = aDataTlv.Get(capacity);
if (CHIP_NO_ERROR == TLVUnpackError)
{
capacityExists = true;
validArgumentCount++;
}
break;
case 1:
if (groupCountExists)
{
ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
break;
}
TLVUnpackError = aDataTlv.Get(groupCount);
if (CHIP_NO_ERROR == TLVUnpackError)
{
groupCountExists = true;
validArgumentCount++;
}
break;
case 2:
if (groupListExists)
{
ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
break;
}
// Just for compatibility, we will add array type support in IM later.
TLVUnpackError = aDataTlv.GetDataPtr(const_cast<const uint8_t *&>(groupList));
if (CHIP_NO_ERROR == TLVUnpackError)
{
groupListExists = true;
validArgumentCount++;
}
break;
default:
// Unsupported tag, ignore it.
ChipLogProgress(Zcl, "Unknown TLV tag during processing.");
break;
}
if (TLVUnpackError != CHIP_NO_ERROR)
{
ChipLogProgress(Zcl, "Failed to decode TLV data with tag %" PRIx32 ": %" PRId32,
TLV::TagNumFromTag(aDataTlv.GetTag()), 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;
}
else
{
ChipLogProgress(Zcl, "Failed to decode TLV data: %" PRId32, TLVError);
}
// TODO(#5590) We should encode a response of status code for invalid TLV.
if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 3 == validArgumentCount)
{
// TODO(#5098) We should pass the Command Object and EndpointId to the cluster callbacks.
emberAfGroupsClusterGetGroupMembershipResponseCallback(apCommandObj, capacity, groupCount, groupList);
}
else
{
apCommandObj->AddStatusCode(nullptr, Protocols::SecureChannel::GeneralStatusCode::kBadRequest,
Protocols::SecureChannel::Id, Protocols::SecureChannel::kProtocolCodeGeneralFailure);
ChipLogProgress(
Zcl, "Failed to dispatch command, %d/%" PRIu32 " arguments parsed, TLVError=%" PRIu32 ", UnpackError=%" PRIu32,
3, validArgumentCount, TLVError, TLVUnpackError);
}
break;
}
case ZCL_REMOVE_GROUP_RESPONSE_COMMAND_ID: {
// 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.
CHIP_ERROR TLVError = CHIP_NO_ERROR;
CHIP_ERROR TLVUnpackError = CHIP_NO_ERROR;
uint8_t status;
bool statusExists = false;
uint16_t groupId;
bool groupIdExists = false;
uint32_t validArgumentCount = 0;
while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR)
{
switch (TLV::TagNumFromTag(aDataTlv.GetTag()))
{
case 0:
if (statusExists)
{
ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
break;
}
TLVUnpackError = aDataTlv.Get(status);
if (CHIP_NO_ERROR == TLVUnpackError)
{
statusExists = true;
validArgumentCount++;
}
break;
case 1:
if (groupIdExists)
{
ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
break;
}
TLVUnpackError = aDataTlv.Get(groupId);
if (CHIP_NO_ERROR == TLVUnpackError)
{
groupIdExists = true;
validArgumentCount++;
}
break;
default:
// Unsupported tag, ignore it.
ChipLogProgress(Zcl, "Unknown TLV tag during processing.");
break;
}
if (TLVUnpackError != CHIP_NO_ERROR)
{
ChipLogProgress(Zcl, "Failed to decode TLV data with tag %" PRIx32 ": %" PRId32,
TLV::TagNumFromTag(aDataTlv.GetTag()), 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;
}
else
{
ChipLogProgress(Zcl, "Failed to decode TLV data: %" PRId32, TLVError);
}
// TODO(#5590) We should encode a response of status code for invalid TLV.
if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 2 == validArgumentCount)
{
// TODO(#5098) We should pass the Command Object and EndpointId to the cluster callbacks.
emberAfGroupsClusterRemoveGroupResponseCallback(apCommandObj, status, groupId);
}
else
{
apCommandObj->AddStatusCode(nullptr, Protocols::SecureChannel::GeneralStatusCode::kBadRequest,
Protocols::SecureChannel::Id, Protocols::SecureChannel::kProtocolCodeGeneralFailure);
ChipLogProgress(
Zcl, "Failed to dispatch command, %d/%" PRIu32 " arguments parsed, TLVError=%" PRIu32 ", UnpackError=%" PRIu32,
2, validArgumentCount, TLVError, TLVUnpackError);
}
break;
}
case ZCL_VIEW_GROUP_RESPONSE_COMMAND_ID: {
// 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.
CHIP_ERROR TLVError = CHIP_NO_ERROR;
CHIP_ERROR TLVUnpackError = CHIP_NO_ERROR;
uint8_t status;
bool statusExists = false;
uint16_t groupId;
bool groupIdExists = false;
const uint8_t * groupName;
bool groupNameExists = false;
uint32_t validArgumentCount = 0;
while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR)
{
switch (TLV::TagNumFromTag(aDataTlv.GetTag()))
{
case 0:
if (statusExists)
{
ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
break;
}
TLVUnpackError = aDataTlv.Get(status);
if (CHIP_NO_ERROR == TLVUnpackError)
{
statusExists = true;
validArgumentCount++;
}
break;
case 1:
if (groupIdExists)
{
ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
break;
}
TLVUnpackError = aDataTlv.Get(groupId);
if (CHIP_NO_ERROR == TLVUnpackError)
{
groupIdExists = true;
validArgumentCount++;
}
break;
case 2:
if (groupNameExists)
{
ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
break;
}
// TODO(#5542): The cluster handlers should accept a ByteSpan for all string types.
TLVUnpackError = aDataTlv.GetDataPtr(groupName);
if (CHIP_NO_ERROR == TLVUnpackError)
{
groupNameExists = true;
validArgumentCount++;
}
break;
default:
// Unsupported tag, ignore it.
ChipLogProgress(Zcl, "Unknown TLV tag during processing.");
break;
}
if (TLVUnpackError != CHIP_NO_ERROR)
{
ChipLogProgress(Zcl, "Failed to decode TLV data with tag %" PRIx32 ": %" PRId32,
TLV::TagNumFromTag(aDataTlv.GetTag()), 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;
}
else
{
ChipLogProgress(Zcl, "Failed to decode TLV data: %" PRId32, TLVError);
}
// TODO(#5590) We should encode a response of status code for invalid TLV.
if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 3 == validArgumentCount)
{
// TODO(#5098) We should pass the Command Object and EndpointId to the cluster callbacks.
emberAfGroupsClusterViewGroupResponseCallback(apCommandObj, status, groupId, const_cast<uint8_t *>(groupName));
}
else
{
apCommandObj->AddStatusCode(nullptr, Protocols::SecureChannel::GeneralStatusCode::kBadRequest,
Protocols::SecureChannel::Id, Protocols::SecureChannel::kProtocolCodeGeneralFailure);
ChipLogProgress(
Zcl, "Failed to dispatch command, %d/%" PRIu32 " arguments parsed, TLVError=%" PRIu32 ", UnpackError=%" PRIu32,
3, validArgumentCount, TLVError, TLVUnpackError);
}
break;
}
default: {
// Unrecognized command ID, error status will apply.
apCommandObj->AddStatusCode(nullptr, Protocols::SecureChannel::GeneralStatusCode::kNotFound,
Protocols::SecureChannel::Id, Protocols::SecureChannel::kProtocolCodeGeneralFailure);
ChipLogError(Zcl, "Unknown command %" PRIx16 " for cluster %" PRIx16, aCommandId, ZCL_GROUPS_CLUSTER_ID);
break;
}
}
}
}
} // namespace Groups
namespace Identify {
void DispatchClientCommand(app::Command * apCommandObj, CommandId aCommandId, EndpointId aEndpointId, TLV::TLVReader & aDataTlv)
{
{
switch (aCommandId)
{
case ZCL_IDENTIFY_QUERY_RESPONSE_COMMAND_ID: {
// 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.
CHIP_ERROR TLVError = CHIP_NO_ERROR;
CHIP_ERROR TLVUnpackError = CHIP_NO_ERROR;
uint16_t timeout;
bool timeoutExists = false;
uint32_t validArgumentCount = 0;
while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR)
{
switch (TLV::TagNumFromTag(aDataTlv.GetTag()))
{
case 0:
if (timeoutExists)
{
ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
break;
}
TLVUnpackError = aDataTlv.Get(timeout);
if (CHIP_NO_ERROR == TLVUnpackError)
{
timeoutExists = true;
validArgumentCount++;
}
break;
default:
// Unsupported tag, ignore it.
ChipLogProgress(Zcl, "Unknown TLV tag during processing.");
break;
}
if (TLVUnpackError != CHIP_NO_ERROR)
{
ChipLogProgress(Zcl, "Failed to decode TLV data with tag %" PRIx32 ": %" PRId32,
TLV::TagNumFromTag(aDataTlv.GetTag()), 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;
}
else
{
ChipLogProgress(Zcl, "Failed to decode TLV data: %" PRId32, TLVError);
}
// TODO(#5590) We should encode a response of status code for invalid TLV.
if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 1 == validArgumentCount)
{
// TODO(#5098) We should pass the Command Object and EndpointId to the cluster callbacks.
emberAfIdentifyClusterIdentifyQueryResponseCallback(apCommandObj, timeout);
}
else
{
apCommandObj->AddStatusCode(nullptr, Protocols::SecureChannel::GeneralStatusCode::kBadRequest,
Protocols::SecureChannel::Id, Protocols::SecureChannel::kProtocolCodeGeneralFailure);
ChipLogProgress(
Zcl, "Failed to dispatch command, %d/%" PRIu32 " arguments parsed, TLVError=%" PRIu32 ", UnpackError=%" PRIu32,
1, validArgumentCount, TLVError, TLVUnpackError);
}
break;
}
default: {
// Unrecognized command ID, error status will apply.
apCommandObj->AddStatusCode(nullptr, Protocols::SecureChannel::GeneralStatusCode::kNotFound,
Protocols::SecureChannel::Id, Protocols::SecureChannel::kProtocolCodeGeneralFailure);
ChipLogError(Zcl, "Unknown command %" PRIx16 " for cluster %" PRIx16, aCommandId, ZCL_IDENTIFY_CLUSTER_ID);
break;
}
}
}
}
} // namespace Identify
namespace NetworkCommissioning {
void DispatchClientCommand(app::Command * apCommandObj, CommandId aCommandId, EndpointId aEndpointId, TLV::TLVReader & aDataTlv)
{
{
switch (aCommandId)
{
case ZCL_ADD_THREAD_NETWORK_RESPONSE_COMMAND_ID: {
// 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.
CHIP_ERROR TLVError = CHIP_NO_ERROR;
CHIP_ERROR TLVUnpackError = CHIP_NO_ERROR;
uint8_t errorCode;
bool errorCodeExists = false;
const uint8_t * debugText;
bool debugTextExists = false;
uint32_t validArgumentCount = 0;
while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR)
{
switch (TLV::TagNumFromTag(aDataTlv.GetTag()))
{
case 0:
if (errorCodeExists)
{
ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
break;
}
TLVUnpackError = aDataTlv.Get(errorCode);
if (CHIP_NO_ERROR == TLVUnpackError)
{
errorCodeExists = true;
validArgumentCount++;
}
break;
case 1:
if (debugTextExists)
{
ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
break;
}
// TODO(#5542): The cluster handlers should accept a ByteSpan for all string types.
TLVUnpackError = aDataTlv.GetDataPtr(debugText);
if (CHIP_NO_ERROR == TLVUnpackError)
{
debugTextExists = true;
validArgumentCount++;
}
break;
default:
// Unsupported tag, ignore it.
ChipLogProgress(Zcl, "Unknown TLV tag during processing.");
break;
}
if (TLVUnpackError != CHIP_NO_ERROR)
{
ChipLogProgress(Zcl, "Failed to decode TLV data with tag %" PRIx32 ": %" PRId32,
TLV::TagNumFromTag(aDataTlv.GetTag()), 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;
}
else
{
ChipLogProgress(Zcl, "Failed to decode TLV data: %" PRId32, TLVError);
}
// TODO(#5590) We should encode a response of status code for invalid TLV.
if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 2 == validArgumentCount)
{
// TODO(#5098) We should pass the Command Object and EndpointId to the cluster callbacks.
emberAfNetworkCommissioningClusterAddThreadNetworkResponseCallback(apCommandObj, errorCode,
const_cast<uint8_t *>(debugText));
}
else
{
apCommandObj->AddStatusCode(nullptr, Protocols::SecureChannel::GeneralStatusCode::kBadRequest,
Protocols::SecureChannel::Id, Protocols::SecureChannel::kProtocolCodeGeneralFailure);
ChipLogProgress(
Zcl, "Failed to dispatch command, %d/%" PRIu32 " arguments parsed, TLVError=%" PRIu32 ", UnpackError=%" PRIu32,
2, validArgumentCount, TLVError, TLVUnpackError);
}
break;
}
case ZCL_ADD_WI_FI_NETWORK_RESPONSE_COMMAND_ID: {
// 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.
CHIP_ERROR TLVError = CHIP_NO_ERROR;
CHIP_ERROR TLVUnpackError = CHIP_NO_ERROR;
uint8_t errorCode;
bool errorCodeExists = false;
const uint8_t * debugText;
bool debugTextExists = false;
uint32_t validArgumentCount = 0;
while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR)
{
switch (TLV::TagNumFromTag(aDataTlv.GetTag()))
{
case 0:
if (errorCodeExists)
{
ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
break;
}
TLVUnpackError = aDataTlv.Get(errorCode);
if (CHIP_NO_ERROR == TLVUnpackError)
{
errorCodeExists = true;
validArgumentCount++;
}
break;
case 1:
if (debugTextExists)
{
ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
break;
}
// TODO(#5542): The cluster handlers should accept a ByteSpan for all string types.
TLVUnpackError = aDataTlv.GetDataPtr(debugText);
if (CHIP_NO_ERROR == TLVUnpackError)
{
debugTextExists = true;
validArgumentCount++;
}
break;
default:
// Unsupported tag, ignore it.
ChipLogProgress(Zcl, "Unknown TLV tag during processing.");
break;
}
if (TLVUnpackError != CHIP_NO_ERROR)
{
ChipLogProgress(Zcl, "Failed to decode TLV data with tag %" PRIx32 ": %" PRId32,
TLV::TagNumFromTag(aDataTlv.GetTag()), 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;
}
else
{
ChipLogProgress(Zcl, "Failed to decode TLV data: %" PRId32, TLVError);
}
// TODO(#5590) We should encode a response of status code for invalid TLV.
if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 2 == validArgumentCount)
{
// TODO(#5098) We should pass the Command Object and EndpointId to the cluster callbacks.
emberAfNetworkCommissioningClusterAddWiFiNetworkResponseCallback(apCommandObj, errorCode,
const_cast<uint8_t *>(debugText));
}
else
{
apCommandObj->AddStatusCode(nullptr, Protocols::SecureChannel::GeneralStatusCode::kBadRequest,
Protocols::SecureChannel::Id, Protocols::SecureChannel::kProtocolCodeGeneralFailure);
ChipLogProgress(
Zcl, "Failed to dispatch command, %d/%" PRIu32 " arguments parsed, TLVError=%" PRIu32 ", UnpackError=%" PRIu32,
2, validArgumentCount, TLVError, TLVUnpackError);
}
break;
}
case ZCL_DISABLE_NETWORK_RESPONSE_COMMAND_ID: {
// 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.
CHIP_ERROR TLVError = CHIP_NO_ERROR;
CHIP_ERROR TLVUnpackError = CHIP_NO_ERROR;
uint8_t errorCode;
bool errorCodeExists = false;
const uint8_t * debugText;
bool debugTextExists = false;
uint32_t validArgumentCount = 0;
while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR)
{
switch (TLV::TagNumFromTag(aDataTlv.GetTag()))
{
case 0:
if (errorCodeExists)
{
ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
break;
}
TLVUnpackError = aDataTlv.Get(errorCode);
if (CHIP_NO_ERROR == TLVUnpackError)
{
errorCodeExists = true;
validArgumentCount++;
}
break;
case 1:
if (debugTextExists)
{
ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
break;
}
// TODO(#5542): The cluster handlers should accept a ByteSpan for all string types.
TLVUnpackError = aDataTlv.GetDataPtr(debugText);
if (CHIP_NO_ERROR == TLVUnpackError)
{
debugTextExists = true;
validArgumentCount++;
}
break;
default:
// Unsupported tag, ignore it.
ChipLogProgress(Zcl, "Unknown TLV tag during processing.");
break;
}
if (TLVUnpackError != CHIP_NO_ERROR)
{
ChipLogProgress(Zcl, "Failed to decode TLV data with tag %" PRIx32 ": %" PRId32,
TLV::TagNumFromTag(aDataTlv.GetTag()), 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;
}
else
{
ChipLogProgress(Zcl, "Failed to decode TLV data: %" PRId32, TLVError);
}
// TODO(#5590) We should encode a response of status code for invalid TLV.
if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 2 == validArgumentCount)
{
// TODO(#5098) We should pass the Command Object and EndpointId to the cluster callbacks.
emberAfNetworkCommissioningClusterDisableNetworkResponseCallback(apCommandObj, errorCode,
const_cast<uint8_t *>(debugText));
}
else
{
apCommandObj->AddStatusCode(nullptr, Protocols::SecureChannel::GeneralStatusCode::kBadRequest,
Protocols::SecureChannel::Id, Protocols::SecureChannel::kProtocolCodeGeneralFailure);
ChipLogProgress(
Zcl, "Failed to dispatch command, %d/%" PRIu32 " arguments parsed, TLVError=%" PRIu32 ", UnpackError=%" PRIu32,
2, validArgumentCount, TLVError, TLVUnpackError);
}
break;
}
case ZCL_ENABLE_NETWORK_RESPONSE_COMMAND_ID: {
// 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.
CHIP_ERROR TLVError = CHIP_NO_ERROR;
CHIP_ERROR TLVUnpackError = CHIP_NO_ERROR;
uint8_t errorCode;
bool errorCodeExists = false;
const uint8_t * debugText;
bool debugTextExists = false;
uint32_t validArgumentCount = 0;
while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR)
{
switch (TLV::TagNumFromTag(aDataTlv.GetTag()))
{
case 0:
if (errorCodeExists)
{
ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
break;
}
TLVUnpackError = aDataTlv.Get(errorCode);
if (CHIP_NO_ERROR == TLVUnpackError)
{
errorCodeExists = true;
validArgumentCount++;
}
break;
case 1:
if (debugTextExists)
{
ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
break;
}
// TODO(#5542): The cluster handlers should accept a ByteSpan for all string types.
TLVUnpackError = aDataTlv.GetDataPtr(debugText);
if (CHIP_NO_ERROR == TLVUnpackError)
{
debugTextExists = true;
validArgumentCount++;
}
break;
default:
// Unsupported tag, ignore it.
ChipLogProgress(Zcl, "Unknown TLV tag during processing.");
break;
}
if (TLVUnpackError != CHIP_NO_ERROR)
{
ChipLogProgress(Zcl, "Failed to decode TLV data with tag %" PRIx32 ": %" PRId32,
TLV::TagNumFromTag(aDataTlv.GetTag()), 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;
}
else
{
ChipLogProgress(Zcl, "Failed to decode TLV data: %" PRId32, TLVError);
}
// TODO(#5590) We should encode a response of status code for invalid TLV.
if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 2 == validArgumentCount)
{
// TODO(#5098) We should pass the Command Object and EndpointId to the cluster callbacks.
emberAfNetworkCommissioningClusterEnableNetworkResponseCallback(apCommandObj, errorCode,
const_cast<uint8_t *>(debugText));
}
else
{
apCommandObj->AddStatusCode(nullptr, Protocols::SecureChannel::GeneralStatusCode::kBadRequest,
Protocols::SecureChannel::Id, Protocols::SecureChannel::kProtocolCodeGeneralFailure);
ChipLogProgress(
Zcl, "Failed to dispatch command, %d/%" PRIu32 " arguments parsed, TLVError=%" PRIu32 ", UnpackError=%" PRIu32,
2, validArgumentCount, TLVError, TLVUnpackError);
}
break;
}
case ZCL_REMOVE_NETWORK_RESPONSE_COMMAND_ID: {
// 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.
CHIP_ERROR TLVError = CHIP_NO_ERROR;
CHIP_ERROR TLVUnpackError = CHIP_NO_ERROR;
uint8_t errorCode;
bool errorCodeExists = false;
const uint8_t * debugText;
bool debugTextExists = false;
uint32_t validArgumentCount = 0;
while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR)
{
switch (TLV::TagNumFromTag(aDataTlv.GetTag()))
{
case 0:
if (errorCodeExists)
{
ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
break;
}
TLVUnpackError = aDataTlv.Get(errorCode);
if (CHIP_NO_ERROR == TLVUnpackError)
{
errorCodeExists = true;
validArgumentCount++;
}
break;
case 1:
if (debugTextExists)
{
ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
break;
}
// TODO(#5542): The cluster handlers should accept a ByteSpan for all string types.
TLVUnpackError = aDataTlv.GetDataPtr(debugText);
if (CHIP_NO_ERROR == TLVUnpackError)
{
debugTextExists = true;
validArgumentCount++;
}
break;
default:
// Unsupported tag, ignore it.
ChipLogProgress(Zcl, "Unknown TLV tag during processing.");
break;
}
if (TLVUnpackError != CHIP_NO_ERROR)
{
ChipLogProgress(Zcl, "Failed to decode TLV data with tag %" PRIx32 ": %" PRId32,
TLV::TagNumFromTag(aDataTlv.GetTag()), 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;
}
else
{
ChipLogProgress(Zcl, "Failed to decode TLV data: %" PRId32, TLVError);
}
// TODO(#5590) We should encode a response of status code for invalid TLV.
if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 2 == validArgumentCount)
{
// TODO(#5098) We should pass the Command Object and EndpointId to the cluster callbacks.
emberAfNetworkCommissioningClusterRemoveNetworkResponseCallback(apCommandObj, errorCode,
const_cast<uint8_t *>(debugText));
}
else
{
apCommandObj->AddStatusCode(nullptr, Protocols::SecureChannel::GeneralStatusCode::kBadRequest,
Protocols::SecureChannel::Id, Protocols::SecureChannel::kProtocolCodeGeneralFailure);
ChipLogProgress(
Zcl, "Failed to dispatch command, %d/%" PRIu32 " arguments parsed, TLVError=%" PRIu32 ", UnpackError=%" PRIu32,
2, validArgumentCount, TLVError, TLVUnpackError);
}
break;
}
case ZCL_SCAN_NETWORKS_RESPONSE_COMMAND_ID: {
// 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.
CHIP_ERROR TLVError = CHIP_NO_ERROR;
CHIP_ERROR TLVUnpackError = CHIP_NO_ERROR;
uint8_t errorCode;
bool errorCodeExists = false;
const uint8_t * debugText;
bool debugTextExists = false;
/* TYPE WARNING: array array defaults to */ uint8_t * wifiScanResults;
bool wifiScanResultsExists = false;
/* TYPE WARNING: array array defaults to */ uint8_t * threadScanResults;
bool threadScanResultsExists = false;
uint32_t validArgumentCount = 0;
while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR)
{
switch (TLV::TagNumFromTag(aDataTlv.GetTag()))
{
case 0:
if (errorCodeExists)
{
ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
break;
}
TLVUnpackError = aDataTlv.Get(errorCode);
if (CHIP_NO_ERROR == TLVUnpackError)
{
errorCodeExists = true;
validArgumentCount++;
}
break;
case 1:
if (debugTextExists)
{
ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
break;
}
// TODO(#5542): The cluster handlers should accept a ByteSpan for all string types.
TLVUnpackError = aDataTlv.GetDataPtr(debugText);
if (CHIP_NO_ERROR == TLVUnpackError)
{
debugTextExists = true;
validArgumentCount++;
}
break;
case 2:
if (wifiScanResultsExists)
{
ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
break;
}
// Just for compatibility, we will add array type support in IM later.
TLVUnpackError = aDataTlv.GetDataPtr(const_cast<const uint8_t *&>(wifiScanResults));
if (CHIP_NO_ERROR == TLVUnpackError)
{
wifiScanResultsExists = true;
validArgumentCount++;
}
break;
case 3:
if (threadScanResultsExists)
{
ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
break;
}
// Just for compatibility, we will add array type support in IM later.
TLVUnpackError = aDataTlv.GetDataPtr(const_cast<const uint8_t *&>(threadScanResults));
if (CHIP_NO_ERROR == TLVUnpackError)
{
threadScanResultsExists = true;
validArgumentCount++;
}
break;
default:
// Unsupported tag, ignore it.
ChipLogProgress(Zcl, "Unknown TLV tag during processing.");
break;
}
if (TLVUnpackError != CHIP_NO_ERROR)
{
ChipLogProgress(Zcl, "Failed to decode TLV data with tag %" PRIx32 ": %" PRId32,
TLV::TagNumFromTag(aDataTlv.GetTag()), 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;
}
else
{
ChipLogProgress(Zcl, "Failed to decode TLV data: %" PRId32, TLVError);
}
// TODO(#5590) We should encode a response of status code for invalid TLV.
if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 4 == validArgumentCount)
{
// TODO(#5098) We should pass the Command Object and EndpointId to the cluster callbacks.
emberAfNetworkCommissioningClusterScanNetworksResponseCallback(
apCommandObj, errorCode, const_cast<uint8_t *>(debugText), wifiScanResults, threadScanResults);
}
else
{
apCommandObj->AddStatusCode(nullptr, Protocols::SecureChannel::GeneralStatusCode::kBadRequest,
Protocols::SecureChannel::Id, Protocols::SecureChannel::kProtocolCodeGeneralFailure);
ChipLogProgress(
Zcl, "Failed to dispatch command, %d/%" PRIu32 " arguments parsed, TLVError=%" PRIu32 ", UnpackError=%" PRIu32,
4, validArgumentCount, TLVError, TLVUnpackError);
}
break;
}
case ZCL_UPDATE_THREAD_NETWORK_RESPONSE_COMMAND_ID: {
// 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.
CHIP_ERROR TLVError = CHIP_NO_ERROR;
CHIP_ERROR TLVUnpackError = CHIP_NO_ERROR;
uint8_t errorCode;
bool errorCodeExists = false;
const uint8_t * debugText;
bool debugTextExists = false;
uint32_t validArgumentCount = 0;
while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR)
{
switch (TLV::TagNumFromTag(aDataTlv.GetTag()))
{
case 0:
if (errorCodeExists)
{
ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
break;
}
TLVUnpackError = aDataTlv.Get(errorCode);
if (CHIP_NO_ERROR == TLVUnpackError)
{
errorCodeExists = true;
validArgumentCount++;
}
break;
case 1:
if (debugTextExists)
{
ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
break;
}
// TODO(#5542): The cluster handlers should accept a ByteSpan for all string types.
TLVUnpackError = aDataTlv.GetDataPtr(debugText);
if (CHIP_NO_ERROR == TLVUnpackError)
{
debugTextExists = true;
validArgumentCount++;
}
break;
default:
// Unsupported tag, ignore it.
ChipLogProgress(Zcl, "Unknown TLV tag during processing.");
break;
}
if (TLVUnpackError != CHIP_NO_ERROR)
{
ChipLogProgress(Zcl, "Failed to decode TLV data with tag %" PRIx32 ": %" PRId32,
TLV::TagNumFromTag(aDataTlv.GetTag()), 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;
}
else
{
ChipLogProgress(Zcl, "Failed to decode TLV data: %" PRId32, TLVError);
}
// TODO(#5590) We should encode a response of status code for invalid TLV.
if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 2 == validArgumentCount)
{
// TODO(#5098) We should pass the Command Object and EndpointId to the cluster callbacks.
emberAfNetworkCommissioningClusterUpdateThreadNetworkResponseCallback(apCommandObj, errorCode,
const_cast<uint8_t *>(debugText));
}
else
{
apCommandObj->AddStatusCode(nullptr, Protocols::SecureChannel::GeneralStatusCode::kBadRequest,
Protocols::SecureChannel::Id, Protocols::SecureChannel::kProtocolCodeGeneralFailure);
ChipLogProgress(
Zcl, "Failed to dispatch command, %d/%" PRIu32 " arguments parsed, TLVError=%" PRIu32 ", UnpackError=%" PRIu32,
2, validArgumentCount, TLVError, TLVUnpackError);
}
break;
}
case ZCL_UPDATE_WI_FI_NETWORK_RESPONSE_COMMAND_ID: {
// 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.
CHIP_ERROR TLVError = CHIP_NO_ERROR;
CHIP_ERROR TLVUnpackError = CHIP_NO_ERROR;
uint8_t errorCode;
bool errorCodeExists = false;
const uint8_t * debugText;
bool debugTextExists = false;
uint32_t validArgumentCount = 0;
while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR)
{
switch (TLV::TagNumFromTag(aDataTlv.GetTag()))
{
case 0:
if (errorCodeExists)
{
ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
break;
}
TLVUnpackError = aDataTlv.Get(errorCode);
if (CHIP_NO_ERROR == TLVUnpackError)
{
errorCodeExists = true;
validArgumentCount++;
}
break;
case 1:
if (debugTextExists)
{
ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
break;
}
// TODO(#5542): The cluster handlers should accept a ByteSpan for all string types.
TLVUnpackError = aDataTlv.GetDataPtr(debugText);
if (CHIP_NO_ERROR == TLVUnpackError)
{
debugTextExists = true;
validArgumentCount++;
}
break;
default:
// Unsupported tag, ignore it.
ChipLogProgress(Zcl, "Unknown TLV tag during processing.");
break;
}
if (TLVUnpackError != CHIP_NO_ERROR)
{
ChipLogProgress(Zcl, "Failed to decode TLV data with tag %" PRIx32 ": %" PRId32,
TLV::TagNumFromTag(aDataTlv.GetTag()), 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;
}
else
{
ChipLogProgress(Zcl, "Failed to decode TLV data: %" PRId32, TLVError);
}
// TODO(#5590) We should encode a response of status code for invalid TLV.
if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 2 == validArgumentCount)
{
// TODO(#5098) We should pass the Command Object and EndpointId to the cluster callbacks.
emberAfNetworkCommissioningClusterUpdateWiFiNetworkResponseCallback(apCommandObj, errorCode,
const_cast<uint8_t *>(debugText));
}
else
{
apCommandObj->AddStatusCode(nullptr, Protocols::SecureChannel::GeneralStatusCode::kBadRequest,
Protocols::SecureChannel::Id, Protocols::SecureChannel::kProtocolCodeGeneralFailure);
ChipLogProgress(
Zcl, "Failed to dispatch command, %d/%" PRIu32 " arguments parsed, TLVError=%" PRIu32 ", UnpackError=%" PRIu32,
2, validArgumentCount, TLVError, TLVUnpackError);
}
break;
}
default: {
// Unrecognized command ID, error status will apply.
apCommandObj->AddStatusCode(nullptr, Protocols::SecureChannel::GeneralStatusCode::kNotFound,
Protocols::SecureChannel::Id, Protocols::SecureChannel::kProtocolCodeGeneralFailure);
ChipLogError(Zcl, "Unknown command %" PRIx16 " for cluster %" PRIx16, aCommandId, ZCL_NETWORK_COMMISSIONING_CLUSTER_ID);
break;
}
}
}
}
} // namespace NetworkCommissioning
namespace Scenes {
void DispatchClientCommand(app::Command * apCommandObj, CommandId aCommandId, EndpointId aEndpointId, TLV::TLVReader & aDataTlv)
{
{
switch (aCommandId)
{
case ZCL_ADD_SCENE_RESPONSE_COMMAND_ID: {
// 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.
CHIP_ERROR TLVError = CHIP_NO_ERROR;
CHIP_ERROR TLVUnpackError = CHIP_NO_ERROR;
uint8_t status;
bool statusExists = false;
uint16_t groupId;
bool groupIdExists = false;
uint8_t sceneId;
bool sceneIdExists = false;
uint32_t validArgumentCount = 0;
while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR)
{
switch (TLV::TagNumFromTag(aDataTlv.GetTag()))
{
case 0:
if (statusExists)
{
ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
break;
}
TLVUnpackError = aDataTlv.Get(status);
if (CHIP_NO_ERROR == TLVUnpackError)
{
statusExists = true;
validArgumentCount++;
}
break;
case 1:
if (groupIdExists)
{
ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
break;
}
TLVUnpackError = aDataTlv.Get(groupId);
if (CHIP_NO_ERROR == TLVUnpackError)
{
groupIdExists = true;
validArgumentCount++;
}
break;
case 2:
if (sceneIdExists)
{
ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
break;
}
TLVUnpackError = aDataTlv.Get(sceneId);
if (CHIP_NO_ERROR == TLVUnpackError)
{
sceneIdExists = true;
validArgumentCount++;
}
break;
default:
// Unsupported tag, ignore it.
ChipLogProgress(Zcl, "Unknown TLV tag during processing.");
break;
}
if (TLVUnpackError != CHIP_NO_ERROR)
{
ChipLogProgress(Zcl, "Failed to decode TLV data with tag %" PRIx32 ": %" PRId32,
TLV::TagNumFromTag(aDataTlv.GetTag()), 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;
}
else
{
ChipLogProgress(Zcl, "Failed to decode TLV data: %" PRId32, TLVError);
}
// TODO(#5590) We should encode a response of status code for invalid TLV.
if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 3 == validArgumentCount)
{
// TODO(#5098) We should pass the Command Object and EndpointId to the cluster callbacks.
emberAfScenesClusterAddSceneResponseCallback(apCommandObj, status, groupId, sceneId);
}
else
{
apCommandObj->AddStatusCode(nullptr, Protocols::SecureChannel::GeneralStatusCode::kBadRequest,
Protocols::SecureChannel::Id, Protocols::SecureChannel::kProtocolCodeGeneralFailure);
ChipLogProgress(
Zcl, "Failed to dispatch command, %d/%" PRIu32 " arguments parsed, TLVError=%" PRIu32 ", UnpackError=%" PRIu32,
3, validArgumentCount, TLVError, TLVUnpackError);
}
break;
}
case ZCL_GET_SCENE_MEMBERSHIP_RESPONSE_COMMAND_ID: {
// 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.
CHIP_ERROR TLVError = CHIP_NO_ERROR;
CHIP_ERROR TLVUnpackError = CHIP_NO_ERROR;
uint8_t status;
bool statusExists = false;
uint8_t capacity;
bool capacityExists = false;
uint16_t groupId;
bool groupIdExists = false;
uint8_t sceneCount;
bool sceneCountExists = false;
/* TYPE WARNING: array array defaults to */ uint8_t * sceneList;
bool sceneListExists = false;
uint32_t validArgumentCount = 0;
while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR)
{
switch (TLV::TagNumFromTag(aDataTlv.GetTag()))
{
case 0:
if (statusExists)
{
ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
break;
}
TLVUnpackError = aDataTlv.Get(status);
if (CHIP_NO_ERROR == TLVUnpackError)
{
statusExists = true;
validArgumentCount++;
}
break;
case 1:
if (capacityExists)
{
ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
break;
}
TLVUnpackError = aDataTlv.Get(capacity);
if (CHIP_NO_ERROR == TLVUnpackError)
{
capacityExists = true;
validArgumentCount++;
}
break;
case 2:
if (groupIdExists)
{
ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
break;
}
TLVUnpackError = aDataTlv.Get(groupId);
if (CHIP_NO_ERROR == TLVUnpackError)
{
groupIdExists = true;
validArgumentCount++;
}
break;
case 3:
if (sceneCountExists)
{
ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
break;
}
TLVUnpackError = aDataTlv.Get(sceneCount);
if (CHIP_NO_ERROR == TLVUnpackError)
{
sceneCountExists = true;
validArgumentCount++;
}
break;
case 4:
if (sceneListExists)
{
ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
break;
}
// Just for compatibility, we will add array type support in IM later.
TLVUnpackError = aDataTlv.GetDataPtr(const_cast<const uint8_t *&>(sceneList));
if (CHIP_NO_ERROR == TLVUnpackError)
{
sceneListExists = true;
validArgumentCount++;
}
break;
default:
// Unsupported tag, ignore it.
ChipLogProgress(Zcl, "Unknown TLV tag during processing.");
break;
}
if (TLVUnpackError != CHIP_NO_ERROR)
{
ChipLogProgress(Zcl, "Failed to decode TLV data with tag %" PRIx32 ": %" PRId32,
TLV::TagNumFromTag(aDataTlv.GetTag()), 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;
}
else
{
ChipLogProgress(Zcl, "Failed to decode TLV data: %" PRId32, TLVError);
}
// TODO(#5590) We should encode a response of status code for invalid TLV.
if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 5 == validArgumentCount)
{
// TODO(#5098) We should pass the Command Object and EndpointId to the cluster callbacks.
emberAfScenesClusterGetSceneMembershipResponseCallback(apCommandObj, status, capacity, groupId, sceneCount,
sceneList);
}
else
{
apCommandObj->AddStatusCode(nullptr, Protocols::SecureChannel::GeneralStatusCode::kBadRequest,
Protocols::SecureChannel::Id, Protocols::SecureChannel::kProtocolCodeGeneralFailure);
ChipLogProgress(
Zcl, "Failed to dispatch command, %d/%" PRIu32 " arguments parsed, TLVError=%" PRIu32 ", UnpackError=%" PRIu32,
5, validArgumentCount, TLVError, TLVUnpackError);
}
break;
}
case ZCL_REMOVE_ALL_SCENES_RESPONSE_COMMAND_ID: {
// 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.
CHIP_ERROR TLVError = CHIP_NO_ERROR;
CHIP_ERROR TLVUnpackError = CHIP_NO_ERROR;
uint8_t status;
bool statusExists = false;
uint16_t groupId;
bool groupIdExists = false;
uint32_t validArgumentCount = 0;
while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR)
{
switch (TLV::TagNumFromTag(aDataTlv.GetTag()))
{
case 0:
if (statusExists)
{
ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
break;
}
TLVUnpackError = aDataTlv.Get(status);
if (CHIP_NO_ERROR == TLVUnpackError)
{
statusExists = true;
validArgumentCount++;
}
break;
case 1:
if (groupIdExists)
{
ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
break;
}
TLVUnpackError = aDataTlv.Get(groupId);
if (CHIP_NO_ERROR == TLVUnpackError)
{
groupIdExists = true;
validArgumentCount++;
}
break;
default:
// Unsupported tag, ignore it.
ChipLogProgress(Zcl, "Unknown TLV tag during processing.");
break;
}
if (TLVUnpackError != CHIP_NO_ERROR)
{
ChipLogProgress(Zcl, "Failed to decode TLV data with tag %" PRIx32 ": %" PRId32,
TLV::TagNumFromTag(aDataTlv.GetTag()), 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;
}
else
{
ChipLogProgress(Zcl, "Failed to decode TLV data: %" PRId32, TLVError);
}
// TODO(#5590) We should encode a response of status code for invalid TLV.
if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 2 == validArgumentCount)
{
// TODO(#5098) We should pass the Command Object and EndpointId to the cluster callbacks.
emberAfScenesClusterRemoveAllScenesResponseCallback(apCommandObj, status, groupId);
}
else
{
apCommandObj->AddStatusCode(nullptr, Protocols::SecureChannel::GeneralStatusCode::kBadRequest,
Protocols::SecureChannel::Id, Protocols::SecureChannel::kProtocolCodeGeneralFailure);
ChipLogProgress(
Zcl, "Failed to dispatch command, %d/%" PRIu32 " arguments parsed, TLVError=%" PRIu32 ", UnpackError=%" PRIu32,
2, validArgumentCount, TLVError, TLVUnpackError);
}
break;
}
case ZCL_REMOVE_SCENE_RESPONSE_COMMAND_ID: {
// 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.
CHIP_ERROR TLVError = CHIP_NO_ERROR;
CHIP_ERROR TLVUnpackError = CHIP_NO_ERROR;
uint8_t status;
bool statusExists = false;
uint16_t groupId;
bool groupIdExists = false;
uint8_t sceneId;
bool sceneIdExists = false;
uint32_t validArgumentCount = 0;
while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR)
{
switch (TLV::TagNumFromTag(aDataTlv.GetTag()))
{
case 0:
if (statusExists)
{
ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
break;
}
TLVUnpackError = aDataTlv.Get(status);
if (CHIP_NO_ERROR == TLVUnpackError)
{
statusExists = true;
validArgumentCount++;
}
break;
case 1:
if (groupIdExists)
{
ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
break;
}
TLVUnpackError = aDataTlv.Get(groupId);
if (CHIP_NO_ERROR == TLVUnpackError)
{
groupIdExists = true;
validArgumentCount++;
}
break;
case 2:
if (sceneIdExists)
{
ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
break;
}
TLVUnpackError = aDataTlv.Get(sceneId);
if (CHIP_NO_ERROR == TLVUnpackError)
{
sceneIdExists = true;
validArgumentCount++;
}
break;
default:
// Unsupported tag, ignore it.
ChipLogProgress(Zcl, "Unknown TLV tag during processing.");
break;
}
if (TLVUnpackError != CHIP_NO_ERROR)
{
ChipLogProgress(Zcl, "Failed to decode TLV data with tag %" PRIx32 ": %" PRId32,
TLV::TagNumFromTag(aDataTlv.GetTag()), 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;
}
else
{
ChipLogProgress(Zcl, "Failed to decode TLV data: %" PRId32, TLVError);
}
// TODO(#5590) We should encode a response of status code for invalid TLV.
if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 3 == validArgumentCount)
{
// TODO(#5098) We should pass the Command Object and EndpointId to the cluster callbacks.
emberAfScenesClusterRemoveSceneResponseCallback(apCommandObj, status, groupId, sceneId);
}
else
{
apCommandObj->AddStatusCode(nullptr, Protocols::SecureChannel::GeneralStatusCode::kBadRequest,
Protocols::SecureChannel::Id, Protocols::SecureChannel::kProtocolCodeGeneralFailure);
ChipLogProgress(
Zcl, "Failed to dispatch command, %d/%" PRIu32 " arguments parsed, TLVError=%" PRIu32 ", UnpackError=%" PRIu32,
3, validArgumentCount, TLVError, TLVUnpackError);
}
break;
}
case ZCL_STORE_SCENE_RESPONSE_COMMAND_ID: {
// 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.
CHIP_ERROR TLVError = CHIP_NO_ERROR;
CHIP_ERROR TLVUnpackError = CHIP_NO_ERROR;
uint8_t status;
bool statusExists = false;
uint16_t groupId;
bool groupIdExists = false;
uint8_t sceneId;
bool sceneIdExists = false;
uint32_t validArgumentCount = 0;
while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR)
{
switch (TLV::TagNumFromTag(aDataTlv.GetTag()))
{
case 0:
if (statusExists)
{
ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
break;
}
TLVUnpackError = aDataTlv.Get(status);
if (CHIP_NO_ERROR == TLVUnpackError)
{
statusExists = true;
validArgumentCount++;
}
break;
case 1:
if (groupIdExists)
{
ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
break;
}
TLVUnpackError = aDataTlv.Get(groupId);
if (CHIP_NO_ERROR == TLVUnpackError)
{
groupIdExists = true;
validArgumentCount++;
}
break;
case 2:
if (sceneIdExists)
{
ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
break;
}
TLVUnpackError = aDataTlv.Get(sceneId);
if (CHIP_NO_ERROR == TLVUnpackError)
{
sceneIdExists = true;
validArgumentCount++;
}
break;
default:
// Unsupported tag, ignore it.
ChipLogProgress(Zcl, "Unknown TLV tag during processing.");
break;
}
if (TLVUnpackError != CHIP_NO_ERROR)
{
ChipLogProgress(Zcl, "Failed to decode TLV data with tag %" PRIx32 ": %" PRId32,
TLV::TagNumFromTag(aDataTlv.GetTag()), 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;
}
else
{
ChipLogProgress(Zcl, "Failed to decode TLV data: %" PRId32, TLVError);
}
// TODO(#5590) We should encode a response of status code for invalid TLV.
if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 3 == validArgumentCount)
{
// TODO(#5098) We should pass the Command Object and EndpointId to the cluster callbacks.
emberAfScenesClusterStoreSceneResponseCallback(apCommandObj, status, groupId, sceneId);
}
else
{
apCommandObj->AddStatusCode(nullptr, Protocols::SecureChannel::GeneralStatusCode::kBadRequest,
Protocols::SecureChannel::Id, Protocols::SecureChannel::kProtocolCodeGeneralFailure);
ChipLogProgress(
Zcl, "Failed to dispatch command, %d/%" PRIu32 " arguments parsed, TLVError=%" PRIu32 ", UnpackError=%" PRIu32,
3, validArgumentCount, TLVError, TLVUnpackError);
}
break;
}
case ZCL_VIEW_SCENE_RESPONSE_COMMAND_ID: {
// 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.
CHIP_ERROR TLVError = CHIP_NO_ERROR;
CHIP_ERROR TLVUnpackError = CHIP_NO_ERROR;
uint8_t status;
bool statusExists = false;
uint16_t groupId;
bool groupIdExists = false;
uint8_t sceneId;
bool sceneIdExists = false;
uint16_t transitionTime;
bool transitionTimeExists = false;
const uint8_t * sceneName;
bool sceneNameExists = false;
/* TYPE WARNING: array array defaults to */ uint8_t * extensionFieldSets;
bool extensionFieldSetsExists = false;
uint32_t validArgumentCount = 0;
while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR)
{
switch (TLV::TagNumFromTag(aDataTlv.GetTag()))
{
case 0:
if (statusExists)
{
ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
break;
}
TLVUnpackError = aDataTlv.Get(status);
if (CHIP_NO_ERROR == TLVUnpackError)
{
statusExists = true;
validArgumentCount++;
}
break;
case 1:
if (groupIdExists)
{
ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
break;
}
TLVUnpackError = aDataTlv.Get(groupId);
if (CHIP_NO_ERROR == TLVUnpackError)
{
groupIdExists = true;
validArgumentCount++;
}
break;
case 2:
if (sceneIdExists)
{
ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
break;
}
TLVUnpackError = aDataTlv.Get(sceneId);
if (CHIP_NO_ERROR == TLVUnpackError)
{
sceneIdExists = true;
validArgumentCount++;
}
break;
case 3:
if (transitionTimeExists)
{
ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
break;
}
TLVUnpackError = aDataTlv.Get(transitionTime);
if (CHIP_NO_ERROR == TLVUnpackError)
{
transitionTimeExists = true;
validArgumentCount++;
}
break;
case 4:
if (sceneNameExists)
{
ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
break;
}
// TODO(#5542): The cluster handlers should accept a ByteSpan for all string types.
TLVUnpackError = aDataTlv.GetDataPtr(sceneName);
if (CHIP_NO_ERROR == TLVUnpackError)
{
sceneNameExists = true;
validArgumentCount++;
}
break;
case 5:
if (extensionFieldSetsExists)
{
ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
break;
}
// Just for compatibility, we will add array type support in IM later.
TLVUnpackError = aDataTlv.GetDataPtr(const_cast<const uint8_t *&>(extensionFieldSets));
if (CHIP_NO_ERROR == TLVUnpackError)
{
extensionFieldSetsExists = true;
validArgumentCount++;
}
break;
default:
// Unsupported tag, ignore it.
ChipLogProgress(Zcl, "Unknown TLV tag during processing.");
break;
}
if (TLVUnpackError != CHIP_NO_ERROR)
{
ChipLogProgress(Zcl, "Failed to decode TLV data with tag %" PRIx32 ": %" PRId32,
TLV::TagNumFromTag(aDataTlv.GetTag()), 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;
}
else
{
ChipLogProgress(Zcl, "Failed to decode TLV data: %" PRId32, TLVError);
}
// TODO(#5590) We should encode a response of status code for invalid TLV.
if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 6 == validArgumentCount)
{
// TODO(#5098) We should pass the Command Object and EndpointId to the cluster callbacks.
emberAfScenesClusterViewSceneResponseCallback(apCommandObj, status, groupId, sceneId, transitionTime,
const_cast<uint8_t *>(sceneName), extensionFieldSets);
}
else
{
apCommandObj->AddStatusCode(nullptr, Protocols::SecureChannel::GeneralStatusCode::kBadRequest,
Protocols::SecureChannel::Id, Protocols::SecureChannel::kProtocolCodeGeneralFailure);
ChipLogProgress(
Zcl, "Failed to dispatch command, %d/%" PRIu32 " arguments parsed, TLVError=%" PRIu32 ", UnpackError=%" PRIu32,
6, validArgumentCount, TLVError, TLVUnpackError);
}
break;
}
default: {
// Unrecognized command ID, error status will apply.
apCommandObj->AddStatusCode(nullptr, Protocols::SecureChannel::GeneralStatusCode::kNotFound,
Protocols::SecureChannel::Id, Protocols::SecureChannel::kProtocolCodeGeneralFailure);
ChipLogError(Zcl, "Unknown command %" PRIx16 " for cluster %" PRIx16, aCommandId, ZCL_SCENES_CLUSTER_ID);
break;
}
}
}
}
} // namespace Scenes
} // namespace clusters
void DispatchSingleClusterCommand(chip::ClusterId aClusterId, chip::CommandId aCommandId, chip::EndpointId aEndPointId,
chip::TLV::TLVReader & aReader, Command * apCommandObj)
{
ChipLogDetail(Zcl, "Received Cluster Command: Cluster=%" PRIx16 " Command=%" PRIx8 " Endpoint=%" PRIx8, aClusterId, aCommandId,
aEndPointId);
Compatibility::SetupEmberAfObjects(apCommandObj, aClusterId, aCommandId, aEndPointId);
TLV::TLVType dataTlvType;
SuccessOrExit(aReader.EnterContainer(dataTlvType));
switch (aClusterId)
{
default:
// Unrecognized cluster ID, error status will apply.
apCommandObj->AddStatusCode(nullptr, Protocols::SecureChannel::GeneralStatusCode::kNotFound, Protocols::SecureChannel::Id,
Protocols::SecureChannel::kProtocolCodeGeneralFailure);
ChipLogError(Zcl, "Unknown cluster %" PRIx16, aClusterId);
break;
}
exit:
Compatibility::ResetEmberAfObjects();
aReader.ExitContainer(dataTlvType);
}
} // namespace app
} // namespace chip