#pragma once #include "file.hpp" #include #include #include #include #include #include namespace phosphor { namespace gpio { /* Need a custom deleter for freeing up sd_event */ struct EventDeleter { void operator()(sd_event* event) const { event = sd_event_unref(event); } }; using EventPtr = std::unique_ptr; /* Need a custom deleter for freeing up sd_event_source */ struct EventSourceDeleter { void operator()(sd_event_source* eventSource) const { eventSource = sd_event_source_unref(eventSource); } }; using EventSourcePtr = std::unique_ptr; /* 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 Evdev * @brief Responsible for catching GPIO state changes conditions and taking * actions */ class Evdev { using Property = std::string; using Value = sdbusplus::message::variant; // Association between property and its value using PropertyMap = std::map; using Interface = std::string; // Association between interface and the D-Bus property using InterfaceMap = std::map; using Object = sdbusplus::message::object_path; // Association between object and the interface using ObjectMap = std::map; public: Evdev() = delete; ~Evdev() = default; Evdev(const Evdev&) = delete; Evdev& operator=(const Evdev&) = delete; Evdev(Evdev&&) = delete; Evdev& operator=(Evdev&&) = delete; /** @brief Constructs Evdev object. * * @param[in] path - Device path to read for GPIO pin state * @param[in] key - GPIO key to monitor * @param[in] event - sd_event handler * @param[in] handler - IO callback handler. * @param[in] useEvDev - Whether to use EvDev to retrieve events */ Evdev(const std::string& path, const unsigned int key, EventPtr& event, sd_event_io_handler_t handler, bool useEvDev = true) : path(path), key(key), event(event), callbackHandler(handler), fd(openDevice()) { if (useEvDev) { // If we are asked to use EvDev, do that initialization. initEvDev(); } // Register callback handler when FD has some data registerCallback(); } protected: /** @brief Device path to read for GPIO pin state */ const std::string path; /** @brief GPIO key to monitor */ const unsigned int key; /** @brief Event structure */ EvdevPtr devicePtr; /** @brief Monitor to sd_event */ EventPtr& event; /** @brief Callback handler when the FD has some data */ sd_event_io_handler_t callbackHandler; /** @brief event source */ EventSourcePtr eventSource; /** @brief Opens the device and populates the descriptor */ int openDevice(); /** @brief attaches FD to events and sets up callback handler */ void registerCallback(); /** @brief File descriptor manager */ FileDescriptor fd; /** @brief Initializes evdev handle with the fd */ void initEvDev(); }; } // namespace gpio } // namespace phosphor