1 /**
2  * Copyright © 2017 IBM Corporation
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 #include <algorithm>
17 #include <phosphor-logging/log.hpp>
18 #include <unistd.h>
19 #include "manager.hpp"
20 
21 namespace phosphor
22 {
23 namespace fan
24 {
25 namespace control
26 {
27 
28 using namespace phosphor::logging;
29 
30 constexpr auto SYSTEMD_SERVICE   = "org.freedesktop.systemd1";
31 constexpr auto SYSTEMD_OBJ_PATH  = "/org/freedesktop/systemd1";
32 constexpr auto SYSTEMD_INTERFACE = "org.freedesktop.systemd1.Manager";
33 constexpr auto FAN_CONTROL_READY_TARGET = "obmc-fan-control-ready@0.target";
34 
35 //Note: Future code will check 'mode' before starting control algorithm
36 Manager::Manager(sdbusplus::bus::bus& bus,
37                  Mode mode) :
38     _bus(bus)
39 {
40     //Create the appropriate Zone objects based on the
41     //actual system configuration.
42 
43     //Find the 1 ZoneGroup that meets all of its conditions
44     for (auto& group : _zoneLayouts)
45     {
46         auto& conditions = std::get<conditionListPos>(group);
47 
48         if (std::all_of(conditions.begin(), conditions.end(),
49                         [](const auto& c)
50                         {
51                             //TODO: openbmc/openbmc#1500
52                             //Still need to actually evaluate the conditions
53                             return true;
54                         }))
55         {
56             //Create a Zone object for each zone in this group
57             auto& zones = std::get<zoneListPos>(group);
58 
59             for (auto& z : zones)
60             {
61                 _zones.emplace(std::get<zoneNumPos>(z),
62                                std::make_unique<Zone>(_bus, z));
63             }
64 
65             break;
66         }
67     }
68 
69 }
70 
71 
72 void Manager::doInit()
73 {
74     for (auto& z: _zones)
75     {
76         z.second->setFullSpeed();
77     }
78 
79     auto delay = _powerOnDelay;
80     while (delay > 0)
81     {
82         delay = sleep(delay);
83     }
84 
85     startFanControlReadyTarget();
86 }
87 
88 
89 void Manager::startFanControlReadyTarget()
90 {
91     auto method = _bus.new_method_call(SYSTEMD_SERVICE,
92             SYSTEMD_OBJ_PATH,
93             SYSTEMD_INTERFACE,
94             "StartUnit");
95 
96     method.append(FAN_CONTROL_READY_TARGET);
97     method.append("replace");
98 
99     auto response = _bus.call(method);
100     if (response.is_method_error())
101     {
102         //TODO openbmc/openbmc#1555 create an elog
103         log<level::ERR>("Failed to start fan control ready target");
104         throw std::runtime_error("Failed to start fan control ready target");
105     }
106 }
107 
108 }
109 }
110 }
111