yunhanw-google | 6f89b9b | 2021-12-07 14:26:21 -0800 | [diff] [blame] | 1 | /* |
| 2 | * |
| 3 | * Copyright (c) 2021 Project CHIP Authors |
| 4 | * All rights reserved. |
| 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 | |
| 19 | #pragma once |
| 20 | |
| 21 | #include <app/ConcreteEventPath.h> |
| 22 | #include <app/EventLoggingDelegate.h> |
| 23 | #include <app/EventManagement.h> |
| 24 | #include <app/data-model/Encode.h> |
yunhanw-google | e450832 | 2022-01-26 18:27:51 -0800 | [diff] [blame] | 25 | #include <app/data-model/FabricScoped.h> |
yunhanw-google | 6f89b9b | 2021-12-07 14:26:21 -0800 | [diff] [blame] | 26 | #include <app/data-model/List.h> // So we can encode lists |
| 27 | |
| 28 | namespace chip { |
| 29 | namespace app { |
| 30 | |
| 31 | template <typename T> |
| 32 | class EventLogger : public EventLoggingDelegate |
| 33 | { |
| 34 | public: |
| 35 | EventLogger(const T & aEventData) : mEventData(aEventData){}; |
| 36 | CHIP_ERROR WriteEvent(chip::TLV::TLVWriter & aWriter) final override |
| 37 | { |
Boris Zbarsky | e434c6a | 2023-03-01 12:35:37 -0500 | [diff] [blame] | 38 | return DataModel::Encode(aWriter, TLV::ContextTag(EventDataIB::Tag::kData), mEventData); |
yunhanw-google | 6f89b9b | 2021-12-07 14:26:21 -0800 | [diff] [blame] | 39 | } |
| 40 | |
| 41 | private: |
| 42 | const T & mEventData; |
| 43 | }; |
| 44 | |
| 45 | /** |
| 46 | * @brief |
| 47 | * Log an event via a EventLoggingDelegate, with options. |
| 48 | * |
| 49 | * The EventLoggingDelegate writes the event metadata and calls the `apDelegate` |
| 50 | * with an TLV::TLVWriter reference so that the user code can emit |
| 51 | * the event data directly into the event log. This form of event |
| 52 | * logging minimizes memory consumption, as event data is serialized |
| 53 | * directly into the target buffer. The event data MUST contain |
| 54 | * context tags to be interpreted within the schema identified by |
| 55 | * `ClusterID` and `EventId`. |
| 56 | * |
yunhanw-google | 783c3e0 | 2024-01-29 23:24:48 -0800 | [diff] [blame] | 57 | * The consumer has to either lock the Matter stack lock or queue the event to |
| 58 | * the Matter event queue when using LogEvent. This function is not safe to call |
| 59 | * outside of the main Matter processing context. |
| 60 | * |
yunhanw-google | e450832 | 2022-01-26 18:27:51 -0800 | [diff] [blame] | 61 | * LogEvent has 2 variant, one for fabric-scoped events and one for non-fabric-scoped events. |
| 62 | * @param[in] aEventData The event cluster object |
yunhanw-google | 86823aa | 2021-12-08 06:35:52 -0800 | [diff] [blame] | 63 | * @param[in] aEndpoint The current cluster's Endpoint Id |
yunhanw-google | 6f89b9b | 2021-12-07 14:26:21 -0800 | [diff] [blame] | 64 | * @param[out] aEventNumber The event Number if the event was written to the |
| 65 | * log, 0 otherwise. The Event number is expected to monotonically increase. |
| 66 | * |
| 67 | * @return CHIP_ERROR CHIP Error Code |
| 68 | */ |
Boris Zbarsky | 359fd43 | 2022-01-30 09:21:12 -0500 | [diff] [blame] | 69 | template <typename T, std::enable_if_t<DataModel::IsFabricScoped<T>::value, bool> = true> |
yunhanw-google | cd44f9b | 2022-03-09 10:36:31 -0800 | [diff] [blame] | 70 | CHIP_ERROR LogEvent(const T & aEventData, EndpointId aEndpoint, EventNumber & aEventNumber) |
yunhanw-google | e450832 | 2022-01-26 18:27:51 -0800 | [diff] [blame] | 71 | { |
| 72 | EventLogger<T> eventData(aEventData); |
| 73 | ConcreteEventPath path(aEndpoint, aEventData.GetClusterId(), aEventData.GetEventId()); |
| 74 | EventManagement & logMgmt = chip::app::EventManagement::GetInstance(); |
| 75 | EventOptions eventOptions; |
yunhanw-google | e450832 | 2022-01-26 18:27:51 -0800 | [diff] [blame] | 76 | eventOptions.mPath = path; |
| 77 | eventOptions.mPriority = aEventData.GetPriorityLevel(); |
| 78 | eventOptions.mFabricIndex = aEventData.GetFabricIndex(); |
yunhanw-google | c037fc2 | 2022-08-17 16:02:52 -0700 | [diff] [blame] | 79 | // this skips logging the event if it's fabric-scoped but no fabric association exists yet. |
yunhanw-google | 977aba0 | 2022-08-22 06:53:08 -0700 | [diff] [blame] | 80 | VerifyOrReturnError(eventOptions.mFabricIndex != kUndefinedFabricIndex, CHIP_ERROR_INVALID_FABRIC_INDEX); |
Jerry Johns | 11a5b14 | 2022-02-17 15:21:39 -0800 | [diff] [blame] | 81 | |
| 82 | // |
| 83 | // Unlike attributes which have a different 'EncodeForRead' for fabric-scoped structs, |
| 84 | // fabric-sensitive events don't require that since the actual omission of the event in its entirety |
| 85 | // happens within the event management framework itself at the time of access. |
| 86 | // |
| 87 | // The 'mFabricIndex' field in the event options above is encoded out-of-band alongside the event payload |
| 88 | // and used to match against the accessing fabric. |
| 89 | // |
yunhanw-google | e450832 | 2022-01-26 18:27:51 -0800 | [diff] [blame] | 90 | return logMgmt.LogEvent(&eventData, eventOptions, aEventNumber); |
| 91 | } |
| 92 | |
| 93 | template <typename T, std::enable_if_t<!DataModel::IsFabricScoped<T>::value, bool> = true> |
yunhanw-google | cd44f9b | 2022-03-09 10:36:31 -0800 | [diff] [blame] | 94 | CHIP_ERROR LogEvent(const T & aEventData, EndpointId aEndpoint, EventNumber & aEventNumber) |
yunhanw-google | 6f89b9b | 2021-12-07 14:26:21 -0800 | [diff] [blame] | 95 | { |
| 96 | EventLogger<T> eventData(aEventData); |
| 97 | ConcreteEventPath path(aEndpoint, aEventData.GetClusterId(), aEventData.GetEventId()); |
| 98 | EventManagement & logMgmt = chip::app::EventManagement::GetInstance(); |
yunhanw-google | 86823aa | 2021-12-08 06:35:52 -0800 | [diff] [blame] | 99 | EventOptions eventOptions; |
yunhanw-google | 86823aa | 2021-12-08 06:35:52 -0800 | [diff] [blame] | 100 | eventOptions.mPath = path; |
| 101 | eventOptions.mPriority = aEventData.GetPriorityLevel(); |
| 102 | return logMgmt.LogEvent(&eventData, eventOptions, aEventNumber); |
yunhanw-google | 6f89b9b | 2021-12-07 14:26:21 -0800 | [diff] [blame] | 103 | } |
| 104 | |
| 105 | } // namespace app |
| 106 | } // namespace chip |