xref: /openbmc/phosphor-gpio-monitor/presence/gpio_presence.hpp (revision cf33c593266d1a4fbdf952e1243cddded3920905)
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