summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGunnar Mills <gmills@us.ibm.com>2017-06-29 13:07:39 -0500
committerGunnar Mills <gmills@us.ibm.com>2017-07-26 12:55:37 -0500
commit5f101103e2295f3648c29171ae42245ec23de892 (patch)
treecec19d7c48fa7b71603842418a5f1ac44ab1fc6a
parent7263915ab5528868f8ff70f89fd14c434b48e7ae (diff)
downloadphosphor-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.am8
-rw-r--r--presence/gpio_presence.cpp61
-rw-r--r--presence/gpio_presence.hpp84
-rw-r--r--presence/main.cpp2
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;
}
OpenPOWER on IntegriCloud