Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix Window app commissioning flow #7526

Merged
merged 6 commits into from
Jun 16, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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