yunhanw-google | ef040a7 | 2021-05-05 07:17:56 -0700 | [diff] [blame] | 1 | /** |
| 2 | * |
| 3 | * Copyright (c) 2021 Project CHIP Authors |
| 4 | * Copyright (c) 2015-2017 Nest Labs, Inc. |
| 5 | * |
| 6 | * Licensed under the Apache License, Version 2.0 (the "License"); |
| 7 | * you may not use this file except in compliance with the License. |
| 8 | * You may obtain a copy of the License at |
| 9 | * |
| 10 | * http://www.apache.org/licenses/LICENSE-2.0 |
| 11 | * |
| 12 | * Unless required by applicable law or agreed to in writing, software |
| 13 | * distributed under the License is distributed on an "AS IS" BASIS, |
| 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 15 | * See the License for the specific language governing permissions and |
| 16 | * limitations under the License. |
| 17 | */ |
| 18 | |
Song GUO | 1ccc2af | 2022-03-03 01:53:33 +0800 | [diff] [blame] | 19 | #include <access/AccessControl.h> |
| 20 | #include <access/RequestPath.h> |
| 21 | #include <access/SubjectDescriptor.h> |
yunhanw-google | ef040a7 | 2021-05-05 07:17:56 -0700 | [diff] [blame] | 22 | #include <app/EventManagement.h> |
| 23 | #include <app/InteractionModelEngine.h> |
Song GUO | 1ccc2af | 2022-03-03 01:53:33 +0800 | [diff] [blame] | 24 | #include <app/RequiredPrivilege.h> |
yunhanw-google | 07fc8cd | 2022-03-24 01:41:28 -0700 | [diff] [blame] | 25 | #include <assert.h> |
yunhanw-google | ef040a7 | 2021-05-05 07:17:56 -0700 | [diff] [blame] | 26 | #include <inttypes.h> |
Martin Turon | 82bfcd5 | 2023-01-09 13:30:38 -0800 | [diff] [blame] | 27 | #include <lib/core/TLVUtilities.h> |
Zang MingJie | 53dd583 | 2021-09-03 03:05:16 +0800 | [diff] [blame] | 28 | #include <lib/support/CodeUtils.h> |
Zang MingJie | 53dd583 | 2021-09-03 03:05:16 +0800 | [diff] [blame] | 29 | #include <lib/support/logging/CHIPLogging.h> |
yunhanw-google | ef040a7 | 2021-05-05 07:17:56 -0700 | [diff] [blame] | 30 | |
| 31 | using namespace chip::TLV; |
| 32 | |
| 33 | namespace chip { |
| 34 | namespace app { |
Justin Wood | 3c96d5b | 2024-07-10 11:20:24 -1000 | [diff] [blame] | 35 | static EventManagement sInstance; |
yunhanw-google | ef040a7 | 2021-05-05 07:17:56 -0700 | [diff] [blame] | 36 | |
| 37 | /** |
| 38 | * @brief |
| 39 | * A TLVReader backed by CircularEventBuffer |
| 40 | */ |
| 41 | class CircularEventReader : public TLV::TLVReader |
| 42 | { |
| 43 | public: |
| 44 | /** |
| 45 | * @brief |
| 46 | * Initializes a TLVReader object backed by CircularEventBuffer |
| 47 | * |
| 48 | * Reading begins in the CircularTLVBuffer belonging to this |
| 49 | * CircularEventBuffer. When the reader runs out of data, it begins |
| 50 | * to read from the previous CircularEventBuffer. |
| 51 | * |
| 52 | * @param[in] apBuf A pointer to a fully initialized CircularEventBuffer |
| 53 | * |
| 54 | */ |
| 55 | void Init(CircularEventBufferWrapper * apBuf); |
| 56 | |
| 57 | virtual ~CircularEventReader() = default; |
| 58 | }; |
| 59 | |
Arkadiusz Bokowy | 52e228f | 2022-11-29 12:42:40 +0100 | [diff] [blame] | 60 | EventManagement & EventManagement::GetInstance() |
yunhanw-google | ef040a7 | 2021-05-05 07:17:56 -0700 | [diff] [blame] | 61 | { |
| 62 | return sInstance; |
| 63 | } |
| 64 | |
| 65 | struct ReclaimEventCtx |
| 66 | { |
| 67 | CircularEventBuffer * mpEventBuffer = nullptr; |
| 68 | size_t mSpaceNeededForMovedEvent = 0; |
| 69 | }; |
| 70 | |
| 71 | /** |
| 72 | * @brief |
| 73 | * Internal structure for traversing event list. |
| 74 | */ |
| 75 | struct CopyAndAdjustDeltaTimeContext |
| 76 | { |
| 77 | CopyAndAdjustDeltaTimeContext(TLVWriter * aWriter, EventLoadOutContext * inContext) : mpWriter(aWriter), mpContext(inContext) {} |
| 78 | |
| 79 | TLV::TLVWriter * mpWriter = nullptr; |
| 80 | EventLoadOutContext * mpContext = nullptr; |
| 81 | }; |
| 82 | |
yunhanw-google | 2423a26 | 2021-06-07 14:06:34 -0700 | [diff] [blame] | 83 | void EventManagement::Init(Messaging::ExchangeManager * apExchangeManager, uint32_t aNumBuffers, |
yunhanw-google | 9a74bae | 2021-12-15 13:33:05 -0800 | [diff] [blame] | 84 | CircularEventBuffer * apCircularEventBuffer, const LogStorageResources * const apLogStorageResources, |
Boris Zbarsky | 7c77e8e | 2023-02-23 11:23:27 -0500 | [diff] [blame] | 85 | MonotonicallyIncreasingCounter<EventNumber> * apEventNumberCounter, |
| 86 | System::Clock::Milliseconds64 aMonotonicStartupTime) |
yunhanw-google | ef040a7 | 2021-05-05 07:17:56 -0700 | [diff] [blame] | 87 | { |
| 88 | CircularEventBuffer * current = nullptr; |
| 89 | CircularEventBuffer * prev = nullptr; |
| 90 | CircularEventBuffer * next = nullptr; |
| 91 | |
yunhanw-google | 2423a26 | 2021-06-07 14:06:34 -0700 | [diff] [blame] | 92 | if (aNumBuffers == 0) |
| 93 | { |
| 94 | ChipLogError(EventLogging, "Invalid aNumBuffers"); |
| 95 | return; |
| 96 | } |
yunhanw-google | ef040a7 | 2021-05-05 07:17:56 -0700 | [diff] [blame] | 97 | |
yunhanw-google | 2423a26 | 2021-06-07 14:06:34 -0700 | [diff] [blame] | 98 | if (mState != EventManagementStates::Shutdown) |
| 99 | { |
| 100 | ChipLogError(EventLogging, "Invalid EventManagement State"); |
| 101 | return; |
| 102 | } |
yunhanw-google | ef040a7 | 2021-05-05 07:17:56 -0700 | [diff] [blame] | 103 | mpExchangeMgr = apExchangeManager; |
| 104 | |
yunhanw-google | 2423a26 | 2021-06-07 14:06:34 -0700 | [diff] [blame] | 105 | for (uint32_t bufferIndex = 0; bufferIndex < aNumBuffers; bufferIndex++) |
yunhanw-google | ef040a7 | 2021-05-05 07:17:56 -0700 | [diff] [blame] | 106 | { |
| 107 | next = (bufferIndex < aNumBuffers - 1) ? &apCircularEventBuffer[bufferIndex + 1] : nullptr; |
| 108 | |
| 109 | current = &apCircularEventBuffer[bufferIndex]; |
| 110 | current->Init(apLogStorageResources[bufferIndex].mpBuffer, apLogStorageResources[bufferIndex].mBufferSize, prev, next, |
| 111 | apLogStorageResources[bufferIndex].mPriority); |
| 112 | |
| 113 | prev = current; |
| 114 | |
yunhanw-google | a6e4d4b | 2022-03-02 10:33:30 -0800 | [diff] [blame] | 115 | current->mProcessEvictedElement = nullptr; |
yunhanw-google | ef040a7 | 2021-05-05 07:17:56 -0700 | [diff] [blame] | 116 | current->mAppData = nullptr; |
yunhanw-google | ef040a7 | 2021-05-05 07:17:56 -0700 | [diff] [blame] | 117 | } |
| 118 | |
Boris Zbarsky | cc3a98c | 2022-04-14 23:15:16 -0400 | [diff] [blame] | 119 | mpEventNumberCounter = apEventNumberCounter; |
| 120 | mLastEventNumber = mpEventNumberCounter->GetValue(); |
yunhanw-google | 9a74bae | 2021-12-15 13:33:05 -0800 | [diff] [blame] | 121 | |
yunhanw-google | ef040a7 | 2021-05-05 07:17:56 -0700 | [diff] [blame] | 122 | mpEventBuffer = apCircularEventBuffer; |
| 123 | mState = EventManagementStates::Idle; |
| 124 | mBytesWritten = 0; |
Boris Zbarsky | 7c77e8e | 2023-02-23 11:23:27 -0500 | [diff] [blame] | 125 | |
| 126 | mMonotonicStartupTime = aMonotonicStartupTime; |
yunhanw-google | ef040a7 | 2021-05-05 07:17:56 -0700 | [diff] [blame] | 127 | } |
| 128 | |
| 129 | CHIP_ERROR EventManagement::CopyToNextBuffer(CircularEventBuffer * apEventBuffer) |
| 130 | { |
| 131 | CircularTLVWriter writer; |
| 132 | CircularTLVReader reader; |
| 133 | CHIP_ERROR err = CHIP_NO_ERROR; |
| 134 | CircularEventBuffer * nextBuffer = apEventBuffer->GetNextCircularEventBuffer(); |
| 135 | if (nextBuffer == nullptr) |
| 136 | { |
| 137 | return CHIP_ERROR_INVALID_ARGUMENT; |
| 138 | } |
| 139 | CircularEventBuffer backup = *nextBuffer; |
| 140 | |
| 141 | // Set up the next buffer s.t. it fails if needs to evict an element |
| 142 | nextBuffer->mProcessEvictedElement = AlwaysFail; |
| 143 | |
| 144 | writer.Init(*nextBuffer); |
| 145 | |
| 146 | // Set up the reader s.t. it is positioned to read the head event |
| 147 | reader.Init(*apEventBuffer); |
| 148 | |
| 149 | err = reader.Next(); |
| 150 | SuccessOrExit(err); |
| 151 | |
| 152 | err = writer.CopyElement(reader); |
| 153 | SuccessOrExit(err); |
| 154 | |
| 155 | err = writer.Finalize(); |
| 156 | SuccessOrExit(err); |
| 157 | |
Kamil Kasperczyk | ae5a36a | 2022-03-23 09:54:22 +0100 | [diff] [blame] | 158 | ChipLogDetail(EventLogging, "Copy Event to next buffer with priority %u", static_cast<unsigned>(nextBuffer->GetPriority())); |
yunhanw-google | ef040a7 | 2021-05-05 07:17:56 -0700 | [diff] [blame] | 159 | exit: |
| 160 | if (err != CHIP_NO_ERROR) |
| 161 | { |
| 162 | *nextBuffer = backup; |
| 163 | } |
| 164 | return err; |
| 165 | } |
| 166 | |
Boris Zbarsky | b236bfb | 2023-02-23 11:51:11 -0500 | [diff] [blame] | 167 | CHIP_ERROR EventManagement::EnsureSpaceInCircularBuffer(size_t aRequiredSpace, PriorityLevel aPriority) |
yunhanw-google | ef040a7 | 2021-05-05 07:17:56 -0700 | [diff] [blame] | 168 | { |
| 169 | CHIP_ERROR err = CHIP_NO_ERROR; |
| 170 | size_t requiredSpace = aRequiredSpace; |
| 171 | CircularEventBuffer * eventBuffer = mpEventBuffer; |
| 172 | ReclaimEventCtx ctx; |
| 173 | |
Boris Zbarsky | b236bfb | 2023-02-23 11:51:11 -0500 | [diff] [blame] | 174 | // Check that we have this much space in all our event buffers that might |
| 175 | // hold the event. If we do not, that will prevent the event from being |
Arkadiusz Bokowy | 42b424d | 2023-06-07 17:50:19 +0200 | [diff] [blame] | 176 | // properly evicted into higher-priority buffers. We want to discover |
Boris Zbarsky | b236bfb | 2023-02-23 11:51:11 -0500 | [diff] [blame] | 177 | // this early, so that testing surfaces the need to make those buffers |
| 178 | // larger. |
| 179 | for (auto * currentBuffer = mpEventBuffer; currentBuffer; currentBuffer = currentBuffer->GetNextCircularEventBuffer()) |
| 180 | { |
| 181 | VerifyOrExit(requiredSpace <= currentBuffer->GetTotalDataLength(), err = CHIP_ERROR_BUFFER_TOO_SMALL); |
| 182 | if (currentBuffer->IsFinalDestinationForPriority(aPriority)) |
| 183 | { |
| 184 | break; |
| 185 | } |
| 186 | } |
| 187 | |
dependabot[bot] | c53bef2 | 2023-05-26 14:17:52 +0000 | [diff] [blame] | 188 | VerifyOrExit(eventBuffer != nullptr, err = CHIP_ERROR_INCORRECT_STATE); |
| 189 | |
yunhanw-google | ef040a7 | 2021-05-05 07:17:56 -0700 | [diff] [blame] | 190 | // check whether we actually need to do anything, exit if we don't |
| 191 | VerifyOrExit(requiredSpace > eventBuffer->AvailableDataLength(), err = CHIP_NO_ERROR); |
| 192 | |
| 193 | while (true) |
| 194 | { |
yunhanw-google | ef040a7 | 2021-05-05 07:17:56 -0700 | [diff] [blame] | 195 | if (requiredSpace > eventBuffer->AvailableDataLength()) |
| 196 | { |
| 197 | ctx.mpEventBuffer = eventBuffer; |
| 198 | ctx.mSpaceNeededForMovedEvent = 0; |
| 199 | |
| 200 | eventBuffer->mProcessEvictedElement = EvictEvent; |
| 201 | eventBuffer->mAppData = &ctx; |
| 202 | err = eventBuffer->EvictHead(); |
| 203 | |
| 204 | // one of two things happened: either the element was evicted immediately if the head's priority is same as current |
| 205 | // buffer(final one), or we figured out how much space we need to evict it into the next buffer, the check happens in |
| 206 | // EvictEvent function |
| 207 | |
| 208 | if (err != CHIP_NO_ERROR) |
| 209 | { |
| 210 | VerifyOrExit(ctx.mSpaceNeededForMovedEvent != 0, /* no-op, return err */); |
| 211 | VerifyOrExit(eventBuffer->GetNextCircularEventBuffer() != nullptr, err = CHIP_ERROR_INCORRECT_STATE); |
| 212 | if (ctx.mSpaceNeededForMovedEvent <= eventBuffer->GetNextCircularEventBuffer()->AvailableDataLength()) |
| 213 | { |
| 214 | // we can copy the event outright. copy event and |
| 215 | // subsequently evict head s.t. evicting the head |
| 216 | // element always succeeds. |
| 217 | // Since we're calling CopyElement and we've checked |
| 218 | // that there is space in the next buffer, we don't expect |
| 219 | // this to fail. |
| 220 | err = CopyToNextBuffer(eventBuffer); |
| 221 | SuccessOrExit(err); |
| 222 | // success; evict head unconditionally |
| 223 | eventBuffer->mProcessEvictedElement = nullptr; |
| 224 | err = eventBuffer->EvictHead(); |
| 225 | // if unconditional eviction failed, this |
| 226 | // means that we have no way of further |
| 227 | // clearing the buffer. fail out and let the |
| 228 | // caller know that we could not honor the |
| 229 | // request |
| 230 | SuccessOrExit(err); |
| 231 | continue; |
| 232 | } |
| 233 | // we cannot copy event outright. We remember the |
| 234 | // current required space in mRequiredSpaceForEvicted, we note the |
| 235 | // space requirements for the event in the current |
| 236 | // buffer and make that space in the next buffer. |
| 237 | eventBuffer->SetRequiredSpaceforEvicted(requiredSpace); |
| 238 | eventBuffer = eventBuffer->GetNextCircularEventBuffer(); |
| 239 | |
| 240 | // Sanity check: return error here on null event buffer. If |
| 241 | // eventBuffer->mpNext were null, then the `EvictBuffer` |
| 242 | // would have succeeded -- the event was |
| 243 | // already in the final buffer. |
| 244 | VerifyOrExit(eventBuffer != nullptr, err = CHIP_ERROR_INCORRECT_STATE); |
| 245 | requiredSpace = ctx.mSpaceNeededForMovedEvent; |
| 246 | } |
| 247 | } |
| 248 | else |
| 249 | { |
| 250 | // this branch is only taken when we go back in the buffer chain since we have free/spare enough space in next buffer, |
| 251 | // and need to retry to copy event from current buffer to next buffer, and free space for current buffer |
| 252 | if (eventBuffer == mpEventBuffer) |
| 253 | break; |
| 254 | eventBuffer = eventBuffer->GetPreviousCircularEventBuffer(); |
| 255 | requiredSpace = eventBuffer->GetRequiredSpaceforEvicted(); |
| 256 | err = CHIP_NO_ERROR; |
| 257 | } |
| 258 | } |
| 259 | |
yunhanw-google | a6e4d4b | 2022-03-02 10:33:30 -0800 | [diff] [blame] | 260 | mpEventBuffer->mProcessEvictedElement = nullptr; |
yunhanw-google | ef040a7 | 2021-05-05 07:17:56 -0700 | [diff] [blame] | 261 | mpEventBuffer->mAppData = nullptr; |
| 262 | |
| 263 | exit: |
yunhanw-google | ef040a7 | 2021-05-05 07:17:56 -0700 | [diff] [blame] | 264 | return err; |
| 265 | } |
| 266 | |
| 267 | CHIP_ERROR EventManagement::CalculateEventSize(EventLoggingDelegate * apDelegate, const EventOptions * apOptions, |
| 268 | uint32_t & requiredSize) |
| 269 | { |
yunhanw-google | ef040a7 | 2021-05-05 07:17:56 -0700 | [diff] [blame] | 270 | System::PacketBufferTLVWriter writer; |
yunhanw-google | 9a74bae | 2021-12-15 13:33:05 -0800 | [diff] [blame] | 271 | EventLoadOutContext ctxt = EventLoadOutContext(writer, apOptions->mPriority, GetLastEventNumber()); |
yunhanw-google | ef040a7 | 2021-05-05 07:17:56 -0700 | [diff] [blame] | 272 | System::PacketBufferHandle buf = System::PacketBufferHandle::New(kMaxEventSizeReserve); |
| 273 | if (buf.IsNull()) |
| 274 | { |
| 275 | return CHIP_ERROR_NO_MEMORY; |
| 276 | } |
| 277 | writer.Init(std::move(buf)); |
| 278 | |
yunhanw-google | 9a74bae | 2021-12-15 13:33:05 -0800 | [diff] [blame] | 279 | ctxt.mCurrentEventNumber = mLastEventNumber; |
| 280 | ctxt.mCurrentTime = mLastEventTimestamp; |
| 281 | CHIP_ERROR err = ConstructEvent(&ctxt, apDelegate, apOptions); |
| 282 | if (err == CHIP_NO_ERROR) |
yunhanw-google | ef040a7 | 2021-05-05 07:17:56 -0700 | [diff] [blame] | 283 | { |
yunhanw-google | 9a74bae | 2021-12-15 13:33:05 -0800 | [diff] [blame] | 284 | requiredSize = writer.GetLengthWritten(); |
yunhanw-google | ef040a7 | 2021-05-05 07:17:56 -0700 | [diff] [blame] | 285 | } |
| 286 | return err; |
| 287 | } |
| 288 | |
| 289 | CHIP_ERROR EventManagement::ConstructEvent(EventLoadOutContext * apContext, EventLoggingDelegate * apDelegate, |
| 290 | const EventOptions * apOptions) |
| 291 | { |
yunhanw-google | 299393b | 2021-12-06 09:59:34 -0800 | [diff] [blame] | 292 | VerifyOrReturnError(apContext->mCurrentEventNumber >= apContext->mStartingEventNumber, CHIP_NO_ERROR |
| 293 | /* no-op: don't write event, but advance current event Number */); |
yunhanw-google | ef040a7 | 2021-05-05 07:17:56 -0700 | [diff] [blame] | 294 | |
yunhanw-google | 299393b | 2021-12-06 09:59:34 -0800 | [diff] [blame] | 295 | VerifyOrReturnError(apOptions != nullptr, CHIP_ERROR_INVALID_ARGUMENT); |
yunhanw-google | ef040a7 | 2021-05-05 07:17:56 -0700 | [diff] [blame] | 296 | |
yunhanw-google | 299393b | 2021-12-06 09:59:34 -0800 | [diff] [blame] | 297 | EventReportIB::Builder eventReportBuilder; |
yunhanw-google | a6e4d4b | 2022-03-02 10:33:30 -0800 | [diff] [blame] | 298 | ReturnErrorOnFailure(eventReportBuilder.Init(&(apContext->mWriter))); |
yunhanw-google | 299393b | 2021-12-06 09:59:34 -0800 | [diff] [blame] | 299 | EventDataIB::Builder & eventDataIBBuilder = eventReportBuilder.CreateEventData(); |
| 300 | ReturnErrorOnFailure(eventReportBuilder.GetError()); |
| 301 | EventPathIB::Builder & eventPathBuilder = eventDataIBBuilder.CreatePath(); |
| 302 | ReturnErrorOnFailure(eventDataIBBuilder.GetError()); |
yunhanw-google | ef040a7 | 2021-05-05 07:17:56 -0700 | [diff] [blame] | 303 | |
Boris Zbarsky | df1f7a8 | 2023-05-29 11:24:25 -0400 | [diff] [blame] | 304 | CHIP_ERROR err = eventPathBuilder.Endpoint(apOptions->mPath.mEndpointId) |
| 305 | .Cluster(apOptions->mPath.mClusterId) |
| 306 | .Event(apOptions->mPath.mEventId) |
| 307 | .EndOfEventPathIB(); |
| 308 | ReturnErrorOnFailure(err); |
yunhanw-google | 9a74bae | 2021-12-15 13:33:05 -0800 | [diff] [blame] | 309 | eventDataIBBuilder.EventNumber(apContext->mCurrentEventNumber).Priority(chip::to_underlying(apContext->mPriority)); |
yunhanw-google | 299393b | 2021-12-06 09:59:34 -0800 | [diff] [blame] | 310 | ReturnErrorOnFailure(eventDataIBBuilder.GetError()); |
yunhanw-google | ef040a7 | 2021-05-05 07:17:56 -0700 | [diff] [blame] | 311 | |
yunhanw-google | 7b7374a | 2021-12-01 11:08:09 -0800 | [diff] [blame] | 312 | if (apOptions->mTimestamp.IsSystem()) |
| 313 | { |
yunhanw-google | 9a74bae | 2021-12-15 13:33:05 -0800 | [diff] [blame] | 314 | eventDataIBBuilder.SystemTimestamp(apOptions->mTimestamp.mValue); |
yunhanw-google | 7b7374a | 2021-12-01 11:08:09 -0800 | [diff] [blame] | 315 | } |
| 316 | else |
| 317 | { |
yunhanw-google | 9a74bae | 2021-12-15 13:33:05 -0800 | [diff] [blame] | 318 | eventDataIBBuilder.EpochTimestamp(apOptions->mTimestamp.mValue); |
yunhanw-google | 7b7374a | 2021-12-01 11:08:09 -0800 | [diff] [blame] | 319 | } |
| 320 | |
yunhanw-google | 299393b | 2021-12-06 09:59:34 -0800 | [diff] [blame] | 321 | ReturnErrorOnFailure(eventDataIBBuilder.GetError()); |
yunhanw-google | ef040a7 | 2021-05-05 07:17:56 -0700 | [diff] [blame] | 322 | |
yunhanw-google | ef040a7 | 2021-05-05 07:17:56 -0700 | [diff] [blame] | 323 | // Callback to write the EventData |
yunhanw-google | 299393b | 2021-12-06 09:59:34 -0800 | [diff] [blame] | 324 | ReturnErrorOnFailure(apDelegate->WriteEvent(apContext->mWriter)); |
yunhanw-google | e450832 | 2022-01-26 18:27:51 -0800 | [diff] [blame] | 325 | |
| 326 | // The fabricIndex profile tag is internal use only for fabric filtering when retrieving event from circular event buffer, |
| 327 | // and would not go on the wire. |
yunhanw-google | c438b89 | 2022-05-05 09:31:07 -0700 | [diff] [blame] | 328 | // Revisit FabricRemovedCB function should the encoding of fabricIndex change in the future. |
yunhanw-google | e450832 | 2022-01-26 18:27:51 -0800 | [diff] [blame] | 329 | if (apOptions->mFabricIndex != kUndefinedFabricIndex) |
| 330 | { |
| 331 | apContext->mWriter.Put(TLV::ProfileTag(kEventManagementProfile, kFabricIndexTag), apOptions->mFabricIndex); |
| 332 | } |
Boris Zbarsky | df1f7a8 | 2023-05-29 11:24:25 -0400 | [diff] [blame] | 333 | ReturnErrorOnFailure(eventDataIBBuilder.EndOfEventDataIB()); |
| 334 | ReturnErrorOnFailure(eventReportBuilder.EndOfEventReportIB()); |
yunhanw-google | 299393b | 2021-12-06 09:59:34 -0800 | [diff] [blame] | 335 | ReturnErrorOnFailure(apContext->mWriter.Finalize()); |
yunhanw-google | ef040a7 | 2021-05-05 07:17:56 -0700 | [diff] [blame] | 336 | apContext->mFirst = false; |
yunhanw-google | 299393b | 2021-12-06 09:59:34 -0800 | [diff] [blame] | 337 | return CHIP_NO_ERROR; |
yunhanw-google | ef040a7 | 2021-05-05 07:17:56 -0700 | [diff] [blame] | 338 | } |
| 339 | |
yunhanw-google | 2423a26 | 2021-06-07 14:06:34 -0700 | [diff] [blame] | 340 | void EventManagement::CreateEventManagement(Messaging::ExchangeManager * apExchangeManager, uint32_t aNumBuffers, |
yunhanw-google | ef040a7 | 2021-05-05 07:17:56 -0700 | [diff] [blame] | 341 | CircularEventBuffer * apCircularEventBuffer, |
yunhanw-google | 9a74bae | 2021-12-15 13:33:05 -0800 | [diff] [blame] | 342 | const LogStorageResources * const apLogStorageResources, |
Boris Zbarsky | 7c77e8e | 2023-02-23 11:23:27 -0500 | [diff] [blame] | 343 | MonotonicallyIncreasingCounter<EventNumber> * apEventNumberCounter, |
| 344 | System::Clock::Milliseconds64 aMonotonicStartupTime) |
yunhanw-google | ef040a7 | 2021-05-05 07:17:56 -0700 | [diff] [blame] | 345 | { |
| 346 | |
Boris Zbarsky | 7c77e8e | 2023-02-23 11:23:27 -0500 | [diff] [blame] | 347 | sInstance.Init(apExchangeManager, aNumBuffers, apCircularEventBuffer, apLogStorageResources, apEventNumberCounter, |
| 348 | aMonotonicStartupTime); |
yunhanw-google | ef040a7 | 2021-05-05 07:17:56 -0700 | [diff] [blame] | 349 | } |
| 350 | |
| 351 | /** |
| 352 | * @brief Perform any actions we need to on shutdown. |
| 353 | */ |
| 354 | void EventManagement::DestroyEventManagement() |
| 355 | { |
yunhanw-google | ef040a7 | 2021-05-05 07:17:56 -0700 | [diff] [blame] | 356 | sInstance.mState = EventManagementStates::Shutdown; |
| 357 | sInstance.mpEventBuffer = nullptr; |
| 358 | sInstance.mpExchangeMgr = nullptr; |
yunhanw-google | ef040a7 | 2021-05-05 07:17:56 -0700 | [diff] [blame] | 359 | } |
| 360 | |
yunhanw-google | ef040a7 | 2021-05-05 07:17:56 -0700 | [diff] [blame] | 361 | CircularEventBuffer * EventManagement::GetPriorityBuffer(PriorityLevel aPriority) const |
| 362 | { |
| 363 | CircularEventBuffer * buf = mpEventBuffer; |
| 364 | while (!buf->IsFinalDestinationForPriority(aPriority)) |
| 365 | { |
| 366 | buf = buf->GetNextCircularEventBuffer(); |
| 367 | assert(buf != nullptr); |
| 368 | // code guarantees that every PriorityLevel has a buffer destination. |
| 369 | } |
| 370 | return buf; |
| 371 | } |
| 372 | |
| 373 | CHIP_ERROR EventManagement::CopyAndAdjustDeltaTime(const TLVReader & aReader, size_t aDepth, void * apContext) |
| 374 | { |
yunhanw-google | ef040a7 | 2021-05-05 07:17:56 -0700 | [diff] [blame] | 375 | CopyAndAdjustDeltaTimeContext * ctx = static_cast<CopyAndAdjustDeltaTimeContext *>(apContext); |
| 376 | TLVReader reader(aReader); |
| 377 | |
yunhanw-google | e450832 | 2022-01-26 18:27:51 -0800 | [diff] [blame] | 378 | if (aReader.GetTag() == TLV::ProfileTag(kEventManagementProfile, kFabricIndexTag)) |
yunhanw-google | ef040a7 | 2021-05-05 07:17:56 -0700 | [diff] [blame] | 379 | { |
yunhanw-google | e450832 | 2022-01-26 18:27:51 -0800 | [diff] [blame] | 380 | // Does not go on the wire. |
| 381 | return CHIP_NO_ERROR; |
| 382 | } |
Boris Zbarsky | e434c6a | 2023-03-01 12:35:37 -0500 | [diff] [blame] | 383 | if ((aReader.GetTag() == TLV::ContextTag(EventDataIB::Tag::kSystemTimestamp)) && !(ctx->mpContext->mFirst) && |
Boris Zbarsky | 7c77e8e | 2023-02-23 11:23:27 -0500 | [diff] [blame] | 384 | (ctx->mpContext->mCurrentTime.mType == ctx->mpContext->mPreviousTime.mType)) |
yunhanw-google | e450832 | 2022-01-26 18:27:51 -0800 | [diff] [blame] | 385 | { |
Boris Zbarsky | e434c6a | 2023-03-01 12:35:37 -0500 | [diff] [blame] | 386 | return ctx->mpWriter->Put(TLV::ContextTag(EventDataIB::Tag::kDeltaSystemTimestamp), |
yunhanw-google | e450832 | 2022-01-26 18:27:51 -0800 | [diff] [blame] | 387 | ctx->mpContext->mCurrentTime.mValue - ctx->mpContext->mPreviousTime.mValue); |
yunhanw-google | 9a74bae | 2021-12-15 13:33:05 -0800 | [diff] [blame] | 388 | } |
Boris Zbarsky | e434c6a | 2023-03-01 12:35:37 -0500 | [diff] [blame] | 389 | if ((aReader.GetTag() == TLV::ContextTag(EventDataIB::Tag::kEpochTimestamp)) && !(ctx->mpContext->mFirst) && |
Boris Zbarsky | 7c77e8e | 2023-02-23 11:23:27 -0500 | [diff] [blame] | 390 | (ctx->mpContext->mCurrentTime.mType == ctx->mpContext->mPreviousTime.mType)) |
yunhanw-google | 9a74bae | 2021-12-15 13:33:05 -0800 | [diff] [blame] | 391 | { |
Boris Zbarsky | e434c6a | 2023-03-01 12:35:37 -0500 | [diff] [blame] | 392 | return ctx->mpWriter->Put(TLV::ContextTag(EventDataIB::Tag::kDeltaEpochTimestamp), |
yunhanw-google | e450832 | 2022-01-26 18:27:51 -0800 | [diff] [blame] | 393 | ctx->mpContext->mCurrentTime.mValue - ctx->mpContext->mPreviousTime.mValue); |
yunhanw-google | ef040a7 | 2021-05-05 07:17:56 -0700 | [diff] [blame] | 394 | } |
Andrei Litvin | 1866f46 | 2022-04-08 05:21:04 -1000 | [diff] [blame] | 395 | |
| 396 | return ctx->mpWriter->CopyElement(reader); |
yunhanw-google | ef040a7 | 2021-05-05 07:17:56 -0700 | [diff] [blame] | 397 | } |
| 398 | |
yunhanw-google | 9a74bae | 2021-12-15 13:33:05 -0800 | [diff] [blame] | 399 | void EventManagement::VendEventNumber() |
| 400 | { |
| 401 | CHIP_ERROR err = CHIP_NO_ERROR; |
| 402 | // Now advance the counter. |
| 403 | err = mpEventNumberCounter->Advance(); |
| 404 | if (err != CHIP_NO_ERROR) |
| 405 | { |
| 406 | ChipLogError(EventLogging, "%s Advance() failed with %" CHIP_ERROR_FORMAT, __FUNCTION__, err.Format()); |
| 407 | } |
| 408 | |
| 409 | // Assign event Number to the buffer's counter's value. |
Song GUO | 0b748ff | 2022-05-03 17:55:11 +0800 | [diff] [blame] | 410 | mLastEventNumber = mpEventNumberCounter->GetValue(); |
yunhanw-google | 9a74bae | 2021-12-15 13:33:05 -0800 | [diff] [blame] | 411 | } |
| 412 | |
yunhanw-google | f9ce4be | 2021-12-21 18:27:35 -0800 | [diff] [blame] | 413 | CHIP_ERROR EventManagement::LogEvent(EventLoggingDelegate * apDelegate, const EventOptions & aEventOptions, |
| 414 | EventNumber & aEventNumber) |
yunhanw-google | ef040a7 | 2021-05-05 07:17:56 -0700 | [diff] [blame] | 415 | { |
yunhanw-google | 86977c2 | 2024-02-06 15:39:53 -0800 | [diff] [blame] | 416 | assertChipStackLockedByCurrentThread(); |
yunhanw-google | b8e9ab1 | 2022-06-07 23:15:40 -0700 | [diff] [blame] | 417 | VerifyOrReturnError(mState != EventManagementStates::Shutdown, CHIP_ERROR_INCORRECT_STATE); |
| 418 | return LogEventPrivate(apDelegate, aEventOptions, aEventNumber); |
yunhanw-google | ef040a7 | 2021-05-05 07:17:56 -0700 | [diff] [blame] | 419 | } |
| 420 | |
yunhanw-google | f9ce4be | 2021-12-21 18:27:35 -0800 | [diff] [blame] | 421 | CHIP_ERROR EventManagement::LogEventPrivate(EventLoggingDelegate * apDelegate, const EventOptions & aEventOptions, |
yunhanw-google | ef040a7 | 2021-05-05 07:17:56 -0700 | [diff] [blame] | 422 | EventNumber & aEventNumber) |
| 423 | { |
| 424 | CircularTLVWriter writer; |
yunhanw-google | 41700bd | 2021-12-16 01:20:03 -0800 | [diff] [blame] | 425 | CHIP_ERROR err = CHIP_NO_ERROR; |
| 426 | uint32_t requestSize = 0; |
| 427 | aEventNumber = 0; |
| 428 | CircularTLVWriter checkpoint = writer; |
yunhanw-google | 41700bd | 2021-12-16 01:20:03 -0800 | [diff] [blame] | 429 | EventLoadOutContext ctxt = EventLoadOutContext(writer, aEventOptions.mPriority, mLastEventNumber); |
yunhanw-google | 7b7374a | 2021-12-01 11:08:09 -0800 | [diff] [blame] | 430 | EventOptions opts; |
Boris Zbarsky | aa99d09 | 2023-03-03 22:10:46 -0500 | [diff] [blame] | 431 | |
yunhanw-google | 7b7374a | 2021-12-01 11:08:09 -0800 | [diff] [blame] | 432 | Timestamp timestamp; |
Boris Zbarsky | aa99d09 | 2023-03-03 22:10:46 -0500 | [diff] [blame] | 433 | #if CHIP_DEVICE_CONFIG_EVENT_LOGGING_UTC_TIMESTAMPS |
Boris Zbarsky | 7c77e8e | 2023-02-23 11:23:27 -0500 | [diff] [blame] | 434 | System::Clock::Milliseconds64 utc_time; |
yunhanw-google | 7b7374a | 2021-12-01 11:08:09 -0800 | [diff] [blame] | 435 | err = System::SystemClock().GetClock_RealTimeMS(utc_time); |
Boris Zbarsky | 7c77e8e | 2023-02-23 11:23:27 -0500 | [diff] [blame] | 436 | if (err == CHIP_NO_ERROR) |
| 437 | { |
| 438 | timestamp = Timestamp::Epoch(utc_time); |
| 439 | } |
| 440 | else |
Boris Zbarsky | aa99d09 | 2023-03-03 22:10:46 -0500 | [diff] [blame] | 441 | #endif // CHIP_DEVICE_CONFIG_EVENT_LOGGING_UTC_TIMESTAMPS |
Boris Zbarsky | 7c77e8e | 2023-02-23 11:23:27 -0500 | [diff] [blame] | 442 | { |
| 443 | auto systemTimeMs = System::SystemClock().GetMonotonicMilliseconds64() - mMonotonicStartupTime; |
| 444 | timestamp = Timestamp::System(systemTimeMs); |
| 445 | } |
yunhanw-google | 7b7374a | 2021-12-01 11:08:09 -0800 | [diff] [blame] | 446 | |
| 447 | opts = EventOptions(timestamp); |
yunhanw-google | ef040a7 | 2021-05-05 07:17:56 -0700 | [diff] [blame] | 448 | // Start the event container (anonymous structure) in the circular buffer |
| 449 | writer.Init(*mpEventBuffer); |
yunhanw-google | ef040a7 | 2021-05-05 07:17:56 -0700 | [diff] [blame] | 450 | |
yunhanw-google | ee3df3f | 2021-12-06 16:20:44 -0800 | [diff] [blame] | 451 | opts.mPriority = aEventOptions.mPriority; |
yunhanw-google | ef040a7 | 2021-05-05 07:17:56 -0700 | [diff] [blame] | 452 | // Create all event specific data |
| 453 | // Timestamp; encoded as a delta time |
yunhanw-google | ef040a7 | 2021-05-05 07:17:56 -0700 | [diff] [blame] | 454 | |
yunhanw-google | e450832 | 2022-01-26 18:27:51 -0800 | [diff] [blame] | 455 | opts.mPath = aEventOptions.mPath; |
| 456 | opts.mFabricIndex = aEventOptions.mFabricIndex; |
yunhanw-google | ef040a7 | 2021-05-05 07:17:56 -0700 | [diff] [blame] | 457 | |
yunhanw-google | 9a74bae | 2021-12-15 13:33:05 -0800 | [diff] [blame] | 458 | ctxt.mCurrentEventNumber = mLastEventNumber; |
| 459 | ctxt.mCurrentTime.mValue = mLastEventTimestamp.mValue; |
yunhanw-google | ef040a7 | 2021-05-05 07:17:56 -0700 | [diff] [blame] | 460 | |
| 461 | err = CalculateEventSize(apDelegate, &opts, requestSize); |
| 462 | SuccessOrExit(err); |
| 463 | |
| 464 | // Ensure we have space in the in-memory logging queues |
Boris Zbarsky | b236bfb | 2023-02-23 11:51:11 -0500 | [diff] [blame] | 465 | err = EnsureSpaceInCircularBuffer(requestSize, aEventOptions.mPriority); |
yunhanw-google | ef040a7 | 2021-05-05 07:17:56 -0700 | [diff] [blame] | 466 | SuccessOrExit(err); |
| 467 | |
| 468 | err = ConstructEvent(&ctxt, apDelegate, &opts); |
| 469 | SuccessOrExit(err); |
| 470 | |
yunhanw-google | ef040a7 | 2021-05-05 07:17:56 -0700 | [diff] [blame] | 471 | mBytesWritten += writer.GetLengthWritten(); |
| 472 | |
| 473 | exit: |
yunhanw-google | ef040a7 | 2021-05-05 07:17:56 -0700 | [diff] [blame] | 474 | if (err != CHIP_NO_ERROR) |
| 475 | { |
Damian Królik | 5e9d413 | 2022-06-27 09:02:15 +0200 | [diff] [blame] | 476 | ChipLogError(EventLogging, "Log event with error %" CHIP_ERROR_FORMAT, err.Format()); |
yunhanw-google | 41700bd | 2021-12-16 01:20:03 -0800 | [diff] [blame] | 477 | writer = checkpoint; |
yunhanw-google | ef040a7 | 2021-05-05 07:17:56 -0700 | [diff] [blame] | 478 | } |
yunhanw-google | ee3df3f | 2021-12-06 16:20:44 -0800 | [diff] [blame] | 479 | else if (opts.mPriority >= CHIP_CONFIG_EVENT_GLOBAL_PRIORITY) |
yunhanw-google | ef040a7 | 2021-05-05 07:17:56 -0700 | [diff] [blame] | 480 | { |
yunhanw-google | 9a74bae | 2021-12-15 13:33:05 -0800 | [diff] [blame] | 481 | aEventNumber = mLastEventNumber; |
| 482 | VendEventNumber(); |
| 483 | mLastEventTimestamp = timestamp; |
yunhanw-google | ef040a7 | 2021-05-05 07:17:56 -0700 | [diff] [blame] | 484 | #if CHIP_CONFIG_EVENT_LOGGING_VERBOSE_DEBUG_LOGS |
Boris Zbarsky | 0bca292 | 2021-06-10 11:23:46 -0400 | [diff] [blame] | 485 | ChipLogDetail(EventLogging, |
andrei-menzopol | 57471cb | 2022-04-20 23:31:17 +0300 | [diff] [blame] | 486 | "LogEvent event number: 0x" ChipLogFormatX64 " priority: %u, endpoint id: 0x%x" |
yunhanw-google | 6f89b9b | 2021-12-07 14:26:21 -0800 | [diff] [blame] | 487 | " cluster id: " ChipLogFormatMEI " event id: 0x%" PRIx32 " %s timestamp: 0x" ChipLogFormatX64, |
| 488 | ChipLogValueX64(aEventNumber), static_cast<unsigned>(opts.mPriority), opts.mPath.mEndpointId, |
| 489 | ChipLogValueMEI(opts.mPath.mClusterId), opts.mPath.mEventId, |
| 490 | opts.mTimestamp.mType == Timestamp::Type::kSystem ? "Sys" : "Epoch", ChipLogValueX64(opts.mTimestamp.mValue)); |
yunhanw-google | ef040a7 | 2021-05-05 07:17:56 -0700 | [diff] [blame] | 491 | #endif // CHIP_CONFIG_EVENT_LOGGING_VERBOSE_DEBUG_LOGS |
| 492 | |
yunhanw-google | cd44f9b | 2022-03-09 10:36:31 -0800 | [diff] [blame] | 493 | err = InteractionModelEngine::GetInstance()->GetReportingEngine().ScheduleEventDelivery(opts.mPath, mBytesWritten); |
yunhanw-google | ef040a7 | 2021-05-05 07:17:56 -0700 | [diff] [blame] | 494 | } |
| 495 | |
| 496 | return err; |
| 497 | } |
| 498 | |
| 499 | CHIP_ERROR EventManagement::CopyEvent(const TLVReader & aReader, TLVWriter & aWriter, EventLoadOutContext * apContext) |
| 500 | { |
| 501 | TLVReader reader; |
| 502 | TLVType containerType; |
yunhanw-google | 3bec0f9 | 2021-11-03 16:12:39 -0700 | [diff] [blame] | 503 | TLVType containerType1; |
yunhanw-google | ef040a7 | 2021-05-05 07:17:56 -0700 | [diff] [blame] | 504 | CopyAndAdjustDeltaTimeContext context(&aWriter, apContext); |
| 505 | CHIP_ERROR err = CHIP_NO_ERROR; |
| 506 | |
| 507 | reader.Init(aReader); |
yunhanw-google | 3bec0f9 | 2021-11-03 16:12:39 -0700 | [diff] [blame] | 508 | ReturnErrorOnFailure(reader.EnterContainer(containerType)); |
Boris Zbarsky | 5c096ec | 2021-12-23 13:28:39 -0500 | [diff] [blame] | 509 | ReturnErrorOnFailure(aWriter.StartContainer(AnonymousTag(), kTLVType_Structure, containerType)); |
yunhanw-google | ef040a7 | 2021-05-05 07:17:56 -0700 | [diff] [blame] | 510 | |
yunhanw-google | 3bec0f9 | 2021-11-03 16:12:39 -0700 | [diff] [blame] | 511 | ReturnErrorOnFailure(reader.Next()); |
| 512 | ReturnErrorOnFailure(reader.EnterContainer(containerType1)); |
yunhanw-google | 3bec0f9 | 2021-11-03 16:12:39 -0700 | [diff] [blame] | 513 | ReturnErrorOnFailure( |
Boris Zbarsky | e434c6a | 2023-03-01 12:35:37 -0500 | [diff] [blame] | 514 | aWriter.StartContainer(TLV::ContextTag(EventReportIB::Tag::kEventData), kTLVType_Structure, containerType1)); |
yunhanw-google | ef040a7 | 2021-05-05 07:17:56 -0700 | [diff] [blame] | 515 | err = TLV::Utilities::Iterate(reader, CopyAndAdjustDeltaTime, &context, false /*recurse*/); |
| 516 | if (err == CHIP_END_OF_TLV) |
| 517 | { |
| 518 | err = CHIP_NO_ERROR; |
| 519 | } |
yunhanw-google | 3bec0f9 | 2021-11-03 16:12:39 -0700 | [diff] [blame] | 520 | ReturnErrorOnFailure(err); |
| 521 | ReturnErrorOnFailure(aWriter.EndContainer(containerType1)); |
| 522 | ReturnErrorOnFailure(aWriter.EndContainer(containerType)); |
| 523 | ReturnErrorOnFailure(aWriter.Finalize()); |
| 524 | return CHIP_NO_ERROR; |
yunhanw-google | ef040a7 | 2021-05-05 07:17:56 -0700 | [diff] [blame] | 525 | } |
| 526 | |
Song GUO | 1ccc2af | 2022-03-03 01:53:33 +0800 | [diff] [blame] | 527 | CHIP_ERROR EventManagement::CheckEventContext(EventLoadOutContext * eventLoadOutContext, |
| 528 | const EventManagement::EventEnvelopeContext & event) |
yunhanw-google | d96d8a3 | 2021-05-26 18:24:44 -0700 | [diff] [blame] | 529 | { |
yunhanw-google | d96d8a3 | 2021-05-26 18:24:44 -0700 | [diff] [blame] | 530 | if (eventLoadOutContext->mCurrentEventNumber < eventLoadOutContext->mStartingEventNumber) |
| 531 | { |
Song GUO | 1ccc2af | 2022-03-03 01:53:33 +0800 | [diff] [blame] | 532 | return CHIP_ERROR_UNEXPECTED_EVENT; |
yunhanw-google | d96d8a3 | 2021-05-26 18:24:44 -0700 | [diff] [blame] | 533 | } |
yunhanw-google | e450832 | 2022-01-26 18:27:51 -0800 | [diff] [blame] | 534 | |
yunhanw-google | c438b89 | 2022-05-05 09:31:07 -0700 | [diff] [blame] | 535 | if (event.mFabricIndex.HasValue() && |
| 536 | (event.mFabricIndex.Value() == kUndefinedFabricIndex || |
| 537 | eventLoadOutContext->mSubjectDescriptor.fabricIndex != event.mFabricIndex.Value())) |
yunhanw-google | e450832 | 2022-01-26 18:27:51 -0800 | [diff] [blame] | 538 | { |
Song GUO | 1ccc2af | 2022-03-03 01:53:33 +0800 | [diff] [blame] | 539 | return CHIP_ERROR_UNEXPECTED_EVENT; |
yunhanw-google | e450832 | 2022-01-26 18:27:51 -0800 | [diff] [blame] | 540 | } |
| 541 | |
yunhanw-google | c79b67b | 2021-11-24 20:58:19 -0800 | [diff] [blame] | 542 | ConcreteEventPath path(event.mEndpointId, event.mClusterId, event.mEventId); |
Song GUO | 1ccc2af | 2022-03-03 01:53:33 +0800 | [diff] [blame] | 543 | CHIP_ERROR ret = CHIP_ERROR_UNEXPECTED_EVENT; |
| 544 | |
yunhanw-google | c79b67b | 2021-11-24 20:58:19 -0800 | [diff] [blame] | 545 | for (auto * interestedPath = eventLoadOutContext->mpInterestedEventPaths; interestedPath != nullptr; |
| 546 | interestedPath = interestedPath->mpNext) |
yunhanw-google | d96d8a3 | 2021-05-26 18:24:44 -0700 | [diff] [blame] | 547 | { |
yunhanw-google | 07fc8cd | 2022-03-24 01:41:28 -0700 | [diff] [blame] | 548 | if (interestedPath->mValue.IsEventPathSupersetOf(path)) |
yunhanw-google | d96d8a3 | 2021-05-26 18:24:44 -0700 | [diff] [blame] | 549 | { |
Song GUO | 1ccc2af | 2022-03-03 01:53:33 +0800 | [diff] [blame] | 550 | ret = CHIP_NO_ERROR; |
yunhanw-google | 19cc9e7 | 2022-07-29 07:38:21 -0700 | [diff] [blame] | 551 | break; |
yunhanw-google | d96d8a3 | 2021-05-26 18:24:44 -0700 | [diff] [blame] | 552 | } |
yunhanw-google | d96d8a3 | 2021-05-26 18:24:44 -0700 | [diff] [blame] | 553 | } |
Song GUO | 1ccc2af | 2022-03-03 01:53:33 +0800 | [diff] [blame] | 554 | |
| 555 | ReturnErrorOnFailure(ret); |
| 556 | |
Thomas Lea | 5ad899a | 2024-08-09 13:01:55 -0500 | [diff] [blame] | 557 | Access::RequestPath requestPath{ .cluster = event.mClusterId, |
| 558 | .endpoint = event.mEndpointId, |
Thomas Lea | 87f6277 | 2024-08-27 13:27:10 -0500 | [diff] [blame] | 559 | .requestType = Access::RequestType::kEventReadRequest, |
Thomas Lea | 5ad899a | 2024-08-09 13:01:55 -0500 | [diff] [blame] | 560 | .entityId = event.mEventId }; |
Song GUO | 1ccc2af | 2022-03-03 01:53:33 +0800 | [diff] [blame] | 561 | Access::Privilege requestPrivilege = RequiredPrivilege::ForReadEvent(path); |
| 562 | CHIP_ERROR accessControlError = |
| 563 | Access::GetAccessControl().Check(eventLoadOutContext->mSubjectDescriptor, requestPath, requestPrivilege); |
Song GUO | 1ccc2af | 2022-03-03 01:53:33 +0800 | [diff] [blame] | 564 | if (accessControlError != CHIP_NO_ERROR) |
| 565 | { |
Thomas Lea | 401a2a0 | 2024-08-29 13:06:01 -0500 | [diff] [blame] | 566 | ReturnErrorCodeIf((accessControlError != CHIP_ERROR_ACCESS_DENIED) && |
| 567 | (accessControlError != CHIP_ERROR_ACCESS_RESTRICTED_BY_ARL), |
| 568 | accessControlError); |
yunhanw-google | 19cc9e7 | 2022-07-29 07:38:21 -0700 | [diff] [blame] | 569 | ret = CHIP_ERROR_UNEXPECTED_EVENT; |
Song GUO | 1ccc2af | 2022-03-03 01:53:33 +0800 | [diff] [blame] | 570 | } |
| 571 | |
| 572 | return ret; |
yunhanw-google | d96d8a3 | 2021-05-26 18:24:44 -0700 | [diff] [blame] | 573 | } |
| 574 | |
Song GUO | 1ccc2af | 2022-03-03 01:53:33 +0800 | [diff] [blame] | 575 | CHIP_ERROR EventManagement::EventIterator(const TLVReader & aReader, size_t aDepth, EventLoadOutContext * apEventLoadOutContext, |
| 576 | EventEnvelopeContext * event) |
yunhanw-google | ef040a7 | 2021-05-05 07:17:56 -0700 | [diff] [blame] | 577 | { |
| 578 | CHIP_ERROR err = CHIP_NO_ERROR; |
| 579 | TLVReader innerReader; |
| 580 | TLVType tlvType; |
yunhanw-google | 3bec0f9 | 2021-11-03 16:12:39 -0700 | [diff] [blame] | 581 | TLVType tlvType1; |
yunhanw-google | ef040a7 | 2021-05-05 07:17:56 -0700 | [diff] [blame] | 582 | |
| 583 | innerReader.Init(aReader); |
Song GUO | 1ccc2af | 2022-03-03 01:53:33 +0800 | [diff] [blame] | 584 | VerifyOrDie(event != nullptr); |
yunhanw-google | d96d8a3 | 2021-05-26 18:24:44 -0700 | [diff] [blame] | 585 | ReturnErrorOnFailure(innerReader.EnterContainer(tlvType)); |
yunhanw-google | 3bec0f9 | 2021-11-03 16:12:39 -0700 | [diff] [blame] | 586 | ReturnErrorOnFailure(innerReader.Next()); |
yunhanw-google | f3d6b7c | 2021-11-17 13:42:38 -0800 | [diff] [blame] | 587 | |
yunhanw-google | 3bec0f9 | 2021-11-03 16:12:39 -0700 | [diff] [blame] | 588 | ReturnErrorOnFailure(innerReader.EnterContainer(tlvType1)); |
Song GUO | 1ccc2af | 2022-03-03 01:53:33 +0800 | [diff] [blame] | 589 | err = TLV::Utilities::Iterate(innerReader, FetchEventParameters, event, false /*recurse*/); |
yunhanw-google | 7b7374a | 2021-12-01 11:08:09 -0800 | [diff] [blame] | 590 | |
Song GUO | 1ccc2af | 2022-03-03 01:53:33 +0800 | [diff] [blame] | 591 | if (event->mFieldsToRead != kRequiredEventField) |
yunhanw-google | d96d8a3 | 2021-05-26 18:24:44 -0700 | [diff] [blame] | 592 | { |
| 593 | return CHIP_ERROR_INVALID_ARGUMENT; |
| 594 | } |
yunhanw-google | ef040a7 | 2021-05-05 07:17:56 -0700 | [diff] [blame] | 595 | |
| 596 | if (err == CHIP_END_OF_TLV) |
| 597 | { |
| 598 | err = CHIP_NO_ERROR; |
| 599 | } |
yunhanw-google | d96d8a3 | 2021-05-26 18:24:44 -0700 | [diff] [blame] | 600 | ReturnErrorOnFailure(err); |
yunhanw-google | ef040a7 | 2021-05-05 07:17:56 -0700 | [diff] [blame] | 601 | |
Song GUO | 1ccc2af | 2022-03-03 01:53:33 +0800 | [diff] [blame] | 602 | apEventLoadOutContext->mCurrentTime = event->mCurrentTime; |
| 603 | apEventLoadOutContext->mCurrentEventNumber = event->mEventNumber; |
| 604 | |
| 605 | err = CheckEventContext(apEventLoadOutContext, *event); |
| 606 | if (err == CHIP_NO_ERROR) |
yunhanw-google | ef040a7 | 2021-05-05 07:17:56 -0700 | [diff] [blame] | 607 | { |
Song GUO | 1ccc2af | 2022-03-03 01:53:33 +0800 | [diff] [blame] | 608 | err = CHIP_EVENT_ID_FOUND; |
| 609 | } |
| 610 | else if (err == CHIP_ERROR_UNEXPECTED_EVENT) |
| 611 | { |
| 612 | err = CHIP_NO_ERROR; |
yunhanw-google | ef040a7 | 2021-05-05 07:17:56 -0700 | [diff] [blame] | 613 | } |
yunhanw-google | 9a74bae | 2021-12-15 13:33:05 -0800 | [diff] [blame] | 614 | |
Song GUO | 1ccc2af | 2022-03-03 01:53:33 +0800 | [diff] [blame] | 615 | return err; |
yunhanw-google | ef040a7 | 2021-05-05 07:17:56 -0700 | [diff] [blame] | 616 | } |
| 617 | |
| 618 | CHIP_ERROR EventManagement::CopyEventsSince(const TLVReader & aReader, size_t aDepth, void * apContext) |
| 619 | { |
Kevin Schoedel | f9550e1 | 2021-06-21 17:08:48 -0400 | [diff] [blame] | 620 | EventLoadOutContext * const loadOutContext = static_cast<EventLoadOutContext *>(apContext); |
Song GUO | 1ccc2af | 2022-03-03 01:53:33 +0800 | [diff] [blame] | 621 | EventEnvelopeContext event; |
| 622 | CHIP_ERROR err = EventIterator(aReader, aDepth, loadOutContext, &event); |
yunhanw-google | ef040a7 | 2021-05-05 07:17:56 -0700 | [diff] [blame] | 623 | if (err == CHIP_EVENT_ID_FOUND) |
| 624 | { |
| 625 | // checkpoint the writer |
Kevin Schoedel | f9550e1 | 2021-06-21 17:08:48 -0400 | [diff] [blame] | 626 | TLV::TLVWriter checkpoint = loadOutContext->mWriter; |
yunhanw-google | ef040a7 | 2021-05-05 07:17:56 -0700 | [diff] [blame] | 627 | |
| 628 | err = CopyEvent(aReader, loadOutContext->mWriter, loadOutContext); |
| 629 | |
| 630 | // CHIP_NO_ERROR and CHIP_END_OF_TLV signify a |
| 631 | // successful copy. In all other cases, roll back the |
| 632 | // writer state back to the checkpoint, i.e., the state |
| 633 | // before we began the copy operation. |
Kevin Schoedel | f9550e1 | 2021-06-21 17:08:48 -0400 | [diff] [blame] | 634 | if ((err != CHIP_NO_ERROR) && (err != CHIP_END_OF_TLV)) |
| 635 | { |
| 636 | loadOutContext->mWriter = checkpoint; |
| 637 | return err; |
| 638 | } |
yunhanw-google | ef040a7 | 2021-05-05 07:17:56 -0700 | [diff] [blame] | 639 | |
yunhanw-google | 7b7374a | 2021-12-01 11:08:09 -0800 | [diff] [blame] | 640 | loadOutContext->mPreviousTime.mValue = loadOutContext->mCurrentTime.mValue; |
| 641 | loadOutContext->mFirst = false; |
yunhanw-google | 289ec6e | 2021-07-19 13:51:47 -0700 | [diff] [blame] | 642 | loadOutContext->mEventCount++; |
yunhanw-google | ef040a7 | 2021-05-05 07:17:56 -0700 | [diff] [blame] | 643 | } |
yunhanw-google | ef040a7 | 2021-05-05 07:17:56 -0700 | [diff] [blame] | 644 | return err; |
| 645 | } |
| 646 | |
Andrei Litvin | a3d0a86 | 2024-02-20 04:56:48 -0500 | [diff] [blame] | 647 | CHIP_ERROR EventManagement::FetchEventsSince(TLVWriter & aWriter, const SingleLinkedListNode<EventPathParams> * apEventPathList, |
yunhanw-google | 07fc8cd | 2022-03-24 01:41:28 -0700 | [diff] [blame] | 648 | EventNumber & aEventMin, size_t & aEventCount, |
| 649 | const Access::SubjectDescriptor & aSubjectDescriptor) |
yunhanw-google | ef040a7 | 2021-05-05 07:17:56 -0700 | [diff] [blame] | 650 | { |
yunhanw-google | 8ddfb87 | 2021-05-07 18:13:15 -0700 | [diff] [blame] | 651 | // TODO: Add particular set of event Paths in FetchEventsSince so that we can filter the interested paths |
yunhanw-google | ef040a7 | 2021-05-05 07:17:56 -0700 | [diff] [blame] | 652 | CHIP_ERROR err = CHIP_NO_ERROR; |
| 653 | const bool recurse = false; |
| 654 | TLVReader reader; |
| 655 | CircularEventBufferWrapper bufWrapper; |
yunhanw-google | 9a74bae | 2021-12-15 13:33:05 -0800 | [diff] [blame] | 656 | EventLoadOutContext context(aWriter, PriorityLevel::Invalid, aEventMin); |
yunhanw-google | ef040a7 | 2021-05-05 07:17:56 -0700 | [diff] [blame] | 657 | |
Song GUO | 1ccc2af | 2022-03-03 01:53:33 +0800 | [diff] [blame] | 658 | context.mSubjectDescriptor = aSubjectDescriptor; |
yunhanw-google | 07fc8cd | 2022-03-24 01:41:28 -0700 | [diff] [blame] | 659 | context.mpInterestedEventPaths = apEventPathList; |
yunhanw-google | 9a74bae | 2021-12-15 13:33:05 -0800 | [diff] [blame] | 660 | err = GetEventReader(reader, PriorityLevel::Critical, &bufWrapper); |
yunhanw-google | ef040a7 | 2021-05-05 07:17:56 -0700 | [diff] [blame] | 661 | SuccessOrExit(err); |
| 662 | |
| 663 | err = TLV::Utilities::Iterate(reader, CopyEventsSince, &context, recurse); |
| 664 | if (err == CHIP_END_OF_TLV) |
| 665 | { |
| 666 | err = CHIP_NO_ERROR; |
| 667 | } |
| 668 | |
| 669 | exit: |
Song GUO | 74beee2 | 2022-03-29 23:42:30 +0800 | [diff] [blame] | 670 | if (err == CHIP_ERROR_BUFFER_TOO_SMALL || err == CHIP_ERROR_NO_MEMORY) |
| 671 | { |
| 672 | // We failed to fetch the current event because the buffer is too small, we will start from this one the next time. |
| 673 | aEventMin = context.mCurrentEventNumber; |
| 674 | } |
| 675 | else |
| 676 | { |
| 677 | // For all other cases, continue from the next event. |
| 678 | aEventMin = context.mCurrentEventNumber + 1; |
| 679 | } |
yunhanw-google | 289ec6e | 2021-07-19 13:51:47 -0700 | [diff] [blame] | 680 | aEventCount += context.mEventCount; |
yunhanw-google | ef040a7 | 2021-05-05 07:17:56 -0700 | [diff] [blame] | 681 | return err; |
| 682 | } |
| 683 | |
yunhanw-google | c438b89 | 2022-05-05 09:31:07 -0700 | [diff] [blame] | 684 | CHIP_ERROR EventManagement::FabricRemovedCB(const TLV::TLVReader & aReader, size_t aDepth, void * apContext) |
| 685 | { |
| 686 | // the function does not actually remove the event, instead, it sets the fabric index to an invalid value. |
| 687 | FabricIndex * invalidFabricIndex = static_cast<FabricIndex *>(apContext); |
| 688 | |
| 689 | TLVReader event; |
| 690 | TLVType tlvType; |
| 691 | TLVType tlvType1; |
| 692 | event.Init(aReader); |
| 693 | VerifyOrReturnError(event.EnterContainer(tlvType) == CHIP_NO_ERROR, CHIP_NO_ERROR); |
Boris Zbarsky | e434c6a | 2023-03-01 12:35:37 -0500 | [diff] [blame] | 694 | VerifyOrReturnError(event.Next(TLV::ContextTag(EventReportIB::Tag::kEventData)) == CHIP_NO_ERROR, CHIP_NO_ERROR); |
yunhanw-google | c438b89 | 2022-05-05 09:31:07 -0700 | [diff] [blame] | 695 | VerifyOrReturnError(event.EnterContainer(tlvType1) == CHIP_NO_ERROR, CHIP_NO_ERROR); |
| 696 | |
| 697 | while (CHIP_NO_ERROR == event.Next()) |
| 698 | { |
| 699 | if (event.GetTag() == TLV::ProfileTag(kEventManagementProfile, kFabricIndexTag)) |
| 700 | { |
| 701 | uint8_t fabricIndex = 0; |
| 702 | VerifyOrReturnError(event.Get(fabricIndex) == CHIP_NO_ERROR, CHIP_NO_ERROR); |
| 703 | if (fabricIndex == *invalidFabricIndex) |
| 704 | { |
Martin Turon | 77d84e4 | 2023-01-13 06:58:22 -0800 | [diff] [blame] | 705 | TLVCircularBuffer * readBuffer = static_cast<TLVCircularBuffer *>(event.GetBackingStore()); |
yunhanw-google | c438b89 | 2022-05-05 09:31:07 -0700 | [diff] [blame] | 706 | // fabricIndex is encoded as an integer; the dataPtr will point to a location immediately after its encoding |
| 707 | // shift the dataPtr to point to the encoding of the fabric index, accounting for wraparound in backing storage |
| 708 | // we cannot get the actual encoding size from current container beginning to the fabric index because of several |
| 709 | // optional parameters, so we are assuming minimal encoding is used and the fabric index is 1 byte. |
| 710 | uint8_t * dataPtr; |
| 711 | if (event.GetReadPoint() != readBuffer->GetQueue()) |
| 712 | { |
| 713 | dataPtr = readBuffer->GetQueue() + (event.GetReadPoint() - readBuffer->GetQueue() - 1); |
| 714 | } |
| 715 | else |
| 716 | { |
| 717 | dataPtr = readBuffer->GetQueue() + readBuffer->GetTotalDataLength() - 1; |
| 718 | } |
| 719 | |
| 720 | *dataPtr = kUndefinedFabricIndex; |
| 721 | } |
| 722 | return CHIP_NO_ERROR; |
| 723 | } |
| 724 | } |
| 725 | return CHIP_NO_ERROR; |
| 726 | } |
| 727 | |
| 728 | CHIP_ERROR EventManagement::FabricRemoved(FabricIndex aFabricIndex) |
| 729 | { |
| 730 | const bool recurse = false; |
| 731 | TLVReader reader; |
| 732 | CircularEventBufferWrapper bufWrapper; |
| 733 | |
yunhanw-google | c438b89 | 2022-05-05 09:31:07 -0700 | [diff] [blame] | 734 | ReturnErrorOnFailure(GetEventReader(reader, PriorityLevel::Critical, &bufWrapper)); |
| 735 | CHIP_ERROR err = TLV::Utilities::Iterate(reader, FabricRemovedCB, &aFabricIndex, recurse); |
| 736 | if (err == CHIP_END_OF_TLV) |
| 737 | { |
| 738 | err = CHIP_NO_ERROR; |
| 739 | } |
| 740 | return err; |
| 741 | } |
| 742 | |
yunhanw-google | ef040a7 | 2021-05-05 07:17:56 -0700 | [diff] [blame] | 743 | CHIP_ERROR EventManagement::GetEventReader(TLVReader & aReader, PriorityLevel aPriority, CircularEventBufferWrapper * apBufWrapper) |
| 744 | { |
yunhanw-google | ef040a7 | 2021-05-05 07:17:56 -0700 | [diff] [blame] | 745 | CircularEventBuffer * buffer = GetPriorityBuffer(aPriority); |
Kevin Schoedel | f9550e1 | 2021-06-21 17:08:48 -0400 | [diff] [blame] | 746 | VerifyOrReturnError(buffer != nullptr, CHIP_ERROR_INVALID_ARGUMENT); |
yunhanw-google | ef040a7 | 2021-05-05 07:17:56 -0700 | [diff] [blame] | 747 | apBufWrapper->mpCurrent = buffer; |
Kevin Schoedel | f9550e1 | 2021-06-21 17:08:48 -0400 | [diff] [blame] | 748 | |
| 749 | CircularEventReader reader; |
yunhanw-google | ef040a7 | 2021-05-05 07:17:56 -0700 | [diff] [blame] | 750 | reader.Init(apBufWrapper); |
| 751 | aReader.Init(reader); |
Kevin Schoedel | f9550e1 | 2021-06-21 17:08:48 -0400 | [diff] [blame] | 752 | |
| 753 | return CHIP_NO_ERROR; |
yunhanw-google | ef040a7 | 2021-05-05 07:17:56 -0700 | [diff] [blame] | 754 | } |
| 755 | |
yunhanw-google | c438b89 | 2022-05-05 09:31:07 -0700 | [diff] [blame] | 756 | CHIP_ERROR EventManagement::FetchEventParameters(const TLVReader & aReader, size_t, void * apContext) |
yunhanw-google | ef040a7 | 2021-05-05 07:17:56 -0700 | [diff] [blame] | 757 | { |
Kevin Schoedel | f9550e1 | 2021-06-21 17:08:48 -0400 | [diff] [blame] | 758 | EventEnvelopeContext * const envelope = static_cast<EventEnvelopeContext *>(apContext); |
yunhanw-google | ef040a7 | 2021-05-05 07:17:56 -0700 | [diff] [blame] | 759 | TLVReader reader; |
yunhanw-google | ef040a7 | 2021-05-05 07:17:56 -0700 | [diff] [blame] | 760 | reader.Init(aReader); |
| 761 | |
Boris Zbarsky | e434c6a | 2023-03-01 12:35:37 -0500 | [diff] [blame] | 762 | if (reader.GetTag() == TLV::ContextTag(EventDataIB::Tag::kPath)) |
yunhanw-google | d96d8a3 | 2021-05-26 18:24:44 -0700 | [diff] [blame] | 763 | { |
yunhanw-google | 2fe9024 | 2021-11-01 15:13:44 -0700 | [diff] [blame] | 764 | EventPathIB::Parser path; |
Kevin Schoedel | f9550e1 | 2021-06-21 17:08:48 -0400 | [diff] [blame] | 765 | ReturnErrorOnFailure(path.Init(aReader)); |
yunhanw-google | 1f6c6e6 | 2021-11-02 10:09:53 -0700 | [diff] [blame] | 766 | ReturnErrorOnFailure(path.GetEndpoint(&(envelope->mEndpointId))); |
| 767 | ReturnErrorOnFailure(path.GetCluster(&(envelope->mClusterId))); |
| 768 | ReturnErrorOnFailure(path.GetEvent(&(envelope->mEventId))); |
yunhanw-google | 3bec0f9 | 2021-11-03 16:12:39 -0700 | [diff] [blame] | 769 | envelope->mFieldsToRead |= 1 << to_underlying(EventDataIB::Tag::kPath); |
yunhanw-google | d96d8a3 | 2021-05-26 18:24:44 -0700 | [diff] [blame] | 770 | } |
| 771 | |
Boris Zbarsky | e434c6a | 2023-03-01 12:35:37 -0500 | [diff] [blame] | 772 | if (reader.GetTag() == TLV::ContextTag(EventDataIB::Tag::kPriority)) |
yunhanw-google | ef040a7 | 2021-05-05 07:17:56 -0700 | [diff] [blame] | 773 | { |
Kevin Schoedel | f9550e1 | 2021-06-21 17:08:48 -0400 | [diff] [blame] | 774 | uint16_t extPriority; // Note: the type here matches the type case in EventManagement::LogEvent, priority section |
| 775 | ReturnErrorOnFailure(reader.Get(extPriority)); |
yunhanw-google | ef040a7 | 2021-05-05 07:17:56 -0700 | [diff] [blame] | 776 | envelope->mPriority = static_cast<PriorityLevel>(extPriority); |
yunhanw-google | 3bec0f9 | 2021-11-03 16:12:39 -0700 | [diff] [blame] | 777 | envelope->mFieldsToRead |= 1 << to_underlying(EventDataIB::Tag::kPriority); |
yunhanw-google | ef040a7 | 2021-05-05 07:17:56 -0700 | [diff] [blame] | 778 | } |
| 779 | |
Boris Zbarsky | e434c6a | 2023-03-01 12:35:37 -0500 | [diff] [blame] | 780 | if (reader.GetTag() == TLV::ContextTag(EventDataIB::Tag::kEventNumber)) |
yunhanw-google | 83aac59 | 2021-12-09 23:14:55 -0800 | [diff] [blame] | 781 | { |
yunhanw-google | 9a74bae | 2021-12-15 13:33:05 -0800 | [diff] [blame] | 782 | ReturnErrorOnFailure(reader.Get(envelope->mEventNumber)); |
yunhanw-google | 83aac59 | 2021-12-09 23:14:55 -0800 | [diff] [blame] | 783 | } |
| 784 | |
Boris Zbarsky | e434c6a | 2023-03-01 12:35:37 -0500 | [diff] [blame] | 785 | if (reader.GetTag() == TLV::ContextTag(EventDataIB::Tag::kSystemTimestamp)) |
yunhanw-google | 83aac59 | 2021-12-09 23:14:55 -0800 | [diff] [blame] | 786 | { |
yunhanw-google | 9a74bae | 2021-12-15 13:33:05 -0800 | [diff] [blame] | 787 | uint64_t systemTime; |
| 788 | ReturnErrorOnFailure(reader.Get(systemTime)); |
| 789 | envelope->mCurrentTime.mType = Timestamp::Type::kSystem; |
| 790 | envelope->mCurrentTime.mValue = systemTime; |
| 791 | } |
| 792 | |
Boris Zbarsky | e434c6a | 2023-03-01 12:35:37 -0500 | [diff] [blame] | 793 | if (reader.GetTag() == TLV::ContextTag(EventDataIB::Tag::kEpochTimestamp)) |
yunhanw-google | 9a74bae | 2021-12-15 13:33:05 -0800 | [diff] [blame] | 794 | { |
| 795 | uint64_t epochTime; |
| 796 | ReturnErrorOnFailure(reader.Get(epochTime)); |
| 797 | envelope->mCurrentTime.mType = Timestamp::Type::kEpoch; |
| 798 | envelope->mCurrentTime.mValue = epochTime; |
yunhanw-google | 83aac59 | 2021-12-09 23:14:55 -0800 | [diff] [blame] | 799 | } |
yunhanw-google | e450832 | 2022-01-26 18:27:51 -0800 | [diff] [blame] | 800 | |
| 801 | if (reader.GetTag() == TLV::ProfileTag(kEventManagementProfile, kFabricIndexTag)) |
| 802 | { |
yunhanw-google | c438b89 | 2022-05-05 09:31:07 -0700 | [diff] [blame] | 803 | uint8_t fabricIndex = kUndefinedFabricIndex; |
| 804 | ReturnErrorOnFailure(reader.Get(fabricIndex)); |
| 805 | envelope->mFabricIndex.SetValue(fabricIndex); |
yunhanw-google | e450832 | 2022-01-26 18:27:51 -0800 | [diff] [blame] | 806 | } |
Kevin Schoedel | f9550e1 | 2021-06-21 17:08:48 -0400 | [diff] [blame] | 807 | return CHIP_NO_ERROR; |
yunhanw-google | ef040a7 | 2021-05-05 07:17:56 -0700 | [diff] [blame] | 808 | } |
| 809 | |
Martin Turon | 77d84e4 | 2023-01-13 06:58:22 -0800 | [diff] [blame] | 810 | CHIP_ERROR EventManagement::EvictEvent(TLVCircularBuffer & apBuffer, void * apAppData, TLVReader & aReader) |
yunhanw-google | ef040a7 | 2021-05-05 07:17:56 -0700 | [diff] [blame] | 811 | { |
yunhanw-google | ef040a7 | 2021-05-05 07:17:56 -0700 | [diff] [blame] | 812 | // pull out the delta time, pull out the priority |
Kevin Schoedel | f9550e1 | 2021-06-21 17:08:48 -0400 | [diff] [blame] | 813 | ReturnErrorOnFailure(aReader.Next()); |
yunhanw-google | ef040a7 | 2021-05-05 07:17:56 -0700 | [diff] [blame] | 814 | |
Kevin Schoedel | f9550e1 | 2021-06-21 17:08:48 -0400 | [diff] [blame] | 815 | TLVType containerType; |
yunhanw-google | 3bec0f9 | 2021-11-03 16:12:39 -0700 | [diff] [blame] | 816 | TLVType containerType1; |
Kevin Schoedel | f9550e1 | 2021-06-21 17:08:48 -0400 | [diff] [blame] | 817 | ReturnErrorOnFailure(aReader.EnterContainer(containerType)); |
yunhanw-google | 3bec0f9 | 2021-11-03 16:12:39 -0700 | [diff] [blame] | 818 | ReturnErrorOnFailure(aReader.Next()); |
yunhanw-google | f3d6b7c | 2021-11-17 13:42:38 -0800 | [diff] [blame] | 819 | |
yunhanw-google | 3bec0f9 | 2021-11-03 16:12:39 -0700 | [diff] [blame] | 820 | ReturnErrorOnFailure(aReader.EnterContainer(containerType1)); |
Kevin Schoedel | f9550e1 | 2021-06-21 17:08:48 -0400 | [diff] [blame] | 821 | EventEnvelopeContext context; |
| 822 | constexpr bool recurse = false; |
| 823 | CHIP_ERROR err = TLV::Utilities::Iterate(aReader, FetchEventParameters, &context, recurse); |
yunhanw-google | ef040a7 | 2021-05-05 07:17:56 -0700 | [diff] [blame] | 824 | if (err == CHIP_END_OF_TLV) |
| 825 | { |
| 826 | err = CHIP_NO_ERROR; |
| 827 | } |
Kevin Schoedel | f9550e1 | 2021-06-21 17:08:48 -0400 | [diff] [blame] | 828 | ReturnErrorOnFailure(err); |
yunhanw-google | ef040a7 | 2021-05-05 07:17:56 -0700 | [diff] [blame] | 829 | |
yunhanw-google | 3bec0f9 | 2021-11-03 16:12:39 -0700 | [diff] [blame] | 830 | ReturnErrorOnFailure(aReader.ExitContainer(containerType1)); |
Kevin Schoedel | f9550e1 | 2021-06-21 17:08:48 -0400 | [diff] [blame] | 831 | ReturnErrorOnFailure(aReader.ExitContainer(containerType)); |
Kevin Schoedel | f9550e1 | 2021-06-21 17:08:48 -0400 | [diff] [blame] | 832 | const PriorityLevel imp = static_cast<PriorityLevel>(context.mPriority); |
yunhanw-google | ef040a7 | 2021-05-05 07:17:56 -0700 | [diff] [blame] | 833 | |
Kevin Schoedel | f9550e1 | 2021-06-21 17:08:48 -0400 | [diff] [blame] | 834 | ReclaimEventCtx * const ctx = static_cast<ReclaimEventCtx *>(apAppData); |
| 835 | CircularEventBuffer * const eventBuffer = ctx->mpEventBuffer; |
yunhanw-google | ef040a7 | 2021-05-05 07:17:56 -0700 | [diff] [blame] | 836 | if (eventBuffer->IsFinalDestinationForPriority(imp)) |
| 837 | { |
yunhanw-google | 9a74bae | 2021-12-15 13:33:05 -0800 | [diff] [blame] | 838 | ChipLogProgress(EventLogging, |
| 839 | "Dropped 1 event from buffer with priority %u and event number 0x" ChipLogFormatX64 |
| 840 | " due to overflow: event priority_level: %u", |
| 841 | static_cast<unsigned>(eventBuffer->GetPriority()), ChipLogValueX64(context.mEventNumber), |
| 842 | static_cast<unsigned>(imp)); |
yunhanw-google | ef040a7 | 2021-05-05 07:17:56 -0700 | [diff] [blame] | 843 | ctx->mSpaceNeededForMovedEvent = 0; |
Kevin Schoedel | f9550e1 | 2021-06-21 17:08:48 -0400 | [diff] [blame] | 844 | return CHIP_NO_ERROR; |
yunhanw-google | ef040a7 | 2021-05-05 07:17:56 -0700 | [diff] [blame] | 845 | } |
| 846 | |
Kevin Schoedel | f9550e1 | 2021-06-21 17:08:48 -0400 | [diff] [blame] | 847 | // event is not getting dropped. Note how much space it requires, and return. |
| 848 | ctx->mSpaceNeededForMovedEvent = aReader.GetLengthRead(); |
| 849 | return CHIP_END_OF_TLV; |
yunhanw-google | ef040a7 | 2021-05-05 07:17:56 -0700 | [diff] [blame] | 850 | } |
| 851 | |
Andrei Litvin | d43e6a7 | 2022-03-17 17:39:24 -0400 | [diff] [blame] | 852 | void EventManagement::SetScheduledEventInfo(EventNumber & aEventNumber, uint32_t & aInitialWrittenEventBytes) const |
yunhanw-google | 8ddfb87 | 2021-05-07 18:13:15 -0700 | [diff] [blame] | 853 | { |
yunhanw-google | 41700bd | 2021-12-16 01:20:03 -0800 | [diff] [blame] | 854 | aEventNumber = mLastEventNumber; |
| 855 | aInitialWrittenEventBytes = mBytesWritten; |
yunhanw-google | 8ddfb87 | 2021-05-07 18:13:15 -0700 | [diff] [blame] | 856 | } |
| 857 | |
Andrei Litvin | 0b8ffb7 | 2024-09-18 14:53:18 -0400 | [diff] [blame] | 858 | CHIP_ERROR EventManagement::GenerateEvent(EventLoggingDelegate * eventPayloadWriter, const EventOptions & options, |
| 859 | EventNumber & generatedEventNumber) |
| 860 | { |
| 861 | return LogEvent(eventPayloadWriter, options, generatedEventNumber); |
| 862 | } |
| 863 | |
yunhanw-google | ef040a7 | 2021-05-05 07:17:56 -0700 | [diff] [blame] | 864 | void CircularEventBuffer::Init(uint8_t * apBuffer, uint32_t aBufferLength, CircularEventBuffer * apPrev, |
| 865 | CircularEventBuffer * apNext, PriorityLevel aPriorityLevel) |
| 866 | { |
Martin Turon | 77d84e4 | 2023-01-13 06:58:22 -0800 | [diff] [blame] | 867 | TLVCircularBuffer::Init(apBuffer, aBufferLength); |
Boris Zbarsky | cc3a98c | 2022-04-14 23:15:16 -0400 | [diff] [blame] | 868 | mpPrev = apPrev; |
| 869 | mpNext = apNext; |
| 870 | mPriority = aPriorityLevel; |
yunhanw-google | ef040a7 | 2021-05-05 07:17:56 -0700 | [diff] [blame] | 871 | } |
| 872 | |
| 873 | bool CircularEventBuffer::IsFinalDestinationForPriority(PriorityLevel aPriority) const |
| 874 | { |
| 875 | return !((mpNext != nullptr) && (mpNext->mPriority <= aPriority)); |
| 876 | } |
| 877 | |
yunhanw-google | 015f11c | 2023-02-22 15:28:07 -0800 | [diff] [blame] | 878 | /** |
| 879 | * @brief |
| 880 | * TLVCircularBuffer::OnInit can modify the state of the buffer, but we don't want that behavior here. |
| 881 | * We want to make sure we don't change our state, and just report the currently-available space. |
| 882 | */ |
| 883 | CHIP_ERROR CircularEventBuffer::OnInit(TLV::TLVWriter & writer, uint8_t *& bufStart, uint32_t & bufLen) |
| 884 | { |
| 885 | GetCurrentWritableBuffer(bufStart, bufLen); |
| 886 | return CHIP_NO_ERROR; |
| 887 | } |
| 888 | |
yunhanw-google | ef040a7 | 2021-05-05 07:17:56 -0700 | [diff] [blame] | 889 | void CircularEventReader::Init(CircularEventBufferWrapper * apBufWrapper) |
| 890 | { |
| 891 | CircularEventBuffer * prev; |
| 892 | |
| 893 | if (apBufWrapper->mpCurrent == nullptr) |
| 894 | return; |
| 895 | |
| 896 | TLVReader::Init(*apBufWrapper, apBufWrapper->mpCurrent->DataLength()); |
| 897 | mMaxLen = apBufWrapper->mpCurrent->DataLength(); |
| 898 | for (prev = apBufWrapper->mpCurrent->GetPreviousCircularEventBuffer(); prev != nullptr; |
| 899 | prev = prev->GetPreviousCircularEventBuffer()) |
| 900 | { |
| 901 | CircularEventBufferWrapper bufWrapper; |
| 902 | bufWrapper.mpCurrent = prev; |
| 903 | mMaxLen += prev->DataLength(); |
| 904 | } |
| 905 | } |
| 906 | |
| 907 | CHIP_ERROR CircularEventBufferWrapper::GetNextBuffer(TLVReader & aReader, const uint8_t *& aBufStart, uint32_t & aBufLen) |
| 908 | { |
| 909 | CHIP_ERROR err = CHIP_NO_ERROR; |
| 910 | mpCurrent->GetNextBuffer(aReader, aBufStart, aBufLen); |
| 911 | SuccessOrExit(err); |
| 912 | |
| 913 | if ((aBufLen == 0) && (mpCurrent->GetPreviousCircularEventBuffer() != nullptr)) |
| 914 | { |
| 915 | mpCurrent = mpCurrent->GetPreviousCircularEventBuffer(); |
| 916 | aBufStart = nullptr; |
| 917 | err = GetNextBuffer(aReader, aBufStart, aBufLen); |
| 918 | } |
| 919 | |
| 920 | exit: |
yunhanw-google | ef040a7 | 2021-05-05 07:17:56 -0700 | [diff] [blame] | 921 | return err; |
| 922 | } |
Andrei Litvin | 0b8ffb7 | 2024-09-18 14:53:18 -0400 | [diff] [blame] | 923 | |
yunhanw-google | ef040a7 | 2021-05-05 07:17:56 -0700 | [diff] [blame] | 924 | } // namespace app |
| 925 | } // namespace chip |