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
evdevOpen(int fd)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
setAirCooled()49 void CoolingType::setAirCooled()
50 {
51 airCooled = true;
52 }
53
setWaterCooled()54 void CoolingType::setWaterCooled()
55 {
56 waterCooled = true;
57 }
58
readGpio(const std::string & gpioPath,unsigned int keycode)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 =
69 libevdev_fetch_event_value(gpioDev.get(), EV_KEY, keycode, &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
getObjectMap(const std::string & objpath)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
updateInventory(const std::string & objpath)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