1 #include "cooling_type.hpp" 2 3 #include "sdbusplus.hpp" 4 #include "utility.hpp" 5 6 #include <fcntl.h> 7 #include <libevdev/libevdev.h> 8 #include <unistd.h> 9 10 #include <phosphor-logging/elog-errors.hpp> 11 #include <phosphor-logging/elog.hpp> 12 #include <phosphor-logging/log.hpp> 13 #include <sdbusplus/bus.hpp> 14 #include <xyz/openbmc_project/Common/error.hpp> 15 16 #include <format> 17 18 namespace phosphor 19 { 20 namespace cooling 21 { 22 namespace type 23 { 24 25 // For throwing exception 26 using namespace phosphor::logging; 27 using InternalFailure = 28 sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure; 29 30 std::unique_ptr<libevdev, FreeEvDev> evdevOpen(int fd) 31 { 32 libevdev* gpioDev = nullptr; 33 34 auto rc = libevdev_new_from_fd(fd, &gpioDev); 35 if (!rc) 36 { 37 return decltype(evdevOpen(0))(gpioDev); 38 } 39 40 log<level::ERR>( 41 std::format( 42 "Failed to get libevdev from file descriptor {}, return code {}", 43 fd, rc) 44 .c_str()); 45 elog<InternalFailure>(); 46 return decltype(evdevOpen(0))(nullptr); 47 } 48 49 void CoolingType::setAirCooled() 50 { 51 airCooled = true; 52 } 53 54 void CoolingType::setWaterCooled() 55 { 56 waterCooled = true; 57 } 58 59 void CoolingType::readGpio(const std::string& gpioPath, unsigned int keycode) 60 { 61 using namespace phosphor::logging; 62 63 gpioFd.open(gpioPath.c_str(), O_RDONLY); 64 65 auto gpioDev = evdevOpen(gpioFd()); 66 67 int value = 0; 68 auto fetch_rc = libevdev_fetch_event_value(gpioDev.get(), EV_KEY, keycode, 69 &value); 70 if (0 == fetch_rc) 71 { 72 log<level::ERR>( 73 std::format("Device does not support event type keycode {}", 74 keycode) 75 .c_str()); 76 elog<InternalFailure>(); 77 } 78 79 // TODO openbmc/phosphor-fan-presence#6 80 if (value > 0) 81 { 82 setAirCooled(); 83 } 84 else 85 { 86 setWaterCooled(); 87 } 88 } 89 90 CoolingType::ObjectMap CoolingType::getObjectMap(const std::string& objpath) 91 { 92 ObjectMap invObj; 93 InterfaceMap invIntf; 94 PropertyMap invProp; 95 96 invProp.emplace("AirCooled", airCooled); 97 invProp.emplace("WaterCooled", waterCooled); 98 invIntf.emplace("xyz.openbmc_project.Inventory.Decorator.CoolingType", 99 std::move(invProp)); 100 invObj.emplace(objpath, std::move(invIntf)); 101 102 return invObj; 103 } 104 105 void CoolingType::updateInventory(const std::string& objpath) 106 { 107 using namespace phosphor::fan; 108 109 ObjectMap invObj = getObjectMap(objpath); 110 111 // Update inventory 112 static_cast<void>(util::SDBusPlus::lookupAndCallMethod( 113 bus, util::INVENTORY_PATH, util::INVENTORY_INTF, "Notify", 114 std::move(invObj))); 115 } 116 117 } // namespace type 118 } // namespace cooling 119 } // namespace phosphor 120 // vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4 121