xref: /openbmc/phosphor-gpio-monitor/presence/gpio_presence.hpp (revision 3ce88a7b5a1c17ca53b63859a5dad840a995f42e)
17263915aSGunnar Mills #pragma once
2dace680fSPatrick Venture #include "evdev.hpp"
3dace680fSPatrick Venture 
4dace680fSPatrick Venture #include <systemd/sd-event.h>
5dace680fSPatrick Venture 
6902d1c37SMatt Spinler #include <experimental/filesystem>
75f101103SGunnar Mills #include <string>
87263915aSGunnar Mills 
97263915aSGunnar Mills namespace phosphor
107263915aSGunnar Mills {
117263915aSGunnar Mills namespace gpio
127263915aSGunnar Mills {
137263915aSGunnar Mills namespace presence
147263915aSGunnar Mills {
157263915aSGunnar Mills 
16902d1c37SMatt Spinler static constexpr auto deviceField = 0;
17902d1c37SMatt Spinler static constexpr auto pathField = 1;
18902d1c37SMatt Spinler using Device = std::string;
19902d1c37SMatt Spinler using Path = std::experimental::filesystem::path;
20902d1c37SMatt Spinler using Driver = std::tuple<Device, Path>;
21206f0040SAnthony Wilson using Interface = std::string;
22902d1c37SMatt Spinler 
235f101103SGunnar Mills /** @class Presence
24835dfb88SGunnar Mills  *  @brief Responsible for determining and monitoring presence,
25835dfb88SGunnar Mills  *  by monitoring GPIO state changes, of inventory items and
26835dfb88SGunnar Mills  *  updating D-Bus accordingly.
275f101103SGunnar Mills  */
28835dfb88SGunnar Mills class Presence : public Evdev
295f101103SGunnar Mills {
305f101103SGunnar Mills 
3180292bbeSGunnar Mills     using Property = std::string;
32*3ce88a7bSPatrick Williams     using Value = std::variant<bool, std::string>;
3380292bbeSGunnar Mills     // Association between property and its value
3480292bbeSGunnar Mills     using PropertyMap = std::map<Property, Value>;
3580292bbeSGunnar Mills     using Interface = std::string;
3680292bbeSGunnar Mills     // Association between interface and the D-Bus property
3780292bbeSGunnar Mills     using InterfaceMap = std::map<Interface, PropertyMap>;
3880292bbeSGunnar Mills     using Object = sdbusplus::message::object_path;
3980292bbeSGunnar Mills     // Association between object and the interface
4080292bbeSGunnar Mills     using ObjectMap = std::map<Object, InterfaceMap>;
4180292bbeSGunnar Mills 
425f101103SGunnar Mills   public:
435f101103SGunnar Mills     Presence() = delete;
445f101103SGunnar Mills     ~Presence() = default;
455f101103SGunnar Mills     Presence(const Presence&) = delete;
465f101103SGunnar Mills     Presence& operator=(const Presence&) = delete;
475f101103SGunnar Mills     Presence(Presence&&) = delete;
485f101103SGunnar Mills     Presence& operator=(Presence&&) = delete;
495f101103SGunnar Mills 
505f101103SGunnar Mills     /** @brief Constructs Presence object.
515f101103SGunnar Mills      *
5280292bbeSGunnar Mills      *  @param[in] bus       - D-Bus bus Object
535f101103SGunnar Mills      *  @param[in] inventory - Object path under inventory
545f101103SGunnar Mills                                to display this inventory item
555f101103SGunnar Mills      *  @param[in] path      - Device path to read for GPIO pin state
565f101103SGunnar Mills                                to determine presence of inventory item
575f101103SGunnar Mills      *  @param[in] key       - GPIO key to monitor
585f101103SGunnar Mills      *  @param[in] name      - Pretty name of the inventory item
59765725e0SGunnar Mills      *  @param[in] event     - sd_event handler
60902d1c37SMatt Spinler      *  @param[in] drivers   - list of device drivers to bind and unbind
61206f0040SAnthony Wilson      *  @param[in] ifaces    - list of extra interfaces to associate with the
62206f0040SAnthony Wilson      *                         inventory item
63765725e0SGunnar Mills      *  @param[in] handler   - IO callback handler. Defaults to one in this
64765725e0SGunnar Mills      *                        class
655f101103SGunnar Mills      */
66dace680fSPatrick Venture     Presence(sdbusplus::bus::bus& bus, const std::string& inventory,
67dace680fSPatrick Venture              const std::string& path, const unsigned int key,
68dace680fSPatrick Venture              const std::string& name, EventPtr& event,
69902d1c37SMatt Spinler              const std::vector<Driver>& drivers,
70206f0040SAnthony Wilson              const std::vector<Interface>& ifaces,
71765725e0SGunnar Mills              sd_event_io_handler_t handler = Presence::processEvents) :
72835dfb88SGunnar Mills         Evdev(path, key, event, handler, true),
73206f0040SAnthony Wilson         bus(bus), inventory(inventory), name(name), drivers(drivers),
74206f0040SAnthony Wilson         ifaces(ifaces)
755f101103SGunnar Mills     {
765f101103SGunnar Mills         determinePresence();
775f101103SGunnar Mills     }
785f101103SGunnar Mills 
79765725e0SGunnar Mills     /** @brief Callback handler when the FD has some activity on it
80765725e0SGunnar Mills      *
81765725e0SGunnar Mills      *  @param[in] es       - Populated event source
82765725e0SGunnar Mills      *  @param[in] fd       - Associated File descriptor
83765725e0SGunnar Mills      *  @param[in] revents  - Type of event
84765725e0SGunnar Mills      *  @param[in] userData - User data that was passed during registration
85765725e0SGunnar Mills      *
86765725e0SGunnar Mills      *  @return             - 0 or positive number on success and negative
87765725e0SGunnar Mills      *                        errno otherwise
88765725e0SGunnar Mills      */
89dace680fSPatrick Venture     static int processEvents(sd_event_source* es, int fd, uint32_t revents,
90dace680fSPatrick Venture                              void* userData);
91765725e0SGunnar Mills 
925f101103SGunnar Mills   private:
935f101103SGunnar Mills     /**
9480292bbeSGunnar Mills      * @brief Update the present property for the inventory item.
9580292bbeSGunnar Mills      *
9680292bbeSGunnar Mills      * @param[in] present - What the present property should be set to.
9780292bbeSGunnar Mills      */
9880292bbeSGunnar Mills     void updateInventory(bool present);
9980292bbeSGunnar Mills 
10080292bbeSGunnar Mills     /**
10180292bbeSGunnar Mills      * @brief Construct the inventory object map for the inventory item.
10280292bbeSGunnar Mills      *
10380292bbeSGunnar Mills      * @param[in] present - What the present property should be set to.
10480292bbeSGunnar Mills      *
10580292bbeSGunnar Mills      * @return The inventory object map to update inventory
10680292bbeSGunnar Mills      */
10780292bbeSGunnar Mills     ObjectMap getObjectMap(bool present);
10880292bbeSGunnar Mills 
10980292bbeSGunnar Mills     /** @brief Connection for sdbusplus bus */
11080292bbeSGunnar Mills     sdbusplus::bus::bus& bus;
11180292bbeSGunnar Mills 
11280292bbeSGunnar Mills     /**
1135f101103SGunnar Mills      * @brief Read the GPIO device to determine initial presence and set
1145f101103SGunnar Mills      *        present property at D-Bus path.
115902d1c37SMatt Spinler      */
1165f101103SGunnar Mills     void determinePresence();
1175f101103SGunnar Mills 
1185f101103SGunnar Mills     /** @brief Object path under inventory to display this inventory item */
1195f101103SGunnar Mills     const std::string inventory;
1205f101103SGunnar Mills 
1215f101103SGunnar Mills     /** @brief Pretty name of the inventory item*/
1225f101103SGunnar Mills     const std::string name;
1235f101103SGunnar Mills 
124765725e0SGunnar Mills     /** @brief Analyzes the GPIO event and update present property*/
125765725e0SGunnar Mills     void analyzeEvent();
126902d1c37SMatt Spinler 
127902d1c37SMatt Spinler     /** @brief  Vector of path and device tuples to bind/unbind*/
128902d1c37SMatt Spinler     const std::vector<Driver> drivers;
129902d1c37SMatt Spinler 
130206f0040SAnthony Wilson     /** @brief  Vector of extra inventory interfaces to associate with the
131206f0040SAnthony Wilson      *          inventory item
132206f0040SAnthony Wilson      */
133206f0040SAnthony Wilson     const std::vector<Interface> ifaces;
134206f0040SAnthony Wilson 
135902d1c37SMatt Spinler     /**
136902d1c37SMatt Spinler      * @brief Binds or unbinds drivers
137902d1c37SMatt Spinler      *
138902d1c37SMatt Spinler      * Called when a presence change is detected to either
139902d1c37SMatt Spinler      * bind the drivers for the new card or unbind them for
140902d1c37SMatt Spinler      * the just removed card.  Operates on the drivers vector.
141902d1c37SMatt Spinler      *
142902d1c37SMatt Spinler      * Writes <device> to <path>/bind (or unbind)
143902d1c37SMatt Spinler      *
144902d1c37SMatt Spinler      * @param present - when true, will bind the drivers
145902d1c37SMatt Spinler      *                  when false, will unbind them
146902d1c37SMatt Spinler      */
147902d1c37SMatt Spinler     void bindOrUnbindDrivers(bool present);
1485f101103SGunnar Mills };
1495f101103SGunnar Mills 
15080292bbeSGunnar Mills /**
15180292bbeSGunnar Mills  * @brief Get the service name from the mapper for the
15280292bbeSGunnar Mills  *        interface and path passed in.
15380292bbeSGunnar Mills  *
15480292bbeSGunnar Mills  * @param[in] path      - The D-Bus path name
15580292bbeSGunnar Mills  * @param[in] interface - The D-Bus interface name
15680292bbeSGunnar Mills  * @param[in] bus       - The D-Bus bus object
15780292bbeSGunnar Mills  *
15880292bbeSGunnar Mills  * @return The service name
15980292bbeSGunnar Mills  */
160dace680fSPatrick Venture std::string getService(const std::string& path, const std::string& interface,
16180292bbeSGunnar Mills                        sdbusplus::bus::bus& bus);
16280292bbeSGunnar Mills 
1637263915aSGunnar Mills } // namespace presence
1647263915aSGunnar Mills } // namespace gpio
1657263915aSGunnar Mills } // namespace phosphor
166