Skip to content

Commit

Permalink
Add suport to send IM events
Browse files Browse the repository at this point in the history
-- When receiving read requested, store interested event path inside
clusterInfo as eventClusterInfoList, reporting engine would fetch
events via EventManamgenment from circular event buffers according to
eventClusterInfoList, and finally send IM report via reader
handler.
-- Reconstruct ClusterInfo so that it can represent the intersted
attribute and event efficiently.
  • Loading branch information
yunhanw-google authored and restyled-io[bot] committed May 7, 2021
1 parent da11194 commit 3274488
Show file tree
Hide file tree
Showing 20 changed files with 485 additions and 176 deletions.
39 changes: 32 additions & 7 deletions src/app/ClusterInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,17 +25,42 @@ namespace chip {
namespace app {
struct ClusterInfo
{
ClusterInfo(const AttributePathParams & aAttributePathParams, bool aDirty) :
mAttributePathParams(aAttributePathParams), mDirty(aDirty)
{}
enum class Type : uint8_t
{
kInvalid = 0,
kFieldIdValid = 0x01,
kListIndexValid = 0x02,
kEventIdValid = 0x03,
};

ClusterInfo() {}
bool IsDirty() { return mDirty; }
void SetDirty() { mDirty = true; }
void ClearDirty() { mDirty = false; }
bool IsSamePath(const ClusterInfo & other) const { return other.mAttributePathParams.IsSamePath(mAttributePathParams); }
AttributePathParams mAttributePathParams;
bool mDirty = false;
ClusterInfo * mpNext = nullptr;
NodeId mNodeId = 0;
ClusterId mClusterId = 0;
ListIndex mListIndex = 0;
FieldId mFieldId = 0;
EndpointId mEndpointId = 0;
bool mDirty = false;
Type mType = Type::kInvalid;
ClusterInfo * mpNext = nullptr;
EventId mEventId = 0;
/* For better structure alignment
* Above ordering is by bit-size to ensure least amount of memory alignment padding.
* Changing order to something more natural (e.g. clusterid before nodeid) will result
* in extra memory alignment padding.
* uint64 mNodeId
* uint16_t mClusterId
* uint16_t mListIndex
* uint8_t FieldId
* uint8_t EndpointId
* uint8_t mDirty
* uint8_t mType
* uint32_t mpNext
* uint16_t EventId
* padding 2 bytes
*/
};
} // namespace app
} // namespace chip
24 changes: 22 additions & 2 deletions src/app/EventManagement.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -332,7 +332,7 @@ CHIP_ERROR EventManagement::ConstructEvent(EventLoadOutContext * apContext, Even
SuccessOrExit(err);

eventDataElementBuilder.EndOfEventDataElement();
SuccessOrExit(eventDataElementBuilder.GetError());
SuccessOrExit(err = eventDataElementBuilder.GetError());

err = apContext->mWriter.Finalize();
SuccessOrExit(err);
Expand Down Expand Up @@ -654,8 +654,10 @@ CHIP_ERROR EventManagement::CopyEventsSince(const TLVReader & aReader, size_t aD
return err;
}

CHIP_ERROR EventManagement::FetchEventsSince(TLVWriter & aWriter, PriorityLevel aPriority, EventNumber & aEventNumber)
CHIP_ERROR EventManagement::FetchEventsSince(TLVWriter & aWriter, ClusterInfo * apClusterInfolist, PriorityLevel aPriority,
EventNumber & aEventNumber)
{
// TODO: Add particular set of event Paths in FetchEventsSince so that we can filter the interested paths
CHIP_ERROR err = CHIP_NO_ERROR;
const bool recurse = false;
TLVReader reader;
Expand Down Expand Up @@ -787,6 +789,24 @@ CHIP_ERROR EventManagement::ScheduleFlushIfNeeded(EventOptions::Type aUrgent)
return CHIP_NO_ERROR;
}

void EventManagement::SetScheduledEventEndpoint(EventNumber * apEventEndpoints)
{
CircularEventBuffer * eventBuffer = mpEventBuffer;

CriticalSectionEnter();

while (eventBuffer != nullptr)
{
if (eventBuffer->GetPriorityLevel() >= PriorityLevel::First && (eventBuffer->GetPriorityLevel() <= PriorityLevel::Last))
{
apEventEndpoints[static_cast<uint8_t>(eventBuffer->GetPriorityLevel())] = eventBuffer->GetLastEventNumber();
}
eventBuffer = eventBuffer->GetNextCircularEventBuffer();
}

CriticalSectionExit();
}

void CircularEventBuffer::Init(uint8_t * apBuffer, uint32_t aBufferLength, CircularEventBuffer * apPrev,
CircularEventBuffer * apNext, PriorityLevel aPriorityLevel)
{
Expand Down
19 changes: 16 additions & 3 deletions src/app/EventManagement.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@

#include "EventLoggingDelegate.h"
#include "EventLoggingTypes.h"
#include <app/ClusterInfo.h>
#include <app/MessageDef/EventDataElement.h>
#include <app/util/basic-types.h>
#include <core/CHIPCircularTLVBuffer.h>
Expand Down Expand Up @@ -373,7 +374,7 @@ class EventManagement
* will terminate the event writing on event boundary.
*
* @param[in] aWriter The writer to use for event storage
*
* @param[in] apEventClusterInfolist the interested cluster info list with event path inside
* @param[in] aPriority The priority of events to be fetched
*
* @param[inout] aEventNumber On input, the Event number immediately
Expand All @@ -394,7 +395,8 @@ class EventManagement
* available.
*
*/
CHIP_ERROR FetchEventsSince(chip::TLV::TLVWriter & aWriter, PriorityLevel aPriority, EventNumber & aEventNumber);
CHIP_ERROR FetchEventsSince(chip::TLV::TLVWriter & aWriter, ClusterInfo * apClusterInfolist, PriorityLevel aPriority,
EventNumber & aEventNumber);

/**
* @brief
Expand Down Expand Up @@ -449,6 +451,17 @@ class EventManagement
*/
EventNumber GetFirstEventNumber(PriorityLevel aPriority);

/**
* @brief
* IsValid returns whether the EventManagement instance is valid
*/
bool IsValid(void) { return EventManagementStates::Shutdown != mState; };

/**
* Logger would save last logged event number for each logger buffer into schedule event number array
*/
void SetScheduledEventEndpoint(EventNumber * aEventEndpoints);

private:
CHIP_ERROR CalculateEventSize(EventLoggingDelegate * apDelegate, const EventOptions * apOptions, uint32_t & requiredSize);
/**
Expand Down Expand Up @@ -555,7 +568,7 @@ class EventManagement
// EventBuffer for debug level,
CircularEventBuffer * mpEventBuffer = nullptr;
Messaging::ExchangeManager * mpExchangeMgr = nullptr;
EventManagementStates mState = EventManagementStates::Idle;
EventManagementStates mState = EventManagementStates::Shutdown;
uint32_t mBytesWritten = 0;
};
} // namespace app
Expand Down
30 changes: 15 additions & 15 deletions src/app/InteractionModelEngine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -254,24 +254,23 @@ DispatchSingleClusterCommand(chip::ClusterId aClusterId, chip::CommandId aComman
"Default DispatchSingleClusterCommand is called, this should be replaced by actual dispatched for cluster commands");
}

CHIP_ERROR __attribute__((weak)) ReadSingleClusterData(AttributePathParams & aAttributePathParams, TLV::TLVWriter & aWriter)
CHIP_ERROR __attribute__((weak)) ReadSingleClusterData(ClusterInfo & aClusterInfo, TLV::TLVWriter & aWriter)
{
ChipLogDetail(DataManagement,
"Received Cluster Command: Cluster=%" PRIx16 " NodeId=%" PRIx64 " Endpoint=%" PRIx8 " FieldId=%" PRIx8
" ListIndex=%" PRIx8,
aAttributePathParams.mClusterId, aAttributePathParams.mNodeId, aAttributePathParams.mEndpointId,
aAttributePathParams.mFieldId, aAttributePathParams.mListIndex);
ChipLogDetail(
DataManagement,
"Received Cluster Command: Cluster=%" PRIx16 " NodeId=%" PRIx64 " Endpoint=%" PRIx8 " FieldId=%" PRIx8 " ListIndex=%" PRIx8,
aClusterInfo.mClusterId, aClusterInfo.mNodeId, aClusterInfo.mEndpointId, aClusterInfo.mFieldId, aClusterInfo.mListIndex);
ChipLogError(DataManagement,
"Default ReadSingleClusterData is called, this should be replaced by actual dispatched for cluster");
return CHIP_NO_ERROR;
}

CHIP_ERROR __attribute__((weak)) WriteSingleClusterData(AttributePathParams & aAttributePathParams, TLV::TLVReader & aReader)
CHIP_ERROR __attribute__((weak)) WriteSingleClusterData(ClusterInfo & aClusterInfo, TLV::TLVReader & aReader)
{
ChipLogDetail(DataManagement,
"Received Cluster Attribute: Cluster=%" PRIx16 " NodeId=%" PRIx64 " Endpoint=%" PRIx8 " FieldId=%" PRIx8,
" ListIndex=%" PRIx8, aAttributePathParams.mClusterId, aAttributePathParams.mNodeId,
aAttributePathParams.mEndpointId, aAttributePathParams.mFieldId, aAttributePathParams.mListIndex);
" ListIndex=%" PRIx8, aClusterInfo.mClusterId, aClusterInfo.mNodeId, aClusterInfo.mEndpointId,
aClusterInfo.mFieldId, aClusterInfo.mListIndex);
ChipLogError(DataManagement,
"Default WriteSingleClusterData is called, this should be replaced by actual dispatched for cluster");
return CHIP_NO_ERROR;
Expand All @@ -296,22 +295,23 @@ void InteractionModelEngine::ReleaseClusterInfoList(ClusterInfo *& aClusterInfo)
lastClusterInfo = lastClusterInfo->mpNext;
}
lastClusterInfo->ClearDirty();
lastClusterInfo->mType = ClusterInfo::Type::kInvalid;
lastClusterInfo->mpNext = mpNextAvailableClusterInfo;
mpNextAvailableClusterInfo = aClusterInfo;
aClusterInfo = nullptr;
}

CHIP_ERROR InteractionModelEngine::PushFront(ClusterInfo *& aClusterInfo, AttributePathParams & aAttributePathParams)
CHIP_ERROR InteractionModelEngine::PushFront(ClusterInfo *& aClusterInfoList, ClusterInfo & aClusterInfo)
{
ClusterInfo * last = aClusterInfo;
ClusterInfo * last = aClusterInfoList;
if (mpNextAvailableClusterInfo == nullptr)
{
return CHIP_ERROR_NO_MEMORY;
}
aClusterInfo = mpNextAvailableClusterInfo;
mpNextAvailableClusterInfo = mpNextAvailableClusterInfo->mpNext;
aClusterInfo->mpNext = last;
aClusterInfo->mAttributePathParams = aAttributePathParams;
aClusterInfoList = mpNextAvailableClusterInfo;
mpNextAvailableClusterInfo = mpNextAvailableClusterInfo->mpNext;
*aClusterInfoList = aClusterInfo;
aClusterInfoList->mpNext = last;
return CHIP_NO_ERROR;
}

Expand Down
6 changes: 3 additions & 3 deletions src/app/InteractionModelEngine.h
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ class InteractionModelEngine : public Messaging::ExchangeDelegate
reporting::Engine & GetReportingEngine() { return mReportingEngine; }

void ReleaseClusterInfoList(ClusterInfo *& aClusterInfo);
CHIP_ERROR PushFront(ClusterInfo *& aClusterInfo, AttributePathParams & aAttributePathParams);
CHIP_ERROR PushFront(ClusterInfo *& aClusterInfoLisst, ClusterInfo & aClusterInfo);

private:
friend class reporting::Engine;
Expand Down Expand Up @@ -163,7 +163,7 @@ class InteractionModelEngine : public Messaging::ExchangeDelegate

void DispatchSingleClusterCommand(chip::ClusterId aClusterId, chip::CommandId aCommandId, chip::EndpointId aEndPointId,
chip::TLV::TLVReader & aReader, Command * apCommandObj);
CHIP_ERROR ReadSingleClusterData(AttributePathParams & aAttributePathParams, TLV::TLVWriter & aWriter);
CHIP_ERROR WriteSingleClusterData(AttributePathParams & aAttributePathParams, TLV::TLVReader & aReader);
CHIP_ERROR ReadSingleClusterData(ClusterInfo & aClusterInfo, TLV::TLVWriter & aWriter);
CHIP_ERROR WriteSingleClusterData(ClusterInfo & aClusterInfo, TLV::TLVReader & aReader);
} // namespace app
} // namespace chip
49 changes: 35 additions & 14 deletions src/app/ReadClient.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,9 @@ void ReadClient::MoveToState(const ClientState aTargetState)

CHIP_ERROR ReadClient::SendReadRequest(NodeId aNodeId, Transport::AdminId aAdminId, EventPathParams * apEventPathParamsList,
size_t aEventPathParamsListSize, AttributePathParams * apAttributePathParamsList,
size_t aAttributePathParamsListSize)
size_t aAttributePathParamsListSize, EventNumber aEventNumber)
{
// TODO: SendRequest parameter is too long, need to have the structure to represent it
CHIP_ERROR err = CHIP_NO_ERROR;
System::PacketBufferHandle msgBuf;
ChipLogDetail(DataManagement, "%s: Client[%u] [%5.5s]", __func__,
Expand All @@ -103,13 +104,33 @@ CHIP_ERROR ReadClient::SendReadRequest(NodeId aNodeId, Transport::AdminId aAdmin

if (aEventPathParamsListSize != 0 && apEventPathParamsList != nullptr)
{
// TODO: fill to construct event paths
EventPathList::Builder & eventPathListBuilder = request.CreateEventPathListBuilder();
EventPath::Builder eventPathBuilder = eventPathListBuilder.CreateEventPathBuilder();
for (size_t eventIndex = 0; eventIndex < aEventPathParamsListSize; ++eventIndex)
{
EventPathParams eventPath = apEventPathParamsList[eventIndex];
eventPathBuilder.NodeId(eventPath.mNodeId)
.EventId(eventPath.mEventId)
.EndpointId(eventPath.mEndpointId)
.ClusterId(eventPath.mClusterId)
.EndOfEventPath();
SuccessOrExit(err = eventPathBuilder.GetError());
}

eventPathListBuilder.EndOfEventPathList();
SuccessOrExit(err = eventPathListBuilder.GetError());

if (aEventNumber != 0)
{
// EventNumber is optional
request.EventNumber(aEventNumber);
}
}

if (aAttributePathParamsListSize != 0 && apAttributePathParamsList != nullptr)
{
AttributePathList::Builder attributePathListBuilder = request.CreateAttributePathListBuilder();
SuccessOrExit(attributePathListBuilder.GetError());
SuccessOrExit(err = attributePathListBuilder.GetError());
for (size_t index = 0; index < aAttributePathParamsListSize; index++)
{
AttributePath::Builder attributePathBuilder = attributePathListBuilder.CreateAttributePathBuilder();
Expand All @@ -129,11 +150,11 @@ CHIP_ERROR ReadClient::SendReadRequest(NodeId aNodeId, Transport::AdminId aAdmin
err = CHIP_ERROR_INVALID_ARGUMENT;
ExitNow();
}
SuccessOrExit(attributePathBuilder.GetError());
SuccessOrExit(err = attributePathBuilder.GetError());
}
}
request.EndOfReadRequest();
SuccessOrExit(request.GetError());
SuccessOrExit(err = request.GetError());

err = writer.Finalize(&msgBuf);
SuccessOrExit(err);
Expand Down Expand Up @@ -293,39 +314,39 @@ CHIP_ERROR ReadClient::ProcessAttributeDataList(TLV::TLVReader & aAttributeDataL
chip::TLV::TLVReader dataReader;
AttributeDataElement::Parser element;
AttributePath::Parser attributePathParser;
AttributePathParams attributePathParams;
ClusterInfo clusterInfo;
TLV::TLVReader reader = aAttributeDataListReader;
err = element.Init(reader);
SuccessOrExit(err);

err = element.GetAttributePath(&attributePathParser);
SuccessOrExit(err);

err = attributePathParser.GetNodeId(&(attributePathParams.mNodeId));
err = attributePathParser.GetNodeId(&(clusterInfo.mNodeId));
SuccessOrExit(err);

err = attributePathParser.GetEndpointId(&(attributePathParams.mEndpointId));
err = attributePathParser.GetEndpointId(&(clusterInfo.mEndpointId));
SuccessOrExit(err);

err = attributePathParser.GetClusterId(&(attributePathParams.mClusterId));
err = attributePathParser.GetClusterId(&(clusterInfo.mClusterId));
SuccessOrExit(err);

err = attributePathParser.GetFieldId(&(attributePathParams.mFieldId));
err = attributePathParser.GetFieldId(&(clusterInfo.mFieldId));
if (CHIP_NO_ERROR == err)
{
attributePathParams.mFlags = AttributePathFlags::kFieldIdValid;
clusterInfo.mType = ClusterInfo::Type::kFieldIdValid;
}
else if (CHIP_END_OF_TLV == err)
{
err = attributePathParser.GetListIndex(&(attributePathParams.mListIndex));
err = attributePathParser.GetListIndex(&(clusterInfo.mListIndex));
SuccessOrExit(err);
attributePathParams.mFlags = AttributePathFlags::kListIndexValid;
clusterInfo.mType = ClusterInfo::Type::kListIndexValid;
}
SuccessOrExit(err);

err = element.GetData(&dataReader);
SuccessOrExit(err);
err = WriteSingleClusterData(attributePathParams, dataReader);
err = WriteSingleClusterData(clusterInfo, dataReader);
SuccessOrExit(err);
}

Expand Down
8 changes: 1 addition & 7 deletions src/app/ReadClient.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,18 +66,12 @@ class ReadClient : public Messaging::ExchangeDelegate
* until the corresponding InteractionModelDelegate::ReportProcessed or InteractionModelDelegate::ReportError
* call happens with guarantee.
*
* @param[in] aNodeId Node Id
* @param[in] aAdminId Admin ID
* @param[in] apEventPathParamsList a list of event paths the read client is interested in
* @param[in] aEventPathParamsListSize Number of event paths in apEventPathParamsList
* @param[in] apAttributePathParamsList a list of attribute paths the read client is interested in
* @param[in] aAttributePathParamsListSize Number of attribute paths in apAttributePathParamsList
* @retval #others fail to send read request
* @retval #CHIP_NO_ERROR On success.
*/
CHIP_ERROR SendReadRequest(NodeId aNodeId, Transport::AdminId aAdminId, EventPathParams * apEventPathParamsList,
size_t aEventPathParamsListSize, AttributePathParams * apAttributePathParamsList,
size_t aAttributePathParamsListSize);
size_t aAttributePathParamsListSize, EventNumber aEventNumber);

private:
friend class TestReadInteraction;
Expand Down
Loading

0 comments on commit 3274488

Please sign in to comment.