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