xref: /openbmc/phosphor-fan-presence/cooling-type/cooling_type.cpp (revision 9d533806250cea56406bdd39e025f0d820c4ed90)
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