blob: 4b9b24ceaec17fb28e4e0025ac386108c6f2570c [file] [log] [blame]
Gunnar Mills72639152017-06-22 15:06:21 -05001#pragma once
Patrick Venturedace6802018-11-01 16:52:10 -07002#include "evdev.hpp"
3
4#include <systemd/sd-event.h>
5
Brandon Wymanb08a0f62021-03-03 19:53:18 -06006#include <cstdlib>
Matt Spinler902d1c32017-09-01 11:03:02 -05007#include <experimental/filesystem>
Patrick Williamsbc5b3752022-07-22 19:26:56 -05008#include <sdbusplus/bus.hpp>
Gunnar Mills5f101102017-06-29 13:07:39 -05009#include <string>
Gunnar Mills72639152017-06-22 15:06:21 -050010
11namespace phosphor
12{
13namespace gpio
14{
15namespace presence
16{
17
Matt Spinler902d1c32017-09-01 11:03:02 -050018static constexpr auto deviceField = 0;
19static constexpr auto pathField = 1;
20using Device = std::string;
21using Path = std::experimental::filesystem::path;
22using Driver = std::tuple<Device, Path>;
Anthony Wilson206f0042019-05-02 00:02:23 -050023using Interface = std::string;
Matt Spinler902d1c32017-09-01 11:03:02 -050024
Gunnar Mills5f101102017-06-29 13:07:39 -050025/** @class Presence
Gunnar Mills835dfb82017-07-26 16:15:21 -050026 * @brief Responsible for determining and monitoring presence,
27 * by monitoring GPIO state changes, of inventory items and
28 * updating D-Bus accordingly.
Gunnar Mills5f101102017-06-29 13:07:39 -050029 */
Gunnar Mills835dfb82017-07-26 16:15:21 -050030class Presence : public Evdev
Gunnar Mills5f101102017-06-29 13:07:39 -050031{
32
Patrick Venturedace6802018-11-01 16:52:10 -070033 using Property = std::string;
Patrick Williams3ce88a72020-06-03 06:02:48 -050034 using Value = std::variant<bool, std::string>;
Patrick Venturedace6802018-11-01 16:52:10 -070035 // Association between property and its value
36 using PropertyMap = std::map<Property, Value>;
37 using Interface = std::string;
38 // Association between interface and the D-Bus property
39 using InterfaceMap = std::map<Interface, PropertyMap>;
40 using Object = sdbusplus::message::object_path;
41 // Association between object and the interface
42 using ObjectMap = std::map<Object, InterfaceMap>;
Gunnar Mills80292bb2017-07-05 16:34:51 -050043
Patrick Venturedace6802018-11-01 16:52:10 -070044 public:
45 Presence() = delete;
46 ~Presence() = default;
47 Presence(const Presence&) = delete;
48 Presence& operator=(const Presence&) = delete;
49 Presence(Presence&&) = delete;
50 Presence& operator=(Presence&&) = delete;
Gunnar Mills5f101102017-06-29 13:07:39 -050051
Patrick Venturedace6802018-11-01 16:52:10 -070052 /** @brief Constructs Presence object.
53 *
54 * @param[in] bus - D-Bus bus Object
55 * @param[in] inventory - Object path under inventory
56 to display this inventory item
57 * @param[in] path - Device path to read for GPIO pin state
58 to determine presence of inventory item
59 * @param[in] key - GPIO key to monitor
60 * @param[in] name - Pretty name of the inventory item
61 * @param[in] event - sd_event handler
62 * @param[in] drivers - list of device drivers to bind and unbind
Anthony Wilson206f0042019-05-02 00:02:23 -050063 * @param[in] ifaces - list of extra interfaces to associate with the
64 * inventory item
Patrick Venturedace6802018-11-01 16:52:10 -070065 * @param[in] handler - IO callback handler. Defaults to one in this
66 * class
67 */
Patrick Williamsbc5b3752022-07-22 19:26:56 -050068 Presence(sdbusplus::bus_t& bus, const std::string& inventory,
Patrick Venturedace6802018-11-01 16:52:10 -070069 const std::string& path, const unsigned int key,
70 const std::string& name, EventPtr& event,
71 const std::vector<Driver>& drivers,
Anthony Wilson206f0042019-05-02 00:02:23 -050072 const std::vector<Interface>& ifaces,
Patrick Venturedace6802018-11-01 16:52:10 -070073 sd_event_io_handler_t handler = Presence::processEvents) :
74 Evdev(path, key, event, handler, true),
Anthony Wilson206f0042019-05-02 00:02:23 -050075 bus(bus), inventory(inventory), name(name), drivers(drivers),
76 ifaces(ifaces)
Patrick Venturedace6802018-11-01 16:52:10 -070077 {
Brandon Wymanb08a0f62021-03-03 19:53:18 -060078 // See if the environment (from configuration file?) has a
79 // DRIVER_BIND_DELAY_MS set.
80 if (char* envDelay = std::getenv("DRIVER_BIND_DELAY_MS"))
81 {
82 // DRIVER_BIND_DELAY_MS environment variable is set.
83 // Update the bind delay (in milliseconds) to the value from the
84 // environment.
85 delay = std::strtoull(envDelay, NULL, 10);
86 }
Patrick Venturedace6802018-11-01 16:52:10 -070087 determinePresence();
88 }
Gunnar Mills5f101102017-06-29 13:07:39 -050089
Patrick Venturedace6802018-11-01 16:52:10 -070090 /** @brief Callback handler when the FD has some activity on it
91 *
92 * @param[in] es - Populated event source
93 * @param[in] fd - Associated File descriptor
94 * @param[in] revents - Type of event
95 * @param[in] userData - User data that was passed during registration
96 *
97 * @return - 0 or positive number on success and negative
98 * errno otherwise
99 */
100 static int processEvents(sd_event_source* es, int fd, uint32_t revents,
101 void* userData);
Gunnar Mills765725e2017-07-06 14:17:44 -0500102
Patrick Venturedace6802018-11-01 16:52:10 -0700103 private:
104 /**
105 * @brief Update the present property for the inventory item.
106 *
107 * @param[in] present - What the present property should be set to.
108 */
109 void updateInventory(bool present);
Gunnar Mills80292bb2017-07-05 16:34:51 -0500110
Patrick Venturedace6802018-11-01 16:52:10 -0700111 /**
112 * @brief Construct the inventory object map for the inventory item.
113 *
114 * @param[in] present - What the present property should be set to.
115 *
116 * @return The inventory object map to update inventory
117 */
118 ObjectMap getObjectMap(bool present);
Gunnar Mills80292bb2017-07-05 16:34:51 -0500119
Patrick Venturedace6802018-11-01 16:52:10 -0700120 /** @brief Connection for sdbusplus bus */
Patrick Williamsbc5b3752022-07-22 19:26:56 -0500121 sdbusplus::bus_t& bus;
Gunnar Mills80292bb2017-07-05 16:34:51 -0500122
Patrick Venturedace6802018-11-01 16:52:10 -0700123 /**
124 * @brief Read the GPIO device to determine initial presence and set
125 * present property at D-Bus path.
126 */
127 void determinePresence();
Gunnar Mills5f101102017-06-29 13:07:39 -0500128
Patrick Venturedace6802018-11-01 16:52:10 -0700129 /** @brief Object path under inventory to display this inventory item */
130 const std::string inventory;
Gunnar Mills5f101102017-06-29 13:07:39 -0500131
Brandon Wymanb08a0f62021-03-03 19:53:18 -0600132 /** @brief Delay in milliseconds from present to bind device driver */
133 unsigned int delay = 0;
134
Patrick Venturedace6802018-11-01 16:52:10 -0700135 /** @brief Pretty name of the inventory item*/
136 const std::string name;
Gunnar Mills5f101102017-06-29 13:07:39 -0500137
Patrick Venturedace6802018-11-01 16:52:10 -0700138 /** @brief Analyzes the GPIO event and update present property*/
139 void analyzeEvent();
Matt Spinler902d1c32017-09-01 11:03:02 -0500140
Patrick Venturedace6802018-11-01 16:52:10 -0700141 /** @brief Vector of path and device tuples to bind/unbind*/
142 const std::vector<Driver> drivers;
Matt Spinler902d1c32017-09-01 11:03:02 -0500143
Anthony Wilson206f0042019-05-02 00:02:23 -0500144 /** @brief Vector of extra inventory interfaces to associate with the
145 * inventory item
146 */
147 const std::vector<Interface> ifaces;
148
Patrick Venturedace6802018-11-01 16:52:10 -0700149 /**
150 * @brief Binds or unbinds drivers
151 *
152 * Called when a presence change is detected to either
153 * bind the drivers for the new card or unbind them for
154 * the just removed card. Operates on the drivers vector.
155 *
156 * Writes <device> to <path>/bind (or unbind)
157 *
158 * @param present - when true, will bind the drivers
159 * when false, will unbind them
160 */
161 void bindOrUnbindDrivers(bool present);
Gunnar Mills5f101102017-06-29 13:07:39 -0500162};
163
Gunnar Mills80292bb2017-07-05 16:34:51 -0500164/**
165 * @brief Get the service name from the mapper for the
166 * interface and path passed in.
167 *
168 * @param[in] path - The D-Bus path name
169 * @param[in] interface - The D-Bus interface name
170 * @param[in] bus - The D-Bus bus object
171 *
172 * @return The service name
173 */
Patrick Venturedace6802018-11-01 16:52:10 -0700174std::string getService(const std::string& path, const std::string& interface,
Patrick Williamsbc5b3752022-07-22 19:26:56 -0500175 sdbusplus::bus_t& bus);
Gunnar Mills80292bb2017-07-05 16:34:51 -0500176
Gunnar Mills72639152017-06-22 15:06:21 -0500177} // namespace presence
178} // namespace gpio
179} // namespace phosphor