xref: /openbmc/phosphor-fan-presence/control/json/manager.cpp (revision 12cb125a1ef2b357a032c36157a7a99995d5d7f1)
1a227a16dSMatthew Barth /**
2a227a16dSMatthew Barth  * Copyright © 2020 IBM Corporation
3a227a16dSMatthew Barth  *
4a227a16dSMatthew Barth  * Licensed under the Apache License, Version 2.0 (the "License");
5a227a16dSMatthew Barth  * you may not use this file except in compliance with the License.
6a227a16dSMatthew Barth  * You may obtain a copy of the License at
7a227a16dSMatthew Barth  *
8a227a16dSMatthew Barth  *     http://www.apache.org/licenses/LICENSE-2.0
9a227a16dSMatthew Barth  *
10a227a16dSMatthew Barth  * Unless required by applicable law or agreed to in writing, software
11a227a16dSMatthew Barth  * distributed under the License is distributed on an "AS IS" BASIS,
12a227a16dSMatthew Barth  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13a227a16dSMatthew Barth  * See the License for the specific language governing permissions and
14a227a16dSMatthew Barth  * limitations under the License.
15a227a16dSMatthew Barth  */
16a227a16dSMatthew Barth #include "manager.hpp"
17a227a16dSMatthew Barth 
18de90fb4dSMatthew Barth #include "fan.hpp"
19a227a16dSMatthew Barth #include "json_config.hpp"
2006764946SMatthew Barth #include "profile.hpp"
21acd737cdSMatthew Barth #include "zone.hpp"
22a227a16dSMatthew Barth 
23acd737cdSMatthew Barth #include <nlohmann/json.hpp>
24a227a16dSMatthew Barth #include <sdbusplus/bus.hpp>
25acd737cdSMatthew Barth #include <sdeventplus/event.hpp>
26a227a16dSMatthew Barth 
27de90fb4dSMatthew Barth #include <algorithm>
28a227a16dSMatthew Barth #include <filesystem>
2906764946SMatthew Barth #include <vector>
30a227a16dSMatthew Barth 
31a227a16dSMatthew Barth namespace phosphor::fan::control::json
32a227a16dSMatthew Barth {
33a227a16dSMatthew Barth 
34acd737cdSMatthew Barth using json = nlohmann::json;
35acd737cdSMatthew Barth 
36acd737cdSMatthew Barth std::vector<std::string> Manager::_activeProfiles;
37*12cb125aSMatthew Barth std::map<std::string,
38*12cb125aSMatthew Barth          std::map<std::pair<std::string, bool>, std::vector<std::string>>>
39*12cb125aSMatthew Barth     Manager::_servTree;
40acd737cdSMatthew Barth 
4106764946SMatthew Barth Manager::Manager(sdbusplus::bus::bus& bus, const sdeventplus::Event& event) :
42acd737cdSMatthew Barth     _bus(bus), _event(event)
43a227a16dSMatthew Barth {
44a227a16dSMatthew Barth     // Manager JSON config file is optional
45a227a16dSMatthew Barth     auto confFile =
46a227a16dSMatthew Barth         fan::JsonConfig::getConfFile(bus, confAppName, confFileName, true);
47a227a16dSMatthew Barth     if (!confFile.empty())
48a227a16dSMatthew Barth     {
49a227a16dSMatthew Barth         _jsonObj = fan::JsonConfig::load(confFile);
50a227a16dSMatthew Barth     }
5106764946SMatthew Barth 
52acd737cdSMatthew Barth     // Parse and set the available profiles and which are active
53acd737cdSMatthew Barth     setProfiles();
54acd737cdSMatthew Barth 
55acd737cdSMatthew Barth     // Load the zone configurations
56acd737cdSMatthew Barth     _zones = getConfig<Zone>(bus);
57de90fb4dSMatthew Barth 
58de90fb4dSMatthew Barth     // Load the fan configurations and move each fan into its zone
59de90fb4dSMatthew Barth     auto fans = getConfig<Fan>(bus);
60de90fb4dSMatthew Barth     for (auto& fan : fans)
61de90fb4dSMatthew Barth     {
62de90fb4dSMatthew Barth         auto itZone =
63de90fb4dSMatthew Barth             std::find_if(_zones.begin(), _zones.end(),
64de90fb4dSMatthew Barth                          [&fanZone = fan.second->getZone()](const auto& zone) {
65de90fb4dSMatthew Barth                              return fanZone == zone.second->getName();
66de90fb4dSMatthew Barth                          });
67de90fb4dSMatthew Barth         if (itZone != _zones.end())
68de90fb4dSMatthew Barth         {
69de90fb4dSMatthew Barth             itZone->second->addFan(std::move(fan.second));
70de90fb4dSMatthew Barth         }
71de90fb4dSMatthew Barth     }
7206764946SMatthew Barth }
73acd737cdSMatthew Barth 
74acd737cdSMatthew Barth const std::vector<std::string>& Manager::getActiveProfiles()
75acd737cdSMatthew Barth {
76acd737cdSMatthew Barth     return _activeProfiles;
77a227a16dSMatthew Barth }
78a227a16dSMatthew Barth 
79*12cb125aSMatthew Barth bool Manager::hasOwner(const std::string& path, const std::string& intf)
80*12cb125aSMatthew Barth {
81*12cb125aSMatthew Barth     auto itServ = _servTree.find(path);
82*12cb125aSMatthew Barth     if (itServ == _servTree.end())
83*12cb125aSMatthew Barth     {
84*12cb125aSMatthew Barth         // Path not found in cache, therefore owner missing
85*12cb125aSMatthew Barth         return false;
86*12cb125aSMatthew Barth     }
87*12cb125aSMatthew Barth     for (const auto& serv : itServ->second)
88*12cb125aSMatthew Barth     {
89*12cb125aSMatthew Barth         auto itIntf = std::find_if(
90*12cb125aSMatthew Barth             serv.second.begin(), serv.second.end(),
91*12cb125aSMatthew Barth             [&intf](const auto& interface) { return intf == interface; });
92*12cb125aSMatthew Barth         if (itIntf != std::end(serv.second))
93*12cb125aSMatthew Barth         {
94*12cb125aSMatthew Barth             // Service found, return owner state
95*12cb125aSMatthew Barth             return serv.first.second;
96*12cb125aSMatthew Barth         }
97*12cb125aSMatthew Barth     }
98*12cb125aSMatthew Barth     // Interface not found in cache, therefore owner missing
99*12cb125aSMatthew Barth     return false;
100*12cb125aSMatthew Barth }
101*12cb125aSMatthew Barth 
102a227a16dSMatthew Barth unsigned int Manager::getPowerOnDelay()
103a227a16dSMatthew Barth {
104a227a16dSMatthew Barth     auto powerOnDelay = 0;
105a227a16dSMatthew Barth 
106a227a16dSMatthew Barth     // Parse optional "power_on_delay" from JSON object
107a227a16dSMatthew Barth     if (!_jsonObj.empty() && _jsonObj.contains("power_on_delay"))
108a227a16dSMatthew Barth     {
109a227a16dSMatthew Barth         powerOnDelay = _jsonObj["power_on_delay"].get<unsigned int>();
110a227a16dSMatthew Barth     }
111a227a16dSMatthew Barth 
112a227a16dSMatthew Barth     return powerOnDelay;
113a227a16dSMatthew Barth }
114a227a16dSMatthew Barth 
115acd737cdSMatthew Barth void Manager::setProfiles()
116acd737cdSMatthew Barth {
117acd737cdSMatthew Barth     // Profiles JSON config file is optional
118acd737cdSMatthew Barth     auto confFile = fan::JsonConfig::getConfFile(_bus, confAppName,
119acd737cdSMatthew Barth                                                  Profile::confFileName, true);
120acd737cdSMatthew Barth     if (!confFile.empty())
121acd737cdSMatthew Barth     {
122acd737cdSMatthew Barth         for (const auto& entry : fan::JsonConfig::load(confFile))
123acd737cdSMatthew Barth         {
124acd737cdSMatthew Barth             auto obj = std::make_unique<Profile>(entry);
125acd737cdSMatthew Barth             _profiles.emplace(
126acd737cdSMatthew Barth                 std::make_pair(obj->getName(), obj->getProfiles()),
127acd737cdSMatthew Barth                 std::move(obj));
128acd737cdSMatthew Barth         }
129acd737cdSMatthew Barth     }
130acd737cdSMatthew Barth     // Ensure all configurations use the same set of active profiles
131acd737cdSMatthew Barth     // (In case a profile's active state changes during configuration)
132acd737cdSMatthew Barth     for (const auto& profile : _profiles)
133acd737cdSMatthew Barth     {
134acd737cdSMatthew Barth         if (profile.second->isActive())
135acd737cdSMatthew Barth         {
136acd737cdSMatthew Barth             _activeProfiles.emplace_back(profile.first.first);
137acd737cdSMatthew Barth         }
138acd737cdSMatthew Barth     }
139acd737cdSMatthew Barth }
140acd737cdSMatthew Barth 
141a227a16dSMatthew Barth } // namespace phosphor::fan::control::json
142