Skip to content

Commit

Permalink
A first pass at decoupling the AttributeAccessOverride
Browse files Browse the repository at this point in the history
  • Loading branch information
andy31415 committed Apr 11, 2024
1 parent 9be88c2 commit 2005001
Show file tree
Hide file tree
Showing 20 changed files with 248 additions and 24 deletions.
126 changes: 126 additions & 0 deletions src/app/AttributeAccessInterfaceRegistry.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
/**
* Copyright (c) 2024 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 <app/AttributeAccessInterfaceRegistry.h>

#include <app/AttributeAccessInterfaceCache.h>

using namespace chip::app;

namespace {

AttributeAccessInterface * gAttributeAccessOverrides = nullptr;
AttributeAccessInterfaceCache gAttributeAccessInterfaceCache;

// shouldUnregister returns true if the given AttributeAccessInterface should be
// unregistered.
template <typename F>
void UnregisterMatchingAttributeAccessInterfaces(F shouldUnregister)
{
AttributeAccessInterface * prev = nullptr;
AttributeAccessInterface * cur = gAttributeAccessOverrides;
while (cur)
{
AttributeAccessInterface * next = cur->GetNext();
if (shouldUnregister(cur))
{
// Remove it from the list
if (prev)
{
prev->SetNext(next);
}
else
{
gAttributeAccessOverrides = next;
}

cur->SetNext(nullptr);

// Do not change prev in this case.
}
else
{
prev = cur;
}
cur = next;
}
}

} // namespace

void unregisterAttributeAccessOverride(AttributeAccessInterface * attrOverride)
{
gAttributeAccessInterfaceCache.Invalidate();
UnregisterMatchingAttributeAccessInterfaces([attrOverride](AttributeAccessInterface * entry) { return entry == attrOverride; });
}

void unregisterAttributeAccessOverrideForEndpoint(EmberAfDefinedEndpoint * definedEndpoint)
{
UnregisterMatchingAttributeAccessInterfaces(
[endpoint = definedEndpoint->endpoint](AttributeAccessInterface * entry) { return entry->MatchesEndpoint(endpoint); });
}

bool registerAttributeAccessOverride(AttributeAccessInterface * attrOverride)
{
gAttributeAccessInterfaceCache.Invalidate();
for (auto * cur = gAttributeAccessOverrides; cur; cur = cur->GetNext())
{
if (cur->Matches(*attrOverride))
{
ChipLogError(Zcl, "Duplicate attribute override registration failed");
return false;
}
}
attrOverride->SetNext(gAttributeAccessOverrides);
gAttributeAccessOverrides = attrOverride;
return true;
}

namespace chip {
namespace app {

app::AttributeAccessInterface * GetAttributeAccessOverride(EndpointId endpointId, ClusterId clusterId)
{
using CacheResult = AttributeAccessInterfaceCache::CacheResult;

AttributeAccessInterface * cached = nullptr;
CacheResult result = gAttributeAccessInterfaceCache.Get(endpointId, clusterId, &cached);
switch (result)
{
case CacheResult::kDefinitelyUnused:
return nullptr;
case CacheResult::kDefinitelyUsed:
return cached;
case CacheResult::kCacheMiss:
default:
// Did not cache yet, search set of AAI registered, and cache if found.
for (app::AttributeAccessInterface * cur = gAttributeAccessOverrides; cur; cur = cur->GetNext())
{
if (cur->Matches(endpointId, clusterId))
{
gAttributeAccessInterfaceCache.MarkUsed(endpointId, clusterId, cur);
return cur;
}
}

// Did not find AAI registered: mark as definitely not using.
gAttributeAccessInterfaceCache.MarkUnused(endpointId, clusterId);
}

return nullptr;
}

} // namespace app
} // namespace chip
54 changes: 54 additions & 0 deletions src/app/AttributeAccessInterfaceRegistry.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/**
* Copyright (c) 2024 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 <app/util/af-types.h>
#include <app/AttributeAccessInterface.h>

/**
* Register an attribute access override. It will remain registered until the
* endpoint it's registered for is disabled (or until shutdown if it's
* registered for all endpoints) or until it is explicitly unregistered.
* Registration will fail if there is an already-registered override for the
* same set of attributes.
*
* @return false if there is an existing override that the new one would
* conflict with. In this case the override is not registered.
* @return true if registration was successful.
*/
bool registerAttributeAccessOverride(chip::app::AttributeAccessInterface * attrOverride);

