| {{#if (isServer parent.clusterSide)}} |
| Commands::{{asUpperCamelCase commandName}}::DecodableType commandData; |
| TLVError = DataModel::Decode(aDataTlv, commandData); |
| if (TLVError == CHIP_NO_ERROR) { |
| wasHandled = emberAf{{asUpperCamelCase parent.clusterName}}Cluster{{asUpperCamelCase commandName}}Callback(apCommandObj, aCommandPath, commandData); |
| } |
| {{else}} |
| {{#if (zcl_command_arguments_count this.id)}} |
| expectArgumentCount = {{ zcl_command_arguments_count this.id }}; |
| {{#zcl_command_arguments}} |
| {{#if isArray}} |
| {{asUnderlyingZclType type}} {{asSymbol label}}; |
| {{else}} |
| {{#if_is_struct type}} |
| {{zapTypeToDecodableClusterObjectType type ns=parent.parent.clusterName}} {{asSymbol label}}; |
| {{else}} |
| {{asUnderlyingZclType type}} {{asSymbol label}}; |
| {{/if_is_struct}} |
| {{/if}} |
| {{/zcl_command_arguments}} |
| bool argExists[{{zcl_command_arguments_count this.id}}]; |
| |
| memset(argExists, 0, sizeof argExists); |
| |
| while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR) |
| { |
| // Since call to aDataTlv.Next() is CHIP_NO_ERROR, the read head always points to an element. |
| // Skip this element if it is not a ContextTag, not consider it as an error if other values are valid. |
| if (!TLV::IsContextTag(aDataTlv.GetTag())) |
| { |
| continue; |
| } |
| currentDecodeTagId = TLV::TagNumFromTag(aDataTlv.GetTag()); |
| if (currentDecodeTagId < {{zcl_command_arguments_count this.id}}) |
| { |
| if (argExists[currentDecodeTagId]) |
| { |
| ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag())); |
| TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_IB; |
| break; |
| } |
| else |
| { |
| argExists[currentDecodeTagId] = true; |
| validArgumentCount++; |
| } |
| } |
| switch (currentDecodeTagId) |
| { |
| {{#zcl_command_arguments}} |
| case {{fieldIdentifier}}: |
| {{#if isArray}} |
| // Just for compatibility, we will add array type support in IM later. |
| TLVUnpackError = aDataTlv.GetDataPtr(const_cast<const uint8_t *&>({{asSymbol label}})); |
| {{else}} |
| {{#if_is_struct type}} |
| // Not supported, just error out. |
| TLVUnpackError = CHIP_ERROR_UNEXPECTED_TLV_ELEMENT; |
| {{else}} |
| TLVUnpackError = aDataTlv.Get({{asSymbol label}}); |
| {{/if_is_struct}} |
| {{/if}} |
| break; |
| {{/zcl_command_arguments}} |
| default: |
| // Unsupported tag, ignore it. |
| ChipLogProgress(Zcl, "Unknown TLV tag during processing."); |
| break; |
| } |
| if (CHIP_NO_ERROR != TLVUnpackError) |
| { |
| break; |
| } |
| } |
| |
| if (CHIP_END_OF_TLV == TLVError) |
| { |
| // CHIP_END_OF_TLV means we have iterated all items in the structure, which is not a real error. |
| TLVError = CHIP_NO_ERROR; |
| } |
| {{/if}} |
| |
| {{#if (zcl_command_arguments_count this.id)}} |
| if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && {{zcl_command_arguments_count this.id}} == validArgumentCount) |
| { |
| {{/if}} |
| wasHandled = emberAf{{asUpperCamelCase parent.clusterName}}Cluster{{asUpperCamelCase commandName}}Callback(aCommandPath.mEndpointId, apCommandObj{{#zcl_command_arguments}}, {{asSymbol label}}{{/zcl_command_arguments}}); |
| {{#if (zcl_command_arguments_count this.id)}} |
| } |
| {{/if}} |
| {{/if}} |