Skip to content

Commit

Permalink
Merge fc636e0 into 934c876
Browse files Browse the repository at this point in the history
  • Loading branch information
pan-apple authored May 11, 2021
2 parents 934c876 + fc636e0 commit 1265219
Show file tree
Hide file tree
Showing 108 changed files with 3,148 additions and 171 deletions.
69 changes: 69 additions & 0 deletions examples/all-clusters-app/all-clusters-common/all-clusters-app.zap
Original file line number Diff line number Diff line change
Expand Up @@ -1875,6 +1875,75 @@
}
]
},
{
"name": "Trusted Root Certificates",
"code": 63,
"mfgCode": null,
"define": "TRUSTED_ROOT_CERTIFICATES_CLUSTER",
"side": "client",
"enabled": 0,
"commands": [
{
"name": "AddTrustedRootCertificate",
"code": 0,
"mfgCode": null,
"source": "client",
"incoming": 1,
"outgoing": 1
},
{
"name": "RemoveTrustedRootCertificate",
"code": 1,
"mfgCode": null,
"source": "client",
"incoming": 1,
"outgoing": 1
}
],
"attributes": [
{
"name": "cluster revision",
"code": 65533,
"mfgCode": null,
"side": "client",
"included": 1,
"storageOption": "RAM",
"singleton": 0,
"bounded": 0,
"defaultValue": "0x0001",
"reportable": 0,
"minInterval": 0,
"maxInterval": 65344,
"reportableChange": 0
}
]
},
{
"name": "Trusted Root Certificates",
"code": 63,
"mfgCode": null,
"define": "TRUSTED_ROOT_CERTIFICATES_CLUSTER",
"side": "server",
"enabled": 1,
"commands": [],
"attributes": [
{
"name": "cluster revision",
"code": 65533,
"mfgCode": null,
"side": "server",
"included": 1,
"storageOption": "RAM",
"singleton": 0,
"bounded": 0,
"defaultValue": "0x0001",
"reportable": 0,
"minInterval": 0,
"maxInterval": 65344,
"reportableChange": 0
}
]
},
{
"name": "Door Lock",
"code": 257,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8166,6 +8166,169 @@ void DispatchServerCommand(app::Command * apCommandObj, CommandId aCommandId, En

} // namespace TestCluster

namespace TrustedRootCertificates {

void DispatchServerCommand(app::Command * apCommandObj, CommandId aCommandId, EndpointId aEndpointId, TLV::TLVReader & aDataTlv)
{
{
switch (aCommandId)
{
case ZCL_ADD_TRUSTED_ROOT_CERTIFICATE_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;
chip::ByteSpan RootCertificate;
bool RootCertificateExists = false;
uint32_t validArgumentCount = 0;

while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR)
{
switch (TLV::TagNumFromTag(aDataTlv.GetTag()))
{
case 0:
if (RootCertificateExists)
{
ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
break;
}
{
const uint8_t * data = nullptr;
TLVUnpackError = aDataTlv.GetDataPtr(data);
RootCertificate = chip::ByteSpan(data, aDataTlv.GetLength());
}
if (CHIP_NO_ERROR == TLVUnpackError)
{
RootCertificateExists = 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.
emberAfTrustedRootCertificatesClusterAddTrustedRootCertificateCallback(apCommandObj, RootCertificate);
}
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_REMOVE_TRUSTED_ROOT_CERTIFICATE_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;
chip::ByteSpan TrustedRootIdentifier;
bool TrustedRootIdentifierExists = false;
uint32_t validArgumentCount = 0;

while ((TLVError = aDataTlv.Next()) == CHIP_NO_ERROR)
{
switch (TLV::TagNumFromTag(aDataTlv.GetTag()))
{
case 0:
if (TrustedRootIdentifierExists)
{
ChipLogProgress(Zcl, "Duplicate TLV tag %" PRIx32, TLV::TagNumFromTag(aDataTlv.GetTag()));
TLVUnpackError = CHIP_ERROR_IM_MALFORMED_COMMAND_DATA_ELEMENT;
break;
}
{
const uint8_t * data = nullptr;
TLVUnpackError = aDataTlv.GetDataPtr(data);
TrustedRootIdentifier = chip::ByteSpan(data, aDataTlv.GetLength());
}
if (CHIP_NO_ERROR == TLVUnpackError)
{
TrustedRootIdentifierExists = 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.
emberAfTrustedRootCertificatesClusterRemoveTrustedRootCertificateCallback(apCommandObj, TrustedRootIdentifier);
}
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_TRUSTED_ROOT_CERTIFICATES_CLUSTER_ID);
break;
}
}
}
}

} // namespace TrustedRootCertificates

} // namespace clusters

void DispatchSingleClusterCommand(chip::ClusterId aClusterId, chip::CommandId aCommandId, chip::EndpointId aEndPointId,
Expand Down Expand Up @@ -8229,6 +8392,9 @@ void DispatchSingleClusterCommand(chip::ClusterId aClusterId, chip::CommandId aC
case ZCL_TEST_CLUSTER_ID:
clusters::TestCluster::DispatchServerCommand(apCommandObj, aCommandId, aEndPointId, aReader);
break;
case ZCL_TRUSTED_ROOT_CERTIFICATES_CLUSTER_ID:
clusters::TrustedRootCertificates::DispatchServerCommand(apCommandObj, aCommandId, aEndPointId, aReader);
break;
default:
// Unrecognized cluster ID, error status will apply.
apCommandObj->AddStatusCode(nullptr, Protocols::SecureChannel::GeneralStatusCode::kNotFound, Protocols::SecureChannel::Id,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -456,6 +456,12 @@
// Server attributes
#define ZCL_FABRICS_ATTRIBUTE_ID (0x0001)

// Attribute ids for cluster: Trusted Root Certificates

// Client attributes

// Server attributes

// Attribute ids for cluster: Shade Configuration

// Client attributes
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ EmberAfStatus emberAfSwitchClusterServerCommandParse(EmberAfClusterCommand * cmd
EmberAfStatus emberAfTemperatureMeasurementClusterServerCommandParse(EmberAfClusterCommand * cmd);
EmberAfStatus emberAfTestClusterClusterServerCommandParse(EmberAfClusterCommand * cmd);
EmberAfStatus emberAfThermostatClusterServerCommandParse(EmberAfClusterCommand * cmd);
EmberAfStatus emberAfTrustedRootCertificatesClusterServerCommandParse(EmberAfClusterCommand * cmd);
EmberAfStatus emberAfWiFiNetworkDiagnosticsClusterServerCommandParse(EmberAfClusterCommand * cmd);

static EmberAfStatus status(bool wasHandled, bool clusterExists, bool mfgSpecific)
Expand Down Expand Up @@ -177,6 +178,9 @@ EmberAfStatus emberAfClusterSpecificCommandParse(EmberAfClusterCommand * cmd)
// No commands are enabled for cluster Thermostat
result = status(false, true, cmd->mfgSpecific);
break;
case ZCL_TRUSTED_ROOT_CERTIFICATES_CLUSTER_ID:
result = emberAfTrustedRootCertificatesClusterServerCommandParse(cmd);
break;
case ZCL_WIFI_NETWORK_DIAGNOSTICS_CLUSTER_ID:
// No commands are enabled for cluster WiFi Network Diagnostics
result = status(false, true, cmd->mfgSpecific);
Expand Down Expand Up @@ -2642,3 +2646,51 @@ EmberAfStatus emberAfTestClusterClusterServerCommandParse(EmberAfClusterCommand
}
return status(wasHandled, true, cmd->mfgSpecific);
}
EmberAfStatus emberAfTrustedRootCertificatesClusterServerCommandParse(EmberAfClusterCommand * cmd)
{
bool wasHandled = false;

if (!cmd->mfgSpecific)
{
switch (cmd->commandId)
{
case ZCL_ADD_TRUSTED_ROOT_CERTIFICATE_COMMAND_ID: {
uint16_t payloadOffset = cmd->payloadStartIndex;
chip::ByteSpan RootCertificate;

if (cmd->bufLen < payloadOffset + 1u)
{
return EMBER_ZCL_STATUS_MALFORMED_COMMAND;
}
{
uint8_t * rawData = emberAfGetString(cmd->buffer, payloadOffset, cmd->bufLen);
RootCertificate = chip::ByteSpan(rawData + 1u, emberAfStringLength(rawData));
}

wasHandled = emberAfTrustedRootCertificatesClusterAddTrustedRootCertificateCallback(nullptr, RootCertificate);
break;
}
case ZCL_REMOVE_TRUSTED_ROOT_CERTIFICATE_COMMAND_ID: {
uint16_t payloadOffset = cmd->payloadStartIndex;
chip::ByteSpan TrustedRootIdentifier;

if (cmd->bufLen < payloadOffset + 1u)
{
return EMBER_ZCL_STATUS_MALFORMED_COMMAND;
}
{
uint8_t * rawData = emberAfGetString(cmd->buffer, payloadOffset, cmd->bufLen);
TrustedRootIdentifier = chip::ByteSpan(rawData + 1u, emberAfStringLength(rawData));
}

wasHandled = emberAfTrustedRootCertificatesClusterRemoveTrustedRootCertificateCallback(nullptr, TrustedRootIdentifier);
break;
}
default: {
// Unrecognized command ID, error status will apply.
break;
}
}
}
return status(wasHandled, true, cmd->mfgSpecific);
}
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,9 @@ void emberAfClusterInitCallback(EndpointId endpoint, ClusterId clusterId)
case ZCL_THERMOSTAT_CLUSTER_ID:
emberAfThermostatClusterInitCallback(endpoint);
break;
case ZCL_TRUSTED_ROOT_CERTIFICATES_CLUSTER_ID:
emberAfTrustedRootCertificatesClusterInitCallback(endpoint);
break;
case ZCL_WIFI_NETWORK_DIAGNOSTICS_CLUSTER_ID:
emberAfWiFiNetworkDiagnosticsClusterInitCallback(endpoint);
break;
Expand Down Expand Up @@ -238,6 +241,11 @@ void __attribute__((weak)) emberAfThermostatClusterInitCallback(EndpointId endpo
// To prevent warning
(void) endpoint;
}
void __attribute__((weak)) emberAfTrustedRootCertificatesClusterInitCallback(EndpointId endpoint)
{
// To prevent warning
(void) endpoint;
}
void __attribute__((weak)) emberAfWiFiNetworkDiagnosticsClusterInitCallback(EndpointId endpoint)
{
// To prevent warning
Expand Down
Loading

0 comments on commit 1265219

Please sign in to comment.