/**
* Unregister an attribute access override (for example if the object
* implementing AttributeAccessInterface is being destroyed).
*/
void unregisterAttributeAccessOverride(chip::app::AttributeAccessInterface * attrOverride);

/**
* Unregister all attribute access interfaces that match this given endpoint.
*/
void unregisterAttributeAccessOverrideForEndpoint(EmberAfDefinedEndpoint *definedEndpoint);

namespace chip {
namespace app {

/**
* Get the registered attribute access override. nullptr when attribute access override is not found.
*/
AttributeAccessInterface * GetAttributeAccessOverride(EndpointId aEndpointId, ClusterId aClusterId);

} // namespace app
} // namespace chip
34 changes: 27 additions & 7 deletions src/app/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -275,14 +275,38 @@ source_set("events") {
]
}

static_library("attribute-access") {
sources = [
"AttributeAccessInterfaceCache.h",
"AttributeAccessInterface.cpp",
"AttributeAccessInterface.h",
"AttributeAccessInterfaceRegistry.cpp",
"AttributeAccessInterfaceRegistry.h",
]

# TODO: double-check if this is still a thing:
# TODO: the following items cannot be included due to platform includes not being
# able to depend on src/app
# Name with _ so that linter does not recognize it
# "_AttributeAccessInterface._h",

deps = [
":paths",
"${chip_root}/src/access:types",
"${chip_root}/src/app/data-model",
"${chip_root}/src/app/MessageDef",
"${chip_root}/src/app/util:af-types",
"${chip_root}/src/lib/core",
"${chip_root}/src/lib/support",
]
}

# Note to developpers, instead of continuously adding files in the app librabry, it is recommand to create smaller source_sets that app can depend on.
# This way, we can have a better understanding of dependencies and other componenets can depend on the different source_sets without needing to depend on the entire app library.
static_library("app") {
output_name = "libCHIPDataModel"

sources = [
"AttributeAccessInterface.cpp",
"AttributeAccessInterfaceCache.h",
"AttributePathExpandIterator.cpp",
"AttributePathExpandIterator.h",
"AttributePersistenceProvider.h",
Expand Down Expand Up @@ -315,18 +339,14 @@ static_library("app") {
# "CommandHandler._h"
# "ReadHandler._h",
# "WriteHandler._h"

# TODO: the following items cannot be included due to platform includes not being
# able to depend on src/app
# Name with _ so that linter does not recognize it
# "_AttributeAccessInterface._h",
]

public_deps = [
":app_config",
":constants",
":global-attributes",
":interaction-model",
":attribute-access",
"${chip_root}/src/app/data-model",
"${chip_root}/src/app/icd/server:icd-server-config",
"${chip_root}/src/app/util:callbacks",
Expand Down
1 change: 1 addition & 0 deletions src/app/InteractionModelEngine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
#include "access/SubjectDescriptor.h"
#include <app/AppConfig.h>
#include <app/RequiredPrivilege.h>
#include <app/util/IMClusterCommandHandler.h>
#include <app/util/af-types.h>
#include <app/util/ember-compatibility-functions.h>
#include <app/util/endpoint-config-api.h>
Expand Down
4 changes: 0 additions & 4 deletions src/app/InteractionModelEngine.h
Original file line number Diff line number Diff line change
Expand Up @@ -712,9 +712,5 @@ class InteractionModelEngine : public Messaging::UnsolicitedMessageHandler,
uint32_t mMagic = 0;
};

void DispatchSingleClusterCommand(const ConcreteCommandPath & aCommandPath, chip::TLV::TLVReader & aReader,
CommandHandler * apCommandObj);


} // namespace app
} // namespace chip
1 change: 1 addition & 0 deletions src/app/WriteHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

#include "messaging/ExchangeContext.h"
#include <app/AppConfig.h>
#include <app/AttributeAccessInterfaceRegistry.h>
#include <app/InteractionModelEngine.h>
#include <app/MessageDef/EventPathIB.h>
#include <app/StatusResponse.h>
Expand Down
1 change: 0 additions & 1 deletion src/app/icd/server/ICDManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@
#include <platform/ConnectivityManager.h>
#include <platform/LockTracker.h>
#include <platform/internal/CHIPDeviceLayerInternal.h>
#include <stdlib.h>

