17263915aSGunnar Mills #pragma once 2dace680fSPatrick Venture #include "evdev.hpp" 3dace680fSPatrick Venture 4dace680fSPatrick Venture #include <systemd/sd-event.h> 5dace680fSPatrick Venture 639084b4aSPatrick Williams #include <sdbusplus/bus.hpp> 739084b4aSPatrick Williams 8b08a0f69SBrandon Wyman #include <cstdlib> 9f70cbe75SPatrick Williams #include <filesystem> 105f101103SGunnar Mills #include <string> 117263915aSGunnar Mills 127263915aSGunnar Mills namespace phosphor 137263915aSGunnar Mills { 147263915aSGunnar Mills namespace gpio 157263915aSGunnar Mills { 167263915aSGunnar Mills namespace presence 177263915aSGunnar Mills { 187263915aSGunnar Mills 19902d1c37SMatt Spinler static constexpr auto deviceField = 0; 20902d1c37SMatt Spinler static constexpr auto pathField = 1; 21902d1c37SMatt Spinler using Device = std::string; 22f70cbe75SPatrick Williams using Path = std::filesystem::path; 23902d1c37SMatt Spinler using Driver = std::tuple<Device, Path>; 24206f0040SAnthony Wilson using Interface = std::string; 25902d1c37SMatt Spinler 265f101103SGunnar Mills /** @class Presence 27835dfb88SGunnar Mills * @brief Responsible for determining and monitoring presence, 28835dfb88SGunnar Mills * by monitoring GPIO state changes, of inventory items and 29835dfb88SGunnar Mills * updating D-Bus accordingly. 305f101103SGunnar Mills */ 31835dfb88SGunnar Mills class Presence : public Evdev 325f101103SGunnar Mills { 3380292bbeSGunnar Mills using Property = std::string; 343ce88a7bSPatrick Williams using Value = std::variant<bool, std::string>; 3580292bbeSGunnar Mills // Association between property and its value 3680292bbeSGunnar Mills using PropertyMap = std::map<Property, Value>; 3780292bbeSGunnar Mills using Interface = std::string; 3880292bbeSGunnar Mills // Association between interface and the D-Bus property 3980292bbeSGunnar Mills using InterfaceMap = std::map<Interface, PropertyMap>; 4080292bbeSGunnar Mills using Object = sdbusplus::message::object_path; 4180292bbeSGunnar Mills // Association between object and the interface 4280292bbeSGunnar Mills using ObjectMap = std::map<Object, InterfaceMap>; 4380292bbeSGunnar Mills 445f101103SGunnar Mills public: 455f101103SGunnar Mills Presence() = delete; 465f101103SGunnar Mills ~Presence() = default; 475f101103SGunnar Mills Presence(const Presence&) = delete; 485f101103SGunnar Mills Presence& operator=(const Presence&) = delete; 495f101103SGunnar Mills Presence(Presence&&) = delete; 505f101103SGunnar Mills Presence& operator=(Presence&&) = delete; 515f101103SGunnar Mills 525f101103SGunnar Mills /** @brief Constructs Presence object. 535f101103SGunnar Mills * 5480292bbeSGunnar Mills * @param[in] bus - D-Bus bus Object 555f101103SGunnar Mills * @param[in] inventory - Object path under inventory 565f101103SGunnar Mills to display this inventory item 575f101103SGunnar Mills * @param[in] path - Device path to read for GPIO pin state 585f101103SGunnar Mills to determine presence of inventory item 595f101103SGunnar Mills * @param[in] key - GPIO key to monitor 605f101103SGunnar Mills * @param[in] name - Pretty name of the inventory item 61765725e0SGunnar Mills * @param[in] event - sd_event handler 62902d1c37SMatt Spinler * @param[in] drivers - list of device drivers to bind and unbind 63206f0040SAnthony Wilson * @param[in] ifaces - list of extra interfaces to associate with the 64206f0040SAnthony Wilson * inventory item 65765725e0SGunnar Mills * @param[in] handler - IO callback handler. Defaults to one in this 66765725e0SGunnar Mills * class 675f101103SGunnar Mills */ Presence(sdbusplus::bus_t & bus,const std::string & inventory,const std::string & path,const unsigned int key,const std::string & name,EventPtr & event,const std::vector<Driver> & drivers,const std::vector<Interface> & ifaces,sd_event_io_handler_t handler=Presence::processEvents)68bc5b3751SPatrick Williams Presence(sdbusplus::bus_t& bus, const std::string& inventory, 69dace680fSPatrick Venture const std::string& path, const unsigned int key, 70dace680fSPatrick Venture const std::string& name, EventPtr& event, 71902d1c37SMatt Spinler const std::vector<Driver>& drivers, 72206f0040SAnthony Wilson const std::vector<Interface>& ifaces, 73765725e0SGunnar Mills sd_event_io_handler_t handler = Presence::processEvents) : 748377d59cSPatrick Williams Evdev(path, key, event, handler, true), bus(bus), inventory(inventory), 758377d59cSPatrick Williams name(name), drivers(drivers), ifaces(ifaces) 765f101103SGunnar Mills { 77b08a0f69SBrandon Wyman // See if the environment (from configuration file?) has a 78b08a0f69SBrandon Wyman // DRIVER_BIND_DELAY_MS set. 79b08a0f69SBrandon Wyman if (char* envDelay = std::getenv("DRIVER_BIND_DELAY_MS")) 80b08a0f69SBrandon Wyman { 81b08a0f69SBrandon Wyman // DRIVER_BIND_DELAY_MS environment variable is set. 82b08a0f69SBrandon Wyman // Update the bind delay (in milliseconds) to the value from the 83b08a0f69SBrandon Wyman // environment. 84*cf33c593SJayanth Othayoth delay = std::strtoull(envDelay, nullptr, 10); 85b08a0f69SBrandon Wyman } 865f101103SGunnar Mills determinePresence(); 875f101103SGunnar Mills } 885f101103SGunnar Mills 89765725e0SGunnar Mills /** @brief Callback handler when the FD has some activity on it 90765725e0SGunnar Mills * 91765725e0SGunnar Mills * @param[in] es - Populated event source 92765725e0SGunnar Mills * @param[in] fd - Associated File descriptor 93765725e0SGunnar Mills * @param[in] revents - Type of event 94765725e0SGunnar Mills * @param[in] userData - User data that was passed during registration 95765725e0SGunnar Mills * 96765725e0SGunnar Mills * @return - 0 or positive number on success and negative 97765725e0SGunnar Mills * errno otherwise 98765725e0SGunnar Mills */ 99dace680fSPatrick Venture static int processEvents(sd_event_source* es, int fd, uint32_t revents, 100dace680fSPatrick Venture void* userData); 101765725e0SGunnar Mills 1025f101103SGunnar Mills private: 1035f101103SGunnar Mills /** 10480292bbeSGunnar Mills * @brief Update the present property for the inventory item. 10580292bbeSGunnar Mills * 10680292bbeSGunnar Mills * @param[in] present - What the present property should be set to. 10780292bbeSGunnar Mills */ 10880292bbeSGunnar Mills void updateInventory(bool present); 10980292bbeSGunnar Mills 11080292bbeSGunnar Mills /** 11180292bbeSGunnar Mills * @brief Construct the inventory object map for the inventory item. 11280292bbeSGunnar Mills * 11380292bbeSGunnar Mills * @param[in] present - What the present property should be set to. 11480292bbeSGunnar Mills * 11580292bbeSGunnar Mills * @return The inventory object map to update inventory 11680292bbeSGunnar Mills */ 11780292bbeSGunnar Mills ObjectMap getObjectMap(bool present); 11880292bbeSGunnar Mills 11980292bbeSGunnar Mills /** @brief Connection for sdbusplus bus */ 120bc5b3751SPatrick Williams sdbusplus::bus_t& bus; 12180292bbeSGunnar Mills 12280292bbeSGunnar Mills /** 1235f101103SGunnar Mills * @brief Read the GPIO device to determine initial presence and set 1245f101103SGunnar Mills * present property at D-Bus path. 125902d1c37SMatt Spinler */ 1265f101103SGunnar Mills void determinePresence(); 1275f101103SGunnar Mills 1285f101103SGunnar Mills /** @brief Object path under inventory to display this inventory item */ 1295f101103SGunnar Mills const std::string inventory; 1305f101103SGunnar Mills 131b08a0f69SBrandon Wyman /** @brief Delay in milliseconds from present to bind device driver */ 132b08a0f69SBrandon Wyman unsigned int delay = 0; 133b08a0f69SBrandon Wyman 1345f101103SGunnar Mills /** @brief Pretty name of the inventory item*/ 1355f101103SGunnar Mills const std::string name; 1365f101103SGunnar Mills 137765725e0SGunnar Mills /** @brief Analyzes the GPIO event and update present property*/ 138765725e0SGunnar Mills void analyzeEvent(); 139902d1c37SMatt Spinler 140902d1c37SMatt Spinler /** @brief Vector of path and device tuples to bind/unbind*/ 141902d1c37SMatt Spinler const std::vector<Driver> drivers; 142902d1c37SMatt Spinler 143206f0040SAnthony Wilson /** @brief Vector of extra inventory interfaces to associate with the 144206f0040SAnthony Wilson * inventory item 145206f0040SAnthony Wilson */ 146206f0040SAnthony Wilson const std::vector<Interface> ifaces; 147206f0040SAnthony Wilson 148902d1c37SMatt Spinler /** 149902d1c37SMatt Spinler * @brief Binds or unbinds drivers 150902d1c37SMatt Spinler * 151902d1c37SMatt Spinler * Called when a presence change is detected to either 152902d1c37SMatt Spinler * bind the drivers for the new card or unbind them for 153902d1c37SMatt Spinler * the just removed card. Operates on the drivers vector. 154902d1c37SMatt Spinler * 155902d1c37SMatt Spinler * Writes <device> to <path>/bind (or unbind) 156902d1c37SMatt Spinler * 157902d1c37SMatt Spinler * @param present - when true, will bind the drivers 158902d1c37SMatt Spinler * when false, will unbind them 159902d1c37SMatt Spinler */ 160902d1c37SMatt Spinler void bindOrUnbindDrivers(bool present); 1615f101103SGunnar Mills }; 1625f101103SGunnar Mills 16380292bbeSGunnar Mills /** 16480292bbeSGunnar Mills * @brief Get the service name from the mapper for the 16580292bbeSGunnar Mills * interface and path passed in. 16680292bbeSGunnar Mills * 16780292bbeSGunnar Mills * @param[in] path - The D-Bus path name 16880292bbeSGunnar Mills * @param[in] interface - The D-Bus interface name 16980292bbeSGunnar Mills * @param[in] bus - The D-Bus bus object 17080292bbeSGunnar Mills * 17180292bbeSGunnar Mills * @return The service name 17280292bbeSGunnar Mills */ 173dace680fSPatrick Venture std::string getService(const std::string& path, const std::string& interface, 174bc5b3751SPatrick Williams sdbusplus::bus_t& bus); 17580292bbeSGunnar Mills 1767263915aSGunnar Mills } // namespace presence 1777263915aSGunnar Mills } // namespace gpio 1787263915aSGunnar Mills } // namespace phosphor 179