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 1 commit
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
106 changes: 106 additions & 0 deletions src/app/data-model/FabricScopedPreEncodedValue.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
/*
* 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/support/CodeUtils.h>

#include <optional>

namespace chip {
namespace app {
namespace DataModel {

FabricScopedPreEncodedValue::FabricScopedPreEncodedValue(const ByteSpan & aData)
{
mReader.Init(aData);
bzbarsky-apple marked this conversation as resolved.
Show resolved Hide resolved
}

CHIP_ERROR FabricScopedPreEncodedValue::EncodeForRead(TLV::TLVWriter & aWriter, TLV::Tag aTag, FabricIndex aFabricIndex) const
{
// Clone our reader, since we need to do Next() to move to its first element
// but not change our state. And CopyElement needs a non-const reader
// anyway since it also changes reader state.
TLV::TLVReader reader(mReader);

ReturnErrorOnFailure(reader.Next());

return aWriter.CopyElement(aTag, reader);
}

FabricIndex FabricScopedPreEncodedValue::GetFabricIndex() const
{
TLV::TLVReader reader(mReader);
bzbarsky-apple marked this conversation as resolved.
Show resolved Hide resolved
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
59 changes: 59 additions & 0 deletions src/app/data-model/FabricScopedPreEncodedValue.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/*
* 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/TLVReader.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:
TLV::TLVReader mReader;
bzbarsky-apple marked this conversation as resolved.
Show resolved Hide resolved
};

} // namespace DataModel
} // namespace app
} // namespace chip
44 changes: 44 additions & 0 deletions src/app/data-model/PreEncodedValue.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
* 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/support/CodeUtils.h>

namespace chip {
namespace app {
namespace DataModel {

PreEncodedValue::PreEncodedValue(const ByteSpan & aData)
{
mReader.Init(aData);
}

CHIP_ERROR PreEncodedValue::Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const
{
// Clone our reader, since we need to do Next() to move to its first element
// but not change our state. And CopyElement needs a non-const reader
// anyway since it also changes reader state.
TLV::TLVReader reader(mReader);

ReturnErrorOnFailure(reader.Next());

return aWriter.CopyElement(aTag, reader);
}

} // namespace DataModel
} // namespace app
} // namespace chip
53 changes: 53 additions & 0 deletions src/app/data-model/PreEncodedValue.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/*
* 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/TLVReader.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:
TLV::TLVReader mReader;
};

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