17263915aSGunnar Mills #pragma once 25f101103SGunnar Mills #include <string> 3*765725e0SGunnar Mills #include <systemd/sd-event.h> 45f101103SGunnar Mills #include <libevdev/libevdev.h> 55f101103SGunnar Mills #include "file.hpp" 67263915aSGunnar Mills 77263915aSGunnar Mills namespace phosphor 87263915aSGunnar Mills { 97263915aSGunnar Mills namespace gpio 107263915aSGunnar Mills { 117263915aSGunnar Mills namespace presence 127263915aSGunnar Mills { 137263915aSGunnar Mills 14*765725e0SGunnar Mills /* Need a custom deleter for freeing up sd_event */ 15*765725e0SGunnar Mills struct EventDeleter 16*765725e0SGunnar Mills { 17*765725e0SGunnar Mills void operator()(sd_event* event) const 18*765725e0SGunnar Mills { 19*765725e0SGunnar Mills event = sd_event_unref(event); 20*765725e0SGunnar Mills } 21*765725e0SGunnar Mills }; 22*765725e0SGunnar Mills using EventPtr = std::unique_ptr<sd_event, EventDeleter>; 23*765725e0SGunnar Mills 24*765725e0SGunnar Mills /* Need a custom deleter for freeing up sd_event_source */ 25*765725e0SGunnar Mills struct EventSourceDeleter 26*765725e0SGunnar Mills { 27*765725e0SGunnar Mills void operator()(sd_event_source* eventSource) const 28*765725e0SGunnar Mills { 29*765725e0SGunnar Mills eventSource = sd_event_source_unref(eventSource); 30*765725e0SGunnar Mills } 31*765725e0SGunnar Mills }; 32*765725e0SGunnar Mills using EventSourcePtr = std::unique_ptr<sd_event_source, EventSourceDeleter>; 33*765725e0SGunnar Mills 345f101103SGunnar Mills /* Need a custom deleter for freeing up evdev struct */ 355f101103SGunnar Mills struct FreeEvDev 365f101103SGunnar Mills { 375f101103SGunnar Mills void operator()(struct libevdev* device) const 385f101103SGunnar Mills { 395f101103SGunnar Mills libevdev_free(device); 405f101103SGunnar Mills } 415f101103SGunnar Mills }; 425f101103SGunnar Mills using EvdevPtr = std::unique_ptr<struct libevdev, FreeEvDev>; 435f101103SGunnar Mills 445f101103SGunnar Mills /** @class Presence 455f101103SGunnar Mills * @brief Responsible for determining and monitoring presence of 465f101103SGunnar Mills * inventory items and updating D-Bus accordingly. 475f101103SGunnar Mills */ 485f101103SGunnar Mills class Presence 495f101103SGunnar Mills { 505f101103SGunnar Mills 5180292bbeSGunnar Mills using Property = std::string; 5280292bbeSGunnar Mills using Value = sdbusplus::message::variant<bool, std::string>; 5380292bbeSGunnar Mills // Association between property and its value 5480292bbeSGunnar Mills using PropertyMap = std::map<Property, Value>; 5580292bbeSGunnar Mills using Interface = std::string; 5680292bbeSGunnar Mills // Association between interface and the D-Bus property 5780292bbeSGunnar Mills using InterfaceMap = std::map<Interface, PropertyMap>; 5880292bbeSGunnar Mills using Object = sdbusplus::message::object_path; 5980292bbeSGunnar Mills // Association between object and the interface 6080292bbeSGunnar Mills using ObjectMap = std::map<Object, InterfaceMap>; 6180292bbeSGunnar Mills 625f101103SGunnar Mills public: 635f101103SGunnar Mills Presence() = delete; 645f101103SGunnar Mills ~Presence() = default; 655f101103SGunnar Mills Presence(const Presence&) = delete; 665f101103SGunnar Mills Presence& operator=(const Presence&) = delete; 675f101103SGunnar Mills Presence(Presence&&) = delete; 685f101103SGunnar Mills Presence& operator=(Presence&&) = delete; 695f101103SGunnar Mills 705f101103SGunnar Mills /** @brief Constructs Presence object. 715f101103SGunnar Mills * 7280292bbeSGunnar Mills * @param[in] bus - D-Bus bus Object 735f101103SGunnar Mills * @param[in] inventory - Object path under inventory 745f101103SGunnar Mills to display this inventory item 755f101103SGunnar Mills * @param[in] path - Device path to read for GPIO pin state 765f101103SGunnar Mills to determine presence of inventory item 775f101103SGunnar Mills * @param[in] key - GPIO key to monitor 785f101103SGunnar Mills * @param[in] name - Pretty name of the inventory item 79*765725e0SGunnar Mills * @param[in] event - sd_event handler 80*765725e0SGunnar Mills * @param[in] handler - IO callback handler. Defaults to one in this 81*765725e0SGunnar Mills * class 825f101103SGunnar Mills */ 8380292bbeSGunnar Mills Presence(sdbusplus::bus::bus& bus, 8480292bbeSGunnar Mills const std::string& inventory, 855f101103SGunnar Mills const std::string& path, 865f101103SGunnar Mills const unsigned int key, 87*765725e0SGunnar Mills const std::string& name, 88*765725e0SGunnar Mills EventPtr& event, 89*765725e0SGunnar Mills sd_event_io_handler_t handler = Presence::processEvents) : 9080292bbeSGunnar Mills bus(bus), 915f101103SGunnar Mills inventory(inventory), 925f101103SGunnar Mills path(path), 935f101103SGunnar Mills key(key), 945f101103SGunnar Mills name(name), 95*765725e0SGunnar Mills event(event), 96*765725e0SGunnar Mills callbackHandler(handler), 975f101103SGunnar Mills fd(openDevice()) 98*765725e0SGunnar Mills 995f101103SGunnar Mills { 1005f101103SGunnar Mills initEvDev(); 1015f101103SGunnar Mills determinePresence(); 102*765725e0SGunnar Mills // Register callback handler when FD has some data 103*765725e0SGunnar Mills registerCallback(); 1045f101103SGunnar Mills } 1055f101103SGunnar Mills 106*765725e0SGunnar Mills /** @brief Callback handler when the FD has some activity on it 107*765725e0SGunnar Mills * 108*765725e0SGunnar Mills * @param[in] es - Populated event source 109*765725e0SGunnar Mills * @param[in] fd - Associated File descriptor 110*765725e0SGunnar Mills * @param[in] revents - Type of event 111*765725e0SGunnar Mills * @param[in] userData - User data that was passed during registration 112*765725e0SGunnar Mills * 113*765725e0SGunnar Mills * @return - 0 or positive number on success and negative 114*765725e0SGunnar Mills * errno otherwise 115*765725e0SGunnar Mills */ 116*765725e0SGunnar Mills static int processEvents(sd_event_source* es, int fd, 117*765725e0SGunnar Mills uint32_t revents, void* userData); 118*765725e0SGunnar Mills 1195f101103SGunnar Mills private: 1205f101103SGunnar Mills /** 12180292bbeSGunnar Mills * @brief Update the present property for the inventory item. 12280292bbeSGunnar Mills * 12380292bbeSGunnar Mills * @param[in] present - What the present property should be set to. 12480292bbeSGunnar Mills */ 12580292bbeSGunnar Mills void updateInventory(bool present); 12680292bbeSGunnar Mills 12780292bbeSGunnar Mills /** 12880292bbeSGunnar Mills * @brief Construct the inventory object map for the inventory item. 12980292bbeSGunnar Mills * 13080292bbeSGunnar Mills * @param[in] present - What the present property should be set to. 13180292bbeSGunnar Mills * 13280292bbeSGunnar Mills * @return The inventory object map to update inventory 13380292bbeSGunnar Mills */ 13480292bbeSGunnar Mills ObjectMap getObjectMap(bool present); 13580292bbeSGunnar Mills 13680292bbeSGunnar Mills /** @brief Connection for sdbusplus bus */ 13780292bbeSGunnar Mills sdbusplus::bus::bus& bus; 13880292bbeSGunnar Mills 13980292bbeSGunnar Mills /** 1405f101103SGunnar Mills * @brief Read the GPIO device to determine initial presence and set 1415f101103SGunnar Mills * present property at D-Bus path. 1425f101103SGunnar Mills **/ 1435f101103SGunnar Mills void determinePresence(); 1445f101103SGunnar Mills 1455f101103SGunnar Mills /** @brief Object path under inventory to display this inventory item */ 1465f101103SGunnar Mills const std::string inventory; 1475f101103SGunnar Mills 1485f101103SGunnar Mills /** @brief Device path to read for GPIO pin state 1495f101103SGunnar Mills to determine presence of inventory item */ 1505f101103SGunnar Mills const std::string path; 1515f101103SGunnar Mills 1525f101103SGunnar Mills /** @brief GPIO key to monitor */ 1535f101103SGunnar Mills const unsigned int key; 1545f101103SGunnar Mills 1555f101103SGunnar Mills /** @brief Pretty name of the inventory item*/ 1565f101103SGunnar Mills const std::string name; 1575f101103SGunnar Mills 1585f101103SGunnar Mills /** @brief Event structure */ 1595f101103SGunnar Mills EvdevPtr devicePtr; 1605f101103SGunnar Mills 161*765725e0SGunnar Mills /** @brief Monitor to sd_event */ 162*765725e0SGunnar Mills EventPtr& event; 163*765725e0SGunnar Mills 164*765725e0SGunnar Mills /** @brief Callback handler when the FD has some data */ 165*765725e0SGunnar Mills sd_event_io_handler_t callbackHandler; 166*765725e0SGunnar Mills 167*765725e0SGunnar Mills /** @brief event source */ 168*765725e0SGunnar Mills EventSourcePtr eventSource; 169*765725e0SGunnar Mills 1705f101103SGunnar Mills /** @brief Opens the device and populates the descriptor */ 1715f101103SGunnar Mills int openDevice(); 1725f101103SGunnar Mills 173*765725e0SGunnar Mills /** @brief attaches FD to events and sets up callback handler */ 174*765725e0SGunnar Mills void registerCallback(); 175*765725e0SGunnar Mills 1765f101103SGunnar Mills /** @brief File descriptor manager */ 1775f101103SGunnar Mills FileDescriptor fd; 1785f101103SGunnar Mills 179*765725e0SGunnar Mills /** @brief Analyzes the GPIO event and update present property*/ 180*765725e0SGunnar Mills void analyzeEvent(); 181*765725e0SGunnar Mills 1825f101103SGunnar Mills /** @brief Initializes evdev handle with the fd */ 1835f101103SGunnar Mills void initEvDev(); 1845f101103SGunnar Mills }; 1855f101103SGunnar Mills 18680292bbeSGunnar Mills /** 18780292bbeSGunnar Mills * @brief Get the service name from the mapper for the 18880292bbeSGunnar Mills * interface and path passed in. 18980292bbeSGunnar Mills * 19080292bbeSGunnar Mills * @param[in] path - The D-Bus path name 19180292bbeSGunnar Mills * @param[in] interface - The D-Bus interface name 19280292bbeSGunnar Mills * @param[in] bus - The D-Bus bus object 19380292bbeSGunnar Mills * 19480292bbeSGunnar Mills * @return The service name 19580292bbeSGunnar Mills */ 19680292bbeSGunnar Mills std::string getService(const std::string& path, 19780292bbeSGunnar Mills const std::string& interface, 19880292bbeSGunnar Mills sdbusplus::bus::bus& bus); 19980292bbeSGunnar Mills 2007263915aSGunnar Mills } // namespace presence 2017263915aSGunnar Mills } // namespace gpio 2027263915aSGunnar Mills } // namespace phosphor 2037263915aSGunnar Mills 204