Skip to content

Commit

Permalink
Fix Window app commissioning flow (#7526)
Browse files Browse the repository at this point in the history
* move operational clusters to endpoint 0, keep the application cluster (window cover) in ep 1

* regenerate files with zap

regen after rebase

Rebase and regen for updates

* Rebase and regen

* Fix missed issue when rebabse didn't remove TRUSTED_ROOT_CERTIFICATES_CLUSTER in the modified window-app.zap file
Regen files

* Rebase and Regen

Rebase and Regen2

* rebase&regen
  • Loading branch information
jmartinez-silabs authored and pull[bot] committed Jun 19, 2021
1 parent 4a751cb commit 1083680
Show file tree
Hide file tree
Showing 13 changed files with 5,477 additions and 211 deletions.
996 changes: 996 additions & 0 deletions examples/window-app/common/gen/CHIPClientCallbacks.cpp

Large diffs are not rendered by default.

31 changes: 31 additions & 0 deletions examples/window-app/common/gen/CHIPClientCallbacks.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,35 @@

// THIS FILE IS GENERATED BY ZAP

#pragma once

#include <app/Command.h>
#include <app/common/gen/af-structs.h>
#include <app/util/af-enums.h>
#include <inttypes.h>
#include <lib/support/Span.h>

// Note: The IMDefaultResponseCallback is a bridge to the old CallbackMgr before IM is landed, so it still accepts EmberAfStatus
// instead of IM status code.
// #6308 should handle IM error code on the application side, either modify this function or remove this.
bool IMDefaultResponseCallback(const chip::app::Command * commandObj, EmberAfStatus status);

// Global Response Callbacks
typedef void (*DefaultSuccessCallback)(void * context);
typedef void (*DefaultFailureCallback)(void * context, uint8_t status);
typedef void (*BooleanAttributeCallback)(void * context, bool value);
typedef void (*Int8uAttributeCallback)(void * context, uint8_t value);
typedef void (*Int8sAttributeCallback)(void * context, int8_t value);
typedef void (*Int16uAttributeCallback)(void * context, uint16_t value);
typedef void (*Int16sAttributeCallback)(void * context, int16_t value);
typedef void (*Int32uAttributeCallback)(void * context, uint32_t value);
typedef void (*Int32sAttributeCallback)(void * context, int32_t value);
typedef void (*Int64uAttributeCallback)(void * context, uint64_t value);
typedef void (*Int64sAttributeCallback)(void * context, int64_t value);
typedef void (*StringAttributeCallback)(void * context, const chip::ByteSpan value);
typedef void (*ReadReportingConfigurationReportedCallback)(void * context, uint16_t minInterval, uint16_t maxInterval);
typedef void (*ReadReportingConfigurationReceivedCallback)(void * context, uint16_t timeout);

// Cluster Specific Response Callbacks

// List specific responses
410 changes: 410 additions & 0 deletions examples/window-app/common/gen/CHIPClusters.cpp

Large diffs are not rendered by default.

71 changes: 71 additions & 0 deletions examples/window-app/common/gen/CHIPClusters.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,74 @@
*/

// THIS FILE IS GENERATED BY ZAP

// Prevent multiple inclusion
#pragma once

#include <controller/CHIPCluster.h>
#include <core/CHIPCallback.h>
#include <lib/support/Span.h>

namespace chip {
namespace Controller {

constexpr ClusterId kWindowCoveringClusterId = 0x0102;

class DLL_EXPORT WindowCoveringCluster : public ClusterBase
{
public:
WindowCoveringCluster() : ClusterBase(kWindowCoveringClusterId) {}
~WindowCoveringCluster() {}

// Cluster Commands
CHIP_ERROR WindowCoveringDownClose(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback);
CHIP_ERROR WindowCoveringGoToLiftPercentage(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback,
uint8_t percentageLiftValue);
CHIP_ERROR WindowCoveringGoToLiftValue(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback,
uint16_t liftValue);
CHIP_ERROR WindowCoveringGoToTiltPercentage(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback,
uint8_t percentageTiltValue);
CHIP_ERROR WindowCoveringGoToTiltValue(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback,
uint16_t tiltValue);
CHIP_ERROR WindowCoveringStop(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback);
CHIP_ERROR WindowCoveringUpOpen(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback);

// Cluster Attributes
CHIP_ERROR DiscoverAttributes(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback);
CHIP_ERROR ReadAttributeWindowCoveringType(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback);
CHIP_ERROR ReadAttributeCurrentPositionLift(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback);
CHIP_ERROR ReadAttributeCurrentPositionTilt(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback);
CHIP_ERROR ReadAttributeConfigStatus(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback);
CHIP_ERROR ReadAttributeInstalledOpenLimitLift(Callback::Cancelable * onSuccessCallback,
Callback::Cancelable * onFailureCallback);
CHIP_ERROR ReadAttributeInstalledClosedLimitLift(Callback::Cancelable * onSuccessCallback,
Callback::Cancelable * onFailureCallback);
CHIP_ERROR ReadAttributeInstalledOpenLimitTilt(Callback::Cancelable * onSuccessCallback,
Callback::Cancelable * onFailureCallback);
CHIP_ERROR ReadAttributeInstalledClosedLimitTilt(Callback::Cancelable * onSuccessCallback,
Callback::Cancelable * onFailureCallback);
CHIP_ERROR ReadAttributeMode(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback);
CHIP_ERROR ReadAttributeClusterRevision(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback);
CHIP_ERROR WriteAttributeMode(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback,
uint8_t value);
CHIP_ERROR ConfigureAttributeCurrentPositionLift(Callback::Cancelable * onSuccessCallback,
Callback::Cancelable * onFailureCallback, uint16_t minInterval,
uint16_t maxInterval, uint16_t change);
CHIP_ERROR ReportAttributeCurrentPositionLift(Callback::Cancelable * onReportCallback);
CHIP_ERROR ConfigureAttributeCurrentPositionTilt(Callback::Cancelable * onSuccessCallback,
Callback::Cancelable * onFailureCallback, uint16_t minInterval,
uint16_t maxInterval, uint16_t change);
CHIP_ERROR ReportAttributeCurrentPositionTilt(Callback::Cancelable * onReportCallback);

private:
static constexpr CommandId kWindowCoveringDownCloseCommandId = 0x01;
static constexpr CommandId kWindowCoveringGoToLiftPercentageCommandId = 0x05;
static constexpr CommandId kWindowCoveringGoToLiftValueCommandId = 0x04;
static constexpr CommandId kWindowCoveringGoToTiltPercentageCommandId = 0x08;
static constexpr CommandId kWindowCoveringGoToTiltValueCommandId = 0x07;
static constexpr CommandId kWindowCoveringStopCommandId = 0x02;
static constexpr CommandId kWindowCoveringUpOpenCommandId = 0x00;
};

} // namespace Controller
} // namespace chip
217 changes: 199 additions & 18 deletions examples/window-app/common/gen/IMClusterCommandHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,202 @@ namespace app {

namespace clusters {

namespace GeneralCommissioning {

void DispatchServerCommand(app::Command * apCommandObj, CommandId aCommandId, EndpointId aEndpointId, TLV::TLVReader & aDataTlv)
{
// We are using TLVUnpackError and TLVError here since both of them can be CHIP_END_OF_TLV
// When TLVError is CHIP_END_OF_TLV, it means we have iterated all of the items, which is not a real error.
// Any error value TLVUnpackError means we have received an illegal value.
// The following variables are used for all commands to save code size.
CHIP_ERROR TLVError = CHIP_NO_ERROR;
CHIP_ERROR TLVUnpackError = CHIP_NO_ERROR;
uint32_t validArgumentCount = 0;
uint32_t expectArgumentCount = 0;
uint32_t currentDecodeTagId = 0;
bool wasHandled = false;
{
switch (aCommandId)
{
case ZCL_ARM_FAIL_SAFE_COMMAND_ID: {
expectArgumentCount = 3;
uint16_t expiryLengthSeconds;
uint64_t breadcrumb;
uint32_t timeoutMs;
bool argExists[3];

memset(argExists, 0, sizeof argExists);

while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR)
{
// Since call to aDataTlv.Next() is CHIP_NO_ERROR, the read head always points to an element.
// Skip this element if it is not a ContextTag, not consider it as an error if other values are valid.
if (!TLV::IsContextTag(aDataTlv.GetTag()))
{
continue;
}
currentDecodeTagId = TLV::TagNumFromTag(aDataTlv.GetTag());
if (currentDecodeTagId < 3)
{
if (argExists[currentDecodeTagId])
{
ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
break;
}
else
{
argExists[currentDecodeTagId] = true;
validArgumentCount++;
}
}
switch (currentDecodeTagId)
{
case 0:
TLVUnpackError = aDataTlv.Get(expiryLengthSeconds);
break;
case 1:
TLVUnpackError = aDataTlv.Get(breadcrumb);
break;
case 2:
TLVUnpackError = aDataTlv.Get(timeoutMs);
break;
default:
// Unsupported tag, ignore it.
ChipLogProgress(Zcl, "Unknown TLV tag during processing.");
break;
}
if (CHIP_NO_ERROR != TLVUnpackError)
{
break;
}
}

if (CHIP_END_OF_TLV == TLVError)
{
// CHIP_END_OF_TLV means we have iterated all items in the structure, which is not a real error.
TLVError = CHIP_NO_ERROR;
}

if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 3 == validArgumentCount)
{
// TODO(#5098) We should pass the Command Object and EndpointId to the cluster callbacks.
wasHandled =
emberAfGeneralCommissioningClusterArmFailSafeCallback(apCommandObj, expiryLengthSeconds, breadcrumb, timeoutMs);
}
break;
}
case ZCL_COMMISSIONING_COMPLETE_COMMAND_ID: {

// TODO(#5098) We should pass the Command Object and EndpointId to the cluster callbacks.
wasHandled = emberAfGeneralCommissioningClusterCommissioningCompleteCallback(apCommandObj);
break;
}
case ZCL_SET_REGULATORY_CONFIG_COMMAND_ID: {
expectArgumentCount = 4;
uint8_t location;
const uint8_t * countryCode;
uint64_t breadcrumb;
uint32_t timeoutMs;
bool argExists[4];

memset(argExists, 0, sizeof argExists);

while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR)
{
// Since call to aDataTlv.Next() is CHIP_NO_ERROR, the read head always points to an element.
// Skip this element if it is not a ContextTag, not consider it as an error if other values are valid.
if (!TLV::IsContextTag(aDataTlv.GetTag()))
{
continue;
}
currentDecodeTagId = TLV::TagNumFromTag(aDataTlv.GetTag());
if (currentDecodeTagId < 4)
{
if (argExists[currentDecodeTagId])
{
ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
break;
}
else
{
argExists[currentDecodeTagId] = true;
validArgumentCount++;
}
}
switch (currentDecodeTagId)
{
case 0:
TLVUnpackError = aDataTlv.Get(location);
break;
case 1:
// TODO(#5542): The cluster handlers should accept a ByteSpan for all string types.
TLVUnpackError = aDataTlv.GetDataPtr(countryCode);
break;
case 2:
TLVUnpackError = aDataTlv.Get(breadcrumb);
break;
case 3:
TLVUnpackError = aDataTlv.Get(timeoutMs);
break;
default:
// Unsupported tag, ignore it.
ChipLogProgress(Zcl, "Unknown TLV tag during processing.");
break;
}
if (CHIP_NO_ERROR != TLVUnpackError)
{
break;
}
}

if (CHIP_END_OF_TLV == TLVError)
{
// CHIP_END_OF_TLV means we have iterated all items in the structure, which is not a real error.
TLVError = CHIP_NO_ERROR;
}

if (CHIP_NO_ERROR == TLVError && CHIP_NO_ERROR == TLVUnpackError && 4 == validArgumentCount)
{
// TODO(#5098) We should pass the Command Object and EndpointId to the cluster callbacks.
wasHandled = emberAfGeneralCommissioningClusterSetRegulatoryConfigCallback(
apCommandObj, location, const_cast<uint8_t *>(countryCode), breadcrumb, timeoutMs);
}
break;
}
default: {
// Unrecognized command ID, error status will apply.
chip::app::CommandPathParams returnStatusParam = { aEndpointId,
0, // GroupId
ZCL_GENERAL_COMMISSIONING_CLUSTER_ID, aCommandId,
(chip::app::CommandPathFlags::kEndpointIdValid) };
apCommandObj->AddStatusCode(returnStatusParam, Protocols::SecureChannel::GeneralStatusCode::kNotFound,
Protocols::SecureChannel::Id,
Protocols::InteractionModel::ProtocolCode::UnsupportedCommand);
ChipLogError(Zcl, "Unknown command %" PRIx16 " for cluster %" PRIx16, aCommandId, ZCL_GENERAL_COMMISSIONING_CLUSTER_ID);
return;
}
}
}

if (CHIP_NO_ERROR != TLVError || CHIP_NO_ERROR != TLVUnpackError || expectArgumentCount != validArgumentCount || !wasHandled)
{
chip::app::CommandPathParams returnStatusParam = { aEndpointId,
0, // GroupId
ZCL_GENERAL_COMMISSIONING_CLUSTER_ID, aCommandId,
(chip::app::CommandPathFlags::kEndpointIdValid) };
apCommandObj->AddStatusCode(returnStatusParam, Protocols::SecureChannel::GeneralStatusCode::kBadRequest,
Protocols::SecureChannel::Id, Protocols::InteractionModel::ProtocolCode::InvalidCommand);
ChipLogProgress(Zcl,
"Failed to dispatch command, %" PRIu32 "/%" PRIu32 " arguments parsed, TLVError=%" PRIu32
", UnpackError=%" PRIu32 " (last decoded tag = %" PRIu32,
validArgumentCount, expectArgumentCount, TLVError, TLVUnpackError, currentDecodeTagId);
}
}

} // namespace GeneralCommissioning

