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 IM event processing function and callback interface in client side #11615

Merged
Show file tree
Hide file tree
Changes from all commits
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
1 change: 1 addition & 0 deletions src/app/ClusterInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ struct ClusterInfo
private:
// Allow AttributePathParams access these constants.
friend struct AttributePathParams;
friend struct ConcreteEventPath;

// The ClusterId, AttributeId and EventId are MEIs,
// 0xFFFF is not a valid manufacturer code, thus 0xFFFF'FFFF is not a valid MEI
Expand Down
63 changes: 63 additions & 0 deletions src/app/ConcreteEventPath.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/*
*
* Copyright (c) 2021 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/ClusterInfo.h>
#include <app/util/basic-types.h>

namespace chip {
namespace app {

/**
* A representation of a concrete event path.
*/
struct ConcreteEventPath
{
ConcreteEventPath(EndpointId aEndpointId, ClusterId aClusterId, EventId aEventId) :
mEndpointId(aEndpointId), mClusterId(aClusterId), mEventId(aEventId)
{}

ConcreteEventPath() {}

ConcreteEventPath & operator=(ConcreteEventPath && other)
{
if (&other == this)
return *this;

mEndpointId = other.mEndpointId;
mClusterId = other.mClusterId;
mEventId = other.mEventId;
return *this;
}

bool operator==(const ConcreteEventPath & other) const
{
return mEndpointId == other.mEndpointId && mClusterId == other.mClusterId && mEventId == other.mEventId;
}

bool IsValidEventPath() const { return !HasWildcardEventId(); }

inline bool HasWildcardEventId() const { return mEventId == ClusterInfo::kInvalidEventId; }

EndpointId mEndpointId = 0;
ClusterId mClusterId = 0;
EventId mEventId = 0;
};
} // namespace app
} // namespace chip
4 changes: 3 additions & 1 deletion src/app/DeviceControllerInteractionModelDelegate.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,9 @@ class DeviceControllerInteractionModelDelegate : public chip::app::ReadClient::C

void OnDone(app::WriteClient * apWriteClient) override {}

void OnEventData(const app::ReadClient * apReadClient, TLV::TLVReader & aEventList) override {}
void OnEventData(const app::ReadClient * apReadClient, const app::EventHeader & aEventHeader, TLV::TLVReader * apData,
const app::StatusIB * apStatus) override
{}

void OnAttributeData(const app::ReadClient * apReadClient, const app::ConcreteAttributePath & aPath, TLV::TLVReader * apData,
const app::StatusIB & aStatus) override
Expand Down
35 changes: 35 additions & 0 deletions src/app/EventHeader.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*
*
* Copyright (c) 2021 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 "ConcreteEventPath.h"
#include "EventLoggingTypes.h"
#include <app/util/basic-types.h>

namespace chip {
namespace app {
struct EventHeader
{
ConcreteEventPath mPath;
EventNumber mEventNumber = 0;
PriorityLevel mPriorityLevel = PriorityLevel::Invalid;
Timestamp mTimestamp;
};
} // namespace app
} // namespace chip
20 changes: 11 additions & 9 deletions src/app/EventLoggingTypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -104,23 +104,22 @@ struct EventSchema

/**
* @brief
* The struct that provides an application set system or UTC timestamp.
* The struct that provides an application set System or Epoch timestamp.
*/
struct Timestamp
{
enum class Type
{
kInvalid = 0,
kSystem,
kUTC
kSystem = 0,
kEpoch
};
Timestamp() {}
Timestamp(Type aType) : mType(aType) { mValue = 0; }
Timestamp(Type aType, uint64_t aValue) : mType(aType), mValue(aValue) {}
Timestamp(System::Clock::Timestamp aValue) : mType(Type::kSystem), mValue(aValue.count()) {}
static Timestamp UTC(uint64_t aValue)
{
Timestamp timestamp(Type::kUTC, aValue);
Timestamp timestamp(Type::kEpoch, aValue);
return timestamp;
}
static Timestamp System(System::Clock::Timestamp aValue)
Expand All @@ -129,7 +128,10 @@ struct Timestamp
return timestamp;
}

Type mType = Type::kInvalid;
bool IsSystem() { return mType == Type::kSystem; }
bool IsEpoch() { return mType == Type::kEpoch; }

Type mType = Type::kSystem;
uint64_t mValue = 0;
};

