xref: /openbmc/phosphor-gpio-monitor/multi-presence/gpio_presence.hpp (revision 8377d59c61c653a34df1c3c4ca72219eceb0b43b)
1 #pragma once
2 
3 #include <gpiod.h>
4 
5 #include <boost/asio/io_context.hpp>
6 #include <boost/asio/posix/stream_descriptor.hpp>
7 #include <sdbusplus/bus.hpp>
8 #include <sdbusplus/message.hpp>
9 
10 #include <cstdlib>
11 #include <filesystem>
12 #include <map>
13 #include <string>
14 #include <vector>
15 
16 static constexpr auto deviceField = 0;
17 static constexpr auto pathField = 1;
18 using Device = std::string;
19 using Path = std::filesystem::path;
20 using Driver = std::tuple<Device, Path>;
21 using Interface = std::string;
22 
23 namespace phosphor
24 {
25 namespace gpio
26 {
27 
28 /** @class GpioPresence
29  *  @brief Responsible for catching GPIO state change
30  *  condition and updating the inventory presence.
31  */
32 class GpioPresence
33 {
34     using Property = std::string;
35     using Value = std::variant<bool, std::string>;
36     // Association between property and its value
37     using PropertyMap = std::map<Property, Value>;
38     using Interface = std::string;
39     // Association between interface and the D-Bus property
40     using InterfaceMap = std::map<Interface, PropertyMap>;
41     using Object = sdbusplus::message::object_path;
42     // Association between object and the interface
43     using ObjectMap = std::map<Object, InterfaceMap>;
44 
45   public:
46     GpioPresence() = delete;
47     ~GpioPresence() = default;
48     GpioPresence(const GpioPresence&) = delete;
49     GpioPresence& operator=(const GpioPresence&) = delete;
50 
51     /** @brief Constructs GpioPresence object.
52      *
53      *  @param[in] line             - GPIO line from libgpiod
54      *  @param[in] config           - configuration of line with event
55      *  @param[in] io               - io service
56      *  @param[in] inventory        - Object path under inventory that
57                                       will be created
58      *  @param[in] extraInterfaces  - List of interfaces to associate to
59                                       inventory item
60      *  @param[in] name             - PrettyName of inventory object
61      *  @param[in] lineMsg          - GPIO line message to be used for log
62      */
GpioPresence(gpiod_line * line,gpiod_line_request_config & config,boost::asio::io_context & io,const std::string & inventory,const std::vector<std::string> & extraInterfaces,const std::string & name,const std::string & lineMsg)63     GpioPresence(gpiod_line* line, gpiod_line_request_config& config,
64                  boost::asio::io_context& io, const std::string& inventory,
65                  const std::vector<std::string>& extraInterfaces,
66                  const std::string& name, const std::string& lineMsg) :
67         gpioLine(line), gpioConfig(config), gpioEventDescriptor(io),
68         inventory(inventory), interfaces(extraInterfaces), name(name),
69         gpioLineMsg(lineMsg)
70     {
71         requestGPIOEvents();
72     };
73 
GpioPresence(GpioPresence && old)74     GpioPresence(GpioPresence&& old) noexcept :
75         gpioLine(old.gpioLine), gpioConfig(old.gpioConfig),
76         gpioEventDescriptor(old.gpioEventDescriptor.get_executor()),
77         inventory(std::move(old.inventory)),
78         interfaces(std::move(old.interfaces)), name(std::move(old.name)),
79         gpioLineMsg(std::move(old.gpioLineMsg))
80     {
81         old.cancelEventHandler();
82 
83         gpioEventDescriptor = std::move(old.gpioEventDescriptor);
84 
85         scheduleEventHandler();
86     };
87 
88   private:
89     /** @brief GPIO line */
90     gpiod_line* gpioLine;
91 
92     /** @brief GPIO line configuration */
93     gpiod_line_request_config gpioConfig;
94 
95     /** @brief GPIO event descriptor */
96     boost::asio::posix::stream_descriptor gpioEventDescriptor;
97 
98     /** @brief Object path under inventory that will be created */
99     const std::string inventory;
100 
101     /** @brief List of interfaces to associate to inventory item */
102     const std::vector<std::string> interfaces;
103 
104     /** @brief PrettyName of inventory object */
105     const std::string name;
106 
107     /** @brief GPIO line name message */
108     const std::string gpioLineMsg;
109 
110     /** @brief register handler for gpio event
111      *
112      *  @return  - 0 on success and -1 otherwise
113      */
114     int requestGPIOEvents();
115 
116     /** @brief Schedule an event handler for GPIO event to trigger */
117     void scheduleEventHandler();
118 
119     /** @brief Stop the event handler for GPIO events */
120     void cancelEventHandler();
121 
122     /** @brief Handle the GPIO event and starts configured target */
123     void gpioEventHandler();
124 
125     /** @brief Returns the object map for the inventory object */
126     ObjectMap getObjectMap(bool present);
127 
128     /** @brief Updates the inventory */
129     void updateInventory(bool present);
130 };
131 
132 } // namespace gpio
133 } // namespace phosphor
134