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