blob: ec26fde471ba2b23012726a9a77672833d50a91f [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>
Gunnar Mills5f101102017-06-29 13:07:39 -05008#include <string>
Gunnar Mills72639152017-06-22 15:06:21 -05009
10namespace phosphor
11{
12namespace gpio
13{
14namespace presence
15{
16
Matt Spinler902d1c32017-09-01 11:03:02 -050017static constexpr auto deviceField = 0;
18static constexpr auto pathField = 1;
19using Device = std::string;
20using Path = std::experimental::filesystem::path;
21using Driver = std::tuple<Device, Path>;
Anthony Wilson206f0042019-05-02 00:02:23 -050022using Interface = std::string;
Matt Spinler902d1c32017-09-01 11:03:02 -050023
Gunnar Mills5f101102017-06-29 13:07:39 -050024/** @class Presence
Gunnar Mills835dfb82017-07-26 16:15:21 -050025 * @brief Responsible for determining and monitoring presence,
26 * by monitoring GPIO state changes, of inventory items and
27 * updating D-Bus accordingly.
Gunnar Mills5f101102017-06-29 13:07:39 -050028 */
Gunnar Mills835dfb82017-07-26 16:15:21 -050029class Presence : public Evdev
Gunnar Mills5f101102017-06-29 13:07:39 -050030{
31
Patrick Venturedace6802018-11-01 16:52:10 -070032 using Property = std::string;
Patrick Williams3ce88a72020-06-03 06:02:48 -050033 using Value = std::variant<bool, std::string>;
Patrick Venturedace6802018-11-01 16:52:10 -070034 // Association between property and its value
35 using PropertyMap = std::map<Property, Value>;
36 using Interface = std::string;
37 // Association between interface and the D-Bus property
38 using InterfaceMap = std::map<Interface, PropertyMap>;
39 using Object = sdbusplus::message::object_path;
40 // Association between object and the interface
41 using ObjectMap = std::map<Object, InterfaceMap>;
Gunnar Mills80292bb2017-07-05 16:34:51 -050042
Patrick Venturedace6802018-11-01 16:52:10 -070043 public:
44 Presence() = delete;
45 ~Presence() = default;
46 Presence(const Presence&) = delete;
47 Presence& operator=(const Presence&) = delete;
48 Presence(Presence&&) = delete;
49 Presence& operator=(Presence&&) = delete;
Gunnar Mills5f101102017-06-29 13:07:39 -050050
Patrick Venturedace6802018-11-01 16:52:10 -070051 /** @brief Constructs Presence object.
52 *
53 * @param[in] bus - D-Bus bus Object
54 * @param[in] inventory - Object path under inventory
55 to display this inventory item
56 * @param[in] path - Device path to read for GPIO pin state
57 to determine presence of inventory item
58 * @param[in] key - GPIO key to monitor
59 * @param[in] name - Pretty name of the inventory item
60 * @param[in] event - sd_event handler
61 * @param[in] drivers - list of device drivers to bind and unbind
Anthony Wilson206f0042019-05-02 00:02:23 -050062 * @param[in] ifaces - list of extra interfaces to associate with the
63 * inventory item
Patrick Venturedace6802018-11-01 16:52:10 -070064 * @param[in] handler - IO callback handler. Defaults to one in this
65 * class
66 */
67 Presence(sdbusplus::bus::bus& bus, const std::string& inventory,
68 const std::string& path, const unsigned int key,
69 const std::string& name, EventPtr& event,
70 const std::vector<Driver>& drivers,
Anthony Wilson206f0042019-05-02 00:02:23 -050071 const std::vector<Interface>& ifaces,
Patrick Venturedace6802018-11-01 16:52:10 -070072 sd_event_io_handler_t handler = Presence::processEvents) :
73 Evdev(path, key, event, handler, true),
Anthony Wilson206f0042019-05-02 00:02:23 -050074 bus(bus), inventory(inventory), name(name), drivers(drivers),
75 ifaces(ifaces)
Patrick Venturedace6802018-11-01 16:52:10 -070076 {
Brandon Wymanb08a0f62021-03-03 19:53:18 -060077 // See if the environment (from configuration file?) has a
78 // DRIVER_BIND_DELAY_MS set.
79 if (char* envDelay = std::getenv("DRIVER_BIND_DELAY_MS"))
80 {
81 // DRIVER_BIND_DELAY_MS environment variable is set.
82 // Update the bind delay (in milliseconds) to the value from the
83 // environment.
84 delay = std::strtoull(envDelay, NULL, 10);
85 }
Patrick Venturedace6802018-11-01 16:52:10 -070086 determinePresence();
87 }
Gunnar Mills5f101102017-06-29 13:07:39 -050088
Patrick Venturedace6802018-11-01 16:52:10 -070089 /** @brief Callback handler when the FD has some activity on it
90 *
91 * @param[in] es - Populated event source
92 * @param[in] fd - Associated File descriptor
93 * @param[in] revents - Type of event
94 * @param[in] userData - User data that was passed during registration
95 *
96 * @return - 0 or positive number on success and negative
97 * errno otherwise
98 */
99 static int processEvents(sd_event_source* es, int fd, uint32_t revents,
100 void* userData);
Gunnar Mills765725e2017-07-06 14:17:44 -0500101
Patrick Venturedace6802018-11-01 16:52:10 -0700102 private:
103 /**
104 * @brief Update the present property for the inventory item.
105 *
106 * @param[in] present - What the present property should be set to.
107 */
108 void updateInventory(bool present);
Gunnar Mills80292bb2017-07-05 16:34:51 -0500109
Patrick Venturedace6802018-11-01 16:52:10 -0700110 /**
111 * @brief Construct the inventory object map for the inventory item.
112 *
113 * @param[in] present - What the present property should be set to.
114 *
115 * @return The inventory object map to update inventory
116 */
117 ObjectMap getObjectMap(bool present);
Gunnar Mills80292bb2017-07-05 16:34:51 -0500118
Patrick Venturedace6802018-11-01 16:52:10 -0700119 /** @brief Connection for sdbusplus bus */
120 sdbusplus::bus::bus& bus;
Gunnar Mills80292bb2017-07-05 16:34:51 -0500121
Patrick Venturedace6802018-11-01 16:52:10 -0700122 /**
123 * @brief Read the GPIO device to determine initial presence and set
124 * present property at D-Bus path.
125 */
126 void determinePresence();
Gunnar Mills5f101102017-06-29 13:07:39 -0500127
Patrick Venturedace6802018-11-01 16:52:10 -0700128 /** @brief Object path under inventory to display this inventory item */
129 const std::string inventory;
Gunnar Mills5f101102017-06-29 13:07:39 -0500130
Brandon Wymanb08a0f62021-03-03 19:53:18 -0600131 /** @brief Delay in milliseconds from present to bind device driver */
132 unsigned int delay = 0;
133
Patrick Venturedace6802018-11-01 16:52:10 -0700134 /** @brief Pretty name of the inventory item*/
135 const std::string name;
Gunnar Mills5f101102017-06-29 13:07:39 -0500136
Patrick Venturedace6802018-11-01 16:52:10 -0700137 /** @brief Analyzes the GPIO event and update present property*/
138 void analyzeEvent();
Matt Spinler902d1c32017-09-01 11:03:02 -0500139
Patrick Venturedace6802018-11-01 16:52:10 -0700140 /** @brief Vector of path and device tuples to bind/unbind*/
141 const std::vector<Driver> drivers;
Matt Spinler902d1c32017-09-01 11:03:02 -0500142
Anthony Wilson206f0042019-05-02 00:02:23 -0500143 /** @brief Vector of extra inventory interfaces to associate with the
144 * inventory item
145 */
146 const std::vector<Interface> ifaces;
147
Patrick Venturedace6802018-11-01 16:52:10 -0700148 /**
149 * @brief Binds or unbinds drivers
150 *
151 * Called when a presence change is detected to either
152 * bind the drivers for the new card or unbind them for
153 * the just removed card. Operates on the drivers vector.
154 *
155 * Writes <device> to <path>/bind (or unbind)
156 *
157 * @param present - when true, will bind the drivers
158 * when false, will unbind them
159 */
160 void bindOrUnbindDrivers(bool present);
Gunnar Mills5f101102017-06-29 13:07:39 -0500161};
162
Gunnar Mills80292bb2017-07-05 16:34:51 -0500163/**
164 * @brief Get the service name from the mapper for the
165 * interface and path passed in.
166 *
167 * @param[in] path - The D-Bus path name
168 * @param[in] interface - The D-Bus interface name
169 * @param[in] bus - The D-Bus bus object
170 *
171 * @return The service name
172 */
Patrick Venturedace6802018-11-01 16:52:10 -0700173std::string getService(const std::string& path, const std::string& interface,
Gunnar Mills80292bb2017-07-05 16:34:51 -0500174 sdbusplus::bus::bus& bus);
175
Gunnar Mills72639152017-06-22 15:06:21 -0500176} // namespace presence
177} // namespace gpio
178} // namespace phosphor