xref: /openbmc/phosphor-pid-control/ipmi/dbus_mode.cpp (revision 46a755fce8dc0bdd9c0c5ea09d55d3e5494f335f)
1 // SPDX-License-Identifier: Apache-2.0
2 // SPDX-FileCopyrightText: Copyright 2017 Google Inc
3 
4 #include "dbus_mode.hpp"
5 
6 #include <ipmid/api-types.hpp>
7 #include <sdbusplus/bus.hpp>
8 #include <sdbusplus/exception.hpp>
9 #include <sdbusplus/message.hpp>
10 
11 #include <cstdint>
12 #include <map>
13 #include <string>
14 #include <variant>
15 
16 namespace pid_control::ipmi
17 {
18 
19 static constexpr auto objectPath = "/xyz/openbmc_project/settings/fanctrl/zone";
20 static constexpr auto busName = "xyz.openbmc_project.State.FanCtrl";
21 static constexpr auto intf = "xyz.openbmc_project.Control.Mode";
22 static constexpr auto propertiesintf = "org.freedesktop.DBus.Properties";
23 
24 using Property = std::string;
25 using Value = std::variant<bool>;
26 using PropertyMap = std::map<Property, Value>;
27 
28 /* The following was copied directly from my manual thread handler. */
29 static std::string getControlPath(int8_t zone)
30 {
31     return std::string(objectPath) + std::to_string(zone);
32 }
33 
34 uint8_t DbusZoneControl::getFanCtrlProperty(uint8_t zoneId, bool* value,
35                                             const std::string& property)
36 {
37     std::string path = getControlPath(zoneId);
38 
39     auto propertyReadBus = sdbusplus::bus::new_system();
40     auto pimMsg = propertyReadBus.new_method_call(busName, path.c_str(),
41                                                   propertiesintf, "GetAll");
42     pimMsg.append(intf);
43 
44     try
45     {
46         PropertyMap propMap;
47 
48         /* a method could error but the call not error. */
49         auto valueResponseMsg = propertyReadBus.call(pimMsg);
50 
51         valueResponseMsg.read(propMap);
52 
53         *value = std::get<bool>(propMap[property]);
54     }
55     catch (const sdbusplus::exception_t& ex)
56     {
57         return ::ipmi::ccInvalidCommand;
58     }
59 
60     return ::ipmi::ccSuccess;
61 }
62 
63 uint8_t DbusZoneControl::setFanCtrlProperty(uint8_t zoneId, bool value,
64                                             const std::string& property)
65 {
66     using Value = std::variant<bool>;
67     Value v{value};
68 
69     std::string path = getControlPath(zoneId);
70 
71     auto PropertyWriteBus = sdbusplus::bus::new_system();
72     auto pimMsg = PropertyWriteBus.new_method_call(busName, path.c_str(),
73                                                    propertiesintf, "Set");
74     pimMsg.append(intf);
75     pimMsg.append(property);
76     pimMsg.append(v);
77 
78     try
79     {
80         PropertyWriteBus.call_noreply(pimMsg);
81     }
82     catch (const sdbusplus::exception_t& ex)
83     {
84         return ::ipmi::ccInvalidCommand;
85     }
86 
87     /* TODO(venture): Should sanity check the result. */
88     return ::ipmi::ccSuccess;
89 }
90 
91 } // namespace pid_control::ipmi
92