blob: b37cc0c7ed1bf02cf13d06ed4c119e9c8ff1126b [file] [log] [blame]
Christopher Meis75ff1672025-09-23 11:40:06 +02001// SPDX-License-Identifier: Apache-2.0
2// SPDX-FileCopyrightText: Copyright OpenBMC Authors
3
Gunnar Mills72639152017-06-22 15:06:21 -05004#pragma once
Patrick Venturedace6802018-11-01 16:52:10 -07005#include "evdev.hpp"
6
7#include <systemd/sd-event.h>
8
Patrick Williams39084b42023-05-10 07:50:58 -05009#include <sdbusplus/bus.hpp>
10
Brandon Wymanb08a0f62021-03-03 19:53:18 -060011#include <cstdlib>
Patrick Williamsf70cbe72023-06-01 07:00:08 -050012#include <filesystem>
Gunnar Mills5f101102017-06-29 13:07:39 -050013#include <string>
Gunnar Mills72639152017-06-22 15:06:21 -050014
15namespace phosphor
16{
17namespace gpio
18{
19namespace presence
20{
21
Matt Spinler902d1c32017-09-01 11:03:02 -050022static constexpr auto deviceField = 0;
23static constexpr auto pathField = 1;
24using Device = std::string;
Patrick Williamsf70cbe72023-06-01 07:00:08 -050025using Path = std::filesystem::path;
Matt Spinler902d1c32017-09-01 11:03:02 -050026using Driver = std::tuple<Device, Path>;
Anthony Wilson206f0042019-05-02 00:02:23 -050027using Interface = std::string;
Matt Spinler902d1c32017-09-01 11:03:02 -050028
Gunnar Mills5f101102017-06-29 13:07:39 -050029/** @class Presence
Gunnar Mills835dfb82017-07-26 16:15:21 -050030 * @brief Responsible for determining and monitoring presence,
31 * by monitoring GPIO state changes, of inventory items and
32 * updating D-Bus accordingly.
Gunnar Mills5f101102017-06-29 13:07:39 -050033 */
Gunnar Mills835dfb82017-07-26 16:15:21 -050034class Presence : public Evdev
Gunnar Mills5f101102017-06-29 13:07:39 -050035{
Patrick Venturedace6802018-11-01 16:52:10 -070036 using Property = std::string;
Patrick Williams3ce88a72020-06-03 06:02:48 -050037 using Value = std::variant<bool, std::string>;
Patrick Venturedace6802018-11-01 16:52:10 -070038 // Association between property and its value
39 using PropertyMap = std::map<Property, Value>;
40 using Interface = std::string;
41 // Association between interface and the D-Bus property
42 using InterfaceMap = std::map<Interface, PropertyMap>;
43 using Object = sdbusplus::message::object_path;
44 // Association between object and the interface
45 using ObjectMap = std::map<Object, InterfaceMap>;
Gunnar Mills80292bb2017-07-05 16:34:51 -050046
Patrick Venturedace6802018-11-01 16:52:10 -070047 public:
48 Presence() = delete;
49 ~Presence() = default;
50 Presence(const Presence&) = delete;
51 Presence& operator=(const Presence&) = delete;
52 Presence(Presence&&) = delete;
53 Presence& operator=(Presence&&) = delete;
Gunnar Mills5f101102017-06-29 13:07:39 -050054
Patrick Venturedace6802018-11-01 16:52:10 -070055 /** @brief Constructs Presence object.
56 *
57 * @param[in] bus - D-Bus bus Object
58 * @param[in] inventory - Object path under inventory
59 to display this inventory item
60 * @param[in] path - Device path to read for GPIO pin state
61 to determine presence of inventory item
62 * @param[in] key - GPIO key to monitor
63 * @param[in] name - Pretty name of the inventory item
64 * @param[in] event - sd_event handler
65 * @param[in] drivers - list of device drivers to bind and unbind
Anthony Wilson206f0042019-05-02 00:02:23 -050066 * @param[in] ifaces - list of extra interfaces to associate with the
67 * inventory item
Patrick Venturedace6802018-11-01 16:52:10 -070068 * @param[in] handler - IO callback handler. Defaults to one in this
69 * class
70 */
Patrick Williamsbc5b3752022-07-22 19:26:56 -050071 Presence(sdbusplus::bus_t& bus, const std::string& inventory,
Patrick Venturedace6802018-11-01 16:52:10 -070072 const std::string& path, const unsigned int key,
73 const std::string& name, EventPtr& event,
74 const std::vector<Driver>& drivers,
Anthony Wilson206f0042019-05-02 00:02:23 -050075 const std::vector<Interface>& ifaces,
Patrick Venturedace6802018-11-01 16:52:10 -070076 sd_event_io_handler_t handler = Presence::processEvents) :
Patrick Williams8377d592024-08-16 15:21:08 -040077 Evdev(path, key, event, handler, true), bus(bus), inventory(inventory),
78 name(name), drivers(drivers), ifaces(ifaces)
Patrick Venturedace6802018-11-01 16:52:10 -070079 {
Brandon Wymanb08a0f62021-03-03 19:53:18 -060080 // See if the environment (from configuration file?) has a
81 // DRIVER_BIND_DELAY_MS set.
82 if (char* envDelay = std::getenv("DRIVER_BIND_DELAY_MS"))
83 {
84 // DRIVER_BIND_DELAY_MS environment variable is set.
85 // Update the bind delay (in milliseconds) to the value from the
86 // environment.
Jayanth Othayothcf33c592024-12-18 07:27:03 -060087 delay = std::strtoull(envDelay, nullptr, 10);
Brandon Wymanb08a0f62021-03-03 19:53:18 -060088 }
Patrick Venturedace6802018-11-01 16:52:10 -070089 determinePresence();
90 }
Gunnar Mills5f101102017-06-29 13:07:39 -050091
Patrick Venturedace6802018-11-01 16:52:10 -070092 /** @brief Callback handler when the FD has some activity on it
93 *
94 * @param[in] es - Populated event source
95 * @param[in] fd - Associated File descriptor
96 * @param[in] revents - Type of event
97 * @param[in] userData - User data that was passed during registration
98 *
99 * @return - 0 or positive number on success and negative
100 * errno otherwise
101 */
102 static int processEvents(sd_event_source* es, int fd, uint32_t revents,
103 void* userData);
Gunnar Mills765725e2017-07-06 14:17:44 -0500104
Patrick Venturedace6802018-11-01 16:52:10 -0700105 private:
106 /**
107 * @brief Update the present property for the inventory item.
108 *
109 * @param[in] present - What the present property should be set to.
110 */
111 void updateInventory(bool present);
Gunnar Mills80292bb2017-07-05 16:34:51 -0500112
Patrick Venturedace6802018-11-01 16:52:10 -0700113 /**
114 * @brief Construct the inventory object map for the inventory item.
115 *
116 * @param[in] present - What the present property should be set to.
117 *
118 * @return The inventory object map to update inventory
119 */
120 ObjectMap getObjectMap(bool present);
Gunnar Mills80292bb2017-07-05 16:34:51 -0500121
Patrick Venturedace6802018-11-01 16:52:10 -0700122 /** @brief Connection for sdbusplus bus */
Patrick Williamsbc5b3752022-07-22 19:26:56 -0500123 sdbusplus::bus_t& bus;
Gunnar Mills80292bb2017-07-05 16:34:51 -0500124
Patrick Venturedace6802018-11-01 16:52:10 -0700125 /**
126 * @brief Read the GPIO device to determine initial presence and set
127 * present property at D-Bus path.
128 */
129 void determinePresence();
Gunnar Mills5f101102017-06-29 13:07:39 -0500130
Patrick Venturedace6802018-11-01 16:52:10 -0700131 /** @brief Object path under inventory to display this inventory item */
132 const std::string inventory;
Gunnar Mills5f101102017-06-29 13:07:39 -0500133
Brandon Wymanb08a0f62021-03-03 19:53:18 -0600134 /** @brief Delay in milliseconds from present to bind device driver */
135 unsigned int delay = 0;
136
Patrick Venturedace6802018-11-01 16:52:10 -0700137 /** @brief Pretty name of the inventory item*/
138 const std::string name;
Gunnar Mills5f101102017-06-29 13:07:39 -0500139
Patrick Venturedace6802018-11-01 16:52:10 -0700140 /** @brief Analyzes the GPIO event and update present property*/
141 void analyzeEvent();
Matt Spinler902d1c32017-09-01 11:03:02 -0500142
Patrick Venturedace6802018-11-01 16:52:10 -0700143 /** @brief Vector of path and device tuples to bind/unbind*/
144 const std::vector<Driver> drivers;
Matt Spinler902d1c32017-09-01 11:03:02 -0500145
Anthony Wilson206f0042019-05-02 00:02:23 -0500146 /** @brief Vector of extra inventory interfaces to associate with the
147 * inventory item
148 */
149 const std::vector<Interface> ifaces;
150
Patrick Venturedace6802018-11-01 16:52:10 -0700151 /**
152 * @brief Binds or unbinds drivers
153 *
154 * Called when a presence change is detected to either
155 * bind the drivers for the new card or unbind them for
156 * the just removed card. Operates on the drivers vector.
157 *
158 * Writes <device> to <path>/bind (or unbind)
159 *
160 * @param present - when true, will bind the drivers
161 * when false, will unbind them
162 */
163 void bindOrUnbindDrivers(bool present);
Gunnar Mills5f101102017-06-29 13:07:39 -0500164};
165
Gunnar Mills80292bb2017-07-05 16:34:51 -0500166/**
167 * @brief Get the service name from the mapper for the
168 * interface and path passed in.
169 *
170 * @param[in] path - The D-Bus path name
171 * @param[in] interface - The D-Bus interface name
172 * @param[in] bus - The D-Bus bus object
173 *
174 * @return The service name
175 */
Patrick Venturedace6802018-11-01 16:52:10 -0700176std::string getService(const std::string& path, const std::string& interface,
Patrick Williamsbc5b3752022-07-22 19:26:56 -0500177 sdbusplus::bus_t& bus);
Gunnar Mills80292bb2017-07-05 16:34:51 -0500178
Gunnar Mills72639152017-06-22 15:06:21 -0500179} // namespace presence
180} // namespace gpio
181} // namespace phosphor