blob: edd2d7ad2401d674e0b31261a20a07b482ae9e98 [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
Matt Spinler902d1c32017-09-01 11:03:02 -05006#include <experimental/filesystem>
Gunnar Mills5f101102017-06-29 13:07:39 -05007#include <string>
Gunnar Mills72639152017-06-22 15:06:21 -05008
9namespace phosphor
10{
11namespace gpio
12{
13namespace presence
14{
15
Matt Spinler902d1c32017-09-01 11:03:02 -050016static constexpr auto deviceField = 0;
17static constexpr auto pathField = 1;
18using Device = std::string;
19using Path = std::experimental::filesystem::path;
20using Driver = std::tuple<Device, Path>;
Anthony Wilson206f0042019-05-02 00:02:23 -050021using Interface = std::string;
Matt Spinler902d1c32017-09-01 11:03:02 -050022
Gunnar Mills5f101102017-06-29 13:07:39 -050023/** @class Presence
Gunnar Mills835dfb82017-07-26 16:15:21 -050024 * @brief Responsible for determining and monitoring presence,
25 * by monitoring GPIO state changes, of inventory items and
26 * updating D-Bus accordingly.
Gunnar Mills5f101102017-06-29 13:07:39 -050027 */
Gunnar Mills835dfb82017-07-26 16:15:21 -050028class Presence : public Evdev
Gunnar Mills5f101102017-06-29 13:07:39 -050029{
30
Patrick Venturedace6802018-11-01 16:52:10 -070031 using Property = std::string;
32 using Value = sdbusplus::message::variant<bool, std::string>;
33 // Association between property and its value
34 using PropertyMap = std::map<Property, Value>;
35 using Interface = std::string;
36 // Association between interface and the D-Bus property
37 using InterfaceMap = std::map<Interface, PropertyMap>;
38 using Object = sdbusplus::message::object_path;
39 // Association between object and the interface
40 using ObjectMap = std::map<Object, InterfaceMap>;
Gunnar Mills80292bb2017-07-05 16:34:51 -050041
Patrick Venturedace6802018-11-01 16:52:10 -070042 public:
43 Presence() = delete;
44 ~Presence() = default;
45 Presence(const Presence&) = delete;
46 Presence& operator=(const Presence&) = delete;
47 Presence(Presence&&) = delete;
48 Presence& operator=(Presence&&) = delete;
Gunnar Mills5f101102017-06-29 13:07:39 -050049
Patrick Venturedace6802018-11-01 16:52:10 -070050 /** @brief Constructs Presence object.
51 *
52 * @param[in] bus - D-Bus bus Object
53 * @param[in] inventory - Object path under inventory
54 to display this inventory item
55 * @param[in] path - Device path to read for GPIO pin state
56 to determine presence of inventory item
57 * @param[in] key - GPIO key to monitor
58 * @param[in] name - Pretty name of the inventory item
59 * @param[in] event - sd_event handler
60 * @param[in] drivers - list of device drivers to bind and unbind
Anthony Wilson206f0042019-05-02 00:02:23 -050061 * @param[in] ifaces - list of extra interfaces to associate with the
62 * inventory item
Patrick Venturedace6802018-11-01 16:52:10 -070063 * @param[in] handler - IO callback handler. Defaults to one in this
64 * class
65 */
66 Presence(sdbusplus::bus::bus& bus, const std::string& inventory,
67 const std::string& path, const unsigned int key,
68 const std::string& name, EventPtr& event,
69 const std::vector<Driver>& drivers,
Anthony Wilson206f0042019-05-02 00:02:23 -050070 const std::vector<Interface>& ifaces,
Patrick Venturedace6802018-11-01 16:52:10 -070071 sd_event_io_handler_t handler = Presence::processEvents) :
72 Evdev(path, key, event, handler, true),
Anthony Wilson206f0042019-05-02 00:02:23 -050073 bus(bus), inventory(inventory), name(name), drivers(drivers),
74 ifaces(ifaces)
Patrick Venturedace6802018-11-01 16:52:10 -070075 {
76 determinePresence();
77 }
Gunnar Mills5f101102017-06-29 13:07:39 -050078
Patrick Venturedace6802018-11-01 16:52:10 -070079 /** @brief Callback handler when the FD has some activity on it
80 *
81 * @param[in] es - Populated event source
82 * @param[in] fd - Associated File descriptor
83 * @param[in] revents - Type of event
84 * @param[in] userData - User data that was passed during registration
85 *
86 * @return - 0 or positive number on success and negative
87 * errno otherwise
88 */
89 static int processEvents(sd_event_source* es, int fd, uint32_t revents,
90 void* userData);
Gunnar Mills765725e2017-07-06 14:17:44 -050091
Patrick Venturedace6802018-11-01 16:52:10 -070092 private:
93 /**
94 * @brief Update the present property for the inventory item.
95 *
96 * @param[in] present - What the present property should be set to.
97 */
98 void updateInventory(bool present);
Gunnar Mills80292bb2017-07-05 16:34:51 -050099
Patrick Venturedace6802018-11-01 16:52:10 -0700100 /**
101 * @brief Construct the inventory object map for the inventory item.
102 *
103 * @param[in] present - What the present property should be set to.
104 *
105 * @return The inventory object map to update inventory
106 */
107 ObjectMap getObjectMap(bool present);
Gunnar Mills80292bb2017-07-05 16:34:51 -0500108
Patrick Venturedace6802018-11-01 16:52:10 -0700109 /** @brief Connection for sdbusplus bus */
110 sdbusplus::bus::bus& bus;
Gunnar Mills80292bb2017-07-05 16:34:51 -0500111
Patrick Venturedace6802018-11-01 16:52:10 -0700112 /**
113 * @brief Read the GPIO device to determine initial presence and set
114 * present property at D-Bus path.
115 */
116 void determinePresence();
Gunnar Mills5f101102017-06-29 13:07:39 -0500117
Patrick Venturedace6802018-11-01 16:52:10 -0700118 /** @brief Object path under inventory to display this inventory item */
119 const std::string inventory;
Gunnar Mills5f101102017-06-29 13:07:39 -0500120
Patrick Venturedace6802018-11-01 16:52:10 -0700121 /** @brief Pretty name of the inventory item*/
122 const std::string name;
Gunnar Mills5f101102017-06-29 13:07:39 -0500123
Patrick Venturedace6802018-11-01 16:52:10 -0700124 /** @brief Analyzes the GPIO event and update present property*/
125 void analyzeEvent();
Matt Spinler902d1c32017-09-01 11:03:02 -0500126
Patrick Venturedace6802018-11-01 16:52:10 -0700127 /** @brief Vector of path and device tuples to bind/unbind*/
128 const std::vector<Driver> drivers;
Matt Spinler902d1c32017-09-01 11:03:02 -0500129
Anthony Wilson206f0042019-05-02 00:02:23 -0500130 /** @brief Vector of extra inventory interfaces to associate with the
131 * inventory item
132 */
133 const std::vector<Interface> ifaces;
134
Patrick Venturedace6802018-11-01 16:52:10 -0700135 /**
136 * @brief Binds or unbinds drivers
137 *
138 * Called when a presence change is detected to either
139 * bind the drivers for the new card or unbind them for
140 * the just removed card. Operates on the drivers vector.
141 *
142 * Writes <device> to <path>/bind (or unbind)
143 *
144 * @param present - when true, will bind the drivers
145 * when false, will unbind them
146 */
147 void bindOrUnbindDrivers(bool present);
Gunnar Mills5f101102017-06-29 13:07:39 -0500148};
149
Gunnar Mills80292bb2017-07-05 16:34:51 -0500150/**
151 * @brief Get the service name from the mapper for the
152 * interface and path passed in.
153 *
154 * @param[in] path - The D-Bus path name
155 * @param[in] interface - The D-Bus interface name
156 * @param[in] bus - The D-Bus bus object
157 *
158 * @return The service name
159 */
Patrick Venturedace6802018-11-01 16:52:10 -0700160std::string getService(const std::string& path, const std::string& interface,
Gunnar Mills80292bb2017-07-05 16:34:51 -0500161 sdbusplus::bus::bus& bus);
162
Gunnar Mills72639152017-06-22 15:06:21 -0500163} // namespace presence
164} // namespace gpio
165} // namespace phosphor