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