namespace {
enum class ICDTestEventTriggerEvent : uint64_t
Expand Down
2 changes: 1 addition & 1 deletion src/app/icd/server/ICDManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,14 @@
#include <app/icd/server/ICDServerConfig.h>

#include <app-common/zap-generated/cluster-enums.h>
#include <app/AppConfig.h>
#include <app/SubscriptionsInfoProvider.h>
#include <app/TestEventTriggerDelegate.h>
#include <app/icd/server/ICDConfigurationData.h>
#include <app/icd/server/ICDNotifier.h>
#include <app/icd/server/ICDStateObserver.h>
#include <credentials/FabricTable.h>
#include <crypto/SessionKeystore.h>
#include <functional>
#include <lib/support/BitFlags.h>
#include <messaging/ExchangeMgr.h>
#include <platform/CHIPDeviceConfig.h>
Expand Down
38 changes: 38 additions & 0 deletions src/app/util/IMClusterCommandHandler.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*
* 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.
*/
#pragma once

#include <app/CommandHandler.h>
#include <app/ConcreteCommandPath.h>
#include <lib/core/TLVReader.h>

namespace chip {
namespace app {

/**
* Dispatch is generally implemented in code-generated code in ember within
* IMClusterCommandHandler.cpp
*
* aCommandPath - the path that is invoked
* aReader - the input TLV data for this command
* apCommandObj - how to send back the reply
*/
void DispatchSingleClusterCommand(const ConcreteCommandPath & aCommandPath, chip::TLV::TLVReader & aReader,
CommandHandler * apCommandObj);

} // namespace app
} // namespace chip
1 change: 0 additions & 1 deletion src/app/util/af-types.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
*/

#include <stdbool.h> // For bool
#include <stddef.h> // For NULL.
#include <stdint.h> // For various uint*_t types

#include <app/util/basic-types.h>
Expand Down
1 change: 0 additions & 1 deletion src/include/platform/ConnectivityManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
#pragma once
#include <memory>

#include <app/AttributeAccessInterface.h>
#include <app/icd/server/ICDServerConfig.h>
#include <inet/UDPEndPoint.h>
#include <lib/support/CodeUtils.h>
Expand Down
1 change: 0 additions & 1 deletion src/include/platform/ThreadStackManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@

#include <app/icd/server/ICDServerConfig.h>

#include <app/AttributeAccessInterface.h>
#include <app/util/basic-types.h>
#include <inet/IPAddress.h>
#include <lib/support/Span.h>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@

#pragma once
#include <app-common/zap-generated/ids/Attributes.h>
#include <app/AttributeAccessInterface.h>

namespace chip {
namespace DeviceLayer {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@

#pragma once

#include <app/AttributeAccessInterface.h>
#include <app/icd/server/ICDServerConfig.h>
#include <lib/support/BitFlags.h>
#include <platform/ThreadStackManager.h>
Expand Down
1 change: 0 additions & 1 deletion src/platform/Linux/ThreadStackManagerImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
#include <platform/internal/CHIPDeviceLayerInternal.h>
#include <platform/internal/DeviceNetworkInfo.h>

#include <app/AttributeAccessInterface.h>
#include <lib/support/CodeUtils.h>
#include <lib/support/logging/CHIPLogging.h>
#include <platform/GLibTypeDeleter.h>
Expand Down
1 change: 0 additions & 1 deletion src/platform/Linux/ThreadStackManagerImpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
#include <memory>
#include <vector>

#include <app/AttributeAccessInterface.h>
#include <app/icd/server/ICDServerConfig.h>
#include <lib/support/ThreadOperationalDataset.h>
#include <platform/GLibTypeDeleter.h>
Expand Down
1 change: 0 additions & 1 deletion src/platform/Tizen/ThreadStackManagerImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@
#include <thread.h>
#include <tizen_error.h>

#include <app/AttributeAccessInterface.h>
#include <inet/IPAddress.h>
#include <lib/core/CHIPError.h>
#include <lib/core/DataModelTypes.h>
Expand Down
Loading

0 comments on commit 2005001

Please sign in to comment.