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

Add support for pre-encoded things in AttributeAccessInterface. #31639

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
4 changes: 4 additions & 0 deletions src/app/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,10 @@ static_library("app") {
"TimerDelegates.h",
"WriteClient.cpp",
"WriteHandler.cpp",
"data-model/FabricScopedPreEncodedValue.cpp",
"data-model/FabricScopedPreEncodedValue.h",
"data-model/PreEncodedValue.cpp",
"data-model/PreEncodedValue.h",
"reporting/Engine.cpp",
"reporting/Engine.h",
"reporting/ReportScheduler.h",
Expand Down
103 changes: 103 additions & 0 deletions src/app/data-model/FabricScopedPreEncodedValue.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
/*
* Copyright (c) 2024 Project CHIP Authors
* All rights reserved.
*
* 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.
*/

#include "FabricScopedPreEncodedValue.h"
#include <lib/core/TLVReader.h>
#include <lib/support/CodeUtils.h>

#include <optional>

namespace chip {
namespace app {
namespace DataModel {

FabricScopedPreEncodedValue::FabricScopedPreEncodedValue(const ByteSpan & aData) : mData(aData) {}

CHIP_ERROR FabricScopedPreEncodedValue::EncodeForRead(TLV::TLVWriter & aWriter, TLV::Tag aTag, FabricIndex aFabricIndex) const
{
TLV::TLVReader reader;
reader.Init(mData);

ReturnErrorOnFailure(reader.Next());

return aWriter.CopyElement(aTag, reader);
}

FabricIndex FabricScopedPreEncodedValue::GetFabricIndex() const
{
TLV::TLVReader reader;
reader.Init(mData);
CHIP_ERROR err = reader.Next();
if (err != CHIP_NO_ERROR)
{
return kUndefinedFabricIndex;
}

// We must have a struct here.
if (reader.GetType() != TLV::kTLVType_Structure)
{
return kUndefinedFabricIndex;
}

TLV::TLVType structType;
err = reader.EnterContainer(structType);
if (err != CHIP_NO_ERROR)
{
return kUndefinedFabricIndex;
}

// Now look for a single field with the right tag.
std::optional<FabricIndex> foundFabricIndex;
constexpr TLV::Tag kFabricIndexTag = TLV::ContextTag(254);
while ((err = reader.Next()) == CHIP_NO_ERROR)
{
if (reader.GetTag() != kFabricIndexTag)
{
continue;
}

if (foundFabricIndex.has_value())
{
// Two fabric indices? Just give up. Note that this will lead to
// errors encoding our value.
return kUndefinedFabricIndex;
}

err = reader.Get(foundFabricIndex.emplace());
if (err != CHIP_NO_ERROR)
{
return kUndefinedFabricIndex;
}
}

if (err != CHIP_ERROR_END_OF_TLV)
{
return kUndefinedFabricIndex;
}

err = reader.ExitContainer(structType);
if (err != CHIP_NO_ERROR)
{
return kUndefinedFabricIndex;
}

return foundFabricIndex.value_or(kUndefinedFabricIndex);
}

} // namespace DataModel
} // namespace app
} // namespace chip
58 changes: 58 additions & 0 deletions src/app/data-model/FabricScopedPreEncodedValue.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/*
* Copyright (c) 2024 Project CHIP Authors
* All rights reserved.
*
* 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.
*/

#include <lib/core/CHIPError.h>
#include <lib/core/DataModelTypes.h>
#include <lib/core/TLVTags.h>
#include <lib/core/TLVWriter.h>

namespace chip {
namespace app {
namespace DataModel {

/**
* FabridScopedPreEncodedValue represents the value of a single item in a list
* of fabric-scoped structs that has already been encoded as TLV. To enable
* reading these values successfully, the struct must have the fabric index it
* corresponds to encoded with the right tag.
*
* Note: Fabric-sensitive fields are currently not supported; there is no way to
* specify which fields are fabric-sensitive.
*/
class FabricScopedPreEncodedValue
{
public:
/**
* The data buffer backing the ByteSpan must outlive the
* FabricScopedPreEncodedValue instance.
*/
FabricScopedPreEncodedValue(const ByteSpan & aData);

/**
* Encodable object API implementation.
*/
static constexpr bool kIsFabricScoped = true;
CHIP_ERROR EncodeForRead(TLV::TLVWriter & aWriter, TLV::Tag aTag, FabricIndex aFabricIndex) const;
FabricIndex GetFabricIndex() const;

private:
const ByteSpan mData;
};

} // namespace DataModel
} // namespace app
} // namespace chip
40 changes: 40 additions & 0 deletions src/app/data-model/PreEncodedValue.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
* Copyright (c) 2024 Project CHIP Authors
* All rights reserved.
*
* 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.
*/

#include "PreEncodedValue.h"
#include <lib/core/TLVReader.h>
#include <lib/support/CodeUtils.h>

namespace chip {
namespace app {
namespace DataModel {

PreEncodedValue::PreEncodedValue(const ByteSpan & aData) : mData(aData) {}

CHIP_ERROR PreEncodedValue::Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const
{
TLV::TLVReader reader;
reader.Init(mData);

ReturnErrorOnFailure(reader.Next());

return aWriter.CopyElement(aTag, reader);
}

} // namespace DataModel
} // namespace app
} // namespace chip
52 changes: 52 additions & 0 deletions src/app/data-model/PreEncodedValue.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/*
* Copyright (c) 2024 Project CHIP Authors
* All rights reserved.
*
* 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.
*/

#include <lib/core/CHIPError.h>
#include <lib/core/TLVTags.h>
#include <lib/core/TLVWriter.h>

namespace chip {
namespace app {
namespace DataModel {

/**
* PreEncodedValue represents the value of an attribute or the value of a single
* item in a list of non-fabric-scoped structs that has already been
* encoded as TLV.
*/
class PreEncodedValue
{
public:
/**
* The data buffer backing the ByteSpan must outlive the PreEncodedValue
* instance.
*/
PreEncodedValue(const ByteSpan & aData);

/**
* Encodable object API implementation.
*/
static constexpr bool kIsFabricScoped = false;
CHIP_ERROR Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const;

private:
const ByteSpan mData;
};

} // namespace DataModel
} // namespace app
} // namespace chip
Loading
Loading