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 <phosphor-logging/log.hpp>
17 #include <string>
18 #include "fan.hpp"
19 #include "utility.hpp"
20 
21 namespace phosphor
22 {
23 namespace fan
24 {
25 namespace control
26 {
27 
28 constexpr auto PROPERTY_INTERFACE = "org.freedesktop.DBus.Properties";
29 constexpr auto FAN_SENSOR_PATH = "/xyz/openbmc_project/sensors/fan_tach/";
30 constexpr auto FAN_SENSOR_CONTROL_INTF = "xyz.openbmc_project.Control.FanSpeed";
31 constexpr auto FAN_TARGET_PROPERTY = "Target";
32 
33 
34 Fan::Fan(sdbusplus::bus::bus& bus, const FanDefinition& def):
35     _bus(bus),
36     _name(std::get<fanNamePos>(def))
37 {
38     auto sensors = std::get<sensorListPos>(def);
39     for (auto& s : sensors)
40     {
41         _sensors.emplace_back(FAN_SENSOR_PATH + s);
42     }
43 }
44 
45 
46 //TODO openbmc/openbmc#1524  Can cache this value when
47 //openbmc/openbmc#1496 is resolved.
48 std::string Fan::getService(const std::string& sensor)
49 {
50     return phosphor::fan::util::getService(sensor,
51                                            FAN_SENSOR_CONTROL_INTF,
52                                            _bus);
53 }
54 
55 
56 void Fan::setSpeed(uint64_t speed)
57 {
58     sdbusplus::message::variant<uint64_t> value = speed;
59     std::string property{FAN_TARGET_PROPERTY};
60 
61     for (auto& sensor : _sensors)
62     {
63         try
64         {
65             auto service = getService(sensor);
66 
67             auto method = _bus.new_method_call(service.c_str(),
68                                                sensor.c_str(),
69                                                PROPERTY_INTERFACE,
70                                                "Set");
71             method.append(FAN_SENSOR_CONTROL_INTF, property, value);
72 
73             auto response = _bus.call(method);
74             if (response.is_method_error())
75             {
76                 throw std::runtime_error(
77                     "Failed call to set fan speed on " + sensor);
78             }
79         }
80         catch (std::exception& e)
81         {
82             //Other applications will handle reporting errors for this
83             phosphor::logging::log<phosphor::logging::level::INFO>(e.what());
84         }
85     }
86 }
87 
88 }
89 }
90 }
91