Skip to content

Commit

Permalink
Merge 9f6b792 into 479ca01
Browse files Browse the repository at this point in the history
  • Loading branch information
lpbeliveau-silabs authored Mar 24, 2023
2 parents 479ca01 + 9f6b792 commit 1189732
Show file tree
Hide file tree
Showing 17 changed files with 3,052 additions and 5 deletions.
10 changes: 9 additions & 1 deletion scripts/examples/gn_efr32_example.sh
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,10 @@ else
shift
while [ $# -gt 0 ]; do
case $1 in
--clean)
DIR_CLEAN=true
shift
;;
--wifi)
if [ -z "$2" ]; then
echo "--wifi requires rs9116 or SiWx917 or wf200"
Expand Down Expand Up @@ -214,7 +218,6 @@ else
if [ "$1" =~ *"use_rs9116=true"* ] || [ "$1" =~ *"use_SiWx917=true"* ] || [ "$1" =~ *"use_wf200=true"* ]; then
USE_WIFI=true
fi

optArgs+=$1" "
shift
;;
Expand All @@ -236,6 +239,11 @@ else

BUILD_DIR=$OUTDIR/$SILABS_BOARD
echo BUILD_DIR="$BUILD_DIR"

if [ "$DIR_CLEAN" == true ]; then
rm -rf "$BUILD_DIR"
fi