Expand All @@ -144,9 +146,9 @@ class EventOptions
kUrgent = 0,
kNotUrgent,
};
EventOptions(void) : mTimestamp(Timestamp::Type::kInvalid), mpEventSchema(nullptr), mUrgent(Type::kNotUrgent) {}
EventOptions(void) : mTimestamp(Timestamp::Type::kSystem), mpEventSchema(nullptr), mUrgent(Type::kNotUrgent) {}

EventOptions(Type aType) : mTimestamp(Timestamp::Type::kInvalid), mpEventSchema(nullptr), mUrgent(aType) {}
EventOptions(Type aType) : mTimestamp(Timestamp::Type::kSystem), mpEventSchema(nullptr), mUrgent(aType) {}

EventOptions(Timestamp aTimestamp) : mTimestamp(aTimestamp), mpEventSchema(nullptr), mUrgent(Type::kNotUrgent) {}

Expand All @@ -167,7 +169,7 @@ struct EventLoadOutContext
{
EventLoadOutContext(TLV::TLVWriter & aWriter, PriorityLevel aPriority, EventNumber aStartingEventNumber) :
mWriter(aWriter), mPriority(aPriority), mStartingEventNumber(aStartingEventNumber),
mCurrentSystemTime(Timestamp::Type::kSystem), mCurrentEventNumber(0), mCurrentUTCTime(Timestamp::Type::kUTC), mFirst(true)
mCurrentSystemTime(Timestamp::Type::kSystem), mCurrentEventNumber(0), mCurrentUTCTime(Timestamp::Type::kEpoch), mFirst(true)
{}

TLV::TLVWriter & mWriter;
Expand Down
64 changes: 8 additions & 56 deletions src/app/EventManagement.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -304,40 +304,16 @@ CHIP_ERROR EventManagement::ConstructEvent(EventLoadOutContext * apContext, Even
EventReportIB::Builder eventReportBuilder;
EventDataIB::Builder eventDataIBBuilder;
EventPathIB::Builder eventPathBuilder;
EventStatusIB::Builder eventStatusIBBuilder;
StatusIB::Builder statusIBBuilder;
StatusIB status;
uint64_t deltatime = 0;

VerifyOrExit(apContext->mCurrentEventNumber >= apContext->mStartingEventNumber,
/* no-op: don't write event, but advance current event Number */);

VerifyOrExit(apOptions != nullptr, err = CHIP_ERROR_INVALID_ARGUMENT);
VerifyOrExit(apOptions->mTimestamp.mType != Timestamp::Type::kInvalid, err = CHIP_ERROR_INVALID_ARGUMENT);

eventReportBuilder.Init(&(apContext->mWriter));
// TODO: Update IsUrgent, issue 11386
// TODO: Update statusIB, issue 11388
yunhanw-google marked this conversation as resolved.
Show resolved Hide resolved
eventStatusIBBuilder = eventReportBuilder.CreateEventStatus();
eventPathBuilder = eventStatusIBBuilder.CreatePath();
err = eventStatusIBBuilder.GetError();
SuccessOrExit(err);
eventPathBuilder.Node(apOptions->mpEventSchema->mNodeId)
.Endpoint(apOptions->mpEventSchema->mEndpointId)
.Cluster(apOptions->mpEventSchema->mClusterId)
.Event(apOptions->mpEventSchema->mEventId)
.IsUrgent(false)
.EndOfEventPathIB();
err = eventPathBuilder.GetError();
SuccessOrExit(err);
statusIBBuilder = eventStatusIBBuilder.CreateErrorStatus();
err = eventStatusIBBuilder.GetError();
SuccessOrExit(err);
statusIBBuilder.EncodeStatusIB(status);
eventStatusIBBuilder.EndOfEventStatusIB();
err = statusIBBuilder.GetError();
SuccessOrExit(err);

eventDataIBBuilder = eventReportBuilder.CreateEventData();
eventPathBuilder = eventDataIBBuilder.CreatePath();
err = eventDataIBBuilder.GetError();
Expand Down Expand Up @@ -466,6 +442,12 @@ CHIP_ERROR EventManagement::CopyAndAdjustDeltaTime(const TLVReader & aReader, si
CopyAndAdjustDeltaTimeContext * ctx = static_cast<CopyAndAdjustDeltaTimeContext *>(apContext);
TLVReader reader(aReader);

if (aReader.GetTag() == TLV::ContextTag(to_underlying(EventDataIB::Tag::kPath)))
{
err =
ctx->mpWriter->Put(TLV::ContextTag(to_underlying(EventDataIB::Tag::kEventNumber)), ctx->mpContext->mCurrentEventNumber);
}

// TODO: Add UTC timestamp support
if (aReader.GetTag() == TLV::ContextTag(to_underlying(EventDataIB::Tag::kDeltaSystemTimestamp)))
{
Expand All @@ -485,17 +467,6 @@ CHIP_ERROR EventManagement::CopyAndAdjustDeltaTime(const TLVReader & aReader, si
err = ctx->mpWriter->CopyElement(reader);
}

// First event in the sequence gets a event number neatly packaged
// right after the priority to keep tags ordered
if (aReader.GetTag() == TLV::ContextTag(to_underlying(EventDataIB::Tag::kPriority)))
{
if (ctx->mpContext->mFirst)
{
err = ctx->mpWriter->Put(TLV::ContextTag(to_underlying(EventDataIB::Tag::kEventNumber)),
ctx->mpContext->mCurrentEventNumber);
}
}

return err;
}

Expand Down Expand Up @@ -621,23 +592,6 @@ CHIP_ERROR EventManagement::CopyEvent(const TLVReader & aReader, TLVWriter & aWr
ReturnErrorOnFailure(reader.EnterContainer(containerType));
ReturnErrorOnFailure(aWriter.StartContainer(AnonymousTag, kTLVType_Structure, containerType));

ReturnErrorOnFailure(reader.Next());
ReturnErrorOnFailure(reader.EnterContainer(containerType1));
ReturnErrorOnFailure(aWriter.StartContainer(TLV::ContextTag(to_underlying(EventReportIB::Tag::kEventStatus)),
kTLVType_Structure, containerType1));
ReturnErrorOnFailure(reader.Next());
do
{
ReturnErrorOnFailure(aWriter.CopyElement(reader));
} while (CHIP_NO_ERROR == (err = reader.Next()));
if (err == CHIP_END_OF_TLV)
{
err = CHIP_NO_ERROR;
}
ReturnErrorOnFailure(err);
ReturnErrorOnFailure(reader.ExitContainer(containerType1));
ReturnErrorOnFailure(aWriter.EndContainer(containerType1));

ReturnErrorOnFailure(reader.Next());
ReturnErrorOnFailure(reader.EnterContainer(containerType1));
ReturnErrorOnFailure(
Expand Down Expand Up @@ -685,8 +639,7 @@ CHIP_ERROR EventManagement::EventIterator(const TLVReader & aReader, size_t aDep
innerReader.Init(aReader);
ReturnErrorOnFailure(innerReader.EnterContainer(tlvType));
ReturnErrorOnFailure(innerReader.Next());
// Skip EventStatus Element
ReturnErrorOnFailure(innerReader.Next());

ReturnErrorOnFailure(innerReader.EnterContainer(tlvType1));
err = TLV::Utilities::Iterate(innerReader, FetchEventParameters, &event, false /*recurse*/);
if (event.mFieldsToRead != kRequiredEventField)
Expand Down Expand Up @@ -836,8 +789,7 @@ CHIP_ERROR EventManagement::EvictEvent(CHIPCircularTLVBuffer & apBuffer, void *
TLVType containerType1;
ReturnErrorOnFailure(aReader.EnterContainer(containerType));
ReturnErrorOnFailure(aReader.Next());
// Skip EventStatus
ReturnErrorOnFailure(aReader.Next());

ReturnErrorOnFailure(aReader.EnterContainer(containerType1));
EventEnvelopeContext context;
constexpr bool recurse = false;
Expand Down
3 changes: 3 additions & 0 deletions src/app/EventPathParams.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ struct EventPathParams
EventPathParams(NodeId aNodeId, EndpointId aEndpointId, ClusterId aClusterId, EventId aEventId, bool aIsUrgent) :
mNodeId(aNodeId), mEndpointId(aEndpointId), mClusterId(aClusterId), mEventId(aEventId), mIsUrgent(aIsUrgent)
{}
EventPathParams(EndpointId aEndpointId, ClusterId aClusterId, EventId aEventId) :
EventPathParams(0, aEndpointId, aClusterId, aEventId, false)
{}
EventPathParams() {}
bool IsSamePath(const EventPathParams & other) const
{
Expand Down
Loading