From 5f101103e2295f3648c29171ae42245ec23de892 Mon Sep 17 00:00:00 2001 From: Gunnar Mills Date: Thu, 29 Jun 2017 13:07:39 -0500 Subject: 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 --- presence/Makefile.am | 8 +++-- presence/gpio_presence.cpp | 61 +++++++++++++++++++++++++++++++++ presence/gpio_presence.hpp | 84 ++++++++++++++++++++++++++++++++++++++++++++++ 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 +#include +#include +#include +#include +#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("Failed to open device path", + entry("DEVICEPATH=%s", path.c_str()), + entry("ERRNO=%d", errno)); + elog(); + } + 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("Failed to initialize evdev"); + elog(); + return; + } + + // Packing in the unique_ptr + devicePtr.reset(evdev); +} + +void Presence::determinePresence() +{ + auto value = static_cast(0); + auto fetch_rc = libevdev_fetch_event_value(devicePtr.get(), EV_KEY, + key, &value); + if (0 == fetch_rc) + { + log("Device does not support event type", + entry("KEYCODE=%d", key)); + elog(); + 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 +#include +#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; + +/** @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; } -- cgit v1.2.1