blob: 67e22d91f753a7d658a57fa99e3557a2cc0f85db [file] [log] [blame]
Matt Spinler7f88fe62017-04-10 14:39:02 -05001/**
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 */
Dinesh Chinari618027a2017-06-26 23:26:50 -050016#include <phosphor-logging/log.hpp>
Matthew Barthdf3e8d62017-05-31 11:07:24 -050017#include <phosphor-logging/elog.hpp>
Dinesh Chinari618027a2017-06-26 23:26:50 -050018#include <phosphor-logging/elog-errors.hpp>
19#include <xyz/openbmc_project/Common/error.hpp>
Matt Spinler7f88fe62017-04-10 14:39:02 -050020#include "zone.hpp"
Matthew Barthdf3e8d62017-05-31 11:07:24 -050021#include "utility.hpp"
Matt Spinler7f88fe62017-04-10 14:39:02 -050022
23namespace phosphor
24{
25namespace fan
26{
27namespace control
28{
29
Matthew Barthdf3e8d62017-05-31 11:07:24 -050030using namespace phosphor::logging;
Dinesh Chinari618027a2017-06-26 23:26:50 -050031using InternalFailure = sdbusplus::xyz::openbmc_project::Common::
32 Error::InternalFailure;
Matt Spinler7f88fe62017-04-10 14:39:02 -050033
Matthew Barth14184132017-05-19 14:37:30 -050034Zone::Zone(Mode mode,
35 sdbusplus::bus::bus& bus,
Matt Spinler7f88fe62017-04-10 14:39:02 -050036 const ZoneDefinition& def) :
37 _bus(bus),
38 _fullSpeed(std::get<fullSpeedPos>(def)),
Matthew Barth1de66622017-06-12 13:13:02 -050039 _zoneNum(std::get<zoneNumPos>(def)),
40 _defFloorSpeed(std::get<floorSpeedPos>(def))
Matt Spinler7f88fe62017-04-10 14:39:02 -050041{
42 auto& fanDefs = std::get<fanListPos>(def);
43
44 for (auto& def : fanDefs)
45 {
46 _fans.emplace_back(std::make_unique<Fan>(bus, def));
47 }
Matthew Barth38a93a82017-05-11 14:12:27 -050048
Matthew Barth14184132017-05-19 14:37:30 -050049 // Do not enable set speed events when in init mode
50 if (mode != Mode::init)
Matthew Barth17d1fe22017-05-11 15:00:36 -050051 {
Matthew Barth14184132017-05-19 14:37:30 -050052 // Setup signal trigger for set speed events
53 for (auto& event : std::get<setSpeedEventsPos>(def))
Matthew Barth17d1fe22017-05-11 15:00:36 -050054 {
Matthew Barthdf3e8d62017-05-31 11:07:24 -050055 // Get the current value for each property
56 for (auto& entry : std::get<groupPos>(event))
57 {
58 try
59 {
Matthew Barth9e741ed2017-06-02 16:29:09 -050060 PropertyVariantType property;
Matthew Barthdf3e8d62017-05-31 11:07:24 -050061 getProperty(_bus,
62 entry.first,
63 std::get<intfPos>(entry.second),
64 std::get<propPos>(entry.second),
Matthew Barth9e741ed2017-06-02 16:29:09 -050065 property);
Matthew Barthdf3e8d62017-05-31 11:07:24 -050066 setPropertyValue(entry.first.c_str(),
Matthew Barthcec5ab72017-06-02 15:20:56 -050067 std::get<intfPos>(entry.second).c_str(),
Matthew Barthdf3e8d62017-05-31 11:07:24 -050068 std::get<propPos>(entry.second).c_str(),
Matthew Barth9e741ed2017-06-02 16:29:09 -050069 property);
Matthew Barthdf3e8d62017-05-31 11:07:24 -050070 }
71 catch (const std::exception& e)
72 {
73 log<level::ERR>(e.what());
74 }
75 }
76 // Setup signal matches for property change events
Matthew Barth14184132017-05-19 14:37:30 -050077 for (auto& prop : std::get<propChangeListPos>(event))
78 {
79 _signalEvents.emplace_back(
Matthew Barth34f1bda2017-05-31 13:45:36 -050080 std::make_unique<EventData>(
Matthew Barth14184132017-05-19 14:37:30 -050081 EventData
82 {
83 std::get<groupPos>(event),
84 std::get<handlerObjPos>(prop),
85 std::get<actionPos>(event)
86 }));
87 _matches.emplace_back(
88 bus,
89 std::get<signaturePos>(prop).c_str(),
Matthew Barth34f1bda2017-05-31 13:45:36 -050090 std::bind(std::mem_fn(&Zone::handleEvent),
91 this,
92 std::placeholders::_1,
93 _signalEvents.back().get()));
Matthew Barth14184132017-05-19 14:37:30 -050094 }
Matthew Barthdf3e8d62017-05-31 11:07:24 -050095 // Run action function for initial event state
96 std::get<actionPos>(event)(*this,
97 std::get<groupPos>(event));
Matthew Barth17d1fe22017-05-11 15:00:36 -050098 }
Matthew Barth38a93a82017-05-11 14:12:27 -050099 }
Matt Spinler7f88fe62017-04-10 14:39:02 -0500100}
101
102
103void Zone::setSpeed(uint64_t speed)
104{
105 for (auto& fan : _fans)
106 {
Matthew Barth4af419c2017-06-12 13:39:31 -0500107 //TODO openbmc/openbmc#1626 Move to control algorithm function
108 if (speed < _floorSpeed)
109 {
110 speed = _floorSpeed;
111 }
Matt Spinler7f88fe62017-04-10 14:39:02 -0500112 fan->setSpeed(speed);
113 }
114}
115
Matthew Barth861d77c2017-05-22 14:18:25 -0500116void Zone::setActiveAllow(const Group* group, bool isActiveAllow)
117{
118 _active[group] = isActiveAllow;
119 if (!isActiveAllow)
120 {
121 _isActive = false;
122 }
123 else
124 {
125 // Check all entries are set to allow control active
126 auto actPred = [](auto const& entry) {return entry.second;};
127 _isActive = std::all_of(_active.begin(),
128 _active.end(),
129 actPred);
130 }
131}
132
Matthew Barthdf3e8d62017-05-31 11:07:24 -0500133void Zone::getProperty(sdbusplus::bus::bus& bus,
134 const std::string& path,
135 const std::string& iface,
136 const std::string& prop,
Matthew Barth9e741ed2017-06-02 16:29:09 -0500137 PropertyVariantType& value)
Matthew Barthdf3e8d62017-05-31 11:07:24 -0500138{
Matthew Barthdf3e8d62017-05-31 11:07:24 -0500139 auto serv = phosphor::fan::util::getService(path, iface, bus);
140 auto hostCall = bus.new_method_call(serv.c_str(),
141 path.c_str(),
142 "org.freedesktop.DBus.Properties",
143 "Get");
144 hostCall.append(iface);
145 hostCall.append(prop);
146 auto hostResponseMsg = bus.call(hostCall);
147 if (hostResponseMsg.is_method_error())
148 {
Dinesh Chinari618027a2017-06-26 23:26:50 -0500149 log<level::ERR>("Error in host call response for retrieving property");
150 elog<InternalFailure>();
Matthew Barthdf3e8d62017-05-31 11:07:24 -0500151 }
Matthew Barth9e741ed2017-06-02 16:29:09 -0500152 hostResponseMsg.read(value);
Matthew Barthdf3e8d62017-05-31 11:07:24 -0500153}
154
Matthew Barth38a93a82017-05-11 14:12:27 -0500155void Zone::handleEvent(sdbusplus::message::message& msg,
Matthew Barth34f1bda2017-05-31 13:45:36 -0500156 const EventData* eventData)
Matthew Barth38a93a82017-05-11 14:12:27 -0500157{
158 // Handle the callback
Matthew Barth34f1bda2017-05-31 13:45:36 -0500159 std::get<eventHandlerPos>(*eventData)(_bus, msg, *this);
Matthew Barth17d1fe22017-05-11 15:00:36 -0500160 // Perform the action
Matthew Barth34f1bda2017-05-31 13:45:36 -0500161 std::get<eventActionPos>(*eventData)(*this,
162 std::get<eventGroupPos>(*eventData));
Matthew Barth38a93a82017-05-11 14:12:27 -0500163}
164
Matt Spinler7f88fe62017-04-10 14:39:02 -0500165}
166}
167}