Skip to content

Commit 13b502d

Browse files
andy31415andreilitvinbzbarsky-apple
authored
Post-merge updates for IM/DM separation (#33730)
* Some cleanup logic for event generation - naming and return values as eventid is not the same as event number * Comment fix * More naming updates * Several comment updates and renamed RequestContext to ActionContext * Restyle * Rename to InteractionModelContext * one more rename * Fix typo * Fix tests to compile * More renames of actions to context * One more comment added * Restyle * make clang-tidy happy * Operator== exists on optional ... make use of that directly * Update src/app/interaction-model/Events.h Co-authored-by: Boris Zbarsky <bzbarsky@apple.com> * Update src/app/interaction-model/IterationTypes.h Co-authored-by: Boris Zbarsky <bzbarsky@apple.com> * Update src/app/interaction-model/Paths.h Co-authored-by: Boris Zbarsky <bzbarsky@apple.com> * Comment update --------- Co-authored-by: Andrei Litvin <andreilitvin@google.com> Co-authored-by: Boris Zbarsky <bzbarsky@apple.com>
1 parent 31d10bc commit 13b502d

10 files changed

+72
-60
lines changed

src/app/interaction-model/RequestContext.h src/app/interaction-model/ActionContext.h

+4-4
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,13 @@ namespace chip {
2222
namespace app {
2323
namespace InteractionModel {
2424

25-
// Context for a currently executing request
26-
class RequestContext
25+
// Context for a currently executing action
26+
class ActionContext
2727
{
2828
public:
29-
virtual ~RequestContext() = default;
29+
virtual ~ActionContext() = default;
3030

31-
/// Valid ONLY during synchronous handling of a Read/Write/Invoke
31+
/// Valid ONLY during synchronous handling of an action.
3232
///
3333
/// Used sparingly, however some operations will require these. An example
3434
/// usage is "Operational Credentials aborting communications on removed fabrics"

src/app/interaction-model/BUILD.gn

+2-2
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,14 @@ import("//build_overrides/chip.gni")
1515

1616
source_set("interaction-model") {
1717
sources = [
18-
"Actions.h",
18+
"ActionContext.h",
19+
"Context.h",
1920
"Events.h",
2021
"InvokeResponder.h",
2122
"IterationTypes.h",
2223
"Model.h",
2324
"OperationTypes.h",
2425
"Paths.h",
25-
"RequestContext.h",
2626
]
2727

2828
public_deps = [

src/app/interaction-model/Actions.h src/app/interaction-model/Context.h

+7-3
Original file line numberDiff line numberDiff line change
@@ -16,20 +16,24 @@
1616
*/
1717
#pragma once
1818

19+
#include <app/interaction-model/ActionContext.h>
1920
#include <app/interaction-model/Events.h>
2021
#include <app/interaction-model/Paths.h>
21-
#include <app/interaction-model/RequestContext.h>
2222

2323
namespace chip {
2424
namespace app {
2525
namespace InteractionModel {
2626

2727
/// Data provided to data models in order to interface with the interaction model environment.
28-
struct InteractionModelActions
28+
///
29+
/// Provides callback-style functionality to notify the interaction model of changes
30+
/// (e.g. using paths to notify of attribute data changes or events to generate events)
31+
/// as well as fetching current state (via actionContext)
32+
struct InteractionModelContext
2933
{
3034
Events * events;
3135
Paths * paths;
32-
RequestContext * requestContext;
36+
ActionContext * actionContext;
3337
};
3438

3539
} // namespace InteractionModel

src/app/interaction-model/Events.h

+26-20
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include <lib/core/CHIPError.h>
2525
#include <lib/support/logging/CHIPLogging.h>
2626

27+
#include <optional>
2728
#include <type_traits>
2829

2930
namespace chip {
@@ -32,10 +33,10 @@ namespace InteractionModel {
3233

3334
namespace internal {
3435
template <typename T>
35-
class SimpleEventLoggingDelegate : public EventLoggingDelegate
36+
class SimpleEventPayloadWriter : public EventLoggingDelegate
3637
{
3738
public:
38-
SimpleEventLoggingDelegate(const T & aEventData) : mEventData(aEventData){};
39+
SimpleEventPayloadWriter(const T & aEventData) : mEventData(aEventData){};
3940
CHIP_ERROR WriteEvent(chip::TLV::TLVWriter & aWriter) final override
4041
{
4142
return DataModel::Encode(aWriter, TLV::ContextTag(EventDataIB::Tag::kData), mEventData);
@@ -45,22 +46,22 @@ class SimpleEventLoggingDelegate : public EventLoggingDelegate
4546
const T & mEventData;
4647
};
4748

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)
49+
template <typename G, typename T, std::enable_if_t<DataModel::IsFabricScoped<T>::value, bool> = true>
50+
std::optional<EventNumber> GenerateEvent(G & generator, const T & aEventData, EndpointId aEndpoint)
5051
{
51-
internal::SimpleEventLoggingDelegate<T> eventData(aEventData);
52+
internal::SimpleEventPayloadWriter<T> eventPayloadWriter(aEventData);
5253
ConcreteEventPath path(aEndpoint, aEventData.GetClusterId(), aEventData.GetEventId());
5354
EventOptions eventOptions;
5455
eventOptions.mPath = path;
5556
eventOptions.mPriority = aEventData.GetPriorityLevel();
5657
eventOptions.mFabricIndex = aEventData.GetFabricIndex();
5758

58-
// this skips logging the event if it's fabric-scoped but no fabric association exists yet.
59-
59+
// this skips generating the event if it is fabric-scoped but the provided event data is not
60+
// associated with any fabric.
6061
if (eventOptions.mFabricIndex == kUndefinedFabricIndex)
6162
{
6263
ChipLogError(EventLogging, "Event encode failure: no fabric index for fabric scoped event");
63-
return kInvalidEventId;
64+
return std::nullopt;
6465
}
6566

6667
//
@@ -72,37 +73,41 @@ EventNumber GenerateEvent(E & emittor, const T & aEventData, EndpointId aEndpoin
7273
// and used to match against the accessing fabric.
7374
//
7475
EventNumber eventNumber;
75-
CHIP_ERROR err = emittor.GenerateEvent(&eventData, eventOptions, eventNumber);
76+
CHIP_ERROR err = generator.GenerateEvent(&eventPayloadWriter, eventOptions, eventNumber);
7677
if (err != CHIP_NO_ERROR)
7778
{
78-
ChipLogError(EventLogging, "Failed to log event: %" CHIP_ERROR_FORMAT, err.Format());
79-
return kInvalidEventId;
79+
ChipLogError(EventLogging, "Failed to generate event: %" CHIP_ERROR_FORMAT, err.Format());
80+
return std::nullopt;
8081
}
8182

8283
return eventNumber;
8384
}
8485

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)
86+
template <typename G, typename T, std::enable_if_t<!DataModel::IsFabricScoped<T>::value, bool> = true>
87+
std::optional<EventNumber> GenerateEvent(G & generator, const T & aEventData, EndpointId endpointId)
8788
{
88-
internal::SimpleEventLoggingDelegate<T> eventData(aEventData);
89+
internal::SimpleEventPayloadWriter<T> eventPayloadWriter(aEventData);
8990
ConcreteEventPath path(endpointId, aEventData.GetClusterId(), aEventData.GetEventId());
9091
EventOptions eventOptions;
9192
eventOptions.mPath = path;
9293
eventOptions.mPriority = aEventData.GetPriorityLevel();
9394
EventNumber eventNumber;
94-
CHIP_ERROR err = emittor.GenerateEvent(&eventData, eventOptions, eventNumber);
95+
CHIP_ERROR err = generator.GenerateEvent(&eventPayloadWriter, eventOptions, eventNumber);
9596
if (err != CHIP_NO_ERROR)
9697
{
97-
ChipLogError(EventLogging, "Failed to log event: %" CHIP_ERROR_FORMAT, err.Format());
98-
return kInvalidEventId;
98+
ChipLogError(EventLogging, "Failed to generate event: %" CHIP_ERROR_FORMAT, err.Format());
99+
return std::nullopt;
99100
}
100101

101102
return eventNumber;
102103
}
103104

104105
} // namespace internal
105106

107+
/// Exposes event access capabilities.
108+
///
109+
/// Allows callers to "generate events" which effectively notifies of an event having
110+
/// ocurred.
106111
class Events
107112
{
108113
public:
@@ -113,13 +118,14 @@ class Events
113118
/// Events are generally expected to be sent to subscribed clients and also
114119
/// be available for read later until they get overwritten by new events
115120
/// that are being generated.
116-
virtual CHIP_ERROR GenerateEvent(EventLoggingDelegate * eventContentWriter, const EventOptions & options,
121+
virtual CHIP_ERROR GenerateEvent(EventLoggingDelegate * eventPayloadWriter, const EventOptions & options,
117122
EventNumber & generatedEventNumber) = 0;
118123

119124
// Convenience methods for event logging using cluster-object structures
120-
// On error, these log and return kInvalidEventId
125+
//
126+
// On error, these log and return nullopt.
121127
template <typename T>
122-
EventNumber GenerateEvent(const T & eventData, EndpointId endpointId)
128+
std::optional<EventNumber> GenerateEvent(const T & eventData, EndpointId endpointId)
123129
{
124130
return internal::GenerateEvent(*this, eventData, endpointId);
125131
}

src/app/interaction-model/InvokeResponder.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ namespace InteractionModel {
2626

2727
/// Handles encoding of an invoke response for a specific invoke request.
2828
///
29-
/// This class handles a single response (i.e. a CommandDataIB within the
29+
/// This class handles a single request (i.e. a CommandDataIB within the
3030
/// matter protocol) and is responsible for constructing its corresponding
3131
/// response (i.e. a InvokeResponseIB within the matter protocol)
3232
///

src/app/interaction-model/IterationTypes.h

+7-2
Original file line numberDiff line numberDiff line change
@@ -70,8 +70,13 @@ struct AttributeEntry
7070
/// Iteration rules:
7171
/// - kInvalidEndpointId will be returned when iteration ends (or generally kInvalid* for paths)
7272
/// - Any internal iteration errors are just logged (callers do not handle iteration CHIP_ERROR)
73-
/// - Iteration order is NOT guaranteed, however uniqueness and completeness is (must iterate
74-
/// over all possible distinct values as long as no internal structural changes occur)
73+
/// - Iteration order is NOT guaranteed globally. Only the following is guaranteed:
74+
/// - when iterating over an endpoint, ALL clusters of that endpoint will be iterated first, before
75+
/// switching the endpoint (order of clusters themselves not guaranteed)
76+
/// - when iterating over a cluster, ALL attributes of that cluster will be iterated first, before
77+
/// switching to a new cluster
78+
/// - uniqueness and completeness (iterate over all possible distinct values as long as no
79+
/// internal structural changes occur)
7580
class AttributeTreeIterator
7681
{
7782
public:

src/app/interaction-model/Model.h

+10-10
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
#include <app/AttributeValueDecoder.h>
2323
#include <app/AttributeValueEncoder.h>
2424

25-
#include <app/interaction-model/Actions.h>
25+
#include <app/interaction-model/Context.h>
2626
#include <app/interaction-model/InvokeResponder.h>
2727
#include <app/interaction-model/IterationTypes.h>
2828
#include <app/interaction-model/OperationTypes.h>
@@ -43,17 +43,17 @@ class Model : public AttributeTreeIterator
4343
public:
4444
virtual ~Model() = default;
4545

46-
// `actions` pointers will be guaranteed valid until Shutdown is called()
47-
virtual CHIP_ERROR Startup(InteractionModelActions actions)
46+
// `context` pointers will be guaranteed valid until Shutdown is called()
47+
virtual CHIP_ERROR Startup(InteractionModelContext context)
4848
{
49-
mActions = actions;
49+
mContext = context;
5050
return CHIP_NO_ERROR;
5151
}
5252
virtual CHIP_ERROR Shutdown() = 0;
5353

5454
// During the transition phase, we expect a large subset of code to require access to
5555
// event emitting, path marking and other operations
56-
virtual InteractionModelActions CurrentActions() { return mActions; }
56+
virtual InteractionModelContext CurrentContext() const { return mContext; }
5757

5858
/// List reading has specific handling logic:
5959
/// `state` contains in/out data about the current list reading. MUST start with kInvalidListIndex on first call
@@ -94,14 +94,14 @@ class Model : public AttributeTreeIterator
9494
/// - `NeedsTimedInteraction` for writes that are not timed however are required to be so
9595
virtual CHIP_ERROR WriteAttribute(const WriteAttributeRequest & request, AttributeValueDecoder & decoder) = 0;
9696

97-
/// `responder` is used to send back the reply.
97+
/// `reply` is used to send back the reply.
9898
/// - calling Reply() or ReplyAsync() will let the application control the reply
9999
/// - returning a CHIP_NO_ERROR without reply/reply_async implies a Status::Success reply without data
100-
/// - returning a CHIP_*_ERROR implies an error reply (error and data are mutually exclusive)
100+
/// - returning a value other than CHIP_NO_ERROR implies an error reply (error and data are mutually exclusive)
101101
///
102102
/// See InvokeReply/AutoCompleteInvokeResponder for details on how to send back replies and expected
103-
/// error handling. If you require knowledge if a response was successfully sent, use the underlying
104-
/// `reply` object instead of returning an error codes from Invoke.
103+
/// error handling. If you need to know weather a response was successfully sent, use the underlying
104+
/// `reply` object instead of returning an error code from Invoke.
105105
///
106106
/// Return codes
107107
/// CHIP_IM_GLOBAL_STATUS(code):
@@ -115,7 +115,7 @@ class Model : public AttributeTreeIterator
115115
virtual CHIP_ERROR Invoke(const InvokeRequest & request, chip::TLV::TLVReader & input_arguments, InvokeReply & reply) = 0;
116116

117117
private:
118-
InteractionModelActions mActions = { nullptr };
118+
InteractionModelContext mContext = { nullptr };
119119
};
120120

121121
} // namespace InteractionModel

src/app/interaction-model/OperationTypes.h

+3-3
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,8 @@ struct ReadState
6666

6767
enum class WriteFlags : uint32_t
6868
{
69-
kTimed = 0x0001, // Received as a 2nd command after a timed invoke
70-
kListBegin = 0x0002, // This is the FIRST list data element in a series of data
69+
kTimed = 0x0001, // Write is a timed write (i.e. a Timed Request Action preceeded it)
70+
kListBegin = 0x0002, // This is the FIRST list of data elements
7171
kListEnd = 0x0004, // This is the LAST list element to write
7272
};
7373

@@ -79,7 +79,7 @@ struct WriteAttributeRequest : OperationRequest
7979

8080
enum class InvokeFlags : uint32_t
8181
{
82-
kTimed = 0x0001, // Received as a 2nd command after a timed invoke
82+
kTimed = 0x0001, // Command received as part of a timed invoke interaction.
8383
};
8484

8585
struct InvokeRequest : OperationRequest

src/app/interaction-model/Paths.h

+7-9
Original file line numberDiff line numberDiff line change
@@ -22,23 +22,21 @@ namespace chip {
2222
namespace app {
2323
namespace InteractionModel {
2424

25-
/// Handles path attributes for interaction models.
25+
/// Notification listener for attribute changes.
2626
///
27-
/// It allows a user of the class to mark specific paths
28-
/// as having changed. The intended use is for some listener to
29-
/// perform operations as a result of something having changed,
30-
/// usually by forwarding updates (e.g. in case of subscriptions
31-
/// that cover that path).
27+
/// Used to notify that a specific attribute path (or several attributes
28+
/// via wildcards) have changed their underlying content.
3229
///
33-
/// Methods on this class MUCH be called from within the matter
30+
/// Methods on this class MUST be called from within the matter
3431
/// main loop as they will likely trigger interaction model
35-
/// internal updates and subscription event updates.
32+
/// internal updates and subscription data reporting.
3633
class Paths
3734
{
3835
public:
3936
virtual ~Paths() = 0;
4037

41-
/// Mark some specific attributes dirty.
38+
/// Mark all attributes matching the given path (which may be a wildcard) dirty.
39+
///
4240
/// Wildcards are supported.
4341
virtual void MarkDirty(const AttributePathParams & path) = 0;
4442
};

src/app/interaction-model/tests/TestEventEmitting.cpp

+5-6
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,8 @@ TEST(TestInteractionModelEventEmitting, TestBasicType)
100100

101101
StartUpEventType event{ kFakeSoftwareVersion };
102102

103-
EventNumber n1 = events->GenerateEvent(event, 0 /* EndpointId */);
103+
std::optional<EventNumber> n1 = events->GenerateEvent(event, 0 /* EndpointId */);
104+
104105
ASSERT_EQ(n1, logOnlyEvents.CurrentEventNumber());
105106
ASSERT_EQ(logOnlyEvents.LastOptions().mPath,
106107
ConcreteEventPath(0 /* endpointId */, StartUpEventType::GetClusterId(), StartUpEventType::GetEventId()));
@@ -115,9 +116,8 @@ TEST(TestInteractionModelEventEmitting, TestBasicType)
115116
ASSERT_EQ(err, CHIP_NO_ERROR);
116117
ASSERT_EQ(decoded_event.softwareVersion, kFakeSoftwareVersion);
117118

118-
EventNumber n2 = events->GenerateEvent(event, /* endpointId = */ 1);
119+
std::optional<EventNumber> n2 = events->GenerateEvent(event, /* endpointId = */ 1);
119120
ASSERT_EQ(n2, logOnlyEvents.CurrentEventNumber());
120-
ASSERT_NE(n1, logOnlyEvents.CurrentEventNumber());
121121

122122
ASSERT_EQ(logOnlyEvents.LastOptions().mPath,
123123
ConcreteEventPath(1 /* endpointId */, StartUpEventType::GetClusterId(), StartUpEventType::GetEventId()));
@@ -137,14 +137,13 @@ TEST(TestInteractionModelEventEmitting, TestFabricScoped)
137137
event.adminNodeID = chip::app::DataModel::MakeNullable(kTestNodeId);
138138
event.adminPasscodeID = chip::app::DataModel::MakeNullable(kTestPasscode);
139139

140-
EventNumber n1 = events->GenerateEvent(event, 0 /* EndpointId */);
140+
std::optional<EventNumber> n1 = events->GenerateEvent(event, 0 /* EndpointId */);
141141
// encoding without a fabric ID MUST fail for fabric events
142-
ASSERT_EQ(n1, kInvalidEventId);
142+
ASSERT_FALSE(n1.has_value());
143143

144144
event.fabricIndex = kTestFabricIndex;
145145
n1 = events->GenerateEvent(event, /* endpointId = */ 0);
146146

147-
ASSERT_NE(n1, kInvalidEventId);
148147
ASSERT_EQ(n1, logOnlyEvents.CurrentEventNumber());
149148
ASSERT_EQ(logOnlyEvents.LastOptions().mPath,
150149
ConcreteEventPath(0 /* endpointId */, AccessControlEntryChangedType::GetClusterId(),

0 commit comments

Comments
 (0)