if [ "$USE_WIFI" == true ]; then
# wifi build
# NCP mode EFR32 + wifi module
Expand Down
6 changes: 6 additions & 0 deletions src/app/chip_data_model.gni
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,12 @@ template("chip_data_model") {
"${_app_root}/clusters/identify-server/identify-server.h",
"${_app_root}/clusters/level-control/level-control.h",
"${_app_root}/clusters/on-off-server/on-off-server.h",
"${_app_root}/clusters/scenes/ExtensionFieldSets.h",
"${_app_root}/clusters/scenes/ExtensionFieldSetsImpl.cpp",
"${_app_root}/clusters/scenes/ExtensionFieldSetsImpl.h",
"${_app_root}/clusters/scenes/SceneTable.h",
"${_app_root}/clusters/scenes/SceneTableImpl.cpp",
"${_app_root}/clusters/scenes/SceneTableImpl.h",
"${_app_root}/clusters/scenes/scenes-tokens.h",
"${_app_root}/clusters/scenes/scenes.h",
"${_app_root}/util/ClientMonitoringRegistrationTable.cpp",
Expand Down
34 changes: 34 additions & 0 deletions src/app/clusters/scenes/BUILD.gn
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Copyright (c) 2023 Project CHIP Authors
#
# 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.
import("//build_overrides/chip.gni")

static_library("scenes") {
output_name = "libCHIPScenes"

sources = [
"ExtensionFieldSets.h",
"ExtensionFieldSetsImpl.cpp",
"ExtensionFieldSetsImpl.h",
"SceneTable.h",
"SceneTableImpl.cpp",
"SceneTableImpl.h",
]

deps = [ "${chip_root}/src/app" ]

cflags = [
"-Wconversion",
"-Wshadow",
]
}
48 changes: 48 additions & 0 deletions src/app/clusters/scenes/ExtensionFieldSets.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/**
*
* Copyright (c) 2023 Project CHIP Authors
*
* 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.
*/

#pragma once

#include <lib/core/CHIPError.h>
#include <lib/core/TLV.h>

namespace chip {
namespace scenes {

static constexpr uint8_t kInvalidPosition = 0xff;
static constexpr uint8_t kMaxClustersPerScene = CHIP_CONFIG_SCENES_MAX_CLUSTERS_PER_SCENE;
static constexpr uint8_t kMaxFieldBytesPerCluster = CHIP_CONFIG_SCENES_MAX_EXTENSION_FIELDSET_SIZE_PER_CLUSTER;

/// @brief A way to serialize and deserialize all cluster attribute data for a scene.
class ExtensionFieldSets
{
public:
ExtensionFieldSets(){};
virtual ~ExtensionFieldSets() = default;

virtual CHIP_ERROR Serialize(TLV::TLVWriter & writer, TLV::Tag structTa) const = 0;
virtual CHIP_ERROR Deserialize(TLV::TLVReader & reader, TLV::Tag structTa) = 0;
virtual void Clear() = 0;
virtual bool IsEmpty() const = 0;
/// @brief Gets a count of how many initialized fields sets are in the object
/// @return The number of initialized field sets the object
/// @note Field set refers to extension field sets, from the scene cluster (see 1.4.6.2 ExtensionFieldSet in Matter Application
/// Clusters)
virtual uint8_t GetFieldSetCount() const = 0;
};
} // namespace scenes
} // namespace chip
154 changes: 154 additions & 0 deletions src/app/clusters/scenes/ExtensionFieldSetsImpl.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
/*
*
* Copyright (c) 2023 Project CHIP Authors
*
* 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 "ExtensionFieldSetsImpl.h"

namespace chip {
namespace scenes {

// ExtensionFieldSetsImpl::ExtensionFieldSetsImpl() : ExtensionFieldSets() {}

CHIP_ERROR ExtensionFieldSetsImpl::Serialize(TLV::TLVWriter & writer, TLV::Tag structTag) const
{
TLV::TLVType structureContainer;
ReturnErrorOnFailure(writer.StartContainer(structTag, TLV::kTLVType_Structure, structureContainer));
TLV::TLVType arrayContainer;
ReturnErrorOnFailure(
writer.StartContainer(TLV::ContextTag(TagEFS::kFieldSetArrayContainer), TLV::kTLVType_Array, arrayContainer));
for (uint8_t i = 0; i < mFieldSetsCount; i++)
{
ReturnErrorOnFailure(mFieldSets[i].Serialize(writer));
}

ReturnErrorOnFailure(writer.EndContainer(arrayContainer));
return writer.EndContainer(structureContainer);
}

CHIP_ERROR ExtensionFieldSetsImpl::Deserialize(TLV::TLVReader & reader, TLV::Tag structTag)
{
TLV::TLVType structureContainer;
ReturnErrorOnFailure(reader.Next(TLV::kTLVType_Structure, structTag));
ReturnErrorOnFailure(reader.EnterContainer(structureContainer));

TLV::TLVType arrayContainer;
ReturnErrorOnFailure(reader.Next(TLV::kTLVType_Array, TLV::ContextTag(TagEFS::kFieldSetArrayContainer)));
ReturnErrorOnFailure(reader.EnterContainer(arrayContainer));

uint8_t i = 0;
CHIP_ERROR err;
while ((err = reader.Next(TLV::AnonymousTag())) == CHIP_NO_ERROR && i < kMaxClustersPerScene)
{
ReturnErrorOnFailure(mFieldSets[i].Deserialize(reader));
i++;
}
mFieldSetsCount = i;

// In the event of an OTA where the maximum number of clusters per scene has been reduced, the extension field set will be
// considered "corrupted" if we don't manage to load it all (if err == CHIP_NO_ERROR after the loop). We therefore return an
// error and this scene will have to be deleted. This is done because truncating an EFS doesn't guarantee the order of the
// clusters loaded, which might lead to loading clusters that are no longer supported and losing supported ones.
if (err != CHIP_END_OF_TLV)
{
if (err == CHIP_NO_ERROR)
return CHIP_ERROR_BUFFER_TOO_SMALL;

return err;
}

ReturnErrorOnFailure(reader.ExitContainer(arrayContainer));
return reader.ExitContainer(structureContainer);
}

void ExtensionFieldSetsImpl::Clear()
{
for (uint8_t i = 0; i < mFieldSetsCount; i++)
{
mFieldSets[i].Clear();
}

mFieldSetsCount = 0;
}

/// @brief Inserts a field Set set into the array of extension field Set sets for a scene entry.
/// If the same ID is present in the EFS array, it will overwrite it.
/// @param fieldSet field set to be inserted
/// @return CHIP_NO_ERROR if insertion worked, CHIP_ERROR_NO_MEMORY if the array is already full
CHIP_ERROR ExtensionFieldSetsImpl::InsertFieldSet(const ExtensionFieldSet & fieldSet)
{
uint8_t firstEmptyPosition = kInvalidPosition;

VerifyOrReturnError(fieldSet.mID != kInvalidClusterId, CHIP_ERROR_INVALID_ARGUMENT);
VerifyOrReturnError(!fieldSet.IsEmpty(), CHIP_ERROR_INVALID_ARGUMENT);

for (uint8_t i = 0; i < kMaxClustersPerScene; i++)
{
if (mFieldSets[i].mID == fieldSet.mID)
{
mFieldSets[i] = fieldSet;
return CHIP_NO_ERROR;
}

if (mFieldSets[i].IsEmpty() && firstEmptyPosition == kInvalidPosition)
{
firstEmptyPosition = i;
}
}

// if found, replace at found position, otherwise insert at first free position, otherwise return error
if (firstEmptyPosition < kMaxClustersPerScene)
{
mFieldSets[firstEmptyPosition] = fieldSet;
mFieldSetsCount++;
return CHIP_NO_ERROR;
}

return CHIP_ERROR_NO_MEMORY;
}

CHIP_ERROR ExtensionFieldSetsImpl::GetFieldSetAtPosition(ExtensionFieldSet & fieldSet, uint8_t position) const
{
VerifyOrReturnError(position < mFieldSetsCount, CHIP_ERROR_BUFFER_TOO_SMALL);

fieldSet = mFieldSets[position];

return CHIP_NO_ERROR;
}

CHIP_ERROR ExtensionFieldSetsImpl::RemoveFieldAtPosition(uint8_t position)
{
VerifyOrReturnValue(position < mFieldSetsCount, CHIP_NO_ERROR);

uint8_t nextPos = static_cast<uint8_t>(position + 1);
uint8_t moveNum = static_cast<uint8_t>(kMaxClustersPerScene - nextPos);

// TODO: Implement general array management methods
// Compress array after removal, if the removed position is not the last
if (moveNum)
{
memmove(&mFieldSets[position], &mFieldSets[nextPos], sizeof(ExtensionFieldSet) * moveNum);
}

mFieldSetsCount--;
// Clear last occupied position
mFieldSets[mFieldSetsCount].Clear();

return CHIP_NO_ERROR;
}

} // namespace scenes

} // namespace chip
Loading

0 comments on commit 1189732

Please sign in to comment.