Skip to content

Commit 36c76e6

Browse files
andy31415restyled-commitsandreilitvintehampson
authored
Define a IM/DM decoupling interface for interaction model engine to interact with the data model bits (#32914)
* Start adding a interaction model decoupling * Restyle * Also add invoke responder bits * Add the first model definition, for each operation * Add all files into the build definition * Start adding the side effect support classes to the interaction model definitions * Add actions and integrate them to the IM model * Add iteration methods * Restyle * Add all files to the build definition * Start defining a unit test to at least validate compilation. Will later validate that we get events emitted * Fix a dependency * Move EventLoggingDelegate to be part of "events" in app. - Remove unneeded includes from this header - add dependency to core (due to TLV) * Prepare for testing ... does not compile however TODOs are starting to go away * Fix SFINAE logic on eventing * test that something is actually emitted for events * Tests actually do something * Some tests actually pass * Restyle * Minor style updates * Rename EmitEvent to GenerateEvent * Add description for paths * Cleanup some example text ... we do not need an exhaustive usage list * Restyle * Fix spelling * Renames based on code review: use UpperCamelCase * Updated proposal for retries and paths * Restyle * one more comment * Restyled by clang-format * Fix typo in parameter type * Some updates for code review * Undo submodule update * Fix logic error in buffer-too-small check for buffer data * Fix return error code when send encounters an error * Fix logic for mCompleted handling in the auto-complete handling * More comments * Comments * Use AAI types for interaction model. I think they will need some splitting, however for now they seem to be a solid catch-all * Update some naming to not use the a... syntax since those are odd * Code review updates * Added extra comment * Enforce lifetime in invoke responses * More comments * More comments * Restyle * Added comment on replyasync with nullptr * Update src/app/interaction-model/InvokeResponder.h Co-authored-by: Terence Hampson <thampson@google.com> * Update src/app/interaction-model/InvokeResponder.h Co-authored-by: Terence Hampson <thampson@google.com> * Update src/app/interaction-model/InvokeResponder.h Co-authored-by: Terence Hampson <thampson@google.com> * Update src/app/interaction-model/InvokeResponder.h Co-authored-by: Terence Hampson <thampson@google.com> * Some code review updates * Some code review updates * Make the subject descriptor optional * use std::optional instead of chip optiona * Restyle --------- Co-authored-by: Restyled.io <commits@restyled.io> Co-authored-by: Andrei Litvin <andreilitvin@google.com> Co-authored-by: Terence Hampson <thampson@google.com>
1 parent f4a7cb4 commit 36c76e6

12 files changed

+1114
-0
lines changed

src/BUILD.gn

+1
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ if (chip_build_tests) {
5555
chip_test_group("tests") {
5656
deps = []
5757
tests = [
58+
"${chip_root}/src/app/interaction-model/tests",
5859
"${chip_root}/src/access/tests",
5960
"${chip_root}/src/crypto/tests",
6061
"${chip_root}/src/inet/tests",

src/app/interaction-model/Actions.h

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/*
2+
* Copyright (c) 2024 Project CHIP Authors
3+
* All rights reserved.
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
#pragma once
18+
19+
#include <app/interaction-model/Events.h>
20+
#include <app/interaction-model/Paths.h>
21+
#include <app/interaction-model/RequestContext.h>
22+
23+
namespace chip {
24+
namespace app {
25+
namespace InteractionModel {
26+
27+
/// Data provided to data models in order to interface with the interaction model environment.
28+
struct InteractionModelActions
29+
{
30+
Events * events;
31+
Paths * paths;
32+
RequestContext * requestContext;
33+
};
34+
35+
} // namespace InteractionModel
36+
} // namespace app
37+
} // namespace chip

src/app/interaction-model/BUILD.gn

+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# Copyright (c) 2024 Project CHIP Authors
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
import("//build_overrides/chip.gni")
15+
16+
source_set("interaction-model") {
17+
sources = [
18+
"Actions.h",
19+
"Events.h",
20+
"InvokeResponder.h",
21+
"IterationTypes.h",
22+
"Model.h",
23+
"OperationTypes.h",
24+
"Paths.h",
25+
"RequestContext.h",
26+
]
27+
28+
public_deps = [
29+
"${chip_root}/src/access:types",
30+
"${chip_root}/src/app:attribute-access",
31+
"${chip_root}/src/app:events",
32+
"${chip_root}/src/app:paths",
33+
"${chip_root}/src/app/MessageDef",
34+
"${chip_root}/src/app/data-model",
35+
"${chip_root}/src/lib/core",
36+
"${chip_root}/src/lib/core:error",
37+
"${chip_root}/src/lib/core:types",
38+
"${chip_root}/src/lib/support",
39+
"${chip_root}/src/messaging",
40+
]
41+
}

src/app/interaction-model/Events.h

+130
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
/*
2+
* Copyright (c) 2024 Project CHIP Authors
3+
* All rights reserved.
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
#pragma once
18+
19+
#include <app/EventLoggingDelegate.h>
20+
#include <app/EventLoggingTypes.h>
21+
#include <app/MessageDef/EventDataIB.h>
22+
#include <app/data-model/Encode.h>
23+
#include <app/data-model/FabricScoped.h>
24+
#include <lib/core/CHIPError.h>
25+
#include <lib/support/logging/CHIPLogging.h>
26+
27+
#include <type_traits>
28+
29+
namespace chip {
30+
namespace app {
31+
namespace InteractionModel {
32+
33+
namespace internal {
34+
template <typename T>
35+
class SimpleEventLoggingDelegate : public EventLoggingDelegate
36+
{
37+
public:
38+
SimpleEventLoggingDelegate(const T & aEventData) : mEventData(aEventData){};
39+
CHIP_ERROR WriteEvent(chip::TLV::TLVWriter & aWriter) final override
40+
{
41+
return DataModel::Encode(aWriter, TLV::ContextTag(EventDataIB::Tag::kData), mEventData);
42+
}
43+
44+
private:
45+
const T & mEventData;
46+
};
47+
48+
template <typename E, typename T, std::enable_if_t<DataModel::IsFabricScoped<T>::value, bool> = true>
49+
EventNumber GenerateEvent(E & emittor, const T & aEventData, EndpointId aEndpoint)
50+
{
51+
internal::SimpleEventLoggingDelegate<T> eventData(aEventData);
52+
ConcreteEventPath path(aEndpoint, aEventData.GetClusterId(), aEventData.GetEventId());
53+
EventOptions eventOptions;
54+
eventOptions.mPath = path;
55+
eventOptions.mPriority = aEventData.GetPriorityLevel();
56+
eventOptions.mFabricIndex = aEventData.GetFabricIndex();
57+
58+
// this skips logging the event if it's fabric-scoped but no fabric association exists yet.
59+
60+
if (eventOptions.mFabricIndex == kUndefinedFabricIndex)
61+
{
62+
ChipLogError(EventLogging, "Event encode failure: no fabric index for fabric scoped event");
63+
return kInvalidEventId;
64+
}
65+
66+
//
67+
// Unlike attributes which have a different 'EncodeForRead' for fabric-scoped structs,
68+
// fabric-sensitive events don't require that since the actual omission of the event in its entirety
69+
// happens within the event management framework itself at the time of access.
70+
//
71+
// The 'mFabricIndex' field in the event options above is encoded out-of-band alongside the event payload
72+
// and used to match against the accessing fabric.
73+
//
74+
EventNumber eventNumber;
75+
CHIP_ERROR err = emittor.GenerateEvent(&eventData, eventOptions, eventNumber);
76+
if (err != CHIP_NO_ERROR)
77+
{
78+
ChipLogError(EventLogging, "Failed to log event: %" CHIP_ERROR_FORMAT, err.Format());
79+
return kInvalidEventId;
80+
}
81+
82+
return eventNumber;
83+
}
84+
85+
template <typename E, typename T, std::enable_if_t<!DataModel::IsFabricScoped<T>::value, bool> = true>
86+
EventNumber GenerateEvent(E & emittor, const T & aEventData, EndpointId endpointId)
87+
{
88+
internal::SimpleEventLoggingDelegate<T> eventData(aEventData);
89+
ConcreteEventPath path(endpointId, aEventData.GetClusterId(), aEventData.GetEventId());
90+
EventOptions eventOptions;
91+
eventOptions.mPath = path;
92+
eventOptions.mPriority = aEventData.GetPriorityLevel();
93+
EventNumber eventNumber;
94+
CHIP_ERROR err = emittor.GenerateEvent(&eventData, eventOptions, eventNumber);
95+
if (err != CHIP_NO_ERROR)
96+
{
97+
ChipLogError(EventLogging, "Failed to log event: %" CHIP_ERROR_FORMAT, err.Format());
98+
return kInvalidEventId;
99+
}
100+
101+
return eventNumber;
102+
}
103+
104+
} // namespace internal
105+
106+
class Events
107+
{
108+
public:
109+
virtual ~Events() = default;
110+
111+
/// Generates the given event.
112+
///
113+
/// Events are generally expected to be sent to subscribed clients and also
114+
/// be available for read later until they get overwritten by new events
115+
/// that are being generated.
116+
virtual CHIP_ERROR GenerateEvent(EventLoggingDelegate * eventContentWriter, const EventOptions & options,
117+
EventNumber & generatedEventNumber) = 0;
118+
119+
// Convenience methods for event logging using cluster-object structures
120+
// On error, these log and return kInvalidEventId
121+
template <typename T>
122+
EventNumber GenerateEvent(const T & eventData, EndpointId endpointId)
123+
{
124+
return internal::GenerateEvent(*this, eventData, endpointId);
125+
}
126+
};
127+
128+
} // namespace InteractionModel
129+
} // namespace app
130+
} // namespace chip

0 commit comments

Comments
 (0)