diff --git a/src/app/ClusterInfo.h b/src/app/ClusterInfo.h index 6f65438969470b..ef68b036961740 100644 --- a/src/app/ClusterInfo.h +++ b/src/app/ClusterInfo.h @@ -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 diff --git a/src/app/EventManagement.cpp b/src/app/EventManagement.cpp index 8dc26d08d08c25..4c73ee12fbd255 100644 --- a/src/app/EventManagement.cpp +++ b/src/app/EventManagement.cpp @@ -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); @@ -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; @@ -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(eventBuffer->GetPriorityLevel())] = eventBuffer->GetLastEventNumber(); + } + eventBuffer = eventBuffer->GetNextCircularEventBuffer(); + } + + CriticalSectionExit(); +} + void CircularEventBuffer::Init(uint8_t * apBuffer, uint32_t aBufferLength, CircularEventBuffer * apPrev, CircularEventBuffer * apNext, PriorityLevel aPriorityLevel) { diff --git a/src/app/EventManagement.h b/src/app/EventManagement.h index f15e87460274cb..c6b8487a816d85 100644 --- a/src/app/EventManagement.h +++ b/src/app/EventManagement.h @@ -28,6 +28,7 @@ #include "EventLoggingDelegate.h" #include "EventLoggingTypes.h" +#include #include #include #include @@ -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 @@ -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 @@ -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); /** @@ -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 diff --git a/src/app/InteractionModelEngine.cpp b/src/app/InteractionModelEngine.cpp index 496c788b441977..b43e645a92cde9 100644 --- a/src/app/InteractionModelEngine.cpp +++ b/src/app/InteractionModelEngine.cpp @@ -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; @@ -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; } diff --git a/src/app/InteractionModelEngine.h b/src/app/InteractionModelEngine.h index f7475ccf79181f..9f887b4230922f 100644 --- a/src/app/InteractionModelEngine.h +++ b/src/app/InteractionModelEngine.h @@ -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; @@ -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 diff --git a/src/app/ReadClient.cpp b/src/app/ReadClient.cpp index 9e385eed3f0fbb..e080f3eea66c73 100644 --- a/src/app/ReadClient.cpp +++ b/src/app/ReadClient.cpp @@ -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__, @@ -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(); @@ -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); @@ -293,7 +314,7 @@ 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); @@ -301,31 +322,31 @@ CHIP_ERROR ReadClient::ProcessAttributeDataList(TLV::TLVReader & aAttributeDataL 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); } diff --git a/src/app/ReadClient.h b/src/app/ReadClient.h index 2f7189910fab3f..15ad864cc055f1 100644 --- a/src/app/ReadClient.h +++ b/src/app/ReadClient.h @@ -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; diff --git a/src/app/ReadHandler.cpp b/src/app/ReadHandler.cpp index 9d8441559b58d2..28c60fc66bc0e3 100644 --- a/src/app/ReadHandler.cpp +++ b/src/app/ReadHandler.cpp @@ -35,11 +35,12 @@ CHIP_ERROR ReadHandler::Init(InteractionModelDelegate * apDelegate) // Error if already initialized. VerifyOrExit(apDelegate != nullptr, err = CHIP_ERROR_INCORRECT_STATE); VerifyOrExit(mpExchangeCtx == nullptr, err = CHIP_ERROR_INCORRECT_STATE); - mpExchangeCtx = nullptr; - mpDelegate = apDelegate; - mSuppressResponse = true; - mGetToAllEvents = true; - mpClusterInfoList = nullptr; + mpExchangeCtx = nullptr; + mpDelegate = apDelegate; + mSuppressResponse = true; + mpAttributeClusterInfoList = nullptr; + mpEventClusterInfoList = nullptr; + mCurrentPriority = PriorityLevel::Invalid; MoveToState(HandlerState::Initialized); exit: @@ -49,10 +50,14 @@ CHIP_ERROR ReadHandler::Init(InteractionModelDelegate * apDelegate) void ReadHandler::Shutdown() { - InteractionModelEngine::GetInstance()->ReleaseClusterInfoList(mpClusterInfoList); + InteractionModelEngine::GetInstance()->ReleaseClusterInfoList(mpAttributeClusterInfoList); + InteractionModelEngine::GetInstance()->ReleaseClusterInfoList(mpEventClusterInfoList); ClearExistingExchangeContext(); MoveToState(HandlerState::Uninitialized); - mpDelegate = nullptr; + mpDelegate = nullptr; + mpAttributeClusterInfoList = nullptr; + mpEventClusterInfoList = nullptr; + mCurrentPriority = PriorityLevel::Invalid; } CHIP_ERROR ReadHandler::ClearExistingExchangeContext() @@ -72,8 +77,7 @@ CHIP_ERROR ReadHandler::OnReadRequest(Messaging::ExchangeContext * apExchangeCon System::PacketBufferHandle response; mpExchangeCtx = apExchangeContext; - - err = ProcessReadRequest(std::move(aPayload)); + err = ProcessReadRequest(std::move(aPayload)); SuccessOrExit(err); exit: @@ -107,7 +111,6 @@ CHIP_ERROR ReadHandler::ProcessReadRequest(System::PacketBufferHandle aPayload) ReadRequest::Parser readRequestParser; EventPathList::Parser eventPathListParser; AttributePathList::Parser attributePathListParser; - TLV::TLVReader eventPathListReader; reader.Init(std::move(aPayload)); @@ -116,7 +119,6 @@ CHIP_ERROR ReadHandler::ProcessReadRequest(System::PacketBufferHandle aPayload) err = readRequestParser.Init(reader); SuccessOrExit(err); - #if CHIP_CONFIG_IM_ENABLE_SCHEMA_CHECK err = readRequestParser.CheckSchemaValidity(); SuccessOrExit(err); @@ -130,9 +132,9 @@ CHIP_ERROR ReadHandler::ProcessReadRequest(System::PacketBufferHandle aPayload) else { SuccessOrExit(err); - ProcessAttributePathList(attributePathListParser); + err = ProcessAttributePathList(attributePathListParser); } - + SuccessOrExit(err); err = readRequestParser.GetEventPathList(&eventPathListParser); if (err == CHIP_END_OF_TLV) { @@ -141,19 +143,9 @@ CHIP_ERROR ReadHandler::ProcessReadRequest(System::PacketBufferHandle aPayload) else { SuccessOrExit(err); - eventPathListParser.GetReader(&eventPathListReader); - - while (CHIP_NO_ERROR == (err = eventPathListReader.Next())) - { - VerifyOrExit(TLV::AnonymousTag == eventPathListReader.GetTag(), err = CHIP_ERROR_INVALID_TLV_TAG); - - EventPath::Parser eventPath; - - err = eventPath.Init(eventPathListReader); - SuccessOrExit(err); - // TODO: Pass event path to report engine to generate report with interested events - } + err = ProcessEventPathList(eventPathListParser); } + SuccessOrExit(err); // if we have exhausted this container if (CHIP_END_OF_TLV == err) @@ -180,21 +172,31 @@ CHIP_ERROR ReadHandler::ProcessAttributePathList(AttributePathList::Parser & aAt { VerifyOrExit(TLV::AnonymousTag == reader.GetTag(), err = CHIP_ERROR_INVALID_TLV_TAG); VerifyOrExit(TLV::kTLVType_List == reader.GetType(), err = CHIP_ERROR_WRONG_TLV_TYPE); - AttributePathParams attributePathParams; + ClusterInfo clusterInfo; AttributePath::Parser path; err = path.Init(reader); SuccessOrExit(err); - err = path.GetNodeId(&(attributePathParams.mNodeId)); + err = path.GetNodeId(&(clusterInfo.mNodeId)); SuccessOrExit(err); - err = path.GetEndpointId(&(attributePathParams.mEndpointId)); + err = path.GetEndpointId(&(clusterInfo.mEndpointId)); SuccessOrExit(err); - err = path.GetClusterId(&(attributePathParams.mClusterId)); + err = path.GetClusterId(&(clusterInfo.mClusterId)); SuccessOrExit(err); - err = path.GetFieldId(&(attributePathParams.mFieldId)); + err = path.GetFieldId(&(clusterInfo.mFieldId)); + if (CHIP_NO_ERROR == err) + { + clusterInfo.mType = ClusterInfo::Type::kFieldIdValid; + } + else if (CHIP_END_OF_TLV == err) + { + err = path.GetListIndex(&(clusterInfo.mListIndex)); + SuccessOrExit(err); + clusterInfo.mType = ClusterInfo::Type::kListIndexValid; + } SuccessOrExit(err); - err = InteractionModelEngine::GetInstance()->PushFront(mpClusterInfoList, attributePathParams); + err = InteractionModelEngine::GetInstance()->PushFront(mpAttributeClusterInfoList, clusterInfo); SuccessOrExit(err); - mpClusterInfoList->SetDirty(); + mpAttributeClusterInfoList->SetDirty(); } // if we have exhausted this container if (CHIP_END_OF_TLV == err) @@ -207,6 +209,44 @@ CHIP_ERROR ReadHandler::ProcessAttributePathList(AttributePathList::Parser & aAt return err; } +CHIP_ERROR ReadHandler::ProcessEventPathList(EventPathList::Parser & aEventPathListParser) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + TLV::TLVReader reader; + aEventPathListParser.GetReader(&reader); + + while (CHIP_NO_ERROR == (err = reader.Next())) + { + VerifyOrExit(TLV::AnonymousTag == reader.GetTag(), err = CHIP_ERROR_INVALID_TLV_TAG); + VerifyOrExit(TLV::kTLVType_List == reader.GetType(), err = CHIP_ERROR_WRONG_TLV_TYPE); + ClusterInfo clusterInfo; + EventPath::Parser path; + err = path.Init(reader); + SuccessOrExit(err); + err = path.GetNodeId(&(clusterInfo.mNodeId)); + SuccessOrExit(err); + err = path.GetEndpointId(&(clusterInfo.mEndpointId)); + SuccessOrExit(err); + err = path.GetClusterId(&(clusterInfo.mClusterId)); + SuccessOrExit(err); + err = path.GetEventId(&(clusterInfo.mEventId)); + SuccessOrExit(err); + clusterInfo.mType = ClusterInfo::Type::kEventIdValid; + err = InteractionModelEngine::GetInstance()->PushFront(mpEventClusterInfoList, clusterInfo); + SuccessOrExit(err); + } + + // if we have exhausted this container + if (CHIP_END_OF_TLV == err) + { + err = CHIP_NO_ERROR; + } + +exit: + ChipLogFunctError(err); + return err; +} + const char * ReadHandler::GetStateStr() const { #if CHIP_DETAIL_LOGGING @@ -231,5 +271,46 @@ void ReadHandler::MoveToState(const HandlerState aTargetState) ChipLogDetail(DataManagement, "IM RH moving to [%s]", GetStateStr()); } +bool ReadHandler::CheckEventClean(EventManagement & aEventManager) +{ + if (mCurrentPriority == PriorityLevel::Invalid) + { + // Upload is not in middle, previous mLastScheduledEventNumber is not valid, Check for new events, and set a checkpoint + for (size_t index = 0; index < ArraySize(mSelfProcessedEvents); index++) + { + EventNumber lastEventNumber = aEventManager.GetLastEventNumber(static_cast(index)); + if ((lastEventNumber != 0) && (lastEventNumber >= mSelfProcessedEvents[index])) + { + // We have more events. snapshot last event IDs + aEventManager.SetScheduledEventEndpoint(&(mLastScheduledEventNumber[0])); + // initialize the next priority level to transfer + MoveToNextScheduledDirtyPriority(); + return false; + } + } + return true; + } + else + { + // Upload is in middle, previous mLastScheduledEventNumber is still valid, recheck via MoveToNextScheduledDirtyPriority, + // if finally mCurrentPriority is invalid, it means no more event + MoveToNextScheduledDirtyPriority(); + return mCurrentPriority == PriorityLevel::Invalid; + } +} + +void ReadHandler::MoveToNextScheduledDirtyPriority() +{ + for (uint8_t i = 0; i < ArraySize(mSelfProcessedEvents); i++) + { + if ((mLastScheduledEventNumber[i] != 0) && mSelfProcessedEvents[i] <= mLastScheduledEventNumber[i]) + { + mCurrentPriority = static_cast(i); + return; + } + } + + mCurrentPriority = PriorityLevel::Invalid; +} } // namespace app } // namespace chip diff --git a/src/app/ReadHandler.h b/src/app/ReadHandler.h index 2c8a3057d2d1ce..968bd0fcf8c312 100644 --- a/src/app/ReadHandler.h +++ b/src/app/ReadHandler.h @@ -25,6 +25,7 @@ #pragma once #include +#include #include #include #include @@ -100,7 +101,18 @@ class ReadHandler virtual ~ReadHandler() = default; - ClusterInfo * GetCluterInfolist() { return mpClusterInfoList; }; + ClusterInfo * GetAttributeClusterInfolist() { return mpAttributeClusterInfoList; } + ClusterInfo * GetEventClusterInfolist() { return mpEventClusterInfoList; } + EventNumber * GetVendedEventNumberList() { return mSelfProcessedEvents; } + PriorityLevel GetCurrentPriority() { return mCurrentPriority; } + + // if current priority is in the middle, it has valid snapshoted last event number, it check cleaness via comparing + // with snapshotted last event number. if current priority is in the end, no valid + // sanpshotted last event, check with latest last event number, re-setup snapshoted checkpoint, and compare again. + bool CheckEventClean(EventManagement & aEventManager); + + // Move to the next dirty priority where last schedule event number is larger than current self vended event number + void MoveToNextScheduledDirtyPriority(); private: enum class HandlerState @@ -112,6 +124,7 @@ class ReadHandler CHIP_ERROR ProcessReadRequest(System::PacketBufferHandle aPayload); CHIP_ERROR ProcessAttributePathList(AttributePathList::Parser & aAttributePathListParser); + CHIP_ERROR ProcessEventPathList(EventPathList::Parser & aEventPathListParser); void MoveToState(const HandlerState aTargetState); const char * GetStateStr() const; @@ -121,14 +134,20 @@ class ReadHandler InteractionModelDelegate * mpDelegate = nullptr; // Don't need the response for report data if true - bool mSuppressResponse; - - // Retrieve all events - bool mGetToAllEvents; + bool mSuppressResponse = false; // Current Handler state - HandlerState mState; - ClusterInfo * mpClusterInfoList = nullptr; + HandlerState mState = HandlerState::Uninitialized; + ClusterInfo * mpAttributeClusterInfoList = nullptr; + ClusterInfo * mpEventClusterInfoList = nullptr; + + PriorityLevel mCurrentPriority = PriorityLevel::Invalid; + + // The event number of the last processed event for each priority level + EventNumber mSelfProcessedEvents[kNumPriorityLevel]; + + // The last schedule event number snapshoted in the beginning when preparing to fill new events to reports + EventNumber mLastScheduledEventNumber[kNumPriorityLevel]; }; } // namespace app } // namespace chip diff --git a/src/app/reporting/Engine.cpp b/src/app/reporting/Engine.cpp index 332231ede3a8c2..71f00b1699ce77 100644 --- a/src/app/reporting/Engine.cpp +++ b/src/app/reporting/Engine.cpp @@ -37,23 +37,37 @@ CHIP_ERROR Engine::Init() return CHIP_NO_ERROR; } +EventNumber Engine::CountEvents(ReadHandler * apReadHandler, EventNumber * apInitialEvents) +{ + EventNumber event_count = 0; + EventNumber * vendedEventNumberList = apReadHandler->GetVendedEventNumberList(); + for (size_t index = 0; index < kNumPriorityLevel; index++) + { + if (vendedEventNumberList[index] > apInitialEvents[index]) + { + event_count += vendedEventNumberList[index] - apInitialEvents[index]; + } + } + return event_count; +} + CHIP_ERROR Engine::RetrieveClusterData(AttributeDataElement::Builder & aAttributeDataElementBuilder, ClusterInfo & aClusterInfo) { CHIP_ERROR err = CHIP_NO_ERROR; TLV::TLVType type = TLV::kTLVType_NotSpecified; AttributePath::Builder attributePathBuilder = aAttributeDataElementBuilder.CreateAttributePathBuilder(); - attributePathBuilder.NodeId(aClusterInfo.mAttributePathParams.mNodeId) - .EndpointId(aClusterInfo.mAttributePathParams.mEndpointId) - .ClusterId(aClusterInfo.mAttributePathParams.mClusterId) - .FieldId(aClusterInfo.mAttributePathParams.mFieldId) + attributePathBuilder.NodeId(aClusterInfo.mNodeId) + .EndpointId(aClusterInfo.mEndpointId) + .ClusterId(aClusterInfo.mClusterId) + .FieldId(aClusterInfo.mFieldId) .EndOfAttributePath(); err = attributePathBuilder.GetError(); SuccessOrExit(err); aAttributeDataElementBuilder.GetWriter()->StartContainer(TLV::ContextTag(AttributeDataElement::kCsTag_Data), TLV::kTLVType_Structure, type); - err = ReadSingleClusterData(aClusterInfo.mAttributePathParams, *(aAttributeDataElementBuilder.GetWriter())); + err = ReadSingleClusterData(aClusterInfo, *(aAttributeDataElementBuilder.GetWriter())); SuccessOrExit(err); aAttributeDataElementBuilder.GetWriter()->EndContainer(type); aAttributeDataElementBuilder.DataVersion(0).MoreClusterData(false).EndOfAttributeDataElement(); @@ -65,8 +79,7 @@ Engine::RetrieveClusterData(AttributeDataElement::Builder & aAttributeDataElemen if (err != CHIP_NO_ERROR) { - ChipLogError(DataManagement, "Error retrieving data from clusterId: %08x, err = %d", - aClusterInfo.mAttributePathParams.mClusterId, err); + ChipLogError(DataManagement, "Error retrieving data from clusterId: %08x, err = %d", aClusterInfo.mClusterId, err); } return err; @@ -75,17 +88,16 @@ Engine::RetrieveClusterData(AttributeDataElement::Builder & aAttributeDataElemen CHIP_ERROR Engine::BuildSingleReportDataAttributeDataList(ReportData::Builder & reportDataBuilder, ReadHandler * apReadHandler) { CHIP_ERROR err = CHIP_NO_ERROR; - ClusterInfo * clusterInfo = apReadHandler->GetCluterInfolist(); + ClusterInfo * clusterInfo = apReadHandler->GetAttributeClusterInfolist(); AttributeDataList::Builder attributeDataList = reportDataBuilder.CreateAttributeDataListBuilder(); - SuccessOrExit(reportDataBuilder.GetError()); + SuccessOrExit(err = reportDataBuilder.GetError()); // TODO: Need to handle multiple chunk of message while (clusterInfo != nullptr) { if (clusterInfo->IsDirty()) { AttributeDataElement::Builder attributeDataElementBuilder = attributeDataList.CreateAttributeDataElementBuilder(); - ChipLogDetail(DataManagement, " Cluster %u, Field %u is dirty", clusterInfo->mAttributePathParams.mClusterId, - clusterInfo->mAttributePathParams.mFieldId); + ChipLogDetail(DataManagement, " Cluster %u, Field %u is dirty", clusterInfo->mClusterId, clusterInfo->mFieldId); // Retrieve data for this cluster instance and clear its dirty flag. err = RetrieveClusterData(attributeDataElementBuilder, *clusterInfo); VerifyOrExit(err == CHIP_NO_ERROR, @@ -94,12 +106,123 @@ CHIP_ERROR Engine::BuildSingleReportDataAttributeDataList(ReportData::Builder & clusterInfo = clusterInfo->mpNext; } + attributeDataList.EndOfAttributeDataList(); + err = attributeDataList.GetError(); exit: ChipLogFunctError(err); return err; } +CHIP_ERROR Engine::BuildSingleReportDataEventList(ReportData::Builder & aReportDataBuilder, ReadHandler * apReadHandler) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + EventNumber eventCount = 0; + TLV::TLVWriter backup; + bool eventClean = true; + EventNumber initialEvents[kNumPriorityLevel]; + ClusterInfo * clusterInfoList = apReadHandler->GetEventClusterInfolist(); + EventNumber * eventNumberList = apReadHandler->GetVendedEventNumberList(); + EventManagement & eventManager = EventManagement::GetInstance(); + EventList::Builder eventList; + + VerifyOrExit(clusterInfoList != nullptr, ); + + aReportDataBuilder.Checkpoint(backup); + + VerifyOrExit(apReadHandler != nullptr, err = CHIP_ERROR_INVALID_ARGUMENT); + + eventList = aReportDataBuilder.CreateEventDataListBuilder(); + SuccessOrExit(err = eventList.GetError()); + + memcpy(initialEvents, eventNumberList, sizeof(initialEvents)); + // If the eventManager is not valid or has not been initialized, + // skip the rest of processing + VerifyOrExit(eventManager.IsValid(), err = CHIP_ERROR_INCORRECT_STATE); + + for (size_t index = 0; index < kNumPriorityLevel; index++) + { + EventNumber tmpNumber = eventManager.GetFirstEventNumber(static_cast(index)); + if (tmpNumber > initialEvents[index]) + { + initialEvents[index] = tmpNumber; + } + } + + eventClean = apReadHandler->CheckEventClean(eventManager); + + // proceed only if there are new events. + if (eventClean) + { + aReportDataBuilder.Rollback(backup); + ExitNow(); // Read clean, move along + } + + while (apReadHandler->GetCurrentPriority() != PriorityLevel::Invalid) + { + uint8_t priorityIndex = static_cast(apReadHandler->GetCurrentPriority()); + err = eventManager.FetchEventsSince(*(eventList.GetWriter()), clusterInfoList, apReadHandler->GetCurrentPriority(), + eventNumberList[priorityIndex]); + + if ((err == CHIP_END_OF_TLV) || (err == CHIP_ERROR_TLV_UNDERRUN) || (err == CHIP_NO_ERROR)) + { + // We have successfully reached the end of the log for + // the current priority. Advance to the next + // priority level. + err = CHIP_NO_ERROR; + apReadHandler->MoveToNextScheduledDirtyPriority(); + mMoreChunkedMessages = false; + } + else if ((err == CHIP_ERROR_BUFFER_TOO_SMALL) || (err == CHIP_ERROR_NO_MEMORY)) + { + eventCount = CountEvents(apReadHandler, initialEvents); + + // when first cluster event is too big to fit in the packet, ignore that cluster event. + if (eventCount == 0) + { + eventNumberList[priorityIndex]++; + ChipLogDetail(DataManagement, " first cluster event is too big so that it fails to fit in the packet!"); + err = CHIP_NO_ERROR; + } + else + { + // `FetchEventsSince` has filled the available space + // within the allowed buffer before it fit all the + // available events. This is an expected condition, + // so we do not propagate the error to higher levels; + // instead, we terminate the event processing for now + // (we will get another chance immediately afterwards, + // with a ew buffer) and do not advance the processing + // to the next priority level. + err = CHIP_NO_ERROR; + break; + } + mMoreChunkedMessages = true; + } + else + { + // All other errors are propagated to higher level. + // Exiting here and returning an error will lead to + // abandoning subscription. + ExitNow(); + } + } + + eventList.EndOfEventList(); + SuccessOrExit(err = eventList.GetError()); + + eventCount = CountEvents(apReadHandler, initialEvents); + ChipLogDetail(DataManagement, "Fetched %d events", eventCount); + +exit: + if (err != CHIP_NO_ERROR) + { + ChipLogError(DataManagement, "Error retrieving events, err = %d", err); + } + + return err; +} + CHIP_ERROR Engine::BuildAndSendSingleReportData(ReadHandler * apReadHandler) { CHIP_ERROR err = CHIP_NO_ERROR; @@ -117,9 +240,9 @@ CHIP_ERROR Engine::BuildAndSendSingleReportData(ReadHandler * apReadHandler) err = BuildSingleReportDataAttributeDataList(reportDataBuilder, apReadHandler); SuccessOrExit(err); - // TODO: Fill in the EventList. - // err = BuildSingleReportDataEventList(reportDataBuilder, apReadHandler); - // SuccessOrExit(err); + + err = BuildSingleReportDataEventList(reportDataBuilder, apReadHandler); + SuccessOrExit(err); // TODO: Add mechanism to set mSuppressResponse to handle status reports for multiple reports // TODO: Add more chunk message support, currently mMoreChunkedMessages is always false. @@ -129,7 +252,7 @@ CHIP_ERROR Engine::BuildAndSendSingleReportData(ReadHandler * apReadHandler) } reportDataBuilder.EndOfReportData(); - SuccessOrExit(reportDataBuilder.GetError()); + SuccessOrExit(err = reportDataBuilder.GetError()); err = reportDataWriter.Finalize(&bufHandle); SuccessOrExit(err); diff --git a/src/app/reporting/Engine.h b/src/app/reporting/Engine.h index 9c41172e5e2c25..efa0d5a56f5f9e 100644 --- a/src/app/reporting/Engine.h +++ b/src/app/reporting/Engine.h @@ -79,8 +79,10 @@ class Engine CHIP_ERROR BuildAndSendSingleReportData(ReadHandler * apReadHandler); CHIP_ERROR BuildSingleReportDataAttributeDataList(ReportData::Builder & reportDataBuilder, ReadHandler * apReadHandler); - + CHIP_ERROR BuildSingleReportDataEventList(ReportData::Builder & reportDataBuilder, ReadHandler * apReadHandler); CHIP_ERROR RetrieveClusterData(AttributeDataElement::Builder & aAttributeDataElementBuilder, ClusterInfo & aClusterInfo); + EventNumber CountEvents(ReadHandler * apReadHandler, EventNumber * apInitialEvents); + /** * Send Report via ReadHandler * diff --git a/src/app/tests/TestClusterInfo.cpp b/src/app/tests/TestClusterInfo.cpp index 0fcca3490c36ae..16a19a22b5bfac 100644 --- a/src/app/tests/TestClusterInfo.cpp +++ b/src/app/tests/TestClusterInfo.cpp @@ -29,28 +29,9 @@ namespace chip { namespace app { namespace TestClusterInfo { -void TestSamePath(nlTestSuite * apSuite, void * apContext) -{ - AttributePathParams attributePathParams1(1, 2, 3, 4, 5, AttributePathFlags::kFieldIdValid); - AttributePathParams attributePathParams2(1, 2, 3, 4, 5, AttributePathFlags::kFieldIdValid); - ClusterInfo clusterInfo1(attributePathParams1, false); - ClusterInfo clusterInfo2(attributePathParams2, false); - NL_TEST_ASSERT(apSuite, clusterInfo1.IsSamePath(clusterInfo2)); -} - -void TestDifferentPath(nlTestSuite * apSuite, void * apContext) -{ - AttributePathParams attributePathParams1(1, 2, 3, 4, 5, AttributePathFlags::kFieldIdValid); - AttributePathParams attributePathParams2(6, 2, 3, 4, 5, AttributePathFlags::kFieldIdValid); - ClusterInfo clusterInfo1(attributePathParams1, false); - ClusterInfo clusterInfo2(attributePathParams2, false); - NL_TEST_ASSERT(apSuite, !clusterInfo1.IsSamePath(clusterInfo2)); -} - void TestDirty(nlTestSuite * apSuite, void * apContext) { - AttributePathParams attributePathParams1(1, 2, 3, 4, 5, AttributePathFlags::kFieldIdValid); - ClusterInfo clusterInfo1(attributePathParams1, false); + ClusterInfo clusterInfo1; clusterInfo1.SetDirty(); NL_TEST_ASSERT(apSuite, clusterInfo1.IsDirty()); clusterInfo1.ClearDirty(); @@ -61,9 +42,7 @@ void TestDirty(nlTestSuite * apSuite, void * apContext) } // namespace chip namespace { -const nlTest sTests[] = { NL_TEST_DEF("TestSamePath", chip::app::TestClusterInfo::TestSamePath), - NL_TEST_DEF("TestDifferentPath", chip::app::TestClusterInfo::TestDifferentPath), - NL_TEST_DEF("TestDirty", chip::app::TestClusterInfo::TestDirty), NL_TEST_SENTINEL() }; +const nlTest sTests[] = { NL_TEST_DEF("TestDirty", chip::app::TestClusterInfo::TestDirty), NL_TEST_SENTINEL() }; } int TestClusterInfo() diff --git a/src/app/tests/TestEventLogging.cpp b/src/app/tests/TestEventLogging.cpp index b7e46dcf06efac..e391ad7304bb69 100644 --- a/src/app/tests/TestEventLogging.cpp +++ b/src/app/tests/TestEventLogging.cpp @@ -22,6 +22,7 @@ * */ +#include #include #include #include @@ -145,8 +146,9 @@ static void CheckLogReadOut(nlTestSuite * apSuite, chip::app::EventManagement & uint8_t backingStore[1024]; size_t elementCount; writer.Init(backingStore, 1024); - - err = alogMgmt.FetchEventsSince(writer, priority, startingEventNumber); + chip::app::ClusterInfo testClusterInfo; + testClusterInfo.mEventId = 1; + err = alogMgmt.FetchEventsSince(writer, &testClusterInfo, priority, startingEventNumber); NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR || err == CHIP_END_OF_TLV); reader.Init(backingStore, writer.GetLengthWritten()); diff --git a/src/app/tests/TestInteractionModelEngine.cpp b/src/app/tests/TestInteractionModelEngine.cpp index 098bf6330bb7c4..d6d043120e4fb6 100644 --- a/src/app/tests/TestInteractionModelEngine.cpp +++ b/src/app/tests/TestInteractionModelEngine.cpp @@ -76,20 +76,24 @@ void TestInteractionModelEngine::TestClusterInfoPushRelease(nlTestSuite * apSuit err = InteractionModelEngine::GetInstance()->Init(&gExchangeManager, nullptr); NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); ClusterInfo * clusterInfoList = nullptr; - AttributePathParams attributePathParams1(1, 2, 3, 4, 5, AttributePathFlags::kFieldIdValid); - AttributePathParams attributePathParams2(2, 3, 4, 5, 6, AttributePathFlags::kFieldIdValid); - AttributePathParams attributePathParams3(3, 4, 5, 6, 7, AttributePathFlags::kFieldIdValid); + ClusterInfo clusterInfo1; + ClusterInfo clusterInfo2; + ClusterInfo clusterInfo3; - InteractionModelEngine::GetInstance()->PushFront(clusterInfoList, attributePathParams1); - NL_TEST_ASSERT(apSuite, clusterInfoList != nullptr && clusterInfoList->mAttributePathParams.IsSamePath(attributePathParams1)); + clusterInfo1.mEndpointId = 1; + clusterInfo2.mEndpointId = 2; + clusterInfo3.mEndpointId = 3; + + InteractionModelEngine::GetInstance()->PushFront(clusterInfoList, clusterInfo1); + NL_TEST_ASSERT(apSuite, clusterInfoList != nullptr && clusterInfo1.mEndpointId == clusterInfoList->mEndpointId); NL_TEST_ASSERT(apSuite, GetClusterInfoListLength(clusterInfoList) == 1); - InteractionModelEngine::GetInstance()->PushFront(clusterInfoList, attributePathParams2); - NL_TEST_ASSERT(apSuite, clusterInfoList != nullptr && clusterInfoList->mAttributePathParams.IsSamePath(attributePathParams2)); + InteractionModelEngine::GetInstance()->PushFront(clusterInfoList, clusterInfo2); + NL_TEST_ASSERT(apSuite, clusterInfoList != nullptr && clusterInfo2.mEndpointId == clusterInfoList->mEndpointId); NL_TEST_ASSERT(apSuite, GetClusterInfoListLength(clusterInfoList) == 2); - InteractionModelEngine::GetInstance()->PushFront(clusterInfoList, attributePathParams3); - NL_TEST_ASSERT(apSuite, clusterInfoList != nullptr && clusterInfoList->mAttributePathParams.IsSamePath(attributePathParams3)); + InteractionModelEngine::GetInstance()->PushFront(clusterInfoList, clusterInfo3); + NL_TEST_ASSERT(apSuite, clusterInfoList != nullptr && clusterInfo3.mEndpointId == clusterInfoList->mEndpointId); NL_TEST_ASSERT(apSuite, GetClusterInfoListLength(clusterInfoList) == 3); InteractionModelEngine::GetInstance()->ReleaseClusterInfoList(clusterInfoList); diff --git a/src/app/tests/TestReadInteraction.cpp b/src/app/tests/TestReadInteraction.cpp index 4df7aa083a7bbf..7af271004eef78 100644 --- a/src/app/tests/TestReadInteraction.cpp +++ b/src/app/tests/TestReadInteraction.cpp @@ -88,13 +88,15 @@ void TestReadInteraction::TestReadClient(nlTestSuite * apSuite, void * apContext CHIP_ERROR err = CHIP_NO_ERROR; app::ReadClient readClient; + EventNumber eventNumber = 0; System::PacketBufferHandle buf = System::PacketBufferHandle::New(System::PacketBuffer::kMaxSize); err = readClient.Init(&gExchangeManager, nullptr); NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); err = readClient.SendReadRequest(kTestDeviceNodeId, gAdminId, nullptr /*apEventPathParamsList*/, 0 /*aEventPathParamsListSize*/, - nullptr /*apAttributePathParamsList*/, 0 /*aAttributePathParamsListSize*/); + nullptr /*apAttributePathParamsList*/, 0 /*aAttributePathParamsListSize*/, + eventNumber /*aEventNumber*/); NL_TEST_ASSERT(apSuite, err == CHIP_ERROR_INCORRECT_STATE); GenerateReportData(apSuite, apContext, buf); diff --git a/src/app/tests/integration/MockEvents.cpp b/src/app/tests/integration/MockEvents.cpp index d38a3978c3dec7..bd57eb3d97f3bf 100644 --- a/src/app/tests/integration/MockEvents.cpp +++ b/src/app/tests/integration/MockEvents.cpp @@ -24,6 +24,7 @@ */ #include "MockEvents.h" +#include "common.h" #include #include #include @@ -31,15 +32,11 @@ #include #include #include +#include -static const chip::NodeId kTestNodeId = 0x18B4300000000001ULL; -static const chip::NodeId kTestNodeId1 = 0x18B4300000000002ULL; -static const chip::ClusterId kLivenessClusterId = 0x00000022; -static const uint32_t kLivenessChangeEvent = 1; -static const chip::EndpointId kTestEndpointId = 2; -static const uint64_t kLivenessDeviceStatus = chip::TLV::ContextTag(1); -static bool gMockEventStop = false; -static bool gEventIsStopped = false; +static uint64_t kLivenessDeviceStatus = chip::TLV::ContextTag(1); +static bool gMockEventStop = false; +static bool gEventIsStopped = false; EventGenerator::EventGenerator(size_t aNumStates, size_t aInitialState) : mNumStates(aNumStates), mState(aInitialState) {} @@ -56,43 +53,43 @@ void LivenessEventGenerator::Generate(void) switch (mState) { case 0: - LogLiveness(kTestNodeId, kTestEndpointId, LIVENESS_DEVICE_STATUS_ONLINE); + LogLiveness(chip::kTestDeviceNodeId, kTestEndpointId, LIVENESS_DEVICE_STATUS_ONLINE); break; case 1: - LogLiveness(kTestNodeId1, kTestEndpointId, LIVENESS_DEVICE_STATUS_ONLINE); + LogLiveness(chip::kTestDeviceNodeId, kTestEndpointId, LIVENESS_DEVICE_STATUS_ONLINE); break; case 2: - LogLiveness(kTestNodeId, kTestEndpointId, LIVENESS_DEVICE_STATUS_ONLINE); + LogLiveness(chip::kTestDeviceNodeId, kTestEndpointId, LIVENESS_DEVICE_STATUS_ONLINE); break; case 3: - LogLiveness(kTestNodeId1, kTestEndpointId, LIVENESS_DEVICE_STATUS_UNREACHABLE); + LogLiveness(chip::kTestDeviceNodeId, kTestEndpointId, LIVENESS_DEVICE_STATUS_UNREACHABLE); break; case 4: - LogLiveness(kTestNodeId, kTestEndpointId, LIVENESS_DEVICE_STATUS_ONLINE); + LogLiveness(chip::kTestDeviceNodeId, kTestEndpointId, LIVENESS_DEVICE_STATUS_ONLINE); break; case 5: - LogLiveness(kTestNodeId1, kTestEndpointId, LIVENESS_DEVICE_STATUS_REBOOTING); + LogLiveness(chip::kTestDeviceNodeId, kTestEndpointId, LIVENESS_DEVICE_STATUS_REBOOTING); break; case 6: - LogLiveness(kTestNodeId, kTestEndpointId, LIVENESS_DEVICE_STATUS_ONLINE); + LogLiveness(chip::kTestDeviceNodeId, kTestEndpointId, LIVENESS_DEVICE_STATUS_ONLINE); break; case 7: - LogLiveness(kTestNodeId1, kTestEndpointId, LIVENESS_DEVICE_STATUS_ONLINE); + LogLiveness(chip::kTestDeviceNodeId, kTestEndpointId, LIVENESS_DEVICE_STATUS_ONLINE); break; case 8: - LogLiveness(kTestNodeId, kTestEndpointId, LIVENESS_DEVICE_STATUS_ONLINE); + LogLiveness(chip::kTestDeviceNodeId, kTestEndpointId, LIVENESS_DEVICE_STATUS_ONLINE); break; case 9: - LogLiveness(kTestNodeId1, kTestEndpointId, LIVENESS_DEVICE_STATUS_ONLINE); + LogLiveness(chip::kTestDeviceNodeId, kTestEndpointId, LIVENESS_DEVICE_STATUS_ONLINE); break; default: @@ -115,7 +112,7 @@ chip::EventNumber LivenessEventGenerator::LogLiveness(chip::NodeId aNodeId, chip chip::app::EventManagement & logManager = chip::app::EventManagement::GetInstance(); chip::EventNumber number = 0; chip::app::EventSchema schema = { - aNodeId, aEndpointId, kLivenessClusterId, kLivenessChangeEvent, chip::app::PriorityLevel::Critical, + aNodeId, aEndpointId, kTestClusterId, kLivenessChangeEvent, chip::app::PriorityLevel::Critical, }; chip::app::EventOptions options; mStatus = static_cast(aStatus); diff --git a/src/app/tests/integration/chip_im_initiator.cpp b/src/app/tests/integration/chip_im_initiator.cpp index ebeed0df259bec..d1ac99de60b580 100644 --- a/src/app/tests/integration/chip_im_initiator.cpp +++ b/src/app/tests/integration/chip_im_initiator.cpp @@ -128,13 +128,17 @@ CHIP_ERROR SendCommandRequest(void) CHIP_ERROR SendReadRequest(void) { - CHIP_ERROR err = CHIP_NO_ERROR; + CHIP_ERROR err = CHIP_NO_ERROR; + chip::EventNumber number = 0; + chip::app::EventPathParams eventPathParams(chip::kTestDeviceNodeId, kTestEndpointId, kTestClusterId, kLivenessChangeEvent, + false /*not urgent*/); + chip::app::AttributePathParams attributePathParams(chip::kTestDeviceNodeId, kTestEndpointId, kTestClusterId, 1, 0, chip::app::AttributePathFlags::kFieldIdValid); printf("\nSend read request message to Node: %" PRIu64 "\n", chip::kTestDeviceNodeId); - err = gpReadClient->SendReadRequest(chip::kTestDeviceNodeId, gAdminId, nullptr, 0, &attributePathParams, 1); + err = gpReadClient->SendReadRequest(chip::kTestDeviceNodeId, gAdminId, &eventPathParams, 1, &attributePathParams, 1, number); SuccessOrExit(err); if (err == CHIP_NO_ERROR) @@ -265,9 +269,9 @@ void DispatchSingleClusterCommand(chip::ClusterId aClusterId, chip::CommandId aC } } -CHIP_ERROR WriteSingleClusterData(AttributePathParams & aAttributePathParams, TLV::TLVReader & aReader) +CHIP_ERROR WriteSingleClusterData(ClusterInfo & aClusterInfo, TLV::TLVReader & aReader) { - if (aAttributePathParams.mClusterId != kTestClusterId || aAttributePathParams.mEndpointId != kTestEndpointId) + if (aClusterInfo.mClusterId != kTestClusterId || aClusterInfo.mEndpointId != kTestEndpointId) { return CHIP_ERROR_INVALID_ARGUMENT; } diff --git a/src/app/tests/integration/chip_im_responder.cpp b/src/app/tests/integration/chip_im_responder.cpp index c3c1bcfdd60157..2273c8c75c3acc 100644 --- a/src/app/tests/integration/chip_im_responder.cpp +++ b/src/app/tests/integration/chip_im_responder.cpp @@ -97,18 +97,18 @@ void DispatchSingleClusterCommand(chip::ClusterId aClusterId, chip::CommandId aC return; } -CHIP_ERROR ReadSingleClusterData(AttributePathParams & aAttributePathParams, TLV::TLVWriter & aWriter) +CHIP_ERROR ReadSingleClusterData(ClusterInfo & aClusterInfo, TLV::TLVWriter & aWriter) { CHIP_ERROR err = CHIP_NO_ERROR; - VerifyOrExit(aAttributePathParams.mClusterId == kTestClusterId && aAttributePathParams.mEndpointId == kTestEndpointId, + VerifyOrExit(aClusterInfo.mClusterId == kTestClusterId && aClusterInfo.mEndpointId == kTestEndpointId, err = CHIP_ERROR_INVALID_ARGUMENT); - if (aAttributePathParams.mFieldId == kRootFieldId || aAttributePathParams.mFieldId == 1) + if (aClusterInfo.mFieldId == kRootFieldId || aClusterInfo.mFieldId == 1) { err = aWriter.Put(TLV::ContextTag(kTestFieldId1), kTestFieldValue1); SuccessOrExit(err); } - if (aAttributePathParams.mFieldId == kRootFieldId || aAttributePathParams.mFieldId == 2) + if (aClusterInfo.mFieldId == kRootFieldId || aClusterInfo.mFieldId == 2) { err = aWriter.Put(TLV::ContextTag(kTestFieldId2), kTestFieldValue2); SuccessOrExit(err); diff --git a/src/app/tests/integration/common.h b/src/app/tests/integration/common.h index 2b69ebf07e2565..97c1ceea3108e8 100644 --- a/src/app/tests/integration/common.h +++ b/src/app/tests/integration/common.h @@ -32,14 +32,15 @@ extern chip::Messaging::ExchangeManager gExchangeManager; -constexpr chip::ClusterId kTestClusterId = 6; -constexpr chip::CommandId kTestCommandId = 40; -constexpr chip::EndpointId kTestEndpointId = 1; -constexpr chip::GroupId kTestGroupId = 0; -constexpr chip::FieldId kTestFieldId1 = 1; -constexpr chip::FieldId kTestFieldId2 = 2; -constexpr uint8_t kTestFieldValue1 = 1; -constexpr uint8_t kTestFieldValue2 = 2; +constexpr chip::ClusterId kTestClusterId = 6; +constexpr chip::CommandId kTestCommandId = 40; +constexpr chip::EndpointId kTestEndpointId = 1; +constexpr chip::GroupId kTestGroupId = 0; +constexpr chip::FieldId kTestFieldId1 = 1; +constexpr chip::FieldId kTestFieldId2 = 2; +constexpr uint8_t kTestFieldValue1 = 1; +constexpr uint8_t kTestFieldValue2 = 2; +constexpr chip::EventId kLivenessChangeEvent = 1; void InitializeChip(void); void ShutdownChip(void); void TLVPrettyPrinter(const char * aFormat, ...); diff --git a/src/controller/CHIPDeviceController.cpp b/src/controller/CHIPDeviceController.cpp index 6e12937efe5253..fc1d9825664d46 100644 --- a/src/controller/CHIPDeviceController.cpp +++ b/src/controller/CHIPDeviceController.cpp @@ -1074,3 +1074,25 @@ void DeviceCommissioner::OnSessionEstablishmentTimeoutCallback(System::Layer * a } // namespace Controller } // namespace chip + +namespace chip { +namespace Platform { +namespace PersistedStorage { + +/* +* Dummy implementations of PersistedStorage platform methods. These aren't +* used in the context of the Device Controller, but are required to satisfy +* the linker. +*/ + +CHIP_ERROR Read(const char *aKey, uint32_t &aValue) { + return CHIP_NO_ERROR; +} + +CHIP_ERROR Write(const char *aKey, uint32_t aValue) { + return CHIP_NO_ERROR; +} + +} +} +}