namespace NetworkCommissioning {

void DispatchServerCommand(app::Command * apCommandObj, CommandId aCommandId, EndpointId aEndpointId, TLV::TLVReader & aDataTlv)
Expand Down Expand Up @@ -1252,12 +1448,6 @@ void DispatchServerCommand(app::Command * apCommandObj, CommandId aCommandId, En
{
switch (aCommandId)
{
case ZCL_WINDOW_COVERING_DOWN_CLOSE_COMMAND_ID: {

// TODO(#5098) We should pass the Command Object and EndpointId to the cluster callbacks.
wasHandled = emberAfWindowCoveringClusterWindowCoveringDownCloseCallback(apCommandObj);
break;
}
case ZCL_WINDOW_COVERING_GO_TO_LIFT_PERCENTAGE_COMMAND_ID: {
expectArgumentCount = 1;
uint8_t percentageLiftValue;
Expand Down Expand Up @@ -1496,18 +1686,6 @@ void DispatchServerCommand(app::Command * apCommandObj, CommandId aCommandId, En
}
break;
}
case ZCL_WINDOW_COVERING_STOP_COMMAND_ID: {

// TODO(#5098) We should pass the Command Object and EndpointId to the cluster callbacks.
wasHandled = emberAfWindowCoveringClusterWindowCoveringStopCallback(apCommandObj);
break;
}
case ZCL_WINDOW_COVERING_UP_OPEN_COMMAND_ID: {

// TODO(#5098) We should pass the Command Object and EndpointId to the cluster callbacks.
wasHandled = emberAfWindowCoveringClusterWindowCoveringUpOpenCallback(apCommandObj);
break;
}
default: {
// Unrecognized command ID, error status will apply.
chip::app::CommandPathParams returnStatusParam = { aEndpointId,
Expand Down Expand Up @@ -1552,6 +1730,9 @@ void DispatchSingleClusterCommand(chip::ClusterId aClusterId, chip::CommandId aC
SuccessOrExit(aReader.EnterContainer(dataTlvType));
switch (aClusterId)
{
case ZCL_GENERAL_COMMISSIONING_CLUSTER_ID:
clusters::GeneralCommissioning::DispatchServerCommand(apCommandObj, aCommandId, aEndPointId, aReader);
break;
case ZCL_NETWORK_COMMISSIONING_CLUSTER_ID:
clusters::NetworkCommissioning::DispatchServerCommand(apCommandObj, aCommandId, aEndPointId, aReader);
break;
Expand Down
Loading

0 comments on commit 1083680

Please sign in to comment.