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