17f88fe61SMatt Spinler /** 27f88fe61SMatt Spinler * Copyright © 2017 IBM Corporation 37f88fe61SMatt Spinler * 47f88fe61SMatt Spinler * Licensed under the Apache License, Version 2.0 (the "License"); 57f88fe61SMatt Spinler * you may not use this file except in compliance with the License. 67f88fe61SMatt Spinler * You may obtain a copy of the License at 77f88fe61SMatt Spinler * 87f88fe61SMatt Spinler * http://www.apache.org/licenses/LICENSE-2.0 97f88fe61SMatt Spinler * 107f88fe61SMatt Spinler * Unless required by applicable law or agreed to in writing, software 117f88fe61SMatt Spinler * distributed under the License is distributed on an "AS IS" BASIS, 127f88fe61SMatt Spinler * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 137f88fe61SMatt Spinler * See the License for the specific language governing permissions and 147f88fe61SMatt Spinler * limitations under the License. 157f88fe61SMatt Spinler */ 16df3e8d67SMatthew Barth #include <phosphor-logging/elog.hpp> 177f88fe61SMatt Spinler #include "zone.hpp" 18df3e8d67SMatthew Barth #include "utility.hpp" 197f88fe61SMatt Spinler 207f88fe61SMatt Spinler namespace phosphor 217f88fe61SMatt Spinler { 227f88fe61SMatt Spinler namespace fan 237f88fe61SMatt Spinler { 247f88fe61SMatt Spinler namespace control 257f88fe61SMatt Spinler { 267f88fe61SMatt Spinler 27df3e8d67SMatthew Barth using namespace phosphor::logging; 287f88fe61SMatt Spinler 2914184131SMatthew Barth Zone::Zone(Mode mode, 3014184131SMatthew Barth sdbusplus::bus::bus& bus, 317f88fe61SMatt Spinler const ZoneDefinition& def) : 327f88fe61SMatt Spinler _bus(bus), 337f88fe61SMatt Spinler _fullSpeed(std::get<fullSpeedPos>(def)), 347f88fe61SMatt Spinler _zoneNum(std::get<zoneNumPos>(def)) 357f88fe61SMatt Spinler { 367f88fe61SMatt Spinler auto& fanDefs = std::get<fanListPos>(def); 377f88fe61SMatt Spinler 387f88fe61SMatt Spinler for (auto& def : fanDefs) 397f88fe61SMatt Spinler { 407f88fe61SMatt Spinler _fans.emplace_back(std::make_unique<Fan>(bus, def)); 417f88fe61SMatt Spinler } 4238a93a8aSMatthew Barth 4314184131SMatthew Barth // Do not enable set speed events when in init mode 4414184131SMatthew Barth if (mode != Mode::init) 4514184131SMatthew Barth { 4617d1fe23SMatthew Barth // Setup signal trigger for set speed events 4738a93a8aSMatthew Barth for (auto& event : std::get<setSpeedEventsPos>(def)) 4838a93a8aSMatthew Barth { 49df3e8d67SMatthew Barth // Get the current value for each property 50df3e8d67SMatthew Barth for (auto& entry : std::get<groupPos>(event)) 51df3e8d67SMatthew Barth { 52df3e8d67SMatthew Barth try 53df3e8d67SMatthew Barth { 54*9e741ed0SMatthew Barth PropertyVariantType property; 55df3e8d67SMatthew Barth getProperty(_bus, 56df3e8d67SMatthew Barth entry.first, 57df3e8d67SMatthew Barth std::get<intfPos>(entry.second), 58df3e8d67SMatthew Barth std::get<propPos>(entry.second), 59*9e741ed0SMatthew Barth property); 60df3e8d67SMatthew Barth setPropertyValue(entry.first.c_str(), 61cec5ab76SMatthew Barth std::get<intfPos>(entry.second).c_str(), 62df3e8d67SMatthew Barth std::get<propPos>(entry.second).c_str(), 63*9e741ed0SMatthew Barth property); 64df3e8d67SMatthew Barth } 65df3e8d67SMatthew Barth catch (const std::exception& e) 66df3e8d67SMatthew Barth { 67df3e8d67SMatthew Barth log<level::ERR>(e.what()); 68df3e8d67SMatthew Barth } 69df3e8d67SMatthew Barth } 70df3e8d67SMatthew Barth // Setup signal matches for property change events 7117d1fe23SMatthew Barth for (auto& prop : std::get<propChangeListPos>(event)) 7238a93a8aSMatthew Barth { 7338a93a8aSMatthew Barth _signalEvents.emplace_back( 7434f1bda2SMatthew Barth std::make_unique<EventData>( 7517d1fe23SMatthew Barth EventData 7617d1fe23SMatthew Barth { 7717d1fe23SMatthew Barth std::get<groupPos>(event), 7817d1fe23SMatthew Barth std::get<handlerObjPos>(prop), 7917d1fe23SMatthew Barth std::get<actionPos>(event) 8017d1fe23SMatthew Barth })); 8114184131SMatthew Barth _matches.emplace_back( 8214184131SMatthew Barth bus, 8338a93a8aSMatthew Barth std::get<signaturePos>(prop).c_str(), 8434f1bda2SMatthew Barth std::bind(std::mem_fn(&Zone::handleEvent), 8534f1bda2SMatthew Barth this, 8634f1bda2SMatthew Barth std::placeholders::_1, 8734f1bda2SMatthew Barth _signalEvents.back().get())); 8838a93a8aSMatthew Barth } 89df3e8d67SMatthew Barth // Run action function for initial event state 90df3e8d67SMatthew Barth std::get<actionPos>(event)(*this, 91df3e8d67SMatthew Barth std::get<groupPos>(event)); 9238a93a8aSMatthew Barth } 937f88fe61SMatt Spinler } 9414184131SMatthew Barth } 957f88fe61SMatt Spinler 967f88fe61SMatt Spinler 977f88fe61SMatt Spinler void Zone::setSpeed(uint64_t speed) 987f88fe61SMatt Spinler { 997f88fe61SMatt Spinler for (auto& fan : _fans) 1007f88fe61SMatt Spinler { 1017f88fe61SMatt Spinler fan->setSpeed(speed); 1027f88fe61SMatt Spinler } 1037f88fe61SMatt Spinler } 1047f88fe61SMatt Spinler 105861d77c3SMatthew Barth void Zone::setActiveAllow(const Group* group, bool isActiveAllow) 106861d77c3SMatthew Barth { 107861d77c3SMatthew Barth _active[group] = isActiveAllow; 108861d77c3SMatthew Barth if (!isActiveAllow) 109861d77c3SMatthew Barth { 110861d77c3SMatthew Barth _isActive = false; 111861d77c3SMatthew Barth } 112861d77c3SMatthew Barth else 113861d77c3SMatthew Barth { 114861d77c3SMatthew Barth // Check all entries are set to allow control active 115861d77c3SMatthew Barth auto actPred = [](auto const& entry) {return entry.second;}; 116861d77c3SMatthew Barth _isActive = std::all_of(_active.begin(), 117861d77c3SMatthew Barth _active.end(), 118861d77c3SMatthew Barth actPred); 119861d77c3SMatthew Barth } 120861d77c3SMatthew Barth } 121861d77c3SMatthew Barth 122df3e8d67SMatthew Barth void Zone::getProperty(sdbusplus::bus::bus& bus, 123df3e8d67SMatthew Barth const std::string& path, 124df3e8d67SMatthew Barth const std::string& iface, 125df3e8d67SMatthew Barth const std::string& prop, 126*9e741ed0SMatthew Barth PropertyVariantType& value) 127df3e8d67SMatthew Barth { 128df3e8d67SMatthew Barth auto serv = phosphor::fan::util::getService(path, iface, bus); 129df3e8d67SMatthew Barth auto hostCall = bus.new_method_call(serv.c_str(), 130df3e8d67SMatthew Barth path.c_str(), 131df3e8d67SMatthew Barth "org.freedesktop.DBus.Properties", 132df3e8d67SMatthew Barth "Get"); 133df3e8d67SMatthew Barth hostCall.append(iface); 134df3e8d67SMatthew Barth hostCall.append(prop); 135df3e8d67SMatthew Barth auto hostResponseMsg = bus.call(hostCall); 136df3e8d67SMatthew Barth if (hostResponseMsg.is_method_error()) 137df3e8d67SMatthew Barth { 138df3e8d67SMatthew Barth throw std::runtime_error( 139df3e8d67SMatthew Barth "Error in host call response for retrieving property"); 140df3e8d67SMatthew Barth } 141*9e741ed0SMatthew Barth hostResponseMsg.read(value); 142df3e8d67SMatthew Barth } 143df3e8d67SMatthew Barth 14438a93a8aSMatthew Barth void Zone::handleEvent(sdbusplus::message::message& msg, 14534f1bda2SMatthew Barth const EventData* eventData) 14638a93a8aSMatthew Barth { 14738a93a8aSMatthew Barth // Handle the callback 14834f1bda2SMatthew Barth std::get<eventHandlerPos>(*eventData)(_bus, msg, *this); 14917d1fe23SMatthew Barth // Perform the action 15034f1bda2SMatthew Barth std::get<eventActionPos>(*eventData)(*this, 15134f1bda2SMatthew Barth std::get<eventGroupPos>(*eventData)); 15238a93a8aSMatthew Barth } 15338a93a8aSMatthew Barth 1547f88fe61SMatt Spinler } 1557f88fe61SMatt Spinler } 1567f88fe61SMatt Spinler } 157