1 #include "preconditions.hpp"
2 
3 #include "zone.hpp"
4 
5 #include <phosphor-logging/log.hpp>
6 
7 #include <algorithm>
8 
9 namespace phosphor
10 {
11 namespace fan
12 {
13 namespace control
14 {
15 namespace precondition
16 {
17 
18 using namespace phosphor::fan;
19 using namespace phosphor::logging;
20 
21 Action property_states_match(std::vector<PrecondGroup>&& pg,
22                              std::vector<SetSpeedEvent>&& sse)
23 {
24     return [pg = std::move(pg), sse = std::move(sse)](auto& zone, auto& group) {
25         // Compare given precondition entries
26         auto precondState =
27             std::all_of(pg.begin(), pg.end(), [&zone](auto const& entry) {
28                 try
29                 {
30                     return zone.getPropValueVariant(
31                                std::get<pcPathPos>(entry),
32                                std::get<pcIntfPos>(entry),
33                                std::get<pcPropPos>(entry)) ==
34                            std::get<pcValuePos>(entry);
35                 }
36                 catch (const std::out_of_range& oore)
37                 {
38                     // Default to property variants not equal when not found
39                     return false;
40                 }
41             });
42 
43         if (precondState)
44         {
45             log<level::DEBUG>(
46                 "Preconditions passed, init the associated events",
47                 entry("EVENT_COUNT=%u", sse.size()));
48             // Init the events when all the precondition(s) are true
49             std::for_each(sse.begin(), sse.end(), [&zone](auto const& entry) {
50                 zone.initEvent(entry);
51             });
52         }
53         else
54         {
55             log<level::DEBUG>(
56                 "Preconditions not met for events, events removed if present",
57                 entry("EVENT_COUNT=%u", sse.size()));
58             // Unsubscribe the events' signals when any precondition is false
59             std::for_each(sse.begin(), sse.end(), [&zone](auto const& entry) {
60                 zone.removeEvent(entry);
61             });
62             zone.setFullSpeed();
63         }
64         // Update group's fan control active allowed
65         zone.setActiveAllow(&group, precondState);
66     };
67 }
68 
69 Action services_missing_owner(std::vector<SetSpeedEvent>&& sse)
70 {
71     return [sse = std::move(sse)](auto& zone, auto& group) {
72         // Set/update the services of the group
73         zone.setServices(&group);
74         const auto& services = zone.getGroupServices(&group);
75         auto precondState =
76             std::any_of(services.begin(), services.end(), [](const auto& s) {
77                 return !std::get<hasOwnerPos>(s);
78             });
79 
80         if (precondState)
81         {
82             // Init the events when all the precondition(s) are true
83             std::for_each(sse.begin(), sse.end(), [&zone](auto const& entry) {
84                 zone.initEvent(entry);
85             });
86         }
87         else
88         {
89             // Unsubscribe the events' signals when any precondition is false
90             std::for_each(sse.begin(), sse.end(), [&zone](auto const& entry) {
91                 zone.removeEvent(entry);
92             });
93         }
94     };
95 }
96 
97 } // namespace precondition
98 } // namespace control
99 } // namespace fan
100 } // namespace phosphor
101