diff options
author | Gunnar Mills <gmills@us.ibm.com> | 2017-06-29 13:07:39 -0500 |
---|---|---|
committer | Gunnar Mills <gmills@us.ibm.com> | 2017-07-26 12:55:37 -0500 |
commit | 5f101103e2295f3648c29171ae42245ec23de892 (patch) | |
tree | cec19d7c48fa7b71603842418a5f1ac44ab1fc6a | |
parent | 7263915ab5528868f8ff70f89fd14c434b48e7ae (diff) | |
download | phosphor-gpio-monitor-5f101103e2295f3648c29171ae42245ec23de892.tar.gz phosphor-gpio-monitor-5f101103e2295f3648c29171ae42245ec23de892.zip |
Read GPIO key on startup
Create class Presence which will be responsible for
determining and monitoring presence of inventory items
and updating D-Bus accordingly. With this commit
class Presence only reads the GPIO key on startup,
more to come later.
Change-Id: I647ae11d42a813a103e6d9d8922fd0f5b2155132
Signed-off-by: Gunnar Mills <gmills@us.ibm.com>
-rw-r--r-- | presence/Makefile.am | 8 | ||||
-rw-r--r-- | presence/gpio_presence.cpp | 61 | ||||
-rw-r--r-- | presence/gpio_presence.hpp | 84 | ||||
-rw-r--r-- | presence/main.cpp | 2 |
4 files changed, 153 insertions, 2 deletions
diff --git a/presence/Makefile.am b/presence/Makefile.am index f66c0e7..8af030c 100644 --- a/presence/Makefile.am +++ b/presence/Makefile.am @@ -10,8 +10,12 @@ phosphor_gpio_presence_SOURCES = \ gpio_presence.cpp phosphor_gpio_presence_CXXFLAGS = \ - $(PHOSPHOR_LOGGING_CFLAGS) + $(PHOSPHOR_LOGGING_CFLAGS) \ + $(PHOSPHOR_DBUS_INTERFACES_CFLAGS) \ + $(LIBEVDEV_CFLAGS) phosphor_gpio_presence_LDADD = \ - $(PHOSPHOR_LOGGING_LIBS) + $(PHOSPHOR_LOGGING_LIBS) \ + $(PHOSPHOR_DBUS_INTERFACES_LIBS) \ + $(LIBEVDEV_LIBS) diff --git a/presence/gpio_presence.cpp b/presence/gpio_presence.cpp index 11a32cd..710e4ae 100644 --- a/presence/gpio_presence.cpp +++ b/presence/gpio_presence.cpp @@ -1,3 +1,9 @@ +#include <libevdev/libevdev.h> +#include <fcntl.h> +#include <phosphor-logging/elog.hpp> +#include <phosphor-logging/log.hpp> +#include <phosphor-logging/elog-errors.hpp> +#include "xyz/openbmc_project/Common/error.hpp" #include "gpio_presence.hpp" namespace phosphor @@ -7,6 +13,61 @@ namespace gpio namespace presence { +using namespace phosphor::logging; +using namespace sdbusplus::xyz::openbmc_project::Common::Error; + +// Populate the file descriptor for passed in device +int Presence::openDevice() +{ + using namespace phosphor::logging; + + auto fd = open(path.c_str(), O_RDONLY | O_NONBLOCK); + if (fd < 0) + { + log<level::ERR>("Failed to open device path", + entry("DEVICEPATH=%s", path.c_str()), + entry("ERRNO=%d", errno)); + elog<InternalFailure>(); + } + return fd; +} + +// Initializes the event device with the fd +void Presence::initEvDev() +{ + if (devicePtr) + { + // Init can be done only once per device + return; + } + + struct libevdev* evdev = nullptr; + auto rc = libevdev_new_from_fd((fd)(), &evdev); + if (rc < 0) + { + log<level::ERR>("Failed to initialize evdev"); + elog<InternalFailure>(); + return; + } + + // Packing in the unique_ptr + devicePtr.reset(evdev); +} + +void Presence::determinePresence() +{ + auto value = static_cast<int>(0); + auto fetch_rc = libevdev_fetch_event_value(devicePtr.get(), EV_KEY, + key, &value); + if (0 == fetch_rc) + { + log<level::ERR>("Device does not support event type", + entry("KEYCODE=%d", key)); + elog<InternalFailure>(); + return; + } +} + } // namespace presence } // namespace gpio } // namespace phosphor diff --git a/presence/gpio_presence.hpp b/presence/gpio_presence.hpp index 67fd4cb..3faa7e1 100644 --- a/presence/gpio_presence.hpp +++ b/presence/gpio_presence.hpp @@ -1,4 +1,7 @@ #pragma once +#include <string> +#include <libevdev/libevdev.h> +#include "file.hpp" namespace phosphor { @@ -7,6 +10,87 @@ namespace gpio namespace presence { +/* Need a custom deleter for freeing up evdev struct */ +struct FreeEvDev +{ + void operator()(struct libevdev* device) const + { + libevdev_free(device); + } +}; +using EvdevPtr = std::unique_ptr<struct libevdev, FreeEvDev>; + +/** @class Presence + * @brief Responsible for determining and monitoring presence of + * inventory items and updating D-Bus accordingly. + */ +class Presence +{ + + public: + Presence() = delete; + ~Presence() = default; + Presence(const Presence&) = delete; + Presence& operator=(const Presence&) = delete; + Presence(Presence&&) = delete; + Presence& operator=(Presence&&) = delete; + + /** @brief Constructs Presence object. + * + * @param[in] inventory - Object path under inventory + to display this inventory item + * @param[in] path - Device path to read for GPIO pin state + to determine presence of inventory item + * @param[in] key - GPIO key to monitor + * @param[in] name - Pretty name of the inventory item + */ + Presence(const std::string& inventory, + const std::string& path, + const unsigned int key, + const std::string& name) : + inventory(inventory), + path(path), + key(key), + name(name), + fd(openDevice()) + { + initEvDev(); + determinePresence(); + } + + private: + /** + * @brief Read the GPIO device to determine initial presence and set + * present property at D-Bus path. + **/ + void determinePresence(); + + /** @brief Object path under inventory to display this inventory item */ + const std::string inventory; + + /** @brief Device path to read for GPIO pin state + to determine presence of inventory item */ + const std::string path; + + /** @brief GPIO key to monitor */ + const unsigned int key; + + /** @brief Pretty name of the inventory item*/ + const std::string name; + + /** @brief Event structure */ + EvdevPtr devicePtr; + + /** @brief Opens the device and populates the descriptor */ + int openDevice(); + + /** @brief File descriptor manager */ + FileDescriptor fd; + + /** @brief Initializes evdev handle with the fd */ + void initEvDev(); +}; + } // namespace presence } // namespace gpio } // namespace phosphor diff --git a/presence/main.cpp b/presence/main.cpp index 3c7c3cf..8935568 100644 --- a/presence/main.cpp +++ b/presence/main.cpp @@ -5,6 +5,7 @@ using namespace phosphor::logging; using namespace phosphor::gpio; +using namespace phosphor::gpio::presence; int main(int argc, char* argv[]) { @@ -36,6 +37,7 @@ int main(int argc, char* argv[]) std::cerr << "Device path argument required\n"; options.usage(argv); } + Presence presence(inventory, path, std::stoul(key), options["name"]); return 0; } |