Matter SDK Coverage Report
Current view: top level - app/data-model-provider - EventsGenerator.h (source / functions) Coverage Total Hit
Test: SHA:b879ecb8e99e175eea0a293a888bda853da2b19c Lines: 100.0 % 1 1
Test Date: 2025-01-17 19:00:11 Functions: 50.0 % 2 1

            Line data    Source code
       1              : /*
       2              :  *    Copyright (c) 2024 Project CHIP Authors
       3              :  *    All rights reserved.
       4              :  *
       5              :  *    Licensed under the Apache License, Version 2.0 (the "License");
       6              :  *    you may not use this file except in compliance with the License.
       7              :  *    You may obtain a copy of the License at
       8              :  *
       9              :  *        http://www.apache.org/licenses/LICENSE-2.0
      10              :  *
      11              :  *    Unless required by applicable law or agreed to in writing, software
      12              :  *    distributed under the License is distributed on an "AS IS" BASIS,
      13              :  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      14              :  *    See the License for the specific language governing permissions and
      15              :  *    limitations under the License.
      16              :  */
      17              : #pragma once
      18              : 
      19              : #include <app/EventLoggingDelegate.h>
      20              : #include <app/EventLoggingTypes.h>
      21              : #include <app/MessageDef/EventDataIB.h>
      22              : #include <app/data-model/Encode.h>
      23              : #include <app/data-model/FabricScoped.h>
      24              : #include <lib/core/CHIPError.h>
      25              : #include <lib/support/logging/CHIPLogging.h>
      26              : 
      27              : #include <optional>
      28              : #include <type_traits>
      29              : 
      30              : namespace chip {
      31              : namespace app {
      32              : namespace DataModel {
      33              : 
      34              : namespace internal {
      35              : template <typename T>
      36              : class SimpleEventPayloadWriter : public EventLoggingDelegate
      37              : {
      38              : public:
      39              :     SimpleEventPayloadWriter(const T & aEventData) : mEventData(aEventData){};
      40              :     CHIP_ERROR WriteEvent(chip::TLV::TLVWriter & aWriter) final override
      41              :     {
      42              :         return DataModel::Encode(aWriter, TLV::ContextTag(EventDataIB::Tag::kData), mEventData);
      43              :     }
      44              : 
      45              : private:
      46              :     const T & mEventData;
      47              : };
      48              : 
      49              : template <typename G, typename T, std::enable_if_t<DataModel::IsFabricScoped<T>::value, bool> = true>
      50              : std::optional<EventNumber> GenerateEvent(G & generator, const T & aEventData, EndpointId aEndpoint)
      51              : {
      52              :     internal::SimpleEventPayloadWriter<T> eventPayloadWriter(aEventData);
      53              :     ConcreteEventPath path(aEndpoint, aEventData.GetClusterId(), aEventData.GetEventId());
      54              :     EventOptions eventOptions;
      55              :     eventOptions.mPath        = path;
      56              :     eventOptions.mPriority    = aEventData.GetPriorityLevel();
      57              :     eventOptions.mFabricIndex = aEventData.GetFabricIndex();
      58              : 
      59              :     // this skips generating the event if it is fabric-scoped but the provided event data is not
      60              :     // associated with any fabric.
      61              :     if (eventOptions.mFabricIndex == kUndefinedFabricIndex)
      62              :     {
      63              :         ChipLogError(EventLogging, "Event encode failure: no fabric index for fabric scoped event");
      64              :         return std::nullopt;
      65              :     }
      66              : 
      67              :     //
      68              :     // Unlike attributes which have a different 'EncodeForRead' for fabric-scoped structs,
      69              :     // fabric-sensitive events don't require that since the actual omission of the event in its entirety
      70              :     // happens within the event management framework itself at the time of access.
      71              :     //
      72              :     // The 'mFabricIndex' field in the event options above is encoded out-of-band alongside the event payload
      73              :     // and used to match against the accessing fabric.
      74              :     //
      75              :     EventNumber eventNumber;
      76              :     CHIP_ERROR err = generator.GenerateEvent(&eventPayloadWriter, eventOptions, eventNumber);
      77              :     if (err != CHIP_NO_ERROR)
      78              :     {
      79              :         ChipLogError(EventLogging, "Failed to generate event: %" CHIP_ERROR_FORMAT, err.Format());
      80              :         return std::nullopt;
      81              :     }
      82              : 
      83              :     return eventNumber;
      84              : }
      85              : 
      86              : template <typename G, typename T, std::enable_if_t<!DataModel::IsFabricScoped<T>::value, bool> = true>
      87              : std::optional<EventNumber> GenerateEvent(G & generator, const T & aEventData, EndpointId endpointId)
      88              : {
      89              :     internal::SimpleEventPayloadWriter<T> eventPayloadWriter(aEventData);
      90              :     ConcreteEventPath path(endpointId, aEventData.GetClusterId(), aEventData.GetEventId());
      91              :     EventOptions eventOptions;
      92              :     eventOptions.mPath     = path;
      93              :     eventOptions.mPriority = aEventData.GetPriorityLevel();
      94              :     EventNumber eventNumber;
      95              :     CHIP_ERROR err = generator.GenerateEvent(&eventPayloadWriter, eventOptions, eventNumber);
      96              :     if (err != CHIP_NO_ERROR)
      97              :     {
      98              :         ChipLogError(EventLogging, "Failed to generate event: %" CHIP_ERROR_FORMAT, err.Format());
      99              :         return std::nullopt;
     100              :     }
     101              : 
     102              :     return eventNumber;
     103              : }
     104              : 
     105              : } // namespace internal
     106              : 
     107              : /// Exposes event generation capabilities.
     108              : ///
     109              : /// Allows callers to "generate events" which effectively notifies of an event having
     110              : /// ocurred.
     111              : class EventsGenerator
     112              : {
     113              : public:
     114           60 :     virtual ~EventsGenerator() = default;
     115              : 
     116              :     /// Generates the given event.
     117              :     ///
     118              :     /// Events are generally expected to be sent to subscribed clients and also
     119              :     /// be available for read later until they get overwritten by new events
     120              :     /// that are being generated.
     121              :     virtual CHIP_ERROR GenerateEvent(EventLoggingDelegate * eventPayloadWriter, const EventOptions & options,
     122              :                                      EventNumber & generatedEventNumber) = 0;
     123              : 
     124              :     // Convenience methods for event logging using cluster-object structures
     125              :     //
     126              :     // On error, these log and return nullopt.
     127              :     template <typename T>
     128              :     std::optional<EventNumber> GenerateEvent(const T & eventData, EndpointId endpointId)
     129              :     {
     130              :         return internal::GenerateEvent(*this, eventData, endpointId);
     131              :     }
     132              : };
     133              : 
     134              : } // namespace DataModel
     135              : } // namespace app
     136              : } // namespace chip
        

Generated by: LCOV version 2.0-1