1 /** 2 * Copyright 2017 Google Inc. 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 17 #include "dbus_mode.hpp" 18 19 #include <ipmid/api.h> 20 21 #include <sdbusplus/bus.hpp> 22 #include <sdbusplus/message.hpp> 23 24 #include <cstdint> 25 #include <string> 26 #include <variant> 27 28 namespace pid_control 29 { 30 namespace ipmi 31 { 32 33 static constexpr auto objectPath = "/xyz/openbmc_project/settings/fanctrl/zone"; 34 static constexpr auto busName = "xyz.openbmc_project.State.FanCtrl"; 35 static constexpr auto intf = "xyz.openbmc_project.Control.Mode"; 36 static constexpr auto propertiesintf = "org.freedesktop.DBus.Properties"; 37 38 using Property = std::string; 39 using Value = std::variant<bool>; 40 using PropertyMap = std::map<Property, Value>; 41 42 /* The following was copied directly from my manual thread handler. */ 43 static std::string getControlPath(int8_t zone) 44 { 45 return std::string(objectPath) + std::to_string(zone); 46 } 47 48 uint8_t DbusZoneControl::getFanCtrlProperty(uint8_t zoneId, bool* value, 49 const std::string& property) 50 { 51 std::string path = getControlPath(zoneId); 52 53 auto propertyReadBus = sdbusplus::bus::new_system(); 54 auto pimMsg = propertyReadBus.new_method_call(busName, path.c_str(), 55 propertiesintf, "GetAll"); 56 pimMsg.append(intf); 57 58 try 59 { 60 PropertyMap propMap; 61 62 /* a method could error but the call not error. */ 63 auto valueResponseMsg = propertyReadBus.call(pimMsg); 64 65 valueResponseMsg.read(propMap); 66 67 *value = std::get<bool>(propMap[property]); 68 } 69 catch (const sdbusplus::exception_t& ex) 70 { 71 return IPMI_CC_INVALID; 72 } 73 74 return IPMI_CC_OK; 75 } 76 77 uint8_t DbusZoneControl::setFanCtrlProperty(uint8_t zoneId, bool value, 78 const std::string& property) 79 { 80 using Value = std::variant<bool>; 81 Value v{value}; 82 83 std::string path = getControlPath(zoneId); 84 85 auto PropertyWriteBus = sdbusplus::bus::new_system(); 86 auto pimMsg = PropertyWriteBus.new_method_call(busName, path.c_str(), 87 propertiesintf, "Set"); 88 pimMsg.append(intf); 89 pimMsg.append(property); 90 pimMsg.append(v); 91 92 try 93 { 94 PropertyWriteBus.call_noreply(pimMsg); 95 } 96 catch (const sdbusplus::exception_t& ex) 97 { 98 return IPMI_CC_INVALID; 99 } 100 101 /* TODO(venture): Should sanity check the result. */ 102 return IPMI_CC_OK; 103 } 104 105 } // namespace ipmi 106 } // namespace pid_control 107