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