Add phosphor-multi-gpio-presence
The new service works like phosphor-gpio-presence, but uses libgpiod
and can monitor an arbitrary amount of GPIOs.
The driver loading feature hasn't been ported to the new service.
Change-Id: I412345f804208e48eec40ec020b3a0d8f668a34b
Signed-off-by: Patrick Rudolph <patrick.rudolph@9elements.com>
diff --git a/multi-presence/gpio_presence.hpp b/multi-presence/gpio_presence.hpp
new file mode 100644
index 0000000..abc4b63
--- /dev/null
+++ b/multi-presence/gpio_presence.hpp
@@ -0,0 +1,133 @@
+#pragma once
+
+#include <gpiod.h>
+
+#include <boost/asio/io_context.hpp>
+#include <boost/asio/posix/stream_descriptor.hpp>
+#include <sdbusplus/bus.hpp>
+#include <sdbusplus/message.hpp>
+
+#include <cstdlib>
+#include <filesystem>
+#include <map>
+#include <string>
+#include <vector>
+
+static constexpr auto deviceField = 0;
+static constexpr auto pathField = 1;
+using Device = std::string;
+using Path = std::filesystem::path;
+using Driver = std::tuple<Device, Path>;
+using Interface = std::string;
+
+namespace phosphor
+{
+namespace gpio
+{
+
+/** @class GpioPresence
+ * @brief Responsible for catching GPIO state change
+ * condition and updating the inventory presence.
+ */
+class GpioPresence
+{
+ using Property = std::string;
+ using Value = std::variant<bool, std::string>;
+ // Association between property and its value
+ using PropertyMap = std::map<Property, Value>;
+ using Interface = std::string;
+ // Association between interface and the D-Bus property
+ using InterfaceMap = std::map<Interface, PropertyMap>;
+ using Object = sdbusplus::message::object_path;
+ // Association between object and the interface
+ using ObjectMap = std::map<Object, InterfaceMap>;
+
+ public:
+ GpioPresence() = delete;
+ ~GpioPresence() = default;
+ GpioPresence(const GpioPresence&) = delete;
+ GpioPresence& operator=(const GpioPresence&) = delete;
+
+ /** @brief Constructs GpioPresence object.
+ *
+ * @param[in] line - GPIO line from libgpiod
+ * @param[in] config - configuration of line with event
+ * @param[in] io - io service
+ * @param[in] inventory - Object path under inventory that
+ will be created
+ * @param[in] extraInterfaces - List of interfaces to associate to
+ inventory item
+ * @param[in] name - PrettyName of inventory object
+ * @param[in] lineMsg - GPIO line message to be used for log
+ */
+ GpioPresence(gpiod_line* line, gpiod_line_request_config& config,
+ boost::asio::io_context& io, const std::string& inventory,
+ const std::vector<std::string>& extraInterfaces,
+ const std::string& name, const std::string& lineMsg) :
+ gpioLine(line),
+ gpioConfig(config), gpioEventDescriptor(io), inventory(inventory),
+ interfaces(extraInterfaces), name(name), gpioLineMsg(lineMsg)
+ {
+ requestGPIOEvents();
+ };
+
+ GpioPresence(GpioPresence&& old) noexcept :
+ gpioLine(old.gpioLine), gpioConfig(old.gpioConfig),
+ gpioEventDescriptor(old.gpioEventDescriptor.get_executor()),
+ inventory(std::move(old.inventory)),
+ interfaces(std::move(old.interfaces)), name(std::move(old.name)),
+ gpioLineMsg(std::move(old.gpioLineMsg))
+ {
+ old.cancelEventHandler();
+
+ gpioEventDescriptor = std::move(old.gpioEventDescriptor);
+
+ scheduleEventHandler();
+ };
+
+ private:
+ /** @brief GPIO line */
+ gpiod_line* gpioLine;
+
+ /** @brief GPIO line configuration */
+ gpiod_line_request_config gpioConfig;
+
+ /** @brief GPIO event descriptor */
+ boost::asio::posix::stream_descriptor gpioEventDescriptor;
+
+ /** @brief Object path under inventory that will be created */
+ const std::string inventory;
+
+ /** @brief List of interfaces to associate to inventory item */
+ const std::vector<std::string> interfaces;
+
+ /** @brief PrettyName of inventory object */
+ const std::string name;
+
+ /** @brief GPIO line name message */
+ const std::string gpioLineMsg;
+
+ /** @brief register handler for gpio event
+ *
+ * @return - 0 on success and -1 otherwise
+ */
+ int requestGPIOEvents();
+
+ /** @brief Schedule an event handler for GPIO event to trigger */
+ void scheduleEventHandler();
+
+ /** @brief Stop the event handler for GPIO events */
+ void cancelEventHandler();
+
+ /** @brief Handle the GPIO event and starts configured target */
+ void gpioEventHandler();
+
+ /** @brief Returns the object map for the inventory object */
+ ObjectMap getObjectMap(bool present);
+
+ /** @brief Updates the inventory */
+ void updateInventory(bool present);
+};
+
+} // namespace gpio
+} // namespace phosphor