blob: 1a299e2dc6d28625f3728ac15ed5136a74d24501 [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 */
Matthew Barthdf3e8d62017-05-31 11:07:24 -050016#include <phosphor-logging/elog.hpp>
Matt Spinler7f88fe62017-04-10 14:39:02 -050017#include "zone.hpp"
Matthew Barthdf3e8d62017-05-31 11:07:24 -050018#include "utility.hpp"
Matt Spinler7f88fe62017-04-10 14:39:02 -050019
20namespace phosphor
21{
22namespace fan
23{
24namespace control
25{
26
Matthew Barthdf3e8d62017-05-31 11:07:24 -050027using namespace phosphor::logging;
Matt Spinler7f88fe62017-04-10 14:39:02 -050028
Matthew Barth14184132017-05-19 14:37:30 -050029Zone::Zone(Mode mode,
30 sdbusplus::bus::bus& bus,
Matt Spinler7f88fe62017-04-10 14:39:02 -050031 const ZoneDefinition& def) :
32 _bus(bus),
33 _fullSpeed(std::get<fullSpeedPos>(def)),
Matthew Barth1de66622017-06-12 13:13:02 -050034 _zoneNum(std::get<zoneNumPos>(def)),
35 _defFloorSpeed(std::get<floorSpeedPos>(def))
Matt Spinler7f88fe62017-04-10 14:39:02 -050036{
37 auto& fanDefs = std::get<fanListPos>(def);
38
39 for (auto& def : fanDefs)
40 {
41 _fans.emplace_back(std::make_unique<Fan>(bus, def));
42 }
Matthew Barth38a93a82017-05-11 14:12:27 -050043
Matthew Barth14184132017-05-19 14:37:30 -050044 // Do not enable set speed events when in init mode
45 if (mode != Mode::init)
Matthew Barth17d1fe22017-05-11 15:00:36 -050046 {
Matthew Barth14184132017-05-19 14:37:30 -050047 // Setup signal trigger for set speed events
48 for (auto& event : std::get<setSpeedEventsPos>(def))
Matthew Barth17d1fe22017-05-11 15:00:36 -050049 {
Matthew Barthdf3e8d62017-05-31 11:07:24 -050050 // Get the current value for each property
51 for (auto& entry : std::get<groupPos>(event))
52 {
53 try
54 {
Matthew Barth9e741ed2017-06-02 16:29:09 -050055 PropertyVariantType property;
Matthew Barthdf3e8d62017-05-31 11:07:24 -050056 getProperty(_bus,
57 entry.first,
58 std::get<intfPos>(entry.second),
59 std::get<propPos>(entry.second),
Matthew Barth9e741ed2017-06-02 16:29:09 -050060 property);
Matthew Barthdf3e8d62017-05-31 11:07:24 -050061 setPropertyValue(entry.first.c_str(),
Matthew Barthcec5ab72017-06-02 15:20:56 -050062 std::get<intfPos>(entry.second).c_str(),
Matthew Barthdf3e8d62017-05-31 11:07:24 -050063 std::get<propPos>(entry.second).c_str(),
Matthew Barth9e741ed2017-06-02 16:29:09 -050064 property);
Matthew Barthdf3e8d62017-05-31 11:07:24 -050065 }
66 catch (const std::exception& e)
67 {
68 log<level::ERR>(e.what());
69 }
70 }
71 // Setup signal matches for property change events
Matthew Barth14184132017-05-19 14:37:30 -050072 for (auto& prop : std::get<propChangeListPos>(event))
73 {
74 _signalEvents.emplace_back(
Matthew Barth34f1bda2017-05-31 13:45:36 -050075 std::make_unique<EventData>(
Matthew Barth14184132017-05-19 14:37:30 -050076 EventData
77 {
78 std::get<groupPos>(event),
79 std::get<handlerObjPos>(prop),
80 std::get<actionPos>(event)
81 }));
82 _matches.emplace_back(
83 bus,
84 std::get<signaturePos>(prop).c_str(),
Matthew Barth34f1bda2017-05-31 13:45:36 -050085 std::bind(std::mem_fn(&Zone::handleEvent),
86 this,
87 std::placeholders::_1,
88 _signalEvents.back().get()));
Matthew Barth14184132017-05-19 14:37:30 -050089 }
Matthew Barthdf3e8d62017-05-31 11:07:24 -050090 // Run action function for initial event state
91 std::get<actionPos>(event)(*this,
92 std::get<groupPos>(event));
Matthew Barth17d1fe22017-05-11 15:00:36 -050093 }
Matthew Barth38a93a82017-05-11 14:12:27 -050094 }
Matt Spinler7f88fe62017-04-10 14:39:02 -050095}
96
97
98void Zone::setSpeed(uint64_t speed)
99{
100 for (auto& fan : _fans)
101 {
102 fan->setSpeed(speed);
103 }
104}
105
Matthew Barth861d77c2017-05-22 14:18:25 -0500106void Zone::setActiveAllow(const Group* group, bool isActiveAllow)
107{
108 _active[group] = isActiveAllow;
109 if (!isActiveAllow)
110 {
111 _isActive = false;
112 }
113 else
114 {
115 // Check all entries are set to allow control active
116 auto actPred = [](auto const& entry) {return entry.second;};
117 _isActive = std::all_of(_active.begin(),
118 _active.end(),
119 actPred);
120 }
121}
122
Matthew Barthdf3e8d62017-05-31 11:07:24 -0500123void Zone::getProperty(sdbusplus::bus::bus& bus,
124 const std::string& path,
125 const std::string& iface,
126 const std::string& prop,
Matthew Barth9e741ed2017-06-02 16:29:09 -0500127 PropertyVariantType& value)
Matthew Barthdf3e8d62017-05-31 11:07:24 -0500128{
Matthew Barthdf3e8d62017-05-31 11:07:24 -0500129 auto serv = phosphor::fan::util::getService(path, iface, bus);
130 auto hostCall = bus.new_method_call(serv.c_str(),
131 path.c_str(),
132 "org.freedesktop.DBus.Properties",
133 "Get");
134 hostCall.append(iface);
135 hostCall.append(prop);
136 auto hostResponseMsg = bus.call(hostCall);
137 if (hostResponseMsg.is_method_error())
138 {
139 throw std::runtime_error(
140 "Error in host call response for retrieving property");
141 }
Matthew Barth9e741ed2017-06-02 16:29:09 -0500142 hostResponseMsg.read(value);
Matthew Barthdf3e8d62017-05-31 11:07:24 -0500143}
144
Matthew Barth38a93a82017-05-11 14:12:27 -0500145void Zone::handleEvent(sdbusplus::message::message& msg,
Matthew Barth34f1bda2017-05-31 13:45:36 -0500146 const EventData* eventData)
Matthew Barth38a93a82017-05-11 14:12:27 -0500147{
148 // Handle the callback
Matthew Barth34f1bda2017-05-31 13:45:36 -0500149 std::get<eventHandlerPos>(*eventData)(_bus, msg, *this);
Matthew Barth17d1fe22017-05-11 15:00:36 -0500150 // Perform the action
Matthew Barth34f1bda2017-05-31 13:45:36 -0500151 std::get<eventActionPos>(*eventData)(*this,
152 std::get<eventGroupPos>(*eventData));
Matthew Barth38a93a82017-05-11 14:12:27 -0500153}
154
Matt Spinler7f88fe62017-04-10 14:39:02 -0500155}
156}
157}